CPLXMLNode *VRTRasterBand::SerializeToXML( const char *pszVRTPath ) { CPLXMLNode *psTree; psTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTRasterBand" ); /* -------------------------------------------------------------------- */ /* Various kinds of metadata. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMD; CPLSetXMLValue( psTree, "#dataType", GDALGetDataTypeName( GetRasterDataType() ) ); if( nBand > 0 ) CPLSetXMLValue( psTree, "#band", CPLSPrintf( "%d", GetBand() ) ); psMD = oMDMD.Serialize(); if( psMD != NULL ) CPLAddXMLChild( psTree, psMD ); if( strlen(GetDescription()) > 0 ) CPLSetXMLValue( psTree, "Description", GetDescription() ); if( bNoDataValueSet ) { if (CPLIsNan(dfNoDataValue)) CPLSetXMLValue( psTree, "NoDataValue", "nan"); else CPLSetXMLValue( psTree, "NoDataValue", CPLSPrintf( "%.14E", dfNoDataValue ) ); } if( bHideNoDataValue ) CPLSetXMLValue( psTree, "HideNoDataValue", CPLSPrintf( "%d", bHideNoDataValue ) ); if( pszUnitType != NULL ) CPLSetXMLValue( psTree, "UnitType", pszUnitType ); if( dfOffset != 0.0 ) CPLSetXMLValue( psTree, "Offset", CPLSPrintf( "%.16g", dfOffset ) ); if( dfScale != 1.0 ) CPLSetXMLValue( psTree, "Scale", CPLSPrintf( "%.16g", dfScale ) ); if( eColorInterp != GCI_Undefined ) CPLSetXMLValue( psTree, "ColorInterp", GDALGetColorInterpretationName( eColorInterp ) ); /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( papszCategoryNames != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "CategoryNames" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; papszCategoryNames[iEntry] != NULL; iEntry++ ) { CPLXMLNode *psNode = CPLCreateXMLElementAndValue( NULL, "Category", papszCategoryNames[iEntry] ); if( psLastChild == NULL ) psCT_XML->psChild = psNode; else psLastChild->psNext = psNode; psLastChild = psNode; } } /* -------------------------------------------------------------------- */ /* Histograms. */ /* -------------------------------------------------------------------- */ if( psSavedHistograms != NULL ) CPLAddXMLChild( psTree, CPLCloneXMLTree( psSavedHistograms ) ); /* -------------------------------------------------------------------- */ /* Color Table. */ /* -------------------------------------------------------------------- */ if( poColorTable != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "ColorTable" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; iEntry < poColorTable->GetColorEntryCount(); iEntry++ ) { GDALColorEntry sEntry; CPLXMLNode *psEntry_XML = CPLCreateXMLNode( NULL, CXT_Element, "Entry" ); if( psLastChild == NULL ) psCT_XML->psChild = psEntry_XML; else psLastChild->psNext = psEntry_XML; psLastChild = psEntry_XML; poColorTable->GetColorEntryAsRGB( iEntry, &sEntry ); CPLSetXMLValue( psEntry_XML, "#c1", CPLSPrintf("%d",sEntry.c1) ); CPLSetXMLValue( psEntry_XML, "#c2", CPLSPrintf("%d",sEntry.c2) ); CPLSetXMLValue( psEntry_XML, "#c3", CPLSPrintf("%d",sEntry.c3) ); CPLSetXMLValue( psEntry_XML, "#c4", CPLSPrintf("%d",sEntry.c4) ); } } /* ==================================================================== */ /* Overviews */ /* ==================================================================== */ for( int iOvr = 0; iOvr < (int)apoOverviews.size(); iOvr ++ ) { CPLXMLNode *psOVR_XML = CPLCreateXMLNode( psTree, CXT_Element, "Overview" ); int bRelativeToVRT; const char *pszRelativePath; VSIStatBufL sStat; if( VSIStatExL( apoOverviews[iOvr].osFilename, &sStat, VSI_STAT_EXISTS_FLAG ) != 0 ) { pszRelativePath = apoOverviews[iOvr].osFilename; bRelativeToVRT = FALSE; } else { pszRelativePath = CPLExtractRelativePath( pszVRTPath, apoOverviews[iOvr].osFilename, &bRelativeToVRT ); } CPLSetXMLValue( psOVR_XML, "SourceFilename", pszRelativePath ); CPLCreateXMLNode( CPLCreateXMLNode( CPLGetXMLNode( psOVR_XML, "SourceFilename" ), CXT_Attribute, "relativeToVRT" ), CXT_Text, bRelativeToVRT ? "1" : "0" ); CPLSetXMLValue( psOVR_XML, "SourceBand", CPLSPrintf("%d",apoOverviews[iOvr].nBand) ); } /* ==================================================================== */ /* Mask band (specific to that raster band) */ /* ==================================================================== */ if( poMaskBand != NULL ) { CPLXMLNode *psBandTree = poMaskBand->SerializeToXML(pszVRTPath); if( psBandTree != NULL ) { CPLXMLNode *psMaskBandElement = CPLCreateXMLNode( psTree, CXT_Element, "MaskBand" ); CPLAddXMLChild( psMaskBandElement, psBandTree ); } } return psTree; }
CPLXMLNode *VRTWarpedDataset::SerializeToXML( const char *pszVRTPath ) { CPLXMLNode *psTree; psTree = VRTDataset::SerializeToXML( pszVRTPath ); if( psTree == NULL ) return psTree; /* -------------------------------------------------------------------- */ /* Set subclass. */ /* -------------------------------------------------------------------- */ CPLCreateXMLNode( CPLCreateXMLNode( psTree, CXT_Attribute, "subClass" ), CXT_Text, "VRTWarpedDataset" ); /* -------------------------------------------------------------------- */ /* Serialize the block size. */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "BlockXSize", CPLSPrintf( "%d", nBlockXSize ) ); CPLCreateXMLElementAndValue( psTree, "BlockYSize", CPLSPrintf( "%d", nBlockYSize ) ); /* -------------------------------------------------------------------- */ /* Serialize the overview list. */ /* -------------------------------------------------------------------- */ if( nOverviewCount > 0 ) { char *pszOverviewList; int iOverview; pszOverviewList = (char *) CPLMalloc(nOverviewCount*8 + 10); pszOverviewList[0] = '\0'; for( iOverview = 0; iOverview < nOverviewCount; iOverview++ ) { int nOvFactor; nOvFactor = (int) (0.5+GetRasterXSize() / (double) papoOverviews[iOverview]->GetRasterXSize()); sprintf( pszOverviewList + strlen(pszOverviewList), "%d ", nOvFactor ); } CPLCreateXMLElementAndValue( psTree, "OverviewList", pszOverviewList ); CPLFree( pszOverviewList ); } /* ==================================================================== */ /* Serialize the warp options. */ /* ==================================================================== */ CPLXMLNode *psWOTree; if( poWarper != NULL ) { /* -------------------------------------------------------------------- */ /* We reset the destination dataset name so it doesn't get */ /* written out in the serialize warp options. */ /* -------------------------------------------------------------------- */ char *pszSavedName = CPLStrdup(GetDescription()); SetDescription(""); psWOTree = GDALSerializeWarpOptions( poWarper->GetOptions() ); CPLAddXMLChild( psTree, psWOTree ); SetDescription( pszSavedName ); CPLFree( pszSavedName ); /* -------------------------------------------------------------------- */ /* We need to consider making the source dataset relative to */ /* the VRT file if possible. Adjust accordingly. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSDS = CPLGetXMLNode( psWOTree, "SourceDataset" ); int bRelativeToVRT; char *pszRelativePath; pszRelativePath = CPLStrdup( CPLExtractRelativePath( pszVRTPath, psSDS->psChild->pszValue, &bRelativeToVRT ) ); CPLFree( psSDS->psChild->pszValue ); psSDS->psChild->pszValue = pszRelativePath; CPLCreateXMLNode( CPLCreateXMLNode( psSDS, CXT_Attribute, "relativeToVRT" ), CXT_Text, bRelativeToVRT ? "1" : "0" ); } return psTree; }