This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository mapnik-vector-tile.
commit 58af4aff88a6136b04a1ccdab57a1b83c5f6becc Author: Bas Couwenberg <[email protected]> Date: Fri Dec 25 01:44:10 2015 +0100 Imported Upstream version 0.14.2+dfsg --- CHANGELOG.md | 12 ++-- README.md | 2 +- package.json | 2 +- src/vector_tile_backend_pbf.ipp | 4 +- src/vector_tile_geometry_encoder.hpp | 6 +- src/vector_tile_processor.ipp | 10 +-- test/fixtures/alpha-white-2.png | Bin 0 -> 9102 bytes test/fixtures/expected-4.png | Bin 0 -> 8955 bytes test/raster_tile.cpp | 128 +++++++++++++++++++++++++++++++++++ 9 files changed, 149 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f46192..8cbb176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,19 @@ # Changelog +## 0.14.2 + +- Fixed premultiplication bug in raster encoding (#170) + ## 0.14.1 - Had error in publish, republishing. ## 0.14.0 - - Added the ability for the processor to ignore invalid rings and simply process them, this is exposed via the option `process_all_rings`. - - Exposed the ability for different fill types to be used - - Added the ability for multipolygons to be union or not selectively, exposed as option `multipoly_polyon_union` - - Added new test suite for geometries + - Added the ability for the processor to continue processing invalid rings rather than throwing them out. This is exposed via the option `process_all_rings`. (default is `false` meaning that all interior rings will be skipped if an invalid exterior ring is encountered) + - Exposed the ability for different fill types to be used (default is `NonZero` meaning that winding order of input polygons is expected to be reversed for interior rings vs exterior rings) + - Added the ability for multipolygons to be unioned or not, exposed as option `multipoly_polyon_union` (default is `true` meaning that overlapping polygons in a multipolygon will be unioned) + - Added new test suite for geometries to increase code coverage ## 0.13.0 diff --git a/README.md b/README.md index 5a1c2b2..94a6c47 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Provides C++ headers that support rendering geodata into vector tiles and render - Master: [](https://travis-ci.org/mapbox/mapnik-vector-tile) - 0.6.x series: [](http://travis-ci.org/mapbox/mapnik-vector-tile) -[](https://coveralls.io/r/mapbox/mapnik-vector-tile?branch=coverage) +[](https://coveralls.io/github/mapbox/mapnik-vector-tile?branch=master) ## Depends diff --git a/package.json b/package.json index a2c009a..a138a25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mapnik-vector-tile", - "version": "0.14.1", + "version": "0.14.2", "description": "Mapnik vector tile API", "main": "./package.json", "repository" : { diff --git a/src/vector_tile_backend_pbf.ipp b/src/vector_tile_backend_pbf.ipp index ee285c0..70276c1 100644 --- a/src/vector_tile_backend_pbf.ipp +++ b/src/vector_tile_backend_pbf.ipp @@ -76,9 +76,9 @@ void backend_pbf::add_tile_feature_raster(std::string const& image_buffer) void backend_pbf::stop_tile_feature() { - if (current_feature_) + if (current_layer_ && current_feature_) { - if (current_feature_->geometry_size() == 0 && current_layer_) + if (!current_feature_->has_raster() && current_feature_->geometry_size() == 0 ) { current_layer_->mutable_features()->RemoveLast(); } diff --git a/src/vector_tile_geometry_encoder.hpp b/src/vector_tile_geometry_encoder.hpp index afd2dbb..ed2c250 100644 --- a/src/vector_tile_geometry_encoder.hpp +++ b/src/vector_tile_geometry_encoder.hpp @@ -24,7 +24,7 @@ inline bool encode_geometry(mapnik::geometry::point<std::int64_t> const& pt, int32_t & start_x, int32_t & start_y) { - current_feature.add_geometry(9); // 1 | (move_to << 3) + current_feature.add_geometry(9); // move_to | (1 << 3) int32_t dx = pt.x - start_x; int32_t dy = pt.y - start_y; // Manual zigzag encoding. @@ -63,7 +63,7 @@ inline bool encode_geometry(mapnik::geometry::line_string<std::int64_t> const& l if (status == move_to) { status = line_to; - current_feature.add_geometry(9); // 1 | (move_to << 3) + current_feature.add_geometry(9); // move_to | (1 << 3) } else if (status == line_to) { @@ -114,7 +114,7 @@ inline bool encode_geometry(mapnik::geometry::linear_ring<std::int64_t> const& r if (status == move_to) { status = line_to; - current_feature.add_geometry(9); // 1 | (move_to << 3) + current_feature.add_geometry(9); // move_to | (1 << 3) } else if (status == line_to) { diff --git a/src/vector_tile_processor.ipp b/src/vector_tile_processor.ipp index ab0bc60..f521d67 100644 --- a/src/vector_tile_processor.ipp +++ b/src/vector_tile_processor.ipp @@ -107,8 +107,8 @@ public: void operator() (mapnik::image_rgba8 & source_data) { - mapnik::image_rgba8 data(raster_width_, raster_height_); - mapnik::raster target(target_ext_, data, source_.get_filter_factor()); + mapnik::image_rgba8 data(raster_width_, raster_height_, true, true); + mapnik::raster target(target_ext_, std::move(data), source_.get_filter_factor()); mapnik::premultiply_alpha(source_data); if (!prj_trans_.equal()) { @@ -133,10 +133,10 @@ public: source_.get_filter_factor()); } - using pixfmt_type = agg::pixfmt_rgba32; + using pixfmt_type = agg::pixfmt_rgba32_pre; using renderer_type = agg::renderer_base<pixfmt_type>; - mapnik::image_any im_tile(width_, height_, mapnik::image_dtype_rgba8, true, true); + mapnik::image_rgba8 im_tile(width_, height_, true, true); agg::rendering_buffer dst_buffer(im_tile.bytes(), im_tile.width(), im_tile.height(), im_tile.row_size()); agg::rendering_buffer src_buffer(target.data_.bytes(),target.data_.width(), target.data_.height(), target.data_.row_size()); pixfmt_type src_pixf(src_buffer); @@ -144,7 +144,9 @@ public: renderer_type ren(dst_pixf); ren.copy_from(src_pixf,0,start_x_, start_y_); backend_.start_tile_feature(feature_); + mapnik::demultiply_alpha(im_tile); backend_.add_tile_feature_raster(mapnik::save_to_string(im_tile,image_format_)); + backend_.stop_tile_feature(); painted_ = true; } diff --git a/test/fixtures/alpha-white-2.png b/test/fixtures/alpha-white-2.png new file mode 100644 index 0000000..89a5508 Binary files /dev/null and b/test/fixtures/alpha-white-2.png differ diff --git a/test/fixtures/expected-4.png b/test/fixtures/expected-4.png new file mode 100644 index 0000000..4db812f Binary files /dev/null and b/test/fixtures/expected-4.png differ diff --git a/test/raster_tile.cpp b/test/raster_tile.cpp index 6039873..3afb8d6 100644 --- a/test/raster_tile.cpp +++ b/test/raster_tile.cpp @@ -16,6 +16,8 @@ #include <mapnik/load_map.hpp> #include <mapnik/image_reader.hpp> #include <mapnik/image_util.hpp> +#include <mapnik/feature_factory.hpp> +#include <mapnik/raster.hpp> #include <sstream> #include <fstream> @@ -246,3 +248,129 @@ TEST_CASE( "raster tile output 2", "should be able to overzoom raster" ) { mapnik::save_to_file(im,"test/fixtures/actual-3.png","png32"); } } + +TEST_CASE( "raster tile output 3", "should be able to round trip image with alpha" ) { + mapnik::box2d<double> bbox(-20037508.342789,-20037508.342789,20037508.342789,20037508.342789); + + // create a vtile from scratch with a raster + + vector_tile::Tile tile; + std::string format("png32"); + { + mapnik::vector_tile_impl::backend_pbf backend(tile,16); + backend.start_tile_layer("layer"); + mapnik::feature_ptr feature(mapnik::feature_factory::create(std::make_shared<mapnik::context_type>(),1)); + backend.start_tile_feature(*feature); + std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader("./test/fixtures/alpha-white-2.png")); + if (!reader.get()) { + throw std::runtime_error("could not open image"); + } + mapnik::image_rgba8 im_data(reader->width(),reader->height()); + reader->read(0,0,im_data); + backend.add_tile_feature_raster(mapnik::save_to_string(im_data,format)); + backend.stop_tile_feature(); + backend.stop_tile_layer(); + } + { + REQUIRE(1 == tile.layers_size()); + vector_tile::Tile_Layer const& layer = tile.layers(0); + REQUIRE(1 == layer.features_size()); + vector_tile::Tile_Feature const& f = layer.features(0); + REQUIRE(f.has_raster()); + std::string const& ras_buffer = f.raster(); + REQUIRE(!ras_buffer.empty()); + std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(ras_buffer.data(),ras_buffer.size())); + if (!reader.get()) { + throw std::runtime_error("could not open image bytes"); + } + mapnik::image_rgba8 im_data(reader->width(),reader->height()); + reader->read(0,0,im_data); + unsigned diff = testing::compare_images(im_data,"./test/fixtures/alpha-white-2.png",0,true); + CHECK(0 == diff); + if (diff > 0) { + mapnik::save_to_file(im_data,"test/fixtures/actual-4.png",format); + } + + } + + // Now actually re-render to trigger the raster being passed through the processor + // and confirm raster still looks correct + { + // create datasource wrapping raster + unsigned tile_size = 256; + std::shared_ptr<mapnik::vector_tile_impl::tile_datasource> ds = std::make_shared< + mapnik::vector_tile_impl::tile_datasource>( + tile.layers(0),0,0,0,tile_size); + // before rendering let's query the raster directly to ensure + // the datasource returns it correctly. + mapnik::query q(bbox); + mapnik::featureset_ptr fs = ds->features(q); + mapnik::feature_ptr feat = fs->next(); + mapnik::raster_ptr const& source = feat->get_raster(); + CHECK(source->data_.is<mapnik::image_rgba8>()); + mapnik::image_rgba8 const& source_data = mapnik::util::get<mapnik::image_rgba8>(source->data_); + unsigned diff = testing::compare_images(source_data,"./test/fixtures/alpha-white-2.png",0,true); + CHECK(0 == diff); + if (diff > 0) { + mapnik::save_to_file(source_data,"test/fixtures/actual-5.png",format); + } + + // okay, now we'll re-render another vector tile from original + // which triggers the raster to be resampled + mapnik::Map map(tile_size,tile_size,"+init=epsg:3857"); + mapnik::layer lyr("layer",map.srs()); + ds->set_envelope(bbox); + lyr.set_datasource(ds); + map.add_layer(lyr); + map.zoom_to_box(bbox); + + typedef mapnik::vector_tile_impl::backend_pbf backend_type; + vector_tile::Tile round_tipped_tile; + backend_type backend(round_tipped_tile,16); + typedef mapnik::vector_tile_impl::processor<backend_type> renderer_type; + mapnik::request m_req(tile_size,tile_size,bbox); + renderer_type ren(backend, + map, + m_req, + 1.0, + 0, + 0, + 1, + false, + format, + mapnik::SCALING_BILINEAR); + ren.apply(); + REQUIRE(1 == round_tipped_tile.layers_size()); + vector_tile::Tile_Layer const& layer = round_tipped_tile.layers(0); + REQUIRE(1 == layer.features_size()); + vector_tile::Tile_Feature const& f = layer.features(0); + REQUIRE(f.has_raster()); + std::string const& ras_buffer = f.raster(); + REQUIRE(!ras_buffer.empty()); + std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(ras_buffer.data(),ras_buffer.size())); + if (!reader.get()) { + throw std::runtime_error("could not open image bytes"); + } + + mapnik::image_rgba8 im_data(reader->width(),reader->height()); + reader->read(0,0,im_data); + + if (!mapnik::util::exists("test/fixtures/expected-4.png")) { + mapnik::save_to_file(im_data,"test/fixtures/expected-4.png","png32"); + } + + diff = testing::compare_images(im_data,"test/fixtures/expected-4.png",0,true); + CHECK(0 == diff); + if (diff > 0) { + mapnik::save_to_file(im_data,"test/fixtures/actual-7.png",format); + } + + // visually identical but scaling causes some pixels shifts compared to original + diff = testing::compare_images(im_data,"./test/fixtures/alpha-white-2.png",0,true); + CHECK(13853 == diff); + if (diff > 0) { + mapnik::save_to_file(im_data,"test/fixtures/actual-7.png",format); + } + } + +} -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapnik-vector-tile.git _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

