CPLErr VRTSourcedRasterBand::ComputeRasterMinMax( int bApproxOK, double* adfMinMax ) { double dfMin = 0.0; double dfMax = 0.0; /* -------------------------------------------------------------------- */ /* Does the driver already know the min/max? */ /* -------------------------------------------------------------------- */ if( bApproxOK ) { int bSuccessMin, bSuccessMax; dfMin = GetMinimum( &bSuccessMin ); dfMax = GetMaximum( &bSuccessMax ); if( bSuccessMin && bSuccessMax ) { adfMinMax[0] = dfMin; adfMinMax[1] = dfMax; return CE_None; } } /* -------------------------------------------------------------------- */ /* If we have overview bands, use them for min/max. */ /* -------------------------------------------------------------------- */ if ( bApproxOK && GetOverviewCount() > 0 && !HasArbitraryOverviews() ) { GDALRasterBand *poBand; poBand = GetRasterSampleOverview( GDALSTAT_APPROX_NUMSAMPLES ); if ( poBand != this ) return poBand->ComputeRasterMinMax( FALSE, adfMinMax ); } /* -------------------------------------------------------------------- */ /* Try with source bands. */ /* -------------------------------------------------------------------- */ if ( bAntiRecursionFlag ) { CPLError( CE_Failure, CPLE_AppDefined, "VRTSourcedRasterBand::ComputeRasterMinMax() called recursively on the same band. " "It looks like the VRT is referencing itself." ); return CE_Failure; } bAntiRecursionFlag = TRUE; adfMinMax[0] = 0.0; adfMinMax[1] = 0.0; for( int iSource = 0; iSource < nSources; iSource++ ) { double adfSourceMinMax[2]; CPLErr eErr = papoSources[iSource]->ComputeRasterMinMax(GetXSize(), GetYSize(), bApproxOK, adfSourceMinMax); if (eErr != CE_None) { eErr = GDALRasterBand::ComputeRasterMinMax(bApproxOK, adfMinMax); bAntiRecursionFlag = FALSE; return eErr; } if (iSource == 0 || adfSourceMinMax[0] < adfMinMax[0]) adfMinMax[0] = adfSourceMinMax[0]; if (iSource == 0 || adfSourceMinMax[1] > adfMinMax[1]) adfMinMax[1] = adfSourceMinMax[1]; } bAntiRecursionFlag = FALSE; return CE_None; }
/** Private method to calculate statistics for each band. Populates rasterStatsMap. */ void ImageWriter::calculateStats(RasterBandStats * theRasterBandStats,GDALDataset * gdalDataset) { std::cout << "Calculating statistics..." << std::endl; GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand( 1 ); QString myColorInterpretation = GDALGetColorInterpretationName(myGdalBand->GetColorInterpretation()); theRasterBandStats->bandName=myColorInterpretation; theRasterBandStats->bandNo=1; // get the dimensions of the raster int myColsInt = myGdalBand->GetXSize(); int myRowsInt = myGdalBand->GetYSize(); theRasterBandStats->elementCountInt=myColsInt*myRowsInt; theRasterBandStats->noDataDouble=myGdalBand->GetNoDataValue(); //allocate a buffer to hold one row of ints int myAllocationSizeInt = sizeof(uint)*myColsInt; uint * myScanlineAllocInt = (uint*) CPLMalloc(myAllocationSizeInt); bool myFirstIterationFlag = true; //unfortunately we need to make two passes through the data to calculate stddev for (int myCurrentRowInt=0; myCurrentRowInt < myRowsInt;myCurrentRowInt++) { CPLErr myResult = myGdalBand->RasterIO( GF_Read, 0, myCurrentRowInt, myColsInt, 1, myScanlineAllocInt, myColsInt, 1, GDT_UInt32, 0, 0 ); for (int myCurrentColInt=0; myCurrentColInt < myColsInt; myCurrentColInt++) { //get the nth element from the current row double myDouble=myScanlineAllocInt[myCurrentColInt]; //only use this element if we have a non null element if (myDouble != theRasterBandStats->noDataDouble ) { if (myFirstIterationFlag) { //this is the first iteration so initialise vars myFirstIterationFlag=false; theRasterBandStats->minValDouble=myDouble; theRasterBandStats->maxValDouble=myDouble; } //end of true part for first iteration check else { //this is done for all subsequent iterations if (myDouble < theRasterBandStats->minValDouble) { theRasterBandStats->minValDouble=myDouble; } if (myDouble > theRasterBandStats->maxValDouble) { // printf ("Maxval updated to %f\n",myDouble); theRasterBandStats->maxValDouble=myDouble; } //only increment the running total if it is not a nodata value if (myDouble != theRasterBandStats->noDataDouble) { theRasterBandStats->sumDouble += myDouble; ++theRasterBandStats->elementCountInt; } } //end of false part for first iteration check } //end of nodata chec } //end of column wise loop } //end of row wise loop // //end of first pass through data now calculate the range theRasterBandStats->rangeDouble = theRasterBandStats->maxValDouble-theRasterBandStats->minValDouble; //calculate the mean theRasterBandStats->meanDouble = theRasterBandStats->sumDouble / theRasterBandStats->elementCountInt; //for the second pass we will get the sum of the squares / mean for (int myCurrentRowInt=0; myCurrentRowInt < myRowsInt;myCurrentRowInt++) { CPLErr myResult = myGdalBand->RasterIO( GF_Read, 0, myCurrentRowInt, myColsInt, 1, myScanlineAllocInt, myColsInt, 1, GDT_UInt32, 0, 0 ); for (int myCurrentColInt=0; myCurrentColInt < myColsInt; myCurrentColInt++) { //get the nth element from the current row double myDouble=myScanlineAllocInt[myCurrentColInt]; theRasterBandStats->sumSqrDevDouble += static_cast<double>(pow(myDouble - theRasterBandStats->meanDouble,2)); } //end of column wise loop } //end of row wise loop //divide result by sample size - 1 and get square root to get stdev theRasterBandStats->stdDevDouble = static_cast<double>(sqrt(theRasterBandStats->sumSqrDevDouble / (theRasterBandStats->elementCountInt - 1))); CPLFree(myScanlineAllocInt); //printf("CalculateStats::\n"); //std::cout << "Band Name : " << theRasterBandStats->bandName << std::endl; //printf("Band No : %i\n",theRasterBandStats->bandNo); //printf("Band min : %f\n",theRasterBandStats->minValDouble); //printf("Band max : %f\n",theRasterBandStats->maxValDouble); //printf("Band range: %f\n",theRasterBandStats->rangeDouble); //printf("Band mean : %f\n",theRasterBandStats->meanDouble); //printf("Band sum : %f\n",theRasterBandStats->sumDouble); return ; }
GDALDataset *GS7BGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, CPL_UNUSED char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "Driver does not support source dataset with zero band.\n"); return NULL; } else if (nBands > 1) { if( bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "Unable to create copy, " "format only supports one raster band.\n" ); return NULL; } else CPLError( CE_Warning, CPLE_NotSupported, "Format only supports one " "raster band, first band will be copied.\n" ); } GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); if( !pfnProgress( 0.0, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" ); return NULL; } VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file '%s' failed.\n", pszFilename ); return NULL; } GInt32 nXSize = poSrcBand->GetXSize(); GInt32 nYSize = poSrcBand->GetYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2; double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]; double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3]; double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2; CPLErr eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* Copy band data. */ /* -------------------------------------------------------------------- */ double *pfData = (double *)VSI_MALLOC2_VERBOSE( nXSize, sizeof( double ) ); if( pfData == NULL ) { VSIFCloseL( fp ); return NULL; } int bSrcHasNDValue; double dfSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue ); double dfMinZ = DBL_MAX; double dfMaxZ = -DBL_MAX; for( GInt32 iRow = nYSize - 1; iRow >= 0; iRow-- ) { eErr = poSrcBand->RasterIO( GF_Read, 0, iRow, nXSize, 1, pfData, nXSize, 1, GDT_Float64, 0, 0, NULL ); if( eErr != CE_None ) { VSIFCloseL( fp ); VSIFree( pfData ); return NULL; } for( int iCol=0; iCol<nXSize; iCol++ ) { if( bSrcHasNDValue && pfData[iCol] == dfSrcNoDataValue ) { pfData[iCol] = dfDefaultNoDataValue; } else { if( pfData[iCol] > dfMaxZ ) dfMaxZ = pfData[iCol]; if( pfData[iCol] < dfMinZ ) dfMinZ = pfData[iCol]; } CPL_LSBPTR64( pfData+iCol ); } if( VSIFWriteL( (void *)pfData, sizeof( double ), nXSize, fp ) != static_cast<unsigned>(nXSize) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid row. Disk full?\n" ); return NULL; } if( !pfnProgress( static_cast<double>(nYSize - iRow)/nYSize, NULL, pProgressData ) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return NULL; } } VSIFree( pfData ); /* write out the min and max values */ eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename, GA_Update ); if (poDS) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); } return poDS; }
/* TODO: check if georeference is the same as for BLX files, WGS84 */ static GDALDataset * BLXCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { // -------------------------------------------------------------------- // Some rudimentary checks // -------------------------------------------------------------------- const int nBands = poSrcDS->GetRasterCount(); if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "BLX driver doesn't support %d bands. Must be 1 (grey) ", nBands ); return NULL; } if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Int16 && bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "BLX driver doesn't support data type %s. " "Only 16 bit byte bands supported.\n", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); return NULL; } const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); if( (nXSize % 128 != 0) || (nYSize % 128 != 0) ) { CPLError( CE_Failure, CPLE_NotSupported, "BLX driver doesn't support dimensions that are not a multiple of 128.\n"); return NULL; } // -------------------------------------------------------------------- // What options has the user selected? // -------------------------------------------------------------------- int zscale = 1; if( CSLFetchNameValue(papszOptions,"ZSCALE") != NULL ) { zscale = atoi(CSLFetchNameValue(papszOptions,"ZSCALE")); if( zscale < 1 ) { CPLError( CE_Failure, CPLE_IllegalArg, "ZSCALE=%s is not a legal value in the range >= 1.", CSLFetchNameValue(papszOptions,"ZSCALE") ); return NULL; } } int fillundef = 1; if( CSLFetchNameValue(papszOptions,"FILLUNDEF") != NULL && EQUAL(CSLFetchNameValue(papszOptions,"FILLUNDEF"),"NO") ) fillundef = 0; int fillundefval = 0; if( CSLFetchNameValue(papszOptions,"FILLUNDEFVAL") != NULL ) { fillundefval = atoi(CSLFetchNameValue(papszOptions,"FILLUNDEFVAL")); if( (fillundefval < -32768) || (fillundefval > 32767) ) { CPLError( CE_Failure, CPLE_IllegalArg, "FILLUNDEFVAL=%s is not a legal value in the range -32768, 32767.", CSLFetchNameValue(papszOptions,"FILLUNDEFVAL") ); return NULL; } } int endian = LITTLEENDIAN; if( CSLFetchNameValue(papszOptions,"BIGENDIAN") != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"BIGENDIAN"),"NO") ) endian = BIGENDIAN; // -------------------------------------------------------------------- // Create the dataset. // -------------------------------------------------------------------- // Create a BLX context blxcontext_t *ctx = blx_create_context(); // Setup BLX parameters ctx->cell_rows = nYSize / ctx->cell_ysize; ctx->cell_cols = nXSize / ctx->cell_xsize; ctx->zscale = zscale; ctx->fillundef = fillundef; ctx->fillundefval = fillundefval; ctx->endian = endian; if(blxopen(ctx, pszFilename, "wb")) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create blx file %s.\n", pszFilename ); blx_free_context(ctx); return NULL; } // -------------------------------------------------------------------- // Loop over image, copying image data. // -------------------------------------------------------------------- GInt16 *pabyTile = (GInt16 *) VSI_MALLOC_VERBOSE( sizeof(GInt16)*ctx->cell_xsize*ctx->cell_ysize ); if (pabyTile == NULL) { blxclose(ctx); blx_free_context(ctx); return NULL; } CPLErr eErr=CE_None; if( !pfnProgress( 0.0, NULL, pProgressData ) ) eErr = CE_Failure; for(int i=0; (i < ctx->cell_rows) && (eErr == CE_None); i++) for(int j=0; j < ctx->cell_cols; j++) { blxdata *celldata; GDALRasterBand * poBand = poSrcDS->GetRasterBand( 1 ); eErr = poBand->RasterIO( GF_Read, j*ctx->cell_xsize, i*ctx->cell_ysize, ctx->cell_xsize, ctx->cell_ysize, pabyTile, ctx->cell_xsize, ctx->cell_ysize, GDT_Int16, 0, 0, NULL ); if(eErr >= CE_Failure) break; celldata = pabyTile; if (blx_writecell(ctx, celldata, i, j) != 0) { eErr = CE_Failure; break; } if ( ! pfnProgress( 1.0 * (i * ctx->cell_cols + j) / (ctx->cell_rows * ctx->cell_cols), NULL, pProgressData )) { eErr = CE_Failure; break; } } pfnProgress( 1.0, NULL, pProgressData ); CPLFree( pabyTile ); double adfGeoTransform[6]; if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None ) { ctx->lon = adfGeoTransform[0]; ctx->lat = adfGeoTransform[3]; ctx->pixelsize_lon = adfGeoTransform[1]; ctx->pixelsize_lat = adfGeoTransform[5]; } blxclose(ctx); blx_free_context(ctx); if (eErr == CE_None) return reinterpret_cast<GDALDataset *>( GDALOpen( pszFilename, GA_ReadOnly ) ); return NULL; }
GDALDataset * GIFDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); int bInterlace = FALSE; /* -------------------------------------------------------------------- */ /* Check for interlaced option. */ /* -------------------------------------------------------------------- */ bInterlace = CSLFetchBoolean(papszOptions, "INTERLACING", FALSE); /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "GIF driver only supports one band images.\n" ); return NULL; } if (nXSize > 65535 || nYSize > 65535) { CPLError( CE_Failure, CPLE_NotSupported, "GIF driver only supports datasets up to 65535x65535 size.\n" ); return NULL; } if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte && bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "GIF driver doesn't support data type %s. " "Only eight bit bands supported.\n", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the output file. */ /* -------------------------------------------------------------------- */ GifFileType *hGifFile; VSILFILE *fp; fp = VSIFOpenL( pszFilename, "wb" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create %s:\n%s", pszFilename, VSIStrerror( errno ) ); return NULL; } #if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5 int nError; hGifFile = EGifOpen( fp, VSIGIFWriteFunc, &nError ); #else hGifFile = EGifOpen( fp, VSIGIFWriteFunc ); #endif if( hGifFile == NULL ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_OpenFailed, "EGifOpenFilename(%s) failed. Does file already exist?", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Prepare colortable. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poBand = poSrcDS->GetRasterBand(1); ColorMapObject *psGifCT; int iColor; if( poBand->GetColorTable() == NULL ) { psGifCT = GifMakeMapObject( 256, NULL ); for( iColor = 0; iColor < 256; iColor++ ) { psGifCT->Colors[iColor].Red = (GifByteType) iColor; psGifCT->Colors[iColor].Green = (GifByteType) iColor; psGifCT->Colors[iColor].Blue = (GifByteType) iColor; } } else { GDALColorTable *poCT = poBand->GetColorTable(); int nFullCount = 1; while( nFullCount < poCT->GetColorEntryCount() ) nFullCount = nFullCount * 2; psGifCT = GifMakeMapObject( nFullCount, NULL ); for( iColor = 0; iColor < poCT->GetColorEntryCount(); iColor++ ) { GDALColorEntry sEntry; poCT->GetColorEntryAsRGB( iColor, &sEntry ); psGifCT->Colors[iColor].Red = (GifByteType) sEntry.c1; psGifCT->Colors[iColor].Green = (GifByteType) sEntry.c2; psGifCT->Colors[iColor].Blue = (GifByteType) sEntry.c3; } for( ; iColor < nFullCount; iColor++ ) { psGifCT->Colors[iColor].Red = 0; psGifCT->Colors[iColor].Green = 0; psGifCT->Colors[iColor].Blue = 0; } } /* -------------------------------------------------------------------- */ /* Setup parameters. */ /* -------------------------------------------------------------------- */ if (EGifPutScreenDesc(hGifFile, nXSize, nYSize, psGifCT->ColorCount, 255, psGifCT) == GIF_ERROR) { GifFreeMapObject(psGifCT); GDALPrintGifError(hGifFile, "Error writing gif file."); GIFAbstractDataset::myEGifCloseFile(hGifFile); VSIFCloseL( fp ); return NULL; } GifFreeMapObject(psGifCT); psGifCT = NULL; /* Support for transparency */ int bNoDataValue; double noDataValue = poBand->GetNoDataValue(&bNoDataValue); if (bNoDataValue && noDataValue >= 0 && noDataValue <= 255) { unsigned char extensionData[4]; extensionData[0] = 1; /* Transparent Color Flag */ extensionData[1] = 0; extensionData[2] = 0; extensionData[3] = (unsigned char)noDataValue; EGifPutExtension(hGifFile, 0xf9, 4, extensionData); } if (EGifPutImageDesc(hGifFile, 0, 0, nXSize, nYSize, bInterlace, NULL) == GIF_ERROR ) { GDALPrintGifError(hGifFile, "Error writing gif file."); GIFAbstractDataset::myEGifCloseFile(hGifFile); VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* Loop over image, copying image data. */ /* -------------------------------------------------------------------- */ CPLErr eErr; GDALPamDataset *poDS; GByte *pabyScanline; pabyScanline = (GByte *) CPLMalloc( nXSize ); if( !pfnProgress( 0.0, NULL, pProgressData ) ) eErr = CE_Failure; if( !bInterlace ) { for( int iLine = 0; iLine < nYSize; iLine++ ) { eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, pabyScanline, nXSize, 1, GDT_Byte, nBands, nBands * nXSize ); if( eErr != CE_None || EGifPutLine( hGifFile, pabyScanline, nXSize ) == GIF_ERROR ) { CPLError( CE_Failure, CPLE_AppDefined, "Error writing gif file." ); goto error; } if( !pfnProgress( (iLine + 1) * 1.0 / nYSize, NULL, pProgressData ) ) { goto error; } } } else { int i, j; int nLinesRead = 0; int nLinesToRead = 0; for ( i = 0; i < 4; i++) { for (j = InterlacedOffset[i]; j < nYSize; j += InterlacedJumps[i]) { nLinesToRead ++; } } /* Need to perform 4 passes on the images: */ for ( i = 0; i < 4; i++) { for (j = InterlacedOffset[i]; j < nYSize; j += InterlacedJumps[i]) { eErr= poBand->RasterIO( GF_Read, 0, j, nXSize, 1, pabyScanline, nXSize, 1, GDT_Byte, 1, nXSize ); if (eErr != CE_None || EGifPutLine(hGifFile, pabyScanline, nXSize) == GIF_ERROR) { CPLError( CE_Failure, CPLE_AppDefined, "Error writing gif file." ); goto error; } nLinesRead ++; if( !pfnProgress( nLinesRead * 1.0 / nYSize, NULL, pProgressData ) ) { goto error; } } } } CPLFree( pabyScanline ); pabyScanline = NULL; /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ if (GIFAbstractDataset::myEGifCloseFile(hGifFile) == GIF_ERROR) { CPLError( CE_Failure, CPLE_AppDefined, "EGifCloseFile() failed.\n" ); hGifFile = NULL; goto error; } hGifFile = NULL; VSIFCloseL( fp ); fp = NULL; /* -------------------------------------------------------------------- */ /* Do we need a world file? */ /* -------------------------------------------------------------------- */ if( CSLFetchBoolean( papszOptions, "WORLDFILE", FALSE ) ) { double adfGeoTransform[6]; if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None ) GDALWriteWorldFile( pszFilename, "wld", adfGeoTransform ); } /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxilary pam information. */ /* -------------------------------------------------------------------- */ /* If outputing to stdout, we can't reopen it, so we'll return */ /* a fake dataset to make the caller happy */ CPLPushErrorHandler(CPLQuietErrorHandler); poDS = (GDALPamDataset*) GDALOpen(pszFilename, GA_ReadOnly); CPLPopErrorHandler(); if (poDS) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; } else { CPLErrorReset(); GIFDataset* poGIF_DS = new GIFDataset(); poGIF_DS->nRasterXSize = nXSize; poGIF_DS->nRasterYSize = nYSize; for(int i=0;i<nBands;i++) poGIF_DS->SetBand( i+1, new GIFRasterBand( poGIF_DS, i+1, NULL, 0 ) ); return poGIF_DS; } error: if (hGifFile) GIFAbstractDataset::myEGifCloseFile(hGifFile); if (fp) VSIFCloseL( fp ); if (pabyScanline) CPLFree( pabyScanline ); return NULL; }
static GDALDataset * BSBCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "BSB driver only supports one band images.\n" ); return NULL; } if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte && bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "BSB driver doesn't support data type %s. " "Only eight bit bands supported.\n", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the output file. */ /* -------------------------------------------------------------------- */ BSBInfo *psBSB; psBSB = BSBCreate( pszFilename, 0, 200, nXSize, nYSize ); if( psBSB == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Prepare initial color table.colortable. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poBand = poSrcDS->GetRasterBand(1); int iColor; unsigned char abyPCT[771]; int nPCTSize; int anRemap[256]; abyPCT[0] = 0; abyPCT[1] = 0; abyPCT[2] = 0; if( poBand->GetColorTable() == NULL ) { /* map greyscale down to 63 grey levels. */ for( iColor = 0; iColor < 256; iColor++ ) { int nOutValue = (int) (iColor / 4.1) + 1; anRemap[iColor] = nOutValue; abyPCT[nOutValue*3 + 0] = (unsigned char) iColor; abyPCT[nOutValue*3 + 1] = (unsigned char) iColor; abyPCT[nOutValue*3 + 2] = (unsigned char) iColor; } nPCTSize = 64; } else { GDALColorTable *poCT = poBand->GetColorTable(); int nColorTableSize = poCT->GetColorEntryCount(); if (nColorTableSize > 255) nColorTableSize = 255; for( iColor = 0; iColor < nColorTableSize; iColor++ ) { GDALColorEntry sEntry; poCT->GetColorEntryAsRGB( iColor, &sEntry ); anRemap[iColor] = iColor + 1; abyPCT[(iColor+1)*3 + 0] = (unsigned char) sEntry.c1; abyPCT[(iColor+1)*3 + 1] = (unsigned char) sEntry.c2; abyPCT[(iColor+1)*3 + 2] = (unsigned char) sEntry.c3; } nPCTSize = nColorTableSize + 1; // Add entries for pixel values which apparently will not occur. for( iColor = nPCTSize; iColor < 256; iColor++ ) anRemap[iColor] = 1; } /* -------------------------------------------------------------------- */ /* Boil out all duplicate entries. */ /* -------------------------------------------------------------------- */ int i; for( i = 1; i < nPCTSize-1; i++ ) { int j; for( j = i+1; j < nPCTSize; j++ ) { if( abyPCT[i*3+0] == abyPCT[j*3+0] && abyPCT[i*3+1] == abyPCT[j*3+1] && abyPCT[i*3+2] == abyPCT[j*3+2] ) { int k; nPCTSize--; abyPCT[j*3+0] = abyPCT[nPCTSize*3+0]; abyPCT[j*3+1] = abyPCT[nPCTSize*3+1]; abyPCT[j*3+2] = abyPCT[nPCTSize*3+2]; for( k = 0; k < 256; k++ ) { // merge matching entries. if( anRemap[k] == j ) anRemap[k] = i; // shift the last PCT entry into the new hole. if( anRemap[k] == nPCTSize ) anRemap[k] = j; } } } } /* -------------------------------------------------------------------- */ /* Boil out all duplicate entries. */ /* -------------------------------------------------------------------- */ if( nPCTSize > 128 ) { CPLError( CE_Warning, CPLE_AppDefined, "Having to merge color table entries to reduce %d real\n" "color table entries down to 127 values.", nPCTSize ); } while( nPCTSize > 128 ) { int nBestRange = 768; int iBestMatch1=-1, iBestMatch2=-1; // Find the closest pair of color table entries. for( i = 1; i < nPCTSize-1; i++ ) { int j; for( j = i+1; j < nPCTSize; j++ ) { int nRange = ABS(abyPCT[i*3+0] - abyPCT[j*3+0]) + ABS(abyPCT[i*3+1] - abyPCT[j*3+1]) + ABS(abyPCT[i*3+2] - abyPCT[j*3+2]); if( nRange < nBestRange ) { iBestMatch1 = i; iBestMatch2 = j; nBestRange = nRange; } } } // Merge the second entry into the first. nPCTSize--; abyPCT[iBestMatch2*3+0] = abyPCT[nPCTSize*3+0]; abyPCT[iBestMatch2*3+1] = abyPCT[nPCTSize*3+1]; abyPCT[iBestMatch2*3+2] = abyPCT[nPCTSize*3+2]; for( i = 0; i < 256; i++ ) { // merge matching entries. if( anRemap[i] == iBestMatch2 ) anRemap[i] = iBestMatch1; // shift the last PCT entry into the new hole. if( anRemap[i] == nPCTSize ) anRemap[i] = iBestMatch2; } } /* -------------------------------------------------------------------- */ /* Write the PCT. */ /* -------------------------------------------------------------------- */ if( !BSBWritePCT( psBSB, nPCTSize, abyPCT ) ) { BSBClose( psBSB ); return NULL; } /* -------------------------------------------------------------------- */ /* Write the GCPs. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; int nGCPCount = poSrcDS->GetGCPCount(); if (nGCPCount) { const char* pszGCPProjection = poSrcDS->GetGCPProjection(); if ( BSBIsSRSOK(pszGCPProjection) ) { const GDAL_GCP * pasGCPList = poSrcDS->GetGCPs(); for( i = 0; i < nGCPCount; i++ ) { VSIFPrintfL( psBSB->fp, "REF/%d,%f,%f,%f,%f\n", i+1, pasGCPList[i].dfGCPPixel, pasGCPList[i].dfGCPLine, pasGCPList[i].dfGCPY, pasGCPList[i].dfGCPX); } } } else if (poSrcDS->GetGeoTransform(adfGeoTransform) == CE_None) { const char* pszProjection = poSrcDS->GetProjectionRef(); if ( BSBIsSRSOK(pszProjection) ) { VSIFPrintfL( psBSB->fp, "REF/%d,%d,%d,%f,%f\n", 1, 0, 0, adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5], adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]); VSIFPrintfL( psBSB->fp, "REF/%d,%d,%d,%f,%f\n", 2, nXSize, 0, adfGeoTransform[3] + nXSize * adfGeoTransform[4] + 0 * adfGeoTransform[5], adfGeoTransform[0] + nXSize * adfGeoTransform[1] + 0 * adfGeoTransform[2]); VSIFPrintfL( psBSB->fp, "REF/%d,%d,%d,%f,%f\n", 3, nXSize, nYSize, adfGeoTransform[3] + nXSize * adfGeoTransform[4] + nYSize * adfGeoTransform[5], adfGeoTransform[0] + nXSize * adfGeoTransform[1] + nYSize * adfGeoTransform[2]); VSIFPrintfL( psBSB->fp, "REF/%d,%d,%d,%f,%f\n", 4, 0, nYSize, adfGeoTransform[3] + 0 * adfGeoTransform[4] + nYSize * adfGeoTransform[5], adfGeoTransform[0] + 0 * adfGeoTransform[1] + nYSize * adfGeoTransform[2]); } } /* -------------------------------------------------------------------- */ /* Loop over image, copying image data. */ /* -------------------------------------------------------------------- */ GByte *pabyScanline; CPLErr eErr = CE_None; pabyScanline = (GByte *) CPLMalloc( nXSize ); for( int iLine = 0; iLine < nYSize && eErr == CE_None; iLine++ ) { eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, pabyScanline, nXSize, 1, GDT_Byte, nBands, nBands * nXSize ); if( eErr == CE_None ) { for( i = 0; i < nXSize; i++ ) pabyScanline[i] = (GByte) anRemap[pabyScanline[i]]; if( !BSBWriteScanline( psBSB, pabyScanline ) ) eErr = CE_Failure; } } CPLFree( pabyScanline ); /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ BSBClose( psBSB ); if( eErr != CE_None ) { VSIUnlink( pszFilename ); return NULL; } else return (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly ); }
CPLErr GDALMRFRasterBand::IWriteBlock(int xblk, int yblk, void *buffer) { GInt32 cstride = img.pagesize.c; ILSize req(xblk, yblk, 0, m_band/cstride, m_l); GUIntBig infooffset = IdxOffset(req, img); CPLDebug("MRF_IB", "IWriteBlock %d,%d,0,%d, level %d, stride %d\n", xblk, yblk, m_band, m_l, cstride); if (1 == cstride) { // Separate bands, we can write it as is // Empty page skip int success; double val = GetNoDataValue(&success); if (!success) val = 0.0; if (isAllVal(eDataType, buffer, img.pageSizeBytes, val)) return poDS->WriteTile(NULL, infooffset, 0); // Use the pbuffer to hold the compressed page before writing it poDS->tile = ILSize(); // Mark it corrupt buf_mgr src; src.buffer = (char *)buffer; src.size = static_cast<size_t>(img.pageSizeBytes); buf_mgr dst = {(char *)poDS->GetPBuffer(), poDS->GetPBufferSize()}; // Swab the source before encoding if we need to if (is_Endianess_Dependent(img.dt, img.comp) && (img.nbo != NET_ORDER)) swab_buff(src, img); // Compress functions need to return the compressed size in // the bytes in buffer field Compress(dst, src); void *usebuff = dst.buffer; if (deflatep) { usebuff = DeflateBlock(dst, poDS->pbsize - dst.size, deflate_flags); if (!usebuff) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: Deflate error"); return CE_Failure; } } return poDS->WriteTile(usebuff, infooffset , dst.size); } // Multiple bands per page, use a temporary to assemble the page // Temporary is large because we use it to hold both the uncompressed and the compressed poDS->tile=req; poDS->bdirty=0; // Keep track of what bands are empty GUIntBig empties=0; void *tbuffer = VSIMalloc(img.pageSizeBytes + poDS->pbsize); if (!tbuffer) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: Can't allocate write buffer"); return CE_Failure; } // Get the other bands from the block cache for (int iBand=0; iBand < poDS->nBands; iBand++ ) { const char *pabyThisImage=NULL; GDALRasterBlock *poBlock=NULL; if (iBand == m_band) { pabyThisImage = (char *) buffer; poDS->bdirty |= bandbit(); } else { GDALRasterBand *band = poDS->GetRasterBand(iBand +1); // Pick the right overview if (m_l) band = band->GetOverview(m_l -1); poBlock = ((GDALMRFRasterBand *)band) ->TryGetLockedBlockRef(xblk, yblk); if (NULL==poBlock) continue; // This is where the image data is for this band pabyThisImage = (char*) poBlock->GetDataRef(); poDS->bdirty |= bandbit(iBand); } // Keep track of empty bands, but encode them anyhow, in case some are not empty int success; double val = GetNoDataValue(&success); if (!success) val = 0.0; if (isAllVal(eDataType, (char *)pabyThisImage, blockSizeBytes(), val)) empties |= bandbit(iBand); // Copy the data into the dataset buffer here // Just the right mix of templates and macros make this real tidy #define CpySO(T) cpy_stride_out<T> (((T *)tbuffer)+iBand, pabyThisImage,\ blockSizeBytes()/sizeof(T), cstride) // Build the page in tbuffer switch (GDALGetDataTypeSize(eDataType)/8) { case 1: CpySO(GByte); break; case 2: CpySO(GInt16); break; case 4: CpySO(GInt32); break; case 8: CpySO(GIntBig); break; default: { CPLError(CE_Failure,CPLE_AppDefined, "MRF: Write datatype of %d bytes " "not implemented", GDALGetDataTypeSize(eDataType)/8); if (poBlock != NULL) { poBlock->MarkClean(); poBlock->DropLock(); } CPLFree(tbuffer); return CE_Failure; } } if (poBlock != NULL) { poBlock->MarkClean(); poBlock->DropLock(); } } // Should keep track of the individual band buffers and only mix them if this is not // an empty page ( move the Copy with Stride Out from above below this test // This way works fine, but it does work extra for empty pages if (GIntBig(empties) == AllBandMask()) { CPLFree(tbuffer); return poDS->WriteTile(NULL, infooffset, 0); } if (poDS->bdirty != AllBandMask()) CPLError(CE_Warning, CPLE_AppDefined, "MRF: IWrite, band dirty mask is " CPL_FRMT_GIB " instead of " CPL_FRMT_GIB, poDS->bdirty, AllBandMask()); buf_mgr src; src.buffer = (char *)tbuffer; src.size = static_cast<size_t>(img.pageSizeBytes); // Use the space after pagesizebytes for compressed output, it is of pbsize char *outbuff = (char *)tbuffer + img.pageSizeBytes; buf_mgr dst = {outbuff, poDS->pbsize}; CPLErr ret; ret = Compress(dst, src); if (ret != CE_None) { // Compress failed, write it as an empty tile CPLFree(tbuffer); poDS->WriteTile(NULL, infooffset, 0); return CE_None; // Should report the error, but it triggers partial band attempts } // Where the output is, in case we deflate void *usebuff = outbuff; if (deflatep) { // Move the packed part at the start of tbuffer, to make more space available memcpy(tbuffer, outbuff, dst.size); dst.buffer = (char *)tbuffer; usebuff = DeflateBlock(dst, img.pageSizeBytes + poDS->pbsize - dst.size, deflate_flags); if (!usebuff) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: Deflate error"); CPLFree(tbuffer); poDS->WriteTile(NULL, infooffset, 0); poDS->bdirty = 0; return CE_Failure; } } ret = poDS->WriteTile(usebuff, infooffset, dst.size); CPLFree(tbuffer); poDS->bdirty = 0; return ret; }
GDALDataset *IntergraphDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { (void) bStrict; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "Intergraph driver does not support source dataset with zero band.\n"); return NULL; } if( !pfnProgress( 0.0, NULL, pProgressData ) ) { return NULL; } // -------------------------------------------------------------------- // Query GDAL Data Type // -------------------------------------------------------------------- GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); // -------------------------------------------------------------------- // Copy metadata // -------------------------------------------------------------------- char **papszCreateOptions = CSLDuplicate( papszOptions ); const char *pszValue; pszValue = CSLFetchNameValue(papszCreateOptions, "RESOLUTION"); if( pszValue == NULL ) { const char *value = poSrcDS->GetMetadataItem("RESOLUTION"); if (value) { papszCreateOptions = CSLSetNameValue( papszCreateOptions, "RESOLUTION", value ); } } // -------------------------------------------------------------------- // Create IntergraphDataset // -------------------------------------------------------------------- IntergraphDataset *poDstDS; poDstDS = (IntergraphDataset*) IntergraphDataset::Create( pszFilename, poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize(), poSrcDS->GetRasterCount(), eType, papszCreateOptions ); CSLDestroy( papszCreateOptions ); if( poDstDS == NULL ) { return NULL; } // -------------------------------------------------------------------- // Copy Transformation Matrix to the dataset // -------------------------------------------------------------------- double adfGeoTransform[6]; poDstDS->SetProjection( poSrcDS->GetProjectionRef() ); poSrcDS->GetGeoTransform( adfGeoTransform ); poDstDS->SetGeoTransform( adfGeoTransform ); // -------------------------------------------------------------------- // Copy information to the raster band // -------------------------------------------------------------------- GDALRasterBand *poSrcBand; GDALRasterBand *poDstBand; double dfMin; double dfMax; double dfMean; double dfStdDev = -1; for( int i = 1; i <= poDstDS->nBands; i++) { delete poDstDS->GetRasterBand(i); } poDstDS->nBands = 0; if( poDstDS->hHeaderOne.DataTypeCode == Uncompressed24bit ) { poDstDS->SetBand( 1, new IntergraphRGBBand( poDstDS, 1, 0, 3 ) ); poDstDS->SetBand( 2, new IntergraphRGBBand( poDstDS, 2, 0, 2 ) ); poDstDS->SetBand( 3, new IntergraphRGBBand( poDstDS, 3, 0, 1 ) ); poDstDS->nBands = 3; } else { for( int i = 1; i <= poSrcDS->GetRasterCount(); i++ ) { poSrcBand = poSrcDS->GetRasterBand(i); eType = poSrcDS->GetRasterBand(i)->GetRasterDataType(); poDstBand = new IntergraphRasterBand( poDstDS, i, 0, eType ); poDstDS->SetBand( i, poDstBand ); poDstBand->SetCategoryNames( poSrcBand->GetCategoryNames() ); poDstBand->SetColorTable( poSrcBand->GetColorTable() ); poSrcBand->GetStatistics( false, true, &dfMin, &dfMax, &dfMean, &dfStdDev ); poDstBand->SetStatistics( dfMin, dfMax, dfMean, dfStdDev ); } } // -------------------------------------------------------------------- // Copy image data // -------------------------------------------------------------------- int nXSize = poDstDS->GetRasterXSize(); int nYSize = poDstDS->GetRasterYSize(); int nBlockXSize; int nBlockYSize; CPLErr eErr = CE_None; for( int iBand = 1; iBand <= poSrcDS->GetRasterCount(); iBand++ ) { GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand ); GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand ); // ------------------------------------------------------------ // Copy Untiled / Uncompressed // ------------------------------------------------------------ int iYOffset, iXOffset; void *pData; poSrcBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); nBlockXSize = nXSize; nBlockYSize = 1; pData = CPLMalloc( nBlockXSize * nBlockYSize * GDALGetDataTypeSize( eType ) / 8 ); for( iYOffset = 0; iYOffset < nYSize; iYOffset += nBlockYSize ) { for( iXOffset = 0; iXOffset < nXSize; iXOffset += nBlockXSize ) { eErr = poSrcBand->RasterIO( GF_Read, iXOffset, iYOffset, nBlockXSize, nBlockYSize, pData, nBlockXSize, nBlockYSize, eType, 0, 0, NULL ); if( eErr != CE_None ) { return NULL; } eErr = poDstBand->RasterIO( GF_Write, iXOffset, iYOffset, nBlockXSize, nBlockYSize, pData, nBlockXSize, nBlockYSize, eType, 0, 0, NULL ); if( eErr != CE_None ) { return NULL; } } if( ( eErr == CE_None ) && ( ! pfnProgress( ( iYOffset + 1 ) / ( double ) nYSize, NULL, pProgressData ) ) ) { eErr = CE_Failure; CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); } } CPLFree( pData ); } // -------------------------------------------------------------------- // Finalize // -------------------------------------------------------------------- poDstDS->FlushCache(); return poDstDS; }
static std::vector<GDALFeaturePoint> * GatherFeaturePoints( GDALDataset* poDataset, int* panBands, int nOctaveStart, int nOctaveEnd, double dfThreshold ) { if( poDataset == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "GDALDataset isn't specified"); return nullptr; } if( panBands == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Raster bands are not specified"); return nullptr; } if( nOctaveStart <= 0 || nOctaveEnd < 0 || nOctaveStart > nOctaveEnd ) { CPLError(CE_Failure, CPLE_AppDefined, "Octave numbers are invalid"); return nullptr; } if( dfThreshold < 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Threshold have to be greater than zero"); return nullptr; } GDALRasterBand *poRstRedBand = poDataset->GetRasterBand(panBands[0]); GDALRasterBand *poRstGreenBand = poDataset->GetRasterBand(panBands[1]); GDALRasterBand *poRstBlueBand = poDataset->GetRasterBand(panBands[2]); const int nWidth = poRstRedBand->GetXSize(); const int nHeight = poRstRedBand->GetYSize(); if( nWidth == 0 || nHeight == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Must have non-zero width and height."); return nullptr; } // Allocate memory for grayscale image. double **padfImg = new double*[nHeight]; for( int i = 0; ; ) { padfImg[i] = new double[nWidth]; for( int j = 0; j < nWidth; ++j ) padfImg[i][j] = 0.0; ++i; if( i == nHeight ) break; } // Create grayscale image. GDALSimpleSURF::ConvertRGBToLuminosity( poRstRedBand, poRstGreenBand, poRstBlueBand, nWidth, nHeight, padfImg, nHeight, nWidth); // Prepare integral image. GDALIntegralImage *poImg = new GDALIntegralImage(); poImg->Initialize(const_cast<const double**>(padfImg), nHeight, nWidth); // Get feature points. GDALSimpleSURF *poSurf = new GDALSimpleSURF(nOctaveStart, nOctaveEnd); std::vector<GDALFeaturePoint> *poCollection = poSurf->ExtractFeaturePoints(poImg, dfThreshold); // Clean up. delete poImg; delete poSurf; for( int i = 0; i < nHeight; ++i ) delete[] padfImg[i]; delete[] padfImg; return poCollection; }
/** * Sets the surface grids based on a ncepNam (surface only!) forecast. * @param input The WindNinjaInputs for misc. info. * @param airGrid The air temperature grid to be filled. * @param cloudGrid The cloud cover grid to be filled. * @param uGrid The u velocity grid to be filled. * @param vGrid The v velocity grid to be filled. * @param wGrid The w velocity grid to be filled (filled with zeros here?). */ void genericSurfInitialization::setSurfaceGrids( WindNinjaInputs &input, AsciiGrid<double> &airGrid, AsciiGrid<double> &cloudGrid, AsciiGrid<double> &uGrid, AsciiGrid<double> &vGrid, AsciiGrid<double> &wGrid ) { int bandNum = -1; //get time list std::vector<boost::local_time::local_date_time> timeList( getTimeList(input.ninjaTimeZone) ); //Search time list for our time to identify our band number for cloud/speed/dir for(unsigned int i = 0; i < timeList.size(); i++) { if(input.ninjaTime == timeList[i]) { bandNum = i + 1; break; } } if(bandNum < 0) throw std::runtime_error("Could not match ninjaTime with a band number in the forecast file."); //get some info from the nam file in input //Acquire a lock to protect the non-thread safe netCDF library #ifdef _OPENMP omp_guard netCDF_guard(netCDF_lock); #endif GDALDataset* poDS; //attempt to grab the projection from the dem? //check for member prjString first std::string dstWkt; dstWkt = input.dem.prjString; if ( dstWkt.empty() ) { //try to open original poDS = (GDALDataset*)GDALOpen( input.dem.fileName.c_str(), GA_ReadOnly ); if( poDS == NULL ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad projection reference" ); //throw(); } dstWkt = poDS->GetProjectionRef(); if( dstWkt.empty() ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad projection reference" ); //throw() } GDALClose((GDALDatasetH) poDS ); } poDS = (GDALDataset*)GDALOpen( input.forecastFilename.c_str(), GA_ReadOnly ); if( poDS == NULL ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad forecast file" ); } else GDALClose((GDALDatasetH) poDS ); // open ds one by one and warp, then write to grid GDALDataset *srcDS, *wrpDS; std::string temp; std::string srcWkt; std::vector<std::string> varList = getVariableList(); /* * Set the initial values in the warped dataset to no data */ GDALWarpOptions* psWarpOptions; for( unsigned int i = 0;i < varList.size();i++ ) { temp = "NETCDF:" + input.forecastFilename + ":" + varList[i]; srcDS = (GDALDataset*)GDALOpenShared( temp.c_str(), GA_ReadOnly ); if( srcDS == NULL ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad forecast file" ); } srcWkt = srcDS->GetProjectionRef(); if( srcWkt.empty() ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad forecast file" ); //throw } /* * Grab the first band to get the nodata value for the variable, * assume all bands have the same ndv */ GDALRasterBand *poBand = srcDS->GetRasterBand( 1 ); int pbSuccess; double dfNoData = poBand->GetNoDataValue( &pbSuccess ); psWarpOptions = GDALCreateWarpOptions(); int nBandCount = srcDS->GetRasterCount(); psWarpOptions->nBandCount = nBandCount; psWarpOptions->padfDstNoDataReal = (double*) CPLMalloc( sizeof( double ) * nBandCount ); psWarpOptions->padfDstNoDataImag = (double*) CPLMalloc( sizeof( double ) * nBandCount ); for( int b = 0;b < srcDS->GetRasterCount();b++ ) { psWarpOptions->padfDstNoDataReal[b] = dfNoData; psWarpOptions->padfDstNoDataImag[b] = dfNoData; } if( pbSuccess == false ) dfNoData = -9999.0; psWarpOptions->papszWarpOptions = CSLSetNameValue( psWarpOptions->papszWarpOptions, "INIT_DEST", "NO_DATA" ); wrpDS = (GDALDataset*) GDALAutoCreateWarpedVRT( srcDS, srcWkt.c_str(), dstWkt.c_str(), GRA_NearestNeighbour, 1.0, psWarpOptions ); if( varList[i] == "Temperature_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, airGrid ); if( CPLIsNan( dfNoData ) ) { airGrid.set_noDataValue(-9999.0); airGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "V-component_of_wind_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, vGrid ); if( CPLIsNan( dfNoData ) ) { vGrid.set_noDataValue(-9999.0); vGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "U-component_of_wind_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, uGrid ); if( CPLIsNan( dfNoData ) ) { uGrid.set_noDataValue(-9999.0); uGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "Total_cloud_cover" ) { GDAL2AsciiGrid( wrpDS, bandNum, cloudGrid ); if( CPLIsNan( dfNoData ) ) { cloudGrid.set_noDataValue(-9999.0); cloudGrid.replaceNan( -9999.0 ); } } GDALDestroyWarpOptions( psWarpOptions ); GDALClose((GDALDatasetH) srcDS ); GDALClose((GDALDatasetH) wrpDS ); } cloudGrid /= 100.0; wGrid.set_headerData( uGrid ); wGrid = 0.0; }
static GDALDataset * DTEDCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { (void) pProgressData; (void) pfnProgress; (void) papszOptions; (void) bStrict; /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "DTED driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "DTED driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Work out the level. */ /* -------------------------------------------------------------------- */ int nLevel; if( poSrcDS->GetRasterYSize() == 121 ) nLevel = 0; else if( poSrcDS->GetRasterYSize() == 1201 ) nLevel = 1; else if( poSrcDS->GetRasterYSize() == 3601 ) nLevel = 2; else { CPLError( CE_Warning, CPLE_AppDefined, "The source does not appear to be a properly formatted cell." ); nLevel = 1; } /* -------------------------------------------------------------------- */ /* Checks the input SRS */ /* -------------------------------------------------------------------- */ OGRSpatialReference ogrsr_input; OGRSpatialReference ogrsr_wgs84; char* c = (char*)poSrcDS->GetProjectionRef(); ogrsr_input.importFromWkt(&c); ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" ); if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE) { CPLError( CE_Warning, CPLE_AppDefined, "The source projection coordinate system is %s. Only WGS 84 is supported.\n" "The DTED driver will generate a file as if the source was WGS 84 projection coordinate system.", poSrcDS->GetProjectionRef() ); } /* -------------------------------------------------------------------- */ /* Work out the LL origin. */ /* -------------------------------------------------------------------- */ int nLLOriginLat, nLLOriginLong; double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); nLLOriginLat = (int) floor(adfGeoTransform[3] + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5); nLLOriginLong = (int) floor(adfGeoTransform[0] + 0.5); if (fabs(nLLOriginLat - (adfGeoTransform[3] + (poSrcDS->GetRasterYSize() - 0.5) * adfGeoTransform[5])) > 1e-10 || fabs(nLLOriginLong - (adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10) { CPLError( CE_Warning, CPLE_AppDefined, "The corner coordinates of the source are not properly " "aligned on plain latitude/longitude boundaries."); } /* -------------------------------------------------------------------- */ /* Check horizontal source size. */ /* -------------------------------------------------------------------- */ int expectedXSize; if( ABS(nLLOriginLat) >= 80 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 6 + 1; else if( ABS(nLLOriginLat) >= 75 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 4 + 1; else if( ABS(nLLOriginLat) >= 70 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 3 + 1; else if( ABS(nLLOriginLat) >= 50 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 2 + 1; else expectedXSize = poSrcDS->GetRasterYSize(); if (poSrcDS->GetRasterXSize() != expectedXSize) { CPLError( CE_Warning, CPLE_AppDefined, "The horizontal source size is not conformant with the one " "expected by DTED Level %d at this latitude (%d pixels found instead of %d).", nLevel, poSrcDS->GetRasterXSize(), expectedXSize); } /* -------------------------------------------------------------------- */ /* Create the output dted file. */ /* -------------------------------------------------------------------- */ const char *pszError; pszError = DTEDCreate( pszFilename, nLevel, nLLOriginLat, nLLOriginLong ); if( pszError != NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s", pszError ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the DTED file so we can output the data to it. */ /* -------------------------------------------------------------------- */ DTEDInfo *psDTED; psDTED = DTEDOpen( pszFilename, "rb+", FALSE ); if( psDTED == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Read all the data in a single buffer. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); GInt16 *panData; panData = (GInt16 *) VSIMalloc(sizeof(GInt16) * psDTED->nXSize * psDTED->nYSize); if (panData == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory"); DTEDClose(psDTED); return NULL; } for( int iY = 0; iY < psDTED->nYSize; iY++ ) { poSrcBand->RasterIO( GF_Read, 0, iY, psDTED->nXSize, 1, (void *) (panData + iY * psDTED->nXSize), psDTED->nXSize, 1, GDT_Int16, 0, 0 ); if( pfnProgress && !pfnProgress(0.5 * (iY+1) / (double) psDTED->nYSize, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); DTEDClose( psDTED ); CPLFree( panData ); return NULL; } } int bSrcBandHasNoData; double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData); /* -------------------------------------------------------------------- */ /* Write all the profiles. */ /* -------------------------------------------------------------------- */ GInt16 anProfData[3601]; int dfNodataCount=0; GByte iPartialCell; for( int iProfile = 0; iProfile < psDTED->nXSize; iProfile++ ) { for( int iY = 0; iY < psDTED->nYSize; iY++ ) { anProfData[iY] = panData[iProfile + iY * psDTED->nXSize]; if ( bSrcBandHasNoData && anProfData[iY] == srcBandNoData) { anProfData[iY] = DTED_NODATA_VALUE; dfNodataCount++; } else if ( anProfData[iY] == DTED_NODATA_VALUE ) dfNodataCount++; } DTEDWriteProfile( psDTED, iProfile, anProfData ); if( pfnProgress && !pfnProgress( 0.5 + 0.5 * (iProfile+1) / (double) psDTED->nXSize, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); DTEDClose( psDTED ); CPLFree( panData ); return NULL; } } CPLFree( panData ); /* -------------------------------------------------------------------- */ /* Partial cell indicator: 0 for complete coverage; 1-99 for incomplete */ /* -------------------------------------------------------------------- */ char szPartialCell[3]; if ( dfNodataCount == 0 ) iPartialCell = 0; else { iPartialCell = (GByte)int(floor(100.0 - (dfNodataCount*100.0/(psDTED->nXSize * psDTED->nYSize)))); if (iPartialCell < 1) iPartialCell=1; } sprintf(szPartialCell,"%02d",iPartialCell); DTEDSetMetadata(psDTED, DTEDMD_PARTIALCELL_DSI, szPartialCell); /* -------------------------------------------------------------------- */ /* Try to copy any matching available metadata. */ /* -------------------------------------------------------------------- */ if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_UHL, poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_ACC, poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) ); if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_UHL, poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_DSI, poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) ); if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_UHL, poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_DSI, poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) ); if( poSrcDS->GetMetadataItem( "DTED_DataEdition" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_DATA_EDITION, poSrcDS->GetMetadataItem( "DTED_DataEdition" ) ); if( poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_VERSION, poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) ); if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MAINT_DATE, poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_DATE, poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MAINT_DESCRIPTION, poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) ); if( poSrcDS->GetMetadataItem( "DTED_Producer" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_PRODUCER, poSrcDS->GetMetadataItem( "DTED_Producer" ) ); if( poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTDATUM, poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) ); if( poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_HORIZDATUM, poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) ); if( poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_DIGITIZING_SYS, poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) ); if( poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_COMPILATION_DATE, poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_HORIZACCURACY, poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) ); if( poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_REL_HORIZACCURACY, poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) ); if( poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_REL_VERTACCURACY, poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) ); /* -------------------------------------------------------------------- */ /* Try to open the resulting DTED file. */ /* -------------------------------------------------------------------- */ DTEDClose( psDTED ); /* -------------------------------------------------------------------- */ /* Reopen and copy missing information into a PAM file. */ /* -------------------------------------------------------------------- */ GDALPamDataset *poDS = (GDALPamDataset *) GDALOpen( pszFilename, GA_ReadOnly ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; }
/** * Checks the downloaded data to see if it is all valid. */ void genericSurfInitialization::checkForValidData() { //just make up a "dummy" timezone for use here boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("MST-07")); //get time list std::vector<boost::local_time::local_date_time> timeList( getTimeList(zone) ); boost::posix_time::ptime pt_low(boost::gregorian::date(1900,boost::gregorian::Jan,1), boost::posix_time::hours(12)); boost::posix_time::ptime pt_high(boost::gregorian::date(2100,boost::gregorian::Jan,1), boost::posix_time::hours(12)); boost::local_time::local_date_time low_time(pt_low, zone); boost::local_time::local_date_time high_time(pt_high, zone); //check times for(unsigned int i = 0; i < timeList.size(); i++) { if(timeList[i].is_special()) //if time is any special value (not_a_date_time, infinity, etc.) throw badForecastFile("Bad time in forecast file."); if(timeList[i] < low_time || timeList[i] > high_time) throw badForecastFile("Bad time in forecast file."); } // open ds variable by variable GDALDataset *srcDS; std::string temp; std::string srcWkt; int nBands = 0; bool noDataValueExists; bool noDataIsNan; std::vector<std::string> varList = getVariableList(); //Acquire a lock to protect the non-thread safe netCDF library #ifdef _OPENMP omp_guard netCDF_guard(netCDF_lock); #endif for( unsigned int i = 0;i < varList.size();i++ ) { temp = "NETCDF:" + wxModelFileName + ":" + varList[i]; srcDS = (GDALDataset*)GDALOpen( temp.c_str(), GA_ReadOnly ); if( srcDS == NULL ) throw badForecastFile("Cannot open forecast file."); srcWkt = srcDS->GetProjectionRef(); if( srcWkt.empty() ) throw badForecastFile("Forecast file doesn't have projection information."); //Get total bands (time steps) nBands = srcDS->GetRasterCount(); int nXSize, nYSize; GDALRasterBand *poBand; int pbSuccess; double dfNoData; double *padfScanline; nXSize = srcDS->GetRasterXSize(); nYSize = srcDS->GetRasterYSize(); //loop over all bands for this variable (bands are time steps) for(int j = 1; j <= nBands; j++) { poBand = srcDS->GetRasterBand( j ); pbSuccess = 0; dfNoData = poBand->GetNoDataValue( &pbSuccess ); if( pbSuccess == false ) noDataValueExists = false; else { noDataValueExists = true; noDataIsNan = CPLIsNan(dfNoData); } //set the data padfScanline = new double[nXSize*nYSize]; poBand->RasterIO(GF_Read, 0, 0, nXSize, nYSize, padfScanline, nXSize, nYSize, GDT_Float64, 0, 0); for(int k = 0;k < nXSize*nYSize; k++) { //Check if value is no data (if no data value was defined in file) if(noDataValueExists) { if(noDataIsNan) { if(CPLIsNan(padfScanline[k])) throw badForecastFile("Forecast file contains no_data values."); }else { if(padfScanline[k] == dfNoData) throw badForecastFile("Forecast file contains no_data values."); } } if( varList[i] == "Temperature_height_above_ground" ) //units are Kelvin { if(padfScanline[k] < 180.0 || padfScanline[k] > 340.0) //these are near the most extreme temperatures ever recored on earth throw badForecastFile("Temperature is out of range in forecast file."); } else if( varList[i] == "V-component_of_wind_height_above_ground" ) //units are m/s { if(std::abs(padfScanline[k]) > 220.0) throw badForecastFile("V-velocity is out of range in forecast file."); } else if( varList[i] == "U-component_of_wind_height_above_ground" ) //units are m/s { if(std::abs(padfScanline[k]) > 220.0) throw badForecastFile("U-velocity is out of range in forecast file."); } else if( varList[i] == "Total_cloud_cover" ) //units are percent { if(padfScanline[k] < 0.0 || padfScanline[k] > 100.0) throw badForecastFile("Total cloud cover is out of range in forecast file."); } } delete [] padfScanline; } GDALClose((GDALDatasetH) srcDS ); } }
CPLErr VRTSourcedRasterBand::GetHistogram( double dfMin, double dfMax, int nBuckets, int *panHistogram, int bIncludeOutOfRange, int bApproxOK, GDALProgressFunc pfnProgress, void *pProgressData ) { if( nSources != 1 ) return GDALRasterBand::GetHistogram( dfMin, dfMax, nBuckets, panHistogram, bIncludeOutOfRange, bApproxOK, pfnProgress, pProgressData ); if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* If we have overviews, use them for the histogram. */ /* -------------------------------------------------------------------- */ if( bApproxOK && GetOverviewCount() > 0 && !HasArbitraryOverviews() ) { // FIXME: should we use the most reduced overview here or use some // minimum number of samples like GDALRasterBand::ComputeStatistics() // does? GDALRasterBand *poBestOverview = GetRasterSampleOverview( 0 ); if( poBestOverview != this ) { return poBestOverview->GetHistogram( dfMin, dfMax, nBuckets, panHistogram, bIncludeOutOfRange, bApproxOK, pfnProgress, pProgressData ); } } /* -------------------------------------------------------------------- */ /* Try with source bands. */ /* -------------------------------------------------------------------- */ if ( bAntiRecursionFlag ) { CPLError( CE_Failure, CPLE_AppDefined, "VRTSourcedRasterBand::GetHistogram() called recursively on the same band. " "It looks like the VRT is referencing itself." ); return CE_Failure; } bAntiRecursionFlag = TRUE; CPLErr eErr = papoSources[0]->GetHistogram(GetXSize(), GetYSize(), dfMin, dfMax, nBuckets, panHistogram, bIncludeOutOfRange, bApproxOK, pfnProgress, pProgressData); if (eErr != CE_None) { eErr = GDALRasterBand::GetHistogram( dfMin, dfMax, nBuckets, panHistogram, bIncludeOutOfRange, bApproxOK, pfnProgress, pProgressData ); bAntiRecursionFlag = FALSE; return eErr; } bAntiRecursionFlag = FALSE; return CE_None; }
CPLErr VRTSourcedRasterBand::ComputeStatistics( int bApproxOK, double *pdfMin, double *pdfMax, double *pdfMean, double *pdfStdDev, GDALProgressFunc pfnProgress, void *pProgressData ) { if( nSources != 1 ) return GDALRasterBand::ComputeStatistics( bApproxOK, pdfMin, pdfMax, pdfMean, pdfStdDev, pfnProgress, pProgressData ); if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* If we have overview bands, use them for statistics. */ /* -------------------------------------------------------------------- */ if( bApproxOK && GetOverviewCount() > 0 && !HasArbitraryOverviews() ) { GDALRasterBand *poBand; poBand = GetRasterSampleOverview( GDALSTAT_APPROX_NUMSAMPLES ); if( poBand != this ) return poBand->ComputeStatistics( FALSE, pdfMin, pdfMax, pdfMean, pdfStdDev, pfnProgress, pProgressData ); } /* -------------------------------------------------------------------- */ /* Try with source bands. */ /* -------------------------------------------------------------------- */ if ( bAntiRecursionFlag ) { CPLError( CE_Failure, CPLE_AppDefined, "VRTSourcedRasterBand::ComputeStatistics() called recursively on the same band. " "It looks like the VRT is referencing itself." ); return CE_Failure; } bAntiRecursionFlag = TRUE; double dfMin = 0.0, dfMax = 0.0, dfMean = 0.0, dfStdDev = 0.0; CPLErr eErr = papoSources[0]->ComputeStatistics(GetXSize(), GetYSize(), bApproxOK, &dfMin, &dfMax, &dfMean, &dfStdDev, pfnProgress, pProgressData); if (eErr != CE_None) { eErr = GDALRasterBand::ComputeStatistics(bApproxOK, pdfMin, pdfMax, pdfMean, pdfStdDev, pfnProgress, pProgressData); bAntiRecursionFlag = FALSE; return eErr; } bAntiRecursionFlag = FALSE; SetStatistics( dfMin, dfMax, dfMean, dfStdDev ); /* -------------------------------------------------------------------- */ /* Record results. */ /* -------------------------------------------------------------------- */ if( pdfMin != NULL ) *pdfMin = dfMin; if( pdfMax != NULL ) *pdfMax = dfMax; if( pdfMean != NULL ) *pdfMean = dfMean; if( pdfStdDev != NULL ) *pdfStdDev = dfStdDev; return CE_None; }
void output_geotiff ( rgb_image & out ) { int i, r, c; int val; char s[2]; OGRSpatialReference ref; GDALDataset *df; char *wkt = NULL; GDALRasterBand *bd; double trans[6]; GDALDriver *gt; char **options = NULL; int ov[] = { 2, 4, 8, 16, 32 }; int nov; int n; int bands[] = { 1, 2, 3 }; char file[1000]; int block, ir, rows; options = CSLSetNameValue ( options, "TILED", "NO" ); options = CSLSetNameValue ( options, "BLOCKXSIZE", "256" ); options = CSLSetNameValue ( options, "BLOCKYSIZE", "256" ); options = CSLSetNameValue ( options, "COMPRESS", "LZW" ); gt = GetGDALDriverManager()->GetDriverByName("GTiff"); if ( !gt ) { fprintf(stderr,"Could not get GTiff driver\n"); exit(1); } strcpy ( file, p.value("output_file").c_str() ); df = gt->Create( file, out.cols, out.rows, 3, GDT_Byte, options ); if( df == NULL ) { fprintf(stderr,"Could not create %s\n", file ); exit(1); } trans[0] = p.dvalue("easting_left"); trans[1] = p.dvalue("output_cell_size"); trans[2] = 0.0; trans[3] = p.dvalue("northing_top"); trans[4] = 0.0; trans[5] = -p.dvalue("output_cell_size"); df->SetGeoTransform ( trans ); ref.SetUTM ( p.ivalue("utm_zone") ); ref.SetWellKnownGeogCS ( "NAD27" ); ref.exportToWkt ( &wkt ); df->SetProjection(wkt); CPLFree ( wkt ); for ( ir = 0; ir < out.rows; ir += bs ) { rows = out.rows - ir; if ( rows > bs ) rows = bs; //printf("Writer waiting for %d\n",ir ); pe.wait_for("data",ir); for ( i = 0; i < 3; i++ ) { bd = df->GetRasterBand(i+1); bd->RasterIO( GF_Write, 0, ir, out.cols, rows, out.img[i].data+ir*out.cols, out.cols, rows, GDT_Byte, 0, 0 ); } } delete df; df = (GDALDataset *)GDALOpen ( file, GA_Update ); if( df == NULL ) { fprintf(stderr,"Could not open for update %s\n", file ); exit(1); } nov = p.ivalue("overviews"); if ( nov > 5 ) nov = 5; if ( nov > 0 ) { df->BuildOverviews("NEAREST", nov, ov, 3, bands, NULL, NULL ); } }
GDALDataset *SAGADataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "SAGA driver does not support source dataset with zero band.\n"); return NULL; } else if (nBands > 1) { if( bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "Unable to create copy, SAGA Binary Grid " "format only supports one raster band.\n" ); return NULL; } else CPLError( CE_Warning, CPLE_NotSupported, "SAGA Binary Grid format only supports one " "raster band, first band will be copied.\n" ); } GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); char** papszCreateOptions = NULL; papszCreateOptions = CSLSetNameValue(papszCreateOptions, "FILL_NODATA", "NO"); int bHasNoDataValue = FALSE; double dfNoDataValue = poSrcBand->GetNoDataValue(&bHasNoDataValue); if (bHasNoDataValue) papszCreateOptions = CSLSetNameValue(papszCreateOptions, "NODATA_VALUE", CPLSPrintf("%.16g", dfNoDataValue)); GDALDataset* poDstDS = Create(pszFilename, poSrcBand->GetXSize(), poSrcBand->GetYSize(), 1, poSrcBand->GetRasterDataType(), papszCreateOptions); CSLDestroy(papszCreateOptions); if (poDstDS == NULL) return NULL; /* -------------------------------------------------------------------- */ /* Copy band data. */ /* -------------------------------------------------------------------- */ CPLErr eErr; eErr = GDALDatasetCopyWholeRaster( (GDALDatasetH) poSrcDS, (GDALDatasetH) poDstDS, NULL, pfnProgress, pProgressData ); if (eErr == CE_Failure) { delete poDstDS; return NULL; } double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); poDstDS->SetGeoTransform( adfGeoTransform ); poDstDS->SetProjection( poSrcDS->GetProjectionRef() ); return poDstDS; }
CPLErr SDEDataset::ComputeRasterInfo() { long nSDEErr; SE_RASTERINFO raster; nSDEErr = SE_rasterinfo_create(&raster); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_rasterinfo_create" ); return CE_Fatal; } LONG nRasterColumnId = 0; nSDEErr = SE_rascolinfo_get_id( hRasterColumn, &nRasterColumnId); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_rascolinfo_get_id" ); return CE_Fatal; } nSDEErr = SE_raster_get_info_by_id( hConnection, nRasterColumnId, 1, raster); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_rascolinfo_get_id" ); return CE_Fatal; } LONG nBandsRet; nSDEErr = SE_raster_get_bands( hConnection, raster, &paohSDERasterBands, &nBandsRet); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_raster_get_bands" ); return CE_Fatal; } nBands = nBandsRet; SE_RASBANDINFO band; // grab our other stuff from the first band and hope for the best band = paohSDERasterBands[0]; LONG nXSRet, nYSRet; nSDEErr = SE_rasbandinfo_get_band_size( band, &nXSRet, &nYSRet ); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_rasbandinfo_get_band_size" ); return CE_Fatal; } nRasterXSize = nXSRet; nRasterYSize = nYSRet; SE_ENVELOPE extent; nSDEErr = SE_rasbandinfo_get_extent(band, &extent); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_rasbandinfo_get_extent" ); return CE_Fatal; } dfMinX = extent.minx; dfMinY = extent.miny; dfMaxX = extent.maxx; dfMaxY = extent.maxy; CPLDebug("SDERASTER", "minx: %.5f, miny: %.5f, maxx: %.5f, maxy: %.5f", dfMinX, dfMinY, dfMaxX, dfMaxY); // x0 roughly corresponds to dfMinX // y0 roughly corresponds to dfMaxY // They can be different than the extent parameters because // SDE uses offsets. The following info is from Duarte Carreira // in relation to bug #2063 http://trac.osgeo.org/gdal/ticket/2063 : // Depending on how the data was loaded, the pixel width // or pixel height may include a pixel offset from the nearest // tile boundary. An offset will be indicated by aplus sign // "+" followed by a value. The value indicates the number // of pixels the nearest tile boundary is to the left of // the image for the x dimension or the number of // pixels the nearest tile boundary is above the image for // the y dimension. The offset information is only useful // for advanced application developers who need to know // where the image begins in relation to the underlying tile structure LFLOAT x0, y0; nSDEErr = SE_rasbandinfo_get_tile_origin(band, &x0, &y0); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_rasbandinfo_get_tile_origin" ); return CE_Fatal; } CPLDebug("SDERASTER", "Tile origin: %.5f, %.5f", x0, y0); // we also need to adjust dfMaxX and dfMinY otherwise the cell size will change dfMaxX = (x0-dfMinX) + dfMaxX; dfMinY = (y0-dfMaxY) + dfMinY; // adjust the bbox based on the tile origin. dfMinX = MIN(x0, dfMinX); dfMaxY = MAX(y0, dfMaxY); nSDEErr = SE_rasterattr_create(&hAttributes, false); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_rasterattr_create" ); return CE_Fatal; } // Grab the pointer for our member variable nSDEErr = SE_stream_create(hConnection, &hStream); if( nSDEErr != SE_SUCCESS ) { IssueSDEError( nSDEErr, "SE_stream_create" ); return CE_Fatal; } for (int i=0; i < nBands; i++) { SetBand( i+1, new SDERasterBand( this, i+1, -1, &(paohSDERasterBands[i]) )); } GDALRasterBand* b = GetRasterBand(1); eDataType = b->GetRasterDataType(); SE_rasterinfo_free(raster); return CE_None; }
feature_ptr gdal_featureset::get_feature(mapnik::query const& q) { feature_ptr feature = feature_factory::create(ctx_,1); int raster_has_nodata = 0; double raster_nodata = 0; GDALRasterBand * red = 0; GDALRasterBand * green = 0; GDALRasterBand * blue = 0; GDALRasterBand * alpha = 0; GDALRasterBand * grey = 0; CPLErr raster_io_error = CE_None; /* #ifdef MAPNIK_LOG double tr[6]; dataset_.GetGeoTransform(tr); const double dx = tr[1]; const double dy = tr[5]; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: dx_=" << dx_ << " dx=" << dx << " dy_=" << dy_ << "dy=" << dy; #endif */ view_transform t(raster_width_, raster_height_, raster_extent_, 0, 0); box2d<double> intersect = raster_extent_.intersect(q.get_bbox()); box2d<double> box = t.forward(intersect); //size of resized output pixel in source image domain double margin_x = 1.0 / (std::fabs(dx_) * std::get<0>(q.resolution())); double margin_y = 1.0 / (std::fabs(dy_) * std::get<1>(q.resolution())); if (margin_x < 1) { margin_x = 1.0; } if (margin_y < 1) { margin_y = 1.0; } //select minimum raster containing whole box int x_off = rint(box.minx() - margin_x); int y_off = rint(box.miny() - margin_y); int end_x = rint(box.maxx() + margin_x); int end_y = rint(box.maxy() + margin_y); //clip to available data if (x_off < 0) { x_off = 0; } if (y_off < 0) { y_off = 0; } if (end_x > (int)raster_width_) { end_x = raster_width_; } if (end_y > (int)raster_height_) { end_y = raster_height_; } int width = end_x - x_off; int height = end_y - y_off; // don't process almost invisible data if (box.width() < 0.5) { width = 0; } if (box.height() < 0.5) { height = 0; } //calculate actual box2d of returned raster box2d<double> feature_raster_extent(x_off, y_off, x_off + width, y_off + height); intersect = t.backward(feature_raster_extent); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Raster extent=" << raster_extent_; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: View extent=" << intersect; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Query resolution=" << std::get<0>(q.resolution()) << "," << std::get<1>(q.resolution()); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: StartX=" << x_off << " StartY=" << y_off << " Width=" << width << " Height=" << height; if (width > 0 && height > 0) { double width_res = std::get<0>(q.resolution()); double height_res = std::get<1>(q.resolution()); int im_width = int(width_res * intersect.width() + 0.5); int im_height = int(height_res * intersect.height() + 0.5); double filter_factor = q.get_filter_factor(); im_width = int(im_width * filter_factor + 0.5); im_height = int(im_height * filter_factor + 0.5); // case where we need to avoid upsampling so that the // image can be later scaled within raster_symbolizer if (im_width >= width || im_height >= height) { im_width = width; im_height = height; } if (im_width > 0 && im_height > 0) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << im_width << "," << im_height << ")"; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_; if (band_ > 0) // we are querying a single band { GDALRasterBand * band = dataset_.GetRasterBand(band_); if (band_ > nbands_) { std::ostringstream s; s << "GDAL Plugin: " << band_ << " is an invalid band, dataset only has " << nbands_ << "bands"; throw datasource_exception(s.str()); } GDALDataType band_type = band->GetRasterDataType(); switch (band_type) { case GDT_Byte: { mapnik::image_gray8 image(im_width, im_height); image.set(std::numeric_limits<std::uint8_t>::max()); raster_nodata = band->GetNoDataValue(&raster_has_nodata); raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height, image.data(), image.width(), image.height(), GDT_Byte, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); break; } case GDT_Float64: case GDT_Float32: { mapnik::image_gray32f image(im_width, im_height); image.set(std::numeric_limits<float>::max()); raster_nodata = band->GetNoDataValue(&raster_has_nodata); raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height, image.data(), image.width(), image.height(), GDT_Float32, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); break; } case GDT_UInt16: { mapnik::image_gray16 image(im_width, im_height); image.set(std::numeric_limits<std::uint16_t>::max()); raster_nodata = band->GetNoDataValue(&raster_has_nodata); raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height, image.data(), image.width(), image.height(), GDT_UInt16, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); break; } default: case GDT_Int16: { mapnik::image_gray16s image(im_width, im_height); image.set(std::numeric_limits<std::int16_t>::max()); raster_nodata = band->GetNoDataValue(&raster_has_nodata); raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height, image.data(), image.width(), image.height(), GDT_Int16, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); break; } } } else // working with all bands { mapnik::image_rgba8 image(im_width, im_height); image.set(std::numeric_limits<std::uint32_t>::max()); for (int i = 0; i < nbands_; ++i) { GDALRasterBand * band = dataset_.GetRasterBand(i + 1); #ifdef MAPNIK_LOG get_overview_meta(band); #endif GDALColorInterp color_interp = band->GetColorInterpretation(); switch (color_interp) { case GCI_RedBand: red = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found red band"; break; case GCI_GreenBand: green = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found green band"; break; case GCI_BlueBand: blue = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found blue band"; break; case GCI_AlphaBand: alpha = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found alpha band"; break; case GCI_GrayIndex: grey = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band"; break; case GCI_PaletteIndex: { grey = band; #ifdef MAPNIK_LOG MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band, and colortable..."; GDALColorTable *color_table = band->GetColorTable(); if (color_table) { int count = color_table->GetColorEntryCount(); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color Table count=" << count; for (int j = 0; j < count; j++) { const GDALColorEntry *ce = color_table->GetColorEntry (j); if (! ce) continue; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color entry RGB=" << ce->c1 << "," <<ce->c2 << "," << ce->c3; } } #endif break; } case GCI_Undefined: #if GDAL_VERSION_NUM <= 1730 if (nbands_ == 4) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming alpha band)"; alpha = band; } else { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)"; grey = band; } #else MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)"; grey = band; #endif break; default: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Band type unknown!"; break; } } if (red && green && blue) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing rgb bands..."; raster_nodata = red->GetNoDataValue(&raster_has_nodata); GDALColorTable *color_table = red->GetColorTable(); bool has_nodata = nodata_value_ || raster_has_nodata; // we can deduce the alpha channel from nodata in the Byte case // by reusing the reading of R,G,B bands directly if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte) { double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; // read the data in and create an alpha channel from the nodata values // TODO - we assume here the nodata value for the red band applies to all bands // more details about this at http://trac.osgeo.org/gdal/ticket/2734 float* imageData = (float*)image.bytes(); raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_) { *reinterpret_cast<unsigned *>(&imageData[i]) = 0; } else { *reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF; } } } /* Use dataset RasterIO in priority in 99.9% of the cases */ if( red->GetBand() == 1 && green->GetBand() == 2 && blue->GetBand() == 3 ) { int nBandsToRead = 3; if( alpha != NULL && alpha->GetBand() == 4 && !raster_has_nodata ) { nBandsToRead = 4; alpha = NULL; // to avoid reading it again afterwards } raster_io_error = dataset_.RasterIO(GF_Read, x_off, y_off, width, height, image.bytes(), image.width(), image.height(), GDT_Byte, nBandsToRead, NULL, 4, 4 * image.width(), 1); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } } else { raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } raster_io_error = green->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 1, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 2, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } } // In the case we skipped initializing the alpha channel if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte) { double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; if( apply_nodata >= 0 && apply_nodata <= 255 ) { int len = image.width() * image.height(); GByte* pabyBytes = (GByte*) image.bytes(); for (int i = 0; i < len; ++i) { // TODO - we assume here the nodata value for the red band applies to all bands // more details about this at http://trac.osgeo.org/gdal/ticket/2734 if (std::fabs(apply_nodata - pabyBytes[4*i]) < nodata_tolerance_) pabyBytes[4*i + 3] = 0; else pabyBytes[4*i + 3] = 255; } } } } else if (grey) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing gray band..."; raster_nodata = grey->GetNoDataValue(&raster_has_nodata); GDALColorTable* color_table = grey->GetColorTable(); bool has_nodata = nodata_value_ || raster_has_nodata; if (!color_table && has_nodata) { double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: applying nodata value for layer=" << apply_nodata; // first read the data in and create an alpha channel from the nodata values float* imageData = (float*)image.bytes(); raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_) { *reinterpret_cast<unsigned *>(&imageData[i]) = 0; } else { *reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF; } } } raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 1, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 2, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } if (color_table) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Loading color table..."; for (unsigned y = 0; y < image.height(); ++y) { unsigned int* row = image.get_row(y); for (unsigned x = 0; x < image.width(); ++x) { unsigned value = row[x] & 0xff; const GDALColorEntry *ce = color_table->GetColorEntry(value); if (ce) { row[x] = (ce->c4 << 24)| (ce->c3 << 16) | (ce->c2 << 8) | (ce->c1) ; } else { // make lacking color entry fully alpha // note - gdal_translate makes black row[x] = 0; } } } } } if (alpha) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: processing alpha band..."; if (!raster_has_nodata) { raster_io_error = alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } } else { MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of alpha band"; } } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); } // report actual/original source nodata in feature attributes if (raster_has_nodata) { feature->put("nodata",raster_nodata); } return feature; } } return feature_ptr(); }
bool GDALUtilities::createRasterFile(QString& theFilename, QString& theFormat, GDALDataType theType, int theBands, int theRows, int theCols, void ** theData, double * theGeoTransform, const QgsCoordinateReferenceSystem * theCrs, double theNodataValue) { if ( theBands <= 0 ) return false; if ( theRows <= 0 ) return false; if ( theCols <= 0 ) return false; if ( !theData ) return false; /* bool formatSupported = false; QMapIterator<QString, QString> i(mSupportedFormats); while (i.hasNext()) { i.next(); if( theFormat == i.key()) { formatSupported = true; break; } } if ( !formatSupported ) return false; */ //GDALAllRegister(); GDALDriver * driver; //set format char * format = new char[theFormat.size() + 1]; strcpy( format, theFormat.toLocal8Bit().data() ); driver = GetGDALDriverManager()->GetDriverByName(format); if( driver == NULL ) return false; char ** metadata = driver->GetMetadata(); if( !CSLFetchBoolean( metadata, GDAL_DCAP_CREATE, FALSE ) ) return false; GDALDataset * dstDS; //set options char ** options = NULL; options = CSLSetNameValue( options, "COMPRESS", "LZW" ); //if it is a GeoTIFF format set correct compression options if ( !strcmp( format, "GTiff" ) ) { if( theType == GDT_Byte ) { options = CSLSetNameValue( options, "PREDICTOR", "1" ); } else { if ( theType == GDT_UInt16 || theType == GDT_Int16 || theType == GDT_UInt32 || theType == GDT_Int32 ) { options = CSLSetNameValue( options, "PREDICTOR", "2" ); } else { options = CSLSetNameValue( options, "PREDICTOR", "3" ); } } } //set filename char * dstFilename = new char[theFilename.size() + 1]; strcpy( dstFilename, theFilename.toLocal8Bit().data() ); dstDS = driver->Create( dstFilename, theCols, theRows, theBands, theType, options ); delete dstFilename; delete [] options; //set geotransform dstDS->SetGeoTransform( theGeoTransform ); //set CRS char * crsWkt = new char[theCrs->toWkt().size() + 1]; strcpy( crsWkt, theCrs->toWkt().toLocal8Bit().data()); dstDS->SetProjection( crsWkt ); delete crsWkt; GDALRasterBand * band; for( int i=1; i <= theBands; i++ ) { band = dstDS->GetRasterBand( i ); band->SetNoDataValue( theNodataValue ); band->RasterIO( GF_Write, 0, 0, theCols, theRows, theData[ i-1 ], theCols, theRows, theType, 0, 0); } GDALClose( (GDALDatasetH) dstDS ); return true; }
FXImage* GUISUMOAbstractView::checkGDALImage(Decal& d) { #ifdef HAVE_GDAL GDALAllRegister(); GDALDataset* poDataset = (GDALDataset*)GDALOpen(d.filename.c_str(), GA_ReadOnly); if (poDataset == 0) { return 0; } const int xSize = poDataset->GetRasterXSize(); const int ySize = poDataset->GetRasterYSize(); // checking for geodata in the picture and try to adapt position and scale if (d.width <= 0.) { double adfGeoTransform[6]; if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) { Position topLeft(adfGeoTransform[0], adfGeoTransform[3]); const double horizontalSize = xSize * adfGeoTransform[1]; const double verticalSize = ySize * adfGeoTransform[5]; Position bottomRight(topLeft.x() + horizontalSize, topLeft.y() + verticalSize); if (GeoConvHelper::getProcessing().x2cartesian(topLeft) && GeoConvHelper::getProcessing().x2cartesian(bottomRight)) { d.width = bottomRight.x() - topLeft.x(); d.height = topLeft.y() - bottomRight.y(); d.centerX = (topLeft.x() + bottomRight.x()) / 2; d.centerY = (topLeft.y() + bottomRight.y()) / 2; //WRITE_MESSAGE("proj: " + toString(poDataset->GetProjectionRef()) + " dim: " + toString(d.width) + "," + toString(d.height) + " center: " + toString(d.centerX) + "," + toString(d.centerY)); } else { WRITE_WARNING("Could not convert coordinates in " + d.filename + "."); } } } #endif if (d.width <= 0.) { d.width = getGridWidth(); d.height = getGridHeight(); } // trying to read the picture #ifdef HAVE_GDAL const int picSize = xSize * ySize; FXColor* result; if (!FXMALLOC(&result, FXColor, picSize)) { WRITE_WARNING("Could not allocate memory for " + d.filename + "."); return 0; } for (int j = 0; j < picSize; j++) { result[j] = FXRGB(0, 0, 0); } bool valid = true; for (int i = 1; i <= poDataset->GetRasterCount(); i++) { GDALRasterBand* poBand = poDataset->GetRasterBand(i); int shift = -1; if (poBand->GetColorInterpretation() == GCI_RedBand) { shift = 0; } else if (poBand->GetColorInterpretation() == GCI_GreenBand) { shift = 1; } else if (poBand->GetColorInterpretation() == GCI_BlueBand) { shift = 2; } else if (poBand->GetColorInterpretation() == GCI_AlphaBand) { shift = 3; } else { WRITE_MESSAGE("Unknown color band in " + d.filename + ", maybe fox can parse it."); valid = false; break; } assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize()); if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, ((unsigned char*)result) + shift, xSize, ySize, GDT_Byte, 4, 4 * xSize) == CE_Failure) { valid = false; break; } } GDALClose(poDataset); if (valid) { return new FXImage(getApp(), result, IMAGE_OWNED | IMAGE_KEEP | IMAGE_SHMI | IMAGE_SHMP, xSize, ySize); } FXFREE(&result); #endif return 0; }
static int ProxyMain( int argc, char ** argv ) { // GDALDatasetH hDataset, hOutDS; // int i; // int nRasterXSize, nRasterYSize; // const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; // GDALDriverH hDriver; // int *panBandList = NULL; /* negative value of panBandList[i] means mask band of ABS(panBandList[i]) */ // int nBandCount = 0, bDefBands = TRUE; // double adfGeoTransform[6]; // GDALDataType eOutputType = GDT_Unknown; // int nOXSize = 0, nOYSize = 0; // char *pszOXSize=NULL, *pszOYSize=NULL; // char **papszCreateOptions = NULL; // int anSrcWin[4], bStrict = FALSE; // const char *pszProjection; // int bScale = FALSE, bHaveScaleSrc = FALSE, bUnscale=FALSE; // double dfScaleSrcMin=0.0, dfScaleSrcMax=255.0; // double dfScaleDstMin=0.0, dfScaleDstMax=255.0; // double dfULX, dfULY, dfLRX, dfLRY; // char **papszMetadataOptions = NULL; // char *pszOutputSRS = NULL; // int bQuiet = FALSE, bGotBounds = FALSE; // GDALProgressFunc pfnProgress = GDALTermProgress; // int nGCPCount = 0; // GDAL_GCP *pasGCPs = NULL; // int iSrcFileArg = -1, iDstFileArg = -1; // int bCopySubDatasets = FALSE; // double adfULLR[4] = { 0,0,0,0 }; // int bSetNoData = FALSE; // int bUnsetNoData = FALSE; // double dfNoDataReal = 0.0; // int nRGBExpand = 0; // int bParsedMaskArgument = FALSE; // int eMaskMode = MASK_AUTO; // int nMaskBand = 0; /* negative value means mask band of ABS(nMaskBand) */ // int bStats = FALSE, bApproxStats = FALSE; // GDALDatasetH hDataset, hOutDS; GDALDataset *hDataset = NULL; GDALDataset *hOutDS = NULL; int i; int nRasterXSize, nRasterYSize; const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; // GDALDriverH hDriver; GDALDriver *hDriver; GDALDataType eOutputType = GDT_Unknown; char **papszCreateOptions = NULL; int bStrict = FALSE; int bQuiet = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int iSrcFileArg = -1, iDstFileArg = -1; int bSetNoData = FALSE; int bUnsetNoData = FALSE; double dfNoDataReal = 0.0; GDALRasterBand *inBand = NULL; GDALRasterBand *outBand = NULL; GByte *srcBuffer; double adfGeoTransform[6]; int nRasterCount; int bReplaceIds = FALSE; const char *pszReplaceFilename = NULL; const char *pszReplaceFieldFrom = NULL; const char *pszReplaceFieldTo = NULL; std::map<GByte,GByte> mReplaceTable; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) 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; } } /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Handle command line arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i],"-of") && i < argc-1 ) pszFormat = argv[++i]; else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") ) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if( EQUAL(argv[i],"-ot") && i < argc-1 ) { int iType; for( iType = 1; iType < GDT_TypeCount; iType++ ) { if( GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i+1]) ) { eOutputType = (GDALDataType) iType; } } if( eOutputType == GDT_Unknown ) { printf( "Unknown output pixel type: %s\n", argv[i+1] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } i++; } else if( EQUAL(argv[i],"-not_strict") ) bStrict = FALSE; else if( EQUAL(argv[i],"-strict") ) bStrict = TRUE; else if( EQUAL(argv[i],"-a_nodata") && i < argc - 1 ) { if (EQUAL(argv[i+1], "none")) { bUnsetNoData = TRUE; } else { bSetNoData = TRUE; dfNoDataReal = CPLAtofM(argv[i+1]); } i += 1; } else if( EQUAL(argv[i],"-co") && i < argc-1 ) { papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUAL(argv[i],"-replace_ids") && i < argc-3 ) { bReplaceIds = TRUE; pszReplaceFilename = (argv[++i]); pszReplaceFieldFrom = (argv[++i]); pszReplaceFieldTo = (argv[++i]); } else if( argv[i][0] == '-' ) { printf( "Option %s incomplete, or not recognised.\n\n", argv[i] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } else if( pszSource == NULL ) { iSrcFileArg = i; pszSource = argv[i]; } else if( pszDest == NULL ) { pszDest = argv[i]; iDstFileArg = i; } else { printf( "Too many command options.\n\n" ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } } if( pszDest == NULL ) { Usage(); GDALDestroyDriverManager(); exit( 10 ); } if ( strcmp(pszSource, pszDest) == 0) { fprintf(stderr, "Source and destination datasets must be different.\n"); GDALDestroyDriverManager(); exit( 1 ); } if( bReplaceIds ) { if ( ! pszReplaceFilename | ! pszReplaceFieldFrom | ! pszReplaceFieldTo ) Usage(); // FILE * ifile; // if ( (ifile = fopen(pszReplaceFilename, "r")) == NULL ) // { // fprintf( stderr, "Replace file %s cannot be read!\n\n", pszReplaceFilename ); // Usage(); // } // else // fclose( ifile ); mReplaceTable = InitReplaceTable(pszReplaceFilename, pszReplaceFieldFrom, pszReplaceFieldTo); printf("TMP ET size: %d\n",(int)mReplaceTable.size()); } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ // hDataset = GDALOpenShared( pszSource, GA_ReadOnly ); hDataset = (GDALDataset *) GDALOpen(pszSource, GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg() ); GDALDestroyDriverManager(); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Collect some information from the source file. */ /* -------------------------------------------------------------------- */ // nRasterXSize = GDALGetRasterXSize( hDataset ); // nRasterYSize = GDALGetRasterYSize( hDataset ); nRasterXSize = hDataset->GetRasterXSize(); nRasterYSize = hDataset->GetRasterYSize(); if( !bQuiet ) printf( "Input file size is %d, %d\n", nRasterXSize, nRasterYSize ); /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GetGDALDriverManager()->GetDriverByName( pszFormat ); if( hDriver == NULL ) { int iDr; printf( "Output driver `%s' not recognised.\n", pszFormat ); printf( "The following format drivers are configured and support output:\n" ); for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ ) { GDALDriverH hDriver = GDALGetDriver(iDr); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL ) { printf( " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } printf( "\n" ); Usage(); GDALClose( (GDALDatasetH) hDataset ); GDALDestroyDriverManager(); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Create Dataset and copy info */ /* -------------------------------------------------------------------- */ nRasterCount = hDataset->GetRasterCount(); printf("creating\n"); hOutDS = hDriver->Create( pszDest, nRasterXSize, nRasterYSize, nRasterCount, GDT_Byte, papszCreateOptions); printf("created\n"); if( hOutDS != NULL ) { hDataset->GetGeoTransform( adfGeoTransform); hOutDS->SetGeoTransform( adfGeoTransform ); hOutDS->SetProjection( hDataset->GetProjectionRef() ); /* ==================================================================== */ /* Process all bands. */ /* ==================================================================== */ // if (0) for( i = 1; i < nRasterCount+1; i++ ) { inBand = hDataset->GetRasterBand( i ); // hOutDS->AddBand(GDT_Byte); outBand = hOutDS->GetRasterBand( i ); CopyBandInfo( inBand, outBand, 0, 1, 1 ); nRasterXSize = inBand->GetXSize( ); nRasterYSize = inBand->GetYSize( ); GByte old_value, new_value; // char tmp_value[255]; // const char *tmp_value2; std::map<GByte,GByte>::iterator it; //tmp int nXBlocks, nYBlocks, nXBlockSize, nYBlockSize; int iXBlock, iYBlock; inBand->GetBlockSize( &nXBlockSize, &nYBlockSize ); // nXBlockSize = nXBlockSize / 4; // nYBlockSize = nYBlockSize / 4; nXBlocks = (inBand->GetXSize() + nXBlockSize - 1) / nXBlockSize; nYBlocks = (inBand->GetYSize() + nYBlockSize - 1) / nYBlockSize; printf("blocks: %d %d %d %d\n",nXBlockSize,nYBlockSize,nXBlocks,nYBlocks); printf("TMP ET creating raster %d x %d\n",nRasterXSize, nRasterYSize); // srcBuffer = new GByte[nRasterXSize * nRasterYSize]; // printf("reading\n"); // inBand->RasterIO( GF_Read, 0, 0, nRasterXSize, nRasterYSize, // srcBuffer, nRasterXSize, nRasterYSize, GDT_Byte, // 0, 0 ); // srcBuffer = (GByte *) CPLMalloc(sizeof(GByte)*nRasterXSize * nRasterYSize); srcBuffer = (GByte *) CPLMalloc(nXBlockSize * nYBlockSize); for( iYBlock = 0; iYBlock < nYBlocks; iYBlock++ ) { // if(iYBlock%1000 == 0) // printf("iXBlock: %d iYBlock: %d\n",iXBlock,iYBlock); if(iYBlock%1000 == 0) printf("iYBlock: %d / %d\n",iYBlock,nYBlocks); for( iXBlock = 0; iXBlock < nXBlocks; iXBlock++ ) { int nXValid, nYValid; // inBand->ReadBlock( iXBlock, iYBlock, srcBuffer ); inBand->RasterIO( GF_Read, iXBlock, iYBlock, nXBlockSize, nYBlockSize, srcBuffer, nXBlockSize, nYBlockSize, GDT_Byte, 0, 0 ); // Compute the portion of the block that is valid // for partial edge blocks. if( (iXBlock+1) * nXBlockSize > inBand->GetXSize() ) nXValid = inBand->GetXSize() - iXBlock * nXBlockSize; else nXValid = nXBlockSize; if( (iYBlock+1) * nYBlockSize > inBand->GetYSize() ) nYValid = inBand->GetYSize() - iYBlock * nYBlockSize; else nYValid = nYBlockSize; // printf("iXBlock: %d iYBlock: %d read, nXValid: %d nYValid: %d\n",iXBlock,iYBlock,nXValid, nYValid); // if(0) if ( pszReplaceFilename ) { for( int iY = 0; iY < nYValid; iY++ ) { for( int iX = 0; iX < nXValid; iX++ ) { // panHistogram[pabyData[iX + iY * nXBlockSize]] += 1; old_value = new_value = srcBuffer[iX + iY * nXBlockSize]; // sprintf(tmp_value,"%d",old_value); it = mReplaceTable.find(old_value); if ( it != mReplaceTable.end() ) new_value = it->second; if ( old_value != new_value ) { srcBuffer[iX + iY * nXBlockSize] = new_value; // printf("old_value %d new_value %d final %d\n",old_value,new_value, srcBuffer[iX + iY * nXBlockSize]); } // tmp_value2 = CSVGetField( pszReplaceFilename,pszReplaceFieldFrom, // tmp_value, CC_Integer, pszReplaceFieldTo); // if( tmp_value2 != NULL ) // { // new_value = atoi(tmp_value2); // } // new_value = old_value +1; // } } } // printf("writing\n"); // outBand->WriteBlock( iXBlock, iYBlock, srcBuffer ); outBand->RasterIO( GF_Write, iXBlock, iYBlock, nXBlockSize, nYBlockSize, srcBuffer, nXBlockSize, nYBlockSize, GDT_Byte, 0, 0 ); // printf("wrote\n"); } } CPLFree(srcBuffer); printf("read\n"); printf("mod\n"); // if ( pszReplaceFilename ) // { // GByte old_value, new_value; // // char tmp_value[255]; // // const char *tmp_value2; // std::map<GByte,GByte>::iterator it; // for ( int j=0; j<nRasterXSize*nRasterYSize; j++ ) // { // old_value = new_value = srcBuffer[j]; // // sprintf(tmp_value,"%d",old_value); // it = mReplaceTable.find(old_value); // if ( it != mReplaceTable.end() ) new_value = it->second; // // tmp_value2 = CSVGetField( pszReplaceFilename,pszReplaceFieldFrom, // // tmp_value, CC_Integer, pszReplaceFieldTo); // // if( tmp_value2 != NULL ) // // { // // new_value = atoi(tmp_value2); // // } // // new_value = old_value +1; // if ( old_value != new_value ) srcBuffer[j] = new_value; // // printf("old_value %d new_value %d final %d\n",old_value,new_value, srcBuffer[j]); // } // printf("writing\n"); // outBand->RasterIO( GF_Write, 0, 0, nRasterXSize, nRasterYSize, // srcBuffer, nRasterXSize, nRasterYSize, GDT_Byte, // 0, 0 ); // printf("wrote\n"); // delete [] srcBuffer; // } } } if( hOutDS != NULL ) GDALClose( (GDALDatasetH) hOutDS ); if( hDataset != NULL ) GDALClose( (GDALDatasetH) hDataset ); GDALDumpOpenDatasets( stderr ); // GDALDestroyDriverManager(); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); return hOutDS == NULL; }
int main(int argc, char *argv[]){ GDALDataset *poDataset; GDALAllRegister(); if(argc != 3){ std::cout << "usage:\n" << argv[0] << " src_file dest_file\n"; exit(0); } const std::string name = argv[1]; const std::string destName = argv[2]; poDataset = (GDALDataset *) GDALOpen(name.c_str(), GA_ReadOnly ); if( poDataset == NULL ){ std::cout << "Failed to open " << name << "\n"; }else{ const char *pszFormat = "GTiff"; GDALDriver *poDriver; char **papszMetadata; poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat); if( poDriver == NULL ){ std::cout << "Cant open driver\n"; exit(1); } papszMetadata = GDALGetMetadata( poDriver, NULL ); if( !CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) ){ std::cout << "Create Method not suported!\n"; } if( !CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) ){ std::cout << "CreateCopy() method not suported.\n"; } char **papszOptions = NULL; GDALDataset *dest = poDriver->Create(destName.c_str() , poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), 3, GDT_Byte, papszOptions ); std::cout << "Reading file " << name << "\n"; std::cout << "x= " << poDataset->GetRasterXSize() << ", h=" << poDataset->GetRasterYSize() << ", bands= " << poDataset->GetRasterCount() << "\n"; GDALRasterBand *data; data = poDataset->GetRasterBand(1); GDALDataType type = data->GetRasterDataType(); printDataType(type); int size = data->GetXSize()*data->GetYSize(); std::cout << "size=" << size << " , w*h = " << poDataset->GetRasterXSize()*poDataset->GetRasterYSize() << "\n"; float *buffer; buffer = (float *) CPLMalloc(sizeof(float)*size); data->RasterIO(GF_Read, 0, 0, data->GetXSize(), data->GetYSize(), buffer, data->GetXSize(), data->GetYSize(), GDT_Float32, 0, 0 ); GDALRasterBand *destBand1 = dest->GetRasterBand(1); GDALRasterBand *destBand2 = dest->GetRasterBand(2); GDALRasterBand *destBand3 = dest->GetRasterBand(3); // GDALRasterBand *destBand4 = dest->GetRasterBand(4); // Metadata, double geot[6]; poDataset->GetGeoTransform(geot); dest->SetGeoTransform(geot);// adfGeoTransform ); dest->SetProjection( poDataset->GetProjectionRef() ); GByte destWrite1[size]; // = (GUInt32 *) CPLMalloc(sizeof(GUInt32)*size); GByte destWrite2[size]; GByte destWrite3[size]; // GByte destWrite4[size]; unsigned int i; float max=0, min=0; for(i=0; i<size; i++){ if(max < buffer[i]){ max = buffer[i]; } if(min > buffer[i]){ min = buffer[i]; } } float range = max - min; std::cout << "range=" << range << ", max=" << max << ", min=" << min << "\n"; std::map<float, unsigned int> counter; for(i=0; i<size; i++){ counter[buffer[i]]++; unsigned int v = buffer[i] * 100; destWrite1[i] = (v & (0xff << 0)) >> 0; destWrite2[i] = (v & (0xff << 8)) >> 8; destWrite3[i] = (v & (0xff << 16)) >> 16; // destWrite4[i] = 0x00; // (v & (0xff << 24)) >> 24; } destBand1->RasterIO( GF_Write, 0, 0, data->GetXSize(), data->GetYSize(), destWrite1, data->GetXSize(), data->GetYSize(), GDT_Byte, 0, 0 ); destBand2->RasterIO( GF_Write, 0, 0, data->GetXSize(), data->GetYSize(), destWrite2, data->GetXSize(), data->GetYSize(), GDT_Byte, 0, 0 ); destBand3->RasterIO( GF_Write, 0, 0, data->GetXSize(), data->GetYSize(), destWrite3, data->GetXSize(), data->GetYSize(), GDT_Byte, 0, 0 ); // destBand4->RasterIO( GF_Write, 0, 0, data->GetXSize(), data->GetYSize(), // destWrite4, data->GetXSize(), data->GetYSize(), GDT_Byte, 0, 0 ); /*std::map<float, unsigned int>::iterator it; std::cout << "Counter: \n"; for(it=counter.begin(); it!=counter.end(); it++){ std::cout << (it->first*1000) << " = " << it->second << "\n"; }*/ /* Once we're done, close properly the dataset */ if( dest != NULL ){ GDALClose(dest ); GDALClose(poDataset ); } /* unsigned int *buffer; buffer = (unsigned int *) CPLMalloc(sizeof(unsigned int)*size); data->RasterIO(GF_Read, 0, 0, size, 1, buffer, size, 1, GDT_UInt32, 0, 0 ); unsigned int i; std::map<unsigned int, unsigned int> counter; for(i=0; i<size; i++){ counter[buffer[i]]++; } std::map<unsigned int, unsigned int>::iterator it; std::cout << "Counter: \n"; for(it=counter.begin(); it!=counter.end(); it++){ std::cout << it->first << " = " << it->second << "\n"; }*/ } exit(0); }
bool gstIconManager::CopyIcon(const std::string& src_path, const std::string& dst_path) { // file must not exist already if (khExists(dst_path)) { notify(NFY_WARN, "Icon \"%s\" already exists", dst_path.c_str()); return false; } GDALDataset* srcDataset = static_cast<GDALDataset*>( GDALOpen(src_path.c_str(), GA_ReadOnly)); if (!srcDataset) { notify(NFY_WARN, "Unable to open icon %s", src_path.c_str()); return false; } // determine the image type // is it rgb or palette_index type bool palette_type = false; if (srcDataset->GetRasterCount() == 1 && srcDataset->GetRasterBand(1)->GetColorInterpretation() == GCI_PaletteIndex) { palette_type = true; } else if (srcDataset->GetRasterCount() != 4) { notify(NFY_WARN, "%s: Image type not supported", src_path.c_str()); return false; } GDALDataset* oldSrcDataset = 0; int target_size = 0; bool need_scaling = false; int srcXSize = srcDataset->GetRasterXSize(); int srcYSize = srcDataset->GetRasterYSize(); if ((srcXSize == 32) || (srcXSize == 64)) { target_size = srcXSize; if ((srcYSize != srcXSize) && (srcYSize != srcXSize*2) && (srcYSize != srcXSize*3)) { need_scaling = true; } } else if (srcXSize < 32) { target_size = 32; need_scaling = true; } else { target_size = 64; need_scaling = true; } if (need_scaling) { // create a temp output dataset to scale the src // icon to a square target_size*target_size. Later we'll make a stack. VRTDataset* tempDataset = new VRTDataset(target_size, target_size); int numBands = palette_type ? 1 : 4; for (int b = 1; b <= numBands; ++b) { tempDataset->AddBand(GDT_Byte, NULL); VRTSourcedRasterBand* tempBand = static_cast<VRTSourcedRasterBand*>(tempDataset->GetRasterBand(b)); GDALRasterBand* srcBand = srcDataset->GetRasterBand(b); tempBand->AddSimpleSource(srcBand, 0, 0, srcXSize, srcYSize, 0, 0, target_size, target_size); if (palette_type) { tempBand->SetColorInterpretation(srcBand->GetColorInterpretation()); tempBand->SetColorTable(srcBand->GetColorTable()); } } oldSrcDataset = srcDataset; srcDataset = tempDataset; srcXSize = srcYSize = target_size; } assert(srcXSize == target_size); // From here on we assume that we have a square, a stack of 2, or a stack of // 3. It will be either 32 or 64 wide. The actual size is stored in srcXSize // and srcYSize bool simpleCopy = false; if (srcYSize == srcXSize * 3) simpleCopy = true; // create a virtual dataset to represent the desired output image VRTDataset* vds = new VRTDataset(target_size, target_size * 3); // copy all the bands from the source int numBands = palette_type ? 1 : 4; for (int b = 1; b <= numBands; ++b) { vds->AddBand(GDT_Byte, NULL); VRTSourcedRasterBand* vrtBand = static_cast<VRTSourcedRasterBand*>(vds->GetRasterBand(b)); GDALRasterBand* srcBand = srcDataset->GetRasterBand(b); if (!simpleCopy) { // extract the normal icon (on bottom of input image) // and put it on the bottom of new image // NOTE: srcYSize calculation lets us hand single, square images // as well as two squares stacked on top of each other vrtBand->AddSimpleSource( srcBand, 0, srcYSize-target_size, target_size, target_size, 0, target_size*2, target_size, target_size); // extract the highlight icon (on top of input image) // and put it in the middle of new image vrtBand->AddSimpleSource(srcBand, 0, 0, target_size, target_size, 0, target_size, target_size, target_size); // extract the normal icon (on bottom of input image), scale it to 16x16 // and put it on the top of the new image // NOTE: srcYSize calculation lets us hand single, square images // as well as two squares stacked on top of each other vrtBand->AddSimpleSource( srcBand, 0, srcYSize-target_size, target_size, target_size, 0, 0, 16, 16); } else { vrtBand->AddSimpleSource(srcBand, 0, 0, target_size, target_size * 3, 0, 0, target_size, target_size * 3); } if (palette_type) { vrtBand->SetColorInterpretation(srcBand->GetColorInterpretation()); vrtBand->SetColorTable(srcBand->GetColorTable()); } } // find output driver GDALDriver* pngDriver = GetGDALDriverManager()->GetDriverByName("PNG"); if (pngDriver == NULL) { notify(NFY_FATAL, "Unable to find png driver!"); return false; } // write out all bands at once GDALDataset* dest = pngDriver->CreateCopy( dst_path.c_str(), vds, false, NULL, NULL, NULL); delete dest; delete vds; delete srcDataset; delete oldSrcDataset; // just in case the umask trimmed any permissions khChmod(dst_path, 0666); return true; }
CC_FILE_ERROR RasterGridFilter::loadFile(QString filename, ccHObject& container, bool alwaysDisplayLoadDialog/*=true*/, bool* coordinatesShiftEnabled/*=0*/, CCVector3d* coordinatesShift/*=0*/) { GDALAllRegister(); ccLog::PrintDebug("(GDAL drivers: %i)", GetGDALDriverManager()->GetDriverCount()); GDALDataset* poDataset = static_cast<GDALDataset*>(GDALOpen( qPrintable(filename), GA_ReadOnly )); if( poDataset != NULL ) { ccLog::Print(QString("Raster file: '%1'").arg(filename)); ccLog::Print( "Driver: %s/%s", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); int rasterCount = poDataset->GetRasterCount(); int rasterX = poDataset->GetRasterXSize(); int rasterY = poDataset->GetRasterYSize(); ccLog::Print( "Size is %dx%dx%d", rasterX, rasterY, rasterCount ); ccPointCloud* pc = new ccPointCloud(); if (!pc->reserve(static_cast<unsigned>(rasterX * rasterY))) { delete pc; return CC_FERR_NOT_ENOUGH_MEMORY; } if( poDataset->GetProjectionRef() != NULL ) ccLog::Print( "Projection is `%s'", poDataset->GetProjectionRef() ); double adfGeoTransform[6] = { 0, //top left x 1, //w-e pixel resolution (can be negative) 0, //0 0, //top left y 0, //0 1 //n-s pixel resolution (can be negative) }; if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { ccLog::Print( "Origin = (%.6f,%.6f)", adfGeoTransform[0], adfGeoTransform[3] ); ccLog::Print( "Pixel Size = (%.6f,%.6f)", adfGeoTransform[1], adfGeoTransform[5] ); } if (adfGeoTransform[1] == 0 || adfGeoTransform[5] == 0) { ccLog::Warning("Invalid pixel size! Forcing it to (1,1)"); adfGeoTransform[1] = adfGeoTransform[5] = 1; } CCVector3d origin( adfGeoTransform[0], adfGeoTransform[3], 0.0 ); CCVector3d Pshift(0,0,0); //check for 'big' coordinates { bool shiftAlreadyEnabled = (coordinatesShiftEnabled && *coordinatesShiftEnabled && coordinatesShift); if (shiftAlreadyEnabled) Pshift = *coordinatesShift; bool applyAll = false; if ( sizeof(PointCoordinateType) < 8 && ccCoordinatesShiftManager::Handle(origin,0,alwaysDisplayLoadDialog,shiftAlreadyEnabled,Pshift,0,&applyAll)) { pc->setGlobalShift(Pshift); ccLog::Warning("[RasterFilter::loadFile] Raster has been recentered! Translation: (%.2f,%.2f,%.2f)",Pshift.x,Pshift.y,Pshift.z); //we save coordinates shift information if (applyAll && coordinatesShiftEnabled && coordinatesShift) { *coordinatesShiftEnabled = true; *coordinatesShift = Pshift; } } } //create blank raster 'grid' { double z = 0.0 /*+ Pshift.z*/; for (int j=0; j<rasterY; ++j) { double y = adfGeoTransform[3] + static_cast<double>(j) * adfGeoTransform[5] + Pshift.y; CCVector3 P( 0, static_cast<PointCoordinateType>(y), static_cast<PointCoordinateType>(z)); for (int i=0; i<rasterX; ++i) { double x = adfGeoTransform[0] + static_cast<double>(i) * adfGeoTransform[1] + Pshift.x; P.x = static_cast<PointCoordinateType>(x); pc->addPoint(P); } } QVariant xVar = QVariant::fromValue<int>(rasterX); QVariant yVar = QVariant::fromValue<int>(rasterY); pc->setMetaData("raster_width",xVar); pc->setMetaData("raster_height",yVar); } //fetch raster bands bool zRasterProcessed = false; unsigned zInvalid = 0; double zMinMax[2] = {0, 0}; for (int i=1; i<=rasterCount; ++i) { ccLog::Print( "Reading band #%i", i); GDALRasterBand* poBand = poDataset->GetRasterBand(i); GDALColorInterp colorInterp = poBand->GetColorInterpretation(); GDALDataType bandType = poBand->GetRasterDataType(); int nBlockXSize, nBlockYSize; poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); ccLog::Print( "Block=%dx%d Type=%s, ColorInterp=%s", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName(colorInterp) ); //fetching raster scan-line int nXSize = poBand->GetXSize(); int nYSize = poBand->GetYSize(); assert(nXSize == rasterX); assert(nYSize == rasterY); int bGotMin, bGotMax; double adfMinMax[2] = {0, 0}; adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if (!bGotMin || !bGotMax ) //DGM FIXME: if the file is corrupted (e.g. ASCII ArcGrid with missing rows) this method will enter in a infinite loop! GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); ccLog::Print( "Min=%.3fd, Max=%.3f", adfMinMax[0], adfMinMax[1] ); GDALColorTable* colTable = poBand->GetColorTable(); if( colTable != NULL ) printf( "Band has a color table with %d entries", colTable->GetColorEntryCount() ); if( poBand->GetOverviewCount() > 0 ) printf( "Band has %d overviews", poBand->GetOverviewCount() ); if (colorInterp == GCI_Undefined && !zRasterProcessed/*&& !colTable*/) //probably heights? { zRasterProcessed = true; zMinMax[0] = adfMinMax[0]; zMinMax[1] = adfMinMax[1]; double* scanline = (double*) CPLMalloc(sizeof(double)*nXSize); //double* scanline = new double[nXSize]; memset(scanline,0,sizeof(double)*nXSize); for (int j=0; j<nYSize; ++j) { if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/scanline, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Float64, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None) { delete pc; CPLFree(scanline); GDALClose(poDataset); return CC_FERR_READING; } for (int k=0; k<nXSize; ++k) { double z = static_cast<double>(scanline[k]) + Pshift[2]; unsigned pointIndex = static_cast<unsigned>(k + j * rasterX); if (pointIndex <= pc->size()) { if (z < zMinMax[0] || z > zMinMax[1]) { z = zMinMax[0] - 1.0; ++zInvalid; } const_cast<CCVector3*>(pc->getPoint(pointIndex))->z = static_cast<PointCoordinateType>(z); } } } //update bounding-box pc->invalidateBoundingBox(); if (scanline) CPLFree(scanline); scanline = 0; } else //colors { bool isRGB = false; bool isScalar = false; bool isPalette = false; switch(colorInterp) { case GCI_Undefined: isScalar = true; break; case GCI_PaletteIndex: isPalette = true; break; case GCI_RedBand: case GCI_GreenBand: case GCI_BlueBand: isRGB = true; break; case GCI_AlphaBand: if (adfMinMax[0] != adfMinMax[1]) isScalar = true; else ccLog::Warning(QString("Alpha band ignored as it has a unique value (%1)").arg(adfMinMax[0])); break; default: isScalar = true; break; } if (isRGB || isPalette) { //first check that a palette exists if the band is a palette index if (isPalette && !colTable) { ccLog::Warning(QString("Band is declared as a '%1' but no palette is associated!").arg(GDALGetColorInterpretationName(colorInterp))); isPalette = false; } else { //instantiate memory for RBG colors if necessary if (!pc->hasColors() && !pc->setRGBColor(MAX_COLOR_COMP,MAX_COLOR_COMP,MAX_COLOR_COMP)) { ccLog::Warning(QString("Failed to instantiate memory for storing color band '%1'!").arg(GDALGetColorInterpretationName(colorInterp))); } else { assert(bandType <= GDT_Int32); int* colIndexes = (int*) CPLMalloc(sizeof(int)*nXSize); //double* scanline = new double[nXSize]; memset(colIndexes,0,sizeof(int)*nXSize); for (int j=0; j<nYSize; ++j) { if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/colIndexes, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Int32, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None) { CPLFree(colIndexes); delete pc; return CC_FERR_READING; } for (int k=0; k<nXSize; ++k) { unsigned pointIndex = static_cast<unsigned>(k + j * rasterX); if (pointIndex <= pc->size()) { colorType* C = const_cast<colorType*>(pc->getPointColor(pointIndex)); switch(colorInterp) { case GCI_PaletteIndex: assert(colTable); { GDALColorEntry col; colTable->GetColorEntryAsRGB(colIndexes[k],&col); C[0] = static_cast<colorType>(col.c1 & MAX_COLOR_COMP); C[1] = static_cast<colorType>(col.c2 & MAX_COLOR_COMP); C[2] = static_cast<colorType>(col.c3 & MAX_COLOR_COMP); } break; case GCI_RedBand: C[0] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP); break; case GCI_GreenBand: C[1] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP); break; case GCI_BlueBand: C[2] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP); break; default: assert(false); break; } } } } if (colIndexes) CPLFree(colIndexes); colIndexes = 0; pc->showColors(true); } } } else if (isScalar) { ccScalarField* sf = new ccScalarField(GDALGetColorInterpretationName(colorInterp)); if (!sf->resize(pc->size(),true,NAN_VALUE)) { ccLog::Warning(QString("Failed to instantiate memory for storing '%1' as a scalar field!").arg(sf->getName())); sf->release(); sf = 0; } else { double* colValues = (double*) CPLMalloc(sizeof(double)*nXSize); //double* scanline = new double[nXSize]; memset(colValues,0,sizeof(double)*nXSize); for (int j=0; j<nYSize; ++j) { if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/colValues, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Float64, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None) { CPLFree(colValues); delete pc; return CC_FERR_READING; } for (int k=0; k<nXSize; ++k) { unsigned pointIndex = static_cast<unsigned>(k + j * rasterX); if (pointIndex <= pc->size()) { ScalarType s = static_cast<ScalarType>(colValues[k]); sf->setValue(pointIndex,s); } } } if (colValues) CPLFree(colValues); colValues = 0; sf->computeMinAndMax(); pc->addScalarField(sf); if (pc->getNumberOfScalarFields() == 1) pc->setCurrentDisplayedScalarField(0); pc->showSF(true); } } } } if (pc) { if (!zRasterProcessed) { ccLog::Warning("Raster has no height (Z) information: you can convert one of its scalar fields to Z with 'Edit > Scalar Fields > Set SF as coordinate(s)'"); } else if (zInvalid != 0 && zInvalid < pc->size()) { //shall we remove the points with invalid heights? if (QMessageBox::question(0,"Remove NaN points?","This raster has pixels with invalid heights. Shall we remove them?",QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { CCLib::ReferenceCloud validPoints(pc); unsigned count = pc->size(); bool error = true; if (validPoints.reserve(count-zInvalid)) { for (unsigned i=0; i<count; ++i) { if (pc->getPoint(i)->z >= zMinMax[0]) validPoints.addPointIndex(i); } if (validPoints.size() > 0) { validPoints.resize(validPoints.size()); ccPointCloud* newPC = pc->partialClone(&validPoints); if (newPC) { delete pc; pc = newPC; error = false; } } else { assert(false); } } if (error) { ccLog::Error("Not enough memory to remove the points with invalid heights!"); } } } container.addChild(pc); } GDALClose(poDataset); } else { return CC_FERR_UNKNOWN_FILE; } return CC_FERR_NO_ERROR; }
void ImageWriter::writeImage(QString theInputFileString, QString theOutputFileString) { //printf("Started with input : %s output: %s \n",theInputFileString,theOutputFileString); GDALAllRegister(); GDALDataset *gdalDataset = (GDALDataset *) GDALOpen( theInputFileString, GA_ReadOnly ); if ( gdalDataset == NULL ) { //valid = FALSE; return ; } int myXDimInt = gdalDataset->GetRasterXSize(); int myYDimInt = gdalDataset->GetRasterYSize(); printf("Raster is %i x %i cells\n", myXDimInt, myYDimInt); GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand( 1 ); // RasterIO() takes care of scaling down image uint *myGdalScanData = (uint*) CPLMalloc(sizeof(uint)*myXDimInt * sizeof(uint)*myYDimInt); CPLErr myResultCPLerr = myGdalBand->RasterIO(GF_Read, 0, 0, myXDimInt, myYDimInt, myGdalScanData, myXDimInt, myYDimInt, GDT_UInt32, 0, 0 ); QImage myQImage=QImage(myXDimInt,myYDimInt,32); myQImage.setAlphaBuffer(true); uint stdDevsToPlotDouble=0; bool invertHistogramFlag=false; int transparencyLevelInt=255; //calculate the adjusted matrix stats - which come into affect if the user has chosen RasterBandStats * myAdjustedRasterBandStats = new RasterBandStats(); calculateStats(myAdjustedRasterBandStats, gdalDataset); myAdjustedRasterBandStats->noDataDouble=0;//hard coding for now //to histogram stretch to a given number of std deviations //see if we are using histogram stretch using stddev and plot only within the selected number of deviations if we are //cout << "stdDevsToPlotDouble: " << cboStdDev->currentText() << " converted to " << stdDevsToPlotDouble << endl; if (stdDevsToPlotDouble > 0) { //work out how far on either side of the mean we should include data float myTotalDeviationDouble = stdDevsToPlotDouble * myAdjustedRasterBandStats->stdDevDouble; //printf("myTotalDeviationDouble: %i\n" , myTotalDeviationDouble ); //adjust min and max accordingly //only change min if it is less than mean - (n x deviations) if (myAdjustedRasterBandStats->minValDouble < (myAdjustedRasterBandStats->meanDouble-myTotalDeviationDouble)) { myAdjustedRasterBandStats->minValDouble=(myAdjustedRasterBandStats->meanDouble-myTotalDeviationDouble); //cout << "Adjusting minValDouble to: " << myAdjustedRasterBandStats->minValDouble << endl; } //only change max if it is greater than mean + (n x deviations) if (myAdjustedRasterBandStats->maxValDouble > (myAdjustedRasterBandStats->meanDouble + myTotalDeviationDouble)) { myAdjustedRasterBandStats->maxValDouble=(myAdjustedRasterBandStats->meanDouble+myTotalDeviationDouble); //cout << "Adjusting maxValDouble to: " << myAdjustedRasterBandStats->maxValDouble << endl; } //update the range myAdjustedRasterBandStats->rangeDouble = myAdjustedRasterBandStats->maxValDouble-myAdjustedRasterBandStats->minValDouble; } printf("Main ::\n"); std::cout << "Band Name : " << myAdjustedRasterBandStats->bandName << std::endl; printf("Band No : %i\n",myAdjustedRasterBandStats->bandNo); printf("Band min : %f\n",myAdjustedRasterBandStats->minValDouble); printf("Band max : %f\n",myAdjustedRasterBandStats->maxValDouble); printf("Band range: %f\n",myAdjustedRasterBandStats->rangeDouble); printf("Band mean : %f\n",myAdjustedRasterBandStats->meanDouble); printf("Band sum : %f\n",myAdjustedRasterBandStats->sumDouble); //double sumSqrDevDouble; //used to calculate stddev //double stdDevDouble; //double sumDouble; //int elementCountInt; //double noDataDouble; //set up the three class breaks for pseudocolour mapping double myBreakSizeDouble = myAdjustedRasterBandStats->rangeDouble / 3; double myClassBreakMin1 = myAdjustedRasterBandStats->minValDouble; double myClassBreakMax1 = myAdjustedRasterBandStats->minValDouble + myBreakSizeDouble; double myClassBreakMin2 = myClassBreakMax1; double myClassBreakMax2 = myClassBreakMin2 + myBreakSizeDouble; double myClassBreakMin3 = myClassBreakMax2; double myClassBreakMax3 = myAdjustedRasterBandStats->maxValDouble; printf ("ClassBreak size : %f \n",myBreakSizeDouble); printf ("ClassBreak 1 : %f - %f\n",myClassBreakMin1,myClassBreakMax1); printf ("ClassBreak 2 : %f - %f\n",myClassBreakMin2,myClassBreakMax2); printf ("ClassBreak 3 : %f - %f\n",myClassBreakMin3,myClassBreakMax3); int myRedInt=0; int myGreenInt=0; int myBlueInt=0; for (int myColumnInt = 0; myColumnInt < myYDimInt; myColumnInt++) { for (int myRowInt =0; myRowInt < myXDimInt; myRowInt++) { int myInt=myGdalScanData[myColumnInt*myXDimInt + myRowInt]; //dont draw this point if it is no data ! //double check that myInt >= min and <= max //this is relevant if we are plotting within stddevs if ((myInt < myAdjustedRasterBandStats->minValDouble ) && (myInt != myAdjustedRasterBandStats->noDataDouble)) { myInt = static_cast<int>(myAdjustedRasterBandStats->minValDouble); } if ((myInt > myAdjustedRasterBandStats->maxValDouble) && (myInt != myAdjustedRasterBandStats->noDataDouble)) { myInt = static_cast<int>(myAdjustedRasterBandStats->maxValDouble); } if (myInt==myAdjustedRasterBandStats->noDataDouble) { //hardcoding to white for now myRedInt = 255; myBlueInt = 255; myGreenInt =255; } else if(!invertHistogramFlag) { //check if we are in the first class break if ((myInt >= myClassBreakMin1) && (myInt < myClassBreakMax1) ) { myRedInt = 0; myBlueInt = 255; myGreenInt = static_cast<int>(((255/myAdjustedRasterBandStats->rangeDouble) * (myInt-myClassBreakMin1))*3); } //check if we are in the second class break else if ((myInt >= myClassBreakMin2) && (myInt < myClassBreakMax2) ) { myRedInt = static_cast<int>(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin2)/1))*3); myBlueInt = static_cast<int>(255-(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin2)/1))*3)); myGreenInt = 255; } //otherwise we must be in the third classbreak else { myRedInt = 255; myBlueInt = 0; myGreenInt = static_cast<int>(255-(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin3)/1)*3))); } } else //invert histogram toggle is on { //check if we are in the first class break if ((myInt >= myClassBreakMin1) && (myInt < myClassBreakMax1) ) { myRedInt = 255; myBlueInt = 0; myGreenInt = static_cast<int>(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin1)/1)*3)); } //check if we are in the second class break else if ((myInt >= myClassBreakMin2) && (myInt < myClassBreakMax2) ) { myRedInt = static_cast<int>(255-(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin2)/1))*3)); myBlueInt = static_cast<int>(((255/myAdjustedRasterBandStats->rangeDouble) * ((myInt-myClassBreakMin2)/1))*3); myGreenInt = 255; } //otherwise we must be in the third classbreak else { myRedInt = 0; myBlueInt = 255; myGreenInt = static_cast<int>(255-(((255/myAdjustedRasterBandStats->rangeDouble) * (myInt-myClassBreakMin3))*3)); } } myQImage.setPixel( myRowInt, myColumnInt, qRgba( myRedInt, myGreenInt, myBlueInt, transparencyLevelInt )); } } //draw with the experimental transaparency support CPLFree(myGdalScanData); GDALClose(gdalDataset); printf("Saving image...\n"); myQImage.save(theOutputFileString,"PNG"); return ; }
// Read image bool readImageGDAL(unsigned char **pImageData, int &width, int &height, int &nChannels, const char *filePath, double trans[6]) { GDALAllRegister(); GDALDataset *poDataset = NULL; poDataset = (GDALDataset *) GDALOpen(filePath, GA_ReadOnly); if(poDataset == NULL) { GDALClose(poDataset); return false; } width = poDataset->GetRasterXSize(); height = poDataset->GetRasterYSize(); printf("width=%d\n", width); printf("height=%d\n", height); CPLErr aaa = poDataset->GetGeoTransform(trans); int k = 0; GDALRasterBand *pBand; int i = 0; int nRastercount = poDataset->GetRasterCount(); // one channel, the gray image if (nRastercount == 1) { nChannels = 1; pBand = poDataset->GetRasterBand(1); *pImageData = new unsigned char[width * height]; pBand->RasterIO(GF_Read, 0, 0, width, height, *pImageData, width, height, GDT_Byte, 0, 0); GDALClose(poDataset); return true; } // three channels, and the output is RGB image else if ( nRastercount == 3 && (nChannels == 3 || nChannels < 0) ) { nChannels = 3; *pImageData = new unsigned char[nRastercount * width * height]; for (i = 1; i <= nRastercount; ++ i) { //Band GDAL RGB is stored in order, we usually need to be converted to BGR storage, namely low address to high address: B G R unsigned char *pImageOffset = *pImageData + i - 1; GDALRasterBand *pBand = poDataset->GetRasterBand(nRastercount - i + 1); pBand->RasterIO( GF_Read, 0, 0, width, height, pImageOffset, width, height, GDT_Byte, 3, 0); } GDALClose(poDataset); return true; } //3 channels, but the required output grayscale images else if ( nRastercount == 3 && nChannels == 1 ) { unsigned char **img = new unsigned char *[nRastercount]; for (i = 0; i < nRastercount; i++) { img[i] = new unsigned char[width * height]; } for (i = 1; i <= nRastercount; ++ i) { //Band GDAL RGB is stored in order, we usually need to be converted to BGR storage, namely low address to high address: B G R pBand = poDataset->GetRasterBand(nRastercount - i + 1); pBand->RasterIO(GF_Read, 0, 0, width, height, img[i - 1], width, height, GDT_Byte, 0, 0); } GDALClose(poDataset); *pImageData = new unsigned char[width * height]; for (int r = 0; r < height; ++ r) { for (int c = 0; c < width; ++ c) { int t = (r * width + c); //r g b components are accounted for in turn:0.299 0.587 0.144,can be simplified as 3:6:1 //img[1.2.3]Correspond to BGR (*pImageData)[t] = (img[2][t] * 3 + img[1][t] * 6 + img[0][t] + 5) / 10; } } for (i = 0; i < nRastercount; ++ i) { delete [] img[i]; } delete []img; img = NULL; return true; } else { return false; } }
bool GdalAdapter::loadImage(const QString& fn) { if (alreadyLoaded(fn)) return true; QFileInfo fi(fn); GdalImage img; QRectF bbox; poDataset = (GDALDataset *) GDALOpen( QDir::toNativeSeparators(fi.absoluteFilePath()).toUtf8().constData(), GA_ReadOnly ); if( poDataset == NULL ) { qDebug() << "GDAL Open failed: " << fn; return false; } bool hasGeo = false; QDir dir(fi.absoluteDir()); QString f = fi.baseName(); QStringList wldFilter; wldFilter << f+".tfw" << f+".tifw" << f+".tiffw" << f+".wld"; QFileInfoList fil = dir.entryInfoList(wldFilter); if (fil.count()) { QFile wld(fil[0].absoluteFilePath()); if (wld.open(QIODevice::ReadOnly)) { int i; for (i=0; i<6; ++i) { if (wld.atEnd()) break; QString l = wld.readLine(); bool ok; double d = l.toDouble(&ok); if (!ok) break; switch (i) { case 0: img.adfGeoTransform[1] = d; break; case 1: img.adfGeoTransform[4] = d; break; case 2: img.adfGeoTransform[2] = d; break; case 3: img.adfGeoTransform[5] = d; break; case 4: img.adfGeoTransform[0] = d; break; case 5: img.adfGeoTransform[3] = d; break; } } if (i == 6) hasGeo = true; } } if(!hasGeo) if ( poDataset->GetGeoTransform( img.adfGeoTransform ) != CE_None ) { GDALClose((GDALDatasetH)poDataset); return false; } qDebug( "Origin = (%.6f,%.6f)\n", img.adfGeoTransform[0], img.adfGeoTransform[3] ); qDebug( "Pixel Size = (%.6f,%.6f)\n", img.adfGeoTransform[1], img.adfGeoTransform[5] ); bbox.setTopLeft(QPointF(img.adfGeoTransform[0], img.adfGeoTransform[3])); bbox.setWidth(img.adfGeoTransform[1]*poDataset->GetRasterXSize()); bbox.setHeight(img.adfGeoTransform[5]*poDataset->GetRasterYSize()); isLatLon = false; if( strlen(poDataset->GetProjectionRef()) != 0 ) { qDebug( "Projection is `%s'\n", poDataset->GetProjectionRef() ); OGRSpatialReference* theSrs = new OGRSpatialReference(poDataset->GetProjectionRef()); if (theSrs && theSrs->Validate() == OGRERR_NONE) { theSrs->morphFromESRI(); char* theProj4; if (theSrs->exportToProj4(&theProj4) == OGRERR_NONE) { qDebug() << "GDAL: to proj4 : " << theProj4; } else { qDebug() << "GDAL: to proj4 error: " << CPLGetLastErrorMsg(); GDALClose((GDALDatasetH)poDataset); return false; } QString srsProj = QString(theProj4); if (!srsProj.isEmpty() && theProjection != srsProj) { cleanup(); theProjection = srsProj; } isLatLon = (theSrs->IsGeographic() == TRUE); } } if (theProjection.isEmpty()) { theProjection = ProjectionChooser::getProjection(QCoreApplication::translate("ImportExportGdal", "Unable to set projection; please specify one")); if (theProjection.isEmpty()) { GDALClose((GDALDatasetH)poDataset); return false; } } qDebug( "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); qDebug( "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() ); GdalAdapter::ImgType theType = GdalAdapter::Unknown; int bandCount = poDataset->GetRasterCount(); int ixA = -1; int ixR, ixG, ixB; int ixH, ixS, ixL; int ixC, ixM, ixY, ixK; int ixYuvY, ixYuvU, ixYuvV; double adfMinMax[2]; double UnknownUnit; GDALColorTable* colTable = NULL; for (int i=0; i<bandCount; ++i) { GDALRasterBand *poBand = poDataset->GetRasterBand( i+1 ); GDALColorInterp bandtype = poBand->GetColorInterpretation(); qDebug() << "Band " << i+1 << " Color: " << GDALGetColorInterpretationName(poBand->GetColorInterpretation()); switch (bandtype) { case GCI_Undefined: theType = GdalAdapter::Unknown; int bGotMin, bGotMax; adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); UnknownUnit = (adfMinMax[1] - adfMinMax[0]) / 256; break; case GCI_GrayIndex: theType = GdalAdapter::GrayScale; break; case GCI_RedBand: theType = GdalAdapter::Rgb; ixR = i; break; case GCI_GreenBand: theType = GdalAdapter::Rgb; ixG = i; break; case GCI_BlueBand : theType = GdalAdapter::Rgb; ixB = i; break; case GCI_HueBand: theType = GdalAdapter::Hsl; ixH = i; break; case GCI_SaturationBand: theType = GdalAdapter::Hsl; ixS = i; break; case GCI_LightnessBand: theType = GdalAdapter::Hsl; ixL = i; break; case GCI_CyanBand: theType = GdalAdapter::Cmyk; ixC = i; break; case GCI_MagentaBand: theType = GdalAdapter::Cmyk; ixM = i; break; case GCI_YellowBand: theType = GdalAdapter::Cmyk; ixY = i; break; case GCI_BlackBand: theType = GdalAdapter::Cmyk; ixK = i; break; case GCI_YCbCr_YBand: theType = GdalAdapter::YUV; ixYuvY = i; break; case GCI_YCbCr_CbBand: theType = GdalAdapter::YUV; ixYuvU = i; break; case GCI_YCbCr_CrBand: theType = GdalAdapter::YUV; ixYuvV = i; break; case GCI_AlphaBand: ixA = i; break; case GCI_PaletteIndex: colTable = poBand->GetColorTable(); switch (colTable->GetPaletteInterpretation()) { case GPI_Gray : theType = GdalAdapter::Palette_Gray; break; case GPI_RGB : theType = GdalAdapter::Palette_RGBA; break; case GPI_CMYK : theType = GdalAdapter::Palette_CMYK; break; case GPI_HLS : theType = GdalAdapter::Palette_HLS; break; } break; } } QSize theImgSize(poDataset->GetRasterXSize(), poDataset->GetRasterYSize()); QImage theImg = QImage(theImgSize, QImage::Format_ARGB32); // Make sure that lineBuf holds one whole line of data. float *lineBuf; lineBuf = (float *) CPLMalloc(theImgSize.width() * bandCount * sizeof(float)); int px, py; //every row loop for (int row = 0; row < theImgSize.height(); row++) { py = row; CPLErr err = poDataset->RasterIO( GF_Read, 0, row, theImgSize.width(), 1, lineBuf, theImgSize.width(), 1, GDT_Float32, bandCount, NULL, sizeof(float) * bandCount, 0, sizeof(float) ); /* FIXME: Perhaps break, or check if more work needs to be done * (filling with an error pattern? */ if (err != CE_None) { qDebug() << "RasterIO failed to read row. Skipping."; continue; } // every pixel in row. for (int col = 0; col < theImgSize.width(); col++) { px = col; switch (theType) { case GdalAdapter::Unknown: { float* v = lineBuf + (col*bandCount); float val = (*v - adfMinMax[0]) / UnknownUnit; theImg.setPixel(px, py, qRgb(val, val, val)); break; } case GdalAdapter::GrayScale: { float* v = lineBuf + (col*bandCount); theImg.setPixel(px, py, qRgb(*v, *v, *v)); break; } case GdalAdapter::Rgb: { float* r = lineBuf + (col*bandCount) + ixR; float* g = lineBuf + (col*bandCount) + ixG; float* b = lineBuf + (col*bandCount) + ixB; int a = 255; if (ixA != -1) { float* fa = lineBuf + (col*bandCount) + ixA; a = *fa; } theImg.setPixel(px, py, qRgba(*r, *g, *b, a)); break; } #if QT_VERSION >= 0x040600 case GdalAdapter::Hsl: { float* h = lineBuf + (col*bandCount) + ixH; float* s = lineBuf + (col*bandCount) + ixS; float* l = lineBuf + (col*bandCount) + ixL; int a = 255; if (ixA != -1) { float* fa = lineBuf + (col*bandCount) + ixA; a = *fa; } QColor C = QColor::fromHsl(*h, *s, *l, a); theImg.setPixel(px, py, C.rgba()); break; } #endif case GdalAdapter::Cmyk: { float* c = lineBuf + (col*bandCount) + ixC; float* m = lineBuf + (col*bandCount) + ixM; float* y = lineBuf + (col*bandCount) + ixY; float* k = lineBuf + (col*bandCount) + ixK; int a = 255; if (ixA != -1) { float* fa = lineBuf + (col*bandCount) + ixA; a = *fa; } QColor C = QColor::fromCmyk(*c, *m, *y, *k, a); theImg.setPixel(px, py, C.rgba()); break; } case GdalAdapter::YUV: { // From http://www.fourcc.org/fccyvrgb.php float* y = lineBuf + (col*bandCount) + ixYuvY; float* u = lineBuf + (col*bandCount) + ixYuvU; float* v = lineBuf + (col*bandCount) + ixYuvV; int a = 255; if (ixA != -1) { float* fa = lineBuf + (col*bandCount) + ixA; a = *fa; } float R = 1.164*(*y - 16) + 1.596*(*v - 128); float G = 1.164*(*y - 16) - 0.813*(*v - 128) - 0.391*(*u - 128); float B = 1.164*(*y - 16) + 2.018*(*u - 128); theImg.setPixel(px, py, qRgba(R, G, B, a)); break; } case GdalAdapter::Palette_Gray: { float* ix = (lineBuf + (col*bandCount)); const GDALColorEntry* color = colTable->GetColorEntry(*ix); theImg.setPixel(px, py, qRgb(color->c1, color->c1, color->c1)); break; } case GdalAdapter::Palette_RGBA: { float* ix = (lineBuf + (col*bandCount)); const GDALColorEntry* color = colTable->GetColorEntry(*ix); theImg.setPixel(px, py, qRgba(color->c1, color->c2, color->c3, color->c4)); break; } #if QT_VERSION >= 0x040600 case GdalAdapter::Palette_HLS: { float* ix = (lineBuf + (col*bandCount)); const GDALColorEntry* color = colTable->GetColorEntry(*ix); QColor C = QColor::fromHsl(color->c1, color->c2, color->c3, color->c4); theImg.setPixel(px, py, C.rgba()); break; } #endif case GdalAdapter::Palette_CMYK: { float* ix = (lineBuf + (col*bandCount)); const GDALColorEntry* color = colTable->GetColorEntry(*ix); QColor C = QColor::fromCmyk(color->c1, color->c2, color->c3, color->c4); theImg.setPixel(px, py, C.rgba()); break; } } } QCoreApplication::processEvents(); } img.theFilename = fn; img.theImg = QPixmap::fromImage(theImg); theImages.push_back(img); theBbox = theBbox.united(bbox); GDALClose((GDALDatasetH)poDataset); return true; }
void output_dist_geotiff ( image<float> & dist, image<unsigned char> & v ) { int r, c; int val; OGRSpatialReference ref; GDALDataset *df; char *wkt = NULL; GDALRasterBand *bd; double trans[6]; GDALDriver *gt; char **options = NULL; int ov[] = { 2, 4, 8, 16, 32 }; int nov; int n; char file[1000]; options = CSLSetNameValue ( options, "TILED", "NO" ); options = CSLSetNameValue ( options, "COMPRESS", "LZW" ); gt = GetGDALDriverManager()->GetDriverByName("GTiff"); if ( !gt ) { fprintf(stderr,"Could not get GTiff driver\n"); exit(1); } strcpy ( file, p.value("dist_file").c_str() ); df = gt->Create( file, dist.cols, dist.rows, 1, GDT_Byte, options ); if( df == NULL ) { fprintf(stderr,"Could not create %s\n", file ); exit(1); } trans[0] = p.dvalue("easting_left"); trans[1] = p.dvalue("output_cell_size"); trans[2] = 0.0; trans[3] = p.dvalue("northing_top"); trans[4] = 0.0; trans[5] = -p.dvalue("output_cell_size"); df->SetGeoTransform ( trans ); ref.SetUTM ( p.ivalue("utm_zone") ); ref.SetWellKnownGeogCS ( "NAD27" ); ref.exportToWkt ( &wkt ); df->SetProjection(wkt); CPLFree ( wkt ); for ( r=0; r < dist.rows; r++ ) { for ( c=0; c < dist.cols; c++ ) { val = int(sqrt(dist[r][c])+0.5); if ( val > 255 ) val = 255; v[r][c] = val; } } bd = df->GetRasterBand(1); bd->RasterIO( GF_Write, 0, 0, v.cols, v.rows, v.data, v.cols, v.rows, GDT_Byte, 0, 0 ); delete df; df = (GDALDataset *)GDALOpen ( file, GA_Update ); if( df == NULL ) { fprintf(stderr,"Could not open for update %s\n", file ); exit(1); } nov = p.ivalue("overviews"); if ( nov > 5 ) nov = 5; if ( nov > 0 ) { n = 1; df->BuildOverviews("NEAREST", nov, ov, 1, &n, NULL, NULL ); } }
CPLErr HFAAuxBuildOverviews( const char *pszOvrFilename, GDALDataset *poParentDS, GDALDataset **ppoODS, int nBands, int *panBandList, int nNewOverviews, int *panNewOverviewList, const char *pszResampling, GDALProgressFunc pfnProgress, void *pProgressData ) { /* ==================================================================== */ /* If the .aux file doesn't exist yet then create it now. */ /* ==================================================================== */ if( *ppoODS == NULL ) { GDALDataType eDT = GDT_Unknown; /* -------------------------------------------------------------------- */ /* Determine the band datatype, and verify that all bands are */ /* the same. */ /* -------------------------------------------------------------------- */ int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBand *poBand = poParentDS->GetRasterBand( panBandList[iBand] ); if( iBand == 0 ) eDT = poBand->GetRasterDataType(); else { if( eDT != poBand->GetRasterDataType() ) { CPLError( CE_Failure, CPLE_NotSupported, "HFAAuxBuildOverviews() doesn't support a mixture of band" " data types." ); return CE_Failure; } } } /* -------------------------------------------------------------------- */ /* Create the HFA (.aux) file. We create it with */ /* COMPRESSED=YES so that no space will be allocated for the */ /* base band. */ /* -------------------------------------------------------------------- */ GDALDriver *poHFADriver = (GDALDriver *) GDALGetDriverByName("HFA"); if (poHFADriver == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "HFA driver is unavailable." ); return CE_Failure; } const char *apszOptions[4] = { "COMPRESSED=YES", "AUX=YES", NULL, NULL }; CPLString osDepFileOpt = "DEPENDENT_FILE="; osDepFileOpt += CPLGetFilename(poParentDS->GetDescription()); apszOptions[2] = osDepFileOpt.c_str(); *ppoODS = poHFADriver->Create( pszOvrFilename, poParentDS->GetRasterXSize(), poParentDS->GetRasterYSize(), poParentDS->GetRasterCount(), eDT, (char **)apszOptions ); if( *ppoODS == NULL ) return CE_Failure; } /* ==================================================================== */ /* Create the layers. We depend on the normal buildoverviews */ /* support for HFA to do this. But we disable the internal */ /* computation of the imagery for these layers. */ /* */ /* We avoid regenerating the new layers here, because if we did */ /* it would use the base layer from the .aux file as the source */ /* data, and that is fake (all invalid tiles). */ /* ==================================================================== */ CPLString oAdjustedResampling = "NO_REGEN:"; oAdjustedResampling += pszResampling; CPLErr eErr = (*ppoODS)->BuildOverviews( oAdjustedResampling, nNewOverviews, panNewOverviewList, nBands, panBandList, pfnProgress, pProgressData ); return eErr; }
CPLErr GDALWMSRasterBand::ReadBlockFromFile(int x, int y, const char *file_name, int to_buffer_band, void *buffer, int advise_read) { CPLErr ret = CE_None; GDALDataset *ds = 0; GByte *color_table = NULL; int i; //CPLDebug("WMS", "ReadBlockFromFile: to_buffer_band=%d, (x,y)=(%d, %d)", to_buffer_band, x, y); /* expected size */ const int esx = MIN(MAX(0, (x + 1) * nBlockXSize), nRasterXSize) - MIN(MAX(0, x * nBlockXSize), nRasterXSize); const int esy = MIN(MAX(0, (y + 1) * nBlockYSize), nRasterYSize) - MIN(MAX(0, y * nBlockYSize), nRasterYSize); ds = reinterpret_cast<GDALDataset*>(GDALOpen(file_name, GA_ReadOnly)); if (ds != NULL) { int sx = ds->GetRasterXSize(); int sy = ds->GetRasterYSize(); bool accepted_as_no_alpha = false; // if the request is for 4 bands but the wms returns 3 /* Allow bigger than expected so pre-tiled constant size images work on corners */ if ((sx > nBlockXSize) || (sy > nBlockYSize) || (sx < esx) || (sy < esy)) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect size %d x %d of downloaded block, expected %d x %d, max %d x %d.", sx, sy, esx, esy, nBlockXSize, nBlockYSize); ret = CE_Failure; } if (ret == CE_None) { int nDSRasterCount = ds->GetRasterCount(); if (nDSRasterCount != m_parent_dataset->nBands) { /* Maybe its an image with color table */ bool accepted_as_ct = false; if ((eDataType == GDT_Byte) && (ds->GetRasterCount() == 1)) { GDALRasterBand *rb = ds->GetRasterBand(1); if (rb->GetRasterDataType() == GDT_Byte) { GDALColorTable *ct = rb->GetColorTable(); if (ct != NULL) { accepted_as_ct = true; if (!advise_read) { color_table = new GByte[256 * 4]; const int count = MIN(256, ct->GetColorEntryCount()); for (i = 0; i < count; ++i) { GDALColorEntry ce; ct->GetColorEntryAsRGB(i, &ce); color_table[i] = static_cast<GByte>(ce.c1); color_table[i + 256] = static_cast<GByte>(ce.c2); color_table[i + 512] = static_cast<GByte>(ce.c3); color_table[i + 768] = static_cast<GByte>(ce.c4); } for (i = count; i < 256; ++i) { color_table[i] = 0; color_table[i + 256] = 0; color_table[i + 512] = 0; color_table[i + 768] = 0; } } } } } if (nDSRasterCount == 4 && m_parent_dataset->nBands == 3) { /* metacarta TMS service sometimes return a 4 band PNG instead of the expected 3 band... */ } else if (!accepted_as_ct) { if (ds->GetRasterCount()==3 && m_parent_dataset->nBands == 4 && (eDataType == GDT_Byte)) { // WMS returned a file with no alpha so we will fill the alpha band with "opaque" accepted_as_no_alpha = true; } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.", nDSRasterCount, m_parent_dataset->nBands); ret = CE_Failure; } } } } if (!advise_read) { for (int ib = 1; ib <= m_parent_dataset->nBands; ++ib) { if (ret == CE_None) { void *p = NULL; GDALRasterBlock *b = NULL; if ((buffer != NULL) && (ib == to_buffer_band)) { p = buffer; } else { GDALWMSRasterBand *band = static_cast<GDALWMSRasterBand *>(m_parent_dataset->GetRasterBand(ib)); if (m_overview >= 0) band = static_cast<GDALWMSRasterBand *>(band->GetOverview(m_overview)); if (!band->IsBlockInCache(x, y)) { b = band->GetLockedBlockRef(x, y, true); if (b != NULL) { p = b->GetDataRef(); if (p == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: GetDataRef returned NULL."); ret = CE_Failure; } } } else { //CPLDebug("WMS", "Band %d, block (x,y)=(%d, %d) already in cache", band->GetBand(), x, y); } } if (p != NULL) { int pixel_space = GDALGetDataTypeSize(eDataType) / 8; int line_space = pixel_space * nBlockXSize; if (color_table == NULL) { if( ib <= ds->GetRasterCount()) { if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, &ib, pixel_space, line_space, 0) != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block."); ret = CE_Failure; } } else { // parent expects 4 bands but file only has 3 so generate a all "opaque" 4th band if (accepted_as_no_alpha) { // the file had 3 bands and we are reading band 4 (Alpha) so fill with 255 (no alpha) GByte *byte_buffer = reinterpret_cast<GByte *>(p); for (int y = 0; y < sy; ++y) { for (int x = 0; x < sx; ++x) { const int offset = x + y * line_space; byte_buffer[offset] = 255; // fill with opaque } } } else { // we should never get here because this case was caught above CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.", ds->GetRasterCount(), m_parent_dataset->nBands); ret = CE_Failure; } } } else if (ib <= 4) { if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, NULL, pixel_space, line_space, 0) != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block."); ret = CE_Failure; } if (ret == CE_None) { GByte *band_color_table = color_table + 256 * (ib - 1); GByte *byte_buffer = reinterpret_cast<GByte *>(p); for (int y = 0; y < sy; ++y) { for (int x = 0; x < sx; ++x) { const int offset = x + y * line_space; byte_buffer[offset] = band_color_table[byte_buffer[offset]]; } } } } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Color table supports at most 4 components."); ret = CE_Failure; } } if (b != NULL) { b->DropLock(); } } } } GDALClose(ds); } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Unable to open downloaded block."); ret = CE_Failure; } if (color_table != NULL) { delete[] color_table; } return ret; }