void toprsGadlReader::getMaxSize( int resLevel,int& maxX, int& maxY ) const { int aGdalBandIndex = 0; maxX = 0; maxY = 0; //if(theOverview.valid() && theOverview->isValidRLevel(resLevel))// xizhi { //toprsIRect rect = theOverview->getBoundingRect(resLevel);//xizhi toprsIRect rect = getBoundingRect(resLevel); if(!rect.hasNAN()) { maxX = rect.width(); maxY = rect.height(); } return; } for(aGdalBandIndex=1; (int)aGdalBandIndex <= (int)GDALGetRasterCount(theDataset); ++aGdalBandIndex) { GDALRasterBandH aBand = resolveRasterBand(resLevel, aGdalBandIndex); if(aBand) { maxY = toprs::max<int>((int)GDALGetRasterBandYSize(aBand), maxY); maxX = toprs::max<int>((int)GDALGetRasterBandXSize(aBand), maxX); } else { break; } } }
extern "C" int CPL_STDCALL GDALComputeMedianCutPCT( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, int (*pfnIncludePixel)(int, int, void*), int nColors, GDALColorTableH hColorTable, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALComputeMedianCutPCT", CE_Failure ); const int nXSize = GDALGetRasterBandXSize( hRed ); const int nYSize = GDALGetRasterBandYSize( hRed ); if( nYSize == 0 ) return CE_Failure; if( static_cast<GUInt32>(nXSize) < UINT_MAX / static_cast<GUInt32>(nYSize) ) { return GDALComputeMedianCutPCTInternal(hRed, hGreen, hBlue, NULL, NULL, NULL, pfnIncludePixel, nColors, 5, static_cast<GUInt32 *>(NULL), hColorTable, pfnProgress, pProgressArg); } else { #ifdef CPL_HAS_GINT64 return GDALComputeMedianCutPCTInternal(hRed, hGreen, hBlue, NULL, NULL, NULL, pfnIncludePixel, nColors, 5, static_cast<GUIntBig * >(NULL), hColorTable, pfnProgress, pProgressArg); #else return CE_Failure; #endif } }
int CPL_STDCALL GDALDitherRGB2PCT( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, GDALRasterBandH hTarget, GDALColorTableH hColorTable, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hGreen, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hBlue, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hTarget, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hColorTable, "GDALDitherRGB2PCT", CE_Failure ); int nXSize, nYSize; CPLErr err = CE_None; /* -------------------------------------------------------------------- */ /* Validate parameters. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize( hRed ); nYSize = GDALGetRasterBandYSize( hRed ); if( GDALGetRasterBandXSize( hGreen ) != nXSize || GDALGetRasterBandYSize( hGreen ) != nYSize || GDALGetRasterBandXSize( hBlue ) != nXSize || GDALGetRasterBandYSize( hBlue ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "Green or blue band doesn't match size of red band.\n" ); return CE_Failure; } if( GDALGetRasterBandXSize( hTarget ) != nXSize || GDALGetRasterBandYSize( hTarget ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Target band doesn't match size of source bands.\n" ); return CE_Failure; } if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Setup more direct colormap. */ /* -------------------------------------------------------------------- */ int nColors, anPCT[768], iColor; nColors = GDALGetColorEntryCount( hColorTable ); if (nColors == 0 ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Color table must not be empty.\n" ); return CE_Failure; } else if (nColors > 256) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Color table cannot have more than 256 entries.\n" ); return CE_Failure; } for( iColor = 0; iColor < nColors; iColor++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hColorTable, iColor, &sEntry ); anPCT[iColor ] = sEntry.c1; anPCT[iColor+256] = sEntry.c2; anPCT[iColor+512] = sEntry.c3; } /* -------------------------------------------------------------------- */ /* Build a 24bit to 8 bit color mapping. */ /* -------------------------------------------------------------------- */ GByte *pabyColorMap; pabyColorMap = (GByte *) CPLMalloc(C_LEVELS * C_LEVELS * C_LEVELS * sizeof(int)); FindNearestColor( nColors, anPCT, pabyColorMap ); /* -------------------------------------------------------------------- */ /* Setup various variables. */ /* -------------------------------------------------------------------- */ GByte *pabyRed, *pabyGreen, *pabyBlue, *pabyIndex; int *panError; pabyRed = (GByte *) VSIMalloc(nXSize); pabyGreen = (GByte *) VSIMalloc(nXSize); pabyBlue = (GByte *) VSIMalloc(nXSize); pabyIndex = (GByte *) VSIMalloc(nXSize); panError = (int *) VSICalloc(sizeof(int),(nXSize+2) * 3); if (pabyRed == NULL || pabyGreen == NULL || pabyBlue == NULL || pabyIndex == NULL || panError == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSIMalloc(): Out of memory in GDALDitherRGB2PCT" ); err = CE_Failure; goto end_and_cleanup; } /* ==================================================================== */ /* Loop over all scanlines of data to process. */ /* ==================================================================== */ int iScanline; for( iScanline = 0; iScanline < nYSize; iScanline++ ) { int nLastRedError, nLastGreenError, nLastBlueError, i; /* -------------------------------------------------------------------- */ /* Report progress */ /* -------------------------------------------------------------------- */ if( !pfnProgress( iScanline / (double) nYSize, NULL, pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } /* -------------------------------------------------------------------- */ /* Read source data. */ /* -------------------------------------------------------------------- */ GDALRasterIO( hRed, GF_Read, 0, iScanline, nXSize, 1, pabyRed, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hGreen, GF_Read, 0, iScanline, nXSize, 1, pabyGreen, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hBlue, GF_Read, 0, iScanline, nXSize, 1, pabyBlue, nXSize, 1, GDT_Byte, 0, 0 ); /* -------------------------------------------------------------------- */ /* Apply the error from the previous line to this one. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nXSize; i++ ) { pabyRed[i] = (GByte) MAX(0,MIN(255,(pabyRed[i] + panError[i*3+0+3]))); pabyGreen[i] = (GByte) MAX(0,MIN(255,(pabyGreen[i] + panError[i*3+1+3]))); pabyBlue[i] = (GByte) MAX(0,MIN(255,(pabyBlue[i] + panError[i*3+2+3]))); } memset( panError, 0, sizeof(int) * (nXSize+2) * 3 ); /* -------------------------------------------------------------------- */ /* Figure out the nearest color to the RGB value. */ /* -------------------------------------------------------------------- */ nLastRedError = 0; nLastGreenError = 0; nLastBlueError = 0; for( i = 0; i < nXSize; i++ ) { int iIndex, nError, nSixth, iRed, iGreen, iBlue; int nRedValue, nGreenValue, nBlueValue; nRedValue = MAX(0,MIN(255, pabyRed[i] + nLastRedError)); nGreenValue = MAX(0,MIN(255, pabyGreen[i] + nLastGreenError)); nBlueValue = MAX(0,MIN(255, pabyBlue[i] + nLastBlueError)); iRed = nRedValue * C_LEVELS / 256; iGreen = nGreenValue * C_LEVELS / 256; iBlue = nBlueValue * C_LEVELS / 256; iIndex = pabyColorMap[iRed + iGreen * C_LEVELS + iBlue * C_LEVELS * C_LEVELS]; pabyIndex[i] = (GByte) iIndex; /* -------------------------------------------------------------------- */ /* Compute Red error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nRedValue - anPCT[iIndex ]; nSixth = nError / 6; panError[i*3 ] += nSixth; panError[i*3+6 ] = nSixth; panError[i*3+3 ] += nError - 5 * nSixth; nLastRedError = 2 * nSixth; /* -------------------------------------------------------------------- */ /* Compute Green error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nGreenValue - anPCT[iIndex+256]; nSixth = nError / 6; panError[i*3 +1] += nSixth; panError[i*3+6+1] = nSixth; panError[i*3+3+1] += nError - 5 * nSixth; nLastGreenError = 2 * nSixth; /* -------------------------------------------------------------------- */ /* Compute Blue error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nBlueValue - anPCT[iIndex+512]; nSixth = nError / 6; panError[i*3 +2] += nSixth; panError[i*3+6+2] = nSixth; panError[i*3+3+2] += nError - 5 * nSixth; nLastBlueError = 2 * nSixth; } /* -------------------------------------------------------------------- */ /* Write results. */ /* -------------------------------------------------------------------- */ GDALRasterIO( hTarget, GF_Write, 0, iScanline, nXSize, 1, pabyIndex, nXSize, 1, GDT_Byte, 0, 0 ); } pfnProgress( 1.0, NULL, pProgressArg ); /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end_and_cleanup: CPLFree( pabyRed ); CPLFree( pabyGreen ); CPLFree( pabyBlue ); CPLFree( pabyIndex ); CPLFree( panError ); CPLFree( pabyColorMap ); return err; }
int main( int argc, char ** argv ) { GDALDatasetH hDataset; GDALRasterBandH hBand; int i, iBand; double adfGeoTransform[6]; GDALDriverH hDriver; char **papszMetadata; int bComputeMinMax = FALSE; if( !GDALBridgeInitialize( "..", stderr ) ) { fprintf( stderr, "Unable to intiailize GDAL bridge.\n" ); exit( 10 ); } if( argc > 1 && strcmp(argv[1],"-mm") == 0 ) { bComputeMinMax = TRUE; argv++; } GDALAllRegister(); hDataset = GDALOpen( argv[1], GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg() ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Report general info. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); printf( "Size is %d, %d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ) ); /* -------------------------------------------------------------------- */ /* Report projection. */ /* -------------------------------------------------------------------- */ if( GDALGetProjectionRef( hDataset ) != NULL ) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "Coordinate System is:\n%s\n", pszPrettyWkt ); } else printf( "Coordinate System is `%s'\n", GDALGetProjectionRef( hDataset ) ); OSRDestroySpatialReference( hSRS ); } /* -------------------------------------------------------------------- */ /* Report Geotransform. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } /* -------------------------------------------------------------------- */ /* Report GCPs. */ /* -------------------------------------------------------------------- */ if( GDALGetGCPCount( hDataset ) > 0 ) { printf( "GCP Projection = %s\n", GDALGetGCPProjection(hDataset) ); for( i = 0; i < GDALGetGCPCount(hDataset); i++ ) { const GDAL_GCP *psGCP; psGCP = GDALGetGCPs( hDataset ) + i; printf( "GCP[%3d]: Id=%s, Info=%s\n" " (%g,%g) -> (%g,%g,%g)\n", i, psGCP->pszId, psGCP->pszInfo, psGCP->dfGCPPixel, psGCP->dfGCPLine, psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ ); } } /* -------------------------------------------------------------------- */ /* Report metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, NULL ); if( papszMetadata != NULL ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report subdatasets. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, "SUBDATASETS" ); if( papszMetadata != NULL ) { printf( "Subdatasets:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report corners. */ /* -------------------------------------------------------------------- */ printf( "Corner Coordinates:\n" ); GDALInfoReportCorner( hDataset, "Upper Left", 0.0, 0.0 ); GDALInfoReportCorner( hDataset, "Lower Left", 0.0, GDALGetRasterYSize(hDataset)); GDALInfoReportCorner( hDataset, "Upper Right", GDALGetRasterXSize(hDataset), 0.0 ); GDALInfoReportCorner( hDataset, "Lower Right", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset) ); GDALInfoReportCorner( hDataset, "Center", GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0 ); /* ==================================================================== */ /* Loop over bands. */ /* ==================================================================== */ for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ ) { double dfMin, dfMax, adfCMinMax[2], dfNoData; int bGotMin, bGotMax, bGotNodata; int nBlockXSize, nBlockYSize; hBand = GDALGetRasterBand( hDataset, iBand+1 ); GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( "Band %d Block=%dx%d Type=%d, ColorInterp=%d\n", iBand+1, nBlockXSize, nBlockYSize, GDALGetRasterDataType(hBand), GDALGetRasterColorInterpretation(hBand) ); dfMin = GDALGetRasterMinimum( hBand, &bGotMin ); dfMax = GDALGetRasterMaximum( hBand, &bGotMax ); printf( " Min=%.3f/%d, Max=%.3f/%d", dfMin, bGotMin, dfMax, bGotMax); if( bComputeMinMax ) { GDALComputeRasterMinMax( hBand, TRUE, adfCMinMax ); printf( ", Computed Min/Max=%.3f,%.3f", adfCMinMax[0], adfCMinMax[1] ); } printf( "\n" ); dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata ); if( bGotNodata ) { printf( " NoData Value=%g\n", dfNoData ); } if( GDALGetOverviewCount(hBand) > 0 ) { int iOverview; printf( " Overviews: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); } printf( "\n" ); } papszMetadata = GDALGetMetadata( hBand, NULL ); if( papszMetadata != NULL ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex ) { GDALColorTableH hTable; int i; hTable = GDALGetRasterColorTable( hBand ); printf( " Color Table (%s with %d entries)\n", GDALGetPaletteInterpretationName( GDALGetPaletteInterpretation( hTable )), GDALGetColorEntryCount( hTable ) ); for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hTable, i, &sEntry ); printf( " %3d: %d,%d,%d,%d\n", i, sEntry.c1, sEntry.c2, sEntry.c3, sEntry.c4 ); } } } GDALClose( hDataset ); exit( 0 ); }
void convert(const input_arguments& args) { // determine the subdataset pattern name using the first available file if(args.verbose) std::cout << "\tlooking for the names of subdatasets (or variables)... " << std::flush; std::vector<std::string> band_names = modis2scidb::extract_subdatasets_pattern_names(args.source_file_name); if(args.verbose) std::cout << "OK!" << std::endl; // check if band numbers are in the valid range if(args.verbose) std::cout << "\tchecking the range for choosed band numbers... " << std::flush; std::size_t num_bands = args.bands.size(); for(std::size_t i = 0; i != num_bands; ++i) if(args.bands[i] >= band_names.size()) throw modis2scidb::invalid_arg_value() << modis2scidb::error_description("band number is invalid!"); if(args.verbose) std::cout << "OK!" << std::endl; // let's buffer each subdataset if(args.verbose) std::cout << "\tbuffering data... " << std::flush; std::vector<boost::shared_array<unsigned char> > data_buffers; std::vector<unsigned char*> aux_data_buffers; std::vector<std::size_t> band_datatype_size; int64_t ncols = 0; int64_t nrows = 0; for(std::size_t i = 0; i != num_bands; ++i) { if(args.verbose) std::cout << "\n\t\tband #" << args.bands[i] << "... " << std::flush; boost::format subdataset(band_names[args.bands[i]]); subdataset.bind_arg(1, args.source_file_name); GDALDatasetH dataset = GDALOpen(subdataset.str().c_str(), GA_ReadOnly); if(dataset == 0) { boost::format err_msg("could not open subdataset: '%1%', for input hdf file: '%2%'!"); throw modis2scidb::gdal_error() << modis2scidb::error_description((err_msg % subdataset.str() % args.source_file_name).str()); } GDALRasterBandH band = GDALGetRasterBand(dataset, 1); if(band == 0) { GDALClose(dataset); boost::format err_msg("could not access band: %1%!"); throw modis2scidb::gdal_error() << modis2scidb::error_description((err_msg % args.bands[i]).str()); } if(i == 0) { ncols = GDALGetRasterBandXSize(band); nrows = GDALGetRasterBandYSize(band); } else { if((GDALGetRasterBandXSize(band) != ncols) || (GDALGetRasterBandYSize(band) != nrows)) { GDALClose(dataset); throw modis2scidb::gdal_error() << modis2scidb::error_description("selected bands must have the same dimension (rows and cols)!"); } } GDALDataType pixel_type = GDALGetRasterDataType(band); std::size_t pixel_size = modis2scidb::num_bytes(pixel_type); band_datatype_size.push_back(pixel_size); boost::shared_array<unsigned char> buffer(new unsigned char[ncols * nrows * pixel_size]); data_buffers.push_back(buffer); aux_data_buffers.push_back(buffer.get()); CPLErr result = GDALRasterIO(band, GF_Read, 0, 0, static_cast<int>(ncols), static_cast<int>(nrows), buffer.get(), static_cast<int>(ncols), static_cast<int>(nrows), pixel_type, 0, 0); if(result == CE_Failure) { GDALClose(dataset); boost::format err_msg("could not read subdataset: '%1%', for input hdf file: '%2%'!"); throw modis2scidb::gdal_error() << modis2scidb::error_description((err_msg % subdataset.str() % args.source_file_name).str()); } GDALClose(dataset); if(args.verbose) std::cout << "OK!" << std::flush; } if(args.verbose) std::cout << "\n\tOK!" << std::endl; // lets write the output to a SciDB binary file if(args.verbose) std::cout << "\tsaving data... " << std::flush; boost::filesystem::path input_file(args.source_file_name); FILE* f = fopen(args.target_file_name.c_str(), "wb"); if(f == 0) { boost::format err_msg("could not open output file: '%1%', for write! check if path exists."); throw modis2scidb::gdal_error() << modis2scidb::error_description((err_msg % args.target_file_name).str()); } for(int32_t i = 0; i != nrows; ++i) { int32_t gi = args.row_offset + i; for(int32_t j = 0; j != ncols; ++j) { int32_t gj = args.column_offset + j; fwrite(&gj, sizeof(unsigned char), sizeof(int32_t), f); fwrite(&gi, sizeof(unsigned char), sizeof(int32_t), f); if(args.time_point >= 0) fwrite(&args.time_point, sizeof(unsigned char), sizeof(int16_t), f); for(std::size_t b = 0; b != num_bands; ++b) { unsigned char* buffer = aux_data_buffers[b]; fwrite(buffer, sizeof(unsigned char), band_datatype_size[b], f); aux_data_buffers[b] = buffer + band_datatype_size[b]; } } } fclose(f); }
CPLErr CPL_STDCALL GDALFillNodata( GDALRasterBandH hTargetBand, GDALRasterBandH hMaskBand, double dfMaxSearchDist, CPL_UNUSED int bDeprecatedOption, int nSmoothingIterations, char **papszOptions, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hTargetBand, "GDALFillNodata", CE_Failure ); const int nXSize = GDALGetRasterBandXSize(hTargetBand); const int nYSize = GDALGetRasterBandYSize(hTargetBand); if( dfMaxSearchDist == 0.0 ) dfMaxSearchDist = std::max(nXSize, nYSize) + 1; const int nMaxSearchDist = static_cast<int>(floor(dfMaxSearchDist)); // Special "x" pixel values identifying pixels as special. GDALDataType eType = GDT_UInt16; GUInt32 nNoDataVal = 65535; if( nXSize > 65533 || nYSize > 65533 ) { eType = GDT_UInt32; nNoDataVal = 4000002; } if( hMaskBand == nullptr ) hMaskBand = GDALGetMaskBand( hTargetBand ); // If there are smoothing iterations, reserve 10% of the progress for them. const double dfProgressRatio = nSmoothingIterations > 0 ? 0.9 : 1.0; const char* pszNoData = CSLFetchNameValue(papszOptions, "NODATA"); bool bHasNoData = false; float fNoData = 0.0f; if( pszNoData ) { bHasNoData = true; fNoData = static_cast<float>(CPLAtof(pszNoData)); } /* -------------------------------------------------------------------- */ /* Initialize progress counter. */ /* -------------------------------------------------------------------- */ if( pfnProgress == nullptr ) pfnProgress = GDALDummyProgress; if( !pfnProgress( 0.0, "Filling...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Determine format driver for temp work files. */ /* -------------------------------------------------------------------- */ CPLString osTmpFileDriver = CSLFetchNameValueDef( papszOptions, "TEMP_FILE_DRIVER", "GTiff"); GDALDriverH hDriver = GDALGetDriverByName(osTmpFileDriver.c_str()); if( hDriver == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Given driver is not registered"); return CE_Failure; } if( GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, nullptr) == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Given driver is incapable of creating temp work files"); return CE_Failure; } char **papszWorkFileOptions = nullptr; if( osTmpFileDriver == "GTiff" ) { papszWorkFileOptions = CSLSetNameValue( papszWorkFileOptions, "COMPRESS", "LZW"); papszWorkFileOptions = CSLSetNameValue( papszWorkFileOptions, "BIGTIFF", "IF_SAFER"); } /* -------------------------------------------------------------------- */ /* Create a work file to hold the Y "last value" indices. */ /* -------------------------------------------------------------------- */ const CPLString osTmpFile = CPLGenerateTempFilename(""); const CPLString osYTmpFile = osTmpFile + "fill_y_work.tif"; GDALDatasetH hYDS = GDALCreate( hDriver, osYTmpFile, nXSize, nYSize, 1, eType, papszWorkFileOptions ); if( hYDS == nullptr ) { CPLError( CE_Failure, CPLE_AppDefined, "Could not create Y index work file. Check driver capabilities."); return CE_Failure; } GDALRasterBandH hYBand = GDALGetRasterBand( hYDS, 1 ); /* -------------------------------------------------------------------- */ /* Create a work file to hold the pixel value associated with */ /* the "last xy value" pixel. */ /* -------------------------------------------------------------------- */ const CPLString osValTmpFile = osTmpFile + "fill_val_work.tif"; GDALDatasetH hValDS = GDALCreate( hDriver, osValTmpFile, nXSize, nYSize, 1, GDALGetRasterDataType( hTargetBand ), papszWorkFileOptions ); if( hValDS == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Could not create XY value work file. Check driver capabilities."); return CE_Failure; } GDALRasterBandH hValBand = GDALGetRasterBand( hValDS, 1 ); /* -------------------------------------------------------------------- */ /* Create a mask file to make it clear what pixels can be filtered */ /* on the filtering pass. */ /* -------------------------------------------------------------------- */ const CPLString osFiltMaskTmpFile = osTmpFile + "fill_filtmask_work.tif"; GDALDatasetH hFiltMaskDS = GDALCreate( hDriver, osFiltMaskTmpFile, nXSize, nYSize, 1, GDT_Byte, papszWorkFileOptions ); if( hFiltMaskDS == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Could not create mask work file. Check driver capabilities."); return CE_Failure; } GDALRasterBandH hFiltMaskBand = GDALGetRasterBand( hFiltMaskDS, 1 ); /* -------------------------------------------------------------------- */ /* Allocate buffers for last scanline and this scanline. */ /* -------------------------------------------------------------------- */ GUInt32 *panLastY = static_cast<GUInt32 *>(VSI_CALLOC_VERBOSE(nXSize, sizeof(GUInt32))); GUInt32 *panThisY = static_cast<GUInt32 *>(VSI_CALLOC_VERBOSE(nXSize, sizeof(GUInt32))); GUInt32 *panTopDownY = static_cast<GUInt32 *>(VSI_CALLOC_VERBOSE(nXSize, sizeof(GUInt32))); float *pafLastValue = static_cast<float *>(VSI_CALLOC_VERBOSE(nXSize, sizeof(float))); float *pafThisValue = static_cast<float *>(VSI_CALLOC_VERBOSE(nXSize, sizeof(float))); float *pafTopDownValue = static_cast<float *>(VSI_CALLOC_VERBOSE(nXSize, sizeof(float))); float *pafScanline = static_cast<float *>(VSI_CALLOC_VERBOSE(nXSize, sizeof(float))); GByte *pabyMask = static_cast<GByte *>(VSI_CALLOC_VERBOSE(nXSize, 1)); GByte *pabyFiltMask = static_cast<GByte *>(VSI_CALLOC_VERBOSE(nXSize, 1)); CPLErr eErr = CE_None; if( panLastY == nullptr || panThisY == nullptr || panTopDownY == nullptr || pafLastValue == nullptr || pafThisValue == nullptr || pafTopDownValue == nullptr || pafScanline == nullptr || pabyMask == nullptr || pabyFiltMask == nullptr ) { eErr = CE_Failure; goto end; } for( int iX = 0; iX < nXSize; iX++ ) { panLastY[iX] = nNoDataVal; } /* ==================================================================== */ /* Make first pass from top to bottom collecting the "last */ /* known value" for each column and writing it out to the work */ /* files. */ /* ==================================================================== */ for( int iY = 0; iY < nYSize && eErr == CE_None; iY++ ) { /* -------------------------------------------------------------------- */ /* Read data and mask for this line. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hMaskBand, GF_Read, 0, iY, nXSize, 1, pabyMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hTargetBand, GF_Read, 0, iY, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Figure out the most recent pixel for each column. */ /* -------------------------------------------------------------------- */ for( int iX = 0; iX < nXSize; iX++ ) { if( pabyMask[iX] ) { pafThisValue[iX] = pafScanline[iX]; panThisY[iX] = iY; } else if( iY <= dfMaxSearchDist + panLastY[iX] ) { pafThisValue[iX] = pafLastValue[iX]; panThisY[iX] = panLastY[iX]; } else { panThisY[iX] = nNoDataVal; } } /* -------------------------------------------------------------------- */ /* Write out best index/value to working files. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hYBand, GF_Write, 0, iY, nXSize, 1, panThisY, nXSize, 1, GDT_UInt32, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hValBand, GF_Write, 0, iY, nXSize, 1, pafThisValue, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Flip this/last buffers. */ /* -------------------------------------------------------------------- */ std::swap(pafThisValue, pafLastValue); std::swap(panThisY, panLastY); /* -------------------------------------------------------------------- */ /* report progress. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( dfProgressRatio * (0.5*(iY+1) / static_cast<double>(nYSize)), "Filling...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } for( int iX = 0; iX < nXSize; iX++ ) { panLastY[iX] = nNoDataVal; } /* ==================================================================== */ /* Now we will do collect similar this/last information from */ /* bottom to top and use it in combination with the top to */ /* bottom search info to interpolate. */ /* ==================================================================== */ for( int iY = nYSize-1; iY >= 0 && eErr == CE_None; iY-- ) { eErr = GDALRasterIO( hMaskBand, GF_Read, 0, iY, nXSize, 1, pabyMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hTargetBand, GF_Read, 0, iY, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Figure out the most recent pixel for each column. */ /* -------------------------------------------------------------------- */ for( int iX = 0; iX < nXSize; iX++ ) { if( pabyMask[iX] ) { pafThisValue[iX] = pafScanline[iX]; panThisY[iX] = iY; } else if( panLastY[iX] - iY <= dfMaxSearchDist ) { pafThisValue[iX] = pafLastValue[iX]; panThisY[iX] = panLastY[iX]; } else { panThisY[iX] = nNoDataVal; } } /* -------------------------------------------------------------------- */ /* Load the last y and corresponding value from the top down pass. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hYBand, GF_Read, 0, iY, nXSize, 1, panTopDownY, nXSize, 1, GDT_UInt32, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hValBand, GF_Read, 0, iY, nXSize, 1, pafTopDownValue, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Attempt to interpolate any pixels that are nodata. */ /* -------------------------------------------------------------------- */ memset( pabyFiltMask, 0, nXSize ); for( int iX = 0; iX < nXSize; iX++ ) { int nThisMaxSearchDist = nMaxSearchDist; // If this was a valid target - no change. if( pabyMask[iX] ) continue; // Quadrants 0:topleft, 1:bottomleft, 2:topright, 3:bottomright double adfQuadDist[4] = {}; float fQuadValue[4] = {}; for( int iQuad = 0; iQuad < 4; iQuad++ ) { adfQuadDist[iQuad] = dfMaxSearchDist + 1.0; fQuadValue[iQuad] = 0.0; } // Step left and right by one pixel searching for the closest // target value for each quadrant. for( int iStep = 0; iStep <= nThisMaxSearchDist; iStep++ ) { const int iLeftX = std::max(0, iX - iStep); const int iRightX = std::min(nXSize - 1, iX + iStep); // Top left includes current line. QUAD_CHECK(adfQuadDist[0], fQuadValue[0], iLeftX, panTopDownY[iLeftX], iX, iY, pafTopDownValue[iLeftX], nNoDataVal ); // Bottom left. QUAD_CHECK(adfQuadDist[1], fQuadValue[1], iLeftX, panLastY[iLeftX], iX, iY, pafLastValue[iLeftX], nNoDataVal ); // Top right and bottom right do no include center pixel. if( iStep == 0 ) continue; // Top right includes current line. QUAD_CHECK(adfQuadDist[2], fQuadValue[2], iRightX, panTopDownY[iRightX], iX, iY, pafTopDownValue[iRightX], nNoDataVal ); // Bottom right. QUAD_CHECK(adfQuadDist[3], fQuadValue[3], iRightX, panLastY[iRightX], iX, iY, pafLastValue[iRightX], nNoDataVal ); // Every four steps, recompute maximum distance. if( (iStep & 0x3) == 0 ) nThisMaxSearchDist = static_cast<int>(floor( std::max(std::max(adfQuadDist[0], adfQuadDist[1]), std::max(adfQuadDist[2], adfQuadDist[3])))); } double dfWeightSum = 0.0; double dfValueSum = 0.0; bool bHasSrcValues = false; for( int iQuad = 0; iQuad < 4; iQuad++ ) { if( adfQuadDist[iQuad] <= dfMaxSearchDist ) { const double dfWeight = 1.0 / adfQuadDist[iQuad]; bHasSrcValues = dfWeight != 0; if( !bHasNoData || fQuadValue[iQuad] != fNoData ) { dfWeightSum += dfWeight; dfValueSum += fQuadValue[iQuad] * dfWeight; } } } if( bHasSrcValues ) { pabyMask[iX] = 255; pabyFiltMask[iX] = 255; if( dfWeightSum > 0.0 ) pafScanline[iX] = static_cast<float>(dfValueSum / dfWeightSum); else pafScanline[iX] = fNoData; } } /* -------------------------------------------------------------------- */ /* Write out the updated data and mask information. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hTargetBand, GF_Write, 0, iY, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hFiltMaskBand, GF_Write, 0, iY, nXSize, 1, pabyFiltMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Flip this/last buffers. */ /* -------------------------------------------------------------------- */ std::swap(pafThisValue, pafLastValue); std::swap(panThisY, panLastY); /* -------------------------------------------------------------------- */ /* report progress. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( dfProgressRatio*(0.5+0.5*(nYSize-iY) / static_cast<double>(nYSize)), "Filling...", pProgressArg) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* ==================================================================== */ /* Now we will do iterative average filters over the */ /* interpolated values to smooth things out and make linear */ /* artifacts less obvious. */ /* ==================================================================== */ if( eErr == CE_None && nSmoothingIterations > 0 ) { // Force masks to be to flushed and recomputed. GDALFlushRasterCache( hMaskBand ); void *pScaledProgress = GDALCreateScaledProgress( dfProgressRatio, 1.0, pfnProgress, nullptr ); eErr = GDALMultiFilter( hTargetBand, hMaskBand, hFiltMaskBand, nSmoothingIterations, GDALScaledProgress, pScaledProgress ); GDALDestroyScaledProgress( pScaledProgress ); } /* -------------------------------------------------------------------- */ /* Close and clean up temporary files. Free working buffers */ /* -------------------------------------------------------------------- */ end: CPLFree(panLastY); CPLFree(panThisY); CPLFree(panTopDownY); CPLFree(pafLastValue); CPLFree(pafThisValue); CPLFree(pafTopDownValue); CPLFree(pafScanline); CPLFree(pabyMask); CPLFree(pabyFiltMask); GDALClose( hYDS ); GDALClose( hValDS ); GDALClose( hFiltMaskDS ); CSLDestroy(papszWorkFileOptions); GDALDeleteDataset( hDriver, osYTmpFile ); GDALDeleteDataset( hDriver, osValTmpFile ); GDALDeleteDataset( hDriver, osFiltMaskTmpFile ); return eErr; }
void CUtils::calculateByteGeoTIFFStatistics(GDALDatasetH hDataset, int userBandNumber, byte flNoDataValueAsBackground, byte NoDataValue) { fputs("\nCalculate statistics...\n", stderr); GDALRasterBandH hBand = GDALGetRasterBand(hDataset, 1); int cols = GDALGetRasterBandXSize(hBand); int rows = GDALGetRasterBandYSize(hBand); int bands = GDALGetRasterCount(hDataset); byte * pbuf = NULL; pbuf = (byte *)CPLMalloc(sizeof(byte)*cols); byte min = 0, max = 0, mean = 0; double stddev = 0; double summ = 0; int count = 0; for(int band=1; band<=bands; band++) { if(userBandNumber != -1) fprintf(stderr, "Band %d...\n", userBandNumber); else fprintf(stderr, "Band %d...\n", band); hBand = GDALGetRasterBand(hDataset, band); if(flNoDataValueAsBackground) NoDataValue = getFloatNoDataValueAsBackground(hBand); min = max = mean = stddev = summ = 0; count = 0; bool flFirst = true; int pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS); for(int i=0; i<rows; i++) { GDALRasterIO(hBand, GF_Read, 0, i, cols, 1, pbuf, cols, 1, GDT_Byte, 0, 0 ); for(int j=0; j<cols; j++) if(pbuf[j]!=NoDataValue) { if(flFirst) { mean = pbuf[j]; min = max = mean; flFirst = false; } else { mean += pbuf[j]; if( min > pbuf[j] ) min = pbuf[j]; if( max < pbuf[j] ) max = pbuf[j]; } count++; } pr = CUtils::progress_ln_ex(stderr, i, rows, pr); } CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS); double dmean = 0; if(count > 0) dmean = mean / (double)count; pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS); for(int i=0; i<rows; i++) { GDALRasterIO(hBand, GF_Read, 0, i, cols, 1, pbuf, cols, 1, GDT_Byte, 0, 0 ); for(int j=0; j<cols; j++) if(pbuf[j]!=NoDataValue) summ += ((double)pbuf[j]-dmean)*((double)pbuf[j]-dmean); pr = CUtils::progress_ln_ex(stderr, i, rows, pr); } CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS); summ = 0; stddev = 0; if((count-1)>0) { summ /= (double)(count-1); if(summ!=0) stddev = sqrt(summ); } GDALSetRasterStatistics(hBand, min, max, mean, stddev); GDALSetRasterNoDataValue(hBand, NoDataValue); } CPLFree(pbuf); }
void QgsRasterCalculator::readRasterPart( double* targetGeotransform, int xOffset, int yOffset, int nCols, int nRows, double* sourceTransform, GDALRasterBandH sourceBand, float* rasterBuffer ) { //If dataset transform is the same as the requested transform, do a normal GDAL raster io if ( transformationsEqual( targetGeotransform, sourceTransform ) ) { GDALRasterIO( sourceBand, GF_Read, xOffset, yOffset, nCols, nRows, rasterBuffer, nCols, nRows, GDT_Float32, 0, 0 ); return; } //pixel calculation needed because of different raster position / resolution int nodataSuccess; double nodataValue = GDALGetRasterNoDataValue( sourceBand, &nodataSuccess ); QgsRectangle targetRect( targetGeotransform[0] + targetGeotransform[1] * xOffset, targetGeotransform[3] + yOffset * targetGeotransform[5] + nRows * targetGeotransform[5] , targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] * nCols, targetGeotransform[3] + yOffset * targetGeotransform[5] ); QgsRectangle sourceRect( sourceTransform[0], sourceTransform[3] + GDALGetRasterBandYSize( sourceBand ) * sourceTransform[5], sourceTransform[0] + GDALGetRasterBandXSize( sourceBand )* sourceTransform[1], sourceTransform[3] ); QgsRectangle intersection = targetRect.intersect( &sourceRect ); //no intersection, fill all the pixels with nodata values if ( intersection.isEmpty() ) { int nPixels = nCols * nRows; for ( int i = 0; i < nPixels; ++i ) { rasterBuffer[i] = nodataValue; } return; } //do raster io in source resolution int sourcePixelOffsetXMin = floor(( intersection.xMinimum() - sourceTransform[0] ) / sourceTransform[1] ); int sourcePixelOffsetXMax = ceil(( intersection.xMaximum() - sourceTransform[0] ) / sourceTransform[1] ); int nSourcePixelsX = sourcePixelOffsetXMax - sourcePixelOffsetXMin; int sourcePixelOffsetYMax = floor(( intersection.yMaximum() - sourceTransform[3] ) / sourceTransform[5] ); int sourcePixelOffsetYMin = ceil(( intersection.yMinimum() - sourceTransform[3] ) / sourceTransform[5] ); int nSourcePixelsY = sourcePixelOffsetYMin - sourcePixelOffsetYMax; float* sourceRaster = ( float * ) CPLMalloc( sizeof( float ) * nSourcePixelsX * nSourcePixelsY ); double sourceRasterXMin = sourceRect.xMinimum() + sourcePixelOffsetXMin * sourceTransform[1]; double sourceRasterYMax = sourceRect.yMaximum() + sourcePixelOffsetYMax * sourceTransform[5]; GDALRasterIO( sourceBand, GF_Read, sourcePixelOffsetXMin, sourcePixelOffsetYMax, nSourcePixelsX, nSourcePixelsY, sourceRaster, nSourcePixelsX, nSourcePixelsY, GDT_Float32, 0, 0 ); double targetPixelX; double targetPixelXMin = targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] / 2.0; double targetPixelY = targetGeotransform[3] + targetGeotransform[5] * yOffset + targetGeotransform[5] / 2.0; //coordinates of current target pixel int sourceIndexX, sourceIndexY; //current raster index in source pixels double sx, sy; for ( int i = 0; i < nRows; ++i ) { targetPixelX = targetPixelXMin; for ( int j = 0; j < nCols; ++j ) { sx = ( targetPixelX - sourceRasterXMin ) / sourceTransform[1]; sourceIndexX = sx > 0 ? sx : floor( sx ); sy = ( targetPixelY - sourceRasterYMax ) / sourceTransform[5]; sourceIndexY = sy > 0 ? sy : floor( sy ); if ( sourceIndexX >= 0 && sourceIndexX < nSourcePixelsX && sourceIndexY >= 0 && sourceIndexY < nSourcePixelsY ) { rasterBuffer[j + i*nRows] = sourceRaster[ sourceIndexX + nSourcePixelsX * sourceIndexY ]; } else { rasterBuffer[j + i*j] = nodataValue; } targetPixelX += targetGeotransform[1]; } targetPixelY += targetGeotransform[5]; } CPLFree( sourceRaster ); return; }
CPLErr CPL_STDCALL GDALFillNodata( GDALRasterBandH hTargetBand, GDALRasterBandH hMaskBand, double dfMaxSearchDist, CPL_UNUSED int bDeprecatedOption, int nSmoothingIterations, CPL_UNUSED char **papszOptions, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hTargetBand, "GDALFillNodata", CE_Failure ); int nXSize = GDALGetRasterBandXSize( hTargetBand ); int nYSize = GDALGetRasterBandYSize( hTargetBand ); CPLErr eErr = CE_None; // Special "x" pixel values identifying pixels as special. GUInt32 nNoDataVal; GDALDataType eType; if( dfMaxSearchDist == 0.0 ) dfMaxSearchDist = MAX(nXSize,nYSize) + 1; int nMaxSearchDist = (int) floor(dfMaxSearchDist); if( nXSize > 65533 || nYSize > 65533 ) { eType = GDT_UInt32; nNoDataVal = 4000002; } else { eType = GDT_UInt16; nNoDataVal = 65535; } if( hMaskBand == NULL ) hMaskBand = GDALGetMaskBand( hTargetBand ); /* If there are smoothing iterations, reserve 10% of the progress for them */ double dfProgressRatio = (nSmoothingIterations > 0) ? 0.9 : 1.0; /* -------------------------------------------------------------------- */ /* Initialize progress counter. */ /* -------------------------------------------------------------------- */ if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; if( !pfnProgress( 0.0, "Filling...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Create a work file to hold the Y "last value" indices. */ /* -------------------------------------------------------------------- */ GDALDriverH hDriver = GDALGetDriverByName( "GTiff" ); if (hDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GDALFillNodata needs GTiff driver"); return CE_Failure; } GDALDatasetH hYDS; GDALRasterBandH hYBand; static const char *apszOptions[] = { "COMPRESS=LZW", "BIGTIFF=IF_SAFER", NULL }; CPLString osTmpFile = CPLGenerateTempFilename(""); CPLString osYTmpFile = osTmpFile + "fill_y_work.tif"; hYDS = GDALCreate( hDriver, osYTmpFile, nXSize, nYSize, 1, eType, (char **) apszOptions ); if( hYDS == NULL ) return CE_Failure; hYBand = GDALGetRasterBand( hYDS, 1 ); /* -------------------------------------------------------------------- */ /* Create a work file to hold the pixel value associated with */ /* the "last xy value" pixel. */ /* -------------------------------------------------------------------- */ GDALDatasetH hValDS; GDALRasterBandH hValBand; CPLString osValTmpFile = osTmpFile + "fill_val_work.tif"; hValDS = GDALCreate( hDriver, osValTmpFile, nXSize, nYSize, 1, GDALGetRasterDataType( hTargetBand ), (char **) apszOptions ); if( hValDS == NULL ) return CE_Failure; hValBand = GDALGetRasterBand( hValDS, 1 ); /* -------------------------------------------------------------------- */ /* Create a mask file to make it clear what pixels can be filtered */ /* on the filtering pass. */ /* -------------------------------------------------------------------- */ GDALDatasetH hFiltMaskDS; GDALRasterBandH hFiltMaskBand; CPLString osFiltMaskTmpFile = osTmpFile + "fill_filtmask_work.tif"; hFiltMaskDS = GDALCreate( hDriver, osFiltMaskTmpFile, nXSize, nYSize, 1, GDT_Byte, (char **) apszOptions ); if( hFiltMaskDS == NULL ) return CE_Failure; hFiltMaskBand = GDALGetRasterBand( hFiltMaskDS, 1 ); /* -------------------------------------------------------------------- */ /* Allocate buffers for last scanline and this scanline. */ /* -------------------------------------------------------------------- */ GUInt32 *panLastY, *panThisY, *panTopDownY; float *pafLastValue, *pafThisValue, *pafScanline, *pafTopDownValue; GByte *pabyMask, *pabyFiltMask; int iX; int iY; panLastY = (GUInt32 *) VSICalloc(nXSize,sizeof(GUInt32)); panThisY = (GUInt32 *) VSICalloc(nXSize,sizeof(GUInt32)); panTopDownY = (GUInt32 *) VSICalloc(nXSize,sizeof(GUInt32)); pafLastValue = (float *) VSICalloc(nXSize,sizeof(float)); pafThisValue = (float *) VSICalloc(nXSize,sizeof(float)); pafTopDownValue = (float *) VSICalloc(nXSize,sizeof(float)); pafScanline = (float *) VSICalloc(nXSize,sizeof(float)); pabyMask = (GByte *) VSICalloc(nXSize,1); pabyFiltMask = (GByte *) VSICalloc(nXSize,1); if (panLastY == NULL || panThisY == NULL || panTopDownY == NULL || pafLastValue == NULL || pafThisValue == NULL || pafTopDownValue == NULL || pafScanline == NULL || pabyMask == NULL || pabyFiltMask == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Could not allocate enough memory for temporary buffers"); eErr = CE_Failure; goto end; } for( iX = 0; iX < nXSize; iX++ ) { panLastY[iX] = nNoDataVal; } /* ==================================================================== */ /* Make first pass from top to bottom collecting the "last */ /* known value" for each column and writing it out to the work */ /* files. */ /* ==================================================================== */ for( iY = 0; iY < nYSize && eErr == CE_None; iY++ ) { /* -------------------------------------------------------------------- */ /* Read data and mask for this line. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hMaskBand, GF_Read, 0, iY, nXSize, 1, pabyMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hTargetBand, GF_Read, 0, iY, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Figure out the most recent pixel for each column. */ /* -------------------------------------------------------------------- */ for( iX = 0; iX < nXSize; iX++ ) { if( pabyMask[iX] ) { pafThisValue[iX] = pafScanline[iX]; panThisY[iX] = iY; } else if( iY <= dfMaxSearchDist + panLastY[iX] ) { pafThisValue[iX] = pafLastValue[iX]; panThisY[iX] = panLastY[iX]; } else { panThisY[iX] = nNoDataVal; } } /* -------------------------------------------------------------------- */ /* Write out best index/value to working files. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hYBand, GF_Write, 0, iY, nXSize, 1, panThisY, nXSize, 1, GDT_UInt32, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hValBand, GF_Write, 0, iY, nXSize, 1, pafThisValue, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Flip this/last buffers. */ /* -------------------------------------------------------------------- */ { float *pafTmp = pafThisValue; pafThisValue = pafLastValue; pafLastValue = pafTmp; GUInt32 *panTmp = panThisY; panThisY = panLastY; panLastY = panTmp; } /* -------------------------------------------------------------------- */ /* report progress. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( dfProgressRatio * (0.5*(iY+1) / (double)nYSize), "Filling...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* ==================================================================== */ /* Now we will do collect similar this/last information from */ /* bottom to top and use it in combination with the top to */ /* bottom search info to interpolate. */ /* ==================================================================== */ for( iY = nYSize-1; iY >= 0 && eErr == CE_None; iY-- ) { eErr = GDALRasterIO( hMaskBand, GF_Read, 0, iY, nXSize, 1, pabyMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hTargetBand, GF_Read, 0, iY, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Figure out the most recent pixel for each column. */ /* -------------------------------------------------------------------- */ for( iX = 0; iX < nXSize; iX++ ) { if( pabyMask[iX] ) { pafThisValue[iX] = pafScanline[iX]; panThisY[iX] = iY; } else if( panLastY[iX] - iY <= dfMaxSearchDist ) { pafThisValue[iX] = pafLastValue[iX]; panThisY[iX] = panLastY[iX]; } else { panThisY[iX] = nNoDataVal; } } /* -------------------------------------------------------------------- */ /* Load the last y and corresponding value from the top down pass. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hYBand, GF_Read, 0, iY, nXSize, 1, panTopDownY, nXSize, 1, GDT_UInt32, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hValBand, GF_Read, 0, iY, nXSize, 1, pafTopDownValue, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Attempt to interpolate any pixels that are nodata. */ /* -------------------------------------------------------------------- */ memset( pabyFiltMask, 0, nXSize ); for( iX = 0; iX < nXSize; iX++ ) { int iStep, iQuad; int nThisMaxSearchDist = nMaxSearchDist; // If this was a valid target - no change. if( pabyMask[iX] ) continue; // Quadrants 0:topleft, 1:bottomleft, 2:topright, 3:bottomright double adfQuadDist[4]; double adfQuadValue[4]; for( iQuad = 0; iQuad < 4; iQuad++ ) { adfQuadDist[iQuad] = dfMaxSearchDist + 1.0; adfQuadValue[iQuad] = 0.0; } // Step left and right by one pixel searching for the closest // target value for each quadrant. for( iStep = 0; iStep < nThisMaxSearchDist; iStep++ ) { int iLeftX = MAX(0,iX - iStep); int iRightX = MIN(nXSize-1,iX + iStep); // top left includes current line QUAD_CHECK(adfQuadDist[0],adfQuadValue[0], iLeftX, panTopDownY[iLeftX], iX, iY, pafTopDownValue[iLeftX] ); // bottom left QUAD_CHECK(adfQuadDist[1],adfQuadValue[1], iLeftX, panLastY[iLeftX], iX, iY, pafLastValue[iLeftX] ); // top right and bottom right do no include center pixel. if( iStep == 0 ) continue; // top right includes current line QUAD_CHECK(adfQuadDist[2],adfQuadValue[2], iRightX, panTopDownY[iRightX], iX, iY, pafTopDownValue[iRightX] ); // bottom right QUAD_CHECK(adfQuadDist[3],adfQuadValue[3], iRightX, panLastY[iRightX], iX, iY, pafLastValue[iRightX] ); // every four steps, recompute maximum distance. if( (iStep & 0x3) == 0 ) nThisMaxSearchDist = (int) floor( MAX(MAX(adfQuadDist[0],adfQuadDist[1]), MAX(adfQuadDist[2],adfQuadDist[3])) ); } double dfWeightSum = 0.0; double dfValueSum = 0.0; for( iQuad = 0; iQuad < 4; iQuad++ ) { if( adfQuadDist[iQuad] <= dfMaxSearchDist ) { double dfWeight = 1.0 / adfQuadDist[iQuad]; dfWeightSum += dfWeight; dfValueSum += adfQuadValue[iQuad] * dfWeight; } } if( dfWeightSum > 0.0 ) { pabyMask[iX] = 255; pabyFiltMask[iX] = 255; pafScanline[iX] = (float) (dfValueSum / dfWeightSum); } } /* -------------------------------------------------------------------- */ /* Write out the updated data and mask information. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hTargetBand, GF_Write, 0, iY, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hFiltMaskBand, GF_Write, 0, iY, nXSize, 1, pabyFiltMask, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; /* -------------------------------------------------------------------- */ /* Flip this/last buffers. */ /* -------------------------------------------------------------------- */ { float *pafTmp = pafThisValue; pafThisValue = pafLastValue; pafLastValue = pafTmp; GUInt32 *panTmp = panThisY; panThisY = panLastY; panLastY = panTmp; } /* -------------------------------------------------------------------- */ /* report progress. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( dfProgressRatio*(0.5+0.5*(nYSize-iY) / (double)nYSize), "Filling...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* ==================================================================== */ /* Now we will do iterative average filters over the */ /* interpolated values to smooth things out and make linear */ /* artifacts less obvious. */ /* ==================================================================== */ if( eErr == CE_None && nSmoothingIterations > 0 ) { // force masks to be to flushed and recomputed. GDALFlushRasterCache( hMaskBand ); void *pScaledProgress; pScaledProgress = GDALCreateScaledProgress( dfProgressRatio, 1.0, pfnProgress, NULL ); eErr = GDALMultiFilter( hTargetBand, hMaskBand, hFiltMaskBand, nSmoothingIterations, GDALScaledProgress, pScaledProgress ); GDALDestroyScaledProgress( pScaledProgress ); } /* -------------------------------------------------------------------- */ /* Close and clean up temporary files. Free working buffers */ /* -------------------------------------------------------------------- */ end: CPLFree(panLastY); CPLFree(panThisY); CPLFree(panTopDownY); CPLFree(pafLastValue); CPLFree(pafThisValue); CPLFree(pafTopDownValue); CPLFree(pafScanline); CPLFree(pabyMask); CPLFree(pabyFiltMask); GDALClose( hYDS ); GDALClose( hValDS ); GDALClose( hFiltMaskDS ); GDALDeleteDataset( hDriver, osYTmpFile ); GDALDeleteDataset( hDriver, osValTmpFile ); GDALDeleteDataset( hDriver, osFiltMaskTmpFile ); return eErr; }
int main( int argc, char *argv[] ) { if( argc < 9 ) { usage(); return 1; } char *inB1 = argv[1]; //Albedo char *inB2 = argv[2]; //Sunza char *inB3 = argv[3]; //e0-1-b31 char *inB4 = argv[4]; //e0-2-b32 char *inB5 = argv[5]; //LST char *inB6 = argv[6]; //DEM char *rnetF = argv[7]; float doy = atof( argv[8] ); float tmax = atof( argv[9] ); //MDB Farm A // double phase_max=sin(2*3.1415927*(doy+365/3.3)/365); // tmax=31.17+(36.9-24.1)/2*((1+1/3+1/5+1/7)*phase_max); // // double phase_min=sin(2*PI*(doy+365/3.5)/365); // // double tmin=31.17+(36.9-24.1)/2*((1+1/3+1/5+1/7)*phase_min); //Convert Tmax from C to K // if(tmax<100.0) tmax+=273.15; // printf("\ndoy\t= %7.2f\ntmax\t= %7.2f\n\n",doy, tmax); GDALAllRegister(); GDALDatasetH hD1 = GDALOpen(inB1,GA_ReadOnly);//Albedo GDALDatasetH hD2 = GDALOpen(inB2,GA_ReadOnly);//Sunza GDALDatasetH hD3 = GDALOpen(inB3,GA_ReadOnly);//e31 GDALDatasetH hD4 = GDALOpen(inB4,GA_ReadOnly);//e32 GDALDatasetH hD5 = GDALOpen(inB5,GA_ReadOnly);//LST GDALDatasetH hD6 = GDALOpen(inB6,GA_ReadOnly);//DEM if(hD1==NULL||hD2==NULL||hD3==NULL|| hD4==NULL||hD5==NULL||hD6==NULL){ printf("One or more input files "); printf("could not be loaded\n"); exit(1); } GDALDriverH hDr6 = GDALGetDatasetDriver(hD6); GDALDatasetH hDOut = GDALCreateCopy(hDr6,rnetF,hD6,FALSE,NULL,NULL,NULL); GDALRasterBandH hBOut = GDALGetRasterBand(hDOut,1); GDALRasterBandH hB1 = GDALGetRasterBand(hD1,1);//Albedo GDALRasterBandH hB2 = GDALGetRasterBand(hD2,1);//Sunza GDALRasterBandH hB3 = GDALGetRasterBand(hD3,1);//e31 GDALRasterBandH hB4 = GDALGetRasterBand(hD4,1);//e32 GDALRasterBandH hB5 = GDALGetRasterBand(hD5,1);//LST GDALRasterBandH hB6 = GDALGetRasterBand(hD6,1);//DEM int nX = GDALGetRasterBandXSize(hB1); int nY = GDALGetRasterBandYSize(hB1); int N=nX*nY; float *mat1 = (float *) malloc(sizeof(float)*N); float *mat2 = (float *) malloc(sizeof(float)*N); float *mat3 = (float *) malloc(sizeof(float)*N); float *mat4 = (float *) malloc(sizeof(float)*N); float *mat5 = (float *) malloc(sizeof(float)*N); float *mat6 = (float *) malloc(sizeof(float)*N); float *matOut = (float *) malloc(sizeof(float)*N); float e0, rnet; int rowcol; GDALRasterIO(hB1,GF_Read,0,0,nX,nY,mat1,nX,nY,GDT_Float32,0,0); GDALRasterIO(hB2,GF_Read,0,0,nX,nY,mat2,nX,nY,GDT_Float32,0,0); GDALRasterIO(hB3,GF_Read,0,0,nX,nY,mat3,nX,nY,GDT_Float32,0,0); GDALRasterIO(hB4,GF_Read,0,0,nX,nY,mat4,nX,nY,GDT_Float32,0,0); GDALRasterIO(hB5,GF_Read,0,0,nX,nY,mat5,nX,nY,GDT_Float32,0,0); GDALRasterIO(hB6,GF_Read,0,0,nX,nY,mat6,nX,nY,GDT_Float32,0,0); #pragma omp parallel for default(none) \ private(rowcol, e0, rnet)\ shared(N, tmax, doy,\ mat1,mat2,mat3,mat4,mat5,mat6, \ matOut ) for(rowcol=0;rowcol<N;rowcol++){ if(mat1[rowcol]==-28768||mat5[rowcol]==-28768||mat5[rowcol]==0) matOut[rowcol] = -28768; else { e0 = 0.5*((mat3[rowcol]*0.002+0.49)+(mat4[rowcol]*0.002+0.49)); rnet = r_net(mat1[rowcol]*0.001,mat2[rowcol]*0.01,e0,mat5[rowcol]*0.02,mat6[rowcol],doy,tmax); matOut[rowcol]=rnet; } } #pragma omp barrier GDALRasterIO(hBOut,GF_Write,0,0,nX,nY,matOut,nX,nY,GDT_Float32,0,0); GDALClose(hDOut); //free memory close unused files if(mat1 != NULL) free(mat1); if(mat2 != NULL) free(mat2); if(mat3 != NULL) free(mat3); if(mat4 != NULL) free(mat4); if(mat5 != NULL) free(mat5); if(mat6 != NULL) free(mat6); if(matOut != NULL) free(matOut); GDALClose(hD1); GDALClose(hD2); GDALClose(hD3); GDALClose(hD4); GDALClose(hD5); GDALClose(hD6); return(EXIT_SUCCESS); }
int GDALDitherRGB2PCTInternal( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, GDALRasterBandH hTarget, GDALColorTableH hColorTable, int nBits, GInt16* pasDynamicColorMap, /* NULL or at least 256 * 256 * 256 * sizeof(GInt16) bytes */ int bDither, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hGreen, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hBlue, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hTarget, "GDALDitherRGB2PCT", CE_Failure ); VALIDATE_POINTER1( hColorTable, "GDALDitherRGB2PCT", CE_Failure ); int nXSize, nYSize; CPLErr err = CE_None; /* -------------------------------------------------------------------- */ /* Validate parameters. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize( hRed ); nYSize = GDALGetRasterBandYSize( hRed ); if( GDALGetRasterBandXSize( hGreen ) != nXSize || GDALGetRasterBandYSize( hGreen ) != nYSize || GDALGetRasterBandXSize( hBlue ) != nXSize || GDALGetRasterBandYSize( hBlue ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "Green or blue band doesn't match size of red band.\n" ); return CE_Failure; } if( GDALGetRasterBandXSize( hTarget ) != nXSize || GDALGetRasterBandYSize( hTarget ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Target band doesn't match size of source bands.\n" ); return CE_Failure; } if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Setup more direct colormap. */ /* -------------------------------------------------------------------- */ int nColors, iColor; #ifdef USE_SSE2 int anPCTUnaligned[256+4]; /* 4 for alignment on 16-byte boundary */ int* anPCT = ALIGN_INT_ARRAY_ON_16_BYTE(anPCTUnaligned); #else int anPCT[256*4]; #endif nColors = GDALGetColorEntryCount( hColorTable ); if (nColors == 0 ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Color table must not be empty.\n" ); return CE_Failure; } else if (nColors > 256) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALDitherRGB2PCT(): " "Color table cannot have more than 256 entries.\n" ); return CE_Failure; } for( iColor = 0; iColor < nColors; iColor++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hColorTable, iColor, &sEntry ); CAST_PCT(anPCT)[4*iColor+0] = sEntry.c1; CAST_PCT(anPCT)[4*iColor+1] = sEntry.c2; CAST_PCT(anPCT)[4*iColor+2] = sEntry.c3; CAST_PCT(anPCT)[4*iColor+3] = 0; } #ifdef USE_SSE2 /* Pad to multiple of 8 colors */ int nColorsMod8 = nColors % 8; if( nColorsMod8 ) { for( iColor = 0; iColor < 8 - nColorsMod8; iColor ++) { anPCT[nColors+iColor] = anPCT[nColors-1]; } } #endif /* -------------------------------------------------------------------- */ /* Setup various variables. */ /* -------------------------------------------------------------------- */ GByte *pabyRed, *pabyGreen, *pabyBlue, *pabyIndex; GByte *pabyColorMap = NULL; int *panError; int nCLevels = 1 << nBits; ColorIndex* psColorIndexMap = NULL; pabyRed = (GByte *) VSIMalloc(nXSize); pabyGreen = (GByte *) VSIMalloc(nXSize); pabyBlue = (GByte *) VSIMalloc(nXSize); pabyIndex = (GByte *) VSIMalloc(nXSize); panError = (int *) VSICalloc(sizeof(int),(nXSize+2) * 3); if (pabyRed == NULL || pabyGreen == NULL || pabyBlue == NULL || pabyIndex == NULL || panError == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSIMalloc(): Out of memory in GDALDitherRGB2PCT" ); err = CE_Failure; goto end_and_cleanup; } if( pasDynamicColorMap == NULL ) { /* -------------------------------------------------------------------- */ /* Build a 24bit to 8 bit color mapping. */ /* -------------------------------------------------------------------- */ pabyColorMap = (GByte *) VSIMalloc(nCLevels * nCLevels * nCLevels * sizeof(GByte)); if( pabyColorMap == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSIMalloc(): Out of memory in GDALDitherRGB2PCT" ); err = CE_Failure; goto end_and_cleanup; } FindNearestColor( nColors, anPCT, pabyColorMap, nCLevels); } else { pabyColorMap = NULL; if( nBits == 8 && (GIntBig)nXSize * nYSize <= 65536 ) { /* If the image is small enough, then the number of colors */ /* will be limited and using a hashmap, rather than a full table */ /* will be more efficient */ psColorIndexMap = (ColorIndex*)pasDynamicColorMap; memset(psColorIndexMap, 0xFF, sizeof(ColorIndex) * PRIME_FOR_65536); } else { memset(pasDynamicColorMap, 0xFF, 256 * 256 * 256 * sizeof(GInt16)); } } /* ==================================================================== */ /* Loop over all scanlines of data to process. */ /* ==================================================================== */ int iScanline; for( iScanline = 0; iScanline < nYSize; iScanline++ ) { int nLastRedError, nLastGreenError, nLastBlueError, i; /* -------------------------------------------------------------------- */ /* Report progress */ /* -------------------------------------------------------------------- */ if( !pfnProgress( iScanline / (double) nYSize, NULL, pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } /* -------------------------------------------------------------------- */ /* Read source data. */ /* -------------------------------------------------------------------- */ GDALRasterIO( hRed, GF_Read, 0, iScanline, nXSize, 1, pabyRed, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hGreen, GF_Read, 0, iScanline, nXSize, 1, pabyGreen, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hBlue, GF_Read, 0, iScanline, nXSize, 1, pabyBlue, nXSize, 1, GDT_Byte, 0, 0 ); /* -------------------------------------------------------------------- */ /* Apply the error from the previous line to this one. */ /* -------------------------------------------------------------------- */ if( bDither ) { for( i = 0; i < nXSize; i++ ) { pabyRed[i] = (GByte) MAX(0,MIN(255,(pabyRed[i] + panError[i*3+0+3]))); pabyGreen[i] = (GByte) MAX(0,MIN(255,(pabyGreen[i] + panError[i*3+1+3]))); pabyBlue[i] = (GByte) MAX(0,MIN(255,(pabyBlue[i] + panError[i*3+2+3]))); } memset( panError, 0, sizeof(int) * (nXSize+2) * 3 ); } /* -------------------------------------------------------------------- */ /* Figure out the nearest color to the RGB value. */ /* -------------------------------------------------------------------- */ nLastRedError = 0; nLastGreenError = 0; nLastBlueError = 0; for( i = 0; i < nXSize; i++ ) { int iIndex, nError, nSixth; int nRedValue, nGreenValue, nBlueValue; nRedValue = MAX(0,MIN(255, pabyRed[i] + nLastRedError)); nGreenValue = MAX(0,MIN(255, pabyGreen[i] + nLastGreenError)); nBlueValue = MAX(0,MIN(255, pabyBlue[i] + nLastBlueError)); if( psColorIndexMap ) { GUInt32 nColorCode = MAKE_COLOR_CODE(nRedValue, nGreenValue, nBlueValue); GUInt32 nIdx = nColorCode % PRIME_FOR_65536; //int nCollisions = 0; //static int nMaxCollisions = 0; while( TRUE ) { if( psColorIndexMap[nIdx].nColorCode == nColorCode ) { iIndex = psColorIndexMap[nIdx].nIndex; break; } if( (int)psColorIndexMap[nIdx].nColorCode < 0 ) { psColorIndexMap[nIdx].nColorCode = nColorCode; iIndex = FindNearestColor( nColors, anPCT, nRedValue, nGreenValue, nBlueValue ); psColorIndexMap[nIdx].nIndex = (GByte) iIndex; break; } if( psColorIndexMap[nIdx].nColorCode2 == nColorCode ) { iIndex = psColorIndexMap[nIdx].nIndex2; break; } if( (int)psColorIndexMap[nIdx].nColorCode2 < 0 ) { psColorIndexMap[nIdx].nColorCode2 = nColorCode; iIndex = FindNearestColor( nColors, anPCT, nRedValue, nGreenValue, nBlueValue ); psColorIndexMap[nIdx].nIndex2 = (GByte) iIndex; break; } if( psColorIndexMap[nIdx].nColorCode3 == nColorCode ) { iIndex = psColorIndexMap[nIdx].nIndex3; break; } if( (int)psColorIndexMap[nIdx].nColorCode3 < 0 ) { psColorIndexMap[nIdx].nColorCode3 = nColorCode; iIndex = FindNearestColor( nColors, anPCT, nRedValue, nGreenValue, nBlueValue ); psColorIndexMap[nIdx].nIndex3 = (GByte) iIndex; break; } do { //nCollisions ++; nIdx+=257; if( nIdx >= PRIME_FOR_65536 ) nIdx -= PRIME_FOR_65536; } while( (int)psColorIndexMap[nIdx].nColorCode >= 0 && psColorIndexMap[nIdx].nColorCode != nColorCode && (int)psColorIndexMap[nIdx].nColorCode2 >= 0 && psColorIndexMap[nIdx].nColorCode2 != nColorCode&& (int)psColorIndexMap[nIdx].nColorCode3 >= 0 && psColorIndexMap[nIdx].nColorCode3 != nColorCode ); /*if( nCollisions > nMaxCollisions ) { nMaxCollisions = nCollisions; printf("nCollisions = %d for R=%d,G=%d,B=%d\n", nCollisions, nRedValue, nGreenValue, nBlueValue); }*/ } } else if( pasDynamicColorMap == NULL ) { int iRed = nRedValue * nCLevels / 256; int iGreen = nGreenValue * nCLevels / 256; int iBlue = nBlueValue * nCLevels / 256; iIndex = pabyColorMap[iRed + iGreen * nCLevels + iBlue * nCLevels * nCLevels]; } else { GUInt32 nColorCode = MAKE_COLOR_CODE(nRedValue, nGreenValue, nBlueValue); GInt16* psIndex = &pasDynamicColorMap[nColorCode]; if( *psIndex < 0 ) iIndex = *psIndex = FindNearestColor( nColors, anPCT, nRedValue, nGreenValue, nBlueValue ); else iIndex = *psIndex; } pabyIndex[i] = (GByte) iIndex; if( !bDither ) continue; /* -------------------------------------------------------------------- */ /* Compute Red error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nRedValue - CAST_PCT(anPCT)[4*iIndex+0]; nSixth = nError / 6; panError[i*3 ] += nSixth; panError[i*3+6 ] = nSixth; panError[i*3+3 ] += nError - 5 * nSixth; nLastRedError = 2 * nSixth; /* -------------------------------------------------------------------- */ /* Compute Green error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nGreenValue - CAST_PCT(anPCT)[4*iIndex+1]; nSixth = nError / 6; panError[i*3 +1] += nSixth; panError[i*3+6+1] = nSixth; panError[i*3+3+1] += nError - 5 * nSixth; nLastGreenError = 2 * nSixth; /* -------------------------------------------------------------------- */ /* Compute Blue error, and carry it on to the next error line. */ /* -------------------------------------------------------------------- */ nError = nBlueValue - CAST_PCT(anPCT)[4*iIndex+2]; nSixth = nError / 6; panError[i*3 +2] += nSixth; panError[i*3+6+2] = nSixth; panError[i*3+3+2] += nError - 5 * nSixth; nLastBlueError = 2 * nSixth; } /* -------------------------------------------------------------------- */ /* Write results. */ /* -------------------------------------------------------------------- */ GDALRasterIO( hTarget, GF_Write, 0, iScanline, nXSize, 1, pabyIndex, nXSize, 1, GDT_Byte, 0, 0 ); } pfnProgress( 1.0, NULL, pProgressArg ); /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end_and_cleanup: CPLFree( pabyRed ); CPLFree( pabyGreen ); CPLFree( pabyBlue ); CPLFree( pabyIndex ); CPLFree( panError ); CPLFree( pabyColorMap ); return err; }
template<class T> int GDALComputeMedianCutPCTInternal( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, GByte* pabyRedBand, GByte* pabyGreenBand, GByte* pabyBlueBand, int (*pfnIncludePixel)(int, int, void*), int nColors, int nBits, T* panHistogram, // NULL, or >= size (1<<nBits)^3 * sizeof(T) bytes. GDALColorTableH hColorTable, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALComputeMedianCutPCT", CE_Failure ); VALIDATE_POINTER1( hGreen, "GDALComputeMedianCutPCT", CE_Failure ); VALIDATE_POINTER1( hBlue, "GDALComputeMedianCutPCT", CE_Failure ); CPLErr err = CE_None; /* -------------------------------------------------------------------- */ /* Validate parameters. */ /* -------------------------------------------------------------------- */ const int nXSize = GDALGetRasterBandXSize( hRed ); const int nYSize = GDALGetRasterBandYSize( hRed ); if( GDALGetRasterBandXSize( hGreen ) != nXSize || GDALGetRasterBandYSize( hGreen ) != nYSize || GDALGetRasterBandXSize( hBlue ) != nXSize || GDALGetRasterBandYSize( hBlue ) != nYSize ) { CPLError(CE_Failure, CPLE_IllegalArg, "Green or blue band doesn't match size of red band."); return CE_Failure; } if( pfnIncludePixel != NULL ) { CPLError(CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT() doesn't currently support " "pfnIncludePixel function."); return CE_Failure; } if( nColors <= 0 ) { CPLError(CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT(): " "nColors must be strictly greater than 1."); return CE_Failure; } if( nColors > 256 ) { CPLError(CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT(): " "nColors must be lesser than or equal to 256."); return CE_Failure; } if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* ==================================================================== */ /* STEP 1: create empty boxes. */ /* ==================================================================== */ if( static_cast<GUInt32>(nXSize) > std::numeric_limits<T>::max() / static_cast<GUInt32>(nYSize) ) { CPLError(CE_Warning, CPLE_AppDefined, "GDALComputeMedianCutPCTInternal() not called " "with large enough type"); } T nPixels = 0; if( nBits == 8 && pabyRedBand != NULL && pabyGreenBand != NULL && pabyBlueBand != NULL && static_cast<GUInt32>(nXSize) <= std::numeric_limits<T>::max() / static_cast<GUInt32>(nYSize) ) { nPixels = static_cast<T>(nXSize) * static_cast<T>(nYSize); } const int nCLevels = 1 << nBits; T* histogram = NULL; HashHistogram* psHashHistogram = NULL; if( panHistogram ) { if( nBits == 8 && static_cast<GUIntBig>(nXSize) * nYSize <= 65536 ) { // If the image is small enough, then the number of colors // will be limited and using a hashmap, rather than a full table // will be more efficient. histogram = NULL; psHashHistogram = (HashHistogram*)panHistogram; memset(psHashHistogram, 0xFF, sizeof(HashHistogram) * PRIME_FOR_65536); } else { histogram = panHistogram; memset(histogram, 0, nCLevels*nCLevels*nCLevels * sizeof(T)); } } else { histogram = static_cast<T*>( VSI_CALLOC_VERBOSE(nCLevels * nCLevels * nCLevels, sizeof(T))); if( histogram == NULL ) { return CE_Failure; } } Colorbox *box_list = static_cast<Colorbox *>(CPLMalloc(nColors*sizeof (Colorbox))); Colorbox *freeboxes = box_list; freeboxes[0].next = &freeboxes[1]; freeboxes[0].prev = NULL; for( int i = 1; i < nColors-1; ++i ) { freeboxes[i].next = &freeboxes[i+1]; freeboxes[i].prev = &freeboxes[i-1]; } freeboxes[nColors-1].next = NULL; freeboxes[nColors-1].prev = &freeboxes[nColors-2]; /* ==================================================================== */ /* Build histogram. */ /* ==================================================================== */ /* -------------------------------------------------------------------- */ /* Initialize the box datastructures. */ /* -------------------------------------------------------------------- */ Colorbox *ptr = freeboxes; freeboxes = ptr->next; if( freeboxes ) freeboxes->prev = NULL; Colorbox *usedboxes = NULL; // TODO(schwehr): What? ptr->next = usedboxes; usedboxes = ptr; if( ptr->next ) ptr->next->prev = ptr; ptr->rmin = 999; ptr->gmin = 999; ptr->bmin = 999; ptr->rmax = -1; ptr->gmax = -1; ptr->bmax = -1; ptr->total = static_cast<GUIntBig>(nXSize) * static_cast<GUIntBig>(nYSize); /* -------------------------------------------------------------------- */ /* Collect histogram. */ /* -------------------------------------------------------------------- */ // TODO(schwehr): Move these closer to usage after removing gotos. const int nColorShift = 8 - nBits; int nColorCounter = 0; GByte anRed[256] = {}; GByte anGreen[256] = {}; GByte anBlue[256] = {}; GByte *pabyRedLine = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nXSize)); GByte *pabyGreenLine = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nXSize)); GByte *pabyBlueLine = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nXSize)); if( pabyRedLine == NULL || pabyGreenLine == NULL || pabyBlueLine == NULL ) { err = CE_Failure; goto end_and_cleanup; } for( int iLine = 0; iLine < nYSize; iLine++ ) { if( !pfnProgress( iLine / static_cast<double>(nYSize), "Generating Histogram", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } err = GDALRasterIO( hRed, GF_Read, 0, iLine, nXSize, 1, pabyRedLine, nXSize, 1, GDT_Byte, 0, 0 ); if( err == CE_None ) err = GDALRasterIO( hGreen, GF_Read, 0, iLine, nXSize, 1, pabyGreenLine, nXSize, 1, GDT_Byte, 0, 0 ); if( err == CE_None ) err = GDALRasterIO( hBlue, GF_Read, 0, iLine, nXSize, 1, pabyBlueLine, nXSize, 1, GDT_Byte, 0, 0 ); if( err != CE_None ) goto end_and_cleanup; for( int iPixel = 0; iPixel < nXSize; iPixel++ ) { const int nRed = pabyRedLine[iPixel] >> nColorShift; const int nGreen = pabyGreenLine[iPixel] >> nColorShift; const int nBlue = pabyBlueLine[iPixel] >> nColorShift; ptr->rmin = std::min(ptr->rmin, nRed); ptr->gmin = std::min(ptr->gmin, nGreen); ptr->bmin = std::min(ptr->bmin, nBlue); ptr->rmax = std::max(ptr->rmax, nRed); ptr->gmax = std::max(ptr->gmax, nGreen); ptr->bmax = std::max(ptr->bmax, nBlue); bool bFirstOccurrence; if( psHashHistogram ) { int* pnColor = FindAndInsertColorCount(psHashHistogram, MAKE_COLOR_CODE(nRed, nGreen, nBlue)); bFirstOccurrence = ( *pnColor == 0 ); (*pnColor)++; } else { T* pnColor = HISTOGRAM(histogram, nCLevels, nRed, nGreen, nBlue); bFirstOccurrence = ( *pnColor == 0 ); (*pnColor)++; } if( bFirstOccurrence) { if( nColorShift == 0 && nColorCounter < nColors ) { anRed[nColorCounter] = static_cast<GByte>(nRed); anGreen[nColorCounter] = static_cast<GByte>(nGreen); anBlue[nColorCounter] = static_cast<GByte>(nBlue); } nColorCounter++; } } } if( !pfnProgress( 1.0, "Generating Histogram", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } if( nColorShift == 0 && nColorCounter <= nColors ) { #if DEBUG_VERBOSE CPLDebug("MEDIAN_CUT", "%d colors found <= %d", nColorCounter, nColors); #endif for( int iColor = 0; iColor < nColorCounter; iColor++ ) { const GDALColorEntry sEntry = { static_cast<GByte>(anRed[iColor]), static_cast<GByte>(anGreen[iColor]), static_cast<GByte>(anBlue[iColor]), 255 }; GDALSetColorEntry( hColorTable, iColor, &sEntry ); } goto end_and_cleanup; } /* ==================================================================== */ /* STEP 3: continually subdivide boxes until no more free */ /* boxes remain or until all colors assigned. */ /* ==================================================================== */ while( freeboxes != NULL ) { ptr = largest_box(usedboxes); if( ptr != NULL ) splitbox(ptr, histogram, psHashHistogram, nCLevels, &freeboxes, &usedboxes, pabyRedBand, pabyGreenBand, pabyBlueBand, nPixels); else freeboxes = NULL; } /* ==================================================================== */ /* STEP 4: assign colors to all boxes */ /* ==================================================================== */ ptr = usedboxes; for( int i = 0; ptr != NULL; ++i, ptr = ptr->next ) { const GDALColorEntry sEntry = { static_cast<GByte>(((ptr->rmin + ptr->rmax) << nColorShift) / 2), static_cast<GByte>(((ptr->gmin + ptr->gmax) << nColorShift) / 2), static_cast<GByte>(((ptr->bmin + ptr->bmax) << nColorShift) / 2), 255 }; GDALSetColorEntry( hColorTable, i, &sEntry ); } end_and_cleanup: CPLFree( pabyRedLine ); CPLFree( pabyGreenLine ); CPLFree( pabyBlueLine ); // We're done with the boxes now. CPLFree(box_list); freeboxes = NULL; usedboxes = NULL; if( panHistogram == NULL ) CPLFree( histogram ); return err; }
int main( int argc, char *argv[] ) { if( argc < 7 ) { usage(); return 1; } int row, col; double geomx[6]={0.0}; char *inB1 = argv[1]; //Albedo char *inB2 = argv[2]; //DEM char *inB3 = argv[3]; //e0 31 char *inB4 = argv[4]; //e0 32 char *inB5 = argv[5]; //LST char *rnetdF = argv[6]; float doy = atof( argv[7] ); // printf("\ndoy\t= %7.2f\n\n",doy); // printf("%s %s %s %s %s\n",inB1, inB2, inB3, inB4, inB5); GDALAllRegister(); GDALDatasetH hD1 = GDALOpen(inB1,GA_ReadOnly);//Albedo GDALDatasetH hD2 = GDALOpen(inB2,GA_ReadOnly);//DEM GDALDatasetH hD3 = GDALOpen(inB3,GA_ReadOnly);//E 31 GDALDatasetH hD4 = GDALOpen(inB4,GA_ReadOnly);//E 32 GDALDatasetH hD5 = GDALOpen(inB5,GA_ReadOnly);//LST if(hD1==NULL||hD2==NULL||hD3==NULL||hD4==NULL||hD5==NULL){ printf("One or more input files "); printf("could not be loaded\n"); exit(1); } if(GDALGetGeoTransform(hD1,geomx)==CE_None){ /* Do Nothing */ // printf( "Origin (ULx,ULy) = (%.6f,%.6f)\n", geomx[0], geomx[3] ); // printf( "Pixel Size = (%.6f,%.6f)\n", geomx[1], geomx[5] ); // printf( "Rot0 = (%.6f,%.6f)\n", geomx[2], geomx[4] ); } else { printf("ERROR: Projection acquisition problem from Band1\n"); exit(1); } GDALDriverH hDr2 = GDALGetDatasetDriver(hD2); //RNETD out GDALDatasetH hDOut = GDALCreateCopy( hDr2, rnetdF,hD2,FALSE,NULL,NULL,NULL); GDALRasterBandH hBOut = GDALGetRasterBand(hDOut,1); GDALRasterBandH hB1 = GDALGetRasterBand(hD1,1);//Albedo GDALRasterBandH hB2 = GDALGetRasterBand(hD2,1);//DEM GDALRasterBandH hB3 = GDALGetRasterBand(hD3,1);//E 31 GDALRasterBandH hB4 = GDALGetRasterBand(hD4,1);//E 32 GDALRasterBandH hB5 = GDALGetRasterBand(hD5,1);//LST int nX = GDALGetRasterBandXSize(hB1); int nY = GDALGetRasterBandYSize(hB1); float *mat1 = (float *) malloc(sizeof(float)*nX); float *mat2 = (float *) malloc(sizeof(float)*nX); float *mat3 = (float *) malloc(sizeof(float)*nX); float *mat4 = (float *) malloc(sizeof(float)*nX); float *mat5 = (float *) malloc(sizeof(float)*nX); float *matOut = (float *) malloc(sizeof(float)*nX); /* int i,temp,histogramT[512]; for (i=0;i<512;i++){ histogramT[i]=0; }*/ float solar, rnetd, e0; for(row=0;row<nY;row++){ GDALRasterIO(hB1,GF_Read,0,row,nX,1,mat1,nX,1,GDT_Float32,0,0); GDALRasterIO(hB2,GF_Read,0,row,nX,1,mat2,nX,1,GDT_Float32,0,0); GDALRasterIO(hB3,GF_Read,0,row,nX,1,mat3,nX,1,GDT_Float32,0,0); GDALRasterIO(hB4,GF_Read,0,row,nX,1,mat4,nX,1,GDT_Float32,0,0); GDALRasterIO(hB5,GF_Read,0,row,nX,1,mat5,nX,1,GDT_Float32,0,0); #pragma omp parallel for default(none) \ private(col, solar, rnetd, e0)\ shared( row, doy, geomx,nX, \ mat1, mat2, mat3, mat4, mat5, matOut ) for(col=0;col<nX;col++){ if(mat1[col]==-28768||mat5[col]==-28768||mat5[col]==0){ matOut[col] = -28768; }else { /*temp = (int) (mat1[col]); if(temp>0) histogramT[temp]=histogramT[temp]+1.0;*/ // printf("lat=%f\n", geomx[3]+geomx[4]*col+geomx[5]*row); // printf("%f \n",e0); e0 = 0.5*((mat3[col]*0.002+0.49)+(mat4[col]*0.002+0.49)); solar = solar_day(geomx[3]+geomx[4]*col+geomx[5]*row, doy, mat2[col] ); //rnetd = r_net_d( mat1[col]*0.001, solar, e0, mat5[col]*0.02, mat2[col]); rnetd = r_net_day( mat1[col]*0.001, solar, mat2[col]); matOut[col]=rnetd; } } #pragma omp barrier GDALRasterIO(hBOut,GF_Write,0,row,nX,1,matOut,nX,1,GDT_Float32,0,0); } GDALClose(hDOut); /* for (i=0;i<512;i++){ printf("%i\t%i\n",i,histogramT[i]); }*/ //free memory close unused files if(mat1 != NULL) free(mat1); if(mat2 != NULL) free(mat2); if(mat3 != NULL) free(mat3); if(mat4 != NULL) free(mat4); if(mat5 != NULL) free(mat5); if(matOut != NULL) free(matOut); GDALClose(hD1); GDALClose(hD2); GDALClose(hD3); GDALClose(hD4); GDALClose(hD5); return(EXIT_SUCCESS); }
extern "C" int CPL_STDCALL GDALComputeMedianCutPCT( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, int (*pfnIncludePixel)(int,int,void*), int nColors, GDALColorTableH hColorTable, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALComputeMedianCutPCT", CE_Failure ); VALIDATE_POINTER1( hGreen, "GDALComputeMedianCutPCT", CE_Failure ); VALIDATE_POINTER1( hBlue, "GDALComputeMedianCutPCT", CE_Failure ); int nXSize, nYSize; CPLErr err = CE_None; /* -------------------------------------------------------------------- */ /* Validate parameters. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize( hRed ); nYSize = GDALGetRasterBandYSize( hRed ); if( GDALGetRasterBandXSize( hGreen ) != nXSize || GDALGetRasterBandYSize( hGreen ) != nYSize || GDALGetRasterBandXSize( hBlue ) != nXSize || GDALGetRasterBandYSize( hBlue ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "Green or blue band doesn't match size of red band.\n" ); return CE_Failure; } if( pfnIncludePixel != NULL ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT() doesn't currently support " " pfnIncludePixel function." ); return CE_Failure; } if ( nColors <= 0 ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT() : nColors must be strictly greater than 1." ); return CE_Failure; } if ( nColors > 256 ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT() : nColors must be lesser than or equal to 256." ); return CE_Failure; } if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* ==================================================================== */ /* STEP 1: crate empty boxes. */ /* ==================================================================== */ int i; Colorbox *box_list, *ptr; int (*histogram)[GMC_B_LEN][GMC_B_LEN]; Colorbox *freeboxes; Colorbox *usedboxes; histogram = (int (*)[GMC_B_LEN][GMC_B_LEN]) CPLCalloc(GMC_B_LEN * GMC_B_LEN * GMC_B_LEN,sizeof(int)); usedboxes = NULL; box_list = freeboxes = (Colorbox *)CPLMalloc(nColors*sizeof (Colorbox)); freeboxes[0].next = &freeboxes[1]; freeboxes[0].prev = NULL; for (i = 1; i < nColors-1; ++i) { freeboxes[i].next = &freeboxes[i+1]; freeboxes[i].prev = &freeboxes[i-1]; } freeboxes[nColors-1].next = NULL; freeboxes[nColors-1].prev = &freeboxes[nColors-2]; /* ==================================================================== */ /* Build histogram. */ /* ==================================================================== */ GByte *pabyRedLine, *pabyGreenLine, *pabyBlueLine; int iLine, iPixel; /* -------------------------------------------------------------------- */ /* Initialize the box datastructures. */ /* -------------------------------------------------------------------- */ ptr = freeboxes; freeboxes = ptr->next; if (freeboxes) freeboxes->prev = NULL; ptr->next = usedboxes; usedboxes = ptr; if (ptr->next) ptr->next->prev = ptr; ptr->rmin = ptr->gmin = ptr->bmin = 999; ptr->rmax = ptr->gmax = ptr->bmax = -1; ptr->total = nXSize * nYSize; /* -------------------------------------------------------------------- */ /* Collect histogram. */ /* -------------------------------------------------------------------- */ pabyRedLine = (GByte *) VSIMalloc(nXSize); pabyGreenLine = (GByte *) VSIMalloc(nXSize); pabyBlueLine = (GByte *) VSIMalloc(nXSize); if (pabyRedLine == NULL || pabyGreenLine == NULL || pabyBlueLine == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSIMalloc(): Out of memory in GDALComputeMedianCutPCT" ); err = CE_Failure; goto end_and_cleanup; } for( iLine = 0; iLine < nYSize; iLine++ ) { if( !pfnProgress( iLine / (double) nYSize, "Generating Histogram", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } GDALRasterIO( hRed, GF_Read, 0, iLine, nXSize, 1, pabyRedLine, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hGreen, GF_Read, 0, iLine, nXSize, 1, pabyGreenLine, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hBlue, GF_Read, 0, iLine, nXSize, 1, pabyBlueLine, nXSize, 1, GDT_Byte, 0, 0 ); for( iPixel = 0; iPixel < nXSize; iPixel++ ) { int nRed, nGreen, nBlue; nRed = pabyRedLine[iPixel] >> COLOR_SHIFT; nGreen = pabyGreenLine[iPixel] >> COLOR_SHIFT; nBlue = pabyBlueLine[iPixel] >> COLOR_SHIFT; ptr->rmin = MIN(ptr->rmin, nRed); ptr->gmin = MIN(ptr->gmin, nGreen); ptr->bmin = MIN(ptr->bmin, nBlue); ptr->rmax = MAX(ptr->rmax, nRed); ptr->gmax = MAX(ptr->gmax, nGreen); ptr->bmax = MAX(ptr->bmax, nBlue); histogram[nRed][nGreen][nBlue]++; } } if( !pfnProgress( 1.0, "Generating Histogram", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } /* ==================================================================== */ /* STEP 3: continually subdivide boxes until no more free */ /* boxes remain or until all colors assigned. */ /* ==================================================================== */ while (freeboxes != NULL) { ptr = largest_box(usedboxes); if (ptr != NULL) splitbox(ptr, histogram, &freeboxes, &usedboxes); else freeboxes = NULL; } /* ==================================================================== */ /* STEP 4: assign colors to all boxes */ /* ==================================================================== */ for (i = 0, ptr = usedboxes; ptr != NULL; ++i, ptr = ptr->next) { GDALColorEntry sEntry; sEntry.c1 = (GByte) (((ptr->rmin + ptr->rmax) << COLOR_SHIFT) / 2); sEntry.c2 = (GByte) (((ptr->gmin + ptr->gmax) << COLOR_SHIFT) / 2); sEntry.c3 = (GByte) (((ptr->bmin + ptr->bmax) << COLOR_SHIFT) / 2); sEntry.c4 = 255; GDALSetColorEntry( hColorTable, i, &sEntry ); } end_and_cleanup: CPLFree( pabyRedLine ); CPLFree( pabyGreenLine ); CPLFree( pabyBlueLine ); /* We're done with the boxes now */ CPLFree(box_list); freeboxes = usedboxes = NULL; CPLFree( histogram ); return err; }
void convert(const input_arguments& args) { if(args.verbose) std::cout << "\n\tbuffering data... " << std::flush; scietl::core::GDALDatasetPtr dataset(GDALOpen(args.source_file_name.c_str(), GA_ReadOnly)); if(dataset == nullptr) { boost::format err_msg("could not open dataset: '%1%'!"); throw scietl::gdal_error() << scietl::error_description((err_msg % args.source_file_name).str()); } if(GDALGetRasterCount(dataset) != 1) { boost::format err_msg("invalid raster data: %1%. It must have only one data band!"); throw scietl::gdal_error() << scietl::error_description((err_msg % args.source_file_name).str()); } GDALRasterBandH band = GDALGetRasterBand(dataset, 1); if(band == 0) { boost::format err_msg("could not access band data for file: %1%!"); throw scietl::gdal_error() << scietl::error_description((err_msg % args.source_file_name).str()); } int ncols = GDALGetRasterBandXSize(band); int nrows = GDALGetRasterBandYSize(band); if((ncols != 1021) || (nrows != 1381)) { boost::format err_msg("invalid raster size: %1%. It must be a 1021x1381!"); throw scietl::gdal_error() << scietl::error_description((err_msg % args.source_file_name).str()); } GDALDataType pixel_type = GDALGetRasterDataType(band); if(pixel_type != GDT_Byte) { boost::format err_msg("invalid raster pixel type: %1%. It must be a raster with a single band with pixels of byte data type!"); throw scietl::gdal_error() << scietl::error_description((err_msg % args.source_file_name).str()); } std::size_t pixel_size = scietl::core::num_bytes(pixel_type); boost::shared_array<unsigned char> buffer(new unsigned char[ncols * nrows * pixel_size]); CPLErr result = GDALRasterIO(band, GF_Read, 0, 0, ncols, nrows, buffer.get(), ncols, nrows, pixel_type, 0, 0); if(result == CE_Failure) { boost::format err_msg("could not read dataset: '%1%'!"); throw scietl::gdal_error() << scietl::error_description((err_msg % args.source_file_name).str()); } if(args.verbose) { std::cout << "OK!" << std::flush; std::cout << "\n\tsaving data... " << std::flush; } std::ofstream f(args.target_file_name.c_str(), std::ios::binary); if(!f.is_open()) { boost::format err_msg("could not create file: '%1%'. Please, check if target file or dir exist."); throw scietl::gdal_error() << scietl::error_description((err_msg % args.target_file_name).str()); } unsigned char* bookmark = buffer.get(); for(int i = 0; i != nrows; ++i) { for(int j = 0; j != ncols; ++j) { int16_t col = static_cast<int16_t>(j); int16_t row = static_cast<int16_t>(j); int16_t t = args.time_point; f.write(reinterpret_cast<char*>(&col), sizeof(int16_t)); f.write(reinterpret_cast<char*>(&row), sizeof(int16_t)); f.write(reinterpret_cast<char*>(&t), sizeof(int16_t)); f.write(reinterpret_cast<char*>(bookmark), pixel_size); bookmark += pixel_size; } } f.close(); }
int WIDInterpolate( int nPoints, double *padfX, double *padfY, double *padfValue, double *padfWeight, GDALRasterBandH hBand, double fExponent, GDALProgressFunc pfnProgress, void * pCBData ) { int nXSize, nYSize, nError = CPLE_None, iY, iPoint; float *pafScanline; double *padfDeltaYSquared; if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; nXSize = GDALGetRasterBandXSize( hBand ); nYSize = GDALGetRasterBandYSize( hBand ); padfDeltaYSquared = (double *) CPLMalloc(sizeof(double) * nPoints); pafScanline = (float *) CPLMalloc(sizeof(float) * nXSize); for( iY = 0; iY < nYSize; iY++ ) { int iX; if( !pfnProgress( iY / (double) nYSize, NULL, pCBData ) ) { nError = CPLE_UserInterrupt; break; } /* Precompute DeltaY Squared for point. It will remain constant over the scanline. */ for( iPoint = 0; iPoint < nPoints; iPoint++ ) { padfDeltaYSquared[iPoint] = (padfY[iPoint]-(double)iY) * (padfY[iPoint]-(double)iY); } for( iX = 0; iX < nXSize; iX++ ) { double dfNumerator=0.0, dfDenominator = 0.0; double dfX = iX; for( iPoint = 0; iPoint < nPoints; iPoint++ ) { double dfDistSquared, dfDeltaX; double dfWeight; dfDeltaX = (padfX[iPoint] - dfX); dfDistSquared = dfDeltaX*dfDeltaX + padfDeltaYSquared[iPoint]; if (fExponent != 2.0) { //if the exponent is not 2, use the exponent / 2 //as the distance is already squared dfDistSquared = pow(dfDistSquared, fExponent / 2.0); } if( padfWeight == NULL ) dfWeight = 1.0 / dfDistSquared; else dfWeight = padfWeight[iPoint] / dfDistSquared; dfDenominator += dfWeight; dfNumerator += dfWeight * padfValue[iPoint]; } pafScanline[iX] = dfNumerator / dfDenominator; } GDALRasterIO( hBand, GF_Write, 0, iY, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); } pfnProgress( 1.0, NULL, pCBData ); CPLFree( pafScanline ); CPLFree( padfDeltaYSquared ); return nError; }
static CPLErr GDALMultiFilter( GDALRasterBandH hTargetBand, GDALRasterBandH hTargetMaskBand, GDALRasterBandH hFiltMaskBand, int nIterations, GDALProgressFunc pfnProgress, void * pProgressArg ) { float *paf3PassLineBuf; GByte *pabyTMaskBuf; GByte *pabyFMaskBuf; float *pafThisPass, *pafLastPass, *pafSLastPass; int nBufLines = nIterations + 2; int iPassCounter = 0; int nNewLine; // the line being loaded this time (zero based scanline) int nXSize = GDALGetRasterBandXSize( hTargetBand ); int nYSize = GDALGetRasterBandYSize( hTargetBand ); CPLErr eErr = CE_None; /* -------------------------------------------------------------------- */ /* Report starting progress value. */ /* -------------------------------------------------------------------- */ if( !pfnProgress( 0.0, "Smoothing Filter...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Allocate rotating buffers. */ /* -------------------------------------------------------------------- */ pabyTMaskBuf = (GByte *) VSIMalloc2(nXSize, nBufLines); pabyFMaskBuf = (GByte *) VSIMalloc2(nXSize, nBufLines); paf3PassLineBuf = (float *) VSIMalloc3(nXSize, nBufLines, 3 * sizeof(float)); if (pabyTMaskBuf == NULL || pabyFMaskBuf == NULL || paf3PassLineBuf == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Could not allocate enough memory for temporary buffers"); eErr = CE_Failure; goto end; } /* -------------------------------------------------------------------- */ /* Process rotating buffers. */ /* -------------------------------------------------------------------- */ for( nNewLine = 0; eErr == CE_None && nNewLine < nYSize+nIterations; nNewLine++ ) { /* -------------------------------------------------------------------- */ /* Rotate pass buffers. */ /* -------------------------------------------------------------------- */ iPassCounter = (iPassCounter + 1) % 3; pafSLastPass = paf3PassLineBuf + ((iPassCounter+0)%3) * nXSize*nBufLines; pafLastPass = paf3PassLineBuf + ((iPassCounter+1)%3) * nXSize*nBufLines; pafThisPass = paf3PassLineBuf + ((iPassCounter+2)%3) * nXSize*nBufLines; /* -------------------------------------------------------------------- */ /* Where does the new line go in the rotating buffer? */ /* -------------------------------------------------------------------- */ int iBufOffset = nNewLine % nBufLines; /* -------------------------------------------------------------------- */ /* Read the new data line if it is't off the bottom of the */ /* image. */ /* -------------------------------------------------------------------- */ if( nNewLine < nYSize ) { eErr = GDALRasterIO( hTargetMaskBand, GF_Read, 0, nNewLine, nXSize, 1, pabyTMaskBuf + nXSize * iBufOffset, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hFiltMaskBand, GF_Read, 0, nNewLine, nXSize, 1, pabyFMaskBuf + nXSize * iBufOffset, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hTargetBand, GF_Read, 0, nNewLine, nXSize, 1, pafThisPass + nXSize * iBufOffset, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; } /* -------------------------------------------------------------------- */ /* Loop over the loaded data, applying the filter to all loaded */ /* lines with neighbours. */ /* -------------------------------------------------------------------- */ int iFLine; for( iFLine = nNewLine-1; eErr == CE_None && iFLine >= nNewLine-nIterations; iFLine-- ) { int iLastOffset, iThisOffset, iNextOffset; iLastOffset = (iFLine-1) % nBufLines; iThisOffset = (iFLine ) % nBufLines; iNextOffset = (iFLine+1) % nBufLines; // default to preserving the old value. if( iFLine >= 0 ) memcpy( pafThisPass + iThisOffset * nXSize, pafLastPass + iThisOffset * nXSize, sizeof(float) * nXSize ); // currently this skips the first and last line. Eventually // we will enable these too. TODO if( iFLine < 1 || iFLine >= nYSize-1 ) { continue; } GDALFilterLine( pafSLastPass + iLastOffset * nXSize, pafLastPass + iThisOffset * nXSize, pafThisPass + iNextOffset * nXSize, pafThisPass + iThisOffset * nXSize, pabyTMaskBuf + iLastOffset * nXSize, pabyTMaskBuf + iThisOffset * nXSize, pabyTMaskBuf + iNextOffset * nXSize, pabyFMaskBuf + iThisOffset * nXSize, nXSize ); } /* -------------------------------------------------------------------- */ /* Write out the top data line that will be rolling out of our */ /* buffer. */ /* -------------------------------------------------------------------- */ int iLineToSave = nNewLine - nIterations; if( iLineToSave >= 0 && eErr == CE_None ) { iBufOffset = iLineToSave % nBufLines; eErr = GDALRasterIO( hTargetBand, GF_Write, 0, iLineToSave, nXSize, 1, pafThisPass + nXSize * iBufOffset, nXSize, 1, GDT_Float32, 0, 0 ); } /* -------------------------------------------------------------------- */ /* Report progress. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( (nNewLine+1) / (double) (nYSize+nIterations), "Smoothing Filter...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end: CPLFree( pabyTMaskBuf ); CPLFree( pabyFMaskBuf ); CPLFree( paf3PassLineBuf ); return eErr; }
int main( int argc, char *argv[] ) { if( argc < 3 ) { usage(); return 1; } //Loading the input files names //----------------------------- char *inB1 = argv[1]; //ETpotd char *inB2 = argv[2]; //ETa char *inB3 = argv[3]; //FC char *taF = argv[4]; //Ta Gap Outfile //Loading the input files //----------------------- GDALAllRegister(); GDALDatasetH hD1 = GDALOpen(inB1,GA_ReadOnly);//ETpotd GDALDatasetH hD2 = GDALOpen(inB2,GA_ReadOnly);//ETa GDALDatasetH hD3 = GDALOpen(inB3,GA_ReadOnly);//FC if(hD1==NULL||hD2==NULL||hD3==NULL){ printf("One or more input files "); printf("could not be loaded\n"); exit(EXIT_FAILURE); } //Loading the file infos //---------------------- GDALDriverH hDr1 = GDALGetDatasetDriver(hD1); GDALDatasetH hDOut = GDALCreateCopy(hDr1,taF,hD1,FALSE,NULL,NULL,NULL); GDALRasterBandH hBOut = GDALGetRasterBand(hDOut,1); GDALRasterBandH hB1 = GDALGetRasterBand(hD1,1);//ETpotd GDALRasterBandH hB2 = GDALGetRasterBand(hD2,1);//ETa GDALRasterBandH hB3 = GDALGetRasterBand(hD3,1);//FC int nX = GDALGetRasterBandXSize(hB1); int nY = GDALGetRasterBandYSize(hB1); int N = nX*nY; float *l1 = (float *) malloc(sizeof(float)*N); float *l2 = (float *) malloc(sizeof(float)*N); short int *l3 = (short int *) malloc(sizeof(short int)*N); float *lOut = (float *) malloc(sizeof(float)*N); int rowcol; GDALRasterIO(hB1,GF_Read,0,0,nX,nY,l1,nX,nY,GDT_Float32,0,0); GDALRasterIO(hB2,GF_Read,0,0,nX,nY,l2,nX,nY,GDT_Float32,0,0); GDALRasterIO(hB3,GF_Read,0,0,nX,nY,l3,nX,nY,GDT_Int16,0,0); #pragma omp parallel for default(none) \ private (rowcol) shared (N, l1, l2, l3, lOut) for(rowcol=0;rowcol<N;rowcol++){ if(l1[rowcol] < 0 || l2[rowcol] < 0 || l3[rowcol] < 0) lOut[rowcol] = -28768; else //FC is in percentage lOut[rowcol] = (l1[rowcol] - l2[rowcol]) * l3[rowcol] / 100.0; } #pragma omp barrier GDALRasterIO(hBOut,GF_Write,0,0,nX,nY,lOut,nX,nY,GDT_Float32,0,0); if( l1 != NULL ) free( l1 ); if( l2 != NULL ) free( l2 ); if( l3 != NULL ) free( l3 ); GDALClose(hD1); GDALClose(hD2); GDALClose(hD3); GDALClose(hDOut); return(EXIT_SUCCESS); }
int main(int argc, char* argv[]) { fprintf(stderr, "TASSELED CAP TRANSFORMATION\nVersion %s.%s. Free software. GNU General Public License, version 3\n", PROG_VERSION, DATE_VERSION); fprintf(stderr, "Copyright (C) 2016 Igor Garkusha.\nUkraine, Dnipro\n\n"); if(argc!=5) { fputs("Input parameters not found!\n", stderr); printHelp(); fputs("\n", stderr); return 1; } GDALDatasetH pSrcDataset = NULL; GDALDatasetH pDstDataset = NULL; GDALRasterBandH pSrcBand = NULL; GDALRasterBandH pDstBand = NULL; GDALDriverH pDriver = NULL; GDALAllRegister(); bool flagNoData = (atoi(argv[argc-1]) == 1)?true:false; int sensorIndexFlag = OLI; if( strcmp(argv[argc-2], "oli") == 0) sensorIndexFlag = OLI; else if( strcmp(argv[argc-2], "etm") == 0) sensorIndexFlag = ETM; else if( strcmp(argv[argc-2], "tm4") == 0) sensorIndexFlag = TM4; else if( strcmp(argv[argc-2], "tm5") == 0) sensorIndexFlag = TM5; else //if( strcmp(argv[argc-2], "msi10") == 0) sensorIndexFlag = S2AMSI10; //else if( strcmp(argv[argc-2], "msi") == 0) sensorIndexFlag = S2AMSI; pSrcDataset = GDALOpen( argv[1], GA_ReadOnly ); int bands = 0; if(pSrcDataset!=NULL) { if(CUtils::isFloat32DataType(pSrcDataset)) { bands = GDALGetRasterCount(pSrcDataset); if( ((bands == 6)||(bands == 4)) ) { pSrcBand = GDALGetRasterBand(pSrcDataset, 1); if(pSrcBand != NULL) { int cols = GDALGetRasterBandXSize(pSrcBand); int rows = GDALGetRasterBandYSize(pSrcBand); float NoDataValue = 0; pDriver = GDALGetDriverByName("GTiff"); char **papszOptions = NULL; pDstDataset = GDALCreate(pDriver, argv[2], cols, rows, COUNT_OUT_BANDS, GDT_Float32, papszOptions); double adfGeoTransform[6]={0}; GDALGetGeoTransform(pSrcDataset, adfGeoTransform ); const char *szProjection = GDALGetProjectionRef(pSrcDataset); GDALSetGeoTransform(pDstDataset, adfGeoTransform ); GDALSetProjection(pDstDataset, szProjection ); pDstBand = GDALGetRasterBand(pDstDataset, 1); float *pSrcLine = NULL; float *pDstLine = NULL; pSrcLine = (float*)CPLMalloc(sizeof(GDALGetRasterDataType(pSrcBand))*cols); pDstLine = (float*)CPLMalloc(sizeof(GDALGetRasterDataType(pDstBand))*cols); if(flagNoData == false) { for(int resultBandNumber=1; resultBandNumber <= COUNT_OUT_BANDS; resultBandNumber++) { fprintf(stderr, "Processing for band %d...\n", resultBandNumber); pDstBand = GDALGetRasterBand(pDstDataset, resultBandNumber); int pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS); for(int i=0; i<rows; i++) { for(int j=0; j<cols; j++) pDstLine[j] = 0; for(int currentBandNumber=1; currentBandNumber <= bands; currentBandNumber++) { pSrcBand = GDALGetRasterBand(pSrcDataset, currentBandNumber); GDALRasterIO(pSrcBand, GF_Read, 0, i, cols, 1, pSrcLine, cols, 1, GDALGetRasterDataType(pSrcBand), 0, 0 ); for(int j=0; j<cols; j++) pDstLine[j] += getTasseledCapValue(pSrcLine[j], sensorIndexFlag, resultBandNumber, currentBandNumber); } if(sensorIndexFlag == TM5) for(int j=0; j<cols; j++) pDstLine[j] += TM5_TCCoeff[resultBandNumber][6]; GDALRasterIO(pDstBand, GF_Write, 0, i, cols, 1, pDstLine, cols, 1, GDT_Float32, 0, 0 ); pr = CUtils::progress_ln_ex(stderr, i, rows, pr); } CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS); } } else // WITH NODATA VALUE - pixel(1,1) { for(int resultBandNumber=1; resultBandNumber <= COUNT_OUT_BANDS; resultBandNumber++) { fprintf(stderr, "Processing for band %d...\n", resultBandNumber); pDstBand = GDALGetRasterBand(pDstDataset, resultBandNumber); int pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS); for(int i=0; i<rows; i++) { for(int j=0; j<cols; j++) pDstLine[j] = 0; for(int currentBandNumber=1; currentBandNumber <= bands; currentBandNumber++) { pSrcBand = GDALGetRasterBand(pSrcDataset, currentBandNumber); NoDataValue = CUtils::getFloatNoDataValueAsBackground(pSrcBand); GDALRasterIO(pSrcBand, GF_Read, 0, i, cols, 1, pSrcLine, cols, 1, GDALGetRasterDataType(pSrcBand), 0, 0 ); for(int j=0; j<cols; j++) { if(NoDataValue == pSrcLine[j]) pDstLine[j] = NoDataValue; else pDstLine[j] += getTasseledCapValue(pSrcLine[j], sensorIndexFlag, resultBandNumber, currentBandNumber); } } if(sensorIndexFlag == TM5) { for(int j=0; j<cols; j++) if(NoDataValue != pDstLine[j]) pDstLine[j] += TM5_TCCoeff[resultBandNumber][6]; } GDALRasterIO(pDstBand, GF_Write, 0, i, cols, 1, pDstLine, cols, 1, GDT_Float32, 0, 0 ); pr = CUtils::progress_ln_ex(stderr, i, rows, pr); } CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS); } } CPLFree(pSrcLine); pSrcLine = NULL; CPLFree(pDstLine); pDstLine = NULL; if(flagNoData) CUtils::calculateFloatGeoTIFFStatistics(pDstDataset, -1, true); else CUtils::calculateFloatGeoTIFFStatistics(pDstDataset, -1, false); fputs("Output band:\n\tband1: Brightness, band2: Greenness (Vegetation), band3: Wetness, band4: Haze\n\n", stderr); fputs("\nEnd Processing.\n\n", stderr); } } else { fputs("\nERROR: Source Band Number is Invalid!!!\n", stderr); fprintf(stderr, "Source Bands Number: %d!\n\n", bands); printHelp(); } } if(pSrcDataset!=NULL) { GDALClose(pSrcDataset); } if(pDstDataset!=NULL) { GDALClose(pDstDataset); } } return 0; }
int equalize_density(char *infile, char *outfile, int fast, int accurate) { int xsize, ysize; // Size of the density grid. double *gridx, *gridy; // Array for grid double **rho; // Initial population density GDALDatasetH hDataset; // The input density raster file. GDALRasterBandH hBand; // The raster band we are going to use. FILE *outfp; // The morphing file (a text file). double adfGeoTransform[6]; // For the georeference of the raster. // Register all GDAL drivers. GDALAllRegister(); #if defined (_OPENMP) omp_set_num_threads(omp_get_num_procs()); #endif hDataset = GDALOpen(infile, GA_ReadOnly); if (hDataset == NULL) { fprintf(stderr,"Error. Unable to open file `%s'\n", infile); exit(1); } outfp = fopen(outfile, "w"); if (outfp == NULL) { fprintf(stderr,"Error. Unable to open file `%s'\n", outfile); exit(1); } // Get the raster band for the dataset; we are using the first band. hBand = GDALGetRasterBand(hDataset, 1); if (hBand == NULL) { fprintf(stderr, "Error. Unable to read band 1 in file `%s'\n", infile); exit(1); } // Determine the raster size xsize = GDALGetRasterBandXSize(hBand); ysize = GDALGetRasterBandYSize(hBand); // Allocate space for the cartogram code to use cart_makews(xsize, ysize); // Read in the population data, transform it, then destroy it again rho = cart_dmalloc(xsize, ysize); if (readpop(hBand, rho, xsize, ysize)) { fprintf(stderr,"Error. Density file contains too few or incorrect data\n"); exit(1); } cart_transform(rho, xsize, ysize); cart_dfree(rho); // Create the grid of points gridx = malloc((xsize+1)*(ysize+1)*sizeof(double)); gridy = malloc((xsize+1)*(ysize+1)*sizeof(double)); creategrid(gridx, gridy, xsize, ysize); // Compute the cartogram cart_makecart(gridx, gridy, (xsize+1)*(ysize+1), xsize, ysize, 0.0); // Write out the final positions of the grid points GDALGetGeoTransform(hDataset, adfGeoTransform); writepoints(outfp, gridx, gridy, xsize, ysize, adfGeoTransform); //writepoints(outfp, gridx, gridy, (xsize+1)*(ysize+1)); // Free up the allocated memory cart_freews(xsize, ysize); free(gridx); free(gridy); // Close the input and output files GDALClose(hDataset); fclose(outfp); return 0; }
CPLErr CPL_STDCALL GDALSieveFilter( GDALRasterBandH hSrcBand, GDALRasterBandH hMaskBand, GDALRasterBandH hDstBand, int nSizeThreshold, int nConnectedness, char **papszOptions, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hSrcBand, "GDALSieveFilter", CE_Failure ); VALIDATE_POINTER1( hDstBand, "GDALSieveFilter", CE_Failure ); if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Allocate working buffers. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; int nXSize = GDALGetRasterBandXSize( hSrcBand ); int nYSize = GDALGetRasterBandYSize( hSrcBand ); GInt32 *panLastLineVal = (GInt32 *) VSIMalloc2(sizeof(GInt32), nXSize); GInt32 *panThisLineVal = (GInt32 *) VSIMalloc2(sizeof(GInt32), nXSize); GInt32 *panLastLineId = (GInt32 *) VSIMalloc2(sizeof(GInt32), nXSize); GInt32 *panThisLineId = (GInt32 *) VSIMalloc2(sizeof(GInt32), nXSize); GInt32 *panThisLineWriteVal = (GInt32 *) VSIMalloc2(sizeof(GInt32), nXSize); GByte *pabyMaskLine = (hMaskBand != NULL) ? (GByte *) VSIMalloc(nXSize) : NULL; if (panLastLineVal == NULL || panThisLineVal == NULL || panLastLineId == NULL || panThisLineId == NULL || panThisLineWriteVal == NULL || (hMaskBand != NULL && pabyMaskLine == NULL)) { CPLError(CE_Failure, CPLE_OutOfMemory, "Could not allocate enough memory for temporary buffers"); CPLFree( panThisLineId ); CPLFree( panLastLineId ); CPLFree( panThisLineVal ); CPLFree( panLastLineVal ); CPLFree( panThisLineWriteVal ); CPLFree( pabyMaskLine ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* The first pass over the raster is only used to build up the */ /* polygon id map so we will know in advance what polygons are */ /* what on the second pass. */ /* -------------------------------------------------------------------- */ int iY, iX, iPoly; GDALRasterPolygonEnumerator oFirstEnum( nConnectedness ); std::vector<int> anPolySizes; for( iY = 0; eErr == CE_None && iY < nYSize; iY++ ) { eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iY, nXSize, 1, panThisLineVal, nXSize, 1, GDT_Int32, 0, 0 ); if( eErr == CE_None && hMaskBand != NULL ) eErr = GPMaskImageData( hMaskBand, pabyMaskLine, iY, nXSize, panThisLineVal ); if( iY == 0 ) oFirstEnum.ProcessLine( NULL, panThisLineVal, NULL, panThisLineId, nXSize ); else oFirstEnum.ProcessLine( panLastLineVal, panThisLineVal, panLastLineId, panThisLineId, nXSize ); /* -------------------------------------------------------------------- */ /* Accumulate polygon sizes. */ /* -------------------------------------------------------------------- */ if( oFirstEnum.nNextPolygonId > (int) anPolySizes.size() ) anPolySizes.resize( oFirstEnum.nNextPolygonId ); for( iX = 0; iX < nXSize; iX++ ) { iPoly = panThisLineId[iX]; CPLAssert( iPoly >= 0 ); anPolySizes[iPoly] += 1; } /* -------------------------------------------------------------------- */ /* swap this/last lines. */ /* -------------------------------------------------------------------- */ GInt32 *panTmp = panLastLineVal; panLastLineVal = panThisLineVal; panThisLineVal = panTmp; panTmp = panThisLineId; panThisLineId = panLastLineId; panLastLineId = panTmp; /* -------------------------------------------------------------------- */ /* Report progress, and support interrupts. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( 0.25 * ((iY+1) / (double) nYSize), "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Make a pass through the maps, ensuring every polygon id */ /* points to the final id it should use, not an intermediate */ /* value. */ /* -------------------------------------------------------------------- */ oFirstEnum.CompleteMerges(); /* -------------------------------------------------------------------- */ /* Push the sizes of merged polygon fragments into the the */ /* merged polygon id's count. */ /* -------------------------------------------------------------------- */ for( iPoly = 0; iPoly < oFirstEnum.nNextPolygonId; iPoly++ ) { if( oFirstEnum.panPolyIdMap[iPoly] != iPoly ) { anPolySizes[oFirstEnum.panPolyIdMap[iPoly]] += anPolySizes[iPoly]; anPolySizes[iPoly] = 0; } } /* -------------------------------------------------------------------- */ /* We will use a new enumerator for the second pass primariliy */ /* so we can preserve the first pass map. */ /* -------------------------------------------------------------------- */ GDALRasterPolygonEnumerator oSecondEnum( nConnectedness ); std::vector<int> anBigNeighbour; anBigNeighbour.resize( anPolySizes.size() ); for( iPoly = 0; iPoly < (int) anPolySizes.size(); iPoly++ ) anBigNeighbour[iPoly] = -1; /* ==================================================================== */ /* Second pass ... identify the largest neighbour for each */ /* polygon. */ /* ==================================================================== */ for( iY = 0; eErr == CE_None && iY < nYSize; iY++ ) { /* -------------------------------------------------------------------- */ /* Read the image data. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iY, nXSize, 1, panThisLineVal, nXSize, 1, GDT_Int32, 0, 0 ); if( eErr == CE_None && hMaskBand != NULL ) eErr = GPMaskImageData( hMaskBand, pabyMaskLine, iY, nXSize, panThisLineVal ); if( eErr != CE_None ) continue; /* -------------------------------------------------------------------- */ /* Determine what polygon the various pixels belong to (redoing */ /* the same thing done in the first pass above). */ /* -------------------------------------------------------------------- */ if( iY == 0 ) oSecondEnum.ProcessLine( NULL, panThisLineVal, NULL, panThisLineId, nXSize ); else oSecondEnum.ProcessLine( panLastLineVal, panThisLineVal, panLastLineId, panThisLineId, nXSize ); /* -------------------------------------------------------------------- */ /* Check our neighbours, and update our biggest neighbour map */ /* as appropriate. */ /* -------------------------------------------------------------------- */ for( iX = 0; iX < nXSize; iX++ ) { if( iY > 0 ) { CompareNeighbour( panThisLineId[iX], panLastLineId[iX], oFirstEnum.panPolyIdMap, oFirstEnum.panPolyValue, anPolySizes, anBigNeighbour ); if( iX > 0 && nConnectedness == 8 ) CompareNeighbour( panThisLineId[iX], panLastLineId[iX-1], oFirstEnum.panPolyIdMap, oFirstEnum.panPolyValue, anPolySizes, anBigNeighbour ); if( iX < nXSize-1 && nConnectedness == 8 ) CompareNeighbour( panThisLineId[iX], panLastLineId[iX+1], oFirstEnum.panPolyIdMap, oFirstEnum.panPolyValue, anPolySizes, anBigNeighbour ); } if( iX > 0 ) CompareNeighbour( panThisLineId[iX], panThisLineId[iX-1], oFirstEnum.panPolyIdMap, oFirstEnum.panPolyValue, anPolySizes, anBigNeighbour ); // We don't need to compare to next pixel or next line // since they will be compared to us. } /* -------------------------------------------------------------------- */ /* Swap pixel value, and polygon id lines to be ready for the */ /* next line. */ /* -------------------------------------------------------------------- */ GInt32 *panTmp = panLastLineVal; panLastLineVal = panThisLineVal; panThisLineVal = panTmp; panTmp = panThisLineId; panThisLineId = panLastLineId; panLastLineId = panTmp; /* -------------------------------------------------------------------- */ /* Report progress, and support interrupts. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( 0.25 + 0.25 * ((iY+1) / (double) nYSize), "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* If our biggest neighbour is still smaller than the */ /* threshold, then try tracking to that polygons biggest */ /* neighbour, and so forth. */ /* -------------------------------------------------------------------- */ int nFailedMerges = 0; int nIsolatedSmall = 0; int nSieveTargets = 0; for( iPoly = 0; iPoly < (int) anPolySizes.size(); iPoly++ ) { if( oFirstEnum.panPolyIdMap[iPoly] != iPoly ) continue; // Ignore nodata polygons. if( oFirstEnum.panPolyValue[iPoly] == GP_NODATA_MARKER ) continue; // Don't try to merge polygons larger than the threshold. if( anPolySizes[iPoly] >= nSizeThreshold ) { anBigNeighbour[iPoly] = -1; continue; } nSieveTargets++; // if we have no neighbours but we are small, what shall we do? if( anBigNeighbour[iPoly] == -1 ) { nIsolatedSmall++; continue; } // If our biggest neighbour is larger than the threshold // then we are golden. if( anPolySizes[anBigNeighbour[iPoly]] >= nSizeThreshold ) continue; #ifdef notdef // Will our neighbours biggest neighbour do? // Eventually we need something sort of recursive here with // loop detection. if( anPolySizes[anBigNeighbour[anBigNeighbour[iPoly]]] >= nSizeThreshold ) { anBigNeighbour[iPoly] = anBigNeighbour[anBigNeighbour[iPoly]]; continue; } #endif nFailedMerges++; anBigNeighbour[iPoly] = -1; } CPLDebug( "GDALSieveFilter", "Small Polygons: %d, Isolated: %d, Unmergable: %d", nSieveTargets, nIsolatedSmall, nFailedMerges ); /* ==================================================================== */ /* Make a third pass over the image, actually applying the */ /* merges. We reuse the second enumerator but preserve the */ /* "final maps" from the first. */ /* ==================================================================== */ oSecondEnum.Clear(); for( iY = 0; eErr == CE_None && iY < nYSize; iY++ ) { /* -------------------------------------------------------------------- */ /* Read the image data. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iY, nXSize, 1, panThisLineVal, nXSize, 1, GDT_Int32, 0, 0 ); memcpy( panThisLineWriteVal, panThisLineVal, 4 * nXSize ); if( eErr == CE_None && hMaskBand != NULL ) eErr = GPMaskImageData( hMaskBand, pabyMaskLine, iY, nXSize, panThisLineVal ); if( eErr != CE_None ) continue; /* -------------------------------------------------------------------- */ /* Determine what polygon the various pixels belong to (redoing */ /* the same thing done in the first pass above). */ /* -------------------------------------------------------------------- */ if( iY == 0 ) oSecondEnum.ProcessLine( NULL, panThisLineVal, NULL, panThisLineId, nXSize ); else oSecondEnum.ProcessLine( panLastLineVal, panThisLineVal, panLastLineId, panThisLineId, nXSize ); /* -------------------------------------------------------------------- */ /* Reprocess the actual pixel values according to the polygon */ /* merging, and write out this line of image data. */ /* -------------------------------------------------------------------- */ for( iX = 0; iX < nXSize; iX++ ) { int iThisPoly = oFirstEnum.panPolyIdMap[panThisLineId[iX]]; if( anBigNeighbour[iThisPoly] != -1 ) { panThisLineWriteVal[iX] = oFirstEnum.panPolyValue[ anBigNeighbour[iThisPoly]]; } } /* -------------------------------------------------------------------- */ /* Write the update data out. */ /* -------------------------------------------------------------------- */ eErr = GDALRasterIO( hDstBand, GF_Write, 0, iY, nXSize, 1, panThisLineWriteVal, nXSize, 1, GDT_Int32, 0, 0 ); /* -------------------------------------------------------------------- */ /* Swap pixel value, and polygon id lines to be ready for the */ /* next line. */ /* -------------------------------------------------------------------- */ GInt32 *panTmp = panLastLineVal; panLastLineVal = panThisLineVal; panThisLineVal = panTmp; panTmp = panThisLineId; panThisLineId = panLastLineId; panLastLineId = panTmp; /* -------------------------------------------------------------------- */ /* Report progress, and support interrupts. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( 0.5 + 0.5 * ((iY+1) / (double) nYSize), "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLFree( panThisLineId ); CPLFree( panLastLineId ); CPLFree( panThisLineVal ); CPLFree( panLastLineVal ); CPLFree( panThisLineWriteVal ); CPLFree( pabyMaskLine ); return eErr; }
CPLErr CPL_STDCALL GDALComputeProximity(GDALRasterBandH hSrcBand, GDALRasterBandH hProximityBand, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressArg) { int nXSize, nYSize, i, bFixedBufVal = FALSE; const char *pszOpt; double dfMaxDist; double dfFixedBufVal = 0.0; VALIDATE_POINTER1(hSrcBand, "GDALComputeProximity", CE_Failure); VALIDATE_POINTER1(hProximityBand, "GDALComputeProximity", CE_Failure); if (pfnProgress == NULL) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Are we using pixels or georeferenced coordinates for distances? */ /* -------------------------------------------------------------------- */ double dfDistMult = 1.0; pszOpt = CSLFetchNameValue(papszOptions, "DISTUNITS"); if (pszOpt) { if (EQUAL(pszOpt, "GEO")) { GDALDatasetH hSrcDS = GDALGetBandDataset(hSrcBand); if (hSrcDS) { double adfGeoTransform[6]; GDALGetGeoTransform(hSrcDS, adfGeoTransform); if (ABS(adfGeoTransform[1]) != ABS(adfGeoTransform[5])) CPLError(CE_Warning, CPLE_AppDefined, "Pixels not square, distances will be inaccurate."); dfDistMult = ABS(adfGeoTransform[1]); } } else if (!EQUAL(pszOpt, "PIXEL")) { CPLError(CE_Failure, CPLE_AppDefined, "Unrecognised DISTUNITS value '%s', should be GEO or PIXEL.", pszOpt); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* What is our maxdist value? */ /* -------------------------------------------------------------------- */ pszOpt = CSLFetchNameValue(papszOptions, "MAXDIST"); if (pszOpt) dfMaxDist = atof(pszOpt) / dfDistMult; else dfMaxDist = GDALGetRasterBandXSize(hSrcBand) + GDALGetRasterBandYSize(hSrcBand); CPLDebug("GDAL", "MAXDIST=%g, DISTMULT=%g", dfMaxDist, dfDistMult); /* -------------------------------------------------------------------- */ /* Verify the source and destination are compatible. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize(hSrcBand); nYSize = GDALGetRasterBandYSize(hSrcBand); if (nXSize != GDALGetRasterBandXSize(hProximityBand) || nYSize != GDALGetRasterBandYSize(hProximityBand)) { CPLError(CE_Failure, CPLE_AppDefined, "Source and proximity bands are not the same size."); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Get output NODATA value. */ /* -------------------------------------------------------------------- */ float fNoDataValue; pszOpt = CSLFetchNameValue(papszOptions, "NODATA"); if (pszOpt != NULL) fNoDataValue = (float) atof(pszOpt); else { int bSuccess; fNoDataValue = (float) GDALGetRasterNoDataValue(hProximityBand, &bSuccess); if (!bSuccess) fNoDataValue = 65535.0; } /* -------------------------------------------------------------------- */ /* Is there a fixed value we wish to force the buffer area to? */ /* -------------------------------------------------------------------- */ pszOpt = CSLFetchNameValue(papszOptions, "FIXED_BUF_VAL"); if (pszOpt) { dfFixedBufVal = atof(pszOpt); bFixedBufVal = TRUE; } /* -------------------------------------------------------------------- */ /* Get the target value(s). */ /* -------------------------------------------------------------------- */ int *panTargetValues = NULL; int nTargetValues = 0; pszOpt = CSLFetchNameValue(papszOptions, "VALUES"); if (pszOpt != NULL) { char **papszValuesTokens; papszValuesTokens = CSLTokenizeStringComplex(pszOpt, ",", FALSE, FALSE); nTargetValues = CSLCount(papszValuesTokens); panTargetValues = (int*) CPLCalloc(sizeof(int), nTargetValues); for (i = 0; i < nTargetValues; i++) panTargetValues[i] = atoi(papszValuesTokens[i]); CSLDestroy(papszValuesTokens); } /* -------------------------------------------------------------------- */ /* Initialize progress counter. */ /* -------------------------------------------------------------------- */ if (!pfnProgress(0.0, "", pProgressArg)) { CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated"); CPLFree(panTargetValues); return CE_Failure; } /* -------------------------------------------------------------------- */ /* We need a signed type for the working proximity values kept */ /* on disk. If our proximity band is not signed, then create a */ /* temporary file for this purpose. */ /* -------------------------------------------------------------------- */ GDALRasterBandH hWorkProximityBand = hProximityBand; GDALDatasetH hWorkProximityDS = NULL; GDALDataType eProxType = GDALGetRasterDataType(hProximityBand); int *panNearX = NULL, *panNearY = NULL; float *pafProximity = NULL; GInt32 *panSrcScanline = NULL; int iLine; CPLErr eErr = CE_None; if (eProxType == GDT_Byte || eProxType == GDT_UInt16 || eProxType == GDT_UInt32) { GDALDriverH hDriver = GDALGetDriverByName("GTiff"); if (hDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GDALComputeProximity needs GTiff driver"); eErr = CE_Failure; goto end; } CPLString osTmpFile = CPLGenerateTempFilename("proximity"); hWorkProximityDS = GDALCreate(hDriver, osTmpFile, nXSize, nYSize, 1, GDT_Float32, NULL); if (hWorkProximityDS == NULL) { eErr = CE_Failure; goto end; } hWorkProximityBand = GDALGetRasterBand(hWorkProximityDS, 1); } /* -------------------------------------------------------------------- */ /* Allocate buffer for two scanlines of distances as floats */ /* (the current and last line). */ /* -------------------------------------------------------------------- */ pafProximity = (float*) VSIMalloc2(sizeof(float), nXSize); panNearX = (int*) VSIMalloc2(sizeof(int), nXSize); panNearY = (int*) VSIMalloc2(sizeof(int), nXSize); panSrcScanline = (GInt32*) VSIMalloc2(sizeof(GInt32), nXSize); if (pafProximity == NULL || panNearX == NULL || panNearY == NULL || panSrcScanline == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory allocating working buffers."); eErr = CE_Failure; goto end; } /* -------------------------------------------------------------------- */ /* Loop from top to bottom of the image. */ /* -------------------------------------------------------------------- */ for (i = 0; i < nXSize; i++) panNearX[i] = panNearY[i] = -1; for (iLine = 0; eErr == CE_None && iLine < nYSize; iLine++) { // Read for target values. eErr = GDALRasterIO(hSrcBand, GF_Read, 0, iLine, nXSize, 1, panSrcScanline, nXSize, 1, GDT_Int32, 0, 0); if (eErr != CE_None) break; for (i = 0; i < nXSize; i++) pafProximity[i] = -1.0; // Left to right ProcessProximityLine(panSrcScanline, panNearX, panNearY, TRUE, iLine, nXSize, dfMaxDist, pafProximity, nTargetValues, panTargetValues); // Right to Left ProcessProximityLine(panSrcScanline, panNearX, panNearY, FALSE, iLine, nXSize, dfMaxDist, pafProximity, nTargetValues, panTargetValues); // Write out results. eErr = GDALRasterIO(hWorkProximityBand, GF_Write, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0); if (eErr != CE_None) break; if (!pfnProgress(0.5 * (iLine + 1) / (double) nYSize, "", pProgressArg)) { CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated"); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Loop from bottom to top of the image. */ /* -------------------------------------------------------------------- */ for (i = 0; i < nXSize; i++) panNearX[i] = panNearY[i] = -1; for (iLine = nYSize - 1; eErr == CE_None && iLine >= 0; iLine--) { // Read first pass proximity eErr = GDALRasterIO(hWorkProximityBand, GF_Read, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0); if (eErr != CE_None) break; // Read pixel values. eErr = GDALRasterIO(hSrcBand, GF_Read, 0, iLine, nXSize, 1, panSrcScanline, nXSize, 1, GDT_Int32, 0, 0); if (eErr != CE_None) break; // Right to left ProcessProximityLine(panSrcScanline, panNearX, panNearY, FALSE, iLine, nXSize, dfMaxDist, pafProximity, nTargetValues, panTargetValues); // Left to right ProcessProximityLine(panSrcScanline, panNearX, panNearY, TRUE, iLine, nXSize, dfMaxDist, pafProximity, nTargetValues, panTargetValues); // Final post processing of distances. for (i = 0; i < nXSize; i++) { if (pafProximity[i] < 0.0) pafProximity[i] = fNoDataValue; else if (pafProximity[i] > 0.0) { if (bFixedBufVal) pafProximity[i] = (float) dfFixedBufVal; else pafProximity[i] = (float)(pafProximity[i] * dfDistMult); } } // Write out results. eErr = GDALRasterIO(hProximityBand, GF_Write, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0); if (eErr != CE_None) break; if (!pfnProgress(0.5 + 0.5 * (nYSize - iLine) / (double) nYSize, "", pProgressArg)) { CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated"); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end: CPLFree(panNearX); CPLFree(panNearY); CPLFree(panSrcScanline); CPLFree(pafProximity); CPLFree(panTargetValues); if (hWorkProximityDS != NULL) { CPLString osProxFile = GDALGetDescription(hWorkProximityDS); GDALClose(hWorkProximityDS); GDALDeleteDataset(GDALGetDriverByName("GTiff"), osProxFile); } return eErr; }
static CPLErr GDALMultiFilter( GDALRasterBandH hTargetBand, GDALRasterBandH hTargetMaskBand, GDALRasterBandH hFiltMaskBand, int nIterations, GDALProgressFunc pfnProgress, void * pProgressArg ) { const int nXSize = GDALGetRasterBandXSize(hTargetBand); const int nYSize = GDALGetRasterBandYSize(hTargetBand); /* -------------------------------------------------------------------- */ /* Report starting progress value. */ /* -------------------------------------------------------------------- */ if( !pfnProgress( 0.0, "Smoothing Filter...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Allocate rotating buffers. */ /* -------------------------------------------------------------------- */ const int nBufLines = nIterations + 2; GByte *pabyTMaskBuf = static_cast<GByte *>(VSI_MALLOC2_VERBOSE(nXSize, nBufLines)); GByte *pabyFMaskBuf = static_cast<GByte *>(VSI_MALLOC2_VERBOSE(nXSize, nBufLines)); float *paf3PassLineBuf = static_cast<float *>( VSI_MALLOC3_VERBOSE(nXSize, nBufLines, 3 * sizeof(float))); if( pabyTMaskBuf == nullptr || pabyFMaskBuf == nullptr || paf3PassLineBuf == nullptr ) { CPLFree( pabyTMaskBuf ); CPLFree( pabyFMaskBuf ); CPLFree( paf3PassLineBuf ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Process rotating buffers. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; int iPassCounter = 0; for( int nNewLine = 0; // Line being loaded (zero based scanline). eErr == CE_None && nNewLine < nYSize+nIterations; nNewLine++ ) { /* -------------------------------------------------------------------- */ /* Rotate pass buffers. */ /* -------------------------------------------------------------------- */ iPassCounter = (iPassCounter + 1) % 3; float * const pafSLastPass = paf3PassLineBuf + ((iPassCounter + 0) % 3) * nXSize * nBufLines; float * const pafLastPass = paf3PassLineBuf + ((iPassCounter + 1) % 3) * nXSize * nBufLines; float * const pafThisPass = paf3PassLineBuf + ((iPassCounter + 2) % 3) * nXSize * nBufLines; /* -------------------------------------------------------------------- */ /* Where does the new line go in the rotating buffer? */ /* -------------------------------------------------------------------- */ const int iBufOffset = nNewLine % nBufLines; /* -------------------------------------------------------------------- */ /* Read the new data line if it is't off the bottom of the */ /* image. */ /* -------------------------------------------------------------------- */ if( nNewLine < nYSize ) { eErr = GDALRasterIO( hTargetMaskBand, GF_Read, 0, nNewLine, nXSize, 1, pabyTMaskBuf + nXSize * iBufOffset, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hFiltMaskBand, GF_Read, 0, nNewLine, nXSize, 1, pabyFMaskBuf + nXSize * iBufOffset, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hTargetBand, GF_Read, 0, nNewLine, nXSize, 1, pafThisPass + nXSize * iBufOffset, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; } /* -------------------------------------------------------------------- */ /* Loop over the loaded data, applying the filter to all loaded */ /* lines with neighbours. */ /* -------------------------------------------------------------------- */ for( int iFLine = nNewLine-1; eErr == CE_None && iFLine >= nNewLine-nIterations; iFLine-- ) { const int iLastOffset = (iFLine-1) % nBufLines; const int iThisOffset = (iFLine ) % nBufLines; const int iNextOffset = (iFLine+1) % nBufLines; // Default to preserving the old value. if( iFLine >= 0 ) memcpy( pafThisPass + iThisOffset * nXSize, pafLastPass + iThisOffset * nXSize, sizeof(float) * nXSize ); // TODO: Enable first and last line. // Skip the first and last line. if( iFLine < 1 || iFLine >= nYSize-1 ) { continue; } GDALFilterLine( pafSLastPass + iLastOffset * nXSize, pafLastPass + iThisOffset * nXSize, pafThisPass + iNextOffset * nXSize, pafThisPass + iThisOffset * nXSize, pabyTMaskBuf + iLastOffset * nXSize, pabyTMaskBuf + iThisOffset * nXSize, pabyTMaskBuf + iNextOffset * nXSize, pabyFMaskBuf + iThisOffset * nXSize, nXSize ); } /* -------------------------------------------------------------------- */ /* Write out the top data line that will be rolling out of our */ /* buffer. */ /* -------------------------------------------------------------------- */ const int iLineToSave = nNewLine - nIterations; if( iLineToSave >= 0 && eErr == CE_None ) { const int iBufOffset2 = iLineToSave % nBufLines; eErr = GDALRasterIO( hTargetBand, GF_Write, 0, iLineToSave, nXSize, 1, pafThisPass + nXSize * iBufOffset2, nXSize, 1, GDT_Float32, 0, 0 ); } /* -------------------------------------------------------------------- */ /* Report progress. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( (nNewLine + 1) / static_cast<double>(nYSize+nIterations), "Smoothing Filter...", pProgressArg) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLFree( pabyTMaskBuf ); CPLFree( pabyFMaskBuf ); CPLFree( paf3PassLineBuf ); return eErr; }
int GDALComputeMedianCutPCTInternal( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, GByte* pabyRedBand, GByte* pabyGreenBand, GByte* pabyBlueBand, int (*pfnIncludePixel)(int,int,void*), int nColors, int nBits, int* panHistogram, /* NULL, or at least of size (1<<nBits)^3 * sizeof(int) bytes */ GDALColorTableH hColorTable, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALComputeMedianCutPCT", CE_Failure ); VALIDATE_POINTER1( hGreen, "GDALComputeMedianCutPCT", CE_Failure ); VALIDATE_POINTER1( hBlue, "GDALComputeMedianCutPCT", CE_Failure ); int nXSize, nYSize; CPLErr err = CE_None; /* -------------------------------------------------------------------- */ /* Validate parameters. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize( hRed ); nYSize = GDALGetRasterBandYSize( hRed ); if( GDALGetRasterBandXSize( hGreen ) != nXSize || GDALGetRasterBandYSize( hGreen ) != nYSize || GDALGetRasterBandXSize( hBlue ) != nXSize || GDALGetRasterBandYSize( hBlue ) != nYSize ) { CPLError( CE_Failure, CPLE_IllegalArg, "Green or blue band doesn't match size of red band.\n" ); return CE_Failure; } if( pfnIncludePixel != NULL ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT() doesn't currently support " " pfnIncludePixel function." ); return CE_Failure; } if ( nColors <= 0 ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT() : nColors must be strictly greater than 1." ); return CE_Failure; } if ( nColors > 256 ) { CPLError( CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT() : nColors must be lesser than or equal to 256." ); return CE_Failure; } if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* ==================================================================== */ /* STEP 1: create empty boxes. */ /* ==================================================================== */ int i; Colorbox *box_list, *ptr; int* histogram; Colorbox *freeboxes; Colorbox *usedboxes; int nCLevels = 1 << nBits; int nColorShift = 8 - nBits; int nColorCounter = 0; GByte anRed[256], anGreen[256], anBlue[256]; int nPixels = 0; HashHistogram* psHashHistogram = NULL; if( nBits == 8 && pabyRedBand != NULL && pabyGreenBand != NULL && pabyBlueBand != NULL && nXSize < INT_MAX / nYSize ) { nPixels = nXSize * nYSize; } if( panHistogram ) { if( nBits == 8 && (GIntBig)nXSize * nYSize <= 65536 ) { /* If the image is small enough, then the number of colors */ /* will be limited and using a hashmap, rather than a full table */ /* will be more efficient */ histogram = NULL; psHashHistogram = (HashHistogram*)panHistogram; memset(psHashHistogram, 0xFF, sizeof(HashHistogram) * PRIME_FOR_65536); } else { histogram = panHistogram; memset(histogram, 0, nCLevels*nCLevels*nCLevels * sizeof(int)); } } else { histogram = (int*) VSICalloc(nCLevels*nCLevels*nCLevels,sizeof(int)); if( histogram == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSICalloc(): Out of memory in GDALComputeMedianCutPCT" ); return CE_Failure; } } usedboxes = NULL; box_list = freeboxes = (Colorbox *)CPLMalloc(nColors*sizeof (Colorbox)); freeboxes[0].next = &freeboxes[1]; freeboxes[0].prev = NULL; for (i = 1; i < nColors-1; ++i) { freeboxes[i].next = &freeboxes[i+1]; freeboxes[i].prev = &freeboxes[i-1]; } freeboxes[nColors-1].next = NULL; freeboxes[nColors-1].prev = &freeboxes[nColors-2]; /* ==================================================================== */ /* Build histogram. */ /* ==================================================================== */ GByte *pabyRedLine, *pabyGreenLine, *pabyBlueLine; int iLine, iPixel; /* -------------------------------------------------------------------- */ /* Initialize the box datastructures. */ /* -------------------------------------------------------------------- */ ptr = freeboxes; freeboxes = ptr->next; if (freeboxes) freeboxes->prev = NULL; ptr->next = usedboxes; usedboxes = ptr; if (ptr->next) ptr->next->prev = ptr; ptr->rmin = ptr->gmin = ptr->bmin = 999; ptr->rmax = ptr->gmax = ptr->bmax = -1; ptr->total = nXSize * nYSize; /* -------------------------------------------------------------------- */ /* Collect histogram. */ /* -------------------------------------------------------------------- */ pabyRedLine = (GByte *) VSIMalloc(nXSize); pabyGreenLine = (GByte *) VSIMalloc(nXSize); pabyBlueLine = (GByte *) VSIMalloc(nXSize); if (pabyRedLine == NULL || pabyGreenLine == NULL || pabyBlueLine == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "VSIMalloc(): Out of memory in GDALComputeMedianCutPCT" ); err = CE_Failure; goto end_and_cleanup; } for( iLine = 0; iLine < nYSize; iLine++ ) { if( !pfnProgress( iLine / (double) nYSize, "Generating Histogram", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } GDALRasterIO( hRed, GF_Read, 0, iLine, nXSize, 1, pabyRedLine, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hGreen, GF_Read, 0, iLine, nXSize, 1, pabyGreenLine, nXSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( hBlue, GF_Read, 0, iLine, nXSize, 1, pabyBlueLine, nXSize, 1, GDT_Byte, 0, 0 ); for( iPixel = 0; iPixel < nXSize; iPixel++ ) { int nRed, nGreen, nBlue; nRed = pabyRedLine[iPixel] >> nColorShift; nGreen = pabyGreenLine[iPixel] >> nColorShift; nBlue = pabyBlueLine[iPixel] >> nColorShift; ptr->rmin = MIN(ptr->rmin, nRed); ptr->gmin = MIN(ptr->gmin, nGreen); ptr->bmin = MIN(ptr->bmin, nBlue); ptr->rmax = MAX(ptr->rmax, nRed); ptr->gmax = MAX(ptr->gmax, nGreen); ptr->bmax = MAX(ptr->bmax, nBlue); int* pnColor; if( psHashHistogram ) { pnColor = FindAndInsertColorCount(psHashHistogram, MAKE_COLOR_CODE(nRed, nGreen, nBlue)); } else { pnColor = &HISTOGRAM(histogram, nCLevels, nRed, nGreen, nBlue); } if( *pnColor == 0 ) { if( nColorShift == 0 && nColorCounter < nColors ) { anRed[nColorCounter] = nRed; anGreen[nColorCounter] = nGreen; anBlue[nColorCounter] = nBlue; } nColorCounter++; } (*pnColor) ++; } } if( !pfnProgress( 1.0, "Generating Histogram", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } if( nColorShift == 0 && nColorCounter <= nColors ) { //CPLDebug("MEDIAN_CUT", "%d colors found <= %d", nColorCounter, nColors); for(int iColor = 0; iColor<nColorCounter; iColor++) { GDALColorEntry sEntry; sEntry.c1 = (GByte) anRed[iColor]; sEntry.c2 = (GByte) anGreen[iColor]; sEntry.c3 = (GByte) anBlue[iColor]; sEntry.c4 = 255; GDALSetColorEntry( hColorTable, iColor, &sEntry ); } goto end_and_cleanup; } /* ==================================================================== */ /* STEP 3: continually subdivide boxes until no more free */ /* boxes remain or until all colors assigned. */ /* ==================================================================== */ while (freeboxes != NULL) { ptr = largest_box(usedboxes); if (ptr != NULL) splitbox(ptr, histogram, psHashHistogram, nCLevels, &freeboxes, &usedboxes, pabyRedBand, pabyGreenBand, pabyBlueBand, nPixels); else freeboxes = NULL; } /* ==================================================================== */ /* STEP 4: assign colors to all boxes */ /* ==================================================================== */ for (i = 0, ptr = usedboxes; ptr != NULL; ++i, ptr = ptr->next) { GDALColorEntry sEntry; sEntry.c1 = (GByte) (((ptr->rmin + ptr->rmax) << nColorShift) / 2); sEntry.c2 = (GByte) (((ptr->gmin + ptr->gmax) << nColorShift) / 2); sEntry.c3 = (GByte) (((ptr->bmin + ptr->bmax) << nColorShift) / 2); sEntry.c4 = 255; GDALSetColorEntry( hColorTable, i, &sEntry ); } end_and_cleanup: CPLFree( pabyRedLine ); CPLFree( pabyGreenLine ); CPLFree( pabyBlueLine ); /* We're done with the boxes now */ CPLFree(box_list); freeboxes = usedboxes = NULL; if( panHistogram == NULL ) CPLFree( histogram ); return err; }
int main( int argc, char ** argv ) { GDALDatasetH hDataset; GDALRasterBandH hBand; int i, iBand; double adfGeoTransform[6]; GDALDriverH hDriver; char **papszMetadata; int bComputeMinMax = FALSE, bSample = FALSE; int bShowGCPs = TRUE, bShowMetadata = TRUE, bShowRAT=TRUE; int bStats = FALSE, bApproxStats = TRUE, iMDD; int bShowColorTable = TRUE, bComputeChecksum = FALSE; int bReportHistograms = FALSE; const char *pszFilename = NULL; char **papszExtraMDDomains = NULL, **papszFileList; const char *pszProjection = NULL; OGRCoordinateTransformationH hTransform = NULL; /* Check that we are running against at least GDAL 1.5 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500) { fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */ /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */ /* for the --format or --formats options */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") ) { CPLSetConfigOption( argv[i+1], argv[i+2] ); i += 2; } } GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i], "-mm") ) bComputeMinMax = TRUE; else if( EQUAL(argv[i], "-hist") ) bReportHistograms = TRUE; else if( EQUAL(argv[i], "-stats") ) { bStats = TRUE; bApproxStats = FALSE; } else if( EQUAL(argv[i], "-approx_stats") ) { bStats = TRUE; bApproxStats = TRUE; } else if( EQUAL(argv[i], "-sample") ) bSample = TRUE; else if( EQUAL(argv[i], "-checksum") ) bComputeChecksum = TRUE; else if( EQUAL(argv[i], "-nogcp") ) bShowGCPs = FALSE; else if( EQUAL(argv[i], "-nomd") ) bShowMetadata = FALSE; else if( EQUAL(argv[i], "-norat") ) bShowRAT = FALSE; else if( EQUAL(argv[i], "-noct") ) bShowColorTable = FALSE; else if( EQUAL(argv[i], "-mdd") && i < argc-1 ) papszExtraMDDomains = CSLAddString( papszExtraMDDomains, argv[++i] ); else if( argv[i][0] == '-' ) Usage(); else if( pszFilename == NULL ) pszFilename = argv[i]; else Usage(); } if( pszFilename == NULL ) Usage(); /* -------------------------------------------------------------------- */ /* Open dataset. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpen( pszFilename, GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "gdalinfo failed - unable to open '%s'.\n", pszFilename ); CSLDestroy( argv ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Report general info. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); papszFileList = GDALGetFileList( hDataset ); if( CSLCount(papszFileList) == 0 ) { printf( "Files: none associated\n" ); } else { printf( "Files: %s\n", papszFileList[0] ); for( i = 1; papszFileList[i] != NULL; i++ ) printf( " %s\n", papszFileList[i] ); } CSLDestroy( papszFileList ); printf( "Size is %d, %d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ) ); /* -------------------------------------------------------------------- */ /* Report projection. */ /* -------------------------------------------------------------------- */ if( GDALGetProjectionRef( hDataset ) != NULL ) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "Coordinate System is:\n%s\n", pszPrettyWkt ); CPLFree( pszPrettyWkt ); } else printf( "Coordinate System is `%s'\n", GDALGetProjectionRef( hDataset ) ); OSRDestroySpatialReference( hSRS ); } /* -------------------------------------------------------------------- */ /* Report Geotransform. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ) { printf( "Origin = (%.15f,%.15f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.15f,%.15f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } else printf( "GeoTransform =\n" " %.16g, %.16g, %.16g\n" " %.16g, %.16g, %.16g\n", adfGeoTransform[0], adfGeoTransform[1], adfGeoTransform[2], adfGeoTransform[3], adfGeoTransform[4], adfGeoTransform[5] ); } /* -------------------------------------------------------------------- */ /* Report GCPs. */ /* -------------------------------------------------------------------- */ if( bShowGCPs && GDALGetGCPCount( hDataset ) > 0 ) { if (GDALGetGCPProjection(hDataset) != NULL) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetGCPProjection( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "GCP Projection = \n%s\n", pszPrettyWkt ); CPLFree( pszPrettyWkt ); } else printf( "GCP Projection = %s\n", GDALGetGCPProjection( hDataset ) ); OSRDestroySpatialReference( hSRS ); } for( i = 0; i < GDALGetGCPCount(hDataset); i++ ) { const GDAL_GCP *psGCP; psGCP = GDALGetGCPs( hDataset ) + i; printf( "GCP[%3d]: Id=%s, Info=%s\n" " (%.15g,%.15g) -> (%.15g,%.15g,%.15g)\n", i, psGCP->pszId, psGCP->pszInfo, psGCP->dfGCPPixel, psGCP->dfGCPLine, psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ ); } } /* -------------------------------------------------------------------- */ /* Report metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, NULL ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } for( iMDD = 0; bShowMetadata && iMDD < CSLCount(papszExtraMDDomains); iMDD++ ) { papszMetadata = GDALGetMetadata( hDataset, papszExtraMDDomains[iMDD] ); if( CSLCount(papszMetadata) > 0 ) { printf( "Metadata (%s):\n", papszExtraMDDomains[iMDD]); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } } /* -------------------------------------------------------------------- */ /* Report "IMAGE_STRUCTURE" metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "IMAGE_STRUCTURE" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Image Structure Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report subdatasets. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, "SUBDATASETS" ); if( CSLCount(papszMetadata) > 0 ) { printf( "Subdatasets:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report geolocation. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "GEOLOCATION" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Geolocation:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report RPCs */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "RPC" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "RPC Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Setup projected to lat/long transform if appropriate. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) pszProjection = GDALGetProjectionRef(hDataset); if( pszProjection != NULL && strlen(pszProjection) > 0 ) { OGRSpatialReferenceH hProj, hLatLong = NULL; hProj = OSRNewSpatialReference( pszProjection ); if( hProj != NULL ) hLatLong = OSRCloneGeogCS( hProj ); if( hLatLong != NULL ) { CPLPushErrorHandler( CPLQuietErrorHandler ); hTransform = OCTNewCoordinateTransformation( hProj, hLatLong ); CPLPopErrorHandler(); OSRDestroySpatialReference( hLatLong ); } if( hProj != NULL ) OSRDestroySpatialReference( hProj ); } /* -------------------------------------------------------------------- */ /* Report corners. */ /* -------------------------------------------------------------------- */ printf( "Corner Coordinates:\n" ); GDALInfoReportCorner( hDataset, hTransform, "Upper Left", 0.0, 0.0 ); GDALInfoReportCorner( hDataset, hTransform, "Lower Left", 0.0, GDALGetRasterYSize(hDataset)); GDALInfoReportCorner( hDataset, hTransform, "Upper Right", GDALGetRasterXSize(hDataset), 0.0 ); GDALInfoReportCorner( hDataset, hTransform, "Lower Right", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset) ); GDALInfoReportCorner( hDataset, hTransform, "Center", GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0 ); if( hTransform != NULL ) { OCTDestroyCoordinateTransformation( hTransform ); hTransform = NULL; } /* ==================================================================== */ /* Loop over bands. */ /* ==================================================================== */ for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ ) { double dfMin, dfMax, adfCMinMax[2], dfNoData; int bGotMin, bGotMax, bGotNodata, bSuccess; int nBlockXSize, nBlockYSize, nMaskFlags; double dfMean, dfStdDev; GDALColorTableH hTable; CPLErr eErr; hBand = GDALGetRasterBand( hDataset, iBand+1 ); if( bSample ) { float afSample[10000]; int nCount; nCount = GDALGetRandomRasterSample( hBand, 10000, afSample ); printf( "Got %d samples.\n", nCount ); } GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( "Band %d Block=%dx%d Type=%s, ColorInterp=%s\n", iBand+1, nBlockXSize, nBlockYSize, GDALGetDataTypeName( GDALGetRasterDataType(hBand)), GDALGetColorInterpretationName( GDALGetRasterColorInterpretation(hBand)) ); if( GDALGetDescription( hBand ) != NULL && strlen(GDALGetDescription( hBand )) > 0 ) printf( " Description = %s\n", GDALGetDescription(hBand) ); dfMin = GDALGetRasterMinimum( hBand, &bGotMin ); dfMax = GDALGetRasterMaximum( hBand, &bGotMax ); if( bGotMin || bGotMax || bComputeMinMax ) { printf( " " ); if( bGotMin ) printf( "Min=%.3f ", dfMin ); if( bGotMax ) printf( "Max=%.3f ", dfMax ); if( bComputeMinMax ) { CPLErrorReset(); GDALComputeRasterMinMax( hBand, FALSE, adfCMinMax ); if (CPLGetLastErrorType() == CE_None) { printf( " Computed Min/Max=%.3f,%.3f", adfCMinMax[0], adfCMinMax[1] ); } } printf( "\n" ); } eErr = GDALGetRasterStatistics( hBand, bApproxStats, bStats, &dfMin, &dfMax, &dfMean, &dfStdDev ); if( eErr == CE_None ) { printf( " Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f\n", dfMin, dfMax, dfMean, dfStdDev ); } if( bReportHistograms ) { int nBucketCount, *panHistogram = NULL; eErr = GDALGetDefaultHistogram( hBand, &dfMin, &dfMax, &nBucketCount, &panHistogram, TRUE, GDALTermProgress, NULL ); if( eErr == CE_None ) { int iBucket; printf( " %d buckets from %g to %g:\n ", nBucketCount, dfMin, dfMax ); for( iBucket = 0; iBucket < nBucketCount; iBucket++ ) printf( "%d ", panHistogram[iBucket] ); printf( "\n" ); CPLFree( panHistogram ); } } if ( bComputeChecksum) { printf( " Checksum=%d\n", GDALChecksumImage(hBand, 0, 0, GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset))); } dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata ); if( bGotNodata ) { printf( " NoData Value=%.18g\n", dfNoData ); } if( GDALGetOverviewCount(hBand) > 0 ) { int iOverview; printf( " Overviews: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; const char *pszResampling = NULL; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); pszResampling = GDALGetMetadataItem( hOverview, "RESAMPLING", "" ); if( pszResampling != NULL && EQUALN(pszResampling,"AVERAGE_BIT2",12) ) printf( "*" ); } printf( "\n" ); if ( bComputeChecksum) { printf( " Overviews checksum: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); printf( "%d", GDALChecksumImage(hOverview, 0, 0, GDALGetRasterBandXSize(hOverview), GDALGetRasterBandYSize(hOverview))); } printf( "\n" ); } } if( GDALHasArbitraryOverviews( hBand ) ) { printf( " Overviews: arbitrary\n" ); } nMaskFlags = GDALGetMaskFlags( hBand ); if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 ) { GDALRasterBandH hMaskBand = GDALGetMaskBand(hBand) ; printf( " Mask Flags: " ); if( nMaskFlags & GMF_PER_DATASET ) printf( "PER_DATASET " ); if( nMaskFlags & GMF_ALPHA ) printf( "ALPHA " ); if( nMaskFlags & GMF_NODATA ) printf( "NODATA " ); if( nMaskFlags & GMF_ALL_VALID ) printf( "ALL_VALID " ); printf( "\n" ); if( hMaskBand != NULL && GDALGetOverviewCount(hMaskBand) > 0 ) { int iOverview; printf( " Overviews of mask band: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hMaskBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hMaskBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); } printf( "\n" ); } } if( strlen(GDALGetRasterUnitType(hBand)) > 0 ) { printf( " Unit Type: %s\n", GDALGetRasterUnitType(hBand) ); } if( GDALGetRasterCategoryNames(hBand) != NULL ) { char **papszCategories = GDALGetRasterCategoryNames(hBand); int i; printf( " Categories:\n" ); for( i = 0; papszCategories[i] != NULL; i++ ) printf( " %3d: %s\n", i, papszCategories[i] ); } if( GDALGetRasterScale( hBand, &bSuccess ) != 1.0 || GDALGetRasterOffset( hBand, &bSuccess ) != 0.0 ) printf( " Offset: %.15g, Scale:%.15g\n", GDALGetRasterOffset( hBand, &bSuccess ), GDALGetRasterScale( hBand, &bSuccess ) ); papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, NULL ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( " Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, "IMAGE_STRUCTURE" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( " Image Structure Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex && (hTable = GDALGetRasterColorTable( hBand )) != NULL ) { int i; printf( " Color Table (%s with %d entries)\n", GDALGetPaletteInterpretationName( GDALGetPaletteInterpretation( hTable )), GDALGetColorEntryCount( hTable ) ); if (bShowColorTable) { for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hTable, i, &sEntry ); printf( " %3d: %d,%d,%d,%d\n", i, sEntry.c1, sEntry.c2, sEntry.c3, sEntry.c4 ); } } } if( bShowRAT && GDALGetDefaultRAT( hBand ) != NULL ) { GDALRasterAttributeTableH hRAT = GDALGetDefaultRAT( hBand ); GDALRATDumpReadable( hRAT, NULL ); } } GDALClose( hDataset ); CSLDestroy( papszExtraMDDomains ); CSLDestroy( argv ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); CPLCleanupTLS(); exit( 0 ); }
int main( int argc, char *argv[] ) { if( argc < 5 ) { usage(); return 1; } int i, row, col; char *in[MAXFILES]; char *out; int imgs_per_year; int n_imgs; int n_null_pix; GDALDatasetH hD[MAXFILES+1]; GDALAllRegister(); GDALDriverH hDr[MAXFILES+1]; GDALRasterBandH hB[MAXFILES+1]; float *l[MAXFILES+1]; int nX, nY; out = argv[1]; printf("Loading input files:\n"); n_imgs = argc - 2; for (i=0;i<n_imgs;i++){ printf("%i / %i %s\r",i,n_imgs,argv[i+2]); in[i] = argv[i+2]; hD[i] = GDALOpen(in[i],GA_ReadOnly); hDr[i] = GDALGetDatasetDriver(hD[i]); hB[i] = GDALGetRasterBand(hD[i],1); nX = GDALGetRasterBandXSize(hB[0]); l[i] = (float *) malloc(sizeof(float)*nX); } nY = GDALGetRasterBandYSize(hB[0]); //Creating output file hD[n_imgs] = GDALCreateCopy( hDr[0], out,hD[0],FALSE,NULL,NULL,NULL); hB[n_imgs] = GDALGetRasterBand(hD[n_imgs],1); l[n_imgs] = (float *) malloc(sizeof(float)*nX); //Accessing the data rowxrow //--------------------------- for(row=0;row<nY;row++){ for (i=0;i<n_imgs;i++){ GDALRasterIO(hB[i],GF_Read,0,row,nX,1,l[i],nX,1,GDT_Float32,0,0); } //Processing the data cellxcell //----------------------------- for(col=0;col<nX;col++){ if(l[i][col] < 0) l[n_imgs][col] = -28768 ; else{ l[n_imgs][col] = 0.0; n_null_pix = 0; for (i=0;i<n_imgs;i++){ if(l[i][col] > 1) n_null_pix++; else l[n_imgs][col] += l[i][col]; } l[n_imgs][col] /= (n_imgs - n_null_pix); } } for(col=0;col<nX;col++){ l[n_imgs][col] *= 32000 ; /*to recover any positive pixel*/ //if(l[n_imgs][col]>0&&l[n_imgs][col]<1) // l[n_imgs][col]=1; } GDALRasterIO(hB[n_imgs],GF_Write,0,row,nX,1,l[n_imgs],nX,1,GDT_Float32,0,0); } for (i=0;i<n_imgs+1;i++){ if( l[i] != NULL ) free( l[i] ); GDALClose(hD[i]); } }
static void DumpBand( GDALDatasetH hBaseDS, GDALRasterBandH hSrcOver, const char *pszName ) { /* -------------------------------------------------------------------- */ /* Get base ds info. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; bool bHaveGT = GDALGetGeoTransform( hBaseDS, adfGeoTransform ) == CE_None; int nOrigXSize = GDALGetRasterXSize( hBaseDS ); int nOrigYSize = GDALGetRasterYSize( hBaseDS ); /* -------------------------------------------------------------------- */ /* Create matching output file. */ /* -------------------------------------------------------------------- */ int nXSize = GDALGetRasterBandXSize( hSrcOver ); int nYSize = GDALGetRasterBandYSize( hSrcOver ); GDALDataType eDT = GDALGetRasterDataType( hSrcOver ); GDALDriverH hDriver = GDALGetDriverByName( "GTiff" ); GDALDatasetH hDstDS = GDALCreate( hDriver, pszName, nXSize, nYSize, 1, eDT, NULL ); if( hDstDS == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Apply corresponding georeferencing, scaled to size. */ /* -------------------------------------------------------------------- */ if( bHaveGT ) { double adfOvGeoTransform[6]; memcpy( adfOvGeoTransform, adfGeoTransform, sizeof(double) * 6 ); adfOvGeoTransform[1] *= (nOrigXSize / (double) nXSize); adfOvGeoTransform[2] *= (nOrigXSize / (double) nXSize); adfOvGeoTransform[4] *= (nOrigYSize / (double) nYSize); adfOvGeoTransform[5] *= (nOrigYSize / (double) nYSize); GDALSetGeoTransform( hDstDS, adfOvGeoTransform ); GDALSetProjection( hDstDS, GDALGetProjectionRef( hBaseDS ) ); } /* -------------------------------------------------------------------- */ /* Copy over all the image data. */ /* -------------------------------------------------------------------- */ void *pData = CPLMalloc(64 * nXSize); for( int iLine = 0; iLine < nYSize; iLine++ ) { GDALRasterIO( hSrcOver, GF_Read, 0, iLine, nXSize, 1, pData, nXSize, 1, eDT, 0, 0 ); GDALRasterIO( GDALGetRasterBand( hDstDS, 1 ), GF_Write, 0, iLine, nXSize, 1, pData, nXSize, 1, eDT, 0, 0 ); } CPLFree( pData ); GDALClose( hDstDS ); }
int main( int argc, char ** argv ) { const char *pszLocX = NULL, *pszLocY = NULL; const char *pszSrcFilename = NULL; char *pszSourceSRS = NULL; std::vector<int> anBandList; bool bAsXML = false, bLIFOnly = false; bool bQuiet = false, bValOnly = false; int nOverview = -1; char **papszOpenOptions = NULL; GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ int i; for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i],"-b") && i < argc-1 ) { anBandList.push_back( atoi(argv[++i]) ); } else if( EQUAL(argv[i],"-overview") && i < argc-1 ) { nOverview = atoi(argv[++i]) - 1; } else if( EQUAL(argv[i],"-l_srs") && i < argc-1 ) { CPLFree(pszSourceSRS); pszSourceSRS = SanitizeSRS(argv[++i]); } else if( EQUAL(argv[i],"-geoloc") ) { CPLFree(pszSourceSRS); pszSourceSRS = CPLStrdup("-geoloc"); } else if( EQUAL(argv[i],"-wgs84") ) { CPLFree(pszSourceSRS); pszSourceSRS = SanitizeSRS("WGS84"); } else if( EQUAL(argv[i],"-xml") ) { bAsXML = true; } else if( EQUAL(argv[i],"-lifonly") ) { bLIFOnly = true; bQuiet = true; } else if( EQUAL(argv[i],"-valonly") ) { bValOnly = true; bQuiet = true; } else if( EQUAL(argv[i], "-oo") && i < argc-1 ) { papszOpenOptions = CSLAddString( papszOpenOptions, argv[++i] ); } else if( argv[i][0] == '-' && !isdigit(argv[i][1]) ) Usage(); else if( pszSrcFilename == NULL ) pszSrcFilename = argv[i]; else if( pszLocX == NULL ) pszLocX = argv[i]; else if( pszLocY == NULL ) pszLocY = argv[i]; else Usage(); } if( pszSrcFilename == NULL || (pszLocX != NULL && pszLocY == NULL) ) Usage(); /* -------------------------------------------------------------------- */ /* Open source file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hSrcDS = NULL; hSrcDS = GDALOpenEx( pszSrcFilename, GDAL_OF_RASTER, NULL, (const char* const* )papszOpenOptions, NULL ); if( hSrcDS == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Setup coordinate transformation, if required */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hSrcSRS = NULL, hTrgSRS = NULL; OGRCoordinateTransformationH hCT = NULL; if( pszSourceSRS != NULL && !EQUAL(pszSourceSRS,"-geoloc") ) { hSrcSRS = OSRNewSpatialReference( pszSourceSRS ); hTrgSRS = OSRNewSpatialReference( GDALGetProjectionRef( hSrcDS ) ); hCT = OCTNewCoordinateTransformation( hSrcSRS, hTrgSRS ); if( hCT == NULL ) exit( 1 ); } /* -------------------------------------------------------------------- */ /* If no bands were requested, we will query them all. */ /* -------------------------------------------------------------------- */ if( anBandList.size() == 0 ) { for( i = 0; i < GDALGetRasterCount( hSrcDS ); i++ ) anBandList.push_back( i+1 ); } /* -------------------------------------------------------------------- */ /* Turn the location into a pixel and line location. */ /* -------------------------------------------------------------------- */ int inputAvailable = 1; double dfGeoX; double dfGeoY; CPLString osXML; if( pszLocX == NULL && pszLocY == NULL ) { if (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2) { inputAvailable = 0; } } else { dfGeoX = CPLAtof(pszLocX); dfGeoY = CPLAtof(pszLocY); } while (inputAvailable) { int iPixel, iLine; if (hCT) { if( !OCTTransform( hCT, 1, &dfGeoX, &dfGeoY, NULL ) ) exit( 1 ); } if( pszSourceSRS != NULL ) { double adfGeoTransform[6], adfInvGeoTransform[6]; if( GDALGetGeoTransform( hSrcDS, adfGeoTransform ) != CE_None ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get geotransform"); exit( 1 ); } if( !GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform ) ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot invert geotransform"); exit( 1 ); } iPixel = (int) floor( adfInvGeoTransform[0] + adfInvGeoTransform[1] * dfGeoX + adfInvGeoTransform[2] * dfGeoY ); iLine = (int) floor( adfInvGeoTransform[3] + adfInvGeoTransform[4] * dfGeoX + adfInvGeoTransform[5] * dfGeoY ); } else { iPixel = (int) floor(dfGeoX); iLine = (int) floor(dfGeoY); } /* -------------------------------------------------------------------- */ /* Prepare report. */ /* -------------------------------------------------------------------- */ CPLString osLine; if( bAsXML ) { osLine.Printf( "<Report pixel=\"%d\" line=\"%d\">", iPixel, iLine ); osXML += osLine; } else if( !bQuiet ) { printf( "Report:\n" ); printf( " Location: (%dP,%dL)\n", iPixel, iLine ); } int bPixelReport = TRUE; if( iPixel < 0 || iLine < 0 || iPixel >= GDALGetRasterXSize( hSrcDS ) || iLine >= GDALGetRasterYSize( hSrcDS ) ) { if( bAsXML ) osXML += "<Alert>Location is off this file! No further details to report.</Alert>"; else if( bValOnly ) printf("\n"); else if( !bQuiet ) printf( "\nLocation is off this file! No further details to report.\n"); bPixelReport = FALSE; } /* -------------------------------------------------------------------- */ /* Process each band. */ /* -------------------------------------------------------------------- */ for( i = 0; bPixelReport && i < (int) anBandList.size(); i++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, anBandList[i] ); int iPixelToQuery = iPixel; int iLineToQuery = iLine; if (nOverview >= 0 && hBand != NULL) { GDALRasterBandH hOvrBand = GDALGetOverview(hBand, nOverview); if (hOvrBand != NULL) { int nOvrXSize = GDALGetRasterBandXSize(hOvrBand); int nOvrYSize = GDALGetRasterBandYSize(hOvrBand); iPixelToQuery = (int)(0.5 + 1.0 * iPixel / GDALGetRasterXSize( hSrcDS ) * nOvrXSize); iLineToQuery = (int)(0.5 + 1.0 * iLine / GDALGetRasterYSize( hSrcDS ) * nOvrYSize); if (iPixelToQuery >= nOvrXSize) iPixelToQuery = nOvrXSize - 1; if (iLineToQuery >= nOvrYSize) iLineToQuery = nOvrYSize - 1; } else { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get overview %d of band %d", nOverview + 1, anBandList[i] ); } hBand = hOvrBand; } if (hBand == NULL) continue; if( bAsXML ) { osLine.Printf( "<BandReport band=\"%d\">", anBandList[i] ); osXML += osLine; } else if( !bQuiet ) { printf( " Band %d:\n", anBandList[i] ); } /* -------------------------------------------------------------------- */ /* Request location info for this location. It is possible */ /* only the VRT driver actually supports this. */ /* -------------------------------------------------------------------- */ CPLString osItem; osItem.Printf( "Pixel_%d_%d", iPixelToQuery, iLineToQuery ); const char *pszLI = GDALGetMetadataItem( hBand, osItem, "LocationInfo"); if( pszLI != NULL ) { if( bAsXML ) osXML += pszLI; else if( !bQuiet ) printf( " %s\n", pszLI ); else if( bLIFOnly ) { /* Extract all files, if any. */ CPLXMLNode *psRoot = CPLParseXMLString( pszLI ); if( psRoot != NULL && psRoot->psChild != NULL && psRoot->eType == CXT_Element && EQUAL(psRoot->pszValue,"LocationInfo") ) { CPLXMLNode *psNode; for( psNode = psRoot->psChild; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType == CXT_Element && EQUAL(psNode->pszValue,"File") && psNode->psChild != NULL ) { char* pszUnescaped = CPLUnescapeString( psNode->psChild->pszValue, NULL, CPLES_XML); printf( "%s\n", pszUnescaped ); CPLFree(pszUnescaped); } } } CPLDestroyXMLNode( psRoot ); } } /* -------------------------------------------------------------------- */ /* Report the pixel value of this band. */ /* -------------------------------------------------------------------- */ double adfPixel[2]; if( GDALRasterIO( hBand, GF_Read, iPixelToQuery, iLineToQuery, 1, 1, adfPixel, 1, 1, GDT_CFloat64, 0, 0) == CE_None ) { CPLString osValue; if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) ) osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] ); else osValue.Printf( "%.15g", adfPixel[0] ); if( bAsXML ) { osXML += "<Value>"; osXML += osValue; osXML += "</Value>"; } else if( !bQuiet ) printf( " Value: %s\n", osValue.c_str() ); else if( bValOnly ) printf( "%s\n", osValue.c_str() ); // Report unscaled if we have scale/offset values. int bSuccess; double dfOffset = GDALGetRasterOffset( hBand, &bSuccess ); double dfScale = GDALGetRasterScale( hBand, &bSuccess ); if( dfOffset != 0.0 || dfScale != 1.0 ) { adfPixel[0] = adfPixel[0] * dfScale + dfOffset; adfPixel[1] = adfPixel[1] * dfScale + dfOffset; if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) ) osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] ); else osValue.Printf( "%.15g", adfPixel[0] ); if( bAsXML ) { osXML += "<DescaledValue>"; osXML += osValue; osXML += "</DescaledValue>"; } else if( !bQuiet ) printf( " Descaled Value: %s\n", osValue.c_str() ); } } if( bAsXML ) osXML += "</BandReport>"; } osXML += "</Report>"; if( (pszLocX != NULL && pszLocY != NULL) || (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2) ) { inputAvailable = 0; } } /* -------------------------------------------------------------------- */ /* Finalize xml report and print. */ /* -------------------------------------------------------------------- */ if( bAsXML ) { CPLXMLNode *psRoot; char *pszFormattedXML; psRoot = CPLParseXMLString( osXML ); pszFormattedXML = CPLSerializeXMLTree( psRoot ); CPLDestroyXMLNode( psRoot ); printf( "%s", pszFormattedXML ); CPLFree( pszFormattedXML ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ if (hCT) { OSRDestroySpatialReference( hSrcSRS ); OSRDestroySpatialReference( hTrgSRS ); OCTDestroyCoordinateTransformation( hCT ); } if (hSrcDS) GDALClose(hSrcDS); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLFree(pszSourceSRS); CSLDestroy(papszOpenOptions); CSLDestroy( argv ); return 0; }
CPLErr CPL_STDCALL GDALFPolygonize( GDALRasterBandH hSrcBand, GDALRasterBandH hMaskBand, OGRLayerH hOutLayer, int iPixValField, char **papszOptions, GDALProgressFunc pfnProgress, void * pProgressArg ) { #ifndef OGR_ENABLED CPLError(CE_Failure, CPLE_NotSupported, "GDALFPolygonize() unimplemented in a non OGR build"); return CE_Failure; #else VALIDATE_POINTER1( hSrcBand, "GDALFPolygonize", CE_Failure ); VALIDATE_POINTER1( hOutLayer, "GDALFPolygonize", CE_Failure ); if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nConnectedness = CSLFetchNameValue( papszOptions, "8CONNECTED" ) ? 8 : 4; /* -------------------------------------------------------------------- */ /* Confirm our output layer will support feature creation. */ /* -------------------------------------------------------------------- */ if( !OGR_L_TestCapability( hOutLayer, OLCSequentialWrite ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Output feature layer does not appear to support creation\n" "of features in GDALFPolygonize()." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Allocate working buffers. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; int nXSize = GDALGetRasterBandXSize( hSrcBand ); int nYSize = GDALGetRasterBandYSize( hSrcBand ); float *pafLastLineVal = (float *) VSIMalloc2(sizeof(float),nXSize + 2); float *pafThisLineVal = (float *) VSIMalloc2(sizeof(float),nXSize + 2); GInt32 *panLastLineId = (GInt32 *) VSIMalloc2(sizeof(GInt32),nXSize + 2); GInt32 *panThisLineId = (GInt32 *) VSIMalloc2(sizeof(GInt32),nXSize + 2); GByte *pabyMaskLine = (hMaskBand != NULL) ? (GByte *) VSIMalloc(nXSize) : NULL; if (pafLastLineVal == NULL || pafThisLineVal == NULL || panLastLineId == NULL || panThisLineId == NULL || (hMaskBand != NULL && pabyMaskLine == NULL)) { CPLError(CE_Failure, CPLE_OutOfMemory, "Could not allocate enough memory for temporary buffers"); CPLFree( panThisLineId ); CPLFree( panLastLineId ); CPLFree( pafThisLineVal ); CPLFree( pafLastLineVal ); CPLFree( pabyMaskLine ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Get the geotransform, if there is one, so we can convert the */ /* vectors into georeferenced coordinates. */ /* -------------------------------------------------------------------- */ GDALDatasetH hSrcDS = GDALGetBandDataset( hSrcBand ); double adfGeoTransform[6] = { 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 }; if( hSrcDS ) GDALGetGeoTransform( hSrcDS, adfGeoTransform ); /* -------------------------------------------------------------------- */ /* The first pass over the raster is only used to build up the */ /* polygon id map so we will know in advance what polygons are */ /* what on the second pass. */ /* -------------------------------------------------------------------- */ int iY; GDALRasterFPolygonEnumerator oFirstEnum(nConnectedness); for( iY = 0; eErr == CE_None && iY < nYSize; iY++ ) { eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iY, nXSize, 1, pafThisLineVal, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr == CE_None && hMaskBand != NULL ) eErr = GPMaskImageData( hMaskBand, pabyMaskLine, iY, nXSize, pafThisLineVal ); if( iY == 0 ) oFirstEnum.ProcessLine( NULL, pafThisLineVal, NULL, panThisLineId, nXSize ); else oFirstEnum.ProcessLine( pafLastLineVal, pafThisLineVal, panLastLineId, panThisLineId, nXSize ); // swap lines float * pafTmp = pafLastLineVal; pafLastLineVal = pafThisLineVal; pafThisLineVal = pafTmp; GInt32 * panTmp = panThisLineId; panThisLineId = panLastLineId; panLastLineId = panTmp; /* -------------------------------------------------------------------- */ /* Report progress, and support interrupts. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( 0.10 * ((iY+1) / (double) nYSize), "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Make a pass through the maps, ensuring every polygon id */ /* points to the final id it should use, not an intermediate */ /* value. */ /* -------------------------------------------------------------------- */ oFirstEnum.CompleteMerges(); /* -------------------------------------------------------------------- */ /* Initialize ids to -1 to serve as a nodata value for the */ /* previous line, and past the beginning and end of the */ /* scanlines. */ /* -------------------------------------------------------------------- */ int iX; panThisLineId[0] = -1; panThisLineId[nXSize+1] = -1; for( iX = 0; iX < nXSize+2; iX++ ) panLastLineId[iX] = -1; /* -------------------------------------------------------------------- */ /* We will use a new enumerator for the second pass primariliy */ /* so we can preserve the first pass map. */ /* -------------------------------------------------------------------- */ GDALRasterFPolygonEnumerator oSecondEnum(nConnectedness); RPolygonF **papoPoly = (RPolygonF **) CPLCalloc(sizeof(RPolygonF*),oFirstEnum.nNextPolygonId); /* ==================================================================== */ /* Second pass during which we will actually collect polygon */ /* edges as geometries. */ /* ==================================================================== */ for( iY = 0; eErr == CE_None && iY < nYSize+1; iY++ ) { /* -------------------------------------------------------------------- */ /* Read the image data. */ /* -------------------------------------------------------------------- */ if( iY < nYSize ) { eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iY, nXSize, 1, pafThisLineVal, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr == CE_None && hMaskBand != NULL ) eErr = GPMaskImageData( hMaskBand, pabyMaskLine, iY, nXSize, pafThisLineVal ); } if( eErr != CE_None ) continue; /* -------------------------------------------------------------------- */ /* Determine what polygon the various pixels belong to (redoing */ /* the same thing done in the first pass above). */ /* -------------------------------------------------------------------- */ if( iY == nYSize ) { for( iX = 0; iX < nXSize+2; iX++ ) panThisLineId[iX] = -1; } else if( iY == 0 ) oSecondEnum.ProcessLine( NULL, pafThisLineVal, NULL, panThisLineId+1, nXSize ); else oSecondEnum.ProcessLine( pafLastLineVal, pafThisLineVal, panLastLineId+1, panThisLineId+1, nXSize ); /* -------------------------------------------------------------------- */ /* Add polygon edges to our polygon list for the pixel */ /* boundaries within and above this line. */ /* -------------------------------------------------------------------- */ for( iX = 0; iX < nXSize+1; iX++ ) { AddEdges( panThisLineId, panLastLineId, oFirstEnum.panPolyIdMap, oFirstEnum.pafPolyValue, papoPoly, iX, iY ); } /* -------------------------------------------------------------------- */ /* Periodically we scan out polygons and write out those that */ /* haven't been added to on the last line as we can be sure */ /* they are complete. */ /* -------------------------------------------------------------------- */ if( iY % 8 == 7 ) { for( iX = 0; eErr == CE_None && iX < oSecondEnum.nNextPolygonId; iX++ ) { if( papoPoly[iX] && papoPoly[iX]->nLastLineUpdated < iY-1 ) { if( hMaskBand == NULL || !GDALFloatEquals(papoPoly[iX]->fPolyValue, GP_NODATA_MARKER) ) { eErr = EmitPolygonToLayer( hOutLayer, iPixValField, papoPoly[iX], adfGeoTransform ); } delete papoPoly[iX]; papoPoly[iX] = NULL; } } } /* -------------------------------------------------------------------- */ /* Swap pixel value, and polygon id lines to be ready for the */ /* next line. */ /* -------------------------------------------------------------------- */ float *pafTmp = pafLastLineVal; pafLastLineVal = pafThisLineVal; pafThisLineVal = pafTmp; GInt32 *panTmp = panThisLineId; panThisLineId = panLastLineId; panLastLineId = panTmp; /* -------------------------------------------------------------------- */ /* Report progress, and support interrupts. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( 0.10 + 0.90 * ((iY+1) / (double) nYSize), "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Make a cleanup pass for all unflushed polygons. */ /* -------------------------------------------------------------------- */ for( iX = 0; eErr == CE_None && iX < oSecondEnum.nNextPolygonId; iX++ ) { if( papoPoly[iX] ) { if( hMaskBand == NULL || !GDALFloatEquals(papoPoly[iX]->fPolyValue, GP_NODATA_MARKER) ) { eErr = EmitPolygonToLayer( hOutLayer, iPixValField, papoPoly[iX], adfGeoTransform ); } delete papoPoly[iX]; papoPoly[iX] = NULL; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLFree( panThisLineId ); CPLFree( panLastLineId ); CPLFree( pafThisLineVal ); CPLFree( pafLastLineVal ); CPLFree( pabyMaskLine ); CPLFree( papoPoly ); return eErr; #endif // OGR_ENABLED }
/* * POPULATE_METADATA_STRUCT * * This routine just queries the GDAL raster file for all the metadata * that can be squeezed out of it. * * The resulting matlab structure is by necessity nested. Each raster * file can have several bands, e.g. PNG files usually have 3, a red, a * blue, and a green channel. Each band can have several overviews (tiffs * come to mind here). * * Fields: * ProjectionRef: a string describing the projection. Not parsed. * GeoTransform: * a 6-tuple. Entries are as follows. * [0] --> top left x * [1] --> w-e pixel resolution * [2] --> rotation, 0 if image is "north up" * [3] --> top left y * [4] --> rotation, 0 if image is "north up" * [5] --> n-s pixel resolution * * DriverShortName: describes the driver used to query *this* raster file * DriverLongName: describes the driver used to query *this* raster file * RasterXSize, RasterYSize: * These are the primary dimensions of the raster. See "Overview", though. * RasterCount: * Number of raster bands present in the file. * Driver: * This itself is a structure array. Each element describes a driver * that the locally compiled GDAL library has available. So you recompile * GDAL with new format support, this structure will change. * * Fields: * DriverShortName, DriverLongName: * Same as fields in top level structure with same name. * * Band: * Also a structure array. One element for each raster band present in * the GDAL file. See "RasterCount". * * Fields: * XSize, YSize: * Dimensions of the current raster band. * Overview: * A structure array, one element for each overview present. If * empty, then there are no overviews. * NoDataValue: * When passed back to MATLAB, one can set pixels with this value to NaN. * ColorMap: * A Mx3 double array with the colormap, or empty if it does not exists * * */ mxArray *populate_metadata_struct (GDALDatasetH hDataset, int correct_bounds) { /* These are used to define the metadata structure about available GDAL drivers. */ mxArray *mxtmp; mxArray *mxProjectionRef; mxArray *mxGeoTransform; mxArray *mxGDALDriverShortName; mxArray *mxGDALDriverLongName; mxArray *mxGDALRasterCount; mxArray *mxGDALRasterXSize; mxArray *mxGDALRasterYSize; mxArray *mxCorners; mxArray *mxGMT_header; /* * These will be matlab structures that hold the metadata. * "metadata_struct" actually encompasses "band_struct", * which encompasses "overview_struct" * */ mxArray *metadata_struct; mxArray *band_struct; mxArray *overview_struct; mxArray *corner_struct; int overview, band_number; /* Loop indices */ double *dptr; /* short cut to the mxArray data */ double *dptr2; /* "" */ GDALDriverH hDriver; /* This is the driver chosen by the GDAL library to query the dataset. */ GDALRasterBandH hBand, overview_hBand; int num_overview_fields; /* Number of metadata items for each overview structure. */ int status; /* success or failure */ double adfGeoTransform[6]; /* bounds on the dataset */ int num_overviews; /* Number of overviews in the current band. */ int num_struct_fields; /* number of fields in the metadata structures. */ int num_band_fields; int num_corner_fields; char *fieldnames[100]; /* this array contains the names of the fields of the metadata structure. */ char *band_fieldnames[100]; char *corner_fieldnames[100]; char *overview_fieldnames[100]; int xSize, ySize, raster_count; /* Dimensions of the dataset */ int gdal_type; /* Datatype of the bands. */ double tmpdble; /* temporary value */ double xy_c[2]; /* Corner coordinates */ int dims[2]; int bGotMin, bGotMax; /* To know if driver transmited Min/Max */ double adfMinMax[2]; /* Dataset Min Max */ double z_min = 1e50, z_max = -1e50; /* Create the metadata structure. Just one element, with XXX fields. */ num_struct_fields = 10; fieldnames[0] = strdup ("ProjectionRef"); fieldnames[1] = strdup ("GeoTransform"); fieldnames[2] = strdup ("DriverShortName"); fieldnames[3] = strdup ("DriverLongName"); fieldnames[4] = strdup ("RasterXSize"); fieldnames[5] = strdup ("RasterYSize"); fieldnames[6] = strdup ("RasterCount"); fieldnames[7] = strdup ("Band"); fieldnames[8] = strdup ("Corners"); fieldnames[9] = strdup("GMT_hdr"); metadata_struct = mxCreateStructMatrix ( 1, 1, num_struct_fields, (const char **)fieldnames ); /* Record the ProjectionRef. */ mxProjectionRef = mxCreateString ( GDALGetProjectionRef( hDataset ) ); mxSetField ( metadata_struct, 0, "ProjectionRef", mxProjectionRef ); /* Record the geotransform. */ mxGeoTransform = mxCreateNumericMatrix ( 6, 1, mxDOUBLE_CLASS, mxREAL ); dptr = mxGetPr ( mxGeoTransform ); if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { dptr[0] = adfGeoTransform[0]; dptr[1] = adfGeoTransform[1]; dptr[2] = adfGeoTransform[2]; dptr[3] = adfGeoTransform[3]; dptr[4] = adfGeoTransform[4]; dptr[5] = adfGeoTransform[5]; mxSetField ( metadata_struct, 0, "GeoTransform", mxGeoTransform ); } /* Get driver information */ hDriver = GDALGetDatasetDriver( hDataset ); mxGDALDriverShortName = mxCreateString ( GDALGetDriverShortName( hDriver ) ); mxSetField ( metadata_struct, 0, (const char *) "DriverShortName", mxGDALDriverShortName ); mxGDALDriverLongName = mxCreateString ( GDALGetDriverLongName( hDriver ) ); mxSetField ( metadata_struct, 0, (const char *) "DriverLongName", mxGDALDriverLongName ); xSize = GDALGetRasterXSize( hDataset ); ySize = GDALGetRasterYSize( hDataset ); mxGDALRasterXSize = mxCreateDoubleScalar ( (double) xSize ); mxSetField ( metadata_struct, 0, (const char *) "RasterXSize", mxGDALRasterXSize ); mxGDALRasterYSize = mxCreateDoubleScalar ( (double) ySize ); mxSetField ( metadata_struct, 0, (const char *) "RasterYSize", mxGDALRasterYSize ); raster_count = GDALGetRasterCount( hDataset ); mxGDALRasterCount = mxCreateDoubleScalar ( (double)raster_count ); mxSetField ( metadata_struct, 0, (const char *) "RasterCount", mxGDALRasterCount ); /* Get the metadata for each band. */ num_band_fields = 5; band_fieldnames[0] = strdup ( "XSize" ); band_fieldnames[1] = strdup ( "YSize" ); band_fieldnames[2] = strdup ( "Overview" ); band_fieldnames[3] = strdup ( "NoDataValue" ); band_fieldnames[4] = strdup ( "DataType" ); band_struct = mxCreateStructMatrix ( raster_count, 1, num_band_fields, (const char **)band_fieldnames ); num_overview_fields = 2; overview_fieldnames[0] = strdup ( "XSize" ); overview_fieldnames[1] = strdup ( "YSize" ); for ( band_number = 1; band_number <= raster_count; ++band_number ) { /* Loop over bands */ hBand = GDALGetRasterBand( hDataset, band_number ); mxtmp = mxCreateDoubleScalar ( (double) GDALGetRasterBandXSize( hBand ) ); mxSetField ( band_struct, 0, "XSize", mxtmp ); mxtmp = mxCreateDoubleScalar ( (double) GDALGetRasterBandYSize( hBand ) ); mxSetField ( band_struct, 0, "YSize", mxtmp ); gdal_type = GDALGetRasterDataType ( hBand ); mxtmp = mxCreateString ( GDALGetDataTypeName ( (GDALDataType)gdal_type ) ); mxSetField ( band_struct, 0, (const char *) "DataType", mxtmp ); tmpdble = GDALGetRasterNoDataValue ( hBand, &status ); mxtmp = mxCreateDoubleScalar ( (double) (GDALGetRasterNoDataValue ( hBand, &status ) ) ); mxSetField ( band_struct, 0, "NoDataValue", mxtmp ); num_overviews = GDALGetOverviewCount( hBand ); /* Can have multiple overviews per band. */ if ( num_overviews > 0 ) { overview_struct = mxCreateStructMatrix ( num_overviews, 1, num_overview_fields, (const char **)overview_fieldnames ); for ( overview = 0; overview < num_overviews; ++overview ) { overview_hBand = GDALGetOverview ( hBand, overview ); xSize = GDALGetRasterBandXSize ( overview_hBand ); mxtmp = mxCreateDoubleScalar ( xSize ); mxSetField ( overview_struct, overview, "XSize", mxtmp ); ySize = GDALGetRasterBandYSize ( overview_hBand ); mxtmp = mxCreateDoubleScalar ( ySize ); mxSetField ( overview_struct, overview, "YSize", mxtmp ); } mxSetField ( band_struct, 0, "Overview", overview_struct ); } } mxSetField ( metadata_struct, 0, "Band", band_struct ); /* Record the GMT header. This will be interleaved with "corners" because they share somes values */ mxGMT_header = mxCreateNumericMatrix(1, 9, mxDOUBLE_CLASS, mxREAL); dptr2 = mxGetPr(mxGMT_header); /* Record corners. */ num_corner_fields = 4; corner_fieldnames[0] = strdup ("LL"); corner_fieldnames[1] = strdup ("UL"); corner_fieldnames[2] = strdup ("UR"); corner_fieldnames[3] = strdup ("LR"); corner_struct = mxCreateStructMatrix(1, 1, num_corner_fields, (const char **)corner_fieldnames); dims[0] = 1; dims[1] = 2; ReportCorner(hDataset, 0.0, GDALGetRasterYSize(hDataset), xy_c); /* Lower Left */ mxCorners = mxCreateNumericArray (2,dims,mxDOUBLE_CLASS, mxREAL); dptr = mxGetPr(mxCorners); dptr[0] = xy_c[0]; dptr[1] = xy_c[1]; dptr2[0] = xy_c[0]; dptr2[2] = xy_c[1]; /* xmin, ymin */ mxSetField(corner_struct, 0, "LL", mxCorners ); ReportCorner(hDataset, 0.0, 0.0, xy_c); /* Upper Left */ mxCorners = mxCreateNumericArray (2,dims,mxDOUBLE_CLASS, mxREAL); dptr = mxGetPr(mxCorners); dptr[0] = xy_c[0]; dptr[1] = xy_c[1]; mxSetField(corner_struct, 0, "UL", mxCorners ); ReportCorner(hDataset, GDALGetRasterXSize(hDataset), 0.0, xy_c); /* Upper Rigt */ mxCorners = mxCreateNumericArray (2,dims,mxDOUBLE_CLASS, mxREAL); dptr = mxGetPr(mxCorners); dptr[0] = xy_c[0]; dptr[1] = xy_c[1]; dptr2[1] = xy_c[0]; dptr2[3] = xy_c[1]; /* xmax, ymax */ mxSetField(corner_struct, 0, "UR", mxCorners ); ReportCorner(hDataset, GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset), xy_c); /* Lower Rigt */ mxCorners = mxCreateNumericArray (2,dims,mxDOUBLE_CLASS, mxREAL); dptr = mxGetPr(mxCorners); dptr[0] = xy_c[0]; dptr[1] = xy_c[1]; mxSetField(corner_struct, 0, "LR", mxCorners ); mxSetField (metadata_struct, 0, "Corners", corner_struct); /* Fill in the rest of the GMT header values */ if (z_min == 1e50) { /* We don't know yet the dataset Min/Max */ adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin ); adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax ); if(!(bGotMin && bGotMax)) GDALComputeRasterMinMax( hBand, TRUE, adfMinMax ); dptr2[4] = adfMinMax[0]; dptr2[5] = adfMinMax[1]; } else { dptr2[4] = z_min; dptr2[5] = z_max; } dptr2[6] = 0; dptr2[7] = adfGeoTransform[1]; dptr2[8] = fabs(adfGeoTransform[5]); if (correct_bounds) { dptr2[0] += dptr2[7] / 2; dptr2[1] -= dptr2[7] / 2; dptr2[2] += dptr2[8] / 2; dptr2[3] -= dptr2[8] / 2; } mxSetField (metadata_struct, 0, "GMT_hdr", mxGMT_header); return ( metadata_struct ); }