GDALDataset *SAGADataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "SAGA driver does not support source dataset with zero band.\n"); return NULL; } else if (nBands > 1) { if( bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "Unable to create copy, SAGA Binary Grid " "format only supports one raster band.\n" ); return NULL; } else CPLError( CE_Warning, CPLE_NotSupported, "SAGA Binary Grid format only supports one " "raster band, first band will be copied.\n" ); } GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); char** papszCreateOptions = NULL; papszCreateOptions = CSLSetNameValue(papszCreateOptions, "FILL_NODATA", "NO"); int bHasNoDataValue = FALSE; double dfNoDataValue = poSrcBand->GetNoDataValue(&bHasNoDataValue); if (bHasNoDataValue) papszCreateOptions = CSLSetNameValue(papszCreateOptions, "NODATA_VALUE", CPLSPrintf("%.16g", dfNoDataValue)); GDALDataset* poDstDS = Create(pszFilename, poSrcBand->GetXSize(), poSrcBand->GetYSize(), 1, poSrcBand->GetRasterDataType(), papszCreateOptions); CSLDestroy(papszCreateOptions); if (poDstDS == NULL) return NULL; /* -------------------------------------------------------------------- */ /* Copy band data. */ /* -------------------------------------------------------------------- */ CPLErr eErr; eErr = GDALDatasetCopyWholeRaster( (GDALDatasetH) poSrcDS, (GDALDatasetH) poDstDS, NULL, pfnProgress, pProgressData ); if (eErr == CE_Failure) { delete poDstDS; return NULL; } double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); poDstDS->SetGeoTransform( adfGeoTransform ); poDstDS->SetProjection( poSrcDS->GetProjectionRef() ); return poDstDS; }
GDALDataset* SIGDEMDataset::CreateCopy( const char * pszFilename, GDALDataset * poSrcDS, int /*bStrict*/, char ** /*papszOptions*/, GDALProgressFunc pfnProgress, void * pProgressData) { const int nBands = poSrcDS->GetRasterCount(); double adfGeoTransform[6] = { }; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM driver requires a valid GeoTransform."); return nullptr; } if (nBands != 1) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM driver doesn't support %d bands. Must be 1 band.", nBands); return nullptr; } VSILFILE *fp = VSIFOpenL(pszFilename, "wb"); if (fp == nullptr) { CPLError(CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed.", pszFilename); return nullptr; } GDALRasterBand* band = poSrcDS->GetRasterBand(1); const char* pszProjection = poSrcDS->GetProjectionRef(); int32_t nCols = poSrcDS->GetRasterXSize(); int32_t nRows = poSrcDS->GetRasterYSize(); int32_t nCoordinateSystemId = GetCoordinateSystemId(pszProjection); SIGDEMHeader sHeader; sHeader.nCoordinateSystemId = nCoordinateSystemId; sHeader.dfMinX = adfGeoTransform[0]; const char* pszMin = band->GetMetadataItem("STATISTICS_MINIMUM"); if (pszMin == nullptr) { sHeader.dfMinZ = -10000; } else { sHeader.dfMinZ = CPLAtof(pszMin); } sHeader.dfMaxY = adfGeoTransform[3]; const char* pszMax = band->GetMetadataItem("STATISTICS_MAXIMUM"); if (pszMax == nullptr) { sHeader.dfMaxZ = 10000; } else { sHeader.dfMaxZ = CPLAtof(pszMax); } sHeader.nCols = poSrcDS->GetRasterXSize(); sHeader.nRows = poSrcDS->GetRasterYSize(); sHeader.dfXDim = adfGeoTransform[1]; sHeader.dfYDim = -adfGeoTransform[5]; sHeader.dfMaxX = sHeader.dfMinX + sHeader.nCols * sHeader.dfXDim; sHeader.dfMinY = sHeader.dfMaxY - sHeader.nRows * sHeader.dfYDim; sHeader.dfOffsetX = sHeader.dfMinX; sHeader.dfOffsetY = sHeader.dfMinY; if( !sHeader.Write(fp) ) { VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } // Write fill with all NO_DATA values int32_t* row = static_cast<int32_t*>(VSI_MALLOC2_VERBOSE(nCols, sizeof(int32_t))); if( !row ) { VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } std::fill(row, row + nCols, CPL_MSBWORD32(NO_DATA)); for (int i = 0; i < nRows; i++) { if( VSIFWriteL(row, CELL_SIZE_FILE, nCols, fp) != static_cast<size_t>(nCols) ) { VSIFree(row); VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } } VSIFree(row); if (VSIFCloseL(fp) != 0) { return nullptr; } if (nCoordinateSystemId <= 0) { if (!EQUAL(pszProjection, "")) { CPLString osPrjFilename = CPLResetExtension(pszFilename, "prj"); VSILFILE *fpProj = VSIFOpenL(osPrjFilename, "wt"); if (fpProj != nullptr) { OGRSpatialReference oSRS; oSRS.importFromWkt(pszProjection); oSRS.morphToESRI(); char *pszESRIProjection = nullptr; oSRS.exportToWkt(&pszESRIProjection); CPL_IGNORE_RET_VAL( VSIFWriteL(pszESRIProjection, 1, strlen(pszESRIProjection), fpProj)); CPL_IGNORE_RET_VAL(VSIFCloseL(fpProj)); CPLFree(pszESRIProjection); } else { CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.", osPrjFilename.c_str()); } } } GDALOpenInfo oOpenInfo(pszFilename, GA_Update); GDALDataset * poDstDS = Open(&oOpenInfo); if (poDstDS != nullptr && GDALDatasetCopyWholeRaster(poSrcDS, poDstDS, nullptr, pfnProgress, pProgressData) == OGRERR_NONE) { return poDstDS; } else { VSIUnlink(pszFilename); return nullptr; } }