[mapnik-vector-tile] 01/05: Imported Upstream version 0.13.0+dfsg

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sun Oct 11 09:02:28 UTC 2015


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 e95c4a5963adae13039bd80d9db6817260e7b8fd
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sun Oct 11 10:43:39 2015 +0200

    Imported Upstream version 0.13.0+dfsg
---
 CHANGELOG.md                           |  15 ++++
 Makefile                               |   4 +-
 bench/vtile-decode.cpp                 |  20 ++---
 bootstrap.sh                           |  19 ++---
 package.json                           |   2 +-
 src/vector_tile_datasource.ipp         |   4 +-
 src/vector_tile_datasource_pbf.ipp     |   9 ++-
 src/vector_tile_geometry_decoder.hpp   | 109 +++++++++++++------------
 src/vector_tile_geometry_encoder.hpp   |   2 +-
 src/vector_tile_processor.ipp          |  57 +++++--------
 src/vector_tile_util.ipp               | 144 ++++++++++++++++-----------------
 test/data/invalid-interior-ring.json   |   4 +-
 test/encoding_util.hpp                 |   4 +-
 test/fixtures/transform-expected-2.png | Bin 0 -> 506 bytes
 test/geometry_encoding.cpp             |  32 ++++----
 test/vector_tile.cpp                   |  26 +++---
 test/vector_tile_pbf.cpp               |  46 +++++------
 17 files changed, 241 insertions(+), 256 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b41e51..e8a1eba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
 # Changelog
 
+## 0.13.0
+
+ - Updated the geometry decoder so that it now supports a variety of geometry formats with the ability to return mapnik 
+   geometries in value types other then doubles.
+
+## 0.12.1
+
+ - Removed repeated points of linestrings prior to them being encoded.
+
+## 0.12.0
+
+ - Reversed the winding order of the geometries that comes out of the angus clipper so they are not reversed again prior to encoding
+ - Fixed an issue with nonZero fill not being applied on multipolygons
+ - Removed unrequired unioning clipping operations as union of different paths occurs during the intersection operation.
+
 ## 0.11.0
 
  - Changed processor so that it now can optionally turn on and off strict enforcing of simple geometries from the clipper
diff --git a/Makefile b/Makefile
index 1e05b3d..e49af36 100755
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 MAPNIK_PLUGINDIR := $(shell mapnik-config --input-plugins)
 BUILDTYPE ?= Release
 
-CLIPPER_REVISION=b848b91877b6f0121356aaf813e8b9a45f929daa
+CLIPPER_REVISION=7484da1
 PROTOZERO_REVISION=v1.0.0
 GYP_REVISION=3464008
 
@@ -33,6 +33,8 @@ testpack:
 
 clean:
 	rm -rf ./build
+	rm -rf ./deps/protozero
+	rm -rf ./deps/clipper
 
 .PHONY: test
 
diff --git a/bench/vtile-decode.cpp b/bench/vtile-decode.cpp
index 7dafbe5..c56314a 100644
--- a/bench/vtile-decode.cpp
+++ b/bench/vtile-decode.cpp
@@ -69,18 +69,14 @@ int main(int argc, char** argv)
             for (std::size_t i=0;i<iterations;++i)
             {
                 protozero::pbf_reader tile(message);
-                while (tile.next()) {
-                    if (tile.tag() == 3) {
-                        ++layer_count;
-                        protozero::pbf_reader layer = tile.get_message();
-                        auto ds = std::make_shared<mapnik::vector_tile_impl::tile_datasource_pbf>(layer,x,y,z,256);
-                        mapnik::query q(ds->get_tile_extent());
-                        auto fs = ds->features(q);
-                        while (fs->next()) {
-                            ++feature_count;
-                        }
-                    } else {
-                        tile.skip();
+                while (tile.next(3)) {
+                    ++layer_count;
+                    protozero::pbf_reader layer = tile.get_message();
+                    auto ds = std::make_shared<mapnik::vector_tile_impl::tile_datasource_pbf>(layer,x,y,z,256);
+                    mapnik::query q(ds->get_tile_extent());
+                    auto fs = ds->features(q);
+                    while (fs->next()) {
+                        ++feature_count;
                     }
                 }
             }
diff --git a/bootstrap.sh b/bootstrap.sh
index c2c6ced..6be6c65 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -21,33 +21,30 @@ function install() {
     fi
 }
 
+ICU_VERSION="55.1"
+
 function install_mason_deps() {
     install mapnik latest
     install protobuf 2.6.1
-    install freetype 2.5.5
+    install freetype 2.6
     install harfbuzz 0.9.40
     install jpeg_turbo 1.4.0
     install libxml2 2.9.2
     install libpng 1.6.17
     install webp 0.4.2
-    install icu 54.1
+    install icu ${ICU_VERSION}
     install proj 4.8.0
     install libtiff 4.0.4beta
-    install boost 1.57.0
-    install boost_libsystem 1.57.0
-    install boost_libthread 1.57.0
-    install boost_libfilesystem 1.57.0
-    install boost_libprogram_options 1.57.0
-    install boost_libregex 1.57.0
-    install boost_libpython 1.57.0
+    install boost 1.59.0
+    install boost_liball 1.59.0
     install pixman 0.32.6
-    install cairo 1.12.18
+    install cairo 1.14.2
 }
 
 function setup_runtime_settings() {
     local MASON_LINKED_ABS=$(pwd)/mason_packages/.link
     export PROJ_LIB=${MASON_LINKED_ABS}/share/proj
-    export ICU_DATA=${MASON_LINKED_ABS}/share/icu/54.1
+    export ICU_DATA=${MASON_LINKED_ABS}/share/icu/${ICU_VERSION}
     export GDAL_DATA=${MASON_LINKED_ABS}/share/gdal
     if [[ $(uname -s) == 'Darwin' ]]; then
         export DYLD_LIBRARY_PATH=$(pwd)/mason_packages/.link/lib:${DYLD_LIBRARY_PATH}
diff --git a/package.json b/package.json
index 59b972c..df39880 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "mapnik-vector-tile",
-    "version": "0.11.0",
+    "version": "0.13.0",
     "description": "Mapnik vector tile API",
     "main": "./package.json",
     "repository"   :  {
diff --git a/src/vector_tile_datasource.ipp b/src/vector_tile_datasource.ipp
index aa35119..acd297d 100644
--- a/src/vector_tile_datasource.ipp
+++ b/src/vector_tile_datasource.ipp
@@ -199,8 +199,8 @@ namespace mapnik { namespace vector_tile_impl {
                 {
                     continue;
                 }
-                mapnik::vector_tile_impl::Geometry geoms(f,tile_x_, tile_y_, scale_, -1*scale_);
-                mapnik::geometry::geometry<double> geom = decode_geometry(geoms, f.type(), filter_.box_);
+                mapnik::vector_tile_impl::Geometry<double> geoms(f,tile_x_, tile_y_, scale_, -1*scale_);
+                mapnik::geometry::geometry<double> geom = decode_geometry<double>(geoms, f.type(), filter_.box_);
                 if (geom.is<mapnik::geometry::geometry_empty>())
                 {
                     continue;
diff --git a/src/vector_tile_datasource_pbf.ipp b/src/vector_tile_datasource_pbf.ipp
index 3bc5a7a..e72d179 100644
--- a/src/vector_tile_datasource_pbf.ipp
+++ b/src/vector_tile_datasource_pbf.ipp
@@ -107,6 +107,7 @@ namespace mapnik { namespace vector_tile_impl {
                                 for (auto _i = tag_iterator.first; _i != tag_iterator.second;)
                                 {
                                     std::size_t key_name = *(_i++);
+                                    assert(_i != tag_iterator.second);
                                     std::size_t key_value = *(_i++);
                                     if (key_name < num_keys_
                                         && key_value < num_values_)
@@ -162,8 +163,8 @@ namespace mapnik { namespace vector_tile_impl {
                             break;
                         case 5:
                             {
-                            std::string const& image_buffer = f.get_bytes();
-                            std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(image_buffer.data(),image_buffer.size()));
+                            auto image_buffer = f.get_data();
+                            std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(image_buffer.first, image_buffer.second));
                             if (reader.get())
                             {
                                 int image_width = reader->width();
@@ -213,8 +214,8 @@ namespace mapnik { namespace vector_tile_impl {
                         case 4:
                             {
                                 auto geom_itr = f.get_packed_uint32();
-                                mapnik::vector_tile_impl::GeometryPBF geoms(geom_itr, tile_x_,tile_y_,scale_,-1*scale_);
-                                mapnik::geometry::geometry<double> geom = decode_geometry(geoms, geometry_type, filter_.box_);
+                                mapnik::vector_tile_impl::GeometryPBF<double> geoms(geom_itr, tile_x_,tile_y_,scale_,-1*scale_);
+                                mapnik::geometry::geometry<double> geom = decode_geometry<double>(geoms, geometry_type, filter_.box_);
                                 if (geom.is<mapnik::geometry::geometry_empty>())
                                 {
                                     continue;
diff --git a/src/vector_tile_geometry_decoder.hpp b/src/vector_tile_geometry_decoder.hpp
index e577014..09d2c77 100644
--- a/src/vector_tile_geometry_decoder.hpp
+++ b/src/vector_tile_geometry_decoder.hpp
@@ -21,21 +21,22 @@ namespace mapnik { namespace vector_tile_impl {
 
 // NOTE: this object is for one-time use.  Once you've progressed to the end
 //       by calling next(), to re-iterate, you must construct a new object
+template <typename ValueType>
 class Geometry {
 
 public:
     inline explicit Geometry(vector_tile::Tile_Feature const& f,
-                             double tile_x, double tile_y,
+                             ValueType tile_x, ValueType tile_y,
                              double scale_x, double scale_y);
 
     enum command : uint8_t {
         end = 0,
-            move_to = 1,
-            line_to = 2,
-            close = 7
-            };
+        move_to = 1,
+        line_to = 2,
+        close = 7
+    };
 
-    inline command next(double& rx, double& ry, std::uint32_t & len);
+    inline command next(ValueType & rx, ValueType & ry, std::uint32_t & len);
 
 private:
     vector_tile::Tile_Feature const& f_;
@@ -45,17 +46,18 @@ private:
     uint32_t geoms_;
     uint8_t cmd;
     uint32_t length;
-    double x, y;
-    double ox, oy;
+    ValueType x, y;
+    ValueType ox, oy;
 };
 
 // NOTE: this object is for one-time use.  Once you've progressed to the end
 //       by calling next(), to re-iterate, you must construct a new object
+template <typename ValueType>
 class GeometryPBF {
 
 public:
     inline explicit GeometryPBF(std::pair< protozero::pbf_reader::const_uint32_iterator, protozero::pbf_reader::const_uint32_iterator > const& geo_iterator,
-                             double tile_x, double tile_y,
+                             ValueType tile_x, ValueType tile_y,
                              double scale_x, double scale_y);
 
     enum command : uint8_t
@@ -66,7 +68,7 @@ public:
         close = 7
     };
 
-    inline command next(double& rx, double& ry, std::uint32_t & len);
+    inline command next(ValueType & rx, ValueType & ry, std::uint32_t & len);
 
 private:
     std::pair< protozero::pbf_reader::const_uint32_iterator, protozero::pbf_reader::const_uint32_iterator > geo_iterator_;
@@ -74,12 +76,14 @@ private:
     double scale_y_;
     uint8_t cmd;
     std::uint32_t length;
-    double x, y;
-    double ox, oy;
+    ValueType x, y;
+    ValueType ox, oy;
 };
 
-Geometry::Geometry(vector_tile::Tile_Feature const& f,
-                   double tile_x, double tile_y,
+
+template <typename ValueType>
+Geometry<ValueType>::Geometry(vector_tile::Tile_Feature const& f,
+                   ValueType tile_x, ValueType tile_y,
                    double scale_x, double scale_y)
     : f_(f),
       scale_x_(scale_x),
@@ -91,7 +95,8 @@ Geometry::Geometry(vector_tile::Tile_Feature const& f,
       x(tile_x), y(tile_y),
       ox(0), oy(0) {}
 
-Geometry::command Geometry::next(double& rx, double& ry, std::uint32_t & len)
+template <typename ValueType>
+typename Geometry<ValueType>::command Geometry<ValueType>::next(ValueType & rx, ValueType & ry, std::uint32_t & len)
 {
     if (k < geoms_)
     {
@@ -110,8 +115,8 @@ Geometry::command Geometry::next(double& rx, double& ry, std::uint32_t & len)
             int32_t dy = f_.geometry(k++);
             dx = ((dx >> 1) ^ (-(dx & 1)));
             dy = ((dy >> 1) ^ (-(dy & 1)));
-            x += (static_cast<double>(dx) / scale_x_);
-            y += (static_cast<double>(dy) / scale_y_);
+            x += static_cast<ValueType>(static_cast<double>(dx) / scale_x_);
+            y += static_cast<ValueType>(static_cast<double>(dy) / scale_y_);
             rx = x;
             ry = y;
             if (cmd == move_to) {
@@ -138,8 +143,9 @@ Geometry::command Geometry::next(double& rx, double& ry, std::uint32_t & len)
     }
 }
 
-GeometryPBF::GeometryPBF(std::pair<protozero::pbf_reader::const_uint32_iterator, protozero::pbf_reader::const_uint32_iterator > const& geo_iterator,
-                   double tile_x, double tile_y,
+template <typename ValueType>
+GeometryPBF<ValueType>::GeometryPBF(std::pair<protozero::pbf_reader::const_uint32_iterator, protozero::pbf_reader::const_uint32_iterator > const& geo_iterator,
+                   ValueType tile_x, ValueType tile_y,
                    double scale_x, double scale_y)
     : geo_iterator_(geo_iterator),
       scale_x_(scale_x),
@@ -149,7 +155,8 @@ GeometryPBF::GeometryPBF(std::pair<protozero::pbf_reader::const_uint32_iterator,
       x(tile_x), y(tile_y),
       ox(0), oy(0) {}
 
-GeometryPBF::command GeometryPBF::next(double& rx, double& ry, std::uint32_t & len)
+template <typename ValueType>
+typename GeometryPBF<ValueType>::command GeometryPBF<ValueType>::next(ValueType & rx, ValueType & ry, std::uint32_t & len)
 {
     if (geo_iterator_.first != geo_iterator_.second)
     {
@@ -168,8 +175,8 @@ GeometryPBF::command GeometryPBF::next(double& rx, double& ry, std::uint32_t & l
             int32_t dy = *geo_iterator_.first++;
             dx = ((dx >> 1) ^ (-(dx & 1)));
             dy = ((dy >> 1) ^ (-(dy & 1)));
-            x += (static_cast<double>(dx) / scale_x_);
-            y += (static_cast<double>(dy) / scale_y_);
+            x += static_cast<ValueType>(static_cast<double>(dx) / scale_x_);
+            y += static_cast<ValueType>(static_cast<double>(dy) / scale_y_);
             rx = x;
             ry = y;
             if (cmd == move_to)
@@ -203,12 +210,12 @@ GeometryPBF::command GeometryPBF::next(double& rx, double& ry, std::uint32_t & l
 
 namespace detail {
 
-template <typename T>
-void decode_point(mapnik::geometry::geometry<double> & geom, T & paths, mapnik::box2d<double> const& bbox)
+template <typename ValueType, typename T>
+void decode_point(mapnik::geometry::geometry<ValueType> & geom, T & paths, mapnik::box2d<double> const& bbox)
 {
     typename T::command cmd;
-    double x1, y1;
-    mapnik::geometry::multi_point<double> mp;
+    ValueType x1, y1;
+    mapnik::geometry::multi_point<ValueType> mp;
     bool first = true;
     std::uint32_t len;
     while ((cmd = paths.next(x1, y1, len)) != T::end)
@@ -251,12 +258,12 @@ void decode_point(mapnik::geometry::geometry<double> & geom, T & paths, mapnik::
     }
 }
 
-template <typename T>
-void decode_linestring(mapnik::geometry::geometry<double> & geom, T & paths, mapnik::box2d<double> const& bbox)
+template <typename ValueType, typename T>
+void decode_linestring(mapnik::geometry::geometry<ValueType> & geom, T & paths, mapnik::box2d<double> const& bbox)
 {
     typename T::command cmd;
-    double x1, y1;
-    mapnik::geometry::multi_line_string<double> multi_line;
+    ValueType x1, y1;
+    mapnik::geometry::multi_line_string<ValueType> multi_line;
     multi_line.emplace_back();
     bool first = true;
     bool first_line_to = true;
@@ -330,14 +337,14 @@ void decode_linestring(mapnik::geometry::geometry<double> & geom, T & paths, map
     }
 }
 
-template <typename T>
-void read_rings(std::vector<mapnik::geometry::linear_ring<double>> & rings,
+template <typename ValueType, typename T>
+void read_rings(std::vector<mapnik::geometry::linear_ring<ValueType> > & rings,
                 T & paths, mapnik::box2d<double> const& bbox)
 {
     typename T::command cmd;
-    double x1, y1;
+    ValueType x1, y1;
     rings.emplace_back();
-    double x2,y2;
+    ValueType x2, y2;
     bool first = true;
     bool first_line_to = true;
     std::uint32_t len;
@@ -404,8 +411,8 @@ void read_rings(std::vector<mapnik::geometry::linear_ring<double>> & rings,
     }
 }
 
-template <typename T>
-void decode_polygons(mapnik::geometry::geometry<double> & geom, T && rings)
+template <typename ValueType, typename T>
+void decode_polygons(mapnik::geometry::geometry<ValueType> & geom, T && rings)
 {
     auto rings_itr = std::make_move_iterator(rings.begin());
     auto rings_end = std::make_move_iterator(rings.end());
@@ -423,13 +430,13 @@ void decode_polygons(mapnik::geometry::geometry<double> & geom, T && rings)
             std::reverse(rings_itr->begin(), rings_itr->end());
         }
         // return the single polygon without interior rings
-        mapnik::geometry::polygon<double> poly;
+        mapnik::geometry::polygon<ValueType> poly;
         poly.set_exterior_ring(std::move(*rings_itr));
         geom = std::move(poly);
     }
     else
     {
-        mapnik::geometry::multi_polygon<double> multi_poly;
+        mapnik::geometry::multi_polygon<ValueType> multi_poly;
         bool first = true;
         bool is_clockwise = true;
         for (; rings_itr != rings_end; ++rings_itr)
@@ -478,7 +485,7 @@ void decode_polygons(mapnik::geometry::geometry<double> & geom, T && rings)
         if (num_poly == 1)
         {
             auto itr = std::make_move_iterator(multi_poly.begin());
-            geom = mapnik::geometry::polygon<double>(std::move(*itr));
+            geom = mapnik::geometry::polygon<ValueType>(std::move(*itr));
         }
         else
         {
@@ -489,26 +496,26 @@ void decode_polygons(mapnik::geometry::geometry<double> & geom, T && rings)
 
 } // ns detail
 
-template <typename T>
-inline mapnik::geometry::geometry<double> decode_geometry(T & paths, int32_t geom_type, mapnik::box2d<double> const& bbox)
+template <typename ValueType, typename T>
+inline mapnik::geometry::geometry<ValueType> decode_geometry(T & paths, int32_t geom_type, mapnik::box2d<double> const& bbox)
 {
-    mapnik::geometry::geometry<double> geom; // output geometry
+    mapnik::geometry::geometry<ValueType> geom; // output geometry
     switch (geom_type)
     {
     case vector_tile::Tile_GeomType_POINT:
     {
-        detail::decode_point(geom, paths, bbox);
+        detail::decode_point<ValueType, T>(geom, paths, bbox);
         break;
     }
     case vector_tile::Tile_GeomType_LINESTRING:
     {
-        detail::decode_linestring(geom, paths, bbox);
+        detail::decode_linestring<ValueType, T>(geom, paths, bbox);
         break;
     }
     case vector_tile::Tile_GeomType_POLYGON:
     {
-        std::vector<mapnik::geometry::linear_ring<double>> rings;
-        detail::read_rings(rings, paths, bbox);
+        std::vector<mapnik::geometry::linear_ring<ValueType> > rings;
+        detail::read_rings<ValueType, T>(rings, paths, bbox);
         if (rings.empty())
         {
             geom = mapnik::geometry::geometry_empty();
@@ -531,15 +538,15 @@ inline mapnik::geometry::geometry<double> decode_geometry(T & paths, int32_t geo
 
 // For back compatibility in tests / for cases where performance is not critical
 // TODO: consider removing and always requiring bbox arg
-template <typename T>
-inline mapnik::geometry::geometry<double> decode_geometry(T & paths, int32_t geom_type)
+template <typename ValueType, typename T>
+inline mapnik::geometry::geometry<ValueType> decode_geometry(T & paths, int32_t geom_type)
 {
 
-    mapnik::box2d<double> bbox(-std::numeric_limits<double>::max(),
-                               -std::numeric_limits<double>::max(),
+    mapnik::box2d<double> bbox(std::numeric_limits<double>::lowest(),
+                               std::numeric_limits<double>::lowest(),
                                std::numeric_limits<double>::max(),
                                std::numeric_limits<double>::max());
-    return decode_geometry(paths,geom_type,bbox);
+    return decode_geometry<ValueType>(paths,geom_type,bbox);
 }
 
 }} // end ns
diff --git a/src/vector_tile_geometry_encoder.hpp b/src/vector_tile_geometry_encoder.hpp
index 42cdbdd..afd2dbb 100644
--- a/src/vector_tile_geometry_encoder.hpp
+++ b/src/vector_tile_geometry_encoder.hpp
@@ -10,7 +10,7 @@
 
 #include <mapnik/geometry.hpp>
 #include "vector_tile_config.hpp"
-#include <protozero/pbf_writer.hpp>
+#include <protozero/varint.hpp>
 
 #include <cstdlib>
 #include <cmath>
diff --git a/src/vector_tile_processor.ipp b/src/vector_tile_processor.ipp
index e642e21..0d23eeb 100644
--- a/src/vector_tile_processor.ipp
+++ b/src/vector_tile_processor.ipp
@@ -868,6 +868,7 @@ inline void process_polynode_branch(ClipperLib::PolyNode* polynode,
                 if (ring->Contour.size() < 3) continue; // Throw out invalid holes
                 double inner_area = ClipperLib::Area(ring->Contour);
                 if (std::abs(inner_area) < area_threshold) continue;
+                
                 if (inner_area < 0)
                 {
                     std::reverse(ring->Contour.begin(), ring->Contour.end());
@@ -943,6 +944,7 @@ struct encoder_visitor {
     bool operator() (mapnik::geometry::line_string<std::int64_t> & geom)
     {
         bool painted = false;
+        boost::geometry::unique(geom);
         if (geom.size() < 2)
         {
             // This is false because it means the original data was invalid
@@ -982,6 +984,7 @@ struct encoder_visitor {
         clip_box.emplace_back(tile_clipping_extent_.minx(),tile_clipping_extent_.maxy());
         clip_box.emplace_back(tile_clipping_extent_.minx(),tile_clipping_extent_.miny());
         bool first = true;
+        boost::geometry::unique(geom);
         for (auto const& line : geom)
         {
             if (line.size() < 2)
@@ -1045,10 +1048,11 @@ struct encoder_visitor {
             std::reverse(geom.exterior_ring.begin(), geom.exterior_ring.end());
         }
         ClipperLib::Clipper poly_clipper;
-        /*if (strictly_simple_) 
+        
+        if (strictly_simple_) 
         {
             poly_clipper.StrictlySimple(true);
-        }*/
+        }
         if (!poly_clipper.AddPath(geom.exterior_ring, ClipperLib::ptSubject, true))
         {
             return painted;
@@ -1077,22 +1081,10 @@ struct encoder_visitor {
         {
             return painted;
         }
-        mapnik::geometry::multi_line_string<std::int64_t> output_paths;
-        poly_clipper.Execute(ClipperLib::ctIntersection, output_paths, ClipperLib::pftNonZero);
-        poly_clipper.Clear();
-        ClipperLib::CleanPolygons(output_paths, clean_distance);
-        if (!clipper.AddPaths(output_paths, ClipperLib::ptSubject, true))
-        {
-            return painted;
-        }
-        
         ClipperLib::PolyTree polygons;
-        if (strictly_simple_)
-        {
-            clipper.StrictlySimple(true);
-        }
-        clipper.Execute(ClipperLib::ctUnion, polygons); //, ClipperLib::pftNonZero);
-        clipper.Clear();
+        poly_clipper.ReverseSolution(true);
+        poly_clipper.Execute(ClipperLib::ctIntersection, polygons, ClipperLib::pftNonZero);
+        poly_clipper.Clear();
         
         mapnik::geometry::multi_polygon<std::int64_t> mp;
         
@@ -1136,6 +1128,10 @@ struct encoder_visitor {
         clip_box.emplace_back(tile_clipping_extent_.minx(),tile_clipping_extent_.maxy());
         clip_box.emplace_back(tile_clipping_extent_.minx(),tile_clipping_extent_.miny());
         ClipperLib::Clipper clipper;
+        if (!clipper.AddPath( clip_box, ClipperLib::ptClip, true ))
+        {
+            return painted;
+        }
         for (auto & poly : geom)
         {
             if (poly.exterior_ring.size() < 3)
@@ -1151,12 +1147,7 @@ struct encoder_visitor {
             {   
                 std::reverse(poly.exterior_ring.begin(), poly.exterior_ring.end());
             }
-            ClipperLib::Clipper poly_clipper;
-            /*if (strictly_simple_)
-            {
-                poly_clipper.StrictlySimple(true);
-            }*/
-            if (!poly_clipper.AddPath(poly.exterior_ring, ClipperLib::ptSubject, true))
+            if (!clipper.AddPath(poly.exterior_ring, ClipperLib::ptSubject, true))
             {
                 continue;
             }
@@ -1172,24 +1163,11 @@ struct encoder_visitor {
                 {
                     std::reverse(ring.begin(), ring.end());
                 }
-                if (!poly_clipper.AddPath(ring, ClipperLib::ptSubject, true))
+                if (!clipper.AddPath(ring, ClipperLib::ptSubject, true))
                 {
                     continue;
                 }
             }
-            if (!poly_clipper.AddPath( clip_box, ClipperLib::ptClip, true ))
-            {
-                return painted;
-            }
-            mapnik::geometry::multi_line_string<std::int64_t> output_paths;
-            poly_clipper.Execute(ClipperLib::ctIntersection, output_paths);//, ClipperLib::pftNonZero);
-            poly_clipper.Clear();
-            if (output_paths.empty())
-            {
-                continue;
-            }
-            ClipperLib::CleanPolygons(output_paths, clean_distance);
-            clipper.AddPaths(output_paths, ClipperLib::ptSubject, true);
         }
         
         ClipperLib::PolyTree polygons;
@@ -1197,7 +1175,8 @@ struct encoder_visitor {
         {
             clipper.StrictlySimple(true);
         }
-        clipper.Execute(ClipperLib::ctUnion, polygons); //, ClipperLib::pftNonZero);
+        clipper.ReverseSolution(true);
+        clipper.Execute(ClipperLib::ctIntersection, polygons, ClipperLib::pftNonZero);
         clipper.Clear();
         
         mapnik::geometry::multi_polygon<std::int64_t> mp;
@@ -1206,7 +1185,7 @@ struct encoder_visitor {
         {
             process_polynode_branch(polynode, mp, area_threshold_); 
         }
-        
+
         if (mp.empty())
         {
             return painted;
diff --git a/src/vector_tile_util.ipp b/src/vector_tile_util.ipp
index b877af1..ac747ac 100644
--- a/src/vector_tile_util.ipp
+++ b/src/vector_tile_util.ipp
@@ -169,96 +169,88 @@ namespace mapnik { namespace vector_tile_impl {
 
     bool is_solid_extent(std::string const& tile, std::string & key)
     {
-        protozero::pbf_reader item(tile.data(),tile.size());
+        protozero::pbf_reader item(tile);
         unsigned i = 0;
-        while (item.next()) {
-            if (item.tag() == 3) {
-                protozero::pbf_reader layer_msg = item.get_message();
-                unsigned extent = 0;
-                std::string name;
-                std::vector<protozero::pbf_reader> feature_collection;
-                while (layer_msg.next())
+        while (item.next(3)) {
+            protozero::pbf_reader layer_msg = item.get_message();
+            unsigned extent = 0;
+            std::string name;
+            std::vector<protozero::pbf_reader> feature_collection;
+            while (layer_msg.next())
+            {
+                switch(layer_msg.tag())
                 {
-                    switch(layer_msg.tag())
-                    {
-                        case 1:
-                            name = layer_msg.get_string();
-                            break;
-                        case 2:
-                            feature_collection.push_back(layer_msg.get_message());
-                            break;
-                        case 5:
-                            extent = layer_msg.get_uint32();
-                            break;
-                        default:
-                            layer_msg.skip();
-                            break;
-                    }
+                    case 1:
+                        name = layer_msg.get_string();
+                        break;
+                    case 2:
+                        feature_collection.push_back(layer_msg.get_message());
+                        break;
+                    case 5:
+                        extent = layer_msg.get_uint32();
+                        break;
+                    default:
+                        layer_msg.skip();
+                        break;
                 }
-                unsigned side = extent - 1;
-                mapnik::box2d<int> container(2, 2, extent-2, extent-2);
-                double extent_area = side * side;
-                for (auto & features : feature_collection)
-                {
-                    while (features.next()) {
-                        if (features.tag() == 4) {
-                            mapnik::vector_tile_impl::GeometryPBF paths(features.get_packed_uint32(), 0, 0, 1, 1);
-                            mapnik::vector_tile_impl::GeometryPBF::command cmd;
-                            double x0, y0, x1, y1;
-                            mapnik::box2d<int> box;
-                            bool first = true;
-                            std::uint32_t len;
-                            while ((cmd = paths.next(x1, y1, len)) != mapnik::vector_tile_impl::GeometryPBF::end)
+            }
+            unsigned side = extent - 1;
+            mapnik::box2d<int> container(2, 2, extent-2, extent-2);
+            double extent_area = side * side;
+            for (auto & features : feature_collection)
+            {
+                while (features.next(4)) {
+                    mapnik::vector_tile_impl::GeometryPBF<double> paths(features.get_packed_uint32(), 0, 0, 1, 1);
+                    mapnik::vector_tile_impl::GeometryPBF<double>::command cmd;
+                    double x0, y0, x1, y1;
+                    mapnik::box2d<int> box;
+                    bool first = true;
+                    std::uint32_t len;
+                    while ((cmd = paths.next(x1, y1, len)) != mapnik::vector_tile_impl::GeometryPBF<double>::end)
+                    {
+                        if (cmd == mapnik::vector_tile_impl::GeometryPBF<double>::move_to || cmd == mapnik::vector_tile_impl::GeometryPBF<double>::line_to)
+                        {
+                            if ((x1 > 0 && x1 < static_cast<int>(side)) && (y1 > 0 && y1 < static_cast<int>(side)))
                             {
-                                if (cmd == mapnik::vector_tile_impl::GeometryPBF::move_to || cmd == mapnik::vector_tile_impl::GeometryPBF::line_to)
-                                {
-                                    if ((x1 > 0 && x1 < static_cast<int>(side)) && (y1 > 0 && y1 < static_cast<int>(side)))
-                                    {
-                                        // We can abort early if this feature has a vertex that is
-                                        // inside the bbox.
-                                        return false;
-                                    }
-                                    else if (!first && line_intersects_box(x0,y0,x1,y1,container))
-                                    {
-                                        // or if the last line segment intersects with the expected bounding rectangle
-                                        return false;
-                                    }
-                                    x0 = x1;
-                                    y0 = y1;
-                                    if (first)
-                                    {
-                                        box.init(x1,y1,x1,y1);
-                                        first = false;
-                                    }
-                                    else
-                                    {
-                                        box.expand_to_include(x1,y1);
-                                    }
-                                }
+                                // We can abort early if this feature has a vertex that is
+                                // inside the bbox.
+                                return false;
                             }
-                            // Once we have only one clipped result polygon, we can compare the
-                            // areas and return early if they don't match.
-                            int geom_area = box.width() * box.height();
-                            if (geom_area < (extent_area - 32) )
+                            else if (!first && line_intersects_box(x0,y0,x1,y1,container))
                             {
+                                // or if the last line segment intersects with the expected bounding rectangle
                                 return false;
                             }
-                            if (i == 0) {
-                                key = name;
-                            } else if (i > 0) {
-                                key += std::string("-") + name;
+                            x0 = x1;
+                            y0 = y1;
+                            if (first)
+                            {
+                                box.init(x1,y1,x1,y1);
+                                first = false;
+                            }
+                            else
+                            {
+                                box.expand_to_include(x1,y1);
                             }
-                        } else {
-                            features.skip();
                         }
                     }
+                    // Once we have only one clipped result polygon, we can compare the
+                    // areas and return early if they don't match.
+                    int geom_area = box.width() * box.height();
+                    if (geom_area < (extent_area - 32) )
+                    {
+                        return false;
+                    }
+                    if (i == 0) {
+                        key = name;
+                    } else if (i > 0) {
+                        key += std::string("-") + name;
+                    }
                 }
-                ++i;
-            } else {
-                item.skip();
             }
+            ++i;
         }
         return true;
     }
 
-}} // end ns
\ No newline at end of file
+}} // end ns
diff --git a/test/data/invalid-interior-ring.json b/test/data/invalid-interior-ring.json
index 99c75e4..f1e2697 100644
--- a/test/data/invalid-interior-ring.json
+++ b/test/data/invalid-interior-ring.json
@@ -79,7 +79,7 @@
         0.0
       ],
       [
-        29256264171659283709034496,
+        18446744073709551615,
         32.84267363195431
       ],
       [
@@ -92,4 +92,4 @@
       ]
     ]
   ]
-}
\ No newline at end of file
+}
diff --git a/test/encoding_util.hpp b/test/encoding_util.hpp
index 98e0466..7454f6f 100644
--- a/test/encoding_util.hpp
+++ b/test/encoding_util.hpp
@@ -125,7 +125,7 @@ std::string decode_to_path_string(mapnik::geometry::geometry<T> const& g)
 std::string compare(mapnik::geometry::geometry<std::int64_t> const& g)
 {
     vector_tile::Tile_Feature feature = geometry_to_feature(g);
-    mapnik::vector_tile_impl::Geometry geoms(feature,0.0,0.0,1.0,1.0);
-    auto g2 = mapnik::vector_tile_impl::decode_geometry(geoms,feature.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(feature,0.0,0.0,1.0,1.0);
+    auto g2 = mapnik::vector_tile_impl::decode_geometry<double>(geoms,feature.type());
     return decode_to_path_string(g2);
 }
diff --git a/test/fixtures/transform-expected-2.png b/test/fixtures/transform-expected-2.png
new file mode 100644
index 0000000..637efa1
Binary files /dev/null and b/test/fixtures/transform-expected-2.png differ
diff --git a/test/geometry_encoding.cpp b/test/geometry_encoding.cpp
index 948fb09..bcc8313 100644
--- a/test/geometry_encoding.cpp
+++ b/test/geometry_encoding.cpp
@@ -88,7 +88,7 @@ TEST_CASE( "multi_line_string", "should round trip without changes" ) {
 
     vector_tile::Tile_Feature feature = geometry_to_feature(line);
     CHECK( feature.geometry_size() == 0 );
-    auto geom = mapnik::vector_tile_impl::decode_geometry(feature,0.0,0.0,1.0,1.0);
+    auto geom = mapnik::vector_tile_impl::decode_geometry<double>(feature,0.0,0.0,1.0,1.0);
     CHECK( geom.is<mapnik::geometry::geometry_empty>() );
 }*/
 
@@ -111,7 +111,7 @@ TEST_CASE( "multi_line_string with degenerate first part", "should be culled" )
 
     vector_tile::Tile_Feature feature = geometry_to_feature(g);
     CHECK( feature.geometry_size() == 6 );
-    auto geom = mapnik::vector_tile_impl::decode_geometry(feature,0.0,0.0,1.0,1.0);
+    auto geom = mapnik::vector_tile_impl::decode_geometry<double>(feature,0.0,0.0,1.0,1.0);
 
     wkt0.clear();
     CHECK( mapnik::util::to_wkt(wkt0,geom) );
@@ -143,7 +143,7 @@ TEST_CASE( "multi_line_string with degenerate first part", "should be culled" )
     vector_tile::Tile_Feature feature = geometry_to_feature(g);
     CHECK( feature.type() == vector_tile::Tile_GeomType_LINESTRING );
     CHECK( feature.geometry_size() == 8 );
-    auto geom = mapnik::vector_tile_impl::decode_geometry(feature,0.0,0.0,1.0,1.0);
+    auto geom = mapnik::vector_tile_impl::decode_geometry<double>(feature,0.0,0.0,1.0,1.0);
 
     wkt0.clear();
     CHECK( mapnik::util::to_wkt(wkt0,geom) );
@@ -180,8 +180,8 @@ TEST_CASE( "polygon with degenerate exterior ring ", "should be culled" ) {
 
     vector_tile::Tile_Feature feature = geometry_to_feature(p0);
     // since first ring is degenerate the whole polygon should be culled
-    mapnik::vector_tile_impl::Geometry geoms(feature,0.0,0.0,1.0,1.0);
-    auto p1 = mapnik::vector_tile_impl::decode_geometry(geoms, feature.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(feature,0.0,0.0,1.0,1.0);
+    auto p1 = mapnik::vector_tile_impl::decode_geometry<double>(geoms, feature.type());
     CHECK( p1.is<mapnik::geometry::geometry_empty>() );
 }
 
@@ -208,7 +208,7 @@ TEST_CASE( "polygon with degenerate exterior ring ", "should be culled" ) {
     vector_tile::Tile_Feature feature = geometry_to_feature(p0);
     // since first ring is degenerate the whole polygon should be culled
     mapnik::vector_tile_impl::Geometry geoms(feature,0.0,0.0,1.0,1.0);
-    auto p1 = mapnik::vector_tile_impl::decode_geometry(geoms, feature.type());
+    auto p1 = mapnik::vector_tile_impl::decode_geometry<double>(geoms, feature.type());
     CHECK( p1.is<mapnik::geometry::geometry_empty>() );
 }*/
 
@@ -232,8 +232,8 @@ TEST_CASE( "polygon with valid exterior ring but degenerate interior ring", "sho
     CHECK( wkt0 == expected_wkt0);
 
     vector_tile::Tile_Feature feature = geometry_to_feature(p0);
-    mapnik::vector_tile_impl::Geometry geoms(feature,0.0,0.0,1.0,1.0);
-    auto p1 = mapnik::vector_tile_impl::decode_geometry(geoms, feature.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(feature,0.0,0.0,1.0,1.0);
+    auto p1 = mapnik::vector_tile_impl::decode_geometry<double>(geoms, feature.type());
     CHECK( p1.is<mapnik::geometry::polygon<double> >() );
     auto const& poly = mapnik::util::get<mapnik::geometry::polygon<double> >(p1);
     // since interior ring is degenerate it should have been culled when decoded
@@ -273,8 +273,8 @@ TEST_CASE( "polygon with valid exterior ring but one degenerate interior ring of
     CHECK( wkt0 == expected_wkt0);
 
     vector_tile::Tile_Feature feature = geometry_to_feature(p0);
-    mapnik::vector_tile_impl::Geometry geoms(feature,0.0,0.0,1.0,1.0);
-    auto p1 = mapnik::vector_tile_impl::decode_geometry(geoms, feature.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(feature,0.0,0.0,1.0,1.0);
+    auto p1 = mapnik::vector_tile_impl::decode_geometry<double>(geoms, feature.type());
     CHECK( p1.is<mapnik::geometry::polygon<double> >() );
     auto const& poly = mapnik::util::get<mapnik::geometry::polygon<double> >(p1);
     // since first interior ring is degenerate it should have been culled when decoded
@@ -307,8 +307,8 @@ TEST_CASE( "Polygon with de-generate ring(s)", "should skip invalid ring(s)" )
     CHECK( wkt0 == expected_wkt0);
 
     vector_tile::Tile_Feature feature = geometry_to_feature(p0);
-    mapnik::vector_tile_impl::Geometry geoms(feature,0.0,0.0,1.0,1.0);
-    auto p1 = mapnik::vector_tile_impl::decode_geometry(geoms, feature.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(feature,0.0,0.0,1.0,1.0);
+    auto p1 = mapnik::vector_tile_impl::decode_geometry<double>(geoms, feature.type());
     CHECK( p1.is<mapnik::geometry::polygon<double> >() );
     wkt0.clear();
     CHECK( mapnik::util::to_wkt(wkt0,p1) );
@@ -347,8 +347,8 @@ TEST_CASE( "(multi)polygon with hole", "should round trip without changes" ) {
     CHECK( wkt0 == expected_wkt0);
 
     vector_tile::Tile_Feature feature = geometry_to_feature(p0);
-    mapnik::vector_tile_impl::Geometry geoms(feature,0.0,0.0,1.0,1.0);
-    auto p1 = mapnik::vector_tile_impl::decode_geometry(geoms, feature.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(feature,0.0,0.0,1.0,1.0);
+    auto p1 = mapnik::vector_tile_impl::decode_geometry<double>(geoms, feature.type());
     CHECK( p1.is<mapnik::geometry::polygon<double> >() );
     CHECK( extent == mapnik::geometry::envelope(p1) );
 
@@ -627,7 +627,7 @@ TEST_CASE( "test 11", "should correctly encode multiple paths" ) {
     mapnik::geometry_type g2(mapnik::geometry_type::types::Polygon);
     double x0 = 0;
     double y0 = 0;
-    decode_geometry(feature0,g2,x0,y0,path_multiplier);
+    decode_geometry<double>(feature0,g2,x0,y0,path_multiplier);
     mapnik::vertex_adapter va2(g2);
     std::string actual = show_path(va2);
     std::string expected(
@@ -669,7 +669,7 @@ TEST_CASE( "test 12", "should correctly encode multiple paths" ) {
     mapnik::geometry_type g2(mapnik::geometry_type::types::Polygon);
     double x0 = 0;
     double y0 = 0;
-    decode_geometry(feature0,g2,x0,y0,path_multiplier);
+    decode_geometry<double>(feature0,g2,x0,y0,path_multiplier);
     mapnik::vertex_adapter va2(g2);
     std::string actual = show_path(va2);
     std::string expected(
diff --git a/test/vector_tile.cpp b/test/vector_tile.cpp
index 6f34979..cedb613 100644
--- a/test/vector_tile.cpp
+++ b/test/vector_tile.cpp
@@ -665,8 +665,8 @@ mapnik::geometry::geometry<double> round_trip(mapnik::geometry::geometry<double>
     vector_tile::Tile_Feature const& f = layer.features(0);
     double scale = (double)path_multiplier;
 
-    mapnik::vector_tile_impl::Geometry geoms(f,0,0,scale,-1*scale);
-    return mapnik::vector_tile_impl::decode_geometry(geoms, f.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(f,0,0,scale,-1*scale);
+    return mapnik::vector_tile_impl::decode_geometry<double>(geoms, f.type());
 }
 
 TEST_CASE( "vector tile point encoding", "should create vector tile with data" ) {
@@ -767,7 +767,7 @@ TEST_CASE( "vector tile multi_line_string encoding of actual multi_line_string",
     mapnik::geometry::geometry<double> new_geom = round_trip(geom);
     std::string wkt;
     CHECK( mapnik::util::to_wkt(wkt, new_geom) );
-    CHECK( wkt == "MULTILINESTRING((128 -128,192 0),(120.889 -128,63.288 -256))" );
+    CHECK( wkt == "MULTILINESTRING((128 -128,192 0),(120.889 -128,63.289 -256))" );
     CHECK( !mapnik::geometry::is_empty(new_geom) );
     CHECK( new_geom.is<mapnik::geometry::multi_line_string<double> >() );
 }
@@ -785,7 +785,7 @@ TEST_CASE( "vector tile polygon encoding", "should create vector tile with data"
     CHECK( new_geom.is<mapnik::geometry::polygon<double> >() );
     std::string wkt;
     CHECK( mapnik::util::to_wkt(wkt, new_geom) );
-    CHECK( wkt == "POLYGON((128 -113.778,120.889 -113.778,120.889 -128,128 -128,128 -113.778))" );
+    CHECK( wkt == "POLYGON((120.889 -113.778,120.889 -128,128 -128,128 -113.778,120.889 -113.778))" );
 }
 
 
@@ -801,7 +801,7 @@ TEST_CASE( "vector tile multi_polygon encoding of single polygon", "should creat
     mapnik::geometry::geometry<double> new_geom = round_trip(geom);
     std::string wkt;
     CHECK( mapnik::util::to_wkt(wkt, new_geom) );
-    CHECK( wkt == "POLYGON((128 -113.778,120.889 -113.778,120.889 -128,128 -128,128 -113.778))" );
+    CHECK( wkt == "POLYGON((120.889 -113.778,120.889 -128,128 -128,128 -113.778,120.889 -113.778))" );
     CHECK( !mapnik::geometry::is_empty(new_geom) );
     CHECK( new_geom.is<mapnik::geometry::polygon<double> >() );
 }
@@ -923,7 +923,7 @@ TEST_CASE( "vector tile polygon is simplified", "should create vector tile with
     mapnik::geometry::geometry<double> new_geom = round_trip(poly,500);
     std::string wkt;
     CHECK( mapnik::util::to_wkt(wkt, new_geom) );
-    CHECK( wkt == "POLYGON((128 -113.778,120.889 -113.778,120.889 -128,128 -128,128 -113.778),(125.867 -118.044,125.867 -123.733,123.022 -123.733,123.022 -118.044,125.867 -118.044))" );
+    CHECK( wkt == "POLYGON((120.889 -113.778,120.889 -128,128 -128,128 -113.778,120.889 -113.778),(125.867 -123.733,123.022 -123.733,123.022 -118.044,125.867 -118.044,125.867 -123.733))");
     CHECK( !mapnik::geometry::is_empty(new_geom) );
     REQUIRE( new_geom.is<mapnik::geometry::polygon<double> >() );
 }
@@ -952,7 +952,7 @@ TEST_CASE( "vector tile mulit_polygon is simplified", "should create vector tile
     mapnik::geometry::geometry<double> new_geom = round_trip(mp,500);
     std::string wkt;
     CHECK( mapnik::util::to_wkt(wkt, new_geom) );
-    CHECK( wkt == "POLYGON((128 -113.778,120.889 -113.778,120.889 -128,128 -128,128 -113.778),(125.867 -118.044,125.867 -123.733,123.022 -123.733,123.022 -118.044,125.867 -118.044))" );
+    CHECK( wkt == "POLYGON((120.889 -113.778,120.889 -128,128 -128,128 -113.778,120.889 -113.778),(125.867 -123.733,123.022 -123.733,123.022 -118.044,125.867 -118.044,125.867 -123.733))" );
     CHECK( !mapnik::geometry::is_empty(new_geom) );
     REQUIRE( new_geom.is<mapnik::geometry::polygon<double> >() );
 }
@@ -968,7 +968,7 @@ TEST_CASE( "vector tile line_string is simplified when outside bounds", "should
     std::string wkt;
     CHECK( mapnik::util::to_wkt(wkt, new_geom) );
     // yep this test is weird - more of a fuzz than anything
-    CHECK( wkt == "LINESTRING(-7369.526 -128,-7113.526 -128)" );
+    CHECK( wkt == "LINESTRING(0 -128,256 -128)" );
     CHECK( !mapnik::geometry::is_empty(new_geom) );
     CHECK( new_geom.is<mapnik::geometry::line_string<double> >() );
     auto const& line2 = mapnik::util::get<mapnik::geometry::line_string<double> >(new_geom);
@@ -1006,8 +1006,8 @@ TEST_CASE( "vector tile from simplified geojson", "should create vector tile wit
     double tile_x = -0.5 * mapnik::EARTH_CIRCUMFERENCE + x * resolution;
     double tile_y =  0.5 * mapnik::EARTH_CIRCUMFERENCE - y * resolution;
     double scale = (static_cast<double>(layer.extent()) / tile_size) * tile_size/resolution;
-    mapnik::vector_tile_impl::Geometry geoms(f,tile_x, tile_y,scale,-1*scale);
-    auto geom = mapnik::vector_tile_impl::decode_geometry(geoms,f.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(f,tile_x, tile_y,scale,-1*scale);
+    auto geom = mapnik::vector_tile_impl::decode_geometry<double>(geoms,f.type());
 
     unsigned int n_err = 0;
     mapnik::projection wgs84("+init=epsg:4326",true);
@@ -1017,7 +1017,7 @@ TEST_CASE( "vector tile from simplified geojson", "should create vector tile wit
     CHECK( n_err == 0 );
     std::string geojson_string;
     CHECK( mapnik::util::to_geojson(geojson_string,projected_geom) );
-    CHECK( geojson_string == "{\"type\":\"Polygon\",\"coordinates\":[[[160.42359375,11.422482415387],[160.40671875,11.3976701817587],[160.396875,11.3935345987523],[160.39828125,11.4018057045895],[160.39265625,11.4004272036667],[160.38984375,11.3811274888866],[160.3940625,11.3838846711709],[160.3771875,11.3521754635814],[160.33921875,11.3590690696413],[160.35046875,11.3645838345287],[160.3575,11.3645838345287],[160.3575,11.3756130442004],[160.28859375,11.3480392200085],[160.295625,11.3287 [...]
+    CHECK( geojson_string == "{\"type\":\"Polygon\",\"coordinates\":[[[160.40671875,11.3976701817587],[160.396875,11.3935345987524],[160.39828125,11.4018057045896],[160.39265625,11.4004272036667],[160.38984375,11.3811274888866],[160.3940625,11.3838846711709],[160.3771875,11.3521754635814],[160.33921875,11.3590690696413],[160.35046875,11.3645838345287],[160.3575,11.3645838345287],[160.3575,11.3756130442004],[160.29421875,11.3507967223837],[160.2928125,11.3480392200086],[160.28859375,11.34 [...]
 }
 
 mapnik::geometry::geometry<double> round_trip2(mapnik::geometry::geometry<double> const& geom,
@@ -1073,8 +1073,8 @@ mapnik::geometry::geometry<double> round_trip2(mapnik::geometry::geometry<double
     double tile_x = -0.5 * mapnik::EARTH_CIRCUMFERENCE + x * resolution;
     double tile_y =  0.5 * mapnik::EARTH_CIRCUMFERENCE - y * resolution;
     double scale = (static_cast<double>(layer.extent()) / tile_size) * tile_size/resolution;
-    mapnik::vector_tile_impl::Geometry geoms(f,tile_x, tile_y,scale,-1*scale);
-    return mapnik::vector_tile_impl::decode_geometry(geoms,f.type());
+    mapnik::vector_tile_impl::Geometry<double> geoms(f,tile_x, tile_y,scale,-1*scale);
+    return mapnik::vector_tile_impl::decode_geometry<double>(geoms,f.type());
 }
 
 TEST_CASE( "vector tile line_string is verify direction", "should line string with proper directions" ) {
diff --git a/test/vector_tile_pbf.cpp b/test/vector_tile_pbf.cpp
index f1ec69f..6db96c2 100644
--- a/test/vector_tile_pbf.cpp
+++ b/test/vector_tile_pbf.cpp
@@ -1,9 +1,5 @@
 #include "catch.hpp"
 
-// override pbf_assert to disable assertions and allow
-// all tests below to check exceptions even in Debug mode
-#define pbf_assert(x)
-
 // test utils
 #include "test_utils.hpp"
 #include <mapnik/memory_datasource.hpp>
@@ -80,11 +76,11 @@ TEST_CASE( "pbf vector tile input", "should be able to parse message and render
     CHECK(1 == layer2.features_size());
 
     mapnik::layer lyr2("layer",map.srs());
-    
-    protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+
+    protozero::pbf_reader pbf_tile(buffer);
     pbf_tile.next();
     protozero::pbf_reader layer3 = pbf_tile.get_message();
-    
+
     std::shared_ptr<mapnik::vector_tile_impl::tile_datasource_pbf> ds = std::make_shared<
                                     mapnik::vector_tile_impl::tile_datasource_pbf>(
                                         layer3,0,0,0,map2.width());
@@ -106,7 +102,7 @@ TEST_CASE( "pbf vector tile input", "should be able to parse message and render
     {
         names.push_back(desc.get_name());
     }
-    
+
     CHECK(names == expected_names);
     lyr2.set_datasource(ds);
     lyr2.add_style("style");
@@ -160,11 +156,11 @@ TEST_CASE( "pbf vector tile datasource", "should filter features outside extent"
     CHECK(9 == f.geometry(0));
     CHECK(4096 == f.geometry(1));
     CHECK(4096 == f.geometry(2));
-    
-    protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+
+    protozero::pbf_reader pbf_tile(buffer);
     pbf_tile.next();
     protozero::pbf_reader layer2 = pbf_tile.get_message();
-    
+
     // now actually start the meat of the test
     mapnik::vector_tile_impl::tile_datasource_pbf ds(layer2,0,0,0,tile_size);
     mapnik::featureset_ptr fs;
@@ -289,11 +285,11 @@ TEST_CASE( "pbf encoding multi line as one path", "should maintain second move_t
 
     mapnik::featureset_ptr fs;
     mapnik::feature_ptr f_ptr;
-    
-    protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+
+    protozero::pbf_reader pbf_tile(buffer);
     pbf_tile.next();
     protozero::pbf_reader layer2 = pbf_tile.get_message();
-    
+
 
     mapnik::vector_tile_impl::tile_datasource_pbf ds(layer2,0,0,0,tile_size);
     fs = ds.features(mapnik::query(bbox));
@@ -314,7 +310,7 @@ TEST_CASE( "pbf encoding multi line as one path", "should maintain second move_t
 
 TEST_CASE( "pbf decoding empty buffer", "should throw exception" ) {
     std::string buffer;
-    protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+    protozero::pbf_reader pbf_tile(buffer);
     pbf_tile.next();
     protozero::pbf_reader layer2;
     REQUIRE_THROWS(layer2 = pbf_tile.get_message());
@@ -322,7 +318,7 @@ TEST_CASE( "pbf decoding empty buffer", "should throw exception" ) {
 
 TEST_CASE( "pbf decoding garbage buffer", "should throw exception" ) {
     std::string buffer("daufyglwi3h7fseuhfas8w3h,dksufasdf");
-    protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+    protozero::pbf_reader pbf_tile(buffer);
     pbf_tile.next();
     protozero::pbf_reader layer2;
     REQUIRE_THROWS(layer2 = pbf_tile.get_message());
@@ -330,7 +326,7 @@ TEST_CASE( "pbf decoding garbage buffer", "should throw exception" ) {
 
 
 TEST_CASE( "pbf decoding some truncated buffers", "should throw exception" ) {
-  
+
     typedef mapnik::vector_tile_impl::backend_pbf backend_type;
     typedef mapnik::vector_tile_impl::processor<backend_type> renderer_type;
     typedef vector_tile::Tile tile_type;
@@ -362,7 +358,7 @@ TEST_CASE( "pbf decoding some truncated buffers", "should throw exception" ) {
     CHECK(9 == f.geometry(0));
     CHECK(4096 == f.geometry(1));
     CHECK(4096 == f.geometry(2));
-  
+
 
     // We will test truncating the generated protobuf at every increment.
     //  Most cases should fail, except for the lucky bites where we chop
@@ -419,7 +415,7 @@ TEST_CASE( "pbf vector tile from simplified geojson", "should create vector tile
 
     std::string buffer;
     tile.SerializeToString(&buffer);
-    protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+    protozero::pbf_reader pbf_tile(buffer);
     pbf_tile.next();
     protozero::pbf_reader pbf_layer = pbf_tile.get_message();
     // Need to loop because they could be encoded in any order
@@ -430,8 +426,8 @@ TEST_CASE( "pbf vector tile from simplified geojson", "should create vector tile
       while (!found && pbf_feature.next(4)) {
           found = true;
           std::pair< protozero::pbf_reader::const_uint32_iterator, protozero::pbf_reader::const_uint32_iterator > geom_itr = pbf_feature.get_packed_uint32();
-          mapnik::vector_tile_impl::GeometryPBF geoms(geom_itr, tile_x,tile_y,scale,-1*scale);
-          auto geom = mapnik::vector_tile_impl::decode_geometry(geoms, f.type());
+          mapnik::vector_tile_impl::GeometryPBF<double> geoms(geom_itr, tile_x,tile_y,scale,-1*scale);
+          auto geom = mapnik::vector_tile_impl::decode_geometry<double>(geoms, f.type());
               unsigned int n_err = 0;
           mapnik::projection wgs84("+init=epsg:4326",true);
           mapnik::projection merc("+init=epsg:3857",true);
@@ -440,7 +436,7 @@ TEST_CASE( "pbf vector tile from simplified geojson", "should create vector tile
           CHECK( n_err == 0 );
           std::string geojson_string;
           CHECK( mapnik::util::to_geojson(geojson_string,projected_geom) );
-          CHECK( geojson_string == "{\"type\":\"Polygon\",\"coordinates\":[[[160.42359375,11.422482415387],[160.40671875,11.3976701817587],[160.396875,11.3935345987523],[160.39828125,11.4018057045895],[160.39265625,11.4004272036667],[160.38984375,11.3811274888866],[160.3940625,11.3838846711709],[160.3771875,11.3521754635814],[160.33921875,11.3590690696413],[160.35046875,11.3645838345287],[160.3575,11.3645838345287],[160.3575,11.3756130442004],[160.28859375,11.3480392200085],[160.295625,1 [...]
+          CHECK( geojson_string == "{\"type\":\"Polygon\",\"coordinates\":[[[160.40671875,11.3976701817587],[160.396875,11.3935345987524],[160.39828125,11.4018057045896],[160.39265625,11.4004272036667],[160.38984375,11.3811274888866],[160.3940625,11.3838846711709],[160.3771875,11.3521754635814],[160.33921875,11.3590690696413],[160.35046875,11.3645838345287],[160.3575,11.3645838345287],[160.3575,11.3756130442004],[160.29421875,11.3507967223837],[160.2928125,11.3480392200086],[160.28859375 [...]
           break;
       }
     }
@@ -495,7 +491,7 @@ TEST_CASE( "pbf raster tile output", "should be able to overzoom raster" ) {
     std::string buffer;
     CHECK(tile.SerializeToString(&buffer));
 
-    protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+    protozero::pbf_reader pbf_tile(buffer);
     pbf_tile.next();
     protozero::pbf_reader layer2 = pbf_tile.get_message();
 
@@ -546,7 +542,7 @@ TEST_CASE("Check that we throw on various valid-but-we-don't-handle PBF encoded
 
         mapnik::box2d<double> bbox(-20037508.342789,-20037508.342789,20037508.342789,20037508.342789);
         unsigned tile_size = 256;
-          protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+          protozero::pbf_reader pbf_tile(buffer);
           pbf_tile.next();
           protozero::pbf_reader layer2 = pbf_tile.get_message();
           mapnik::vector_tile_impl::tile_datasource_pbf ds(layer2,0,0,0,tile_size);
@@ -586,7 +582,7 @@ TEST_CASE( "pbf vector tile from linestring geojson", "should create vector tile
     REQUIRE(3 == layer.features_size());
     std::string buffer;
     tile.SerializeToString(&buffer);
-    protozero::pbf_reader pbf_tile(buffer.c_str(), buffer.size());
+    protozero::pbf_reader pbf_tile(buffer);
     pbf_tile.next();
     protozero::pbf_reader layer3 = pbf_tile.get_message();
     std::shared_ptr<mapnik::vector_tile_impl::tile_datasource_pbf> ds2 = std::make_shared<

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapnik-vector-tile.git



More information about the Pkg-grass-devel mailing list