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(); }
SEXP RGDAL_GetNoDataValue(SEXP sxpRasterBand) { GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand); int hasNoDataValue; double noDataValue = pRasterBand->GetNoDataValue(&hasNoDataValue); return(hasNoDataValue ? ScalarReal(noDataValue) : R_NilValue); }
feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt) { CPLErr raster_io_error = CE_None; if (band_ > 0) { unsigned raster_xsize = dataset_.GetRasterXSize(); unsigned raster_ysize = dataset_.GetRasterYSize(); double gt[6]; dataset_.GetGeoTransform(gt); double det = gt[1] * gt[5] - gt[2] * gt[4]; // subtract half a pixel width & height because gdal coord reference // is the top-left corner of a pixel, not the center. double X = pt.x - gt[0] - gt[1]/2; double Y = pt.y - gt[3] - gt[5]/2; double det1 = gt[1]*Y + gt[4]*X; double det2 = gt[2]*Y + gt[5]*X; unsigned x = static_cast<unsigned>(det2/det); unsigned y = static_cast<unsigned>(det1/det); if (x < raster_xsize && y < raster_ysize) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: pt.x=" << pt.x << " pt.y=" << pt.y; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: x=" << x << " y=" << y; GDALRasterBand* band = dataset_.GetRasterBand(band_); int raster_has_nodata; double nodata = band->GetNoDataValue(&raster_has_nodata); double value; raster_io_error = band->RasterIO(GF_Read, x, y, 1, 1, &value, 1, 1, GDT_Float64, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } if (! raster_has_nodata || value != nodata) { // construct feature feature_ptr feature = feature_factory::create(ctx_,1); feature->set_geometry(mapnik::geometry::point<double>(pt.x,pt.y)); feature->put_new("value",value); if (raster_has_nodata) { feature->put_new("nodata",nodata); } return feature; } } } return feature_ptr(); }
SEXP RGDAL_GetNoDataValue(SEXP sxpRasterBand) { GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand); int hasNoDataValue; installErrorHandler(); double noDataValue = pRasterBand->GetNoDataValue(&hasNoDataValue); uninstallErrorHandlerAndTriggerError(); return(hasNoDataValue ? ScalarReal(noDataValue) : R_NilValue); }
void getGDALHeader(const std::string &filename, int &height, int &width, T &no_data, double *geotrans){ GDALAllRegister(); GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly); assert(fin!=NULL); GDALRasterBand *band = fin->GetRasterBand(1); height = band->GetYSize(); no_data = band->GetNoDataValue(); width = band->GetXSize(); fin->GetGeoTransform(geotrans); GDALClose(fin); }
feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt) { if (band_ > 0) { unsigned raster_xsize = dataset_.GetRasterXSize(); unsigned raster_ysize = dataset_.GetRasterYSize(); double gt[6]; dataset_.GetGeoTransform(gt); double det = gt[1] * gt[5] - gt[2] * gt[4]; // subtract half a pixel width & height because gdal coord reference // is the top-left corner of a pixel, not the center. double X = pt.x - gt[0] - gt[1]/2; double Y = pt.y - gt[3] - gt[5]/2; double det1 = gt[1]*Y + gt[4]*X; double det2 = gt[2]*Y + gt[5]*X; unsigned x = static_cast<unsigned>(det2/det); unsigned y = static_cast<unsigned>(det1/det); if (x < raster_xsize && y < raster_ysize) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: pt.x=" << pt.x << " pt.y=" << pt.y; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: x=" << x << " y=" << y; GDALRasterBand* band = dataset_.GetRasterBand(band_); int raster_has_nodata; double nodata = band->GetNoDataValue(&raster_has_nodata); double value; band->RasterIO(GF_Read, x, y, 1, 1, &value, 1, 1, GDT_Float64, 0, 0); if (! raster_has_nodata || value != nodata) { // construct feature feature_ptr feature = feature_factory::create(ctx_,1); std::unique_ptr<geometry_type> point = std::make_unique<geometry_type>(mapnik::geometry_type::types::Point); point->move_to(pt.x, pt.y); feature->add_geometry(point.release()); feature->put_new("value",value); if (raster_has_nodata) { feature->put_new("nodata",nodata); } return feature; } } } return feature_ptr(); }
feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt) { if (band_ > 0) { unsigned raster_xsize = dataset_.GetRasterXSize(); unsigned raster_ysize = dataset_.GetRasterYSize(); double gt[6]; dataset_.GetGeoTransform(gt); double det = gt[1] * gt[5] - gt[2] * gt[4]; // subtract half a pixel width & height because gdal coord reference // is the top-left corner of a pixel, not the center. double X = pt.x - gt[0] - gt[1]/2; double Y = pt.y - gt[3] - gt[5]/2; double det1 = gt[1]*Y + gt[4]*X; double det2 = gt[2]*Y + gt[5]*X; unsigned x = det2/det, y = det1/det; if (x < raster_xsize && y < raster_ysize) { #ifdef MAPNIK_DEBUG std::clog << boost::format("GDAL Plugin: pt.x=%f pt.y=%f") % pt.x % pt.y << std::endl; std::clog << boost::format("GDAL Plugin: x=%f y=%f") % x % y << std::endl; #endif GDALRasterBand* band = dataset_.GetRasterBand(band_); int hasNoData; double nodata = band->GetNoDataValue(&hasNoData); double value; band->RasterIO(GF_Read, x, y, 1, 1, &value, 1, 1, GDT_Float64, 0, 0); if (! hasNoData || value != nodata) { // construct feature feature_ptr feature(new Feature(1)); geometry_type * point = new geometry_type(mapnik::Point); point->move_to(pt.x, pt.y); feature->add_geometry(point); (*feature)["value"] = value; return feature; } } } return feature_ptr(); }
SEXP RGDAL_GetBandNoDataValue(SEXP sxpRasterBand) { GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand); SEXP res; int hasNoDataValue; installErrorHandler(); double noDataValue = pRasterBand->GetNoDataValue(&hasNoDataValue); uninstallErrorHandlerAndTriggerError(); if (hasNoDataValue) { PROTECT(res = NEW_NUMERIC(1)); NUMERIC_POINTER(res)[0] = noDataValue; } else { return(R_NilValue); } UNPROTECT(1); return(res); }
void getGDALHeader( const std::string &filename, int32_t &height, int32_t &width, T &no_data, double geotransform[6] ){ GDALAllRegister(); GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly); if(fin==NULL) throw std::runtime_error("Could not get GDAL header: file '" + filename + "'' did not open!"); GDALRasterBand *band = fin->GetRasterBand(1); height = band->GetYSize(); no_data = band->GetNoDataValue(); width = band->GetXSize(); fin->GetGeoTransform(geotransform); GDALClose(fin); }
Dataset::ElevationDataPtr Dataset::convertToElevationData() const { if ( 0x0 == _data ) return 0x0; GDALRasterBand* band ( _data->GetRasterBand ( 1 ) ); if ( 0x0 == band ) return 0x0; // Get the width and height. const int width ( _data->GetRasterXSize() ); const int height ( _data->GetRasterYSize() ); // Read the values. const int size ( width * height ); std::vector<IElevationData::ValueType> bytes ( size, 0 ); if ( CE_None == band->RasterIO ( GF_Read, 0, 0, width, height, &bytes[0], width, height, GDT_Float32, 0, 0 ) ) { Minerva::Core::ElevationData::RefPtr elevationData ( new Minerva::Core::ElevationData ( width, height ) ); // The no data value. const double noDataValue ( band->GetNoDataValue() ); elevationData->noDataValue ( static_cast<IElevationData::ValueType> ( noDataValue ) ); for ( int row = 0; row < height; ++row ) { for ( int column = 0; column < width; ++column ) { const unsigned int index ( column + ( row * width ) ); elevationData->value ( column, ( height - row - 1 ), bytes.at ( index ) ); } } return ElevationDataPtr ( elevationData ); } return 0x0; }
int GDALFillBandNoData(GDALDataset *poDS, int nBand, int nSearchPixels) { (void)nBand; (void)nSearchPixels; if(poDS == NULL) { fprintf(stderr, "Invalid GDAL Dataset Handle, cannot fill no data\n"); return -1; } int nPixels, nLines; nPixels = poDS->GetRasterXSize(); nLines = poDS->GetRasterYSize(); GDALRasterBand *poBand; poBand = poDS->GetRasterBand(1); GDALFillNodata(poBand, NULL, 100, 0, 0, NULL, NULL, NULL); double dfNoData = poBand->GetNoDataValue(NULL); double *padfScanline; padfScanline = (double *) CPLMalloc(sizeof(double)*nPixels); int nNoDataCount = 0; for(int i = 0;i < nLines;i++) { GDALRasterIO(poBand, GF_Read, 0, i, nPixels, 1, padfScanline, nPixels, 1, GDT_Float64, 0, 0); for(int j = 0; j < nPixels;j++) { if(CPLIsEqual(padfScanline[j], dfNoData)) nNoDataCount++; } } CPLFree(padfScanline); return nNoDataCount; }
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); }
/** Check for no data values in a band for an image * @param poDS a pointer to a valid GDALDataset * @param band an integer representation of which band in the image * @return true if the band contains any no data values * @warning May be cpu intensive on large images */ bool GDALHasNoData( GDALDataset *poDS, int band ) { bool hasNDV = false; //check if poDS is NULL #lm int ncols = poDS->GetRasterXSize(); int nrows = poDS->GetRasterYSize(); double nDV; GDALRasterBand *poBand = poDS->GetRasterBand( band ); if( poBand == NULL ) return false; int pbSuccess = 0; nDV = poBand->GetNoDataValue( &pbSuccess ); if( pbSuccess == false ) nDV = -9999.0; double *padfScanline; padfScanline = new double[ncols]; for( int i = 0;i < nrows;i++ ) { poBand->RasterIO( GF_Read, 0, i, ncols, 1, padfScanline, ncols, 1, GDT_Float64, 0, 0 ); for( int j = 0;j < ncols;j++ ) { if( CPLIsEqual( (float)padfScanline[j], (float)nDV ) ) { hasNDV = true; goto done; } } } done: delete[] padfScanline; return hasNDV; }
feature_ptr gdal_featureset::get_feature(mapnik::query const& q) { feature_ptr feature = feature_factory::create(ctx_,1); GDALRasterBand * red = 0; GDALRasterBand * green = 0; GDALRasterBand * blue = 0; GDALRasterBand * alpha = 0; GDALRasterBand * grey = 0; /* #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 */ CoordTransform 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 / (fabs(dx_) * boost::get<0>(q.resolution())); double margin_y = 1.0 / (fabs(dy_) * boost::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=" << boost::get<0>(q.resolution()) << "," << boost::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 = boost::get<0>(q.resolution()); double height_res = boost::get<1>(q.resolution()); int im_width = int(width_res * intersect.width() + 0.5); int im_height = int(height_res * intersect.height() + 0.5); // if layer-level filter_factor is set, apply it if (filter_factor_) { im_width *= filter_factor_; im_height *= filter_factor_; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Applying layer filter_factor=" << filter_factor_; } // otherwise respect symbolizer level factor applied to query, default of 1.0 else { double sym_downsample_factor = q.get_filter_factor(); im_width *= sym_downsample_factor; im_height *= sym_downsample_factor; } // 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::raster_ptr raster = boost::make_shared<mapnik::raster>(intersect, im_width, im_height); feature->set_raster(raster); mapnik::image_data_32 & image = raster->data_; image.set(0xffffffff); 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 { if (band_ > nbands_) { throw datasource_exception((boost::format("GDAL Plugin: '%d' is an invalid band, dataset only has '%d' bands\n") % band_ % nbands_).str()); } float* imageData = (float*)image.getBytes(); GDALRasterBand * band = dataset_.GetRasterBand(band_); int hasNoData(0); double nodata(0); if (nodata_value_) { hasNoData = 1; nodata = *nodata_value_; } else { nodata = band->GetNoDataValue(&hasNoData); } band->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); if (hasNoData) { feature->put("NODATA",nodata); } } else // working with all bands { 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; 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; } } break; } case GCI_Undefined: MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)"; grey = band; 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..."; int hasNoData = 0; double nodata = 0.0; if (nodata_value_) { hasNoData = 1; nodata = *nodata_value_; } else { nodata = red->GetNoDataValue(&hasNoData); } if (hasNoData) { feature->put("NODATA",nodata); } GDALColorTable *color_table = red->GetColorTable(); if (! alpha && hasNoData && ! color_table) { // first read the data in and create an alpha channel from the nodata values float* imageData = (float*)image.getBytes(); red->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { if (nodata == imageData[i]) { *reinterpret_cast<unsigned *>(&imageData[i]) = 0; } else { *reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF; } } } red->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); green->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 1, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); blue->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 2, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); } else if (grey) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing gray band..."; int hasNoData(0); double nodata(0); if (nodata_value_) { hasNoData = 1; nodata = *nodata_value_; } else { nodata = grey->GetNoDataValue(&hasNoData); } GDALColorTable* color_table = grey->GetColorTable(); if (hasNoData && ! color_table) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: No data value for layer=" << nodata; feature->put("NODATA",nodata); // first read the data in and create an alpha channel from the nodata values float* imageData = (float*)image.getBytes(); grey->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { if (nodata == imageData[i]) { *reinterpret_cast<unsigned *>(&imageData[i]) = 0; } else { *reinterpret_cast<unsigned *> (&imageData[i]) = 0xFFFFFFFF; } } } grey->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 1, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 2, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (color_table) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Loading colour table..."; unsigned nodata_value = static_cast<unsigned>(nodata); if (hasNoData) { feature->put("NODATA",static_cast<int>(nodata_value)); } for (unsigned y = 0; y < image.height(); ++y) { unsigned int* row = image.getRow(y); for (unsigned x = 0; x < image.width(); ++x) { unsigned value = row[x] & 0xff; if (hasNoData && (value == nodata_value)) { // make no data fully alpha row[x] = 0; } else { const GDALColorEntry *ce = color_table->GetColorEntry(value); if (ce) { // TODO - big endian support 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..."; alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 3, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); } } return feature; } } return feature_ptr(); }
static GDALDataset * DTEDCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { (void) pProgressData; (void) pfnProgress; (void) papszOptions; (void) bStrict; /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "DTED driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "DTED driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Work out the level. */ /* -------------------------------------------------------------------- */ int nLevel; if( poSrcDS->GetRasterYSize() == 121 ) nLevel = 0; else if( poSrcDS->GetRasterYSize() == 1201 ) nLevel = 1; else if( poSrcDS->GetRasterYSize() == 3601 ) nLevel = 2; else { CPLError( CE_Warning, CPLE_AppDefined, "The source does not appear to be a properly formatted cell." ); nLevel = 1; } /* -------------------------------------------------------------------- */ /* Checks the input SRS */ /* -------------------------------------------------------------------- */ OGRSpatialReference ogrsr_input; OGRSpatialReference ogrsr_wgs84; char* c = (char*)poSrcDS->GetProjectionRef(); ogrsr_input.importFromWkt(&c); ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" ); if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE) { CPLError( CE_Warning, CPLE_AppDefined, "The source projection coordinate system is %s. Only WGS 84 is supported.\n" "The DTED driver will generate a file as if the source was WGS 84 projection coordinate system.", poSrcDS->GetProjectionRef() ); } /* -------------------------------------------------------------------- */ /* Work out the LL origin. */ /* -------------------------------------------------------------------- */ int nLLOriginLat, nLLOriginLong; double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); nLLOriginLat = (int) floor(adfGeoTransform[3] + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5); nLLOriginLong = (int) floor(adfGeoTransform[0] + 0.5); if (fabs(nLLOriginLat - (adfGeoTransform[3] + (poSrcDS->GetRasterYSize() - 0.5) * adfGeoTransform[5])) > 1e-10 || fabs(nLLOriginLong - (adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10) { CPLError( CE_Warning, CPLE_AppDefined, "The corner coordinates of the source are not properly " "aligned on plain latitude/longitude boundaries."); } /* -------------------------------------------------------------------- */ /* Check horizontal source size. */ /* -------------------------------------------------------------------- */ int expectedXSize; if( ABS(nLLOriginLat) >= 80 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 6 + 1; else if( ABS(nLLOriginLat) >= 75 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 4 + 1; else if( ABS(nLLOriginLat) >= 70 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 3 + 1; else if( ABS(nLLOriginLat) >= 50 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 2 + 1; else expectedXSize = poSrcDS->GetRasterYSize(); if (poSrcDS->GetRasterXSize() != expectedXSize) { CPLError( CE_Warning, CPLE_AppDefined, "The horizontal source size is not conformant with the one " "expected by DTED Level %d at this latitude (%d pixels found instead of %d).", nLevel, poSrcDS->GetRasterXSize(), expectedXSize); } /* -------------------------------------------------------------------- */ /* Create the output dted file. */ /* -------------------------------------------------------------------- */ const char *pszError; pszError = DTEDCreate( pszFilename, nLevel, nLLOriginLat, nLLOriginLong ); if( pszError != NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s", pszError ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the DTED file so we can output the data to it. */ /* -------------------------------------------------------------------- */ DTEDInfo *psDTED; psDTED = DTEDOpen( pszFilename, "rb+", FALSE ); if( psDTED == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Read all the data in a single buffer. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); GInt16 *panData; panData = (GInt16 *) VSIMalloc(sizeof(GInt16) * psDTED->nXSize * psDTED->nYSize); if (panData == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory"); DTEDClose(psDTED); return NULL; } for( int iY = 0; iY < psDTED->nYSize; iY++ ) { poSrcBand->RasterIO( GF_Read, 0, iY, psDTED->nXSize, 1, (void *) (panData + iY * psDTED->nXSize), psDTED->nXSize, 1, GDT_Int16, 0, 0, NULL ); if( pfnProgress && !pfnProgress(0.5 * (iY+1) / (double) psDTED->nYSize, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); DTEDClose( psDTED ); CPLFree( panData ); return NULL; } } int bSrcBandHasNoData; double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData); /* -------------------------------------------------------------------- */ /* Write all the profiles. */ /* -------------------------------------------------------------------- */ GInt16 anProfData[3601]; int dfNodataCount=0; GByte iPartialCell; for( int iProfile = 0; iProfile < psDTED->nXSize; iProfile++ ) { for( int iY = 0; iY < psDTED->nYSize; iY++ ) { anProfData[iY] = panData[iProfile + iY * psDTED->nXSize]; if ( bSrcBandHasNoData && anProfData[iY] == srcBandNoData) { anProfData[iY] = DTED_NODATA_VALUE; dfNodataCount++; } else if ( anProfData[iY] == DTED_NODATA_VALUE ) dfNodataCount++; } DTEDWriteProfile( psDTED, iProfile, anProfData ); if( pfnProgress && !pfnProgress( 0.5 + 0.5 * (iProfile+1) / (double) psDTED->nXSize, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); DTEDClose( psDTED ); CPLFree( panData ); return NULL; } } CPLFree( panData ); /* -------------------------------------------------------------------- */ /* Partial cell indicator: 0 for complete coverage; 1-99 for incomplete */ /* -------------------------------------------------------------------- */ char szPartialCell[3]; if ( dfNodataCount == 0 ) iPartialCell = 0; else { iPartialCell = (GByte)int(floor(100.0 - (dfNodataCount*100.0/(psDTED->nXSize * psDTED->nYSize)))); if (iPartialCell < 1) iPartialCell=1; } sprintf(szPartialCell,"%02d",iPartialCell); DTEDSetMetadata(psDTED, DTEDMD_PARTIALCELL_DSI, szPartialCell); /* -------------------------------------------------------------------- */ /* Try to copy any matching available metadata. */ /* -------------------------------------------------------------------- */ if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_UHL, poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_ACC, poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) ); if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_UHL, poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_DSI, poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) ); if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_UHL, poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_DSI, poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) ); if( poSrcDS->GetMetadataItem( "DTED_DataEdition" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_DATA_EDITION, poSrcDS->GetMetadataItem( "DTED_DataEdition" ) ); if( poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_VERSION, poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) ); if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MAINT_DATE, poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_DATE, poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MAINT_DESCRIPTION, poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) ); if( poSrcDS->GetMetadataItem( "DTED_Producer" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_PRODUCER, poSrcDS->GetMetadataItem( "DTED_Producer" ) ); if( poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTDATUM, poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) ); if( poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_HORIZDATUM, poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) ); if( poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_DIGITIZING_SYS, poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) ); if( poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_COMPILATION_DATE, poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_HORIZACCURACY, poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) ); if( poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_REL_HORIZACCURACY, poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) ); if( poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_REL_VERTACCURACY, poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) ); /* -------------------------------------------------------------------- */ /* Try to open the resulting DTED file. */ /* -------------------------------------------------------------------- */ DTEDClose( psDTED ); /* -------------------------------------------------------------------- */ /* Reopen and copy missing information into a PAM file. */ /* -------------------------------------------------------------------- */ GDALPamDataset *poDS = (GDALPamDataset *) GDALOpen( pszFilename, GA_ReadOnly ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; }
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; }
GDALDataset *GS7BGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, CPL_UNUSED char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "Driver does not support source dataset with zero band.\n"); return NULL; } else if (nBands > 1) { if( bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "Unable to create copy, " "format only supports one raster band.\n" ); return NULL; } else CPLError( CE_Warning, CPLE_NotSupported, "Format only supports one " "raster band, first band will be copied.\n" ); } GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); if( !pfnProgress( 0.0, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" ); return NULL; } VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file '%s' failed.\n", pszFilename ); return NULL; } GInt32 nXSize = poSrcBand->GetXSize(); GInt32 nYSize = poSrcBand->GetYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2; double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]; double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3]; double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2; CPLErr eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* Copy band data. */ /* -------------------------------------------------------------------- */ double *pfData = (double *)VSI_MALLOC2_VERBOSE( nXSize, sizeof( double ) ); if( pfData == NULL ) { VSIFCloseL( fp ); return NULL; } int bSrcHasNDValue; double dfSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue ); double dfMinZ = DBL_MAX; double dfMaxZ = -DBL_MAX; for( GInt32 iRow = nYSize - 1; iRow >= 0; iRow-- ) { eErr = poSrcBand->RasterIO( GF_Read, 0, iRow, nXSize, 1, pfData, nXSize, 1, GDT_Float64, 0, 0, NULL ); if( eErr != CE_None ) { VSIFCloseL( fp ); VSIFree( pfData ); return NULL; } for( int iCol=0; iCol<nXSize; iCol++ ) { if( bSrcHasNDValue && pfData[iCol] == dfSrcNoDataValue ) { pfData[iCol] = dfDefaultNoDataValue; } else { if( pfData[iCol] > dfMaxZ ) dfMaxZ = pfData[iCol]; if( pfData[iCol] < dfMinZ ) dfMinZ = pfData[iCol]; } CPL_LSBPTR64( pfData+iCol ); } if( VSIFWriteL( (void *)pfData, sizeof( double ), nXSize, fp ) != static_cast<unsigned>(nXSize) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid row. Disk full?\n" ); return NULL; } if( !pfnProgress( static_cast<double>(nYSize - iRow)/nYSize, NULL, pProgressData ) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return NULL; } } VSIFree( pfData ); /* write out the min and max values */ eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename, GA_Update ); if (poDS) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); } return poDS; }
/** Private method to calculate statistics for each band. Populates rasterStatsMap. */ void ImageWriter::calculateStats(RasterBandStats * theRasterBandStats,GDALDataset * gdalDataset) { std::cout << "Calculating statistics..." << std::endl; GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand( 1 ); QString myColorInterpretation = GDALGetColorInterpretationName(myGdalBand->GetColorInterpretation()); theRasterBandStats->bandName=myColorInterpretation; theRasterBandStats->bandNo=1; // get the dimensions of the raster int myColsInt = myGdalBand->GetXSize(); int myRowsInt = myGdalBand->GetYSize(); theRasterBandStats->elementCountInt=myColsInt*myRowsInt; theRasterBandStats->noDataDouble=myGdalBand->GetNoDataValue(); //allocate a buffer to hold one row of ints int myAllocationSizeInt = sizeof(uint)*myColsInt; uint * myScanlineAllocInt = (uint*) CPLMalloc(myAllocationSizeInt); bool myFirstIterationFlag = true; //unfortunately we need to make two passes through the data to calculate stddev for (int myCurrentRowInt=0; myCurrentRowInt < myRowsInt;myCurrentRowInt++) { CPLErr myResult = myGdalBand->RasterIO( GF_Read, 0, myCurrentRowInt, myColsInt, 1, myScanlineAllocInt, myColsInt, 1, GDT_UInt32, 0, 0 ); for (int myCurrentColInt=0; myCurrentColInt < myColsInt; myCurrentColInt++) { //get the nth element from the current row double myDouble=myScanlineAllocInt[myCurrentColInt]; //only use this element if we have a non null element if (myDouble != theRasterBandStats->noDataDouble ) { if (myFirstIterationFlag) { //this is the first iteration so initialise vars myFirstIterationFlag=false; theRasterBandStats->minValDouble=myDouble; theRasterBandStats->maxValDouble=myDouble; } //end of true part for first iteration check else { //this is done for all subsequent iterations if (myDouble < theRasterBandStats->minValDouble) { theRasterBandStats->minValDouble=myDouble; } if (myDouble > theRasterBandStats->maxValDouble) { // printf ("Maxval updated to %f\n",myDouble); theRasterBandStats->maxValDouble=myDouble; } //only increment the running total if it is not a nodata value if (myDouble != theRasterBandStats->noDataDouble) { theRasterBandStats->sumDouble += myDouble; ++theRasterBandStats->elementCountInt; } } //end of false part for first iteration check } //end of nodata chec } //end of column wise loop } //end of row wise loop // //end of first pass through data now calculate the range theRasterBandStats->rangeDouble = theRasterBandStats->maxValDouble-theRasterBandStats->minValDouble; //calculate the mean theRasterBandStats->meanDouble = theRasterBandStats->sumDouble / theRasterBandStats->elementCountInt; //for the second pass we will get the sum of the squares / mean for (int myCurrentRowInt=0; myCurrentRowInt < myRowsInt;myCurrentRowInt++) { CPLErr myResult = myGdalBand->RasterIO( GF_Read, 0, myCurrentRowInt, myColsInt, 1, myScanlineAllocInt, myColsInt, 1, GDT_UInt32, 0, 0 ); for (int myCurrentColInt=0; myCurrentColInt < myColsInt; myCurrentColInt++) { //get the nth element from the current row double myDouble=myScanlineAllocInt[myCurrentColInt]; theRasterBandStats->sumSqrDevDouble += static_cast<double>(pow(myDouble - theRasterBandStats->meanDouble,2)); } //end of column wise loop } //end of row wise loop //divide result by sample size - 1 and get square root to get stdev theRasterBandStats->stdDevDouble = static_cast<double>(sqrt(theRasterBandStats->sumSqrDevDouble / (theRasterBandStats->elementCountInt - 1))); CPLFree(myScanlineAllocInt); //printf("CalculateStats::\n"); //std::cout << "Band Name : " << theRasterBandStats->bandName << std::endl; //printf("Band No : %i\n",theRasterBandStats->bandNo); //printf("Band min : %f\n",theRasterBandStats->minValDouble); //printf("Band max : %f\n",theRasterBandStats->maxValDouble); //printf("Band range: %f\n",theRasterBandStats->rangeDouble); //printf("Band mean : %f\n",theRasterBandStats->meanDouble); //printf("Band sum : %f\n",theRasterBandStats->sumDouble); return ; }
GDALDataset * GIFDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); int bInterlace = FALSE; /* -------------------------------------------------------------------- */ /* Check for interlaced option. */ /* -------------------------------------------------------------------- */ bInterlace = CSLFetchBoolean(papszOptions, "INTERLACING", FALSE); /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "GIF driver only supports one band images.\n" ); return NULL; } if (nXSize > 65535 || nYSize > 65535) { CPLError( CE_Failure, CPLE_NotSupported, "GIF driver only supports datasets up to 65535x65535 size.\n" ); return NULL; } if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte && bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "GIF driver doesn't support data type %s. " "Only eight bit bands supported.\n", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the output file. */ /* -------------------------------------------------------------------- */ GifFileType *hGifFile; VSILFILE *fp; fp = VSIFOpenL( pszFilename, "wb" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create %s:\n%s", pszFilename, VSIStrerror( errno ) ); return NULL; } #if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5 int nError; hGifFile = EGifOpen( fp, VSIGIFWriteFunc, &nError ); #else hGifFile = EGifOpen( fp, VSIGIFWriteFunc ); #endif if( hGifFile == NULL ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_OpenFailed, "EGifOpenFilename(%s) failed. Does file already exist?", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Prepare colortable. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poBand = poSrcDS->GetRasterBand(1); ColorMapObject *psGifCT; int iColor; if( poBand->GetColorTable() == NULL ) { psGifCT = GifMakeMapObject( 256, NULL ); for( iColor = 0; iColor < 256; iColor++ ) { psGifCT->Colors[iColor].Red = (GifByteType) iColor; psGifCT->Colors[iColor].Green = (GifByteType) iColor; psGifCT->Colors[iColor].Blue = (GifByteType) iColor; } } else { GDALColorTable *poCT = poBand->GetColorTable(); int nFullCount = 1; while( nFullCount < poCT->GetColorEntryCount() ) nFullCount = nFullCount * 2; psGifCT = GifMakeMapObject( nFullCount, NULL ); for( iColor = 0; iColor < poCT->GetColorEntryCount(); iColor++ ) { GDALColorEntry sEntry; poCT->GetColorEntryAsRGB( iColor, &sEntry ); psGifCT->Colors[iColor].Red = (GifByteType) sEntry.c1; psGifCT->Colors[iColor].Green = (GifByteType) sEntry.c2; psGifCT->Colors[iColor].Blue = (GifByteType) sEntry.c3; } for( ; iColor < nFullCount; iColor++ ) { psGifCT->Colors[iColor].Red = 0; psGifCT->Colors[iColor].Green = 0; psGifCT->Colors[iColor].Blue = 0; } } /* -------------------------------------------------------------------- */ /* Setup parameters. */ /* -------------------------------------------------------------------- */ if (EGifPutScreenDesc(hGifFile, nXSize, nYSize, psGifCT->ColorCount, 255, psGifCT) == GIF_ERROR) { GifFreeMapObject(psGifCT); GDALPrintGifError(hGifFile, "Error writing gif file."); GIFAbstractDataset::myEGifCloseFile(hGifFile); VSIFCloseL( fp ); return NULL; } GifFreeMapObject(psGifCT); psGifCT = NULL; /* Support for transparency */ int bNoDataValue; double noDataValue = poBand->GetNoDataValue(&bNoDataValue); if (bNoDataValue && noDataValue >= 0 && noDataValue <= 255) { unsigned char extensionData[4]; extensionData[0] = 1; /* Transparent Color Flag */ extensionData[1] = 0; extensionData[2] = 0; extensionData[3] = (unsigned char)noDataValue; EGifPutExtension(hGifFile, 0xf9, 4, extensionData); } if (EGifPutImageDesc(hGifFile, 0, 0, nXSize, nYSize, bInterlace, NULL) == GIF_ERROR ) { GDALPrintGifError(hGifFile, "Error writing gif file."); GIFAbstractDataset::myEGifCloseFile(hGifFile); VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* Loop over image, copying image data. */ /* -------------------------------------------------------------------- */ CPLErr eErr; GDALPamDataset *poDS; GByte *pabyScanline; pabyScanline = (GByte *) CPLMalloc( nXSize ); if( !pfnProgress( 0.0, NULL, pProgressData ) ) eErr = CE_Failure; if( !bInterlace ) { for( int iLine = 0; iLine < nYSize; iLine++ ) { eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, pabyScanline, nXSize, 1, GDT_Byte, nBands, nBands * nXSize ); if( eErr != CE_None || EGifPutLine( hGifFile, pabyScanline, nXSize ) == GIF_ERROR ) { CPLError( CE_Failure, CPLE_AppDefined, "Error writing gif file." ); goto error; } if( !pfnProgress( (iLine + 1) * 1.0 / nYSize, NULL, pProgressData ) ) { goto error; } } } else { int i, j; int nLinesRead = 0; int nLinesToRead = 0; for ( i = 0; i < 4; i++) { for (j = InterlacedOffset[i]; j < nYSize; j += InterlacedJumps[i]) { nLinesToRead ++; } } /* Need to perform 4 passes on the images: */ for ( i = 0; i < 4; i++) { for (j = InterlacedOffset[i]; j < nYSize; j += InterlacedJumps[i]) { eErr= poBand->RasterIO( GF_Read, 0, j, nXSize, 1, pabyScanline, nXSize, 1, GDT_Byte, 1, nXSize ); if (eErr != CE_None || EGifPutLine(hGifFile, pabyScanline, nXSize) == GIF_ERROR) { CPLError( CE_Failure, CPLE_AppDefined, "Error writing gif file." ); goto error; } nLinesRead ++; if( !pfnProgress( nLinesRead * 1.0 / nYSize, NULL, pProgressData ) ) { goto error; } } } } CPLFree( pabyScanline ); pabyScanline = NULL; /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ if (GIFAbstractDataset::myEGifCloseFile(hGifFile) == GIF_ERROR) { CPLError( CE_Failure, CPLE_AppDefined, "EGifCloseFile() failed.\n" ); hGifFile = NULL; goto error; } hGifFile = NULL; VSIFCloseL( fp ); fp = NULL; /* -------------------------------------------------------------------- */ /* Do we need a world file? */ /* -------------------------------------------------------------------- */ if( CSLFetchBoolean( papszOptions, "WORLDFILE", FALSE ) ) { double adfGeoTransform[6]; if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None ) GDALWriteWorldFile( pszFilename, "wld", adfGeoTransform ); } /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxilary pam information. */ /* -------------------------------------------------------------------- */ /* If outputing to stdout, we can't reopen it, so we'll return */ /* a fake dataset to make the caller happy */ CPLPushErrorHandler(CPLQuietErrorHandler); poDS = (GDALPamDataset*) GDALOpen(pszFilename, GA_ReadOnly); CPLPopErrorHandler(); if (poDS) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; } else { CPLErrorReset(); GIFDataset* poGIF_DS = new GIFDataset(); poGIF_DS->nRasterXSize = nXSize; poGIF_DS->nRasterYSize = nYSize; for(int i=0;i<nBands;i++) poGIF_DS->SetBand( i+1, new GIFRasterBand( poGIF_DS, i+1, NULL, 0 ) ); return poGIF_DS; } error: if (hGifFile) GIFAbstractDataset::myEGifCloseFile(hGifFile); if (fp) VSIFCloseL( fp ); if (pabyScanline) CPLFree( pabyScanline ); return NULL; }
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(); }
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; }
/** * Sets the surface grids based on a ncepNam (surface only!) forecast. * @param input The WindNinjaInputs for misc. info. * @param airGrid The air temperature grid to be filled. * @param cloudGrid The cloud cover grid to be filled. * @param uGrid The u velocity grid to be filled. * @param vGrid The v velocity grid to be filled. * @param wGrid The w velocity grid to be filled (filled with zeros here?). */ void genericSurfInitialization::setSurfaceGrids( WindNinjaInputs &input, AsciiGrid<double> &airGrid, AsciiGrid<double> &cloudGrid, AsciiGrid<double> &uGrid, AsciiGrid<double> &vGrid, AsciiGrid<double> &wGrid ) { int bandNum = -1; //get time list std::vector<boost::local_time::local_date_time> timeList( getTimeList(input.ninjaTimeZone) ); //Search time list for our time to identify our band number for cloud/speed/dir for(unsigned int i = 0; i < timeList.size(); i++) { if(input.ninjaTime == timeList[i]) { bandNum = i + 1; break; } } if(bandNum < 0) throw std::runtime_error("Could not match ninjaTime with a band number in the forecast file."); //get some info from the nam file in input //Acquire a lock to protect the non-thread safe netCDF library #ifdef _OPENMP omp_guard netCDF_guard(netCDF_lock); #endif GDALDataset* poDS; //attempt to grab the projection from the dem? //check for member prjString first std::string dstWkt; dstWkt = input.dem.prjString; if ( dstWkt.empty() ) { //try to open original poDS = (GDALDataset*)GDALOpen( input.dem.fileName.c_str(), GA_ReadOnly ); if( poDS == NULL ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad projection reference" ); //throw(); } dstWkt = poDS->GetProjectionRef(); if( dstWkt.empty() ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad projection reference" ); //throw() } GDALClose((GDALDatasetH) poDS ); } poDS = (GDALDataset*)GDALOpen( input.forecastFilename.c_str(), GA_ReadOnly ); if( poDS == NULL ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad forecast file" ); } else GDALClose((GDALDatasetH) poDS ); // open ds one by one and warp, then write to grid GDALDataset *srcDS, *wrpDS; std::string temp; std::string srcWkt; std::vector<std::string> varList = getVariableList(); /* * Set the initial values in the warped dataset to no data */ GDALWarpOptions* psWarpOptions; for( unsigned int i = 0;i < varList.size();i++ ) { temp = "NETCDF:" + input.forecastFilename + ":" + varList[i]; srcDS = (GDALDataset*)GDALOpenShared( temp.c_str(), GA_ReadOnly ); if( srcDS == NULL ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad forecast file" ); } srcWkt = srcDS->GetProjectionRef(); if( srcWkt.empty() ) { CPLDebug( "ncepNdfdInitialization::setSurfaceGrids()", "Bad forecast file" ); //throw } /* * Grab the first band to get the nodata value for the variable, * assume all bands have the same ndv */ GDALRasterBand *poBand = srcDS->GetRasterBand( 1 ); int pbSuccess; double dfNoData = poBand->GetNoDataValue( &pbSuccess ); psWarpOptions = GDALCreateWarpOptions(); int nBandCount = srcDS->GetRasterCount(); psWarpOptions->nBandCount = nBandCount; psWarpOptions->padfDstNoDataReal = (double*) CPLMalloc( sizeof( double ) * nBandCount ); psWarpOptions->padfDstNoDataImag = (double*) CPLMalloc( sizeof( double ) * nBandCount ); for( int b = 0;b < srcDS->GetRasterCount();b++ ) { psWarpOptions->padfDstNoDataReal[b] = dfNoData; psWarpOptions->padfDstNoDataImag[b] = dfNoData; } if( pbSuccess == false ) dfNoData = -9999.0; psWarpOptions->papszWarpOptions = CSLSetNameValue( psWarpOptions->papszWarpOptions, "INIT_DEST", "NO_DATA" ); wrpDS = (GDALDataset*) GDALAutoCreateWarpedVRT( srcDS, srcWkt.c_str(), dstWkt.c_str(), GRA_NearestNeighbour, 1.0, psWarpOptions ); if( varList[i] == "Temperature_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, airGrid ); if( CPLIsNan( dfNoData ) ) { airGrid.set_noDataValue(-9999.0); airGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "V-component_of_wind_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, vGrid ); if( CPLIsNan( dfNoData ) ) { vGrid.set_noDataValue(-9999.0); vGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "U-component_of_wind_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, uGrid ); if( CPLIsNan( dfNoData ) ) { uGrid.set_noDataValue(-9999.0); uGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "Total_cloud_cover" ) { GDAL2AsciiGrid( wrpDS, bandNum, cloudGrid ); if( CPLIsNan( dfNoData ) ) { cloudGrid.set_noDataValue(-9999.0); cloudGrid.replaceNan( -9999.0 ); } } GDALDestroyWarpOptions( psWarpOptions ); GDALClose((GDALDatasetH) srcDS ); GDALClose((GDALDatasetH) wrpDS ); } cloudGrid /= 100.0; wGrid.set_headerData( uGrid ); wGrid = 0.0; }
CPLErr GDALDefaultOverviews::BuildOverviews( const char * pszBasename, const char * pszResampling, int nOverviews, int * panOverviewList, int nBands, int * panBandList, GDALProgressFunc pfnProgress, void * pProgressData) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; if( nOverviews == 0 ) return CleanOverviews(); /* -------------------------------------------------------------------- */ /* If we don't already have an overview file, we need to decide */ /* what format to use. */ /* -------------------------------------------------------------------- */ if( poODS == NULL ) { bOvrIsAux = CPLTestBool(CPLGetConfigOption( "USE_RRD", "NO" )); if( bOvrIsAux ) { osOvrFilename = CPLResetExtension(poDS->GetDescription(),"aux"); VSIStatBufL sStatBuf; if( VSIStatExL( osOvrFilename, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0 ) osOvrFilename.Printf( "%s.aux", poDS->GetDescription() ); } } /* -------------------------------------------------------------------- */ /* If we already have the overviews open, but they are */ /* read-only, then try and reopen them read-write. */ /* -------------------------------------------------------------------- */ else if( poODS->GetAccess() == GA_ReadOnly ) { GDALClose( poODS ); poODS = static_cast<GDALDataset *>( GDALOpen( osOvrFilename, GA_Update )); if( poODS == NULL ) return CE_Failure; } /* -------------------------------------------------------------------- */ /* Our TIFF overview support currently only works safely if all */ /* bands are handled at the same time. */ /* -------------------------------------------------------------------- */ if( !bOvrIsAux && nBands != poDS->GetRasterCount() ) { CPLError( CE_Failure, CPLE_NotSupported, "Generation of overviews in external TIFF currently only " "supported when operating on all bands. " "Operation failed." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* If a basename is provided, use it to override the internal */ /* overview filename. */ /* -------------------------------------------------------------------- */ if( pszBasename == NULL && osOvrFilename.length() == 0 ) pszBasename = poDS->GetDescription(); if( pszBasename != NULL ) { if( bOvrIsAux ) osOvrFilename.Printf( "%s.aux", pszBasename ); else osOvrFilename.Printf( "%s.ovr", pszBasename ); } /* -------------------------------------------------------------------- */ /* Establish which of the overview levels we already have, and */ /* which are new. We assume that band 1 of the file is */ /* representative. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poBand = poDS->GetRasterBand( 1 ); int nNewOverviews = 0; int *panNewOverviewList = static_cast<int *>( CPLCalloc(sizeof(int), nOverviews) ); double dfAreaNewOverviews = 0; double dfAreaRefreshedOverviews = 0; for( int i = 0; i < nOverviews && poBand != NULL; i++ ) { for( int j = 0; j < poBand->GetOverviewCount(); j++ ) { GDALRasterBand * poOverview = poBand->GetOverview( j ); if( poOverview == NULL ) continue; int nOvFactor = GDALComputeOvFactor(poOverview->GetXSize(), poBand->GetXSize(), poOverview->GetYSize(), poBand->GetYSize()); if( nOvFactor == panOverviewList[i] || nOvFactor == GDALOvLevelAdjust2( panOverviewList[i], poBand->GetXSize(), poBand->GetYSize() ) ) { panOverviewList[i] *= -1; } } const double dfArea = 1.0 / (panOverviewList[i] * panOverviewList[i]); dfAreaRefreshedOverviews += dfArea; if( panOverviewList[i] > 0 ) { dfAreaNewOverviews += dfArea; panNewOverviewList[nNewOverviews++] = panOverviewList[i]; } } /* -------------------------------------------------------------------- */ /* Build band list. */ /* -------------------------------------------------------------------- */ GDALRasterBand **pahBands = static_cast<GDALRasterBand **>( CPLCalloc(sizeof(GDALRasterBand *), nBands) ); for( int i = 0; i < nBands; i++ ) pahBands[i] = poDS->GetRasterBand( panBandList[i] ); /* -------------------------------------------------------------------- */ /* Build new overviews - Imagine. Keep existing file open if */ /* we have it. But mark all overviews as in need of */ /* regeneration, since HFAAuxBuildOverviews() doesn't actually */ /* produce the imagery. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; void* pScaledProgress = GDALCreateScaledProgress( 0, dfAreaNewOverviews / dfAreaRefreshedOverviews, pfnProgress, pProgressData ); if( bOvrIsAux ) { if( nNewOverviews == 0 ) { /* if we call HFAAuxBuildOverviews() with nNewOverviews == 0 */ /* because that there's no new, this will wipe existing */ /* overviews (#4831) */ // eErr = CE_None; } else { eErr = HFAAuxBuildOverviews( osOvrFilename, poDS, &poODS, nBands, panBandList, nNewOverviews, panNewOverviewList, pszResampling, GDALScaledProgress, pScaledProgress ); } for( int j = 0; j < nOverviews; j++ ) { if( panOverviewList[j] > 0 ) panOverviewList[j] *= -1; } } /* -------------------------------------------------------------------- */ /* Build new overviews - TIFF. Close TIFF files while we */ /* operate on it. */ /* -------------------------------------------------------------------- */ else { if( poODS != NULL ) { delete poODS; poODS = NULL; } eErr = GTIFFBuildOverviews( osOvrFilename, nBands, pahBands, nNewOverviews, panNewOverviewList, pszResampling, GDALScaledProgress, pScaledProgress ); // Probe for proxy overview filename. if( eErr == CE_Failure ) { const char *pszProxyOvrFilename = poDS->GetMetadataItem("FILENAME","ProxyOverviewRequest"); if( pszProxyOvrFilename != NULL ) { osOvrFilename = pszProxyOvrFilename; eErr = GTIFFBuildOverviews( osOvrFilename, nBands, pahBands, nNewOverviews, panNewOverviewList, pszResampling, GDALScaledProgress, pScaledProgress ); } } if( eErr == CE_None ) { poODS = static_cast<GDALDataset *>( GDALOpen( osOvrFilename, GA_Update ) ); if( poODS == NULL ) eErr = CE_Failure; } } GDALDestroyScaledProgress( pScaledProgress ); /* -------------------------------------------------------------------- */ /* Refresh old overviews that were listed. */ /* -------------------------------------------------------------------- */ GDALRasterBand **papoOverviewBands = static_cast<GDALRasterBand **>( CPLCalloc(sizeof(void*), nOverviews) ); for( int iBand = 0; iBand < nBands && eErr == CE_None; iBand++ ) { poBand = poDS->GetRasterBand( panBandList[iBand] ); nNewOverviews = 0; for( int i = 0; i < nOverviews && poBand != NULL; i++ ) { for( int j = 0; j < poBand->GetOverviewCount(); j++ ) { GDALRasterBand * poOverview = poBand->GetOverview( j ); if( poOverview == NULL ) continue; int bHasNoData = FALSE; double noDataValue = poBand->GetNoDataValue(&bHasNoData); if( bHasNoData ) poOverview->SetNoDataValue(noDataValue); const int nOvFactor = GDALComputeOvFactor(poOverview->GetXSize(), poBand->GetXSize(), poOverview->GetYSize(), poBand->GetYSize()); if( nOvFactor == - panOverviewList[i] || (panOverviewList[i] < 0 && nOvFactor == GDALOvLevelAdjust2( -panOverviewList[i], poBand->GetXSize(), poBand->GetYSize() )) ) { papoOverviewBands[nNewOverviews++] = poOverview; break; } } } if( nNewOverviews > 0 ) { const double dfOffset = dfAreaNewOverviews / dfAreaRefreshedOverviews; const double dfScale = 1.0 - dfOffset; pScaledProgress = GDALCreateScaledProgress( dfOffset + dfScale * iBand / nBands, dfOffset + dfScale * (iBand+1) / nBands, pfnProgress, pProgressData ); eErr = GDALRegenerateOverviews( (GDALRasterBandH) poBand, nNewOverviews, (GDALRasterBandH*)papoOverviewBands, pszResampling, GDALScaledProgress, pScaledProgress ); GDALDestroyScaledProgress( pScaledProgress ); } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLFree( papoOverviewBands ); CPLFree( panNewOverviewList ); CPLFree( pahBands ); /* -------------------------------------------------------------------- */ /* If we have a mask file, we need to build its overviews too. */ /* -------------------------------------------------------------------- */ if( HaveMaskFile() && poMaskDS ) { // Some config option are not compatible with mask overviews // so unset them, and define more sensible values. const bool bJPEG = EQUAL(CPLGetConfigOption("COMPRESS_OVERVIEW", ""), "JPEG"); const bool bPHOTOMETRIC_YCBCR = EQUAL(CPLGetConfigOption("PHOTOMETRIC_OVERVIEW", ""), "YCBCR"); if( bJPEG ) CPLSetThreadLocalConfigOption("COMPRESS_OVERVIEW", "DEFLATE"); if( bPHOTOMETRIC_YCBCR ) CPLSetThreadLocalConfigOption("PHOTOMETRIC_OVERVIEW", ""); poMaskDS->BuildOverviews( pszResampling, nOverviews, panOverviewList, 0, NULL, pfnProgress, pProgressData ); // Restore config option. if( bJPEG ) CPLSetThreadLocalConfigOption("COMPRESS_OVERVIEW", "JPEG"); if( bPHOTOMETRIC_YCBCR ) CPLSetThreadLocalConfigOption("PHOTOMETRIC_OVERVIEW", "YCBCR"); if( bOwnMaskDS ) { // Reset the poMask member of main dataset bands, since it // will become invalid after poMaskDS closing. for( int iBand = 1; iBand <= poDS->GetRasterCount(); iBand ++ ) { GDALRasterBand *poOtherBand = poDS->GetRasterBand(iBand); if( poOtherBand != NULL ) poOtherBand->InvalidateMaskBand(); } GDALClose( poMaskDS ); } // force next request to reread mask file. poMaskDS = NULL; bOwnMaskDS = false; bCheckedForMask = false; } /* -------------------------------------------------------------------- */ /* If we have an overview dataset, then mark all the overviews */ /* with the base dataset Used later for finding overviews */ /* masks. Uggg. */ /* -------------------------------------------------------------------- */ if( poODS ) { const int nOverviewCount = GetOverviewCount(1); for( int iOver = 0; iOver < nOverviewCount; iOver++ ) { GDALRasterBand *poOtherBand = GetOverview( 1, iOver ); GDALDataset *poOverDS = poOtherBand != NULL ? poOtherBand->GetDataset() : NULL; if( poOverDS != NULL ) { poOverDS->oOvManager.poBaseDS = poDS; poOverDS->oOvManager.poDS = poOverDS; } } } return eErr; }
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)); }
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; }
GDALDataset * SRTMHGTDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** /* papszOptions*/, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ const int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "SRTMHGT driver does not support source dataset with zero band.\n"); return nullptr; } else if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "SRTMHGT driver only uses the first band of the dataset.\n"); if (bStrict) return nullptr; } /* -------------------------------------------------------------------- */ /* Checks the input SRS */ /* -------------------------------------------------------------------- */ OGRSpatialReference ogrsr_input; ogrsr_input.importFromWkt(poSrcDS->GetProjectionRef()); OGRSpatialReference ogrsr_wgs84; ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" ); if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE) { CPLError( CE_Warning, CPLE_AppDefined, "The source projection coordinate system is %s. Only WGS 84 " "is supported.\nThe SRTMHGT driver will generate a file as " "if the source was WGS 84 projection coordinate system.", poSrcDS->GetProjectionRef() ); } /* -------------------------------------------------------------------- */ /* Work out the LL origin. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; if (poSrcDS->GetGeoTransform( adfGeoTransform ) != CE_None) { CPLError( CE_Failure, CPLE_AppDefined, "Source image must have a geo transform matrix."); return nullptr; } const int nLLOriginLat = static_cast<int>( std::floor(adfGeoTransform[3] + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5) ); int nLLOriginLong = static_cast<int>( std::floor(adfGeoTransform[0] + 0.5) ); if (std::abs(nLLOriginLat - ( adfGeoTransform[3] + (poSrcDS->GetRasterYSize() - 0.5 ) * adfGeoTransform[5] ) ) > 1e-10 || std::abs(nLLOriginLong - ( adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10 ) { CPLError( CE_Warning, CPLE_AppDefined, "The corner coordinates of the source are not properly " "aligned on plain latitude/longitude boundaries."); } /* -------------------------------------------------------------------- */ /* Check image dimensions. */ /* -------------------------------------------------------------------- */ const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); if (!((nXSize == 1201 && nYSize == 1201) || (nXSize == 3601 && nYSize == 3601) || (nXSize == 1801 && nYSize == 3601))) { CPLError( CE_Failure, CPLE_AppDefined, "Image dimensions should be 1201x1201, 3601x3601 or 1801x3601."); return nullptr; } /* -------------------------------------------------------------------- */ /* Check filename. */ /* -------------------------------------------------------------------- */ char expectedFileName[12]; CPLsnprintf(expectedFileName, sizeof(expectedFileName), "%c%02d%c%03d.HGT", (nLLOriginLat >= 0) ? 'N' : 'S', (nLLOriginLat >= 0) ? nLLOriginLat : -nLLOriginLat, (nLLOriginLong >= 0) ? 'E' : 'W', (nLLOriginLong >= 0) ? nLLOriginLong : -nLLOriginLong); if (!EQUAL(expectedFileName, CPLGetFilename(pszFilename))) { CPLError( CE_Warning, CPLE_AppDefined, "Expected output filename is %s.", expectedFileName); } /* -------------------------------------------------------------------- */ /* Write output file. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(pszFilename, "wb"); if (fp == nullptr) { CPLError( CE_Failure, CPLE_FileIO, "Cannot create file %s", pszFilename ); return nullptr; } GInt16* panData = reinterpret_cast<GInt16 *>( CPLMalloc(sizeof(GInt16) * nXSize) ); GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(1); int bSrcBandHasNoData; double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData); for( int iY = 0; iY < nYSize; iY++ ) { if( poSrcBand->RasterIO( GF_Read, 0, iY, nXSize, 1, reinterpret_cast<void *>( panData ), nXSize, 1, GDT_Int16, 0, 0, nullptr ) != CE_None ) { VSIFCloseL(fp); CPLFree( panData ); return nullptr; } /* Translate nodata values */ if (bSrcBandHasNoData && srcBandNoData != SRTMHG_NODATA_VALUE) { for( int iX = 0; iX < nXSize; iX++ ) { if (panData[iX] == srcBandNoData) panData[iX] = SRTMHG_NODATA_VALUE; } } #ifdef CPL_LSB GDALSwapWords(panData, 2, nXSize, 2); #endif if( VSIFWriteL( panData,sizeof(GInt16) * nXSize,1,fp ) != 1) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write line %d in SRTMHGT dataset.\n", iY ); VSIFCloseL(fp); CPLFree( panData ); return nullptr; } if( pfnProgress && !pfnProgress( (iY+1) / static_cast<double>( nYSize ), nullptr, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); VSIFCloseL(fp); CPLFree( panData ); return nullptr; } } CPLFree( panData ); VSIFCloseL(fp); /* -------------------------------------------------------------------- */ /* Reopen and copy missing information into a PAM file. */ /* -------------------------------------------------------------------- */ GDALPamDataset *poDS = reinterpret_cast<GDALPamDataset *>( GDALOpen( pszFilename, GA_ReadOnly ) ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT); return poDS; }
CMapRaster::CMapRaster(const QString& fn, CCanvas * parent) : IMap(eRaster, "",parent) , x(0) , y(0) , zoomlevel(1) , zoomfactor(1.0) , rasterBandCount(0) { filename = fn; #ifdef WIN32 dataset = (GDALDataset*)GDALOpen(filename.toLocal8Bit(),GA_ReadOnly); #else dataset = (GDALDataset*)GDALOpen(filename.toUtf8(),GA_ReadOnly); #endif if(dataset == 0) { QMessageBox::warning(0, tr("Error..."), tr("Failed to load file: %1").arg(filename)); return; } rasterBandCount = dataset->GetRasterCount(); if(rasterBandCount == 1) { GDALRasterBand * pBand; pBand = dataset->GetRasterBand(1); if(pBand == 0) { delete dataset; dataset = 0; QMessageBox::warning(0, tr("Error..."), tr("Failed to load file: %1").arg(filename)); return; } if(pBand->GetColorInterpretation() != GCI_PaletteIndex && pBand->GetColorInterpretation() != GCI_GrayIndex) { delete dataset; dataset = 0; QMessageBox::warning(0, tr("Error..."), tr("File must be 8 bit palette or gray indexed.")); return; } if(pBand->GetColorInterpretation() == GCI_PaletteIndex ) { GDALColorTable * pct = pBand->GetColorTable(); for(int i=0; i < pct->GetColorEntryCount(); ++i) { const GDALColorEntry& e = *pct->GetColorEntry(i); colortable << qRgba(e.c1, e.c2, e.c3, e.c4); } } else if(pBand->GetColorInterpretation() == GCI_GrayIndex ) { for(int i=0; i < 256; ++i) { colortable << qRgba(i, i, i, 255); } } else { delete dataset; dataset = 0; QMessageBox::warning(0, tr("Error..."), tr("File must be 8 bit palette or gray indexed.")); return; } int success = 0; double idx = pBand->GetNoDataValue(&success); if(success) { QColor tmp(colortable[idx]); tmp.setAlpha(0); colortable[idx] = tmp.rgba(); } } maparea.setWidth(dataset->GetRasterXSize()); maparea.setHeight(dataset->GetRasterYSize()); }
SEXP RGDAL_GetRasterData(SEXP sxpRasterBand, SEXP sxpRegion, SEXP sxpDimOut, SEXP sxpInterleave) { GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand); GDALDataType eGDALType = GDT_Int32; SEXPTYPE uRType = INTSXP; switch(pRasterBand->GetRasterDataType()) { case GDT_Byte: case GDT_UInt16: case GDT_Int16: case GDT_UInt32: case GDT_Int32: uRType = INTSXP; eGDALType = GDAL_INTEGER_TYPE; break; case GDT_Float32: case GDT_Float64: uRType = REALSXP; eGDALType = GDAL_FLOAT_TYPE; break; case GDT_CInt16: case GDT_CInt32: case GDT_CFloat32: case GDT_CFloat64: uRType = CPLXSXP; eGDALType = GDAL_COMPLEX_TYPE; break; default: error("Raster data type unknown\n"); break; } // Create matrix transposed int pc=0; SEXP sRStorage; PROTECT(sRStorage = allocMatrix(uRType, INTEGER(sxpDimOut)[1], INTEGER(sxpDimOut)[0])); pc++; // replication for 2.4.0 RSB 20060726 switch(uRType) { case INTSXP: if(pRasterBand->RasterIO(GF_Read, INTEGER(sxpRegion)[1] - 1, INTEGER(sxpRegion)[0] - 1, INTEGER(sxpRegion)[3], INTEGER(sxpRegion)[2], (void *)INTEGER(sRStorage), INTEGER(sxpDimOut)[1], INTEGER(sxpDimOut)[0], eGDALType, INTEGER(sxpInterleave)[0], INTEGER(sxpInterleave)[1]) == CE_Failure) error("Failure during raster IO\n"); break; case REALSXP: if(pRasterBand->RasterIO(GF_Read, INTEGER(sxpRegion)[1] - 1, INTEGER(sxpRegion)[0] - 1, INTEGER(sxpRegion)[3], INTEGER(sxpRegion)[2], (void *)REAL(sRStorage), INTEGER(sxpDimOut)[1], INTEGER(sxpDimOut)[0], eGDALType, INTEGER(sxpInterleave)[0], INTEGER(sxpInterleave)[1]) == CE_Failure) error("Failure during raster IO\n"); break; case CPLXSXP: if(pRasterBand->RasterIO(GF_Read, INTEGER(sxpRegion)[1] - 1, INTEGER(sxpRegion)[0] - 1, INTEGER(sxpRegion)[3], INTEGER(sxpRegion)[2], (void *)COMPLEX(sRStorage), INTEGER(sxpDimOut)[1], INTEGER(sxpDimOut)[0], eGDALType, INTEGER(sxpInterleave)[0], INTEGER(sxpInterleave)[1]) == CE_Failure) error("Failure during raster IO\n"); break; default: error("Raster data type unknown\n"); break; } int hasNoDataValue; double noDataValue = pRasterBand->GetNoDataValue(&hasNoDataValue); int i; if (hasNoDataValue) { switch(uRType) { case INTSXP: for (i = 0; i < LENGTH(sRStorage); ++i) if (INTEGER(sRStorage)[i] == (int) noDataValue) { INTEGER(sRStorage)[i] = NA_INTEGER; } break; case REALSXP: switch(pRasterBand->GetRasterDataType()) { case GDT_Float32: for (i = 0; i < LENGTH(sRStorage); ++i) if (REAL(sRStorage)[i] == (double) ((float) noDataValue)) { REAL(sRStorage)[i] = NA_REAL; } break; case GDT_Float64: for (i = 0; i < LENGTH(sRStorage); ++i) if (REAL(sRStorage)[i] == (double) (noDataValue)) { REAL(sRStorage)[i] = NA_REAL; } break; default: error("Raster data type unknown\n"); break; } break; default: warning("Output data values = %f are invalid\n", noDataValue); break; } } UNPROTECT(pc); return(sRStorage); }
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; }
/** * Checks the downloaded data to see if it is all valid. */ void genericSurfInitialization::checkForValidData() { //just make up a "dummy" timezone for use here boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("MST-07")); //get time list std::vector<boost::local_time::local_date_time> timeList( getTimeList(zone) ); boost::posix_time::ptime pt_low(boost::gregorian::date(1900,boost::gregorian::Jan,1), boost::posix_time::hours(12)); boost::posix_time::ptime pt_high(boost::gregorian::date(2100,boost::gregorian::Jan,1), boost::posix_time::hours(12)); boost::local_time::local_date_time low_time(pt_low, zone); boost::local_time::local_date_time high_time(pt_high, zone); //check times for(unsigned int i = 0; i < timeList.size(); i++) { if(timeList[i].is_special()) //if time is any special value (not_a_date_time, infinity, etc.) throw badForecastFile("Bad time in forecast file."); if(timeList[i] < low_time || timeList[i] > high_time) throw badForecastFile("Bad time in forecast file."); } // open ds variable by variable GDALDataset *srcDS; std::string temp; std::string srcWkt; int nBands = 0; bool noDataValueExists; bool noDataIsNan; std::vector<std::string> varList = getVariableList(); //Acquire a lock to protect the non-thread safe netCDF library #ifdef _OPENMP omp_guard netCDF_guard(netCDF_lock); #endif for( unsigned int i = 0;i < varList.size();i++ ) { temp = "NETCDF:" + wxModelFileName + ":" + varList[i]; srcDS = (GDALDataset*)GDALOpen( temp.c_str(), GA_ReadOnly ); if( srcDS == NULL ) throw badForecastFile("Cannot open forecast file."); srcWkt = srcDS->GetProjectionRef(); if( srcWkt.empty() ) throw badForecastFile("Forecast file doesn't have projection information."); //Get total bands (time steps) nBands = srcDS->GetRasterCount(); int nXSize, nYSize; GDALRasterBand *poBand; int pbSuccess; double dfNoData; double *padfScanline; nXSize = srcDS->GetRasterXSize(); nYSize = srcDS->GetRasterYSize(); //loop over all bands for this variable (bands are time steps) for(int j = 1; j <= nBands; j++) { poBand = srcDS->GetRasterBand( j ); pbSuccess = 0; dfNoData = poBand->GetNoDataValue( &pbSuccess ); if( pbSuccess == false ) noDataValueExists = false; else { noDataValueExists = true; noDataIsNan = CPLIsNan(dfNoData); } //set the data padfScanline = new double[nXSize*nYSize]; poBand->RasterIO(GF_Read, 0, 0, nXSize, nYSize, padfScanline, nXSize, nYSize, GDT_Float64, 0, 0); for(int k = 0;k < nXSize*nYSize; k++) { //Check if value is no data (if no data value was defined in file) if(noDataValueExists) { if(noDataIsNan) { if(CPLIsNan(padfScanline[k])) throw badForecastFile("Forecast file contains no_data values."); }else { if(padfScanline[k] == dfNoData) throw badForecastFile("Forecast file contains no_data values."); } } if( varList[i] == "Temperature_height_above_ground" ) //units are Kelvin { if(padfScanline[k] < 180.0 || padfScanline[k] > 340.0) //these are near the most extreme temperatures ever recored on earth throw badForecastFile("Temperature is out of range in forecast file."); } else if( varList[i] == "V-component_of_wind_height_above_ground" ) //units are m/s { if(std::abs(padfScanline[k]) > 220.0) throw badForecastFile("V-velocity is out of range in forecast file."); } else if( varList[i] == "U-component_of_wind_height_above_ground" ) //units are m/s { if(std::abs(padfScanline[k]) > 220.0) throw badForecastFile("U-velocity is out of range in forecast file."); } else if( varList[i] == "Total_cloud_cover" ) //units are percent { if(padfScanline[k] < 0.0 || padfScanline[k] > 100.0) throw badForecastFile("Total cloud cover is out of range in forecast file."); } } delete [] padfScanline; } GDALClose((GDALDatasetH) srcDS ); } }