CPLErr VRTWarpedDataset::AddBand( GDALDataType eType, char **papszOptions ) { UNREFERENCED_PARAM( papszOptions ); SetBand( GetRasterCount() + 1, new VRTWarpedRasterBand( this, GetRasterCount() + 1, eType ) ); return CE_None; }
DIMAPDataset::~DIMAPDataset() { FlushCache(); CPLDestroyXMLNode( psProduct ); CPLFree( pszGCPProjection ); if( nGCPCount > 0 ) { GDALDeinitGCPs( nGCPCount, pasGCPList ); CPLFree( pasGCPList ); } if( poImageDS != NULL ) delete poImageDS; CSLDestroy(papszXMLDimapMetadata); /* -------------------------------------------------------------------- */ /* Disconnect the bands so our destructor doesn't try and */ /* delete them since they really belonged to poImageDS. */ /* -------------------------------------------------------------------- */ int iBand; for( iBand = 0; iBand < GetRasterCount(); iBand++ ) papoBands[iBand] = NULL; }
CPLErr MEMDataset::AddBand( GDALDataType eType, char **papszOptions ) { int nBandId = GetRasterCount() + 1; GByte *pData; int nPixelSize = (GDALGetDataTypeSize(eType) / 8); /* -------------------------------------------------------------------- */ /* Do we need to allocate the memory ourselves? This is the */ /* simple case. */ /* -------------------------------------------------------------------- */ if( CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL ) { pData = (GByte *) VSICalloc(nPixelSize * GetRasterXSize(), GetRasterYSize() ); if( pData == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to create band arrays ... out of memory." ); return CE_Failure; } SetBand( nBandId, new MEMRasterBand( this, nBandId, pData, eType, nPixelSize, nPixelSize * GetRasterXSize(), TRUE ) ); return CE_None; } /* -------------------------------------------------------------------- */ /* Get layout of memory and other flags. */ /* -------------------------------------------------------------------- */ const char *pszOption; int nPixelOffset, nLineOffset; const char *pszDataPointer; pszDataPointer = CSLFetchNameValue(papszOptions,"DATAPOINTER"); pData = (GByte *) CPLScanPointer(pszDataPointer, strlen(pszDataPointer)); pszOption = CSLFetchNameValue(papszOptions,"PIXELOFFSET"); if( pszOption == NULL ) nPixelOffset = nPixelSize; else nPixelOffset = atoi(pszOption); pszOption = CSLFetchNameValue(papszOptions,"LINEOFFSET"); if( pszOption == NULL ) nLineOffset = GetRasterXSize() * nPixelOffset; else nLineOffset = atoi(pszOption); SetBand( nBandId, new MEMRasterBand( this, nBandId, pData, eType, nPixelOffset, nLineOffset, FALSE ) ); return CE_None; }
NDFDataset::~NDFDataset() { FlushCache(); CPLFree( pszProjection ); CSLDestroy( papszHeader ); CSLDestroy( papszExtraFiles ); for( int i = 0; i < GetRasterCount(); i++ ) { VSIFCloseL( ((RawRasterBand *) GetRasterBand(i+1))->GetFPL() ); } }
void GDALPamDataset::PamInitialize() { #ifdef PAM_ENABLED static const char *pszPamDefault = "YES"; #else static const char *pszPamDefault = "NO"; #endif if( psPam || (nPamFlags & GPF_DISABLED) ) return; if( !CSLTestBoolean( CPLGetConfigOption( "GDAL_PAM_ENABLED", pszPamDefault ) ) ) { nPamFlags |= GPF_DISABLED; return; } if( EQUAL( CPLGetConfigOption( "GDAL_PAM_MODE", "PAM" ), "AUX") ) nPamFlags |= GPF_AUXMODE; psPam = new GDALDatasetPamInfo; psPam->pszPamFilename = NULL; psPam->pszProjection = NULL; psPam->bHaveGeoTransform = FALSE; psPam->nGCPCount = 0; psPam->pasGCPList = NULL; psPam->pszGCPProjection = NULL; int iBand; for( iBand = 0; iBand < GetRasterCount(); iBand++ ) { GDALPamRasterBand *poBand = (GDALPamRasterBand *) GetRasterBand(iBand+1); if( poBand == NULL || !(poBand->GetMOFlags() & GMO_PAM_CLASS) ) continue; poBand->PamInitialize(); } }
CPLErr VRTDataset::AddBand( GDALDataType eType, char **papszOptions ) { int i; const char *pszSubClass = CSLFetchNameValue(papszOptions, "subclass"); bNeedsFlush = 1; /* ==================================================================== */ /* Handle a new raw band. */ /* ==================================================================== */ if( pszSubClass != NULL && EQUAL(pszSubClass,"VRTRawRasterBand") ) { int nWordDataSize = GDALGetDataTypeSize( eType ) / 8; vsi_l_offset nImageOffset = 0; int nPixelOffset = nWordDataSize; int nLineOffset = nWordDataSize * GetRasterXSize(); const char *pszFilename; const char *pszByteOrder = NULL; int bRelativeToVRT = FALSE; /* -------------------------------------------------------------------- */ /* Collect required information. */ /* -------------------------------------------------------------------- */ if( CSLFetchNameValue(papszOptions, "ImageOffset") != NULL ) nImageOffset = atoi(CSLFetchNameValue(papszOptions, "ImageOffset")); if( CSLFetchNameValue(papszOptions, "PixelOffset") != NULL ) nPixelOffset = atoi(CSLFetchNameValue(papszOptions,"PixelOffset")); if( CSLFetchNameValue(papszOptions, "LineOffset") != NULL ) nLineOffset = atoi(CSLFetchNameValue(papszOptions, "LineOffset")); if( CSLFetchNameValue(papszOptions, "ByteOrder") != NULL ) pszByteOrder = CSLFetchNameValue(papszOptions, "ByteOrder"); if( CSLFetchNameValue(papszOptions, "SourceFilename") != NULL ) pszFilename = CSLFetchNameValue(papszOptions, "SourceFilename"); else { CPLError( CE_Failure, CPLE_AppDefined, "AddBand() requires a SourceFilename option for VRTRawRasterBands." ); return CE_Failure; } bRelativeToVRT = CSLFetchBoolean( papszOptions, "RelativeToVRT", FALSE ); /* -------------------------------------------------------------------- */ /* Create and initialize the band. */ /* -------------------------------------------------------------------- */ CPLErr eErr; VRTRawRasterBand *poBand = new VRTRawRasterBand( this, GetRasterCount() + 1, eType ); eErr = poBand->SetRawLink( pszFilename, NULL, FALSE, nImageOffset, nPixelOffset, nLineOffset, pszByteOrder ); if( eErr != CE_None ) { delete poBand; return eErr; } SetBand( GetRasterCount() + 1, poBand ); return CE_None; } /* ==================================================================== */ /* Handle a new "sourced" band. */ /* ==================================================================== */ else { VRTSourcedRasterBand *poBand; /* ---- Check for our sourced band 'derived' subclass ---- */ if(pszSubClass != NULL && EQUAL(pszSubClass,"VRTDerivedRasterBand")) { /* We'll need a pointer to the subclass in case we need */ /* to set the new band's pixel function below. */ VRTDerivedRasterBand* poDerivedBand; poDerivedBand = new VRTDerivedRasterBand (this, GetRasterCount() + 1, eType, GetRasterXSize(), GetRasterYSize()); /* Set the pixel function options it provided. */ const char* pszFuncName = CSLFetchNameValue(papszOptions, "PixelFunctionType"); if (pszFuncName != NULL) poDerivedBand->SetPixelFunctionName(pszFuncName); const char* pszTransferTypeName = CSLFetchNameValue(papszOptions, "SourceTransferType"); if (pszTransferTypeName != NULL) { GDALDataType eTransferType = GDALGetDataTypeByName(pszTransferTypeName); if (eTransferType == GDT_Unknown) { CPLError( CE_Failure, CPLE_AppDefined, "invalid SourceTransferType: \"%s\".", pszTransferTypeName); delete poDerivedBand; return CE_Failure; } poDerivedBand->SetSourceTransferType(eTransferType); } /* We're done with the derived band specific stuff, so */ /* we can assigned the base class pointer now. */ poBand = poDerivedBand; } else { /* ---- Standard sourced band ---- */ poBand = new VRTSourcedRasterBand (this, GetRasterCount() + 1, eType, GetRasterXSize(), GetRasterYSize()); } SetBand( GetRasterCount() + 1, poBand ); for( i=0; papszOptions != NULL && papszOptions[i] != NULL; i++ ) { if( EQUALN(papszOptions[i],"AddFuncSource=", 14) ) { VRTImageReadFunc pfnReadFunc = NULL; void *pCBData = NULL; double dfNoDataValue = VRT_NODATA_UNSET; char **papszTokens = CSLTokenizeStringComplex( papszOptions[i]+14, ",", TRUE, FALSE ); if( CSLCount(papszTokens) < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "AddFuncSource() ... required argument missing." ); } sscanf( papszTokens[0], "%p", &pfnReadFunc ); if( CSLCount(papszTokens) > 1 ) sscanf( papszTokens[1], "%p", &pCBData ); if( CSLCount(papszTokens) > 2 ) dfNoDataValue = atof( papszTokens[2] ); poBand->AddFuncSource( pfnReadFunc, pCBData, dfNoDataValue ); } } return CE_None; } }
CPLErr RasterliteDataset::IBuildOverviews( const char * pszResampling, int nOverviews, int * panOverviewList, int nBands, int * panBandList, GDALProgressFunc pfnProgress, void * pProgressData ) { CPLErr eErr = CE_None; if (nLevel != 0) { CPLError(CE_Failure, CPLE_AppDefined, "Overviews can only be computed on the base dataset"); return CE_Failure; } if (osTableName.size() == 0) return CE_Failure; /* -------------------------------------------------------------------- */ /* If we don't have read access, then create the overviews */ /* externally. */ /* -------------------------------------------------------------------- */ if( GetAccess() != GA_Update ) { CPLDebug( "Rasterlite", "File open for read-only accessing, " "creating overviews externally." ); if (nResolutions != 1) { CPLError(CE_Failure, CPLE_NotSupported, "Cannot add external overviews to a " "dataset with internal overviews"); return CE_Failure; } bCheckForExistingOverview = FALSE; eErr = GDALDataset::IBuildOverviews( pszResampling, nOverviews, panOverviewList, nBands, panBandList, pfnProgress, pProgressData ); bCheckForExistingOverview = TRUE; return eErr; } /* -------------------------------------------------------------------- */ /* If zero overviews were requested, we need to clear all */ /* existing overviews. */ /* -------------------------------------------------------------------- */ if (nOverviews == 0) { return CleanOverviews(); } if( nBands != GetRasterCount() ) { CPLError( CE_Failure, CPLE_NotSupported, "Generation of overviews in RASTERLITE only" " supported when operating on all bands.\n" "Operation failed.\n" ); return CE_Failure; } const char* pszOvrOptions = CPLGetConfigOption("RASTERLITE_OVR_OPTIONS", NULL); char** papszOptions = (pszOvrOptions) ? CSLTokenizeString2( pszOvrOptions, ",", 0) : NULL; GDALValidateCreationOptions( GetDriver(), papszOptions); int i; for(i=0;i<nOverviews && eErr == CE_None;i++) { if (panOverviewList[i] <= 1) continue; eErr = CleanOverviewLevel(panOverviewList[i]); if (eErr == CE_None) eErr = CreateOverviewLevel(pszResampling, panOverviewList[i], papszOptions, pfnProgress, pProgressData); ReloadOverviews(); } CSLDestroy(papszOptions); return eErr; }
bool OsmAnd::HeightmapTileProvider_P::obtainData( const TileId tileId, const ZoomLevel zoom, std::shared_ptr<MapTiledData>& outTiledData, const IQueryController* const queryController) { // Obtain raw data from DB QByteArray data; bool ok = _tileDb.obtainTileData(tileId, zoom, data); if (!ok || data.length() == 0) { // There was no data at all, to avoid further requests, mark this tile as empty outTiledData.reset(); return true; } // We have the data, use GDAL to decode this GeoTIFF const auto tileSize = getTileSize(); bool success = false; QString vmemFilename; vmemFilename.sprintf("/vsimem/heightmapTile@%p", data.data()); VSIFileFromMemBuffer(qPrintable(vmemFilename), reinterpret_cast<GByte*>(data.data()), data.length(), FALSE); auto dataset = reinterpret_cast<GDALDataset*>(GDALOpen(qPrintable(vmemFilename), GA_ReadOnly)); if (dataset != nullptr) { bool bad = false; bad = bad || dataset->GetRasterCount() != 1; bad = bad || dataset->GetRasterXSize() != tileSize; bad = bad || dataset->GetRasterYSize() != tileSize; if (bad) { if (dataset->GetRasterCount() != 1) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %d bands instead of 1", tileId.x, tileId.y, zoom, dataset->GetRasterCount()); if (dataset->GetRasterXSize() != tileSize || dataset->GetRasterYSize() != tileSize) { LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %dx%x size instead of %d", tileId.x, tileId.y, zoom, dataset->GetRasterXSize(), dataset->GetRasterYSize(), tileSize); } } else { auto band = dataset->GetRasterBand(1); bad = bad || band->GetColorTable() != nullptr; bad = bad || band->GetRasterDataType() != GDT_Int16; if (bad) { if (band->GetColorTable() != nullptr) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has color table", tileId.x, tileId.y, zoom); if (band->GetRasterDataType() != GDT_Int16) LogPrintf(LogSeverityLevel::Error, "Height tile %dx%d@%d has %s data type in band 1", tileId.x, tileId.y, zoom, GDALGetDataTypeName(band->GetRasterDataType())); } else { auto buffer = new float[tileSize*tileSize]; auto res = dataset->RasterIO(GF_Read, 0, 0, tileSize, tileSize, buffer, tileSize, tileSize, GDT_Float32, 1, nullptr, 0, 0, 0); if (res != CE_None) { delete[] buffer; LogPrintf(LogSeverityLevel::Error, "Failed to decode height tile %dx%d@%d: %s", tileId.x, tileId.y, zoom, CPLGetLastErrorMsg()); } else { outTiledData.reset(new ElevationDataTile(buffer, sizeof(float)*tileSize, tileSize, tileId, zoom)); success = true; } } } GDALClose(dataset); } VSIUnlink(qPrintable(vmemFilename)); return success; }
CPLErr VRTWarpedDataset::IBuildOverviews( const char *pszResampling, int nOverviews, int *panOverviewList, int nListBands, int *panBandList, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Initial progress result. */ /* -------------------------------------------------------------------- */ if( !pfnProgress( 0.0, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Establish which of the overview levels we already have, and */ /* which are new. */ /* -------------------------------------------------------------------- */ int i, nNewOverviews, *panNewOverviewList = NULL; nNewOverviews = 0; panNewOverviewList = (int *) CPLCalloc(sizeof(int),nOverviews); for( i = 0; i < nOverviews; i++ ) { int j; for( j = 0; j < nOverviewCount; j++ ) { int nOvFactor; VRTWarpedDataset *poOverview = papoOverviews[j]; nOvFactor = (int) (0.5+GetRasterXSize() / (double) poOverview->GetRasterXSize()); if( nOvFactor == panOverviewList[i] || nOvFactor == GDALOvLevelAdjust( panOverviewList[i], GetRasterXSize() ) ) panOverviewList[i] *= -1; } if( panOverviewList[i] > 0 ) panNewOverviewList[nNewOverviews++] = panOverviewList[i]; } /* -------------------------------------------------------------------- */ /* Create each missing overview (we don't need to do anything */ /* to update existing overviews). */ /* -------------------------------------------------------------------- */ for( i = 0; i < nNewOverviews; i++ ) { int nOXSize, nOYSize, iBand; VWOTInfo *psInfo; VRTWarpedDataset *poOverviewDS; /* -------------------------------------------------------------------- */ /* What size should this overview be. */ /* -------------------------------------------------------------------- */ nOXSize = (GetRasterXSize() + panNewOverviewList[i] - 1) / panNewOverviewList[i]; nOYSize = (GetRasterYSize() + panNewOverviewList[i] - 1) / panNewOverviewList[i]; /* -------------------------------------------------------------------- */ /* Create the overview dataset. */ /* -------------------------------------------------------------------- */ poOverviewDS = new VRTWarpedDataset( nOXSize, nOYSize ); for( iBand = 0; iBand < GetRasterCount(); iBand++ ) { GDALRasterBand *poOldBand = GetRasterBand(iBand+1); VRTWarpedRasterBand *poNewBand = new VRTWarpedRasterBand( poOverviewDS, iBand+1, poOldBand->GetRasterDataType() ); poNewBand->CopyCommonInfoFrom( poOldBand ); poOverviewDS->SetBand( iBand+1, poNewBand ); } nOverviewCount++; papoOverviews = (VRTWarpedDataset **) CPLRealloc( papoOverviews, sizeof(void*) * nOverviewCount ); papoOverviews[nOverviewCount-1] = poOverviewDS; /* -------------------------------------------------------------------- */ /* Prepare update transformation information that will apply */ /* the overview decimation. */ /* -------------------------------------------------------------------- */ GDALWarpOptions *psWO = (GDALWarpOptions *) poWarper->GetOptions(); psInfo = (VWOTInfo *) CPLCalloc(sizeof(VWOTInfo),1); strcpy( psInfo->sTI.szSignature, "GTI" ); psInfo->sTI.pszClassName = "VRTWarpedOverviewTransform"; psInfo->sTI.pfnTransform = VRTWarpedOverviewTransform; psInfo->sTI.pfnCleanup = VRTWarpedOverviewCleanup; psInfo->sTI.pfnSerialize = NULL; psInfo->pfnBaseTransformer = psWO->pfnTransformer; psInfo->pBaseTransformerArg = psWO->pTransformerArg; psInfo->dfXOverviewFactor = GetRasterXSize() / (double) nOXSize; psInfo->dfYOverviewFactor = GetRasterYSize() / (double) nOYSize; /* -------------------------------------------------------------------- */ /* Initialize the new dataset with adjusted warp options, and */ /* then restore to original condition. */ /* -------------------------------------------------------------------- */ psWO->pfnTransformer = VRTWarpedOverviewTransform; psWO->pTransformerArg = psInfo; poOverviewDS->Initialize( psWO ); psWO->pfnTransformer = psInfo->pfnBaseTransformer; psWO->pTransformerArg = psInfo->pBaseTransformerArg; } CPLFree( panNewOverviewList ); /* -------------------------------------------------------------------- */ /* Progress finished. */ /* -------------------------------------------------------------------- */ pfnProgress( 1.0, NULL, pProgressData ); SetNeedsFlush(); return CE_None; }
CPLErr GDALPamDataset::TryLoadAux() { /* -------------------------------------------------------------------- */ /* Initialize PAM. */ /* -------------------------------------------------------------------- */ PamInitialize(); if( psPam == NULL ) return CE_None; /* -------------------------------------------------------------------- */ /* What is the name of the physical file we are referencing? */ /* We allow an override via the psPam->pszPhysicalFile item. */ /* -------------------------------------------------------------------- */ const char *pszPhysicalFile = psPam->osPhysicalFilename; if( strlen(pszPhysicalFile) == 0 && GetDescription() != NULL ) pszPhysicalFile = GetDescription(); if( strlen(pszPhysicalFile) == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Try to open .aux file. */ /* -------------------------------------------------------------------- */ GDALDataset *poAuxDS = GDALFindAssociatedAuxFile( pszPhysicalFile, GA_ReadOnly, this ); if( poAuxDS == NULL ) return CE_None; /* -------------------------------------------------------------------- */ /* Do we have an SRS on the aux file? */ /* -------------------------------------------------------------------- */ if( strlen(poAuxDS->GetProjectionRef()) > 0 ) GDALPamDataset::SetProjection( poAuxDS->GetProjectionRef() ); /* -------------------------------------------------------------------- */ /* Geotransform. */ /* -------------------------------------------------------------------- */ if( poAuxDS->GetGeoTransform( psPam->adfGeoTransform ) == CE_None ) psPam->bHaveGeoTransform = TRUE; /* -------------------------------------------------------------------- */ /* GCPs */ /* -------------------------------------------------------------------- */ if( poAuxDS->GetGCPCount() > 0 ) { psPam->nGCPCount = poAuxDS->GetGCPCount(); psPam->pasGCPList = GDALDuplicateGCPs( psPam->nGCPCount, poAuxDS->GetGCPs() ); } /* -------------------------------------------------------------------- */ /* Apply metadata. We likely ought to be merging this in rather */ /* than overwriting everything that was there. */ /* -------------------------------------------------------------------- */ char **papszMD = poAuxDS->GetMetadata(); if( CSLCount(papszMD) > 0 ) { char **papszMerged = CSLMerge( CSLDuplicate(GetMetadata()), papszMD ); GDALPamDataset::SetMetadata( papszMerged ); CSLDestroy( papszMerged ); } papszMD = poAuxDS->GetMetadata("XFORMS"); if( CSLCount(papszMD) > 0 ) { char **papszMerged = CSLMerge( CSLDuplicate(GetMetadata("XFORMS")), papszMD ); GDALPamDataset::SetMetadata( papszMerged, "XFORMS" ); CSLDestroy( papszMerged ); } /* ==================================================================== */ /* Process bands. */ /* ==================================================================== */ int iBand; for( iBand = 0; iBand < poAuxDS->GetRasterCount(); iBand++ ) { if( iBand >= GetRasterCount() ) break; GDALRasterBand *poAuxBand = poAuxDS->GetRasterBand( iBand+1 ); GDALRasterBand *poBand = GetRasterBand( iBand+1 ); papszMD = poAuxBand->GetMetadata(); if( CSLCount(papszMD) > 0 ) { char **papszMerged = CSLMerge( CSLDuplicate(poBand->GetMetadata()), papszMD ); poBand->SetMetadata( papszMerged ); CSLDestroy( papszMerged ); } if( poAuxBand->GetCategoryNames() != NULL ) poBand->SetCategoryNames( poAuxBand->GetCategoryNames() ); if( poAuxBand->GetColorTable() != NULL && poBand->GetColorTable() == NULL ) poBand->SetColorTable( poAuxBand->GetColorTable() ); // histograms? double dfMin, dfMax; int nBuckets, *panHistogram=NULL; if( poAuxBand->GetDefaultHistogram( &dfMin, &dfMax, &nBuckets, &panHistogram, FALSE, NULL, NULL ) == CE_None ) { poBand->SetDefaultHistogram( dfMin, dfMax, nBuckets, panHistogram ); CPLFree( panHistogram ); } // RAT if( poAuxBand->GetDefaultRAT() != NULL ) poBand->SetDefaultRAT( poAuxBand->GetDefaultRAT() ); // NoData int bSuccess = FALSE; double dfNoDataValue = poAuxBand->GetNoDataValue( &bSuccess ); if( bSuccess ) poBand->SetNoDataValue( dfNoDataValue ); } GDALClose( poAuxDS ); /* -------------------------------------------------------------------- */ /* Mark PAM info as clean. */ /* -------------------------------------------------------------------- */ nPamFlags &= ~GPF_DIRTY; return CE_Failure; }
CPLErr MEMDataset::AddBand( GDALDataType eType, char **papszOptions ) { const int nBandId = GetRasterCount() + 1; const GSpacing nPixelSize = GDALGetDataTypeSizeBytes(eType); /* -------------------------------------------------------------------- */ /* Do we need to allocate the memory ourselves? This is the */ /* simple case. */ /* -------------------------------------------------------------------- */ if( CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL ) { const GSpacing nTmp = nPixelSize * GetRasterXSize(); GByte *pData = NULL; #if SIZEOF_VOIDP == 4 if( nTmp > INT_MAX ) pData = NULL; else #endif pData = reinterpret_cast<GByte *>( VSI_CALLOC_VERBOSE((size_t)nTmp, GetRasterYSize() ) ); if( pData == NULL ) { return CE_Failure; } SetBand( nBandId, new MEMRasterBand( this, nBandId, pData, eType, nPixelSize, nPixelSize * GetRasterXSize(), TRUE ) ); return CE_None; } /* -------------------------------------------------------------------- */ /* Get layout of memory and other flags. */ /* -------------------------------------------------------------------- */ const char *pszDataPointer = CSLFetchNameValue(papszOptions, "DATAPOINTER"); GByte *pData = reinterpret_cast<GByte *>( CPLScanPointer( pszDataPointer, static_cast<int>(strlen(pszDataPointer)) ) ); const char *pszOption = CSLFetchNameValue(papszOptions, "PIXELOFFSET"); GSpacing nPixelOffset; if( pszOption == NULL ) nPixelOffset = nPixelSize; else nPixelOffset = CPLAtoGIntBig(pszOption); pszOption = CSLFetchNameValue(papszOptions, "LINEOFFSET"); GSpacing nLineOffset; if( pszOption == NULL ) nLineOffset = GetRasterXSize() * static_cast<size_t>( nPixelOffset ); else nLineOffset = CPLAtoGIntBig(pszOption); SetBand( nBandId, new MEMRasterBand( this, nBandId, pData, eType, nPixelOffset, nLineOffset, FALSE ) ); return CE_None; }
CPLErr GDALPamDataset::CloneInfo( GDALDataset *poSrcDS, int nCloneFlags ) { int bOnlyIfMissing = nCloneFlags & GCIF_ONLY_IF_MISSING; int nSavedMOFlags = GetMOFlags(); PamInitialize(); /* -------------------------------------------------------------------- */ /* Supress NotImplemented error messages - mainly needed if PAM */ /* disabled. */ /* -------------------------------------------------------------------- */ SetMOFlags( nSavedMOFlags | GMO_IGNORE_UNIMPLEMENTED ); /* -------------------------------------------------------------------- */ /* GeoTransform */ /* -------------------------------------------------------------------- */ if( nCloneFlags & GCIF_GEOTRANSFORM ) { double adfGeoTransform[6]; if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None ) { double adfOldGT[6]; if( !bOnlyIfMissing || GetGeoTransform( adfOldGT ) != CE_None ) SetGeoTransform( adfGeoTransform ); } } /* -------------------------------------------------------------------- */ /* Projection */ /* -------------------------------------------------------------------- */ if( nCloneFlags & GCIF_PROJECTION ) { const char *pszWKT = poSrcDS->GetProjectionRef(); if( pszWKT != NULL && strlen(pszWKT) > 0 ) { if( !bOnlyIfMissing || GetProjectionRef() == NULL || strlen(GetProjectionRef()) == 0 ) SetProjection( pszWKT ); } } /* -------------------------------------------------------------------- */ /* GCPs */ /* -------------------------------------------------------------------- */ if( nCloneFlags & GCIF_GCPS ) { if( poSrcDS->GetGCPCount() > 0 ) { if( !bOnlyIfMissing || GetGCPCount() == 0 ) { SetGCPs( poSrcDS->GetGCPCount(), poSrcDS->GetGCPs(), poSrcDS->GetGCPProjection() ); } } } /* -------------------------------------------------------------------- */ /* Metadata */ /* -------------------------------------------------------------------- */ if( nCloneFlags & GCIF_METADATA ) { if( poSrcDS->GetMetadata() != NULL ) { if( !bOnlyIfMissing || CSLCount(GetMetadata()) != CSLCount(poSrcDS->GetMetadata()) ) { SetMetadata( poSrcDS->GetMetadata() ); } } if( poSrcDS->GetMetadata("RPC") != NULL ) { if( !bOnlyIfMissing || CSLCount(GetMetadata("RPC")) != CSLCount(poSrcDS->GetMetadata("RPC")) ) { SetMetadata( poSrcDS->GetMetadata("RPC"), "RPC" ); } } } /* -------------------------------------------------------------------- */ /* Process bands. */ /* -------------------------------------------------------------------- */ if( nCloneFlags & GCIF_PROCESS_BANDS ) { int iBand; for( iBand = 0; iBand < GetRasterCount(); iBand++ ) { GDALPamRasterBand *poBand = (GDALPamRasterBand *) GetRasterBand(iBand+1); if( poBand == NULL || !(poBand->GetMOFlags() & GMO_PAM_CLASS) ) continue; if( poSrcDS->GetRasterCount() >= iBand+1 ) poBand->CloneInfo( poSrcDS->GetRasterBand(iBand+1), nCloneFlags ); else CPLDebug( "GDALPamDataset", "Skipping CloneInfo for band not in source, this is a bit unusual!" ); } } /* -------------------------------------------------------------------- */ /* Copy masks. These are really copied at a lower level using */ /* GDALDefaultOverviews, for formats with no native mask */ /* support but this is a convenient central point to put this */ /* for most drivers. */ /* -------------------------------------------------------------------- */ if( nCloneFlags & GCIF_MASK ) { GDALDriver::DefaultCopyMasks( poSrcDS, this, FALSE ); } /* -------------------------------------------------------------------- */ /* Restore MO flags. */ /* -------------------------------------------------------------------- */ SetMOFlags( nSavedMOFlags ); return CE_None; }
CPLErr GDALPamDataset::XMLInit( CPLXMLNode *psTree, const char *pszVRTPath ) { /* -------------------------------------------------------------------- */ /* Check for an SRS node. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetXMLValue(psTree, "SRS", "")) > 0 ) { OGRSpatialReference oSRS; CPLFree( psPam->pszProjection ); psPam->pszProjection = NULL; if( oSRS.SetFromUserInput( CPLGetXMLValue(psTree, "SRS", "") ) == OGRERR_NONE ) oSRS.exportToWkt( &(psPam->pszProjection) ); } /* -------------------------------------------------------------------- */ /* Check for a GeoTransform node. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetXMLValue(psTree, "GeoTransform", "")) > 0 ) { const char *pszGT = CPLGetXMLValue(psTree, "GeoTransform", ""); char **papszTokens; papszTokens = CSLTokenizeStringComplex( pszGT, ",", FALSE, FALSE ); if( CSLCount(papszTokens) != 6 ) { CPLError( CE_Warning, CPLE_AppDefined, "GeoTransform node does not have expected six values."); } else { for( int iTA = 0; iTA < 6; iTA++ ) psPam->adfGeoTransform[iTA] = atof(papszTokens[iTA]); psPam->bHaveGeoTransform = TRUE; } CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { CPLXMLNode *psXMLGCP; OGRSpatialReference oSRS; const char *pszRawProj = CPLGetXMLValue(psGCPList, "Projection", ""); CPLFree( psPam->pszGCPProjection ); if( strlen(pszRawProj) > 0 && oSRS.SetFromUserInput( pszRawProj ) == OGRERR_NONE ) oSRS.exportToWkt( &(psPam->pszGCPProjection) ); else psPam->pszGCPProjection = CPLStrdup(""); // Count GCPs. int nGCPMax = 0; for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) nGCPMax++; psPam->pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax); for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) { GDAL_GCP *psGCP = psPam->pasGCPList + psPam->nGCPCount; if( !EQUAL(psXMLGCP->pszValue,"GCP") || psXMLGCP->eType != CXT_Element ) continue; GDALInitGCPs( 1, psGCP ); CPLFree( psGCP->pszId ); psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id","")); CPLFree( psGCP->pszInfo ); psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info","")); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0")); psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0")); psPam->nGCPCount++; } } /* -------------------------------------------------------------------- */ /* Apply any dataset level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Process bands. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psBandTree; for( psBandTree = psTree->psChild; psBandTree != NULL; psBandTree = psBandTree->psNext ) { if( psBandTree->eType != CXT_Element || !EQUAL(psBandTree->pszValue,"PAMRasterBand") ) continue; int nBand = atoi(CPLGetXMLValue( psBandTree, "band", "0")); if( nBand < 1 || nBand > GetRasterCount() ) continue; GDALPamRasterBand *poBand = (GDALPamRasterBand *) GetRasterBand(nBand); if( poBand == NULL || !(poBand->GetMOFlags() & GMO_PAM_CLASS) ) continue; poBand->XMLInit( psBandTree, pszVRTPath ); } /* -------------------------------------------------------------------- */ /* Clear dirty flag. */ /* -------------------------------------------------------------------- */ nPamFlags &= ~GPF_DIRTY; return CE_None; }
CPLXMLNode *GDALPamDataset::SerializeToXML( const char *pszVRTPath ) { CPLString oFmt; if( psPam == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Setup root node and attributes. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDSTree; psDSTree = CPLCreateXMLNode( NULL, CXT_Element, "PAMDataset" ); /* -------------------------------------------------------------------- */ /* SRS */ /* -------------------------------------------------------------------- */ if( psPam->pszProjection != NULL && strlen(psPam->pszProjection) > 0 ) CPLSetXMLValue( psDSTree, "SRS", psPam->pszProjection ); /* -------------------------------------------------------------------- */ /* GeoTransform. */ /* -------------------------------------------------------------------- */ if( psPam->bHaveGeoTransform ) { CPLSetXMLValue( psDSTree, "GeoTransform", oFmt.Printf( "%24.16e,%24.16e,%24.16e,%24.16e,%24.16e,%24.16e", psPam->adfGeoTransform[0], psPam->adfGeoTransform[1], psPam->adfGeoTransform[2], psPam->adfGeoTransform[3], psPam->adfGeoTransform[4], psPam->adfGeoTransform[5] ) ); } /* -------------------------------------------------------------------- */ /* Metadata. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMD; psMD = oMDMD.Serialize(); if( psMD != NULL ) { if( psMD->psChild == NULL ) CPLDestroyXMLNode( psMD ); else CPLAddXMLChild( psDSTree, psMD ); } /* -------------------------------------------------------------------- */ /* GCPs */ /* -------------------------------------------------------------------- */ if( psPam->nGCPCount > 0 ) { CPLXMLNode *psPamGCPList = CPLCreateXMLNode( psDSTree, CXT_Element, "GCPList" ); if( psPam->pszGCPProjection != NULL && strlen(psPam->pszGCPProjection) > 0 ) CPLSetXMLValue( psPamGCPList, "#Projection", psPam->pszGCPProjection ); for( int iGCP = 0; iGCP < psPam->nGCPCount; iGCP++ ) { CPLXMLNode *psXMLGCP; GDAL_GCP *psGCP = psPam->pasGCPList + iGCP; psXMLGCP = CPLCreateXMLNode( psPamGCPList, CXT_Element, "GCP" ); CPLSetXMLValue( psXMLGCP, "#Id", psGCP->pszId ); if( psGCP->pszInfo != NULL && strlen(psGCP->pszInfo) > 0 ) CPLSetXMLValue( psXMLGCP, "Info", psGCP->pszInfo ); CPLSetXMLValue( psXMLGCP, "#Pixel", oFmt.Printf( "%.4f", psGCP->dfGCPPixel ) ); CPLSetXMLValue( psXMLGCP, "#Line", oFmt.Printf( "%.4f", psGCP->dfGCPLine ) ); CPLSetXMLValue( psXMLGCP, "#X", oFmt.Printf( "%.12E", psGCP->dfGCPX ) ); CPLSetXMLValue( psXMLGCP, "#Y", oFmt.Printf( "%.12E", psGCP->dfGCPY ) ); if( psGCP->dfGCPZ != 0.0 ) CPLSetXMLValue( psXMLGCP, "#GCPZ", oFmt.Printf( "%.12E", psGCP->dfGCPZ ) ); } } /* -------------------------------------------------------------------- */ /* Process bands. */ /* -------------------------------------------------------------------- */ int iBand; for( iBand = 0; iBand < GetRasterCount(); iBand++ ) { CPLXMLNode *psBandTree; GDALPamRasterBand *poBand = (GDALPamRasterBand *) GetRasterBand(iBand+1); if( poBand == NULL || !(poBand->GetMOFlags() & GMO_PAM_CLASS) ) continue; psBandTree = poBand->SerializeToXML( pszVRTPath ); if( psBandTree != NULL ) CPLAddXMLChild( psDSTree, psBandTree ); } /* -------------------------------------------------------------------- */ /* We don't want to return anything if we had no metadata to */ /* attach. */ /* -------------------------------------------------------------------- */ if( psDSTree->psChild == NULL ) { CPLDestroyXMLNode( psDSTree ); psDSTree = NULL; } return psDSTree; }
CPLErr RasterliteDataset::IBuildOverviews( const char * pszResampling, int nOverviews, int * panOverviewList, int nBands, int * panBandList, GDALProgressFunc pfnProgress, void * pProgressData ) { CPLErr eErr = CE_None; if (nLevel != 0) { CPLError(CE_Failure, CPLE_AppDefined, "Overviews can only be computed on the base dataset"); return CE_Failure; } if (osTableName.size() == 0) return CE_Failure; /* -------------------------------------------------------------------- */ /* If we don't have read access, then create the overviews */ /* externally. */ /* -------------------------------------------------------------------- */ if( GetAccess() != GA_Update ) { CPLDebug( "Rasterlite", "File open for read-only accessing, " "creating overviews externally." ); if (nResolutions != 1) { CPLError(CE_Failure, CPLE_NotSupported, "Cannot add external overviews to a " "dataset with internal overviews"); return CE_Failure; } bCheckForExistingOverview = FALSE; eErr = GDALDataset::IBuildOverviews( pszResampling, nOverviews, panOverviewList, nBands, panBandList, pfnProgress, pProgressData ); bCheckForExistingOverview = TRUE; return eErr; } /* -------------------------------------------------------------------- */ /* If zero overviews were requested, we need to clear all */ /* existing overviews. */ /* -------------------------------------------------------------------- */ if (nOverviews == 0) { return CleanOverviews(); } if( nBands != GetRasterCount() ) { CPLError( CE_Failure, CPLE_NotSupported, "Generation of overviews in RASTERLITE only" " supported when operating on all bands.\n" "Operation failed.\n" ); return CE_Failure; } if( !EQUALN(pszResampling, "NEAR", 4)) { CPLError( CE_Failure, CPLE_NotSupported, "Only NEAREST resampling is allowed for now " "for RASTERLITE overviews"); return CE_Failure; } int i; for(i=0;i<nOverviews && eErr == CE_None;i++) { if (panOverviewList[i] <= 1) continue; eErr = CleanOverviewLevel(panOverviewList[i]); if (eErr == CE_None) eErr = CreateOverviewLevel(panOverviewList[i], pfnProgress, pProgressData); ReloadOverviews(); } return eErr; }
void ROIPACDataset::FlushCache( void ) { RawDataset::FlushCache(); GDALRasterBand *band = (GetRasterCount() > 0) ? GetRasterBand(1) : NULL; if ( eAccess == GA_ReadOnly || band == NULL ) return; // If opening an existing file in Update mode (i.e. "r+") we need to make // sure any existing content is cleared, otherwise the file may contain // trailing content from the previous write. CPL_IGNORE_RET_VAL(VSIFTruncateL( fpRsc, 0 )); CPL_IGNORE_RET_VAL(VSIFSeekL( fpRsc, 0, SEEK_SET )); /* -------------------------------------------------------------------- */ /* Rewrite out the header. */ /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ /* Raster dimensions. */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %d\n", "WIDTH", nRasterXSize )); CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %d\n", "FILE_LENGTH", nRasterYSize )); /* -------------------------------------------------------------------- */ /* Georeferencing. */ /* -------------------------------------------------------------------- */ if ( pszProjection != NULL ) { char *pszProjectionTmp = pszProjection; OGRSpatialReference oSRS; if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE ) { int bNorth; int iUTMZone = oSRS.GetUTMZone( &bNorth ); if ( iUTMZone != 0 ) { CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s%d\n", "PROJECTION", "UTM", iUTMZone )); } else if ( oSRS.IsGeographic() ) { CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "PROJECTION", "LL" )); } else { CPLError( CE_Warning, CPLE_AppDefined, "ROI_PAC format only support Latitude/Longitude and " "UTM projections, discarding projection."); } if ( oSRS.GetAttrValue( "DATUM" ) != NULL ) { if ( strcmp( oSRS.GetAttrValue( "DATUM" ), "WGS_1984" ) == 0 ) { CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "DATUM", "WGS84" )); } else { CPLError( CE_Warning, CPLE_AppDefined, "Datum \"%s\" probably not supported in the " "ROI_PAC format, saving it anyway", oSRS.GetAttrValue( "DATUM" ) ); CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "DATUM", oSRS.GetAttrValue( "DATUM" ) )); } } if ( oSRS.GetAttrValue( "UNIT" ) != NULL ) { CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "X_UNIT", oSRS.GetAttrValue( "UNIT" ) )); CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", "Y_UNIT", oSRS.GetAttrValue( "UNIT" ) )); } } } if( bValidGeoTransform ) { if ( adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0 ) { CPLError( CE_Warning, CPLE_AppDefined, "ROI_PAC format do not support geotransform with " "rotation, discarding info."); } else { CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "X_FIRST", adfGeoTransform[0] )); CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "X_STEP", adfGeoTransform[1] )); CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Y_FIRST", adfGeoTransform[3] )); CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Y_STEP", adfGeoTransform[5] )); CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Z_OFFSET", band->GetOffset(NULL) )); CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Z_SCALE", band->GetScale(NULL) )); } } /* -------------------------------------------------------------------- */ /* Metadata stored in the ROI_PAC domain. */ /* -------------------------------------------------------------------- */ char** papszROIPACMetadata = GetMetadata( "ROI_PAC" ); for (int i = 0; i < CSLCount( papszROIPACMetadata ); i++) { /* Get the tokens from the metadata item */ char **papszTokens = CSLTokenizeString2( papszROIPACMetadata[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if ( CSLCount( papszTokens ) != 2 ) { CPLDebug("ROI_PAC", "Line of header file could not be split at = into two elements: %s", papszROIPACMetadata[i]); CSLDestroy( papszTokens ); continue; } /* Don't write it out if it is one of the bits of metadata that is * written out elsewhere in this routine */ if ( strcmp( papszTokens[0], "WIDTH" ) == 0 || strcmp( papszTokens[0], "FILE_LENGTH" ) == 0 ) { CSLDestroy( papszTokens ); continue; } CPL_IGNORE_RET_VAL(VSIFPrintfL( fpRsc, "%-40s %s\n", papszTokens[0], papszTokens[1] )); CSLDestroy( papszTokens ); } }
void ISCEDataset::FlushCache( void ) { RawDataset::FlushCache(); GDALRasterBand *band = (GetRasterCount() > 0) ? GetRasterBand(1) : NULL; if ( eAccess == GA_ReadOnly || band == NULL ) return; /* -------------------------------------------------------------------- */ /* Recreate a XML doc with the dataset information. */ /* -------------------------------------------------------------------- */ char sBuf[64]; CPLXMLNode *psDocNode = CPLCreateXMLNode( NULL, CXT_Element, "imageFile" ); CPLXMLNode *psTmpNode = CPLCreateXMLNode( psDocNode, CXT_Element, "property" ); CPLAddXMLAttributeAndValue( psTmpNode, "name", "WIDTH" ); snprintf(sBuf, sizeof(sBuf), "%d", nRasterXSize); CPLCreateXMLElementAndValue( psTmpNode, "value", sBuf ); psTmpNode = CPLCreateXMLNode( psDocNode, CXT_Element, "property" ); CPLAddXMLAttributeAndValue( psTmpNode, "name", "LENGTH" ); snprintf(sBuf, sizeof(sBuf), "%d", nRasterYSize); CPLCreateXMLElementAndValue( psTmpNode, "value", sBuf ); psTmpNode = CPLCreateXMLNode( psDocNode, CXT_Element, "property" ); CPLAddXMLAttributeAndValue( psTmpNode, "name", "NUMBER_BANDS" ); snprintf(sBuf, sizeof(sBuf), "%d", nBands); CPLCreateXMLElementAndValue( psTmpNode, "value", sBuf ); const char *sType = GDALGetDataTypeName( band->GetRasterDataType() ); psTmpNode = CPLCreateXMLNode( psDocNode, CXT_Element, "property" ); CPLAddXMLAttributeAndValue( psTmpNode, "name", "DATA_TYPE" ); CPLCreateXMLElementAndValue( psTmpNode, "value", CSLFetchNameValue( (char **)apszGDAL2ISCEDatatypes, sType ) ); const char *sScheme = apszSchemeNames[eScheme]; psTmpNode = CPLCreateXMLNode( psDocNode, CXT_Element, "property" ); CPLAddXMLAttributeAndValue( psTmpNode, "name", "SCHEME" ); CPLCreateXMLElementAndValue( psTmpNode, "value", sScheme ); psTmpNode = CPLCreateXMLNode( psDocNode, CXT_Element, "property" ); CPLAddXMLAttributeAndValue( psTmpNode, "name", "BYTE_ORDER" ); #ifdef CPL_LSB CPLCreateXMLElementAndValue( psTmpNode, "value", "l" ); #else CPLCreateXMLElementAndValue( psTmpNode, "value", "b" ); #endif /* -------------------------------------------------------------------- */ /* Then, add the ISCE domain metadata. */ /* -------------------------------------------------------------------- */ char **papszISCEMetadata = GetMetadata( "ISCE" ); for (int i = 0; i < CSLCount( papszISCEMetadata ); i++) { /* Get the tokens from the metadata item */ char **papszTokens = CSLTokenizeString2( papszISCEMetadata[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if ( CSLCount( papszTokens ) != 2 ) { CPLDebug( "ISCE", "Line of header file could not be split at = into two" " elements: %s", papszISCEMetadata[i] ); CSLDestroy( papszTokens ); continue; } /* Don't write it out if it is one of the bits of metadata that is * written out elsewhere in this routine */ if ( strcmp( papszTokens[0], "WIDTH" ) == 0 || strcmp( papszTokens[0], "LENGTH" ) == 0 || strcmp( papszTokens[0], "NUMBER_BANDS" ) == 0 || strcmp( papszTokens[0], "DATA_TYPE" ) == 0 || strcmp( papszTokens[0], "SCHEME" ) == 0 || strcmp( papszTokens[0], "BYTE_ORDER" ) == 0 ) { CSLDestroy( papszTokens ); continue; } psTmpNode = CPLCreateXMLNode( psDocNode, CXT_Element, "property" ); CPLAddXMLAttributeAndValue( psTmpNode, "name", papszTokens[0] ); CPLCreateXMLElementAndValue( psTmpNode, "value", papszTokens[1] ); CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Write the XML file. */ /* -------------------------------------------------------------------- */ CPLSerializeXMLTreeToFile( psDocNode, pszXMLFilename ); /* -------------------------------------------------------------------- */ /* Free the XML Doc. */ /* -------------------------------------------------------------------- */ CPLDestroyXMLNode( psDocNode ); }