diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp index 05835a9da..bf8bf3eba 100644 --- a/plugins/input/gdal/gdal_datasource.cpp +++ b/plugins/input/gdal/gdal_datasource.cpp @@ -24,6 +24,10 @@ #include "gdal_datasource.hpp" #include "gdal_featureset.hpp" +// mapnik +#include +#include + using mapnik::datasource; using mapnik::parameters; @@ -40,6 +44,7 @@ using mapnik::datasource_exception; gdal_datasource::gdal_datasource(parameters const& params) : datasource(params), extent_(), + dataset_(0), desc_(*params.get("type"),"utf-8") { GDALAllRegister(); @@ -53,8 +58,16 @@ gdal_datasource::gdal_datasource(parameters const& params) else dataset_name_ = *file; - dataset_ = boost::shared_ptr(reinterpret_cast(GDALOpenShared((dataset_name_).c_str(),GA_ReadOnly))); - if (!dataset_) throw datasource_exception(CPLGetLastErrorMsg()); + shared_dataset_ = *params_.get("shared",false); + +#if GDAL_VERSION_NUM >= 1600 + if (shared_dataset_) + dataset_ = reinterpret_cast(GDALOpenShared((dataset_name_).c_str(),GA_ReadOnly)); + else +#endif + dataset_ = reinterpret_cast(GDALOpen((dataset_name_).c_str(),GA_ReadOnly)); + + if (! dataset_) throw datasource_exception(CPLGetLastErrorMsg()); double tr[6]; dataset_->GetGeoTransform(tr); @@ -67,8 +80,7 @@ gdal_datasource::gdal_datasource(parameters const& params) gdal_datasource::~gdal_datasource() { - GDALDereferenceDataset (dataset_.get()); - dataset_.reset(); // prevent delete of dataset + GDALClose (dataset_); } int gdal_datasource::type() const diff --git a/plugins/input/gdal/gdal_datasource.hpp b/plugins/input/gdal/gdal_datasource.hpp index 8f0a5e4a5..771cc06eb 100644 --- a/plugins/input/gdal/gdal_datasource.hpp +++ b/plugins/input/gdal/gdal_datasource.hpp @@ -42,8 +42,9 @@ class gdal_datasource : public mapnik::datasource private: mapnik::Envelope extent_; std::string dataset_name_; - boost::shared_ptr dataset_; + GDALDataset* dataset_; mapnik::layer_descriptor desc_; + bool shared_dataset_; }; diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp index a9ea9d25c..78f7f7443 100644 --- a/plugins/input/gdal/gdal_featureset.cpp +++ b/plugins/input/gdal/gdal_featureset.cpp @@ -43,77 +43,17 @@ feature_ptr gdal_featureset::next() { first_ = false; feature_ptr feature(new Feature(1)); + GDALRasterBand * red = 0; GDALRasterBand * green = 0; GDALRasterBand * blue = 0; GDALRasterBand * alpha = 0; GDALRasterBand * grey = 0; - for (int i = 0; i < dataset_.GetRasterCount() ;++i) - { - GDALRasterBand * band = dataset_.GetRasterBand(i+1); - //if (band->GetOverviewCount() > 0) - //{ - // band = band->GetOverview(0); - //} - -#ifdef MAPNIK_DEBUG - int bsx,bsy; - band->GetBlockSize(&bsx,&bsy); - std::cout << boost::format("Block=%dx%d Type=%s Color=%s \n") % bsx % bsy - % GDALGetDataTypeName(band->GetRasterDataType()) - % GDALGetColorInterpretationName(band->GetColorInterpretation()); -#endif - GDALColorInterp color_interp = band->GetColorInterpretation(); - switch (color_interp) - { - case GCI_RedBand: - red = band; - break; - case GCI_GreenBand: - green = band; - break; - case GCI_BlueBand: - blue = band; - break; - case GCI_AlphaBand: - alpha = band; - break; - case GCI_GrayIndex: - grey = band; - break; - case GCI_PaletteIndex: - { - grey = band; - GDALColorTable *color_table = band->GetColorTable(); - - if ( color_table) - { - int count = color_table->GetColorEntryCount(); -#ifdef MAPNIK_DEBUG - std::cout << "Color Table count = " << count << "\n"; -#endif - for ( int i = 0; i < count; i++ ) - { - const GDALColorEntry *ce = color_table->GetColorEntry ( i ); - if (!ce ) continue; -#ifdef MAPNIK_DEBUG - std::cout << "color entry RGB (" << ce->c1 <<"," <c2 << "," << ce->c3 << ")\n"; -#endif - } - } - break; - } - case GCI_Undefined: - grey = band; - break; - default: - break; - ; - } - } - + unsigned raster_xsize = dataset_.GetRasterXSize(); unsigned raster_ysize = dataset_.GetRasterYSize(); + int nbands = dataset_.GetRasterCount(); + double tr[6]; dataset_.GetGeoTransform(tr); double x0 = tr[0]; @@ -129,33 +69,141 @@ feature_ptr gdal_featureset::next() int start_y = int(box.miny()+0.5); int width = int(box.width()+0.5); int height = int(box.height()+0.5); - + +#ifdef MAPNIK_DEBUG + std::cout << boost::format("RasterWidth=%d RasterHeight=%d \n") % raster_xsize % raster_ysize; + std::cout << boost::format("StartX=%d StartY=%d Width=%d Height=%d \n") % start_x % start_y % width % height; +#endif + if (width > 0 && height > 0) { + // Some GDAL drivers operate more efficiently if they know in advance + // what set of upcoming read requests will be made. The AdviseRead() + // method allows an application to notify the driver of the region and + // bands of interest, and at what resolution the region will be read. + // + // dataset_.AdviseRead (start_x, start_y, width, height, width, height, GDT_Byte, nbands, NULL, NULL); + + for (int i = 0; i < nbands; ++i) + { + GDALRasterBand * band = dataset_.GetRasterBand(i+1); + int band_overviews = band->GetOverviewCount(); + + if (band_overviews > 0) + { +#ifdef MAPNIK_DEBUG + for (int b = 0; b < band_overviews; b++) + { + GDALRasterBand * overview = band->GetOverview (b); + std::cout << boost::format("Overview=%d Width=%d Height=%d \n") + % b % overview->GetXSize() % overview->GetYSize(); + } +#endif + +#if 0 + for (int b = band_overviews; --b >= 0;) + { + GDALRasterBand * overview = band->GetOverview (b); + if ((start_x + width) <= overview->GetXSize() + && (start_y + height) <= overview->GetYSize()) + { +#ifdef MAPNIK_DEBUG + std::cout << boost::format("Picked Overview=%d \n") %b; +#endif + band = overview; + break; + } + } + + // band = band->GetRasterSampleOverview (width / height); + // band = band->GetOverview (band->GetOverviewCount() - 1); +#endif + } + +#ifdef MAPNIK_DEBUG + int bsx,bsy; + double scale; + band->GetBlockSize(&bsx,&bsy); + scale = band->GetScale(); + std::cout << boost::format("Block=%dx%d Scale=%f Type=%s Color=%s \n") % bsx % bsy % scale + % GDALGetDataTypeName(band->GetRasterDataType()) + % GDALGetColorInterpretationName(band->GetColorInterpretation()); +#endif + + GDALColorInterp color_interp = band->GetColorInterpretation(); + switch (color_interp) + { + case GCI_RedBand: + red = band; + break; + case GCI_GreenBand: + green = band; + break; + case GCI_BlueBand: + blue = band; + break; + case GCI_AlphaBand: + alpha = band; + break; + case GCI_GrayIndex: + grey = band; + break; + case GCI_PaletteIndex: + { + grey = band; + GDALColorTable *color_table = band->GetColorTable(); + + if ( color_table) + { + int count = color_table->GetColorEntryCount(); +#ifdef MAPNIK_DEBUG + std::cout << "Color Table count = " << count << "\n"; +#endif + for ( int i = 0; i < count; i++ ) + { + const GDALColorEntry *ce = color_table->GetColorEntry ( i ); + if (!ce ) continue; +#ifdef MAPNIK_DEBUG + std::cout << "color entry RGB (" << ce->c1 <<"," <c2 << "," << ce->c3 << ")\n"; +#endif + } + } + break; + } + case GCI_Undefined: + grey = band; + break; + default: + break; + } + } + mapnik::ImageData32 image(width,height); image.set(0xffffffff); if (red && green && blue) { + //red->AdviseRead (start_x, start_y, width, height, width, height, GDT_Byte, nbands, NULL); + //green->AdviseRead(start_x, start_y, width, height, width, height, GDT_Byte, nbands, NULL); + //blue->AdviseRead (start_x, start_y, width, height, width, height, GDT_Byte, nbands, NULL); red->RasterIO (GF_Read,start_x,start_y,width,height, image.getBytes() + 0, width,height, GDT_Byte,4,4*width); green->RasterIO(GF_Read,start_x,start_y,width,height, image.getBytes() + 1, width,height, GDT_Byte,4,4*width); blue->RasterIO (GF_Read,start_x,start_y,width,height, image.getBytes() + 2, width,height, GDT_Byte,4,4*width); - if (alpha) - { - alpha->RasterIO(GF_Read,start_x,start_y,width,height, image.getBytes() + 3, width,height, GDT_Byte,4,4*width); - } } else if (grey) { + // grey->AdviseRead (start_x, start_y, width, height, width, height, GDT_Byte, nbands, NULL); grey->RasterIO(GF_Read,start_x,start_y,width,height,image.getBytes() + 0, width, height,GDT_Byte,4,4*width); grey->RasterIO(GF_Read,start_x,start_y,width,height,image.getBytes() + 1, width, height,GDT_Byte,4,4*width); grey->RasterIO(GF_Read,start_x,start_y,width,height,image.getBytes() + 2, width, height,GDT_Byte,4,4*width); - - if (alpha) - { - alpha->RasterIO(GF_Read,start_x,start_y,width,height, image.getBytes() + 3, width,height, GDT_Byte,4,4*width); - } } + + if (alpha) + { + //alpha->AdviseRead (start_x, start_y, width, height, width, height, GDT_Byte, nbands, NULL); + alpha->RasterIO(GF_Read,start_x,start_y,width,height, image.getBytes() + 3, width,height, GDT_Byte,4,4*width); + } + feature->set_raster(mapnik::raster_ptr(new mapnik::raster(intersection,image))); return feature; }