示例#1
0
CPLErr GDALPamRasterBand::SetDefaultHistogram( double dfMin, double dfMax, 
                                               int nBuckets, int *panHistogram)

{
    CPLXMLNode *psNode;

    PamInitialize();

    if( psPam == NULL )
        return GDALRasterBand::SetDefaultHistogram( dfMin, dfMax, 
                                                    nBuckets, panHistogram );

/* -------------------------------------------------------------------- */
/*      Do we have a matching histogram we should replace?              */
/* -------------------------------------------------------------------- */
    psNode = PamFindMatchingHistogram( psPam->psSavedHistograms, 
                                       dfMin, dfMax, nBuckets,
                                       TRUE, TRUE );
    if( psNode != NULL )
    {
        /* blow this one away */
        CPLRemoveXMLChild( psPam->psSavedHistograms, psNode );
        CPLDestroyXMLNode( psNode );
    }

/* -------------------------------------------------------------------- */
/*      Translate into a histogram XML tree.                            */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psHistItem;

    psHistItem = PamHistogramToXMLTree( dfMin, dfMax, nBuckets, 
                                        panHistogram, TRUE, FALSE );
    if( psHistItem == NULL )
        return CE_Failure;

/* -------------------------------------------------------------------- */
/*      Insert our new default histogram at the front of the            */
/*      histogram list so that it will be the default histogram.        */
/* -------------------------------------------------------------------- */
    psPam->poParentDS->MarkPamDirty();

    if( psPam->psSavedHistograms == NULL )
        psPam->psSavedHistograms = CPLCreateXMLNode( NULL, CXT_Element,
                                                     "Histograms" );
            
    psHistItem->psNext = psPam->psSavedHistograms->psChild;
    psPam->psSavedHistograms->psChild = psHistItem;
    
    return CE_None;
}
示例#2
0
CPLErr VRTRasterBand::SetDefaultHistogram( double dfMin, double dfMax, 
                                           int nBuckets, GUIntBig *panHistogram)

{
    CPLXMLNode *psNode;

/* -------------------------------------------------------------------- */
/*      Do we have a matching histogram we should replace?              */
/* -------------------------------------------------------------------- */
    psNode = PamFindMatchingHistogram( psSavedHistograms, 
                                       dfMin, dfMax, nBuckets,
                                       TRUE, TRUE );
    if( psNode != NULL )
    {
        /* blow this one away */
        CPLRemoveXMLChild( psSavedHistograms, psNode );
        CPLDestroyXMLNode( psNode );
    }

/* -------------------------------------------------------------------- */
/*      Translate into a histogram XML tree.                            */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psHistItem;

    psHistItem = PamHistogramToXMLTree( dfMin, dfMax, nBuckets, 
                                        panHistogram, TRUE, FALSE );
    if( psHistItem == NULL )
        return CE_Failure;

/* -------------------------------------------------------------------- */
/*      Insert our new default histogram at the front of the            */
/*      histogram list so that it will be the default histogram.        */
/* -------------------------------------------------------------------- */
    ((VRTDataset *) poDS)->SetNeedsFlush();

    if( psSavedHistograms == NULL )
        psSavedHistograms = CPLCreateXMLNode( NULL, CXT_Element,
                                              "Histograms" );
            
    psHistItem->psNext = psSavedHistograms->psChild;
    psSavedHistograms->psChild = psHistItem;
    
    return CE_None;
}
static void RemoveIDs( CPLXMLNode * psRoot )

{
    if( psRoot == NULL )
        return;

    CPLXMLNode *psChild = psRoot->psChild;

// check for id attribute
    while( psChild != NULL && !( psChild->eType == CXT_Attribute && EQUAL(psChild->pszValue, "gml:id")))
        psChild = psChild->psNext;
    CPLRemoveXMLChild( psRoot, psChild );
    CPLDestroyXMLNode( psChild );

// search the child elements of psRoot
    for( psChild = psRoot->psChild; psChild != NULL; psChild = psChild->psNext)
        if( psChild->eType == CXT_Element )
            RemoveIDs( psChild );
}
static int TrimTree( CPLXMLNode * psRoot )

{
    if( psRoot == NULL )
        return FALSE;

    CPLXMLNode *psChild = psRoot->psChild;

// check for id attribute
    while( psChild != NULL && !( psChild->eType == CXT_Attribute && EQUAL(psChild->pszValue, "gml:id")))
        psChild = psChild->psNext;

    if( psChild != NULL )
        return TRUE;

// search the child elements of psRoot
    int bReturn = FALSE, bRemove;
    for( psChild = psRoot->psChild; psChild != NULL;)
    {
        CPLXMLNode* psNextChild = psChild->psNext;
        if( psChild->eType == CXT_Element )
        {
            bRemove = TrimTree( psChild );
            if( bRemove )
            {
                bReturn = bRemove;
            }
            else
            {
                //remove this child
                CPLRemoveXMLChild( psRoot, psChild );
                CPLDestroyXMLNode( psChild );
            }
        }

        psChild = psNextChild;
    }
    return bReturn;
}
static CPLErr Resolve( CPLXMLNode * psNode,
                CPLXMLNode *** ppapsRoot,
                char *** ppapszResourceHREF,
                char ** papszSkip,
                const int bStrict )

{
    //for each sibling
    CPLXMLNode *psSibling = NULL;
    CPLXMLNode *psResource = NULL;
    CPLXMLNode *psTarget = NULL;
    CPLErr eReturn = CE_None, eReturned;
    
    for( psSibling = psNode; psSibling != NULL; psSibling = psSibling->psNext )
    {
        if( psSibling->eType != CXT_Element )
            continue;

        CPLXMLNode *psChild = psSibling->psChild;
        while( psChild != NULL &&
               !( psChild->eType == CXT_Attribute &&
                  EQUAL( psChild->pszValue, "xlink:href" ) ) )
            psChild = psChild->psNext;

        //if a child has a "xlink:href" attribute
        if( psChild != NULL && psChild->psChild != NULL )
        {
            if( CSLFindString( papszSkip, psSibling->pszValue ) >= 0 )
            {//Skipping a specified element
                eReturn = CE_Warning;
                continue;
            }

            static int i = 0;
            if( i-- == 0 )
            {//a way to track progress
                i = 256;
                CPLDebug( "GML",
                          "Resolving xlinks... (currently %s)",
                          psChild->psChild->pszValue );
            }

            char **papszTokens;
            papszTokens = CSLTokenizeString2( psChild->psChild->pszValue, "#",
                                              CSLT_ALLOWEMPTYTOKENS |
                                              CSLT_STRIPLEADSPACES |
                                              CSLT_STRIPENDSPACES );
            if( CSLCount( papszTokens ) != 2 || strlen(papszTokens[1]) <= 0 )
            {
                CPLError( bStrict ? CE_Failure : CE_Warning,
                          CPLE_NotSupported,
                          "Error parsing the href %s.%s",
                          psChild->psChild->pszValue,
                          bStrict ? "" : " Skipping..." );
                CSLDestroy( papszTokens );
                if( bStrict )
                    return CE_Failure;
                eReturn = CE_Warning;
                continue;
            }

            //look for the resource with that URL
            psResource = FindTreeByURL( ppapsRoot,
                                        ppapszResourceHREF,
                                        papszTokens[0] );
            if( psResource == NULL )
            {
                CSLDestroy( papszTokens );
                if( bStrict )
                    return CE_Failure;
                eReturn = CE_Warning;
                continue;
            }

            //look for the element with the ID
            psTarget = FindElementByID( psResource, papszTokens[1] );
            if( psTarget != NULL )
            {
                //remove the xlink:href attribute
                CPLRemoveXMLChild( psSibling, psChild );
                CPLDestroyXMLNode( psChild );

                //make a copy of psTarget
                CPLXMLNode *psCopy = CPLCreateXMLNode( NULL,
                                                       CXT_Element,
                                                       psTarget->pszValue );
                psCopy->psChild = CPLCloneXMLTree( psTarget->psChild );
                RemoveIDs( psCopy );
                //correct empty URLs in URL#id pairs
                if( CPLStrnlen( papszTokens[0], 1 ) > 0 )
                {
                    CorrectURLs( psCopy, papszTokens[0] );
                }
                CPLAddXMLChild( psSibling, psCopy );
                CSLDestroy( papszTokens );
            }
            else
            {
                //element not found
                CSLDestroy( papszTokens );
                CPLError( bStrict ? CE_Failure : CE_Warning,
                          CPLE_ObjectNull,
                          "Couldn't find the element with id %s.",
                          psChild->psChild->pszValue );
                if( bStrict )
                    return CE_Failure;
                eReturn = CE_Warning;
            }
        }

        //Recurse with the first child
        eReturned=Resolve( psSibling->psChild,
                           ppapsRoot,
                           ppapszResourceHREF,
                           papszSkip,
                           bStrict );

        if( eReturned == CE_Failure )
            return CE_Failure;

        if( eReturned == CE_Warning )
                eReturn = CE_Warning;
    }
    return eReturn;
}
示例#6
0
CPLErr GDALPamDataset::TrySaveXML()

{
    CPLXMLNode *psTree;
    CPLErr eErr = CE_None;

    nPamFlags &= ~GPF_DIRTY;

    if( psPam == NULL || (nPamFlags & GPF_NOSAVE) )
        return CE_None;

/* -------------------------------------------------------------------- */
/*      Make sure we know the filename we want to store in.             */
/* -------------------------------------------------------------------- */
    if( !BuildPamFilename() )
        return CE_None;

/* -------------------------------------------------------------------- */
/*      Build the XML representation of the auxilary metadata.          */
/* -------------------------------------------------------------------- */
    CPLString osVRTPath = CPLGetPath(psPam->pszPamFilename);

    psTree = SerializeToXML( osVRTPath );

    if( psTree == NULL )
        return CE_None;

/* -------------------------------------------------------------------- */
/*      If we are working with a subdataset, we need to integrate       */
/*      the subdataset tree within the whole existing pam tree,         */
/*      after removing any old version of the same subdataset.          */
/* -------------------------------------------------------------------- */
    if( psPam->osSubdatasetName.size() != 0 )
    {
        CPLXMLNode *psOldTree, *psSubTree;

        CPLErrorReset();
        CPLPushErrorHandler( CPLQuietErrorHandler );
        psOldTree = CPLParseXMLFile( psPam->pszPamFilename );
        CPLPopErrorHandler();

        if( psOldTree == NULL )
            psOldTree = CPLCreateXMLNode( NULL, CXT_Element, "PAMDataset" );

        for( psSubTree = psTree->psChild; 
             psSubTree != NULL;
             psSubTree = psSubTree->psNext )
        {
            if( psSubTree->eType != CXT_Element
                || !EQUAL(psSubTree->pszValue,"Subdataset") )
                continue;

            if( !EQUAL(CPLGetXMLValue( psSubTree, "name", "" ),
                       psPam->osSubdatasetName) )
                continue;

            break;
        }

        if( psSubTree == NULL )
        {
            psSubTree = CPLCreateXMLNode( psOldTree, CXT_Element, 
                                          "Subdataset" );
            CPLCreateXMLNode( 
                CPLCreateXMLNode( psSubTree, CXT_Attribute, "name" ),
                CXT_Text, psPam->osSubdatasetName );
        }
        
        CPLXMLNode *psOldPamDataset = CPLGetXMLNode( psSubTree, "PAMDataset");
        if( psOldPamDataset != NULL )
        {
            CPLRemoveXMLChild( psSubTree, psOldPamDataset );
            CPLDestroyXMLNode( psOldPamDataset );
        }

        CPLAddXMLChild( psSubTree, psTree );
        psTree = psOldTree;
    }

/* -------------------------------------------------------------------- */
/*      Try saving the auxilary metadata.                               */
/* -------------------------------------------------------------------- */
    const char *pszNewPam;
    int bSaved;
    
    CPLPushErrorHandler( CPLQuietErrorHandler );
    bSaved = CPLSerializeXMLTreeToFile( psTree, psPam->pszPamFilename );
    CPLPopErrorHandler();

/* -------------------------------------------------------------------- */
/*      If it fails, check if we have a proxy directory for auxilary    */
/*      metadata to be stored in, and try to save there.                */
/* -------------------------------------------------------------------- */
    if( bSaved )
        eErr = CE_None;
    else if( PamGetProxy(GetDescription()) == NULL 
             && ((pszNewPam = PamAllocateProxy(GetDescription())) != NULL))
    {
        CPLErrorReset();
        CPLFree( psPam->pszPamFilename );
        psPam->pszPamFilename = CPLStrdup(pszNewPam);
        eErr = TrySaveXML();
    }
    else
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
                  "Unable to save auxilary information in %s.",
                  psPam->pszPamFilename );
        eErr = CE_Warning;
    }
    
/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    CPLDestroyXMLNode( psTree );

    return eErr;
}