diff --git a/CHANGELOG.md b/CHANGELOG.md index 92629c520..5d33e79b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,12 @@ Released ... Summary: TODO +- GDAL plugin: Added back support for user driven `nodata` on rgb(a) images (#2023) + +- GDAL plugin: Allowed nodata to override alpha band if set on rgba images (#2023) + +- GDAL plugin: Added `nodata_tolerance` option to set nearby pixels transparent (has similar effect to the `nearblack` program) (#2023) + - Added support for web fonts: .woff format (#2113) - Added missing support for `geometry-transform` in `line-pattern` and `polygon-pattern` symbolizers (#2065) diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp index a69af804b..41f944d8a 100644 --- a/plugins/input/gdal/gdal_datasource.cpp +++ b/plugins/input/gdal/gdal_datasource.cpp @@ -77,7 +77,8 @@ inline GDALDataset* gdal_datasource::open_dataset() const gdal_datasource::gdal_datasource(parameters const& params) : datasource(params), desc_(*params.get("type"), "utf-8"), - nodata_value_(params.get("nodata")) + nodata_value_(params.get("nodata")), + nodata_tolerance_(*params.get("nodata_tolerance",1e-12)) { MAPNIK_LOG_DEBUG(gdal) << "gdal_datasource: Initializing..."; @@ -132,17 +133,29 @@ gdal_datasource::gdal_datasource(parameters const& params) tr[3] = extent_.maxy(); tr[4] = 0; tr[5] = -extent_.height() / (double)height_; + MAPNIK_LOG_DEBUG(gdal) << "gdal_datasource extent override gives Geotransform=" + << tr[0] << "," << tr[1] << "," + << tr[2] << "," << tr[3] << "," + << tr[4] << "," << tr[5]; } else { - dataset->GetGeoTransform(tr); + if (dataset->GetGeoTransform(tr) != CPLE_None) + { + MAPNIK_LOG_DEBUG(gdal) << "gdal_datasource GetGeotransform failure gives=" + << tr[0] << "," << tr[1] << "," + << tr[2] << "," << tr[3] << "," + << tr[4] << "," << tr[5]; + } + else + { + MAPNIK_LOG_DEBUG(gdal) << "gdal_datasource Geotransform=" + << tr[0] << "," << tr[1] << "," + << tr[2] << "," << tr[3] << "," + << tr[4] << "," << tr[5]; + } } - MAPNIK_LOG_DEBUG(gdal) << "gdal_datasource Geotransform=" - << tr[0] << "," << tr[1] << "," - << tr[2] << "," << tr[3] << "," - << tr[4] << "," << tr[5]; - // TODO - We should throw for true non-north up images, but the check // below is clearly too restrictive. // https://github.com/mapnik/mapnik/issues/970 @@ -228,7 +241,8 @@ featureset_ptr gdal_datasource::features(query const& q) const nbands_, dx_, dy_, - nodata_value_)); + nodata_value_, + nodata_tolerance_)); } featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol) const @@ -249,5 +263,6 @@ featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol) nbands_, dx_, dy_, - nodata_value_)); + nodata_value_, + nodata_tolerance_)); } diff --git a/plugins/input/gdal/gdal_datasource.hpp b/plugins/input/gdal/gdal_datasource.hpp index d73682682..bb43b95bd 100644 --- a/plugins/input/gdal/gdal_datasource.hpp +++ b/plugins/input/gdal/gdal_datasource.hpp @@ -67,6 +67,7 @@ private: int nbands_; bool shared_dataset_; boost::optional nodata_value_; + double nodata_tolerance_; }; #endif // GDAL_DATASOURCE_HPP diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp index 03196c442..aa249a918 100644 --- a/plugins/input/gdal/gdal_featureset.cpp +++ b/plugins/input/gdal/gdal_featureset.cpp @@ -34,6 +34,7 @@ #include // stl #include +#include #include "gdal_featureset.hpp" #include @@ -60,7 +61,8 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset, int nbands, double dx, double dy, - boost::optional const& nodata) + boost::optional const& nodata, + double nodata_tolerance) : dataset_(dataset), ctx_(std::make_shared()), band_(band), @@ -72,6 +74,7 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset, dy_(dy), nbands_(nbands), nodata_value_(nodata), + nodata_tolerance_(nodata_tolerance), first_(true) { ctx_->push("nodata"); @@ -287,13 +290,13 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing rgb bands..."; raster_nodata = red->GetNoDataValue(&raster_has_nodata); GDALColorTable *color_table = red->GetColorTable(); - if (!alpha && raster_has_nodata && !color_table) + bool has_nodata = nodata_value_ || raster_has_nodata; + if (has_nodata && !color_table) { + double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; // read the data in and create an alpha channel from the nodata values - // NOTE: we intentionally ignore user supplied nodata value since it only - // works for grayscale images or a single band (as a double) - // TODO - we assume here the nodata value for the red band applies to all band - // but that may not always be the case: http://trac.osgeo.org/gdal/ticket/2734 + // 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.getBytes(); red->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), @@ -301,7 +304,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { - if (std::fabs(raster_nodata - imageData[i]) < 1e-12) + if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_) { *reinterpret_cast(&imageData[i]) = 0; } @@ -336,7 +339,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { - if (std::fabs(apply_nodata - imageData[i]) < 1e-12) + if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_) { *reinterpret_cast(&imageData[i]) = 0; } @@ -380,12 +383,15 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) if (alpha) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: processing alpha band..."; - if (raster_has_nodata) + if (!raster_has_nodata) { - MAPNIK_LOG_ERROR(gdal) << "warning: alpha channel being used instead of nodata value"; + alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 3, + image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); + } + else + { + MAPNIK_LOG_ERROR(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of 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()); } } // set nodata value to be used in raster colorizer diff --git a/plugins/input/gdal/gdal_featureset.hpp b/plugins/input/gdal/gdal_featureset.hpp index b97730995..c7aeb645b 100644 --- a/plugins/input/gdal/gdal_featureset.hpp +++ b/plugins/input/gdal/gdal_featureset.hpp @@ -67,7 +67,8 @@ public: int nbands, double dx, double dy, - boost::optional const& nodata); + boost::optional const& nodata, + double nodata_tolerance); virtual ~gdal_featureset(); mapnik::feature_ptr next(); @@ -90,6 +91,7 @@ private: double dy_; int nbands_; boost::optional nodata_value_; + double nodata_tolerance_; bool first_; }; diff --git a/tests/visual_tests/data/aerial_rgba.tiff b/tests/visual_tests/data/aerial_rgba.tiff new file mode 100644 index 000000000..bccfd575d Binary files /dev/null and b/tests/visual_tests/data/aerial_rgba.tiff differ diff --git a/tests/visual_tests/data/heat_nodata.tif b/tests/visual_tests/data/heat_nodata.tif new file mode 100644 index 000000000..ed6d71ea7 Binary files /dev/null and b/tests/visual_tests/data/heat_nodata.tif differ diff --git a/tests/visual_tests/data/heat_rgb.tif b/tests/visual_tests/data/heat_rgb.tif new file mode 100644 index 000000000..c9ad3b57b Binary files /dev/null and b/tests/visual_tests/data/heat_rgb.tif differ diff --git a/tests/visual_tests/grids/tiff-nodata-edge-rgba-500-100-1.0-grid-reference.json b/tests/visual_tests/grids/tiff-nodata-edge-rgba-500-100-1.0-grid-reference.json new file mode 100644 index 000000000..dcf3d346b --- /dev/null +++ b/tests/visual_tests/grids/tiff-nodata-edge-rgba-500-100-1.0-grid-reference.json @@ -0,0 +1,33 @@ +{ + "keys": [ + "" + ], + "data": {}, + "grid": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ] +} \ No newline at end of file diff --git a/tests/visual_tests/grids/tiff-nodata-rgb-512-512-1.0-grid-reference.json b/tests/visual_tests/grids/tiff-nodata-rgb-512-512-1.0-grid-reference.json new file mode 100644 index 000000000..53162f357 --- /dev/null +++ b/tests/visual_tests/grids/tiff-nodata-rgb-512-512-1.0-grid-reference.json @@ -0,0 +1,136 @@ +{ + "keys": [ + "" + ], + "data": {}, + "grid": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ] +} \ No newline at end of file diff --git a/tests/visual_tests/grids/tiff-nodata-rgba-512-512-1.0-grid-reference.json b/tests/visual_tests/grids/tiff-nodata-rgba-512-512-1.0-grid-reference.json new file mode 100644 index 000000000..53162f357 --- /dev/null +++ b/tests/visual_tests/grids/tiff-nodata-rgba-512-512-1.0-grid-reference.json @@ -0,0 +1,136 @@ +{ + "keys": [ + "" + ], + "data": {}, + "grid": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ] +} \ No newline at end of file diff --git a/tests/visual_tests/grids/tiff-nodata-tolerance-512-512-1.0-grid-reference.json b/tests/visual_tests/grids/tiff-nodata-tolerance-512-512-1.0-grid-reference.json new file mode 100644 index 000000000..53162f357 --- /dev/null +++ b/tests/visual_tests/grids/tiff-nodata-tolerance-512-512-1.0-grid-reference.json @@ -0,0 +1,136 @@ +{ + "keys": [ + "" + ], + "data": {}, + "grid": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ] +} \ No newline at end of file diff --git a/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-1.0-agg-reference.png b/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-1.0-agg-reference.png new file mode 100644 index 000000000..c9c2fbeab Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-1.0-agg-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-1.0-cairo-reference.png b/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-1.0-cairo-reference.png new file mode 100644 index 000000000..eec8d04e1 Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-1.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-2.0-agg-reference.png b/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-2.0-agg-reference.png new file mode 100644 index 000000000..c9c2fbeab Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-2.0-agg-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-2.0-cairo-reference.png b/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-2.0-cairo-reference.png new file mode 100644 index 000000000..eec8d04e1 Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-edge-rgba-500-100-2.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-rgb-512-512-1.0-agg-reference.png b/tests/visual_tests/images/tiff-nodata-rgb-512-512-1.0-agg-reference.png new file mode 100644 index 000000000..e17dd9c3f Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-rgb-512-512-1.0-agg-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-rgb-512-512-1.0-cairo-reference.png b/tests/visual_tests/images/tiff-nodata-rgb-512-512-1.0-cairo-reference.png new file mode 100644 index 000000000..e01309a3d Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-rgb-512-512-1.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-rgb-512-512-2.0-agg-reference.png b/tests/visual_tests/images/tiff-nodata-rgb-512-512-2.0-agg-reference.png new file mode 100644 index 000000000..e17dd9c3f Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-rgb-512-512-2.0-agg-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-rgb-512-512-2.0-cairo-reference.png b/tests/visual_tests/images/tiff-nodata-rgb-512-512-2.0-cairo-reference.png new file mode 100644 index 000000000..e01309a3d Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-rgb-512-512-2.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-rgba-512-512-1.0-agg-reference.png b/tests/visual_tests/images/tiff-nodata-rgba-512-512-1.0-agg-reference.png new file mode 100644 index 000000000..ef1625a41 Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-rgba-512-512-1.0-agg-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-rgba-512-512-1.0-cairo-reference.png b/tests/visual_tests/images/tiff-nodata-rgba-512-512-1.0-cairo-reference.png new file mode 100644 index 000000000..96be15b9e Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-rgba-512-512-1.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-rgba-512-512-2.0-agg-reference.png b/tests/visual_tests/images/tiff-nodata-rgba-512-512-2.0-agg-reference.png new file mode 100644 index 000000000..ef1625a41 Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-rgba-512-512-2.0-agg-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-rgba-512-512-2.0-cairo-reference.png b/tests/visual_tests/images/tiff-nodata-rgba-512-512-2.0-cairo-reference.png new file mode 100644 index 000000000..96be15b9e Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-rgba-512-512-2.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-tolerance-512-512-1.0-agg-reference.png b/tests/visual_tests/images/tiff-nodata-tolerance-512-512-1.0-agg-reference.png new file mode 100644 index 000000000..f33b25a85 Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-tolerance-512-512-1.0-agg-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-tolerance-512-512-1.0-cairo-reference.png b/tests/visual_tests/images/tiff-nodata-tolerance-512-512-1.0-cairo-reference.png new file mode 100644 index 000000000..f33b25a85 Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-tolerance-512-512-1.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-tolerance-512-512-2.0-agg-reference.png b/tests/visual_tests/images/tiff-nodata-tolerance-512-512-2.0-agg-reference.png new file mode 100644 index 000000000..f33b25a85 Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-tolerance-512-512-2.0-agg-reference.png differ diff --git a/tests/visual_tests/images/tiff-nodata-tolerance-512-512-2.0-cairo-reference.png b/tests/visual_tests/images/tiff-nodata-tolerance-512-512-2.0-cairo-reference.png new file mode 100644 index 000000000..f33b25a85 Binary files /dev/null and b/tests/visual_tests/images/tiff-nodata-tolerance-512-512-2.0-cairo-reference.png differ diff --git a/tests/visual_tests/styles/tiff-nodata-edge-rgba.xml b/tests/visual_tests/styles/tiff-nodata-edge-rgba.xml new file mode 100644 index 000000000..4d56afb77 --- /dev/null +++ b/tests/visual_tests/styles/tiff-nodata-edge-rgba.xml @@ -0,0 +1,17 @@ + + + + heat + + ../data/aerial_rgba.tiff + gdal + 255 + 5 + + + \ No newline at end of file diff --git a/tests/visual_tests/styles/tiff-nodata-rgb.xml b/tests/visual_tests/styles/tiff-nodata-rgb.xml new file mode 100644 index 000000000..decad10d8 --- /dev/null +++ b/tests/visual_tests/styles/tiff-nodata-rgb.xml @@ -0,0 +1,17 @@ + + + + heat + + + ../data/heat_rgb.tif + gdal + 255 + + + \ No newline at end of file diff --git a/tests/visual_tests/styles/tiff-nodata-rgba.xml b/tests/visual_tests/styles/tiff-nodata-rgba.xml new file mode 100644 index 000000000..80e674e15 --- /dev/null +++ b/tests/visual_tests/styles/tiff-nodata-rgba.xml @@ -0,0 +1,16 @@ + + + + heat + + + ../data/heat_nodata.tif + gdal + + + \ No newline at end of file diff --git a/tests/visual_tests/styles/tiff-nodata-tolerance.xml b/tests/visual_tests/styles/tiff-nodata-tolerance.xml new file mode 100644 index 000000000..05956a1be --- /dev/null +++ b/tests/visual_tests/styles/tiff-nodata-tolerance.xml @@ -0,0 +1,19 @@ + + + + + + test + + ../data/Yosemite_L9.tif + gdal + 255 + 100 + + + + \ No newline at end of file diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 06b529996..7576fa6d8 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -214,6 +214,9 @@ files = { 'image-filters-galore':{'sizes':[(512,512)]}, 'image-filters-multi-blur':{'sizes':[(512,512)]}, 'line-opacity-multi-render':{'sizes':[(512,512)]}, + 'tiff-nodata-rgb':{'sizes':[(512,512)]}, + 'tiff-nodata-rgba':{'sizes':[(512,512)]}, + 'tiff-nodata-tolerance':{'sizes':[(512,512)]}, 'marker-vs-point':{'sizes':[(512,512)]} }