int GDAL_EDBFile::ReadBlock( int channel, int block_index, void *buffer, int win_xoff, int win_yoff, int win_xsize, int win_ysize ) { GDALRasterBand *poBand = poDS->GetRasterBand(channel); int nBlockXSize, nBlockYSize; int nBlockX, nBlockY; int nWidthInBlocks; int nPixelOffset; int nLineOffset; if( GetType(channel) == CHN_UNKNOWN ) { ThrowPCIDSKException("%s channel type not supported for PCIDSK access.", GDALGetDataTypeName(poBand->GetRasterDataType()) ); } poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); nWidthInBlocks = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize; nBlockX = block_index % nWidthInBlocks; nBlockY = block_index / nWidthInBlocks; nPixelOffset = GDALGetDataTypeSize(poBand->GetRasterDataType()) / 8; nLineOffset = win_xsize * nPixelOffset; /* -------------------------------------------------------------------- */ /* Are we reading a partial block at the edge of the database? */ /* If so, ensure we don't read off the database. */ /* -------------------------------------------------------------------- */ if( nBlockX * nBlockXSize + win_xoff + win_xsize > poBand->GetXSize() ) win_xsize = poBand->GetXSize() - nBlockX * nBlockXSize - win_xoff; if( nBlockY * nBlockYSize + win_yoff + win_ysize > poBand->GetYSize() ) win_ysize = poBand->GetYSize() - nBlockY * nBlockYSize - win_yoff; CPLErr eErr = poBand->RasterIO( GF_Read, nBlockX * nBlockXSize + win_xoff, nBlockY * nBlockYSize + win_yoff, win_xsize, win_ysize, buffer, win_xsize, win_ysize, poBand->GetRasterDataType(), nPixelOffset, nLineOffset, NULL ); if( eErr != CE_None ) { ThrowPCIDSKException( "%s", CPLGetLastErrorMsg() ); } return 1; }
int GDAL_EDBFile::WriteBlock( int channel, int block_index, void *buffer) { GDALRasterBand *poBand = poDS->GetRasterBand(channel); int nBlockXSize, nBlockYSize; int nBlockX, nBlockY; int nWinXSize, nWinYSize; int nWidthInBlocks; if( GetType(channel) == CHN_UNKNOWN ) { ThrowPCIDSKException("%s channel type not supported for PCIDSK access.", GDALGetDataTypeName(poBand->GetRasterDataType()) ); } poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); nWidthInBlocks = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize; nBlockX = block_index % nWidthInBlocks; nBlockY = block_index / nWidthInBlocks; /* -------------------------------------------------------------------- */ /* Are we reading a partial block at the edge of the database? */ /* If so, ensure we don't read off the database. */ /* -------------------------------------------------------------------- */ if( nBlockX * nBlockXSize + nBlockXSize > poBand->GetXSize() ) nWinXSize = poBand->GetXSize() - nBlockX * nBlockXSize; else nWinXSize = nBlockXSize; if( nBlockY * nBlockYSize + nBlockYSize > poBand->GetYSize() ) nWinYSize = poBand->GetYSize() - nBlockY * nBlockYSize; else nWinYSize = nBlockYSize; CPLErr eErr = poBand->RasterIO( GF_Write, nBlockX * nBlockXSize, nBlockY * nBlockYSize, nWinXSize, nWinYSize, buffer, nWinXSize, nWinYSize, poBand->GetRasterDataType(), 0, 0, NULL ); if( eErr != CE_None ) { ThrowPCIDSKException( "%s", CPLGetLastErrorMsg() ); } return 1; }
Raster* import_raster(string raster_filename, int band_number) { GDALAllRegister(); GDALDataset* poDataset = (GDALDataset *) GDALOpen( raster_filename.c_str(), GA_ReadOnly ); if( poDataset == NULL ) { cerr << "Error: Could not open raster data file" << endl; exit(1); } fprintf(stderr, "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); fprintf(stderr, "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() ); if( poDataset->GetProjectionRef() != NULL ) cerr << "Projection is `" << poDataset->GetProjectionRef() << "'" << endl;; GDALRasterBand* poBand = poDataset->GetRasterBand( band_number ); int nBlockXSize, nBlockYSize; poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); fprintf(stderr, "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); Raster* raster = extract_raster_attributes( poDataset ); raster->band = poBand; return raster; }
void DemReader::MetaDataInfo(GDALDataset* gdalDataset, MapControllerPtr mapController) { FileMetaData* header = mapController->GetMapModel()->GetMetaData(); header->driverDesc = gdalDataset->GetDriver()->GetDescription(); header->driverMetaData = gdalDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME); Log::Inst().Write("Driver: " + header->driverDesc + " \\ " + header->driverMetaData); header->xSize = gdalDataset->GetRasterXSize(); header->ySize = gdalDataset->GetRasterYSize(); header->bands = gdalDataset->GetRasterCount(); Log::Inst().Write("Size (x,y): " + StringTools::ToString(header->xSize) + ", " + StringTools::ToString(header->ySize)); Log::Inst().Write("Bands: " + StringTools::ToString(header->bands)); header->projection = std::string(gdalDataset->GetProjectionRef()); Log::Inst().Write("Projection: " + header->projection); double adfGeoTransform[6]; gdalDataset->GetGeoTransform( adfGeoTransform ); header->originX = adfGeoTransform[0]; header->originY = adfGeoTransform[3]; Log::Inst().Write("Origin: " + StringTools::ToString(adfGeoTransform[0]) + ", " + StringTools::ToString(adfGeoTransform[3])); header->pixelSizeX = adfGeoTransform[1]; header->pixelSizeY = adfGeoTransform[5]; Log::Inst().Write("Pixel Size: " + StringTools::ToString(adfGeoTransform[1]) + ", " + StringTools::ToString(adfGeoTransform[5])); GDALRasterBand* gdalBand = gdalDataset->GetRasterBand(1); int nBlockXSize, nBlockYSize; gdalBand->GetBlockSize(&nBlockXSize, &nBlockYSize); header->dataType = std::string(GDALGetDataTypeName(gdalBand->GetRasterDataType())); Log::Inst().Write("Block, Type: " + StringTools::ToString(nBlockXSize) + ", " + StringTools::ToString(nBlockYSize) + ", " + std::string(header->dataType)); header->colourInterpretation = std::string(GDALGetColorInterpretationName(gdalBand->GetColorInterpretation())); Log::Inst().Write("Color Interpretation: " + header->colourInterpretation); header->extents.x = adfGeoTransform[0]; header->extents.y = adfGeoTransform[3] + gdalBand->GetYSize()*adfGeoTransform[5]; Log::Inst().Write("Lower, Left (x,y): " + StringTools::ToString(header->extents.x) + ", " + StringTools::ToString(header->extents.y)); header->extents.dx = adfGeoTransform[0]+gdalBand->GetXSize()*adfGeoTransform[1]; header->extents.dy = adfGeoTransform[3]; Log::Inst().Write("Upper, Right (x,y): " + StringTools::ToString(header->extents.dx) + ", " + StringTools::ToString(header->extents.dy)); Log::Inst().Write(""); }
bool getRawValuesFromFile(string fname,vector<vector<float>>& vecs) { //vector<float> temp = vector<float>() GDALDataset *poDataset; GDALAllRegister(); poDataset= (GDALDataset*) GDALOpen(fname.c_str(),GA_ReadOnly); if(poDataset == NULL) { cout << "OUCH!" << endl; return false; } cout << "Data size: " << GDALGetRasterXSize(poDataset) << " " << GDALGetRasterYSize(poDataset) << endl; GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; poBand = poDataset->GetRasterBand( 1 ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); int width = poBand->GetXSize(); int height = poBand->GetYSize(); int bands = poDataset->GetRasterCount(); float *pafScanline; std::cout << "Before allocation" << adfMinMax[0] << " " << adfMinMax[1] << endl; int dsize = 256; pafScanline = (float *) CPLMalloc(sizeof(float)*width*height); vector<vector<float>> out = vector<vector<float>>(height,vector<float> (width,0)); poBand->RasterIO(GF_Read,0,0,width,height,pafScanline,width,height,GDT_Float32,0,0); cout << "After allocation" << endl; for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { //cout << i << j << endl << pafS; out[i][j] = pafScanline[i*width+j]; } } CPLFree(pafScanline); //for(auto i : out) //for(auto j : i) // cout << j << endl; cout << "After allocation" << endl; vecs = out; return true; }
int main() { GDALDataset *poDataset; GDALAllRegister(); poDataset = (GDALDataset *) GDALOpen( "GE01.tif", GA_ReadOnly ); printf("Working! \n"); if( poDataset != NULL ){ //Get Dataset Information double adfGeoTransform[6]; printf( "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); printf( "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() ); if( poDataset->GetProjectionRef() != NULL ) printf( "Projection is `%s'\n", poDataset->GetProjectionRef() ); if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ){ printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } //Fetch Raster Band GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; poBand = poDataset->GetRasterBand( 1 ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] ); if( poBand->GetOverviewCount() > 0 ) printf( "Band has %d overviews.\n", poBand->GetOverviewCount() ); if( poBand->GetColorTable() != NULL ) printf( "Band has a color table with %d entries.\n", poBand->GetColorTable()->GetColorEntryCount() ); //Close Dataset GDALClose(poDataset); //Exit return 0; } }
void bin2ascii(char *binFile, char *asciiFile){ GDALDataset *layer; GDALAllRegister(); layer = (GDALDataset *)GDALOpen(binFile, GA_ReadOnly); int bandNumber = 1; GDALRasterBand *band = layer->GetRasterBand(bandNumber); GDALDataType type = band->GetRasterDataType(); double ranges[6]; layer->GetGeoTransform(ranges); ofstream outFile; outFile.open(asciiFile); outFile<<"ncols "<<layer->GetRasterXSize()<<"\n"; outFile<<"nrows "<<layer->GetRasterYSize()<<"\n"; outFile<<"xllcorner "<<ranges[0]<<"\n"; outFile<<"yllcorner "<<(ranges[3] + layer->GetRasterXSize() * ranges[4] + layer->GetRasterYSize() * ranges[5])<<"\n"; outFile<<"cellsize " <<ranges[1]<<"\n"; outFile<<"nodata_value "<<"-9999"<<"\n"; //getchar(); getchar(); int cols = layer->GetRasterXSize(); int rows = layer->GetRasterYSize(); double NODATA_VAL = band->GetNoDataValue(); cout<<"NODATA_VALUE= "<<NODATA_VAL<<"\n"; int size = GDALGetDataTypeSize(type) / 8; void *data = CPLMalloc(size); //CPLErr err = band->RasterIO(GF_Read, 0, 0, cols, rows, data, cols, rows, type, 0, 0); //getchar(); getchar(); //for(int j=0; j<rows*cols; j++){ //int col, row; for(int row=0; row<rows; row++){ for(int col=0; col<cols; col++){ CPLErr err = band->RasterIO(GF_Read, col, row, 1, 1, data, 1, 1, type, 0, 0); double tempVal = readValueB2A(data, type, 0); outFile<<( tempVal != NODATA_VAL ? tempVal : -9999)<<" "; //if((j+1)%cols == 0){ // cout<<"\n"; //getchar(); getchar(); // } } outFile<<"\n"; //getchar(); } cout<<"Bin2Ascii.. Done!\n"; outFile.close(); //getchar(); getchar(); }
GDALDataType peekGDALType(const std::string &filename) { GDALAllRegister(); GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly); assert(fin!=NULL); GDALRasterBand *band = fin->GetRasterBand(1); GDALDataType data_type = band->GetRasterDataType(); GDALClose(fin); return data_type; }
int NBHeightMapper::loadTiff(const std::string& file) { #ifdef HAVE_GDAL GDALAllRegister(); GDALDataset* poDataset = (GDALDataset*)GDALOpen(file.c_str(), GA_ReadOnly); if (poDataset == 0) { WRITE_ERROR("Cannot load GeoTIFF file."); return 0; } const int xSize = poDataset->GetRasterXSize(); const int ySize = poDataset->GetRasterYSize(); double adfGeoTransform[6]; if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) { Position topLeft(adfGeoTransform[0], adfGeoTransform[3]); mySizeOfPixel.set(adfGeoTransform[1], adfGeoTransform[5]); const double horizontalSize = xSize * mySizeOfPixel.x(); const double verticalSize = ySize * mySizeOfPixel.y(); myBoundary.add(topLeft); myBoundary.add(topLeft.x() + horizontalSize, topLeft.y() + verticalSize); } else { WRITE_ERROR("Could not parse geo information from " + file + "."); return 0; } const int picSize = xSize * ySize; myRaster = (int16_t*)CPLMalloc(sizeof(int16_t) * picSize); for (int i = 1; i <= poDataset->GetRasterCount(); i++) { GDALRasterBand* poBand = poDataset->GetRasterBand(i); if (poBand->GetColorInterpretation() != GCI_GrayIndex) { WRITE_ERROR("Unknown color band in " + file + "."); clearData(); break; } if (poBand->GetRasterDataType() != GDT_Int16) { WRITE_ERROR("Unknown data type in " + file + "."); clearData(); break; } assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize()); if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, myRaster, xSize, ySize, GDT_Int16, 0, 0) == CE_Failure) { WRITE_ERROR("Failure in reading " + file + "."); clearData(); break; } } GDALClose(poDataset); return picSize; #else UNUSED_PARAMETER(file); WRITE_ERROR("Cannot load GeoTIFF file since SUMO was compiled without GDAL support."); return 0; #endif }
/** @brief Determine data type of a GDAL file's first layer @author Richard Barnes ([email protected]) @param[in] filename Filename of file whose type should be determined */ GDALDataType peekGDALType(const std::string &filename) { GDALAllRegister(); GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly); if(fin==NULL) throw std::runtime_error("Unable to open file '"+filename+"'!"); GDALRasterBand *band = fin->GetRasterBand(1); GDALDataType data_type = band->GetRasterDataType(); GDALClose(fin); return data_type; }
SEXP RGDAL_GetBandType(SEXP sxpRasterBand) { SEXP ans; GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand); PROTECT(ans = NEW_INTEGER(1)); installErrorHandler(); INTEGER_POINTER(ans)[0] = (int) pRasterBand->GetRasterDataType(); uninstallErrorHandlerAndTriggerError(); UNPROTECT(1); return(ans); }
void HazePerfection::invertImage(GDALDataset *pDataset, GDALDataset *dstDataset, float a) { GDALRasterBand *band = pDataset->GetRasterBand(1); GDALDataType dataType = band->GetRasterDataType(); float *pixelData = new float[nXSize*nYSize]; band->RasterIO(GF_Read, 0, 0, nXSize, nYSize, pixelData, nXSize, nYSize, GDT_Float32, 0, 0); GDALRasterBand *dstBand = dstDataset->GetRasterBand(1); for (int j = 0; j < nYSize; j++) { for (int i = 0; i < nXSize; i++) { pixelData[j*nXSize + i] = a - pixelData[j*nXSize + i]; } } dstBand->RasterIO(GF_Write, 0, 0, nXSize, nYSize, pixelData, nXSize, nYSize, GDT_Float32, 0, 0); delete[]pixelData; }
wxGISRasterLayer::wxGISRasterLayer(const wxString &sName, wxGISDataset* pwxGISDataset) : wxGISLayer(sName, pwxGISDataset) { wxGISRasterDataset* pwxGISRasterDataset = wxDynamicCast(pwxGISDataset, wxGISRasterDataset); if(pwxGISRasterDataset) { if(m_sName.IsEmpty()) m_sName = pwxGISRasterDataset->GetName(); m_SpatialReference = pwxGISRasterDataset->GetSpatialReference(); m_FullEnvelope = pwxGISRasterDataset->GetEnvelope(); //TODO: load or get all renderers and check if i render can draw this dataset. If yes - set it as current if(pwxGISRasterDataset->GetBandCount() >= 3) { m_pRenderer = new wxGISRasterRGBARenderer(pwxGISDataset); } else { GDALDataset* poGDALDataset = pwxGISRasterDataset->GetMainRaster(); if(!poGDALDataset) poGDALDataset = pwxGISRasterDataset->GetRaster(); if(!poGDALDataset) return; GDALRasterBand* pBand = poGDALDataset->GetRasterBand(1); GDALColorInterp eColorInterpretation = pBand->GetColorInterpretation(); if( eColorInterpretation == GCI_PaletteIndex ) { m_pRenderer = new wxGISRasterRasterColormapRenderer(pwxGISDataset); } else if(pBand->GetRasterDataType() == GDT_Int32) { m_pRenderer = new wxGISRasterPackedRGBARenderer(pwxGISDataset); } else// if( eColorInterpretation == GCI_GrayIndex ) { //TODO: else RasterStretchColorRampRenderer m_pRenderer = new wxGISRasterGreyScaleRenderer(pwxGISDataset); } } } }
void loadGDAL(const std::string &filename, int xOffset=0, int yOffset=0, int part_width=0, int part_height=0){ assert(empty()); assert(xOffset>=0); assert(yOffset>=0); GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly); assert(fin!=NULL); GDALRasterBand *band = fin->GetRasterBand(1); auto data_type = band->GetRasterDataType(); total_width = band->GetXSize(); total_height = band->GetYSize(); no_data = band->GetNoDataValue(); if(xOffset+part_width>=total_width) part_width = total_width-xOffset; if(yOffset+part_height>=total_height) part_height = total_height-yOffset; if(part_width==0) part_width = total_width; view_width = part_width; if(part_height==0) part_height = total_height; view_height = part_height; view_xoff = xOffset; view_yoff = yOffset; std::cerr<<"Allocating: "<<view_height<<" rows by "<<view_width<<" columns"<<std::endl; data = InternalArray(view_height, Row(view_width)); for(int y=yOffset;y<yOffset+view_height;y++) band->RasterIO( GF_Read, xOffset, y, view_width, 1, data[y-yOffset].data(), view_width, 1, data_type, 0, 0 ); GDALClose(fin); }
GDALDatasetH CPL_STDCALL GDALCreateWarpedVRT( GDALDatasetH hSrcDS, int nPixels, int nLines, double *padfGeoTransform, GDALWarpOptions *psOptions ) { VALIDATE_POINTER1( hSrcDS, "GDALCreateWarpedVRT", NULL ); /* -------------------------------------------------------------------- */ /* Create the VRTDataset and populate it with bands. */ /* -------------------------------------------------------------------- */ VRTWarpedDataset *poDS = new VRTWarpedDataset( nPixels, nLines ); int i; psOptions->hDstDS = (GDALDatasetH) poDS; poDS->SetGeoTransform( padfGeoTransform ); for( i = 0; i < psOptions->nBandCount; i++ ) { VRTWarpedRasterBand *poBand; GDALRasterBand *poSrcBand = (GDALRasterBand *) GDALGetRasterBand( hSrcDS, i+1 ); poDS->AddBand( poSrcBand->GetRasterDataType(), NULL ); poBand = (VRTWarpedRasterBand *) poDS->GetRasterBand( i+1 ); poBand->CopyCommonInfoFrom( poSrcBand ); } /* -------------------------------------------------------------------- */ /* Initialize the warp on the VRTWarpedDataset. */ /* -------------------------------------------------------------------- */ poDS->Initialize( psOptions ); return (GDALDatasetH) poDS; }
/** @brief Retrieve height, width, data type, and geotransform from a GDAL file @author Richard Barnes ([email protected]) @param[in] filename GDAL file to peek at @param[out] height Height of the raster in cells @param[out] width Width of the raster in cells @param[out] dtype Data type of the file in question @param[out] geo_trans Returns the SIX elements of the raster's geotransform */ void getGDALDimensions( const std::string &filename, int32_t &height, int32_t &width, GDALDataType &dtype, double geotransform[6] ){ GDALAllRegister(); GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly); if(fin==NULL) throw std::runtime_error("Could not open file '"+filename+"' to get dimensions."); GDALRasterBand *band = fin->GetRasterBand(1); dtype = band->GetRasterDataType(); if(geotransform!=NULL && fin->GetGeoTransform(geotransform)!=CE_None) throw std::runtime_error("Error getting geotransform from '"+filename+"'."); height = band->GetYSize(); width = band->GetXSize(); GDALClose(fin); }
void generateTexture(string fname, GLuint& tex, int bandnum) { if(bandnum <= 0 ) { bandnum = 1; } GDALDataset *poDataset; GDALAllRegister(); poDataset= (GDALDataset*) GDALOpen(fname.c_str(),GA_ReadOnly); if(poDataset == NULL) { cout << "OUCH!" << endl; //exit(0); return; } cout << "Data size: " << GDALGetRasterXSize(poDataset) << " " << GDALGetRasterYSize(poDataset) << endl; GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; int bands = poDataset->GetRasterCount(); bandnum = bandnum % bands + 1; if(bandnum > bands) { bandnum = 1; } poBand = poDataset->GetRasterBand( bandnum ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); float max = adfMinMax[0] = poBand->GetMinimum( &bGotMin ); float min = adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); int width = poBand->GetXSize(); int height = poBand->GetYSize(); float *pafScanline; std::cout << "Before allocation" << adfMinMax[0] << " " << adfMinMax[1] << endl; min = adfMinMax[0]; max = adfMinMax[1]; int dsize = 256; pafScanline = (float *) CPLMalloc(sizeof(float)*512*512); vector<vector<float>> out = vector<vector<float>>(height,vector<float> (width,0)); //vector<vector<unsigned char>> texs = vector<vector<unsigned char>>(height,vector<unsigned char> (width,0)); unsigned char texs[512*512]; poBand->RasterIO(GF_Read,0,0,width,height,pafScanline,512,512,GDT_Float32,0,0); float no = poBand->GetNoDataValue(); cout << "After allocation" << endl; for(int i = 0; i < 512; i++) { for(int j = 0; j < 512; j++) { //cout << i << j << endl << pafS; if(pafScanline[i*width+j] != no) { // set tex val texs[i*512+j] = (unsigned char)(255*((pafScanline[i*512+j] - min)/(max-min))); //if((int)texs[i*width] < 0) //cout << (int)texs[i*512 +j] << " " << pafScanline[i*512+j] << " " << no << " " << fname << " " << min << " " << max << endl; } else { // Set zero val texs[i*512+j] = 0; //cout << (int)texs[i*512 +j] << fname << endl; } //texs[i*512+j] = 255; //ut[i][j] = pafScanline[i*width+j]; } } CPLFree(pafScanline); //exit(0); // Create a texture glGenTextures(1,&tex); glBindTexture(GL_TEXTURE_2D,tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512,512, 0, GL_RED, GL_UNSIGNED_BYTE,texs); GDALClose( (GDALDatasetH) poDataset); return; }
static GDALDataset * GMTCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, CPL_UNUSED char ** papszOptions, CPL_UNUSED GDALProgressFunc pfnProgress, CPL_UNUSED void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Figure out general characteristics. */ /* -------------------------------------------------------------------- */ nc_type nc_datatype; GDALRasterBand *poBand; int nXSize, nYSize; CPLMutexHolderD(&hNCMutex); if( poSrcDS->GetRasterCount() != 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Currently GMT export only supports 1 band datasets." ); return NULL; } poBand = poSrcDS->GetRasterBand(1); nXSize = poSrcDS->GetRasterXSize(); nYSize = poSrcDS->GetRasterYSize(); if( poBand->GetRasterDataType() == GDT_Int16 ) nc_datatype = NC_SHORT; else if( poBand->GetRasterDataType() == GDT_Int32 ) nc_datatype = NC_INT; else if( poBand->GetRasterDataType() == GDT_Float32 ) nc_datatype = NC_FLOAT; else if( poBand->GetRasterDataType() == GDT_Float64 ) nc_datatype = NC_DOUBLE; else if( bStrict ) { CPLError( CE_Failure, CPLE_AppDefined, "Band data type %s not supported in GMT, giving up.", GDALGetDataTypeName( poBand->GetRasterDataType() ) ); return NULL; } else if( poBand->GetRasterDataType() == GDT_Byte ) nc_datatype = NC_SHORT; else if( poBand->GetRasterDataType() == GDT_UInt16 ) nc_datatype = NC_INT; else if( poBand->GetRasterDataType() == GDT_UInt32 ) nc_datatype = NC_INT; else nc_datatype = NC_FLOAT; /* -------------------------------------------------------------------- */ /* Establish bounds from geotransform. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; double dfXMax, dfYMin; poSrcDS->GetGeoTransform( adfGeoTransform ); if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 ) { CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_AppDefined, "Geotransform has rotational coefficients not supported in GMT." ); if( bStrict ) return NULL; } dfXMax = adfGeoTransform[0] + adfGeoTransform[1] * nXSize; dfYMin = adfGeoTransform[3] + adfGeoTransform[5] * nYSize; /* -------------------------------------------------------------------- */ /* Create base file. */ /* -------------------------------------------------------------------- */ int cdfid, err; err = nc_create (pszFilename, NC_CLOBBER,&cdfid); if( err != NC_NOERR ) { CPLError( CE_Failure, CPLE_AppDefined, "nc_create(%s): %s", pszFilename, nc_strerror( err ) ); return NULL; } /* -------------------------------------------------------------------- */ /* Define the dimensions and so forth. */ /* -------------------------------------------------------------------- */ int side_dim, xysize_dim, dims[1]; int x_range_id, y_range_id, z_range_id, inc_id, nm_id, z_id; nc_def_dim(cdfid, "side", 2, &side_dim); nc_def_dim(cdfid, "xysize", (int) (nXSize * nYSize), &xysize_dim); dims[0] = side_dim; nc_def_var (cdfid, "x_range", NC_DOUBLE, 1, dims, &x_range_id); nc_def_var (cdfid, "y_range", NC_DOUBLE, 1, dims, &y_range_id); nc_def_var (cdfid, "z_range", NC_DOUBLE, 1, dims, &z_range_id); nc_def_var (cdfid, "spacing", NC_DOUBLE, 1, dims, &inc_id); nc_def_var (cdfid, "dimension", NC_LONG, 1, dims, &nm_id); dims[0] = xysize_dim; nc_def_var (cdfid, "z", nc_datatype, 1, dims, &z_id); /* -------------------------------------------------------------------- */ /* Assign attributes. */ /* -------------------------------------------------------------------- */ double default_scale = 1.0; double default_offset = 0.0; int default_node_offset = 1; // pixel is area nc_put_att_text (cdfid, x_range_id, "units", 7, "meters"); nc_put_att_text (cdfid, y_range_id, "units", 7, "meters"); nc_put_att_text (cdfid, z_range_id, "units", 7, "meters"); nc_put_att_double (cdfid, z_id, "scale_factor", NC_DOUBLE, 1, &default_scale ); nc_put_att_double (cdfid, z_id, "add_offset", NC_DOUBLE, 1, &default_offset ); nc_put_att_int (cdfid, z_id, "node_offset", NC_LONG, 1, &default_node_offset ); nc_put_att_text (cdfid, NC_GLOBAL, "title", 1, ""); nc_put_att_text (cdfid, NC_GLOBAL, "source", 1, ""); /* leave define mode */ nc_enddef (cdfid); /* -------------------------------------------------------------------- */ /* Get raster min/max. */ /* -------------------------------------------------------------------- */ double adfMinMax[2]; GDALComputeRasterMinMax( (GDALRasterBandH) poBand, FALSE, adfMinMax ); /* -------------------------------------------------------------------- */ /* Set range variables. */ /* -------------------------------------------------------------------- */ size_t start[2], edge[2]; double dummy[2]; int nm[2]; start[0] = 0; edge[0] = 2; dummy[0] = adfGeoTransform[0]; dummy[1] = dfXMax; nc_put_vara_double(cdfid, x_range_id, start, edge, dummy); dummy[0] = dfYMin; dummy[1] = adfGeoTransform[3]; nc_put_vara_double(cdfid, y_range_id, start, edge, dummy); dummy[0] = adfGeoTransform[1]; dummy[1] = -adfGeoTransform[5]; nc_put_vara_double(cdfid, inc_id, start, edge, dummy); nm[0] = nXSize; nm[1] = nYSize; nc_put_vara_int(cdfid, nm_id, start, edge, nm); nc_put_vara_double(cdfid, z_range_id, start, edge, adfMinMax); /* -------------------------------------------------------------------- */ /* Write out the image one scanline at a time. */ /* -------------------------------------------------------------------- */ double *padfData; int iLine; padfData = (double *) CPLMalloc( sizeof(double) * nXSize ); edge[0] = nXSize; for( iLine = 0; iLine < nYSize; iLine++ ) { start[0] = iLine * nXSize; poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, padfData, nXSize, 1, GDT_Float64, 0, 0, NULL ); err = nc_put_vara_double( cdfid, z_id, start, edge, padfData ); if( err != NC_NOERR ) { CPLError( CE_Failure, CPLE_AppDefined, "nc_put_vara_double(%s): %s", pszFilename, nc_strerror( err ) ); nc_close (cdfid); return( NULL ); } } CPLFree( padfData ); /* -------------------------------------------------------------------- */ /* Close file, and reopen. */ /* -------------------------------------------------------------------- */ nc_close (cdfid); /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxiliary pam information. */ /* -------------------------------------------------------------------- */ GDALPamDataset *poDS = (GDALPamDataset *) GDALOpen( pszFilename, GA_ReadOnly ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; }
CPLErr GTIFFBuildOverviews( const char * pszFilename, int nBands, GDALRasterBand **papoBandList, int nOverviews, int * panOverviewList, const char * pszResampling, GDALProgressFunc pfnProgress, void * pProgressData ) { TIFF *hOTIFF; int nBitsPerPixel=0, nCompression=COMPRESSION_NONE, nPhotometric=0; int nSampleFormat=0, nPlanarConfig, iOverview, iBand; int nXSize=0, nYSize=0; if( nBands == 0 || nOverviews == 0 ) return CE_None; if (!GTiffOneTimeInit()) return CE_Failure; /* -------------------------------------------------------------------- */ /* Verify that the list of bands is suitable for emitting in */ /* TIFF file. */ /* -------------------------------------------------------------------- */ for( iBand = 0; iBand < nBands; iBand++ ) { int nBandBits, nBandFormat; GDALRasterBand *hBand = papoBandList[iBand]; switch( hBand->GetRasterDataType() ) { case GDT_Byte: nBandBits = 8; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_UInt16: nBandBits = 16; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_Int16: nBandBits = 16; nBandFormat = SAMPLEFORMAT_INT; break; case GDT_UInt32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_Int32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_INT; break; case GDT_Float32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_IEEEFP; break; case GDT_Float64: nBandBits = 64; nBandFormat = SAMPLEFORMAT_IEEEFP; break; case GDT_CInt16: nBandBits = 32; nBandFormat = SAMPLEFORMAT_COMPLEXINT; break; case GDT_CInt32: nBandBits = 64; nBandFormat = SAMPLEFORMAT_COMPLEXINT; break; case GDT_CFloat32: nBandBits = 64; nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP; break; case GDT_CFloat64: nBandBits = 128; nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP; break; default: CPLAssert( FALSE ); return CE_Failure; } if( hBand->GetMetadataItem( "NBITS", "IMAGE_STRUCTURE" ) ) { nBandBits = atoi(hBand->GetMetadataItem("NBITS","IMAGE_STRUCTURE")); if( nBandBits == 1 && EQUALN(pszResampling,"AVERAGE_BIT2",12) ) nBandBits = 8; } if( iBand == 0 ) { nBitsPerPixel = nBandBits; nSampleFormat = nBandFormat; nXSize = hBand->GetXSize(); nYSize = hBand->GetYSize(); } else if( nBitsPerPixel != nBandBits || nSampleFormat != nBandFormat ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support a mixture of band" " data types." ); return CE_Failure; } else if( hBand->GetColorTable() != NULL ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " overviews of multiple colormapped bands." ); return CE_Failure; } else if( hBand->GetXSize() != nXSize || hBand->GetYSize() != nYSize ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " overviews of different sized bands." ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Use specified compression method. */ /* -------------------------------------------------------------------- */ const char *pszCompress = CPLGetConfigOption( "COMPRESS_OVERVIEW", NULL ); if( pszCompress != NULL && pszCompress[0] != '\0' ) { nCompression = GTIFFGetCompressionMethod(pszCompress, "COMPRESS_OVERVIEW"); if (nCompression < 0) return CE_Failure; } if( nCompression == COMPRESSION_JPEG && nBitsPerPixel > 8 ) { if( nBitsPerPixel > 16 ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " JPEG compressed overviews of nBitsPerPixel > 16." ); return CE_Failure; } nBitsPerPixel = 12; } /* -------------------------------------------------------------------- */ /* Figure out the planar configuration to use. */ /* -------------------------------------------------------------------- */ if( nBands == 1 ) nPlanarConfig = PLANARCONFIG_CONTIG; else nPlanarConfig = PLANARCONFIG_SEPARATE; const char* pszInterleave = CPLGetConfigOption( "INTERLEAVE_OVERVIEW", NULL ); if (pszInterleave != NULL && pszInterleave[0] != '\0') { if( EQUAL( pszInterleave, "PIXEL" ) ) nPlanarConfig = PLANARCONFIG_CONTIG; else if( EQUAL( pszInterleave, "BAND" ) ) nPlanarConfig = PLANARCONFIG_SEPARATE; else { CPLError( CE_Failure, CPLE_AppDefined, "INTERLEAVE_OVERVIEW=%s unsupported, value must be PIXEL or BAND. ignoring", pszInterleave ); } } /* -------------------------------------------------------------------- */ /* Figure out the photometric interpretation to use. */ /* -------------------------------------------------------------------- */ if( nBands == 3 ) nPhotometric = PHOTOMETRIC_RGB; else if( papoBandList[0]->GetColorTable() != NULL && !EQUALN(pszResampling,"AVERAGE_BIT2",12) ) { nPhotometric = PHOTOMETRIC_PALETTE; /* should set the colormap up at this point too! */ } else nPhotometric = PHOTOMETRIC_MINISBLACK; const char* pszPhotometric = CPLGetConfigOption( "PHOTOMETRIC_OVERVIEW", NULL ); if (pszPhotometric != NULL && pszPhotometric[0] != '\0') { if( EQUAL( pszPhotometric, "MINISBLACK" ) ) nPhotometric = PHOTOMETRIC_MINISBLACK; else if( EQUAL( pszPhotometric, "MINISWHITE" ) ) nPhotometric = PHOTOMETRIC_MINISWHITE; else if( EQUAL( pszPhotometric, "RGB" )) { nPhotometric = PHOTOMETRIC_RGB; } else if( EQUAL( pszPhotometric, "CMYK" )) { nPhotometric = PHOTOMETRIC_SEPARATED; } else if( EQUAL( pszPhotometric, "YCBCR" )) { nPhotometric = PHOTOMETRIC_YCBCR; /* Because of subsampling, setting YCBCR without JPEG compression leads */ /* to a crash currently. Would need to make GTiffRasterBand::IWriteBlock() */ /* aware of subsampling so that it doesn't overrun buffer size returned */ /* by libtiff */ if ( nCompression != COMPRESSION_JPEG ) { CPLError(CE_Failure, CPLE_NotSupported, "Currently, PHOTOMETRIC_OVERVIEW=YCBCR requires COMPRESS_OVERVIEW=JPEG"); return CE_Failure; } if (pszInterleave != NULL && pszInterleave[0] != '\0' && nPlanarConfig == PLANARCONFIG_SEPARATE) { CPLError(CE_Failure, CPLE_NotSupported, "PHOTOMETRIC_OVERVIEW=YCBCR requires INTERLEAVE_OVERVIEW=PIXEL"); return CE_Failure; } else { nPlanarConfig = PLANARCONFIG_CONTIG; } /* YCBCR strictly requires 3 bands. Not less, not more */ /* Issue an explicit error message as libtiff one is a bit cryptic : */ /* JPEGLib:Bogus input colorspace */ if ( nBands != 3 ) { CPLError(CE_Failure, CPLE_NotSupported, "PHOTOMETRIC_OVERVIEW=YCBCR requires a source raster with only 3 bands (RGB)"); return CE_Failure; } } else if( EQUAL( pszPhotometric, "CIELAB" )) { nPhotometric = PHOTOMETRIC_CIELAB; } else if( EQUAL( pszPhotometric, "ICCLAB" )) { nPhotometric = PHOTOMETRIC_ICCLAB; } else if( EQUAL( pszPhotometric, "ITULAB" )) { nPhotometric = PHOTOMETRIC_ITULAB; } else { CPLError( CE_Warning, CPLE_IllegalArg, "PHOTOMETRIC_OVERVIEW=%s value not recognised, ignoring.\n", pszPhotometric ); } } /* -------------------------------------------------------------------- */ /* Figure out the predictor value to use. */ /* -------------------------------------------------------------------- */ int nPredictor = PREDICTOR_NONE; if ( nCompression == COMPRESSION_LZW || nCompression == COMPRESSION_ADOBE_DEFLATE ) { const char* pszPredictor = CPLGetConfigOption( "PREDICTOR_OVERVIEW", NULL ); if( pszPredictor != NULL ) { nPredictor = atoi( pszPredictor ); } } /* -------------------------------------------------------------------- */ /* Create the file, if it does not already exist. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; VSILFILE* fpL = NULL; if( VSIStatExL( pszFilename, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 ) { /* -------------------------------------------------------------------- */ /* Compute the uncompressed size. */ /* -------------------------------------------------------------------- */ double dfUncompressedOverviewSize = 0; int nDataTypeSize = GDALGetDataTypeSize(papoBandList[0]->GetRasterDataType())/8; for( iOverview = 0; iOverview < nOverviews; iOverview++ ) { int nOXSize, nOYSize; nOXSize = (nXSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; nOYSize = (nYSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; dfUncompressedOverviewSize += nOXSize * ((double)nOYSize) * nBands * nDataTypeSize; } if( nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) { #ifndef BIGTIFF_SUPPORT CPLError( CE_Failure, CPLE_NotSupported, "The overview file would be larger than 4GB\n" "but this is the largest size a TIFF can be, and BigTIFF is unavailable.\n" "Creation failed." ); return CE_Failure; #endif } /* -------------------------------------------------------------------- */ /* Should the file be created as a bigtiff file? */ /* -------------------------------------------------------------------- */ const char *pszBIGTIFF = CPLGetConfigOption( "BIGTIFF_OVERVIEW", NULL ); if( pszBIGTIFF == NULL ) pszBIGTIFF = "IF_NEEDED"; int bCreateBigTIFF = FALSE; if( EQUAL(pszBIGTIFF,"IF_NEEDED") ) { if( nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) bCreateBigTIFF = TRUE; } else if( EQUAL(pszBIGTIFF,"IF_SAFER") ) { /* Look at the size of the base image and suppose that */ /* the added overview levels won't be more than 1/2 of */ /* the size of the base image. The theory says 1/3 of the */ /* base image size if the overview levels are 2, 4, 8, 16... */ /* Thus take 1/2 as the security margin for 1/3 */ double dfUncompressedImageSize = nXSize * ((double)nYSize) * nBands * nDataTypeSize; if( dfUncompressedImageSize * .5 > 4200000000.0 ) bCreateBigTIFF = TRUE; } else { bCreateBigTIFF = CSLTestBoolean( pszBIGTIFF ); if (!bCreateBigTIFF && nCompression == COMPRESSION_NONE && dfUncompressedOverviewSize > 4200000000.0 ) { CPLError( CE_Failure, CPLE_NotSupported, "The overview file will be larger than 4GB, so BigTIFF is necessary.\n" "Creation failed."); return CE_Failure; } } #ifndef BIGTIFF_SUPPORT if( bCreateBigTIFF ) { CPLError( CE_Warning, CPLE_NotSupported, "BigTIFF requested, but GDAL built without BigTIFF\n" "enabled libtiff, request ignored." ); bCreateBigTIFF = FALSE; } #endif if( bCreateBigTIFF ) CPLDebug( "GTiff", "File being created as a BigTIFF." ); fpL = VSIFOpenL( pszFilename, "w+" ); if( fpL == NULL ) hOTIFF = NULL; else hOTIFF = VSI_TIFFOpen( pszFilename, (bCreateBigTIFF) ? "w+8" : "w+", fpL ); if( hOTIFF == NULL ) { if( CPLGetLastErrorNo() == 0 ) CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create new tiff file `%s'\n" "failed in VSI_TIFFOpen().\n", pszFilename ); if( fpL != NULL ) VSIFCloseL(fpL); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Otherwise just open it for update access. */ /* -------------------------------------------------------------------- */ else { fpL = VSIFOpenL( pszFilename, "r+" ); if( fpL == NULL ) hOTIFF = NULL; else hOTIFF = VSI_TIFFOpen( pszFilename, "r+", fpL ); if( hOTIFF == NULL ) { if( CPLGetLastErrorNo() == 0 ) CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create new tiff file `%s'\n" "failed in VSI_TIFFOpen().\n", pszFilename ); if( fpL != NULL ) VSIFCloseL(fpL); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Do we have a palette? If so, create a TIFF compatible version. */ /* -------------------------------------------------------------------- */ unsigned short *panRed=NULL, *panGreen=NULL, *panBlue=NULL; if( nPhotometric == PHOTOMETRIC_PALETTE ) { GDALColorTable *poCT = papoBandList[0]->GetColorTable(); int nColorCount; if( nBitsPerPixel <= 8 ) nColorCount = 256; else nColorCount = 65536; panRed = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); panGreen = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); panBlue = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); for( int iColor = 0; iColor < nColorCount; iColor++ ) { GDALColorEntry sRGB; if( poCT->GetColorEntryAsRGB( iColor, &sRGB ) ) { panRed[iColor] = (unsigned short) (257 * sRGB.c1); panGreen[iColor] = (unsigned short) (257 * sRGB.c2); panBlue[iColor] = (unsigned short) (257 * sRGB.c3); } } } /* -------------------------------------------------------------------- */ /* Do we need some metadata for the overviews? */ /* -------------------------------------------------------------------- */ CPLString osMetadata; GDALDataset *poBaseDS = papoBandList[0]->GetDataset(); GTIFFBuildOverviewMetadata( pszResampling, poBaseDS, osMetadata ); /* -------------------------------------------------------------------- */ /* Loop, creating overviews. */ /* -------------------------------------------------------------------- */ int nOvrBlockXSize, nOvrBlockYSize; GTIFFGetOverviewBlockSize(&nOvrBlockXSize, &nOvrBlockYSize); for( iOverview = 0; iOverview < nOverviews; iOverview++ ) { int nOXSize, nOYSize; nOXSize = (nXSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; nOYSize = (nYSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; GTIFFWriteDirectory(hOTIFF, FILETYPE_REDUCEDIMAGE, nOXSize, nOYSize, nBitsPerPixel, nPlanarConfig, nBands, nOvrBlockXSize, nOvrBlockYSize, TRUE, nCompression, nPhotometric, nSampleFormat, nPredictor, panRed, panGreen, panBlue, 0, NULL, /* FIXME? how can we fetch extrasamples */ osMetadata ); } if (panRed) { CPLFree(panRed); CPLFree(panGreen); CPLFree(panBlue); panRed = panGreen = panBlue = NULL; } XTIFFClose( hOTIFF ); VSIFCloseL(fpL); fpL = NULL; /* -------------------------------------------------------------------- */ /* Open the overview dataset so that we can get at the overview */ /* bands. */ /* -------------------------------------------------------------------- */ GDALDataset *hODS; CPLErr eErr = CE_None; hODS = (GDALDataset *) GDALOpen( pszFilename, GA_Update ); if( hODS == NULL ) return CE_Failure; /* -------------------------------------------------------------------- */ /* Do we need to set the jpeg quality? */ /* -------------------------------------------------------------------- */ TIFF *hTIFF = (TIFF*) hODS->GetInternalHandle(NULL); if( nCompression == COMPRESSION_JPEG && CPLGetConfigOption( "JPEG_QUALITY_OVERVIEW", NULL ) != NULL ) { int nJpegQuality = atoi(CPLGetConfigOption("JPEG_QUALITY_OVERVIEW","75")); TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY, nJpegQuality ); GTIFFSetJpegQuality((GDALDatasetH)hODS, nJpegQuality); } /* -------------------------------------------------------------------- */ /* Loop writing overview data. */ /* -------------------------------------------------------------------- */ if (nCompression != COMPRESSION_NONE && nPlanarConfig == PLANARCONFIG_CONTIG && GDALDataTypeIsComplex(papoBandList[0]->GetRasterDataType()) == FALSE && papoBandList[0]->GetColorTable() == NULL && (EQUALN(pszResampling, "NEAR", 4) || EQUAL(pszResampling, "AVERAGE") || EQUAL(pszResampling, "GAUSS") || EQUAL(pszResampling, "CUBIC") || EQUAL(pszResampling, "CUBICSPLINE") || EQUAL(pszResampling, "LANCZOS") || EQUAL(pszResampling, "BILINEAR"))) { /* In the case of pixel interleaved compressed overviews, we want to generate */ /* the overviews for all the bands block by block, and not band after band, */ /* in order to write the block once and not loose space in the TIFF file */ GDALRasterBand ***papapoOverviewBands; papapoOverviewBands = (GDALRasterBand ***) CPLCalloc(sizeof(void*),nBands); for( iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { GDALRasterBand *hSrcBand = papoBandList[iBand]; GDALRasterBand *hDstBand = hODS->GetRasterBand( iBand+1 ); papapoOverviewBands[iBand] = (GDALRasterBand **) CPLCalloc(sizeof(void*),nOverviews); papapoOverviewBands[iBand][0] = hDstBand; int bHasNoData; double noDataValue = hSrcBand->GetNoDataValue(&bHasNoData); if (bHasNoData) hDstBand->SetNoDataValue(noDataValue); for( int i = 0; i < nOverviews-1 && eErr == CE_None; i++ ) { papapoOverviewBands[iBand][i+1] = hDstBand->GetOverview(i); if (papapoOverviewBands[iBand][i+1] == NULL) eErr = CE_Failure; else { if (bHasNoData) papapoOverviewBands[iBand][i+1]->SetNoDataValue(noDataValue); } } } if (eErr == CE_None) eErr = GDALRegenerateOverviewsMultiBand(nBands, papoBandList, nOverviews, papapoOverviewBands, pszResampling, pfnProgress, pProgressData ); for( iBand = 0; iBand < nBands; iBand++ ) { CPLFree(papapoOverviewBands[iBand]); } CPLFree(papapoOverviewBands); } else { GDALRasterBand **papoOverviews; papoOverviews = (GDALRasterBand **) CPLCalloc(sizeof(void*),128); for( iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { GDALRasterBand *hSrcBand = papoBandList[iBand]; GDALRasterBand *hDstBand; int nDstOverviews; hDstBand = hODS->GetRasterBand( iBand+1 ); int bHasNoData; double noDataValue = hSrcBand->GetNoDataValue(&bHasNoData); if (bHasNoData) hDstBand->SetNoDataValue(noDataValue); papoOverviews[0] = hDstBand; nDstOverviews = hDstBand->GetOverviewCount() + 1; CPLAssert( nDstOverviews < 128 ); nDstOverviews = MIN(128,nDstOverviews); for( int i = 0; i < nDstOverviews-1 && eErr == CE_None; i++ ) { papoOverviews[i+1] = hDstBand->GetOverview(i); if (papoOverviews[i+1] == NULL) eErr = CE_Failure; else { if (bHasNoData) papoOverviews[i+1]->SetNoDataValue(noDataValue); } } void *pScaledProgressData; pScaledProgressData = GDALCreateScaledProgress( iBand / (double) nBands, (iBand+1) / (double) nBands, pfnProgress, pProgressData ); if (eErr == CE_None) eErr = GDALRegenerateOverviews( (GDALRasterBandH) hSrcBand, nDstOverviews, (GDALRasterBandH *) papoOverviews, pszResampling, GDALScaledProgress, pScaledProgressData); GDALDestroyScaledProgress( pScaledProgressData ); } CPLFree( papoOverviews ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ if (eErr == CE_None) hODS->FlushCache(); delete hODS; pfnProgress( 1.0, NULL, pProgressData ); return eErr; }
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 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; }
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; }
std::tuple<boost::shared_ptr<Map_Matrix<DataFormat> >, std::string, GeoTransform> read_in_map(fs::path file_path, GDALDataType data_type, const bool doCategorise) throw(std::runtime_error) { std::string projection; GeoTransform transformation; GDALDriver driver; //Check that the file name is valid if (!(fs::is_regular_file(file_path))) { throw std::runtime_error("Input file is not a regular file"); } // Get GDAL to open the file - code is based on the tutorial at http://www.gdal.org/gdal_tutorial.html GDALDataset *poDataset; GDALAllRegister(); //This registers all availble raster file formats for use with this utility. How neat is that. We can input any GDAL supported rater file format. //Open the Raster by calling GDALOpen. http://www.gdal.org/gdal_8h.html#a6836f0f810396c5e45622c8ef94624d4 //char pszfilename[] = file_path.c_str(); //Set this to the file name, as GDALOpen requires the standard C char pointer as function parameter. poDataset = (GDALDataset *) GDALOpen (file_path.string().c_str(), GA_ReadOnly); if (poDataset == NULL) { throw std::runtime_error("Unable to open file"); } // Print some general information about the raster double adfGeoTransform[6]; //An array of doubles that will be used to save information about the raster - where the origin is, what the raster pizel size is. printf( "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); printf( "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() ); if( poDataset->GetProjectionRef() != NULL ) { printf( "Projection is `%s'\n", poDataset->GetProjectionRef() ); projection = poDataset->GetProjectionRef(); } if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); transformation.x_origin = adfGeoTransform[0]; transformation.pixel_width = adfGeoTransform[1]; transformation.x_line_space = adfGeoTransform[2]; transformation.y_origin = adfGeoTransform[3]; transformation.pixel_height = adfGeoTransform[4]; transformation.y_line_space = adfGeoTransform[5]; } /// Some raster file formats allow many layers of data (called a 'band', with each having the same pixel size and origin location and spatial extent). We will get the data for the first layer into a Boost Array. //Get the data from the first band, // TODO implement method with input to specify what band. GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; poBand = poDataset->GetRasterBand( 1 ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] ); if( poBand->GetOverviewCount() > 0 ) printf( "Band has %d overviews.\n", poBand->GetOverviewCount() ); if( poBand->GetColorTable() != NULL ) printf( "Band has a color table with %d entries.\n", poBand->GetColorTable()->GetColorEntryCount() ); DataFormat * pafScanline; int nXSize = poBand->GetXSize(); int nYSize = poBand->GetYSize(); boost::shared_ptr<Map_Matrix<DataFormat> > in_map(new Map_Matrix<DataFormat>(nYSize, nXSize)); //get a c array of this size and read into this. //pafScanline = new DataFormat[nXSize]; //for (int i = 0; i < nYSize; i++) //rows //{ // poBand->RasterIO(GF_Read, 0, i, nXSize, 1, // pafScanline, nXSize, 1, data_type, // 0, 0); // for (int j = 0; j < nXSize; j++) //cols // { // in_map->Get(i, j) = pafScanline[j]; // } //} //get a c array of this size and read into this. pafScanline = new DataFormat[nXSize * nYSize]; //pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize); poBand->RasterIO( GF_Read, 0, 0, nXSize, nYSize, pafScanline, nXSize, nYSize, data_type, 0, 0 ); //Copy into Map_Matrix. int pafIterator = 0; // Note: Map Matrixes indexes are in opposite order to C arrays. e.g. map matrix is indexed by (row, Col) which is (y, x) and c matrices are done by (x, y) which is (Col, Row) //for (int i = 0; i < nXSize; i++) //{ // for(int j = 0; j < nYSize; j++) // { // in_map->Get(j, i) = pafScanline[pafIterator]; // pafIterator++; // } //} for (int i = 0; i < nYSize; i++) //rows { for (int j = 0; j < nXSize; j++) //cols { in_map->Get(i, j) = pafScanline[pafIterator]; pafIterator++; } } //free the c array storage delete pafScanline; int pbsuccess; // can be used with get no data value in_map->SetNoDataValue(poBand->GetNoDataValue(&pbsuccess)); //This creates a list (map?) listing all the unique values contained in the raster. if (doCategorise) in_map->updateCategories(); //Close GDAL, freeing the memory GDAL is using GDALClose( (GDALDatasetH)poDataset); return (std::make_tuple(in_map, projection, transformation)); }
static GDALDataset * VRTCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int /* bStrict */, char ** /* papszOptions */, GDALProgressFunc /* pfnProgress */, void * /* pProgressData */ ) { CPLAssert( NULL != poSrcDS ); /* -------------------------------------------------------------------- */ /* If the source dataset is a virtual dataset then just write */ /* it to disk as a special case to avoid extra layers of */ /* indirection. */ /* -------------------------------------------------------------------- */ if( poSrcDS->GetDriver() != NULL && EQUAL(poSrcDS->GetDriver()->GetDescription(),"VRT") ) { /* -------------------------------------------------------------------- */ /* Convert tree to a single block of XML text. */ /* -------------------------------------------------------------------- */ char *pszVRTPath = CPLStrdup(CPLGetPath(pszFilename)); reinterpret_cast<VRTDataset *>( poSrcDS )->UnsetPreservedRelativeFilenames(); CPLXMLNode *psDSTree = reinterpret_cast<VRTDataset *>( poSrcDS )->SerializeToXML( pszVRTPath ); char *pszXML = CPLSerializeXMLTree( psDSTree ); CPLDestroyXMLNode( psDSTree ); CPLFree( pszVRTPath ); /* -------------------------------------------------------------------- */ /* Write to disk. */ /* -------------------------------------------------------------------- */ GDALDataset* pCopyDS = NULL; if( 0 != strlen( pszFilename ) ) { VSILFILE *fpVRT = VSIFOpenL( pszFilename, "wb" ); if( fpVRT == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create %s", pszFilename); CPLFree( pszXML ); return NULL; } bool bRet = VSIFWriteL( pszXML, strlen(pszXML), 1, fpVRT ) > 0; if( VSIFCloseL( fpVRT ) != 0 ) bRet = false; if( bRet ) pCopyDS = reinterpret_cast<GDALDataset *>( GDALOpen( pszFilename, GA_Update ) ); } else { /* No destination file is given, so pass serialized XML directly. */ pCopyDS = reinterpret_cast<GDALDataset *>( GDALOpen( pszXML, GA_Update ) ); } CPLFree( pszXML ); return pCopyDS; } /* -------------------------------------------------------------------- */ /* Create the virtual dataset. */ /* -------------------------------------------------------------------- */ VRTDataset *poVRTDS = reinterpret_cast<VRTDataset *>( VRTDataset::Create( pszFilename, poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize(), 0, GDT_Byte, NULL ) ); if( poVRTDS == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Do we have a geotransform? */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6] = { 0.0 }; if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None ) { poVRTDS->SetGeoTransform( adfGeoTransform ); } /* -------------------------------------------------------------------- */ /* Copy projection */ /* -------------------------------------------------------------------- */ poVRTDS->SetProjection( poSrcDS->GetProjectionRef() ); /* -------------------------------------------------------------------- */ /* Emit dataset level metadata. */ /* -------------------------------------------------------------------- */ poVRTDS->SetMetadata( poSrcDS->GetMetadata() ); /* -------------------------------------------------------------------- */ /* Copy any special domains that should be transportable. */ /* -------------------------------------------------------------------- */ char **papszMD = poSrcDS->GetMetadata( "RPC" ); if( papszMD ) poVRTDS->SetMetadata( papszMD, "RPC" ); papszMD = poSrcDS->GetMetadata( "IMD" ); if( papszMD ) poVRTDS->SetMetadata( papszMD, "IMD" ); papszMD = poSrcDS->GetMetadata( "GEOLOCATION" ); if( papszMD ) poVRTDS->SetMetadata( papszMD, "GEOLOCATION" ); /* -------------------------------------------------------------------- */ /* GCPs */ /* -------------------------------------------------------------------- */ if( poSrcDS->GetGCPCount() > 0 ) { poVRTDS->SetGCPs( poSrcDS->GetGCPCount(), poSrcDS->GetGCPs(), poSrcDS->GetGCPProjection() ); } /* -------------------------------------------------------------------- */ /* Loop over all the bands. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < poSrcDS->GetRasterCount(); iBand++ ) { GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 ); /* -------------------------------------------------------------------- */ /* Create the band with the appropriate band type. */ /* -------------------------------------------------------------------- */ poVRTDS->AddBand( poSrcBand->GetRasterDataType(), NULL ); VRTSourcedRasterBand *poVRTBand = reinterpret_cast<VRTSourcedRasterBand *>( poVRTDS->GetRasterBand( iBand+1 ) ); /* -------------------------------------------------------------------- */ /* Setup source mapping. */ /* -------------------------------------------------------------------- */ poVRTBand->AddSimpleSource( poSrcBand ); /* -------------------------------------------------------------------- */ /* Emit various band level metadata. */ /* -------------------------------------------------------------------- */ poVRTBand->CopyCommonInfoFrom( poSrcBand ); /* -------------------------------------------------------------------- */ /* Add specific mask band. */ /* -------------------------------------------------------------------- */ if( (poSrcBand->GetMaskFlags() & (GMF_PER_DATASET | GMF_ALL_VALID | GMF_NODATA)) == 0) { VRTSourcedRasterBand* poVRTMaskBand = new VRTSourcedRasterBand( poVRTDS, 0, poSrcBand->GetMaskBand()->GetRasterDataType(), poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize()); poVRTMaskBand->AddMaskBandSource( poSrcBand ); poVRTBand->SetMaskBand( poVRTMaskBand ); } } /* -------------------------------------------------------------------- */ /* Add dataset mask band */ /* -------------------------------------------------------------------- */ if( poSrcDS->GetRasterCount() != 0 && poSrcDS->GetRasterBand(1) != NULL && poSrcDS->GetRasterBand(1)->GetMaskFlags() == GMF_PER_DATASET ) { GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1); VRTSourcedRasterBand* poVRTMaskBand = new VRTSourcedRasterBand( poVRTDS, 0, poSrcBand->GetMaskBand()->GetRasterDataType(), poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize() ); poVRTMaskBand->AddMaskBandSource( poSrcBand ); poVRTDS->SetMaskBand( poVRTMaskBand ); } poVRTDS->FlushCache(); return poVRTDS; }
void readFrames( int argc, char* argv[] ) { pfs::DOMIO pfsio; bool verbose = false; // Parse command line parameters static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; static const char optstring[] = "hv"; pfs::FrameFileIterator it( argc, argv, "rb", NULL, NULL, optstring, cmdLineOptions ); int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, optstring, cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case 'v': verbose = true; break; case '?': throw QuietException(); case ':': throw QuietException(); } } GDALAllRegister(); GDALDataset *poDataset; GDALRasterBand *poBand; double adfGeoTransform[6]; size_t nBlockXSize, nBlockYSize, nBands; int bGotMin, bGotMax; double adfMinMax[2]; float *pafScanline; while( true ) { pfs::FrameFile ff = it.getNextFrameFile(); if( ff.fh == NULL ) break; // No more frames it.closeFrameFile( ff ); VERBOSE_STR << "reading file '" << ff.fileName << "'" << std::endl; if( !( poDataset = (GDALDataset *) GDALOpen( ff.fileName, GA_ReadOnly ) ) ) { std::cerr << "input does not seem to be in a format supported by GDAL" << std::endl; throw QuietException(); } VERBOSE_STR << "GDAL driver: " << poDataset->GetDriver()->GetDescription() << " / " << poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) << std::endl; nBlockXSize = poDataset->GetRasterXSize(); nBlockYSize = poDataset->GetRasterYSize(); nBands = poDataset->GetRasterCount(); VERBOSE_STR << "Data size " << nBlockXSize << "x" << nBlockYSize << "x" << nBands << std::endl; if( poDataset->GetProjectionRef() ) { VERBOSE_STR << "Projection " << poDataset->GetProjectionRef() << std::endl; } if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { VERBOSE_STR << "Origin = (" << adfGeoTransform[0] << ", " << adfGeoTransform[3] << ")" << std::endl; VERBOSE_STR << "Pixel Size = (" << adfGeoTransform[1] << ", " << adfGeoTransform[5] << ")" << std::endl; } if( nBlockXSize==0 || nBlockYSize==0 || ( SIZE_MAX / nBlockYSize < nBlockXSize ) || ( SIZE_MAX / (nBlockXSize * nBlockYSize ) < 4 ) ) { std::cerr << "input data has invalid size" << std::endl; throw QuietException(); } if( !(pafScanline = (float *) CPLMalloc( sizeof(float) * nBlockXSize ) ) ) { std::cerr << "not enough memory" << std::endl; throw QuietException(); } pfs::Frame *frame = pfsio.createFrame( nBlockXSize, nBlockYSize ); pfs::Channel *C[nBands]; char channel_name[32]; frame->getTags()->setString( "X-GDAL_DRIVER_SHORTNAME", poDataset->GetDriver()->GetDescription() ); frame->getTags()->setString( "X-GDAL_DRIVER_LONGNAME", poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); frame->getTags()->setString( "X-PROJECTION", poDataset->GetProjectionRef() ); if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { frame->getTags()->setString( "X-ORIGIN_X", stringify(adfGeoTransform[0]).c_str() ); frame->getTags()->setString( "X-ORIGIN_Y", stringify(adfGeoTransform[3]).c_str() ); frame->getTags()->setString( "X-PIXEL_WIDTH", stringify(adfGeoTransform[1]).c_str() ); frame->getTags()->setString( "X-PIXEL_HEIGHT", stringify(adfGeoTransform[5]).c_str() ); } for ( size_t band = 1; band <= nBands; band++) { size_t nBandXSize, nBandYSize; VERBOSE_STR << "Band " << band << ": " << std::endl; snprintf( channel_name, 32, "X-GDAL%zu", band ); C[band - 1] = frame->createChannel( channel_name ); poBand = poDataset->GetRasterBand( band ); nBandXSize = poBand->GetXSize(); nBandYSize = poBand->GetYSize(); VERBOSE_STR << " " << nBandXSize << "x" << nBandYSize << std::endl; if( nBandXSize != (int)nBlockXSize || nBandYSize != (int)nBlockYSize ) { std::cerr << "data in band " << band << " has different size" << std::endl; throw QuietException(); } VERBOSE_STR << " Type " << GDALGetDataTypeName( poBand->GetRasterDataType() ) << ", " << "Color Interpretation " << GDALGetColorInterpretationName( poBand->GetColorInterpretation() ) << std::endl; adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); if( ! (bGotMin && bGotMax) ) { GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); } VERBOSE_STR << " Min " << adfMinMax[0] << ", Max " << adfMinMax[1] << std::endl; C[band - 1]->getTags()->setString( "X-TYPE", GDALGetDataTypeName( poBand->GetRasterDataType() ) ); C[band - 1]->getTags()->setString( "X-COLOR_INTERPRETATION", GDALGetColorInterpretationName( poBand->GetColorInterpretation() ) ); C[band - 1]->getTags()->setString( "X-MIN", stringify(adfMinMax[0]).c_str() ); C[band - 1]->getTags()->setString( "X-MAX", stringify(adfMinMax[1]).c_str() ); for( size_t y = 0; y < nBlockYSize; y++ ) { if( poBand->RasterIO( GF_Read, 0, y, nBlockXSize, 1, pafScanline, nBlockXSize, 1, GDT_Float32, 0, 0) != CE_None ) { std::cerr << "input error" << std::endl; throw QuietException(); } memcpy( C[band - 1]->getRawData() + y * nBlockXSize, pafScanline, nBlockXSize * sizeof(float) ); } } CPLFree( pafScanline ); GDALClose( poDataset ); const char *fileNameTag = strcmp( "-", ff.fileName )==0 ? "stdin" : ff.fileName; frame->getTags()->setString( "FILE_NAME", fileNameTag ); pfsio.writeFrame( frame, stdout ); pfsio.freeFrame( frame ); } }
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(); }
int Image::scatterImageFileGDAL(const char * filename, int xOffset, int yOffset, PV::Communicator * comm, const PVLayerLoc * loc, float * buf, bool autoResizeFlag) { int status = 0; #ifdef PV_USE_GDAL // const int maxBands = 3; const int nxProcs = comm->numCommColumns(); const int nyProcs = comm->numCommRows(); const int icRank = comm->commRank(); const int nx = loc->nx; const int ny = loc->ny; const int numBands = loc->nf; int numTotal; // will be nx*ny*bandsInFile; const MPI_Comm mpi_comm = comm->communicator(); GDALDataType dataType; char** metadata; char isBinary = true; if (icRank > 0) { #ifdef PV_USE_MPI const int src = 0; const int tag = 13; MPI_Bcast(&dataType, 1, MPI_INT, 0, mpi_comm); MPI_Bcast(&isBinary, 1, MPI_CHAR, 0, mpi_comm); MPI_Bcast(&numTotal, 1, MPI_INT, 0, mpi_comm); #ifdef DEBUG_OUTPUT fprintf(stderr, "[%2d]: scatterImageFileGDAL: received from 0, total number of bytes in buffer is %d\n", numTotal); #endif // DEBUG_OUTPUT MPI_Recv(buf, numTotal, MPI_FLOAT, src, tag, mpi_comm, MPI_STATUS_IGNORE); #ifdef DEBUG_OUTPUT int nf=numTotal/(nx*ny); assert( nf*nx*ny == numTotal ); fprintf(stderr, "[%2d]: scatterImageFileGDAL: received from 0, nx==%d ny==%d nf==%d size==%d\n", comm->commRank(), nx, ny, nf, numTotal); #endif // DEBUG_OUTPUT #endif // PV_USE_MPI } else { GDALAllRegister(); GDALDataset * dataset = PV_GDALOpen(filename); // (GDALDataset *) GDALOpen(filename, GA_ReadOnly); GDALRasterBand * poBand = dataset->GetRasterBand(1); dataType = poBand->GetRasterDataType(); #ifdef PV_USE_MPI MPI_Bcast(&dataType, 1, MPI_INT, 0, mpi_comm); #endif // PV_USE_MPI // GDAL defines whether a band is binary, not whether the image as a whole is binary. // Set isBinary to false if any band is not binary (metadata doesn't have NBITS=1) for(int iBand = 0; iBand < GDALGetRasterCount(dataset); iBand++){ GDALRasterBandH hBand = GDALGetRasterBand(dataset, iBand+1); metadata = GDALGetMetadata(hBand, "Image_Structure"); if(CSLCount(metadata) > 0){ bool found = false; for(int i = 0; metadata[i] != NULL; i++){ if(strcmp(metadata[i], "NBITS=1") == 0){ found = true; break; } } if(!found){ isBinary = false; } } else{ isBinary = false; } } #ifdef PV_USE_MPI MPI_Bcast(&isBinary, 1, MPI_CHAR, 0, mpi_comm); #endif // PV_USE_MPI if (dataset==NULL) return 1; // PV_GDALOpen prints an error message. int xImageSize = dataset->GetRasterXSize(); int yImageSize = dataset->GetRasterYSize(); const int bandsInFile = dataset->GetRasterCount(); numTotal = nx * ny * bandsInFile; #ifdef PV_USE_MPI #ifdef DEBUG_OUTPUT fprintf(stderr, "[%2d]: scatterImageFileGDAL: broadcast from 0, total number of bytes in buffer is %d\n", numTotal); #endif // DEBUG_OUTPUT MPI_Bcast(&numTotal, 1, MPI_INT, 0, mpi_comm); #endif // PV_USE_MPI int xTotalSize = nx * nxProcs; int yTotalSize = ny * nyProcs; // if nf > bands of image, it will copy the gray image to each //band of layer assert(numBands == 1 || numBands == bandsInFile || (numBands > 1 && bandsInFile == 1)); int dest = -1; const int tag = 13; float padValue_conv; if(dataType == GDT_Byte){ padValue_conv = padValue * 255.0f; } else if(dataType == GDT_UInt16){ padValue_conv = padValue * 65535.0f; } else{ std::cout << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n"; exit(-1); } using std::min; using std::max; for( dest = nyProcs*nxProcs-1; dest >= 0; dest-- ) { //Need to clear buffer before reading, since we're skipping some of the buffer #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for(int i = 0; i < nx * ny * bandsInFile; i++){ //Fill with padValue buf[i] = padValue_conv; } int col = columnFromRank(dest,nyProcs,nxProcs); int row = rowFromRank(dest,nyProcs,nxProcs); int kx = nx * col; int ky = ny * row; //? For the auto resize flag, PV checks which side (x or y) is the shortest, relative to the //? hypercolumn size specified. Then it determines the largest chunk it can possibly take //? from the image with the correct aspect ratio determined by hypercolumn. It then //? determines the offset needed in the long dimension to center the cropped image, //? and reads in that portion of the image. The offset can optionally be translated by //? offset{X,Y} specified in the params file (values can be positive or negative). //? If the specified offset takes the cropped image outside the image file, it uses the //? largest-magnitude offset that stays within the image file's borders. if (autoResizeFlag){ if (xImageSize/(double)xTotalSize < yImageSize/(double)yTotalSize){ int new_y = int(round(ny*xImageSize/(double)xTotalSize)); int y_off = int(round((yImageSize - new_y*nyProcs)/2.0)); int jitter_y = max(min(y_off,yOffset),-y_off); kx = xImageSize/nxProcs * col; ky = new_y * row; //fprintf(stderr, "kx = %d, ky = %d, nx = %d, new_y = %d", kx, ky, xImageSize/nxProcs, new_y); dataset->RasterIO(GF_Read, kx, ky + y_off + jitter_y, xImageSize/nxProcs, new_y, buf, nx, ny, GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float)); } else{ int new_x = int(round(nx*yImageSize/(double)yTotalSize)); int x_off = int(round((xImageSize - new_x*nxProcs)/2.0)); int jitter_x = max(min(x_off,xOffset),-x_off); kx = new_x * col; ky = yImageSize/nyProcs * row; //fprintf(stderr, "kx = %d, ky = %d, new_x = %d, ny = %d, x_off = %d", kx, ky, new_x, yImageSize/nyProcs, x_off); dataset->RasterIO(GF_Read, kx + x_off + jitter_x, ky, new_x, yImageSize/nyProcs, buf, nx, ny, GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float),sizeof(float)); } }//End autoResizeFlag else { //Need to calculate corner image pixels in globalres space //offset is in Image space int img_left = -xOffset; int img_top = -yOffset; int img_right = img_left + xImageSize; int img_bot = img_top + yImageSize; //Check if in bounds if(img_left >= kx+nx || img_right <= kx || img_top >= ky+ny || img_bot <= ky){ //Do mpi_send to keep number of sends correct if(dest > 0){ MPI_Send(buf, numTotal, MPI_FLOAT, dest, tag, mpi_comm); } continue; } //start of the buffer on the left/top side int buf_left = img_left > kx ? img_left-kx : 0; int buf_top = img_top > ky ? img_top-ky : 0; int buf_right = img_right < kx+nx ? img_right-kx : nx; int buf_bot = img_bot < ky+ny ? img_bot-ky : ny; int buf_xSize = buf_right - buf_left; int buf_ySize = buf_bot - buf_top; assert(buf_xSize > 0 && buf_ySize > 0); int buf_offset = buf_top * nx * bandsInFile + buf_left * bandsInFile; int img_offset_x = kx+xOffset; int img_offset_y = ky+yOffset; if(img_offset_x < 0){ img_offset_x = 0; } if(img_offset_y < 0){ img_offset_y = 0; } float* buf_start = buf + buf_offset; dataset->RasterIO(GF_Read, img_offset_x, img_offset_y, buf_xSize, buf_ySize, buf_start, buf_xSize, buf_ySize, GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float)); } #ifdef DEBUG_OUTPUT fprintf(stderr, "[%2d]: scatterImageFileGDAL: sending to %d xSize==%d" " ySize==%d bandsInFile==%d size==%d total(over all procs)==%d\n", comm->commRank(), dest, nx, ny, bandsInFile, numTotal, nx*ny*comm->commSize()); #endif // DEBUG_OUTPUT #ifdef PV_USE_MPI if(dest > 0){ MPI_Send(buf, numTotal, MPI_FLOAT, dest, tag, mpi_comm); } #endif // PV_USE_MPI } GDALClose(dataset); //Moved to above for loop // get local image portion //? same logic as before, except this time we know that the row and column are 0 //if (autoResizeFlag){ // if (xImageSize/(double)xTotalSize < yImageSize/(double)yTotalSize){ // int new_y = int(round(ny*xImageSize/(double)xTotalSize)); // int y_off = int(round((yImageSize - new_y*nyProcs)/2.0)); // int offset_y = max(min(y_off,yOffset),-y_off); // //fprintf(stderr, "kx = %d, ky = %d, nx = %d, new_y = %d", 0, 0, xImageSize/nxProcs, new_y); // dataset->RasterIO(GF_Read, 0, y_off + offset_y, xImageSize/nxProcs, new_y, buf, nx, ny, // GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), // bandsInFile*nx*sizeof(float), sizeof(float)); // } // else{ // int new_x = int(round(nx*yImageSize/(double)yTotalSize)); // int x_off = int(round((xImageSize - new_x*nxProcs)/2.0)); // int offset_x = max(min(x_off,xOffset),-x_off); // //fprintf(stderr, "xImageSize = %d, xTotalSize = %d, yImageSize = %d, yTotalSize = %d", xImageSize, xTotalSize, yImageSize, yTotalSize); // //fprintf(stderr, "kx = %d, ky = %d, new_x = %d, ny = %d", // //0, 0, new_x, yImageSize/nyProcs); // dataset->RasterIO(GF_Read, x_off + offset_x, 0, new_x, yImageSize/nyProcs, buf, nx, ny, // GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), // bandsInFile*nx*sizeof(float),sizeof(float)); // } //} //else { // //fprintf(stderr,"just checking"); // dataset->RasterIO(GF_Read, xOffset, yOffset, nx, ny, buf, nx, ny, // GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float)); //} //GDALClose(dataset); } #else fprintf(stderr, GDAL_CONFIG_ERR_STR); exit(1); #endif // PV_USE_GDAL if (status == 0) { if(!isBinary){ float fac; if(dataType == GDT_Byte){ fac = 1.0f / 255.0f; // normalize to 1.0 } else if(dataType == GDT_UInt16){ fac = 1.0f / 65535.0f; // normalize to 1.0 } else{ std::cout << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n"; exit(-1); } for( int n=0; n<numTotal; n++ ) { buf[n] *= fac; } } } return status; }
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); }
GDALDataset * AAIGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int /* bStrict */, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { const int nBands = poSrcDS->GetRasterCount(); const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); // Some rudimentary checks. if( nBands != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "AAIG driver doesn't support %d bands. Must be 1 band.", nBands); return nullptr; } if( !pfnProgress(0.0, nullptr, pProgressData) ) return nullptr; // Create the dataset. VSILFILE *fpImage = VSIFOpenL(pszFilename, "wt"); if( fpImage == nullptr ) { CPLError(CE_Failure, CPLE_OpenFailed, "Unable to create file %s.", pszFilename); return nullptr; } // Write ASCII Grid file header. double adfGeoTransform[6] = {}; char szHeader[2000] = {}; const char *pszForceCellsize = CSLFetchNameValue(papszOptions, "FORCE_CELLSIZE"); poSrcDS->GetGeoTransform(adfGeoTransform); if( std::abs(adfGeoTransform[1] + adfGeoTransform[5]) < 0.0000001 || std::abs(adfGeoTransform[1]-adfGeoTransform[5]) < 0.0000001 || (pszForceCellsize && CPLTestBool(pszForceCellsize)) ) { CPLsnprintf( szHeader, sizeof(szHeader), "ncols %d\n" "nrows %d\n" "xllcorner %.12f\n" "yllcorner %.12f\n" "cellsize %.12f\n", nXSize, nYSize, adfGeoTransform[0], adfGeoTransform[3] - nYSize * adfGeoTransform[1], adfGeoTransform[1]); } else { if( pszForceCellsize == nullptr ) CPLError(CE_Warning, CPLE_AppDefined, "Producing a Golden Surfer style file with DX and DY " "instead of CELLSIZE since the input pixels are " "non-square. Use the FORCE_CELLSIZE=TRUE creation " "option to force use of DX for even though this will " "be distorted. Most ASCII Grid readers (ArcGIS " "included) do not support the DX and DY parameters."); CPLsnprintf( szHeader, sizeof(szHeader), "ncols %d\n" "nrows %d\n" "xllcorner %.12f\n" "yllcorner %.12f\n" "dx %.12f\n" "dy %.12f\n", nXSize, nYSize, adfGeoTransform[0], adfGeoTransform[3] + nYSize * adfGeoTransform[5], adfGeoTransform[1], fabs(adfGeoTransform[5])); } // Builds the format string used for printing float values. char szFormatFloat[32] = { '\0' }; strcpy(szFormatFloat, " %.20g"); const char *pszDecimalPrecision = CSLFetchNameValue(papszOptions, "DECIMAL_PRECISION"); const char *pszSignificantDigits = CSLFetchNameValue(papszOptions, "SIGNIFICANT_DIGITS"); bool bIgnoreSigDigits = false; if( pszDecimalPrecision && pszSignificantDigits ) { CPLError(CE_Warning, CPLE_AppDefined, "Conflicting precision arguments, using DECIMAL_PRECISION"); bIgnoreSigDigits = true; } int nPrecision; if ( pszSignificantDigits && !bIgnoreSigDigits ) { nPrecision = atoi(pszSignificantDigits); if (nPrecision >= 0) snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%dg", nPrecision); CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat); } else if( pszDecimalPrecision ) { nPrecision = atoi(pszDecimalPrecision); if ( nPrecision >= 0 ) snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%df", nPrecision); CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat); } // Handle nodata (optionally). GDALRasterBand *poBand = poSrcDS->GetRasterBand(1); const bool bReadAsInt = poBand->GetRasterDataType() == GDT_Byte || poBand->GetRasterDataType() == GDT_Int16 || poBand->GetRasterDataType() == GDT_UInt16 || poBand->GetRasterDataType() == GDT_Int32; // Write `nodata' value to header if it is exists in source dataset int bSuccess = FALSE; const double dfNoData = poBand->GetNoDataValue(&bSuccess); if ( bSuccess ) { snprintf(szHeader + strlen(szHeader), sizeof(szHeader) - strlen(szHeader), "%s", "NODATA_value "); if( bReadAsInt ) snprintf(szHeader + strlen(szHeader), sizeof(szHeader) - strlen(szHeader), "%d", static_cast<int>(dfNoData)); else CPLsnprintf(szHeader + strlen(szHeader), sizeof(szHeader) - strlen(szHeader), szFormatFloat, dfNoData); snprintf(szHeader + strlen(szHeader), sizeof(szHeader) - strlen(szHeader), "%s", "\n"); } if( VSIFWriteL(szHeader, strlen(szHeader), 1, fpImage) != 1) { CPL_IGNORE_RET_VAL(VSIFCloseL(fpImage)); return nullptr; } // Loop over image, copying image data. // Write scanlines to output file int *panScanline = bReadAsInt ? static_cast<int *>(CPLMalloc( nXSize * GDALGetDataTypeSizeBytes(GDT_Int32))) : nullptr; double *padfScanline = bReadAsInt ? nullptr : static_cast<double *>(CPLMalloc( nXSize * GDALGetDataTypeSizeBytes(GDT_Float64))); CPLErr eErr = CE_None; bool bHasOutputDecimalDot = false; for( int iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ ) { CPLString osBuf; eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, bReadAsInt ? reinterpret_cast<void *>(panScanline) : reinterpret_cast<void *>(padfScanline), nXSize, 1, bReadAsInt ? GDT_Int32 : GDT_Float64, 0, 0, nullptr); if( bReadAsInt ) { for ( int iPixel = 0; iPixel < nXSize; iPixel++ ) { snprintf(szHeader, sizeof(szHeader), " %d", panScanline[iPixel]); osBuf += szHeader; if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 ) { if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1, fpImage) != 1 ) { eErr = CE_Failure; CPLError(CE_Failure, CPLE_AppDefined, "Write failed, disk full?"); break; } osBuf = ""; } } } else { for ( int iPixel = 0; iPixel < nXSize; iPixel++ ) { CPLsnprintf(szHeader, sizeof(szHeader), szFormatFloat, padfScanline[iPixel]); // Make sure that as least one value has a decimal point (#6060) if( !bHasOutputDecimalDot ) { if( strchr(szHeader, '.') || strchr(szHeader, 'e') || strchr(szHeader, 'E') ) { bHasOutputDecimalDot = true; } else if( !CPLIsInf(padfScanline[iPixel]) && !CPLIsNan(padfScanline[iPixel]) ) { strcat(szHeader, ".0"); bHasOutputDecimalDot = true; } } osBuf += szHeader; if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 ) { if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1, fpImage) != 1 ) { eErr = CE_Failure; CPLError(CE_Failure, CPLE_AppDefined, "Write failed, disk full?"); break; } osBuf = ""; } } } if( VSIFWriteL("\n", 1, 1, fpImage) != 1 ) eErr = CE_Failure; if( eErr == CE_None && !pfnProgress((iLine + 1) / static_cast<double>(nYSize), nullptr, pProgressData) ) { eErr = CE_Failure; CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()"); } } CPLFree(panScanline); CPLFree(padfScanline); if( VSIFCloseL(fpImage) != 0 ) eErr = CE_Failure; if( eErr != CE_None ) return nullptr; // Try to write projection file. const char *pszOriginalProjection = poSrcDS->GetProjectionRef(); if( !EQUAL(pszOriginalProjection, "") ) { char *pszDirname = CPLStrdup(CPLGetPath(pszFilename)); char *pszBasename = CPLStrdup(CPLGetBasename(pszFilename)); char *pszPrjFilename = CPLStrdup(CPLFormFilename(pszDirname, pszBasename, "prj")); VSILFILE *fp = VSIFOpenL(pszPrjFilename, "wt"); if (fp != nullptr) { OGRSpatialReference oSRS; oSRS.importFromWkt(pszOriginalProjection); oSRS.morphToESRI(); char *pszESRIProjection = nullptr; oSRS.exportToWkt(&pszESRIProjection); CPL_IGNORE_RET_VAL(VSIFWriteL(pszESRIProjection, 1, strlen(pszESRIProjection), fp)); CPL_IGNORE_RET_VAL(VSIFCloseL(fp)); CPLFree(pszESRIProjection); } else { CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.", pszPrjFilename); } CPLFree(pszDirname); CPLFree(pszBasename); CPLFree(pszPrjFilename); } // Re-open dataset, and copy any auxiliary pam information. // If writing to stdout, we can't reopen it, so return // a fake dataset to make the caller happy. CPLPushErrorHandler(CPLQuietErrorHandler); GDALPamDataset *poDS = reinterpret_cast<GDALPamDataset *>(GDALOpen(pszFilename, GA_ReadOnly)); CPLPopErrorHandler(); if (poDS) { poDS->CloneInfo(poSrcDS, GCIF_PAM_DEFAULT); return poDS; } CPLErrorReset(); AAIGDataset *poAAIG_DS = new AAIGDataset(); poAAIG_DS->nRasterXSize = nXSize; poAAIG_DS->nRasterYSize = nYSize; poAAIG_DS->nBands = 1; poAAIG_DS->SetBand(1, new AAIGRasterBand(poAAIG_DS, 1)); return poAAIG_DS; }
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; }