[mapnik] 02/13: Imported Upstream version 3.0.1+ds

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Tue Aug 25 19:37:34 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository mapnik.

commit ad93d9c5fd6f7e9f3bd6739faacef26eea7fd235
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Tue Aug 25 20:14:00 2015 +0200

    Imported Upstream version 3.0.1+ds
---
 .gitmodules                                        |   2 +
 CHANGELOG.md                                       |  19 +
 SConstruct                                         |  15 +-
 benchmark/build.py                                 |   1 +
 benchmark/test_noop_rendering.cpp                  |  53 ++
 docs/contributing.md                               |  14 +
 include/mapnik/grid/grid_pixfmt.hpp                |  26 +-
 include/mapnik/image_null.hpp                      |   1 -
 .../json/extract_bounding_box_grammar_impl.hpp     |   9 +-
 .../json/geometry_generator_grammar_impl.hpp       |   8 +
 include/mapnik/label_collision_detector.hpp        |  10 +-
 include/mapnik/memory_datasource.hpp               |   1 +
 include/mapnik/svg/svg_path_adapter.hpp            |   2 +-
 include/mapnik/text/face.hpp                       |   2 +-
 include/mapnik/text/glyph_positions.hpp            |   3 +-
 include/mapnik/text/harfbuzz_shaper.hpp            |   5 +
 include/mapnik/text/icu_shaper.hpp                 |  35 +-
 include/mapnik/text/itemizer.hpp                   |   5 +-
 include/mapnik/text/placement_finder.hpp           |   1 -
 include/mapnik/text/placement_finder_impl.hpp      |  18 +-
 include/mapnik/text/renderer.hpp                   |   4 +-
 include/mapnik/text/scrptrun.hpp                   |   6 +-
 include/mapnik/text/symbolizer_helpers.hpp         |   5 +-
 include/mapnik/text/text_line.hpp                  |   8 +-
 include/mapnik/transform_processor.hpp             |  13 +-
 include/mapnik/util/spirit_transform_attribute.hpp |  14 +
 include/mapnik/version.hpp                         |   4 +-
 localize.sh                                        |   1 +
 plugins/input/occi/README                          |  12 -
 plugins/input/occi/build.py                        |  74 ---
 plugins/input/occi/occi_datasource.cpp             | 641 ---------------------
 plugins/input/occi/occi_datasource.hpp             |  95 ---
 plugins/input/occi/occi_featureset.cpp             | 516 -----------------
 plugins/input/occi/occi_featureset.hpp             |  77 ---
 plugins/input/occi/occi_types.cpp                  |  91 ---
 plugins/input/occi/occi_types.hpp                  | 265 ---------
 plugins/input/occi/spatial_classesh.h              | 147 -----
 plugins/input/occi/spatial_classesm.cpp            |  11 -
 plugins/input/occi/spatial_classesm.h              |  14 -
 plugins/input/occi/spatial_classeso.cpp            | 312 ----------
 plugins/input/occi/spatial_types.typ               |   4 -
 plugins/input/osm/basiccurl.cpp                    |  75 ---
 plugins/input/osm/basiccurl.h                      |  40 --
 plugins/input/osm/build.py                         |  69 ---
 plugins/input/osm/dataset_deliverer.cpp            |  66 ---
 plugins/input/osm/dataset_deliverer.h              |  47 --
 plugins/input/osm/osm.cpp                          | 230 --------
 plugins/input/osm/osm.h                            | 136 -----
 plugins/input/osm/osm_datasource.cpp               | 159 -----
 plugins/input/osm/osm_datasource.hpp               |  73 ---
 plugins/input/osm/osm_featureset.cpp               | 132 -----
 plugins/input/osm/osm_featureset.hpp               |  72 ---
 plugins/input/osm/osmparser.cpp                    | 150 -----
 plugins/input/osm/osmparser.h                      |  54 --
 plugins/input/osm/osmtagtypes.h                    |  50 --
 plugins/input/pgraster/pgraster_wkb_reader.cpp     |  16 +-
 plugins/input/rasterlite/build.py                  |  71 ---
 plugins/input/rasterlite/rasterlite_datasource.cpp | 191 ------
 plugins/input/rasterlite/rasterlite_datasource.hpp |  66 ---
 plugins/input/rasterlite/rasterlite_featureset.cpp | 136 -----
 plugins/input/rasterlite/rasterlite_featureset.hpp |  71 ---
 plugins/input/rasterlite/rasterlite_include.hpp    |  31 -
 src/agg/process_group_symbolizer.cpp               |   1 +
 src/agg/process_line_pattern_symbolizer.cpp        |   1 -
 src/agg/process_markers_symbolizer.cpp             |   1 -
 src/agg/process_shield_symbolizer.cpp              |   1 +
 src/agg/process_text_symbolizer.cpp                |   1 +
 src/cairo/process_group_symbolizer.cpp             |   1 +
 src/cairo/process_text_symbolizer.cpp              |   1 +
 src/color_factory.cpp                              |   2 +-
 src/grid/process_group_symbolizer.cpp              |   1 +
 src/grid/process_shield_symbolizer.cpp             |   1 +
 src/grid/process_text_symbolizer.cpp               |   1 +
 src/group/group_symbolizer_helper.cpp              |   3 -
 src/memory_datasource.cpp                          |   4 +-
 src/svg/svg_parser.cpp                             |  23 +-
 src/text/face.cpp                                  |   4 +-
 src/text/placement_finder.cpp                      |   4 +-
 src/text/symbolizer_helpers.cpp                    |  37 +-
 test/unit/core/copy_move_test.cpp                  |   1 -
 test/unit/core/exceptions_test.cpp                 |   2 -
 test/unit/datasource/geojson.cpp                   | 122 ++++
 test/unit/imaging/image_painted_test.cpp           |   2 -
 test/unit/run.cpp                                  |   4 +
 test/unit/svg/svg_parser_test.cpp                  | 295 ++++++++++
 test/unit/text/shaping.cpp                         |  24 +
 test/visual/report.cpp                             |  30 +
 test/visual/report.hpp                             |   2 +-
 test/visual/run.cpp                                |   3 +-
 utils/svg2png/svg2png.cpp                          |  41 +-
 90 files changed, 752 insertions(+), 4340 deletions(-)

diff --git a/.gitmodules b/.gitmodules
index 8ca2e98..d2185cd 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,8 @@
 [submodule "test/data"]
 	path = test/data
 	url = https://github.com/mapnik/test-data.git
+	branch = master
 [submodule "test/data-visual"]
 	path = test/data-visual
 	url = https://github.com/mapnik/test-data-visual.git
+    branch = master
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2cdd960..a8d10ff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,25 @@ Developers: Please commit along with changes.
 
 For a complete change history, see the git log.
 
+## 3.0.1
+
+Released: July 27th, 2015
+
+(Packaged from 28f6f4d)
+
+#### Summary
+
+The 3.0.1 fixes a few bugs in geojson parsing, svg parsing, and rendering. It also avoids a potential hang when using `line-geometry-transform` and includes a speedup for text rendering compared to v3.0.0. It is fully back compatibility with v3.0.0 and everyone is encouraged to upgrade.
+
+- Fixed text placement performance after #2949 (#2963)
+- Fixed rendering behavior for `text-minimum-path-length` which regressed in 3.0.0 (#2990)
+- Fixed handling of `xml:id` in SVG parsing (#2989)
+- Fixed handling of out of range `rx` and `ry` in SVG `rect` (#2991)
+- Fixed reporting of envelope from `mapnik::memory_datasource` when new features are added (#2985)
+- Fixed parsing of GeoJSON when unknown properties encountered at `FeatureCollection` level (#2983)
+- Fixed parsing of GeoJSON when properties contained `{}` (#2964)
+- Fixed potential hang due to invalid use of `line-geometry-transform` (6d6cb15)
+
 ## 3.0.0
 
 Released: July 7th, 2015
diff --git a/SConstruct b/SConstruct
index f4e910b..9f3c0f4 100644
--- a/SConstruct
+++ b/SConstruct
@@ -110,14 +110,7 @@ PLUGINS = { # plugins with external dependencies
             'pgraster': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'},
             'gdal':    {'default':True,'path':None,'inc':'gdal_priv.h','lib':'gdal','lang':'C++'},
             'ogr':     {'default':True,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'},
-            # configured with custom paths, hence 'path': PREFIX/INCLUDES/LIBS
-            'occi':    {'default':False,'path':'OCCI','inc':'occi.h','lib':'clntsh','lang':'C++'},
             'sqlite':  {'default':True,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','lang':'C'},
-            'rasterlite':  {'default':False,'path':'RASTERLITE','inc':['sqlite3.h','rasterlite.h'],'lib':'rasterlite','lang':'C'},
-
-            # todo: osm plugin does also depend on libxml2 (but there is a separate check for that)
-            'osm':     {'default':False,'path':None,'inc':None,'lib':None,'lang':'C'},
-
             # plugins without external dependencies requiring CheckLibWithHeader...
             'shape':   {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
             'csv':     {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
@@ -1904,6 +1897,8 @@ if not HELP_REQUESTED:
     # Build the requested and able-to-be-compiled input plug-ins
     GDAL_BUILT = False
     OGR_BUILT = False
+    POSTGIS_BUILT = False
+    PGRASTER_BUILT = False
     for plugin in env['PLUGINS']:
         if env['PLUGIN_LINKING'] == 'static' or plugin not in env['REQUESTED_PLUGINS']:
             if os.path.exists('plugins/input/%s.input' % plugin):
@@ -1913,11 +1908,17 @@ if not HELP_REQUESTED:
             if details['lib'] in env['LIBS']:
                 if env['PLUGIN_LINKING'] == 'shared':
                     SConscript('plugins/input/%s/build.py' % plugin)
+                # hack to avoid breaking on plugins with the same dep
                 if plugin == 'ogr': OGR_BUILT = True
                 if plugin == 'gdal': GDAL_BUILT = True
+                if plugin == 'postgis': POSTGIS_BUILT = True
+                if plugin == 'pgraster': PGRASTER_BUILT = True
                 if plugin == 'ogr' or plugin == 'gdal':
                     if GDAL_BUILT and OGR_BUILT:
                         env['LIBS'].remove(details['lib'])
+                elif plugin == 'postgis' or plugin == 'pgraster':
+                    if POSTGIS_BUILT and PGRASTER_BUILT:
+                        env['LIBS'].remove(details['lib'])
                 else:
                     env['LIBS'].remove(details['lib'])
             elif not details['lib']:
diff --git a/benchmark/build.py b/benchmark/build.py
index 8b2049e..800a9ab 100644
--- a/benchmark/build.py
+++ b/benchmark/build.py
@@ -46,6 +46,7 @@ benchmarks = [
     "test_offset_converter.cpp",
     "test_marker_cache.cpp",
     "test_quad_tree.cpp",
+    "test_noop_rendering.cpp",
 #    "test_numeric_cast_vs_static_cast.cpp",
 ]
 for cpp_test in benchmarks:
diff --git a/benchmark/test_noop_rendering.cpp b/benchmark/test_noop_rendering.cpp
new file mode 100644
index 0000000..03d2e67
--- /dev/null
+++ b/benchmark/test_noop_rendering.cpp
@@ -0,0 +1,53 @@
+#include "bench_framework.hpp"
+#include <mapnik/map.hpp>
+#include <mapnik/image_util.hpp>
+#include <mapnik/load_map.hpp>
+#include <mapnik/agg_renderer.hpp>
+#include <mapnik/datasource_cache.hpp>
+#include <mapnik/font_engine_freetype.hpp>
+#include <stdexcept>
+#include <mapnik/layer.hpp>
+#include <mapnik/memory_datasource.hpp>
+#include <mapnik/feature_type_style.hpp>
+
+#include <memory>
+    
+class test : public benchmark::test_case
+{
+public:
+    test(mapnik::parameters const& params)
+     : test_case(params) {}
+
+    bool validate() const
+    {
+        return true;
+    }
+    bool operator()() const
+    {
+        mapnik::Map m(256,256,"+init=epsg:3857");
+
+        mapnik::parameters params;
+        params["type"]="memory";
+        auto ds = std::make_shared<mapnik::memory_datasource>(params);
+        // add whitespace to trigger phony "reprojection"
+        mapnik::layer lay("layer",m.srs() + " ");
+        lay.set_datasource(ds);
+        lay.add_style("style");
+        m.add_layer(lay);
+        // dummy style to ensure that layer is processed
+        m.insert_style("style",mapnik::feature_type_style());
+        // dummy bbox, but "valid" because minx and miny are less
+        // with an invalid bbox then layer.visible() returns false
+        // and the initial rendering setup is not run
+        m.zoom_to_box(mapnik::box2d<double>(-1,-1,0,0));
+        for (unsigned i=0;i<iterations_;++i)
+        {
+            mapnik::image_rgba8 im(256,256);
+            mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im);
+            ren.apply();
+        }
+        return true;
+    }
+};
+
+BENCHMARK(test,"rendering with reprojection")
diff --git a/docs/contributing.md b/docs/contributing.md
index e7f3279..bb486a6 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -44,6 +44,20 @@ We host our code on github.com/mapnik and encourage anyone interested to fork th
 
 If you just have a question about the code, or a feature you want to discuss then feel free to create a new issue at github.com/mapnik-support.
 
+## Plugins
+
+Mapnik has a plugin interface for reading various geodata formats. Plugins are both viable inside of Mapnik core and also able to be used outside of Mapnik.
+
+Plugins should be developed outside of core except in rare cases when most of the following are met:
+
+  - The plugin has no external dependencies or dependencies are easily installed
+  - The plugin has excellent unit tests
+  - The plugin has a maintainer willing to support the plugin over time
+  - Setup and testing of the plugin is easy on travis.ci (see .travis.yml)
+
+
+Therefore plugins that depend on proprietary, unmaintained, or difficult to test third-party dependencies are not viable for Mapnik core. However they are still likely very valuable for the Mapnik community, so get in touch via https://github.com/mapnik/mapnik-support if we can help you develop your plugin outside of core.
+
 
 ## Code Philosophy
 
diff --git a/include/mapnik/grid/grid_pixfmt.hpp b/include/mapnik/grid/grid_pixfmt.hpp
index a26a936..fbd6f51 100644
--- a/include/mapnik/grid/grid_pixfmt.hpp
+++ b/include/mapnik/grid/grid_pixfmt.hpp
@@ -38,7 +38,7 @@ namespace mapnik
 {
 
 //============================================================blender_gray
-template<class ColorT> struct blender_gray
+template<typename ColorT> struct blender_gray
 {
     using color_type = ColorT;
     using value_type = typename color_type::value_type;
@@ -55,7 +55,7 @@ template<class ColorT> struct blender_gray
 
 
 //=====================================================apply_gamma_dir_gray
-template<class ColorT, class GammaLut> class apply_gamma_dir_gray
+template<typename ColorT, class GammaLut> class apply_gamma_dir_gray
 {
 public:
     using value_type = typename ColorT::value_type;
@@ -74,7 +74,7 @@ private:
 
 
 //=====================================================apply_gamma_inv_gray
-template<class ColorT, class GammaLut> class apply_gamma_inv_gray
+template<typename ColorT, class GammaLut> class apply_gamma_inv_gray
 {
 public:
     using value_type = typename ColorT::value_type;
@@ -93,7 +93,7 @@ private:
 
 
 //=================================================pixfmt_alpha_blend_gray
-template<class Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
+template<typename Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
 class pixfmt_alpha_blend_gray
 {
 public:
@@ -160,7 +160,7 @@ public:
     void attach(rbuf_type& rb) { m_rbuf = &rb; }
     //--------------------------------------------------------------------
 
-    template<class PixFmt>
+    template<typename PixFmt>
     bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
     {
         agg::rect_i r(x1, y1, x2, y2);
@@ -538,10 +538,10 @@ public:
     }
 
     //--------------------------------------------------------------------
-    template<class Function> void for_each_pixel(Function f)
+    template <typename Function>
+    void for_each_pixel(Function f)
     {
-        unsigned y;
-        for(y = 0; y < height(); ++y)
+        for(unsigned y = 0; y < height(); ++y)
         {
             row_data r = m_rbuf->row(y);
             if(r.ptr)
@@ -562,19 +562,19 @@ public:
     }
 
     //--------------------------------------------------------------------
-    template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
+    template<typename GammaLut> void apply_gamma_dir(const GammaLut& g)
     {
         for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
     }
 
     //--------------------------------------------------------------------
-    template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
+    template<typename GammaLut> void apply_gamma_inv(const GammaLut& g)
     {
         for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
     }
 
     //--------------------------------------------------------------------
-    template<class RenBuf2>
+    template<typename RenBuf2>
     void copy_from(const RenBuf2& from,
                    int xdst, int ydst,
                    int xsrc, int ysrc,
@@ -590,7 +590,7 @@ public:
     }
 
     //--------------------------------------------------------------------
-    template<class SrcPixelFormatRenderer>
+    template<typename SrcPixelFormatRenderer>
     void blend_from_color(const SrcPixelFormatRenderer& from,
                           const color_type& color,
                           int xdst, int ydst,
@@ -617,7 +617,7 @@ public:
     }
 
     //--------------------------------------------------------------------
-    template<class SrcPixelFormatRenderer>
+    template<typename SrcPixelFormatRenderer>
     void blend_from_lut(const SrcPixelFormatRenderer& from,
                         const color_type* color_lut,
                         int xdst, int ydst,
diff --git a/include/mapnik/image_null.hpp b/include/mapnik/image_null.hpp
index c318c76..67dbbd3 100644
--- a/include/mapnik/image_null.hpp
+++ b/include/mapnik/image_null.hpp
@@ -50,7 +50,6 @@ public:
     image(image<null_t> const&) {}
     image(image<null_t> &&) noexcept {}
     image<null_t>& operator=(image<null_t>) { return *this; }
-    image<null_t>const& operator=(image<null_t> const& rhs) const { return rhs; }
     bool operator==(image<null_t> const&) const { return true; }
     bool operator<(image<null_t> const&) const { return false; }
 
diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
index c6fd321..fc08584 100644
--- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
+++ b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
@@ -63,10 +63,9 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_gramm
     start = features(_r1)
         ;
 
-    features = iter_pos[_a = _1] >> -(lit('{') >> -lit("\"type\"")
-                                      >> lit(':') >> lit("\"FeatureCollection\"")
-                                      >> *(lit(',') >> (json.key_value - lit("\"features\"")))
-                                      >> lit(',') >> lit("\"features\"")
+    features = iter_pos[_a = _1] >> -(lit('{')
+                                      >> *((json.key_value - lit("\"features\"")) >> lit(','))
+                                      >> lit("\"features\"")
                                       >> lit(':'))
                                  >> lit('[') >> (feature(_r1,_a) % lit(',')) >> lit(']')
         ;
@@ -78,6 +77,8 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_gramm
                                        |
                                        coords[_b = _1]
                                        |
+                                       json.string_
+                                       |
                                        char_))][push_box(_r1, _r2, _b, _1)]
         ;
 
diff --git a/include/mapnik/json/geometry_generator_grammar_impl.hpp b/include/mapnik/json/geometry_generator_grammar_impl.hpp
index c6968cf..f944980 100644
--- a/include/mapnik/json/geometry_generator_grammar_impl.hpp
+++ b/include/mapnik/json/geometry_generator_grammar_impl.hpp
@@ -23,13 +23,21 @@
 // mapnik
 #include <mapnik/json/geometry_generator_grammar.hpp>
 #include <mapnik/util/spirit_transform_attribute.hpp>
+#include <mapnik/geometry_types.hpp>
 
 // boost
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-local-typedef"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
 #include <boost/spirit/include/karma.hpp>
 #include <boost/spirit/include/phoenix.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_fusion.hpp>
 #include <boost/fusion/include/at.hpp>
+#pragma GCC diagnostic pop
 
 namespace mapnik { namespace json {
 
diff --git a/include/mapnik/label_collision_detector.hpp b/include/mapnik/label_collision_detector.hpp
index 6dce9ff..74a76be 100644
--- a/include/mapnik/label_collision_detector.hpp
+++ b/include/mapnik/label_collision_detector.hpp
@@ -212,12 +212,18 @@ public:
 
     void insert(box2d<double> const& box)
     {
-        tree_.insert(label(box), box);
+        if (tree_.extent().intersects(box))
+        {
+            tree_.insert(label(box), box);
+        }
     }
 
     void insert(box2d<double> const& box, mapnik::value_unicode_string const& text)
     {
-        tree_.insert(label(box, text), box);
+        if (tree_.extent().intersects(box))
+        {
+            tree_.insert(label(box, text), box);
+        }
     }
 
     void clear()
diff --git a/include/mapnik/memory_datasource.hpp b/include/mapnik/memory_datasource.hpp
index a6ab918..cd2b611 100644
--- a/include/mapnik/memory_datasource.hpp
+++ b/include/mapnik/memory_datasource.hpp
@@ -56,6 +56,7 @@ private:
     datasource::datasource_t type_;
     bool bbox_check_;
     mutable box2d<double> extent_;
+    mutable bool dirty_extent_ = true;
 };
 
 }
diff --git a/include/mapnik/svg/svg_path_adapter.hpp b/include/mapnik/svg/svg_path_adapter.hpp
index 9577171..beb8222 100644
--- a/include/mapnik/svg/svg_path_adapter.hpp
+++ b/include/mapnik/svg/svg_path_adapter.hpp
@@ -45,7 +45,7 @@ using namespace agg;
 template<class VertexContainer> class path_adapter : util::noncopyable
 {
 public:
-    using container_type = VertexContainer           ;
+    using container_type = VertexContainer;
     using self_type = path_adapter<VertexContainer>;
 
     //--------------------------------------------------------------------
diff --git a/include/mapnik/text/face.hpp b/include/mapnik/text/face.hpp
index 9c50beb..60a37e6 100644
--- a/include/mapnik/text/face.hpp
+++ b/include/mapnik/text/face.hpp
@@ -44,7 +44,7 @@ extern "C"
 namespace mapnik
 {
 
-class font_face : util::noncopyable
+class MAPNIK_DECL font_face : util::noncopyable
 {
 public:
     font_face(FT_Face face);
diff --git a/include/mapnik/text/glyph_positions.hpp b/include/mapnik/text/glyph_positions.hpp
index 604de8c..e956edd 100644
--- a/include/mapnik/text/glyph_positions.hpp
+++ b/include/mapnik/text/glyph_positions.hpp
@@ -26,6 +26,7 @@
 #include <mapnik/pixel_position.hpp>
 #include <mapnik/text/rotation.hpp>
 #include <mapnik/marker_cache.hpp>
+#include <mapnik/text/glyph_info.hpp>
 
 // agg
 #include "agg_trans_affine.h"
@@ -37,8 +38,6 @@
 namespace mapnik
 {
 
-struct glyph_info;
-
 struct glyph_position
 {
     glyph_position(glyph_info const& _glyph, pixel_position const& _pos, rotation const& _rot)
diff --git a/include/mapnik/text/harfbuzz_shaper.hpp b/include/mapnik/text/harfbuzz_shaper.hpp
index 8c4b830..ac436a1 100644
--- a/include/mapnik/text/harfbuzz_shaper.hpp
+++ b/include/mapnik/text/harfbuzz_shaper.hpp
@@ -28,7 +28,9 @@
 #include <mapnik/text/text_line.hpp>
 #include <mapnik/text/face.hpp>
 #include <mapnik/text/font_feature_settings.hpp>
+#include <mapnik/text/itemizer.hpp>
 #include <mapnik/safe_cast.hpp>
+#include <mapnik/font_engine_freetype.hpp>
 
 // stl
 #include <list>
@@ -38,6 +40,9 @@
 #include <harfbuzz/hb.h>
 #include <harfbuzz/hb-ft.h>
 
+// icu
+#include <unicode/uscript.h>
+
 namespace mapnik
 {
 
diff --git a/include/mapnik/text/icu_shaper.hpp b/include/mapnik/text/icu_shaper.hpp
index dedeafd..bcd822b 100644
--- a/include/mapnik/text/icu_shaper.hpp
+++ b/include/mapnik/text/icu_shaper.hpp
@@ -27,6 +27,10 @@
 #include <mapnik/text/text_properties.hpp>
 #include <mapnik/text/text_line.hpp>
 #include <mapnik/text/face.hpp>
+#include <mapnik/text/font_feature_settings.hpp>
+#include <mapnik/text/itemizer.hpp>
+#include <mapnik/safe_cast.hpp>
+#include <mapnik/font_engine_freetype.hpp>
 #include <mapnik/debug.hpp>
 
 // stl
@@ -59,12 +63,11 @@ static void shape_text(text_line & line,
     UErrorCode err = U_ZERO_ERROR;
     mapnik::value_unicode_string shaped;
     mapnik::value_unicode_string reordered;
-    unsigned char_index = 0;
 
     for (auto const& text_item : list)
     {
-        face_set_ptr face_set = font_manager.get_face_set(text_item.format->face_name, text_item.format->fontset);
-        double size = text_item.format->text_size * scale_factor;
+        face_set_ptr face_set = font_manager.get_face_set(text_item.format_->face_name, text_item.format_->fontset);
+        double size = text_item.format_->text_size * scale_factor;
         face_set->set_unscaled_character_sizes();
         for (auto const& face : *face_set)
         {
@@ -87,33 +90,35 @@ static void shape_text(text_line & line,
             std::size_t num_chars = static_cast<std::size_t>(num_char);
             shaped.releaseBuffer(length);
             bool shaped_status = true;
+            double max_glyph_height = 0;
             if (U_SUCCESS(err) && (num_chars == length))
             {
+                unsigned char_index = 0;
                 U_NAMESPACE_QUALIFIER StringCharacterIterator iter(shaped);
                 for (iter.setToStart(); iter.hasNext();)
                 {
                     UChar ch = iter.nextPostInc();
-                    glyph_info tmp;
-                    tmp.glyph_index = FT_Get_Char_Index(face->get_face(), ch);
-                    tmp.offset.clear();
-                    if (tmp.glyph_index == 0)
+                    auto codepoint = FT_Get_Char_Index(face->get_face(), ch);
+                    glyph_info g(codepoint,char_index,text_item.format_);
+                    //g.offset.clear();
+                    if (g.glyph_index == 0)
                     {
                         shaped_status = false;
                         break;
                     }
-                    if (face->glyph_dimensions(tmp))
+                    if (face->glyph_dimensions(g))
                     {
-                        tmp.char_index = char_index;
-                        tmp.face = face;
-                        tmp.format = text_item.format;
-                        tmp.scale_multiplier = size / face->get_face()->units_per_EM;
-                        width_map[char_index++] += tmp.advance();
-                        line.add_glyph(tmp, scale_factor);
+                        g.face = face;
+                        g.scale_multiplier = size / face->get_face()->units_per_EM;
+                        double tmp_height = g.height();
+                        if (tmp_height > max_glyph_height) max_glyph_height = tmp_height;
+                        width_map[char_index++] += g.advance();
+                        line.add_glyph(std::move(g), scale_factor);
                     }
                 }
             }
             if (!shaped_status) continue;
-            line.update_max_char_height(face->get_char_height(size));
+            line.update_max_char_height(max_glyph_height);
             return;
         }
     }
diff --git a/include/mapnik/text/itemizer.hpp b/include/mapnik/text/itemizer.hpp
index fe036ad..b858944 100644
--- a/include/mapnik/text/itemizer.hpp
+++ b/include/mapnik/text/itemizer.hpp
@@ -27,6 +27,7 @@
 #include <mapnik/text/evaluated_format_properties_ptr.hpp>
 #include <mapnik/value_types.hpp>
 #include <mapnik/util/noncopyable.hpp>
+#include <mapnik/config.hpp>
 
 // stl
 #include <string>
@@ -41,7 +42,7 @@
 namespace mapnik
 {
 
-struct text_item : util::noncopyable
+struct MAPNIK_DECL text_item : util::noncopyable
 {
     text_item(unsigned s,
               unsigned e,
@@ -71,7 +72,7 @@ struct text_item : util::noncopyable
 // - format
 // - script (http://en.wikipedia.org/wiki/Scripts_in_Unicode)
 
-class text_itemizer
+class MAPNIK_DECL text_itemizer : util::noncopyable
 {
 public:
     text_itemizer();
diff --git a/include/mapnik/text/placement_finder.hpp b/include/mapnik/text/placement_finder.hpp
index f2bd36d..0460b2c 100644
--- a/include/mapnik/text/placement_finder.hpp
+++ b/include/mapnik/text/placement_finder.hpp
@@ -26,7 +26,6 @@
 #include <mapnik/box2d.hpp>
 #include <mapnik/pixel_position.hpp>
 #include <mapnik/text/text_layout.hpp>
-#include <mapnik/text/placements/base.hpp>
 #include <mapnik/text/glyph_positions.hpp>
 #include <mapnik/text/rotation.hpp>
 #include <mapnik/util/noncopyable.hpp>
diff --git a/include/mapnik/text/placement_finder_impl.hpp b/include/mapnik/text/placement_finder_impl.hpp
index 7392389..1b8f841 100644
--- a/include/mapnik/text/placement_finder_impl.hpp
+++ b/include/mapnik/text/placement_finder_impl.hpp
@@ -19,23 +19,19 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  *****************************************************************************/
-//mapnik
-#include <mapnik/debug.hpp>
-#include <mapnik/label_collision_detector.hpp>
-#include <mapnik/view_transform.hpp>
-#include <mapnik/expression_evaluator.hpp>
+
+// mapnik
+//#include <mapnik/label_collision_detector.hpp>
+//#include <mapnik/view_transform.hpp>
 #include <mapnik/text/placement_finder.hpp>
 #include <mapnik/text/text_layout.hpp>
 #include <mapnik/text/text_properties.hpp>
-#include <mapnik/text/glyph_positions.hpp>
+//#include <mapnik/text/glyph_positions.hpp>
 #include <mapnik/vertex_cache.hpp>
 #include <mapnik/tolerance_iterator.hpp>
+#include <mapnik/symbolizer_enumerations.hpp>
 
-// agg
-#include "agg_conv_clip_polyline.h"
-
-// stl
-#include <vector>
+#include <memory>
 
 namespace mapnik
 {
diff --git a/include/mapnik/text/renderer.hpp b/include/mapnik/text/renderer.hpp
index a0b521d..1b6bac1 100644
--- a/include/mapnik/text/renderer.hpp
+++ b/include/mapnik/text/renderer.hpp
@@ -56,8 +56,8 @@ public:
     text_renderer (halo_rasterizer_e rasterizer,
                    composite_mode_e comp_op = src_over,
                    composite_mode_e halo_comp_op = src_over,
-                   double scale_factor=1.0,
-                   stroker_ptr stroker=stroker_ptr());
+                   double scale_factor = 1.0,
+                   stroker_ptr stroker = stroker_ptr());
     void set_transform(agg::trans_affine const& transform);
     void set_halo_transform(agg::trans_affine const& halo_transform);
 protected:
diff --git a/include/mapnik/text/scrptrun.hpp b/include/mapnik/text/scrptrun.hpp
index e4c607f..67942b0 100644
--- a/include/mapnik/text/scrptrun.hpp
+++ b/include/mapnik/text/scrptrun.hpp
@@ -17,9 +17,9 @@
 #ifndef __SCRPTRUN_H
 #define __SCRPTRUN_H
 
-#include "unicode/utypes.h"
-#include "unicode/uobject.h"
-#include "unicode/uscript.h"
+#include <unicode/utypes.h>
+#include <unicode/uobject.h>
+#include <unicode/uscript.h>
 
 struct ScriptRecord
 {
diff --git a/include/mapnik/text/symbolizer_helpers.hpp b/include/mapnik/text/symbolizer_helpers.hpp
index 714d566..8a44bdd 100644
--- a/include/mapnik/text/symbolizer_helpers.hpp
+++ b/include/mapnik/text/symbolizer_helpers.hpp
@@ -22,10 +22,13 @@
 #ifndef SYMBOLIZER_HELPERS_HPP
 #define SYMBOLIZER_HELPERS_HPP
 
-//mapnik
+// mapnik
 #include <mapnik/text/placement_finder.hpp>
+#include <mapnik/text/placements/base.hpp>
 #include <mapnik/vertex_converters.hpp>
 #include <mapnik/geometry.hpp>
+#include <mapnik/text/glyph_positions.hpp>
+#include <mapnik/text/text_properties.hpp>
 
 namespace mapnik {
 
diff --git a/include/mapnik/text/text_line.hpp b/include/mapnik/text/text_line.hpp
index 1bd02db..cf47026 100644
--- a/include/mapnik/text/text_line.hpp
+++ b/include/mapnik/text/text_line.hpp
@@ -25,17 +25,17 @@
 //stl
 #include <vector>
 #include <mapnik/util/noncopyable.hpp>
+#include <mapnik/config.hpp>
+#include <mapnik/text/glyph_info.hpp>
 
 namespace mapnik
 {
 
-struct glyph_info;
-
 // This class stores all glyphs of a line in left to right order.
 // It can be used for rendering but no text processing (like line breaking)
 // should be done!
 
-class text_line : util::noncopyable
+class MAPNIK_DECL text_line : util::noncopyable
 {
 public:
     using glyph_vector = std::vector<glyph_info>;
@@ -97,6 +97,6 @@ private:
     unsigned space_count_;
 };
 
-} //namespace mapnik
+} // namespace mapnik
 
 #endif // MAPNIK_TEXT_LINE_HPP
diff --git a/include/mapnik/transform_processor.hpp b/include/mapnik/transform_processor.hpp
index fd45ecc..bec6bff 100644
--- a/include/mapnik/transform_processor.hpp
+++ b/include/mapnik/transform_processor.hpp
@@ -32,6 +32,9 @@
 // agg
 #include <agg_trans_affine.h>
 
+// stl
+#include <cmath>
+
 namespace mapnik {
 
 class feature_impl;
@@ -149,13 +152,19 @@ struct transform_processor
 
         void operator() (skewX_node const& node)
         {
-            double angle = deg2rad(eval(node.angle_));
+            auto degrees = std::fmod(eval(node.angle_),90.0);
+            if (degrees < -89.0) degrees = -89.0;
+            else if (degrees > 89.0) degrees = 89.0;
+            auto angle = deg2rad(degrees);
             transform_.multiply(agg::trans_affine_skewing(angle, 0.0));
         }
 
         void operator() (skewY_node const& node)
         {
-            double angle = deg2rad(eval(node.angle_));
+            auto degrees = std::fmod(eval(node.angle_),90.0);
+            if (degrees < -89.0) degrees = -89.0;
+            else if (degrees > 89.0) degrees = 89.0;
+            auto angle = deg2rad(degrees);
             transform_.multiply(agg::trans_affine_skewing(0.0, angle));
         }
 
diff --git a/include/mapnik/util/spirit_transform_attribute.hpp b/include/mapnik/util/spirit_transform_attribute.hpp
index 1c0bdac..e924fd8 100644
--- a/include/mapnik/util/spirit_transform_attribute.hpp
+++ b/include/mapnik/util/spirit_transform_attribute.hpp
@@ -24,6 +24,20 @@
 #define MAPNIK_UTIL_SPIRIT_TRANSFORM_ATTRIBUTE_HPP
 
 #include <mapnik/geometry.hpp>
+#include <mapnik/util/variant.hpp>
+
+#include <vector>
+#include <cstdint>
+
+// boost
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-local-typedef"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#include <boost/spirit/include/karma.hpp>
+#pragma GCC diagnostic pop
 
 namespace boost { namespace spirit { namespace traits {
 
diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp
index 47a200e..cbba22f 100644
--- a/include/mapnik/version.hpp
+++ b/include/mapnik/version.hpp
@@ -27,9 +27,9 @@
 
 #define MAPNIK_MAJOR_VERSION 3
 #define MAPNIK_MINOR_VERSION 0
-#define MAPNIK_PATCH_VERSION 0
+#define MAPNIK_PATCH_VERSION 1
 
-// translates to 300000
+// translates to 300001
 #define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
 
 #ifndef MAPNIK_STRINGIFY
diff --git a/localize.sh b/localize.sh
index ee62e59..31c6a6e 100755
--- a/localize.sh
+++ b/localize.sh
@@ -8,6 +8,7 @@ else
 fi
 
 export PATH=$(pwd)/utils/nik2img/:${PATH}
+export PATH=$(pwd)/utils/mapnik-config/:${PATH}
 
 # mapnik-settings.env is an optional file to store
 # environment variables that should be used before
diff --git a/plugins/input/occi/README b/plugins/input/occi/README
deleted file mode 100644
index a36411c..0000000
--- a/plugins/input/occi/README
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# To regenerate C++ class declarations & implementations for the Spatial
-# object types of your database you should execute OTT in your server !
-#
-
-echo "TYPE MDSYS.SDO_POINT_TYPE AS SDOPointType" > spatial_types.typ
-echo "TYPE MDSYS.SDO_GEOMETRY AS SDOGeometry" >> spatial_types.typ
-
-ott userid=scott/tiger attraccess=private intype=spatial_types.typ code=cpp \
-     cppfile=spatial_classeso.cpp hfile=spatial_classesh.h mapfile=spatial_classesm.cpp \
-     mapfunc=RegisterClasses
-
diff --git a/plugins/input/occi/build.py b/plugins/input/occi/build.py
deleted file mode 100644
index e0aeb7b..0000000
--- a/plugins/input/occi/build.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# This file is part of Mapnik (c++ mapping toolkit)
-#
-# Copyright (C) 2015 Artem Pavlenko
-#
-# Mapnik is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#
-
-Import ('plugin_base')
-Import ('env')
-
-PLUGIN_NAME = 'occi'
-
-plugin_env = plugin_base.Clone()
-
-plugin_sources = Split(
-  """
-  %(PLUGIN_NAME)s_types.cpp
-  %(PLUGIN_NAME)s_datasource.cpp
-  %(PLUGIN_NAME)s_featureset.cpp
-  spatial_classesm.cpp
-  spatial_classeso.cpp
-  """ % locals()
-)
-
-libraries = [ 'clntsh', 'occi' ]
-libraries.append('boost_system%s' % env['BOOST_APPEND'])
-libraries.append(env['ICU_LIB_NAME'])
-
-if env['PLUGIN_LINKING'] == 'shared':
-    libraries.append(env['MAPNIK_NAME'])
-
-    # libocci.dylib, at least for 11.2 links to libstdc++
-    # so we defer symbol resolution to runtime in order to
-    # dodge linking errors like
-    # Undefined symbols for architecture x86_64:
-    #   "std::string::_Rep::_M_destroy(std::allocator<char> const&)", referenced from:
-    #      RegisterClasses(oracle::occi::Environment*) in spatial_classesm.os
-
-    if env['PLATFORM'] == 'Darwin':
-        plugin_env.Append(LINKFLAGS='-undefined dynamic_lookup')
-
-    TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
-                                      SHLIBPREFIX='',
-                                      SHLIBSUFFIX='.input',
-                                      source=plugin_sources,
-                                      LIBS=libraries)
-
-    # if the plugin links to libmapnik ensure it is built first
-    Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
-
-    if 'uninstall' not in COMMAND_LINE_TARGETS:
-        env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
-        env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
-
-plugin_obj = {
-  'LIBS': libraries,
-  'SOURCES': plugin_sources,
-}
-
-Return('plugin_obj')
diff --git a/plugins/input/occi/occi_datasource.cpp b/plugins/input/occi/occi_datasource.cpp
deleted file mode 100644
index 1c28092..0000000
--- a/plugins/input/occi/occi_datasource.cpp
+++ /dev/null
@@ -1,641 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#include "occi_datasource.hpp"
-#include "occi_featureset.hpp"
-
-// mapnik
-#include <mapnik/debug.hpp>
-#include <mapnik/boolean.hpp>
-#include <mapnik/sql_utils.hpp>
-#include <mapnik/timer.hpp>
-#include <mapnik/value_types.hpp>
-
-// boost
-#include <boost/algorithm/string.hpp>
-#include <boost/tokenizer.hpp>
-
-// stl
-#include <string>
-#include <algorithm>
-#include <set>
-#include <sstream>
-#include <iomanip>
-
-using mapnik::datasource;
-using mapnik::parameters;
-using mapnik::query;
-using mapnik::featureset_ptr;
-using mapnik::layer_descriptor;
-using mapnik::attribute_descriptor;
-using mapnik::datasource_exception;
-using mapnik::box2d;
-using mapnik::coord2d;
-
-using oracle::occi::Environment;
-using oracle::occi::Connection;
-using oracle::occi::Statement;
-using oracle::occi::ResultSet;
-using oracle::occi::MetaData;
-using oracle::occi::SQLException;
-using oracle::occi::Type;
-using oracle::occi::StatelessConnectionPool;
-
-const double occi_datasource::FMAX = std::numeric_limits<double>::max();
-const std::string occi_datasource::METADATA_TABLE = "USER_SDO_GEOM_METADATA";
-
-DATASOURCE_PLUGIN(occi_datasource)
-
-occi_datasource::occi_datasource(parameters const& params)
-    : datasource (params),
-      type_(datasource::Vector),
-      fields_(*params.get<std::string>("fields", "*")),
-      geometry_field_(*params.get<std::string>("geometry_field", "")),
-      srid_initialized_(false),
-      extent_initialized_(false),
-      bbox_token_("!bbox!"),
-      scale_denom_token_("!scale_denominator!"),
-      pixel_width_token_("!pixel_width!"),
-      pixel_height_token_("!pixel_height!"),
-      desc_(occi_datasource::name(), *params.get<std::string>("encoding", "utf-8")),
-      use_wkb_(*params.get<mapnik::boolean_type>("use_wkb", false)),
-      row_limit_(*params.get<mapnik::value_integer>("row_limit", 0)),
-      row_prefetch_(*params.get<mapnik::value_integer>("row_prefetch", 100)),
-      pool_(0),
-      conn_(0)
-{
-#ifdef MAPNIK_STATS
-    mapnik::progress_timer __stats__(std::clog, "occi_datasource::init");
-#endif
-
-    if (! params.get<std::string>("user")) throw datasource_exception("OCCI Plugin: no <user> specified");
-    if (! params.get<std::string>("password")) throw datasource_exception("OCCI Plugin: no <password> specified");
-    if (! params.get<std::string>("host")) throw datasource_exception("OCCI Plugin: no <host> string specified");
-
-    boost::optional<std::string> table = params.get<std::string>("table");
-    if (! table)
-    {
-        throw datasource_exception("OCCI Plugin: no <table> parameter specified");
-    }
-    else
-    {
-        table_ = *table;
-    }
-    estimate_extent_ = *params.get<mapnik::boolean_type>("estimate_extent",false);
-    use_spatial_index_ = *params.get<mapnik::boolean_type>("use_spatial_index",true);
-    use_connection_pool_ = *params.get<mapnik::boolean_type>("use_connection_pool",true);
-
-    boost::optional<std::string> ext = params.get<std::string>("extent");
-    if (ext) extent_initialized_ = extent_.from_string(*ext);
-
-    boost::optional<mapnik::value_integer> srid = params.get<mapnik::value_integer>("srid");
-    if (srid)
-    {
-        srid_ = *srid;
-        srid_initialized_ = true;
-    }
-
-    // connect to environment
-    if (use_connection_pool_)
-    {
-        try
-        {
-            pool_ = occi_environment::instance().create_pool(
-                *params.get<std::string>("user"),
-                *params.get<std::string>("password"),
-                *params.get<std::string>("host"),
-                *params.get<mapnik::value_integer>("max_size", 5),
-                *params.get<mapnik::value_integer>("initial_size", 1),
-                1);
-        }
-        catch (SQLException& ex)
-        {
-            throw datasource_exception("OCCI Plugin: " + ex.getMessage());
-        }
-    }
-    else
-    {
-        try
-        {
-            conn_ = occi_environment::instance().create_connection(
-                *params.get<std::string>("user"),
-                *params.get<std::string>("password"),
-                *params.get<std::string>("host"));
-        }
-        catch (SQLException& ex)
-        {
-            throw datasource_exception("OCCI Plugin: " + ex.getMessage());
-        }
-    }
-
-    // extract real table name
-    table_name_ = mapnik::sql_utils::table_from_sql(table_);
-
-    // get SRID and/or GEOMETRY_FIELD from metadata table only if we need to
-    if (! srid_initialized_ || geometry_field_ == "")
-    {
-#ifdef MAPNIK_STATS
-        mapnik::progress_timer __stats__(std::clog, "occi_datasource::get_srid_and_geometry_field");
-#endif
-
-        std::ostringstream s;
-        s << "SELECT srid, column_name FROM " << METADATA_TABLE << " WHERE";
-        s << " LOWER(table_name) = LOWER('" << table_name_ << "')";
-
-        if (geometry_field_ != "")
-        {
-            s << " AND LOWER(column_name) = LOWER('" << geometry_field_ << "')";
-        }
-
-        MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
-
-        try
-        {
-            occi_connection_ptr conn;
-            if (use_connection_pool_) conn.set_pool(pool_);
-            else                      conn.set_connection(conn_, false);
-
-            ResultSet* rs = conn.execute_query(s.str());
-            if (rs && rs->next ())
-            {
-                if (! srid_initialized_)
-                {
-                    srid_ = rs->getInt(1);
-                    srid_initialized_ = true;
-                }
-
-                if (geometry_field_ == "")
-                {
-                    geometry_field_ = rs->getString(2);
-                }
-            }
-        }
-        catch (SQLException& ex)
-        {
-            throw datasource_exception("OCCI Plugin: " + ex.getMessage());
-        }
-    }
-
-    // get columns description
-    {
-#ifdef MAPNIK_STATS
-        mapnik::progress_timer __stats__(std::clog, "occi_datasource::get_column_description");
-#endif
-
-        std::ostringstream s;
-        s << "SELECT " << fields_ << " FROM (" << table_name_ << ") WHERE ROWNUM < 1";
-
-        MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
-
-        try
-        {
-            occi_connection_ptr conn;
-            if (use_connection_pool_) conn.set_pool(pool_);
-            else                      conn.set_connection(conn_, false);
-
-            ResultSet* rs = conn.execute_query(s.str());
-            if (rs)
-            {
-                std::vector<MetaData> listOfColumns = rs->getColumnListMetaData();
-
-                for (unsigned int i = 0; i < listOfColumns.size(); ++i)
-                {
-                    MetaData columnObj = listOfColumns[i];
-
-                    std::string fld_name = columnObj.getString(MetaData::ATTR_NAME);
-                    int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE);
-
-                    /*
-                      int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE);
-                      if (type_code == OCCI_TYPECODE_OBJECT)
-                      {
-                      desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Object));
-                      continue;
-                      }
-                    */
-
-                    switch (type_oid)
-                    {
-                    case oracle::occi::OCCIBOOL:
-                        desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Boolean));
-                        break;
-                    case oracle::occi::OCCIINT:
-                    case oracle::occi::OCCIUNSIGNED_INT:
-                        desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
-                        break;
-                    case oracle::occi::OCCIFLOAT:
-                    case oracle::occi::OCCIBFLOAT:
-                    case oracle::occi::OCCIDOUBLE:
-                    case oracle::occi::OCCIBDOUBLE:
-                    case oracle::occi::OCCINUMBER:
-                    case oracle::occi::OCCI_SQLT_NUM:
-                        desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
-                        break;
-                    case oracle::occi::OCCICHAR:
-                    case oracle::occi::OCCISTRING:
-                    case oracle::occi::OCCI_SQLT_AFC:
-                    case oracle::occi::OCCI_SQLT_AVC:
-                    case oracle::occi::OCCI_SQLT_CHR:
-                    case oracle::occi::OCCI_SQLT_LNG:
-                    case oracle::occi::OCCI_SQLT_LVC:
-                    case oracle::occi::OCCI_SQLT_STR:
-                    case oracle::occi::OCCI_SQLT_VCS:
-                    case oracle::occi::OCCI_SQLT_VNU:
-                    case oracle::occi::OCCI_SQLT_VBI:
-                    case oracle::occi::OCCI_SQLT_VST:
-                    case oracle::occi::OCCIROWID:
-                    case oracle::occi::OCCI_SQLT_RDD:
-                    case oracle::occi::OCCI_SQLT_RID:
-                    case oracle::occi::OCCIDATE:
-                    case oracle::occi::OCCI_SQLT_DAT:
-                    case oracle::occi::OCCI_SQLT_DATE:
-                    case oracle::occi::OCCI_SQLT_TIME:
-                    case oracle::occi::OCCI_SQLT_TIME_TZ:
-                    case oracle::occi::OCCITIMESTAMP:
-                    case oracle::occi::OCCI_SQLT_TIMESTAMP:
-                    case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
-                    case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
-                        desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
-                        break;
-                    case oracle::occi::OCCIINTERVALDS:
-                    case oracle::occi::OCCIINTERVALYM:
-                    case oracle::occi::OCCI_SQLT_INTERVAL_YM:
-                    case oracle::occi::OCCI_SQLT_INTERVAL_DS:
-                    case oracle::occi::OCCIANYDATA:
-                    case oracle::occi::OCCIBLOB:
-                    case oracle::occi::OCCIBFILE:
-                    case oracle::occi::OCCIBYTES:
-                    case oracle::occi::OCCICLOB:
-                    case oracle::occi::OCCIVECTOR:
-                    case oracle::occi::OCCIMETADATA:
-                    case oracle::occi::OCCIPOBJECT:
-                    case oracle::occi::OCCIREF:
-                    case oracle::occi::OCCIREFANY:
-                    case oracle::occi::OCCISTREAM:
-                    case oracle::occi::OCCICURSOR:
-                    case oracle::occi::OCCI_SQLT_FILE:
-                    case oracle::occi::OCCI_SQLT_CFILE:
-                    case oracle::occi::OCCI_SQLT_REF:
-                    case oracle::occi::OCCI_SQLT_CLOB:
-                    case oracle::occi::OCCI_SQLT_BLOB:
-                    case oracle::occi::OCCI_SQLT_RSET:
-                        MAPNIK_LOG_WARN(occi) << "occi_datasource: Unsupported datatype "
-                                              << occi_enums::resolve_datatype(type_oid)
-                                              << " (type_oid=" << type_oid << ")";
-                        break;
-                    default:
-                        MAPNIK_LOG_WARN(occi) << "occi_datasource: Unknown datatype "
-                                              << "(type_oid=" << type_oid << ")";
-                        break;
-                    }
-                }
-            }
-        }
-        catch (SQLException& ex)
-        {
-            throw datasource_exception(ex.getMessage());
-        }
-    }
-}
-
-occi_datasource::~occi_datasource()
-{
-    if (use_connection_pool_)
-    {
-        if (pool_ != 0)
-        {
-            occi_environment::instance().destroy_pool(pool_);
-        }
-    }
-    else
-    {
-        if (conn_ != 0)
-        {
-            occi_environment::instance().destroy_connection(conn_);
-        }
-    }
-}
-
-const char * occi_datasource::name()
-{
-    return "occi";
-}
-
-mapnik::datasource::datasource_t occi_datasource::type() const
-{
-    return type_;
-}
-
-box2d<double> occi_datasource::envelope() const
-{
-    if (extent_initialized_) return extent_;
-
-    double lox = 0.0, loy = 0.0, hix = 0.0, hiy = 0.0;
-
-
-    if (estimate_extent_)
-    {
-#ifdef MAPNIK_STATS
-        mapnik::progress_timer __stats__(std::clog, "occi_datasource::envelope(estimate_extent)");
-#endif
-
-        std::ostringstream s;
-        s << "SELECT MIN(c.x), MIN(c.y), MAX(c.x), MAX(c.y) FROM ";
-        s << " (SELECT SDO_AGGR_MBR(" << geometry_field_ << ") shape FROM " << table_ << ") a, ";
-        s << " TABLE(SDO_UTIL.GETVERTICES(a.shape)) c";
-
-        MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
-
-        try
-        {
-            occi_connection_ptr conn;
-            if (use_connection_pool_) conn.set_pool(pool_);
-            else                      conn.set_connection(conn_, false);
-
-            ResultSet* rs = conn.execute_query(s.str());
-            if (rs && rs->next())
-            {
-                lox = rs->getDouble(1);
-                loy = rs->getDouble(2);
-                hix = rs->getDouble(3);
-                hiy = rs->getDouble(4);
-                extent_.init(lox, loy, hix, hiy);
-                extent_initialized_ = true;
-            }
-        }
-        catch (SQLException& ex)
-        {
-            throw datasource_exception("OCCI Plugin: " + ex.getMessage());
-        }
-    }
-    else if (use_spatial_index_)
-    {
-#ifdef MAPNIK_STATS
-        mapnik::progress_timer __stats__(std::clog, "occi_datasource::envelope(use_spatial_index)");
-#endif
-
-        std::ostringstream s;
-        s << "SELECT dim.sdo_lb, dim.sdo_ub FROM ";
-        s << METADATA_TABLE << " m, TABLE(m.diminfo) dim ";
-        s << " WHERE LOWER(m.table_name) = LOWER('" << table_name_ << "') AND dim.sdo_dimname = 'X'";
-        s << " UNION ";
-        s << "SELECT dim.sdo_lb, dim.sdo_ub FROM ";
-        s << METADATA_TABLE << " m, TABLE(m.diminfo) dim ";
-        s << " WHERE LOWER(m.table_name) = LOWER('" << table_name_ << "') AND dim.sdo_dimname = 'Y'";
-
-        MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
-
-        try
-        {
-            occi_connection_ptr conn;
-            if (use_connection_pool_) conn.set_pool(pool_);
-            else                      conn.set_connection(conn_, false);
-
-            ResultSet* rs = conn.execute_query(s.str());
-            if (rs)
-            {
-                if (rs->next())
-                {
-                    lox = rs->getDouble(1);
-                    hix = rs->getDouble(2);
-                }
-
-                if (rs->next())
-                {
-                    loy = rs->getDouble(1);
-                    hiy = rs->getDouble(2);
-                }
-                extent_.init(lox, loy, hix, hiy);
-                extent_initialized_ = true;
-            }
-        }
-        catch (SQLException& ex)
-        {
-            throw datasource_exception("OCCI Plugin: " + ex.getMessage());
-        }
-    }
-
-    if (! extent_initialized_)
-    {
-        throw datasource_exception("OCCI Plugin: unable to determine the extent of a <occi> table");
-    }
-
-    return extent_;
-}
-
-
-boost::optional<mapnik::datasource_geometry_t> occi_datasource::get_geometry_type() const
-{
-    return boost::optional<mapnik::datasource_geometry_t>();
-}
-
-layer_descriptor occi_datasource::get_descriptor() const
-{
-    return desc_;
-}
-
-std::string occi_datasource::sql_bbox(box2d<double> const& env) const
-{
-    std::ostringstream b;
-    b << std::setprecision(16);
-    b << "MDSYS.SDO_GEOMETRY(" << SDO_GTYPE_2DPOLYGON << "," << srid_ << ",NULL,";
-    b << " MDSYS.SDO_ELEM_INFO_ARRAY(1," << SDO_ETYPE_POLYGON << "," << SDO_INTERPRETATION_RECTANGLE << "),";
-    b << " MDSYS.SDO_ORDINATE_ARRAY(";
-    b << env.minx() << "," << env.miny() << ", ";
-    b << env.maxx() << "," << env.maxy() << "))";
-    return b.str();
-}
-
-std::string occi_datasource::populate_tokens(std::string const& sql, double scale_denom, box2d<double> const& env, double pixel_width, double pixel_height) const
-{
-    std::string populated_sql = sql;
-
-    if (boost::algorithm::icontains(populated_sql, scale_denom_token_))
-    {
-        std::ostringstream ss;
-        ss << scale_denom;
-        boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str());
-    }
-
-    if (boost::algorithm::icontains(sql, pixel_width_token_))
-    {
-        std::ostringstream ss;
-        ss << pixel_width;
-        boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str());
-    }
-
-    if (boost::algorithm::icontains(sql, pixel_height_token_))
-    {
-        std::ostringstream ss;
-        ss << pixel_height;
-        boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str());
-    }
-
-    if (boost::algorithm::icontains(populated_sql, bbox_token_))
-    {
-        boost::algorithm::replace_all(populated_sql, bbox_token_, sql_bbox(env));
-    }
-
-    return populated_sql;
-}
-
-featureset_ptr occi_datasource::features(query const& q) const
-{
-#ifdef MAPNIK_STATS
-    mapnik::progress_timer __stats__(std::clog, "occi_datasource::features");
-#endif
-
-    box2d<double> const& box = q.get_bbox();
-    const double px_gw = 1.0 / std::get<0>(q.resolution());
-    const double px_gh = 1.0 / std::get<1>(q.resolution());
-    const double scale_denom = q.scale_denominator();
-
-    std::ostringstream s;
-    s << "SELECT ";
-    if (use_wkb_)
-    {
-        s << "SDO_UTIL.TO_WKBGEOMETRY(" << geometry_field_ << ")";
-    }
-    else
-    {
-        s << geometry_field_;
-    }
-    std::set<std::string> const& props = q.property_names();
-    std::set<std::string>::const_iterator pos = props.begin();
-    std::set<std::string>::const_iterator end = props.end();
-    mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
-    for (; pos != end; ++pos)
-    {
-        s << ", " << *pos;
-        ctx->push(*pos);
-    }
-
-    std::string query = populate_tokens(table_, scale_denom, box, px_gw, px_gh);
-
-    if (use_spatial_index_)
-    {
-        std::ostringstream spatial_sql;
-        spatial_sql << " WHERE SDO_FILTER(";
-        spatial_sql << geometry_field_ << "," << sql_bbox(box);
-        spatial_sql << ", 'querytype = WINDOW') = 'TRUE'";
-
-        if (boost::algorithm::ifind_first(query, "WHERE"))
-        {
-            boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
-        }
-        else if (boost::algorithm::ifind_first(query, table_name_))
-        {
-            boost::algorithm::ireplace_first(query, table_name_, table_name_ + " " + spatial_sql.str());
-        }
-        else
-        {
-            MAPNIK_LOG_WARN(occi) << "occi_datasource: cannot determine where to add the spatial filter declaration";
-        }
-    }
-
-    s << " FROM " << query;
-
-    if (row_limit_ > 0)
-    {
-        s << " WHERE ROWNUM < " << row_limit_;
-    }
-
-    MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
-
-    return std::make_shared<occi_featureset>(pool_,
-                                                conn_,
-                                                ctx,
-                                                s.str(),
-                                                desc_.get_encoding(),
-                                                use_connection_pool_,
-                                                use_wkb_,
-                                                row_prefetch_);
-}
-
-featureset_ptr occi_datasource::features_at_point(coord2d const& pt, double tol) const
-{
-#ifdef MAPNIK_STATS
-    mapnik::progress_timer __stats__(std::clog, "occi_datasource::features_at_point");
-#endif
-
-    std::ostringstream s;
-    s << "SELECT ";
-    if (use_wkb_)
-    {
-        s << "SDO_UTIL.TO_WKBGEOMETRY(" << geometry_field_ << ")";
-    }
-    else
-    {
-        s << geometry_field_;
-    }
-    std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
-    std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
-    mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
-    while (itr != end)
-    {
-        s << ", " << itr->get_name();
-        ctx->push(itr->get_name());
-        ++itr;
-    }
-
-    box2d<double> box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol);
-    std::string query = populate_tokens(table_, FMAX, box, 0, 0);
-
-    if (use_spatial_index_)
-    {
-        std::ostringstream spatial_sql;
-        spatial_sql << " WHERE SDO_FILTER(";
-        spatial_sql << geometry_field_ << "," << sql_bbox(box);
-        spatial_sql << ", 'querytype = WINDOW') = 'TRUE'";
-
-        if (boost::algorithm::ifind_first(query, "WHERE"))
-        {
-            boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
-        }
-        else if (boost::algorithm::ifind_first(query, table_name_))
-        {
-            boost::algorithm::ireplace_first(query, table_name_, table_name_ + " " + spatial_sql.str());
-        }
-        else
-        {
-            MAPNIK_LOG_WARN(occi) << "occi_datasource: Cannot determine where to add the spatial filter declaration";
-        }
-    }
-
-    s << " FROM " << query;
-
-    if (row_limit_ > 0)
-    {
-        s << " WHERE ROWNUM < " << row_limit_;
-    }
-
-    MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
-
-    return std::make_shared<occi_featureset>(pool_,
-                                                conn_,
-                                                ctx,
-                                                s.str(),
-                                                desc_.get_encoding(),
-                                                use_connection_pool_,
-                                                use_wkb_,
-                                                row_prefetch_);
-}
diff --git a/plugins/input/occi/occi_datasource.hpp b/plugins/input/occi/occi_datasource.hpp
deleted file mode 100644
index 0affc33..0000000
--- a/plugins/input/occi/occi_datasource.hpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef OCCI_DATASOURCE_HPP
-#define OCCI_DATASOURCE_HPP
-
-// mapnik
-#include <mapnik/datasource.hpp>
-#include <mapnik/params.hpp>
-#include <mapnik/query.hpp>
-#include <mapnik/feature.hpp>
-#include <mapnik/box2d.hpp>
-#include <mapnik/coord.hpp>
-#include <mapnik/feature_layer_desc.hpp>
-#include <mapnik/value_types.hpp>
-
-// boost
-#include <boost/optional.hpp>
-#include <memory>
-
-// stl
-#include <vector>
-#include <string>
-
-// oci
-#include "occi_types.hpp"
-
-class occi_datasource : public mapnik::datasource
-{
-public:
-    occi_datasource(mapnik::parameters const& params);
-    virtual ~occi_datasource ();
-    mapnik::datasource::datasource_t type() const;
-    static const char * name();
-    mapnik::featureset_ptr features(mapnik::query const& q) const;
-    mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const;
-    mapnik::box2d<double> envelope() const;
-    boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
-    mapnik::layer_descriptor get_descriptor() const;
-
-private:
-    std::string sql_bbox(mapnik::box2d<double> const& env) const;
-    std::string populate_tokens(std::string const& sql,
-                                double scale_denom,
-                                mapnik::box2d<double> const& env,
-                                double pixel_width,
-                                double pixel_height) const;
-
-    static const std::string METADATA_TABLE;
-    static const double FMAX;
-
-    mapnik::datasource::datasource_t type_;
-    std::string table_;
-    std::string table_name_;
-    std::string fields_;
-    std::string geometry_field_;
-    int srid_;
-    bool srid_initialized_;
-    mutable bool extent_initialized_;
-    mutable mapnik::box2d<double> extent_;
-    const std::string bbox_token_;
-    const std::string scale_denom_token_;
-    const std::string pixel_width_token_;
-    const std::string pixel_height_token_;
-    mapnik::layer_descriptor desc_;
-    bool use_wkb_;
-    mapnik::value_integer row_limit_;
-    int row_prefetch_;
-    oracle::occi::StatelessConnectionPool* pool_;
-    oracle::occi::Connection* conn_;
-    bool use_connection_pool_;
-    bool use_spatial_index_;
-    bool estimate_extent_;
-};
-
-#endif // OCCI_DATASOURCE_HPP
diff --git a/plugins/input/occi/occi_featureset.cpp b/plugins/input/occi/occi_featureset.cpp
deleted file mode 100644
index 0a0b942..0000000
--- a/plugins/input/occi/occi_featureset.cpp
+++ /dev/null
@@ -1,516 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-// mapnik
-#include <mapnik/global.hpp>
-#include <mapnik/debug.hpp>
-#include <mapnik/box2d.hpp>
-#include <mapnik/feature.hpp>
-#include <mapnik/feature_layer_desc.hpp>
-#include <mapnik/wkb.hpp>
-#include <mapnik/unicode.hpp>
-#include <mapnik/value_types.hpp>
-#include <mapnik/feature_factory.hpp>
-#include <mapnik/make_unique.hpp>
-
-// ogr
-#include "occi_featureset.hpp"
-
-using mapnik::query;
-using mapnik::box2d;
-using mapnik::feature_ptr;
-using mapnik::geometry_type;
-using mapnik::geometry_utils;
-using mapnik::transcoder;
-using mapnik::datasource_exception;
-using mapnik::feature_factory;
-
-using oracle::occi::Connection;
-using oracle::occi::Statement;
-using oracle::occi::ResultSet;
-using oracle::occi::StatelessConnectionPool;
-using oracle::occi::MetaData;
-using oracle::occi::SQLException;
-using oracle::occi::Type;
-using oracle::occi::Number;
-using oracle::occi::Blob;
-
-occi_featureset::occi_featureset(StatelessConnectionPool* pool,
-                                 Connection* conn,
-                                 mapnik::context_ptr const& ctx,
-                                 std::string const& sqlstring,
-                                 std::string const& encoding,
-                                 bool use_connection_pool,
-                                 bool use_wkb,
-                                 unsigned prefetch_rows)
-    : rs_(nullptr),
-      tr_(new transcoder(encoding)),
-      feature_id_(1),
-      ctx_(ctx),
-      use_wkb_(use_wkb)
-{
-    if (use_connection_pool)
-    {
-        conn_.set_pool(pool);
-    }
-    else
-    {
-        conn_.set_connection(conn, false);
-    }
-
-    try
-    {
-        rs_ = conn_.execute_query(sqlstring, prefetch_rows);
-    }
-    catch (SQLException &ex)
-    {
-        MAPNIK_LOG_ERROR(occi) << "OCCI Plugin: error processing " << sqlstring << " : " << ex.getMessage();
-
-        rs_ = nullptr;
-    }
-}
-
-occi_featureset::~occi_featureset()
-{
-}
-
-feature_ptr occi_featureset::next()
-{
-    while (rs_ != nullptr && rs_->next() == oracle::occi::ResultSet::DATA_AVAILABLE)
-    {
-        feature_ptr feature(feature_factory::create(ctx_, feature_id_));
-
-        if (use_wkb_)
-        {
-            Blob blob = rs_->getBlob(1);
-            blob.open(oracle::occi::OCCI_LOB_READONLY);
-
-            unsigned int size = blob.length();
-            if (buffer_.size() < size)
-            {
-                buffer_.resize(size);
-            }
-
-            oracle::occi::Stream* instream = blob.getStream(1, 0);
-            instream->readBuffer(buffer_.data(), size);
-            blob.closeStream(instream);
-            blob.close();
-
-            if (! geometry_utils::from_wkb(feature->paths(), buffer_.data(), size))
-            {
-                continue;
-            }
-        }
-        else
-        {
-            const std::unique_ptr<SDOGeometry> geom(dynamic_cast<SDOGeometry*>(rs_->getObject(1)));
-            if (geom.get())
-            {
-                convert_geometry(geom.get(), feature);
-            }
-            else
-            {
-                continue;
-            }
-        }
-
-        std::vector<MetaData> listOfColumns = rs_->getColumnListMetaData();
-
-        for (unsigned int i = 1; i < listOfColumns.size(); ++i)
-        {
-            MetaData columnObj = listOfColumns[i];
-
-            std::string fld_name = columnObj.getString(MetaData::ATTR_NAME);
-            int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE);
-
-            /*
-              int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE);
-              if (type_code == OCCI_TYPECODE_OBJECT)
-              {
-              continue;
-              }
-            */
-
-            switch (type_oid)
-            {
-            case oracle::occi::OCCIBOOL:
-                feature->put(fld_name, (rs_->getInt(i + 1) != 0));
-                break;
-            case oracle::occi::OCCIINT:
-            case oracle::occi::OCCIUNSIGNED_INT:
-                feature->put(fld_name, static_cast<mapnik::value_integer>(rs_->getInt(i + 1)));
-                break;
-            case oracle::occi::OCCIFLOAT:
-            case oracle::occi::OCCIBFLOAT:
-                feature->put(fld_name, (double)rs_->getFloat(i + 1));
-                break;
-            case oracle::occi::OCCIDOUBLE:
-            case oracle::occi::OCCIBDOUBLE:
-            case oracle::occi::OCCINUMBER:
-            case oracle::occi::OCCI_SQLT_NUM:
-                feature->put(fld_name, rs_->getDouble(i + 1));
-                break;
-            case oracle::occi::OCCICHAR:
-            case oracle::occi::OCCISTRING:
-            case oracle::occi::OCCI_SQLT_AFC:
-            case oracle::occi::OCCI_SQLT_AVC:
-            case oracle::occi::OCCI_SQLT_CHR:
-            case oracle::occi::OCCI_SQLT_LNG:
-            case oracle::occi::OCCI_SQLT_LVC:
-            case oracle::occi::OCCI_SQLT_STR:
-            case oracle::occi::OCCI_SQLT_VCS:
-            case oracle::occi::OCCI_SQLT_VNU:
-            case oracle::occi::OCCI_SQLT_VBI:
-            case oracle::occi::OCCI_SQLT_VST:
-            case oracle::occi::OCCIROWID:
-            case oracle::occi::OCCI_SQLT_RDD:
-            case oracle::occi::OCCI_SQLT_RID:
-            case oracle::occi::OCCIDATE:
-            case oracle::occi::OCCI_SQLT_DAT:
-            case oracle::occi::OCCI_SQLT_DATE:
-            case oracle::occi::OCCI_SQLT_TIME:
-            case oracle::occi::OCCI_SQLT_TIME_TZ:
-            case oracle::occi::OCCITIMESTAMP:
-            case oracle::occi::OCCI_SQLT_TIMESTAMP:
-            case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
-            case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
-                feature->put(fld_name, static_cast<mapnik::value_unicode_string>(tr_->transcode(rs_->getString(i + 1).c_str())));
-                break;
-            case oracle::occi::OCCIINTERVALDS:
-            case oracle::occi::OCCIINTERVALYM:
-            case oracle::occi::OCCI_SQLT_INTERVAL_YM:
-            case oracle::occi::OCCI_SQLT_INTERVAL_DS:
-            case oracle::occi::OCCIANYDATA:
-            case oracle::occi::OCCIBLOB:
-            case oracle::occi::OCCIBFILE:
-            case oracle::occi::OCCIBYTES:
-            case oracle::occi::OCCICLOB:
-            case oracle::occi::OCCIVECTOR:
-            case oracle::occi::OCCIMETADATA:
-            case oracle::occi::OCCIPOBJECT:
-            case oracle::occi::OCCIREF:
-            case oracle::occi::OCCIREFANY:
-            case oracle::occi::OCCISTREAM:
-            case oracle::occi::OCCICURSOR:
-            case oracle::occi::OCCI_SQLT_FILE:
-            case oracle::occi::OCCI_SQLT_CFILE:
-            case oracle::occi::OCCI_SQLT_REF:
-            case oracle::occi::OCCI_SQLT_CLOB:
-            case oracle::occi::OCCI_SQLT_BLOB:
-            case oracle::occi::OCCI_SQLT_RSET:
-                {
-                    MAPNIK_LOG_WARN(occi) << "occi_featureset: Unsupported datatype "
-                                          << occi_enums::resolve_datatype(type_oid)
-                                          << " (type_oid=" << type_oid << ")";
-                    break;
-                }
-            default: // shouldn't get here
-                {
-                    MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown datatype "
-                                          << "(type_oid=" << type_oid << ")";
-                    break;
-                }
-            }
-        }
-
-        ++feature_id_;
-
-        return feature;
-    }
-
-    return feature_ptr();
-}
-
-
-void occi_featureset::convert_geometry(SDOGeometry* geom, feature_ptr feature)
-{
-    int gtype = (int)geom->getSdo_gtype();
-    int dimensions = gtype / 1000;
-    int lrsvalue = (gtype - dimensions * 1000) / 100;
-    int geomtype = (gtype - dimensions * 1000 - lrsvalue * 100);
-
-    const std::vector<Number>& elem_info = geom->getSdo_elem_info();
-    const std::vector<Number>& ordinates = geom->getSdo_ordinates();
-    const int ordinates_size = (int)ordinates.size();
-
-    switch (geomtype)
-    {
-    case SDO_GTYPE_POINT:
-    {
-        SDOPointType* sdopoint = geom->getSdo_point();
-        if (sdopoint && ! sdopoint->isNull())
-        {
-            std::unique_ptr<geometry_type> point = std::make_unique<geometry_type>(mapnik::geometry::geometry_types::Point);
-            point->move_to(sdopoint->getX(), sdopoint->getY());
-            feature->add_geometry(point.release());
-        }
-    }
-    break;
-    case SDO_GTYPE_LINE:
-    {
-        if (ordinates_size >= dimensions)
-        {
-            const bool is_single_geom = true;
-            const bool is_point_type = false;
-            convert_ordinates(feature,
-                              mapnik::geometry::geometry_types::LineString,
-                              elem_info,
-                              ordinates,
-                              dimensions,
-                              is_single_geom,
-                              is_point_type);
-        }
-    }
-    break;
-    case SDO_GTYPE_POLYGON:
-    {
-        if (ordinates_size >= dimensions)
-        {
-            const bool is_single_geom = true;
-            const bool is_point_type = false;
-            convert_ordinates(feature,
-                              mapnik::geometry::geometry_types::Polygon,
-                              elem_info,
-                              ordinates,
-                              dimensions,
-                              is_single_geom,
-                              is_point_type);
-        }
-    }
-    break;
-    case SDO_GTYPE_MULTIPOINT:
-    {
-        if (ordinates_size >= dimensions)
-        {
-            const bool is_single_geom = false;
-            const bool is_point_type = true;
-            convert_ordinates(feature,
-                              mapnik::geometry::geometry_types::Point,
-                              elem_info,
-                              ordinates,
-                              dimensions,
-                              is_single_geom,
-                              is_point_type);
-        }
-    }
-    break;
-    case SDO_GTYPE_MULTILINE:
-    {
-        if (ordinates_size >= dimensions)
-        {
-            const bool is_single_geom = false;
-            const bool is_point_type = false;
-
-            convert_ordinates(feature,
-                              mapnik::geometry::geometry_types::LineString,
-                              elem_info,
-                              ordinates,
-                              dimensions,
-                              is_single_geom,
-                              is_point_type);
-        }
-    }
-    break;
-    case SDO_GTYPE_MULTIPOLYGON:
-    {
-        if (ordinates_size >= dimensions)
-        {
-            const bool is_single_geom = false;
-            const bool is_point_type = false;
-
-            convert_ordinates(feature,
-                              mapnik::geometry::geometry_types::Polygon,
-                              elem_info,
-                              ordinates,
-                              dimensions,
-                              is_single_geom,
-                              is_point_type);
-        }
-
-    }
-    break;
-    case SDO_GTYPE_COLLECTION:
-    {
-        if (ordinates_size >= dimensions)
-        {
-            const bool is_single_geom = false;
-            const bool is_point_type = false;
-
-            convert_ordinates(feature,
-                              mapnik::geometry::geometry_types::Polygon,
-                              elem_info,
-                              ordinates,
-                              dimensions,
-                              is_single_geom,
-                              is_point_type);
-        }
-    }
-    break;
-    case SDO_GTYPE_UNKNOWN:
-    default:
-    {
-        MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown oracle enum "
-                              << occi_enums::resolve_gtype(geomtype)
-                              << "(gtype=" << gtype << ")";
-    }
-    break;
-    }
-}
-
-void occi_featureset::convert_ordinates(mapnik::feature_ptr feature,
-                                        const mapnik::geometry_type::types& geom_type,
-                                        const std::vector<Number>& elem_info,
-                                        const std::vector<Number>& ordinates,
-                                        const int dimensions,
-                                        const bool is_single_geom,
-                                        const bool is_point_geom)
-{
-    const int elem_size = elem_info.size();
-    const int ord_size = ordinates.size();
-
-    if (elem_size >= 0)
-    {
-        int offset = elem_info[0];
-        int etype = elem_info[1];
-        int interp = elem_info[2];
-
-        if (! is_single_geom && elem_size > SDO_ELEM_INFO_SIZE)
-        {
-            geometry_type* geom = new geometry_type(geom_type);
-
-            for (int i = SDO_ELEM_INFO_SIZE; i < elem_size; i+=3)
-            {
-                int next_offset = elem_info[i];
-                int next_etype = elem_info[i + 1];
-                int next_interp = elem_info[i + 2];
-                bool is_linear_element = true;
-                bool is_unknown_etype = false;
-                mapnik::geometry_type::types gtype = mapnik::geometry::geometry_types::Point;
-
-                switch (etype)
-                {
-                case SDO_ETYPE_POINT:
-                    if (interp == SDO_INTERPRETATION_POINT)     {}
-                    if (interp > SDO_INTERPRETATION_POINT)      {}
-                    gtype = mapnik::geometry::geometry_types::Point;
-                    break;
-
-                case SDO_ETYPE_LINESTRING:
-                    if (interp == SDO_INTERPRETATION_STRAIGHT)  {}
-                    if (interp == SDO_INTERPRETATION_CIRCULAR)  {}
-                    gtype = mapnik::geometry::geometry_types::LineString;
-                    break;
-
-                case SDO_ETYPE_POLYGON:
-                case SDO_ETYPE_POLYGON_INTERIOR:
-                    if (interp == SDO_INTERPRETATION_STRAIGHT)  {}
-                    if (interp == SDO_INTERPRETATION_CIRCULAR)  {}
-                    if (interp == SDO_INTERPRETATION_RECTANGLE) {}
-                    if (interp == SDO_INTERPRETATION_CIRCLE)    {}
-                    gtype = mapnik::geometry::geometry_types::Polygon;
-                    break;
-
-                case SDO_ETYPE_COMPOUND_LINESTRING:
-                case SDO_ETYPE_COMPOUND_POLYGON:
-                case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR:
-                    // interp = next ETYPE to consider
-                    is_linear_element = false;
-                    gtype = mapnik::geometry::geometry_types::Polygon;
-                    break;
-
-                case SDO_ETYPE_UNKNOWN:    // unknown
-                default:
-                    is_unknown_etype = true;
-                    break;
-                }
-
-                if (is_unknown_etype)
-                {
-                    break;
-                }
-
-                if (is_linear_element)
-                {
-                    if (geom)
-                    {
-                        feature->add_geometry(geom);
-                    }
-
-                    geom = new geometry_type(gtype);
-                    fill_geometry_type(geom,
-                                       offset - 1,
-                                       next_offset - 1,
-                                       ordinates,
-                                       dimensions,
-                                       is_point_geom);
-                }
-
-                offset = next_offset;
-                etype = next_etype;
-                interp = next_interp;
-            }
-
-            if (geom)
-            {
-                feature->add_geometry(geom);
-                geom = 0;
-            }
-        }
-        else
-        {
-            geometry_type * geom = new geometry_type(geom_type);
-            fill_geometry_type(geom,
-                               offset - 1,
-                               ord_size,
-                               ordinates,
-                               dimensions,
-                               is_point_geom);
-
-            feature->add_geometry(geom);
-        }
-    }
-}
-
-void occi_featureset::fill_geometry_type(geometry_type* geom,
-                                         const int real_offset,
-                                         const int next_offset,
-                                         const std::vector<Number>& ordinates,
-                                         const int dimensions,
-                                         const bool is_point_geom)
-{
-    geom->move_to((double) ordinates[real_offset], (double) ordinates[real_offset + 1]);
-
-    if (is_point_geom)
-    {
-        for (int p = real_offset + dimensions; p < next_offset; p += dimensions)
-        {
-            geom->move_to((double) ordinates[p], (double) ordinates[p + 1]);
-        }
-    }
-    else
-    {
-        for (int p = real_offset + dimensions; p < next_offset; p += dimensions)
-        {
-            geom->line_to((double) ordinates[p], (double) ordinates[p + 1]);
-        }
-    }
-}
diff --git a/plugins/input/occi/occi_featureset.hpp b/plugins/input/occi/occi_featureset.hpp
deleted file mode 100644
index 13445dd..0000000
--- a/plugins/input/occi/occi_featureset.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef OCCI_FEATURESET_HPP
-#define OCCI_FEATURESET_HPP
-
-// mapnik
-#include <mapnik/feature.hpp>
-#include <mapnik/datasource.hpp>
-#include <mapnik/unicode.hpp>
-// stl
-#include <memory>
-
-// oci
-#include "occi_types.hpp"
-
-#include <vector>
-
-class occi_featureset : public mapnik::Featureset
-{
-public:
-    occi_featureset(oracle::occi::StatelessConnectionPool* pool,
-                    oracle::occi::Connection* conn,
-                    mapnik::context_ptr const& ctx,
-                    std::string const& sqlstring,
-                    std::string const& encoding,
-                    bool use_connection_pool,
-                    bool use_wkb,
-                    unsigned prefetch_rows);
-    virtual ~occi_featureset();
-    mapnik::feature_ptr next();
-
-private:
-    void convert_geometry (SDOGeometry* geom, mapnik::feature_ptr feature);
-    void convert_ordinates (mapnik::feature_ptr feature,
-                            const mapnik::geometry_type::types& geom_type,
-                            const std::vector<oracle::occi::Number>& elem_info,
-                            const std::vector<oracle::occi::Number>& ordinates,
-                            const int dimensions,
-                            const bool is_single_geom,
-                            const bool is_point_geom);
-    void fill_geometry_type (mapnik::geometry_type* geom,
-                             const int real_offset,
-                             const int next_offset,
-                             const std::vector<oracle::occi::Number>& ordinates,
-                             const int dimensions,
-                             const bool is_point_geom);
-
-    occi_connection_ptr conn_;
-    oracle::occi::ResultSet* rs_;
-    const std::unique_ptr<mapnik::transcoder> tr_;
-    mapnik::value_integer feature_id_;
-    mapnik::context_ptr ctx_;
-    bool use_wkb_;
-    std::vector<char> buffer_;
-};
-
-#endif // OCCI_FEATURESET_HPP
diff --git a/plugins/input/occi/occi_types.cpp b/plugins/input/occi/occi_types.cpp
deleted file mode 100644
index 4396706..0000000
--- a/plugins/input/occi/occi_types.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software, you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library, if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#include "occi_types.hpp"
-
-std::string occi_enums::resolve_gtype(int gtype)
-{
-    switch (gtype)
-    {
-    case SDO_GTYPE_UNKNOWN:        return "SDO_GTYPE_UNKNOWN";
-    case SDO_GTYPE_POINT:          return "SDO_GTYPE_POINT";
-    case SDO_GTYPE_LINE:           return "SDO_GTYPE_LINE";
-    case SDO_GTYPE_POLYGON:        return "SDO_GTYPE_POLYGON";
-    case SDO_GTYPE_MULTIPOINT:     return "SDO_GTYPE_MULTIPOINT";
-    case SDO_GTYPE_MULTILINE:      return "SDO_GTYPE_MULTILINE";
-    case SDO_GTYPE_MULTIPOLYGON:   return "SDO_GTYPE_MULTIPOLYGON";
-    case SDO_GTYPE_COLLECTION:     return "SDO_GTYPE_COLLECTION";
-    default:                       return "<unknown SDO_GTYPE>";
-    }
-}
-
-std::string occi_enums::resolve_etype(int etype)
-{
-    switch (etype)
-    {
-    case SDO_ETYPE_UNKNOWN:                   return "SDO_ETYPE_UNKNOWN";
-    case SDO_ETYPE_POINT:                     return "SDO_ETYPE_POINT";
-    case SDO_ETYPE_LINESTRING:                return "SDO_ETYPE_LINESTRING";
-    case SDO_ETYPE_POLYGON:                   return "SDO_ETYPE_POLYGON";
-    case SDO_ETYPE_POLYGON_INTERIOR:          return "SDO_ETYPE_POLYGON_INTERIOR";
-    case SDO_ETYPE_COMPOUND_LINESTRING:       return "SDO_ETYPE_COMPOUND_LINESTRING";
-    case SDO_ETYPE_COMPOUND_POLYGON:          return "SDO_ETYPE_COMPOUND_POLYGON";
-    case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR: return "SDO_ETYPE_COMPOUND_POLYGON_INTERIOR";
-    default:                                  return "<unknown SDO_ETYPE>";
-    }
-}
-
-std::string occi_enums::resolve_datatype(int type_id)
-{
-    switch (type_id)
-    {
-    case oracle::occi::OCCIINT:                 return "OCCIINT";
-    case oracle::occi::OCCIUNSIGNED_INT:        return "OCCIUNSIGNED_INT";
-    case oracle::occi::OCCIFLOAT:               return "OCCIFLOAT";
-    case oracle::occi::OCCIBFLOAT:              return "OCCIBFLOAT";
-    case oracle::occi::OCCIDOUBLE:              return "OCCIDOUBLE";
-    case oracle::occi::OCCIBDOUBLE:             return "OCCIBDOUBLE";
-    case oracle::occi::OCCINUMBER:              return "OCCINUMBER";
-    case oracle::occi::OCCI_SQLT_NUM:           return "OCCI_SQLT_NUM";
-    case oracle::occi::OCCICHAR:                return "OCCICHAR";
-    case oracle::occi::OCCISTRING:              return "OCCISTRING";
-    case oracle::occi::OCCI_SQLT_AFC:           return "OCCI_SQLT_AFC";
-    case oracle::occi::OCCI_SQLT_AVC:           return "OCCI_SQLT_AVC";
-    case oracle::occi::OCCI_SQLT_CHR:           return "OCCI_SQLT_CHR";
-    case oracle::occi::OCCI_SQLT_LVC:           return "OCCI_SQLT_LVC";
-    case oracle::occi::OCCI_SQLT_LNG:           return "OCCI_SQLT_LNG";
-    case oracle::occi::OCCI_SQLT_STR:           return "OCCI_SQLT_STR";
-    case oracle::occi::OCCI_SQLT_VCS:           return "OCCI_SQLT_VCS";
-    case oracle::occi::OCCI_SQLT_VNU:           return "OCCI_SQLT_VNU";
-    case oracle::occi::OCCI_SQLT_VBI:           return "OCCI_SQLT_VBI";
-    case oracle::occi::OCCI_SQLT_VST:           return "OCCI_SQLT_VST";
-    case oracle::occi::OCCI_SQLT_RDD:           return "OCCI_SQLT_RDD";
-    case oracle::occi::OCCIDATE:                return "OCCIDATE";
-    case oracle::occi::OCCITIMESTAMP:           return "OCCITIMESTAMP";
-    case oracle::occi::OCCI_SQLT_DAT:           return "OCCI_SQLT_DAT";
-    case oracle::occi::OCCI_SQLT_TIMESTAMP:     return "OCCI_SQLT_TIMESTAMP";
-    case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: return "OCCI_SQLT_TIMESTAMP_LTZ";
-    case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:  return "OCCI_SQLT_TIMESTAMP_TZ";
-    case oracle::occi::OCCIPOBJECT:             return "OCCIPOBJECT";
-    default:                                    return "<unknown ATTR_DATA_TYPE>";
-    }
-}
diff --git a/plugins/input/occi/occi_types.hpp b/plugins/input/occi/occi_types.hpp
deleted file mode 100644
index cc8cd41..0000000
--- a/plugins/input/occi/occi_types.hpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software, you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library, if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef OCCI_TYPES_HPP
-#define OCCI_TYPES_HPP
-
-// mapnik
-#include <mapnik/debug.hpp>
-#include <mapnik/util/singleton.hpp>
-
-// occi
-#include <occi.h>
-
-// ott generated SDOGeometry classes
-#include "spatial_classesh.h"
-#include "spatial_classesm.h"
-
-// check for oracle support
-#if OCCI_MAJOR_VERSION >= 10 && OCCI_MINOR_VERSION >= 1
-//     We have at least ORACLE 10g >= 10.2.0.X
-#else
-#error Only ORACLE 10g >= 10.2.0.X is supported !
-#endif
-
-// geometry types definitions
-enum
-{
-    SDO_GTYPE_UNKNOWN                   = 0,
-    SDO_GTYPE_POINT                     = 1,
-    SDO_GTYPE_LINE                      = 2,
-    SDO_GTYPE_POLYGON                   = 3,
-    SDO_GTYPE_COLLECTION                = 4,
-    SDO_GTYPE_MULTIPOINT                = 5,
-    SDO_GTYPE_MULTILINE                 = 6,
-    SDO_GTYPE_MULTIPOLYGON              = 7,
-
-    SDO_GTYPE_2DPOINT                   = 2001,
-    SDO_GTYPE_2DLINE                    = 2002,
-    SDO_GTYPE_2DPOLYGON                 = 2003,
-    SDO_GTYPE_2DMULTIPOINT              = 2005,
-    SDO_GTYPE_2DMULTILINE               = 2006,
-    SDO_GTYPE_2DMULTIPOLYGON            = 2007,
-
-    SDO_ELEM_INFO_SIZE                  = 3,
-
-    SDO_ETYPE_UNKNOWN                   = 0,
-    SDO_ETYPE_POINT                     = 1,
-    SDO_ETYPE_LINESTRING                = 2,
-    SDO_ETYPE_POLYGON                   = 1003,
-    SDO_ETYPE_POLYGON_INTERIOR          = 2003,
-    SDO_ETYPE_COMPOUND_LINESTRING       = 4,
-    SDO_ETYPE_COMPOUND_POLYGON          = 1005,
-    SDO_ETYPE_COMPOUND_POLYGON_INTERIOR = 2005,
-
-    SDO_INTERPRETATION_POINT            = 1,
-    SDO_INTERPRETATION_RECTANGLE        = 3,
-    SDO_INTERPRETATION_CIRCLE           = 4,
-    SDO_INTERPRETATION_STRAIGHT         = 1,
-    SDO_INTERPRETATION_CIRCULAR         = 2
-};
-
-class occi_environment : public mapnik::singleton<occi_environment, mapnik::CreateStatic>
-{
-    friend class mapnik::CreateStatic<occi_environment>;
-
-public:
-
-    oracle::occi::Environment* get_environment()
-    {
-        return env_;
-    }
-
-    oracle::occi::Connection* create_connection(
-        const std::string& user,
-        const std::string& password,
-        const std::string& host)
-    {
-        MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_connection";
-
-        return env_->createConnection(user, password, host);
-    }
-
-    void destroy_connection(oracle::occi::Connection* conn)
-    {
-        env_->terminateConnection(conn);
-    }
-
-    oracle::occi::StatelessConnectionPool* create_pool(
-        const std::string& user,
-        const std::string& password,
-        const std::string& host,
-        int max_size,
-        int initial_size,
-        int incr_size)
-    {
-        MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_pool";
-
-        return env_->createStatelessConnectionPool(
-            user,
-            password,
-            host,
-            max_size,
-            initial_size,
-            incr_size,
-            oracle::occi::StatelessConnectionPool::HOMOGENEOUS);
-    }
-
-    void destroy_pool(oracle::occi::StatelessConnectionPool* pool)
-    {
-        env_->terminateStatelessConnectionPool(
-            pool,
-            oracle::occi::StatelessConnectionPool::SPD_FORCE);
-    }
-
-private:
-
-    occi_environment()
-        : env_(0)
-    {
-        MAPNIK_LOG_DEBUG(occi) << "occi_environment: constructor";
-
-        env_ = oracle::occi::Environment::createEnvironment(
-            (oracle::occi::Environment::Mode)(oracle::occi::Environment::OBJECT
-                                              | oracle::occi::Environment::THREADED_MUTEXED));
-        RegisterClasses(env_);
-    }
-
-    ~occi_environment()
-    {
-        MAPNIK_LOG_DEBUG(occi) << "occi_environment: destructor";
-
-        oracle::occi::Environment::terminateEnvironment(env_);
-        env_ = 0;
-    }
-
-    oracle::occi::Environment* env_;
-};
-
-
-class occi_connection_ptr
-{
-public:
-    explicit occi_connection_ptr()
-        : pool_(0),
-          conn_(0),
-          stmt_(0),
-          rs_(0),
-          owns_connection_(false)
-    {
-    }
-
-    ~occi_connection_ptr()
-    {
-        close_query(true);
-    }
-
-    void set_pool(oracle::occi::StatelessConnectionPool* pool)
-    {
-        close_query(true);
-
-        pool_ = pool;
-        conn_ = pool_->getConnection();
-        owns_connection_ = true;
-    }
-
-    void set_connection(oracle::occi::Connection* conn, bool owns_connection)
-    {
-        close_query(true);
-
-        pool_ = 0;
-        conn_ = conn;
-        owns_connection_ = owns_connection;
-    }
-
-    oracle::occi::ResultSet* execute_query(std::string const& s, const unsigned prefetch = 0)
-    {
-        close_query(false);
-
-        MAPNIK_LOG_DEBUG(occi) << "occi_connection_ptr: " << s;
-
-        stmt_ = conn_->createStatement(s);
-
-        if (prefetch > 0)
-        {
-            stmt_->setPrefetchMemorySize(0);
-            stmt_->setPrefetchRowCount(prefetch);
-        }
-
-        rs_ = stmt_->executeQuery();
-
-        return rs_;
-    }
-
-private:
-    void close_query(const bool release_connection)
-    {
-        if (conn_)
-        {
-            if (stmt_)
-            {
-                if (rs_)
-                {
-                    stmt_->closeResultSet(rs_);
-                    rs_ = 0;
-                }
-
-                conn_->terminateStatement(stmt_);
-                stmt_ = 0;
-            }
-
-            if (release_connection)
-            {
-                if (pool_)
-                {
-                    pool_->releaseConnection(conn_);
-                }
-                else
-                {
-                    if (owns_connection_)
-                    {
-                        occi_environment::instance().destroy_connection(conn_);
-                    }
-                }
-
-                conn_ = 0;
-            }
-        }
-    }
-
-    oracle::occi::StatelessConnectionPool* pool_;
-    oracle::occi::Connection* conn_;
-    oracle::occi::Statement* stmt_;
-    oracle::occi::ResultSet* rs_;
-    bool owns_connection_;
-};
-
-class occi_enums
-{
-public:
-
-    static std::string resolve_gtype(int gtype);
-    static std::string resolve_etype(int etype);
-    static std::string resolve_datatype(int type_id);
-};
-
-#endif // OCCI_TYPES_HPP
diff --git a/plugins/input/occi/spatial_classesh.h b/plugins/input/occi/spatial_classesh.h
deleted file mode 100644
index 9543b4e..0000000
--- a/plugins/input/occi/spatial_classesh.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#ifndef SPATIAL_CLASSESH_ORACLE
-# define SPATIAL_CLASSESH_ORACLE
-
-#ifndef OCCI_ORACLE
-# include <occi.h>
-#endif
-
-class SDOPointType;
-class SDOGeometry;
-
-/************************************************************/
-//  generated declarations for the SDO_POINT_TYPE object type.
-/************************************************************/
-
-class SDOPointType : public oracle::occi::PObject {
-
-private:
-
-   oracle::occi::Number X;
-   oracle::occi::Number Y;
-   oracle::occi::Number Z;
-
-public:
-
-   oracle::occi::Number getX() const;
-
-   void setX(const oracle::occi::Number &value);
-
-   oracle::occi::Number getY() const;
-
-   void setY(const oracle::occi::Number &value);
-
-   oracle::occi::Number getZ() const;
-
-   void setZ(const oracle::occi::Number &value);
-
-   void *operator new(size_t size);
-
-   void *operator new(size_t size, const oracle::occi::Connection * sess,
-      const OCCI_STD_NAMESPACE::string& table);
-
-   void *operator new(size_t, void *ctxOCCI_);
-
-   void *operator new(size_t size, const oracle::occi::Connection *sess,
-      const OCCI_STD_NAMESPACE::string &tableName, 
-      const OCCI_STD_NAMESPACE::string &typeName,
-      const OCCI_STD_NAMESPACE::string &tableSchema, 
-      const OCCI_STD_NAMESPACE::string &typeSchema);
-
-   OCCI_STD_NAMESPACE::string getSQLTypeName() const;
-
-   void getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
-      unsigned int &schemaNameLen, void **typeName,
-      unsigned int &typeNameLen) const;
-
-   SDOPointType();
-
-   SDOPointType(void *ctxOCCI_) : oracle::occi::PObject (ctxOCCI_) { }
-
-   static void *readSQL(void *ctxOCCI_);
-
-   virtual void readSQL(oracle::occi::AnyData& streamOCCI_);
-
-   static void writeSQL(void *objOCCI_, void *ctxOCCI_);
-
-   virtual void writeSQL(oracle::occi::AnyData& streamOCCI_);
-
-   ~SDOPointType();
-
-};
-
-/************************************************************/
-//  generated declarations for the SDO_GEOMETRY object type.
-/************************************************************/
-
-class SDOGeometry : public oracle::occi::PObject {
-
-private:
-
-   oracle::occi::Number SDO_GTYPE;
-   oracle::occi::Number SDO_SRID;
-   SDOPointType * SDO_POINT;
-   OCCI_STD_NAMESPACE::vector< oracle::occi::Number > SDO_ELEM_INFO;
-   OCCI_STD_NAMESPACE::vector< oracle::occi::Number > SDO_ORDINATES;
-
-public:
-
-   oracle::occi::Number getSdo_gtype() const;
-
-   void setSdo_gtype(const oracle::occi::Number &value);
-
-   oracle::occi::Number getSdo_srid() const;
-
-   void setSdo_srid(const oracle::occi::Number &value);
-
-   SDOPointType * getSdo_point() const;
-
-   void setSdo_point(SDOPointType * value);
-
-   OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_elem_info();
-
-   const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_elem_info() const;
-
-   void setSdo_elem_info(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value);
-
-   OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_ordinates();
-
-   const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& getSdo_ordinates() const;
-
-   void setSdo_ordinates(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value);
-
-   void *operator new(size_t size);
-
-   void *operator new(size_t size, const oracle::occi::Connection * sess,
-      const OCCI_STD_NAMESPACE::string& table);
-
-   void *operator new(size_t, void *ctxOCCI_);
-
-   void *operator new(size_t size, const oracle::occi::Connection *sess,
-      const OCCI_STD_NAMESPACE::string &tableName, 
-      const OCCI_STD_NAMESPACE::string &typeName,
-      const OCCI_STD_NAMESPACE::string &tableSchema, 
-      const OCCI_STD_NAMESPACE::string &typeSchema);
-
-   OCCI_STD_NAMESPACE::string getSQLTypeName() const;
-
-   void getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
-      unsigned int &schemaNameLen, void **typeName,
-      unsigned int &typeNameLen) const;
-
-   SDOGeometry();
-
-   SDOGeometry(void *ctxOCCI_) : oracle::occi::PObject (ctxOCCI_) { }
-
-   static void *readSQL(void *ctxOCCI_);
-
-   virtual void readSQL(oracle::occi::AnyData& streamOCCI_);
-
-   static void writeSQL(void *objOCCI_, void *ctxOCCI_);
-
-   virtual void writeSQL(oracle::occi::AnyData& streamOCCI_);
-
-   ~SDOGeometry();
-
-};
-
-#endif
diff --git a/plugins/input/occi/spatial_classesm.cpp b/plugins/input/occi/spatial_classesm.cpp
deleted file mode 100644
index aa4ea86..0000000
--- a/plugins/input/occi/spatial_classesm.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#ifndef SPATIAL_CLASSESM_ORACLE
-# include "spatial_classesm.h"
-#endif
-
-void RegisterClasses(oracle::occi::Environment* envOCCI_)
-{
-    oracle::occi::Map *mapOCCI_ = envOCCI_->getMap();
-    mapOCCI_->put("MDSYS.SDO_POINT_TYPE", &SDOPointType::readSQL, &SDOPointType::writeSQL);
-    mapOCCI_->put("MDSYS.SDO_GEOMETRY", &SDOGeometry::readSQL, &SDOGeometry::writeSQL);
-}
diff --git a/plugins/input/occi/spatial_classesm.h b/plugins/input/occi/spatial_classesm.h
deleted file mode 100644
index 78ca1c4..0000000
--- a/plugins/input/occi/spatial_classesm.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef SPATIAL_CLASSESM_ORACLE
-# define SPATIAL_CLASSESM_ORACLE
-
-#ifndef OCCI_ORACLE
-# include <occi.h>
-#endif
-
-#ifndef SPATIAL_CLASSESH_ORACLE
-# include "spatial_classesh.h"
-#endif
-
-void RegisterClasses(oracle::occi::Environment* envOCCI_);
-
-#endif
diff --git a/plugins/input/occi/spatial_classeso.cpp b/plugins/input/occi/spatial_classeso.cpp
deleted file mode 100644
index cbc7046..0000000
--- a/plugins/input/occi/spatial_classeso.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-#ifndef SPATIAL_CLASSESH_ORACLE
-# include "spatial_classesh.h"
-#endif
-
-
-/*****************************************************************/
-//  generated method implementations for the SDO_POINT_TYPE object type.
-/*****************************************************************/
-
-oracle::occi::Number SDOPointType::getX() const
-{
-    return X;
-}
-
-void SDOPointType::setX(const oracle::occi::Number &value)
-{
-    X = value;
-}
-
-oracle::occi::Number SDOPointType::getY() const
-{
-    return Y;
-}
-
-void SDOPointType::setY(const oracle::occi::Number &value)
-{
-    Y = value;
-}
-
-oracle::occi::Number SDOPointType::getZ() const
-{
-    return Z;
-}
-
-void SDOPointType::setZ(const oracle::occi::Number &value)
-{
-    Z = value;
-}
-
-void *SDOPointType::operator new(size_t size)
-{
-    return oracle::occi::PObject::operator new(size);
-}
-
-void *SDOPointType::operator new(size_t size, const oracle::occi::Connection * sess,
-                                 const OCCI_STD_NAMESPACE::string& table)
-{
-    return oracle::occi::PObject::operator new(size, sess, table,
-                                               (char *) "MDSYS.SDO_POINT_TYPE");
-}
-
-void *SDOPointType::operator new(size_t size, void *ctxOCCI_)
-{
-    return oracle::occi::PObject::operator new(size, ctxOCCI_);
-}
-
-void *SDOPointType::operator new(size_t size,
-                                 const oracle::occi::Connection *sess,
-                                 const OCCI_STD_NAMESPACE::string &tableName,
-                                 const OCCI_STD_NAMESPACE::string &typeName,
-                                 const OCCI_STD_NAMESPACE::string &tableSchema,
-                                 const OCCI_STD_NAMESPACE::string &typeSchema)
-{
-    return oracle::occi::PObject::operator new(size, sess, tableName,
-                                               typeName, tableSchema, typeSchema);
-}
-
-OCCI_STD_NAMESPACE::string SDOPointType::getSQLTypeName() const
-{
-    return OCCI_STD_NAMESPACE::string("MDSYS.SDO_POINT_TYPE");
-}
-
-void SDOPointType::getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
-                                  unsigned int &schemaNameLen, void **typeName, unsigned int &typeNameLen) const
-{
-    PObject::getSQLTypeName(env, &SDOPointType::readSQL, schemaName,
-                            schemaNameLen, typeName, typeNameLen);
-}
-
-SDOPointType::SDOPointType()
-{
-}
-
-void *SDOPointType::readSQL(void *ctxOCCI_)
-{
-    SDOPointType *objOCCI_ = new(ctxOCCI_) SDOPointType(ctxOCCI_);
-    oracle::occi::AnyData streamOCCI_(ctxOCCI_);
-
-    try
-    {
-        if (streamOCCI_.isNull())
-            objOCCI_->setNull();
-        else
-            objOCCI_->readSQL(streamOCCI_);
-    }
-    catch (oracle::occi::SQLException& excep)
-    {
-        delete objOCCI_;
-        excep.setErrorCtx(ctxOCCI_);
-        return (void *)nullptr;
-    }
-    return (void *)objOCCI_;
-}
-
-void SDOPointType::readSQL(oracle::occi::AnyData& streamOCCI_)
-{
-    X = streamOCCI_.getNumber();
-    Y = streamOCCI_.getNumber();
-    Z = streamOCCI_.getNumber();
-}
-
-void SDOPointType::writeSQL(void *objectOCCI_, void *ctxOCCI_)
-{
-    SDOPointType *objOCCI_ = (SDOPointType *) objectOCCI_;
-    oracle::occi::AnyData streamOCCI_(ctxOCCI_);
-
-    try
-    {
-        if (objOCCI_->isNull())
-            streamOCCI_.setNull();
-        else
-            objOCCI_->writeSQL(streamOCCI_);
-    }
-    catch (oracle::occi::SQLException& excep)
-    {
-        excep.setErrorCtx(ctxOCCI_);
-    }
-    return;
-}
-
-void SDOPointType::writeSQL(oracle::occi::AnyData& streamOCCI_)
-{
-    streamOCCI_.setNumber(X);
-    streamOCCI_.setNumber(Y);
-    streamOCCI_.setNumber(Z);
-}
-
-SDOPointType::~SDOPointType()
-{
-}
-
-/*****************************************************************/
-//  generated method implementations for the SDO_GEOMETRY object type.
-/*****************************************************************/
-
-oracle::occi::Number SDOGeometry::getSdo_gtype() const
-{
-    return SDO_GTYPE;
-}
-
-void SDOGeometry::setSdo_gtype(const oracle::occi::Number &value)
-{
-    SDO_GTYPE = value;
-}
-
-oracle::occi::Number SDOGeometry::getSdo_srid() const
-{
-    return SDO_SRID;
-}
-
-void SDOGeometry::setSdo_srid(const oracle::occi::Number &value)
-{
-    SDO_SRID = value;
-}
-
-SDOPointType * SDOGeometry::getSdo_point() const
-{
-    return SDO_POINT;
-}
-
-void SDOGeometry::setSdo_point(SDOPointType * value)
-{
-    SDO_POINT = value;
-}
-
-OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_elem_info()
-{
-    return SDO_ELEM_INFO;
-}
-
-const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_elem_info() const
-{
-    return SDO_ELEM_INFO;
-}
-
-void SDOGeometry::setSdo_elem_info(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value)
-{
-    SDO_ELEM_INFO = value;
-}
-
-OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_ordinates()
-{
-    return SDO_ORDINATES;
-}
-
-const OCCI_STD_NAMESPACE::vector< oracle::occi::Number >& SDOGeometry::getSdo_ordinates() const
-{
-    return SDO_ORDINATES;
-}
-
-void SDOGeometry::setSdo_ordinates(const OCCI_STD_NAMESPACE::vector< oracle::occi::Number > &value)
-{
-    SDO_ORDINATES = value;
-}
-
-void *SDOGeometry::operator new(size_t size)
-{
-    return oracle::occi::PObject::operator new(size);
-}
-
-void *SDOGeometry::operator new(size_t size, const oracle::occi::Connection * sess,
-                                const OCCI_STD_NAMESPACE::string& table)
-{
-    return oracle::occi::PObject::operator new(size, sess, table,
-                                               (char *) "MDSYS.SDO_GEOMETRY");
-}
-
-void *SDOGeometry::operator new(size_t size, void *ctxOCCI_)
-{
-    return oracle::occi::PObject::operator new(size, ctxOCCI_);
-}
-
-void *SDOGeometry::operator new(size_t size,
-                                const oracle::occi::Connection *sess,
-                                const OCCI_STD_NAMESPACE::string &tableName,
-                                const OCCI_STD_NAMESPACE::string &typeName,
-                                const OCCI_STD_NAMESPACE::string &tableSchema,
-                                const OCCI_STD_NAMESPACE::string &typeSchema)
-{
-    return oracle::occi::PObject::operator new(size, sess, tableName,
-                                               typeName, tableSchema, typeSchema);
-}
-
-OCCI_STD_NAMESPACE::string SDOGeometry::getSQLTypeName() const
-{
-    return OCCI_STD_NAMESPACE::string("MDSYS.SDO_GEOMETRY");
-}
-
-void SDOGeometry::getSQLTypeName(oracle::occi::Environment *env, void **schemaName,
-                                 unsigned int &schemaNameLen, void **typeName, unsigned int &typeNameLen) const
-{
-    PObject::getSQLTypeName(env, &SDOGeometry::readSQL, schemaName,
-                            schemaNameLen, typeName, typeNameLen);
-}
-
-SDOGeometry::SDOGeometry()
-{
-    SDO_POINT = (SDOPointType *) 0;
-}
-
-void *SDOGeometry::readSQL(void *ctxOCCI_)
-{
-    SDOGeometry *objOCCI_ = new(ctxOCCI_) SDOGeometry(ctxOCCI_);
-    oracle::occi::AnyData streamOCCI_(ctxOCCI_);
-
-    try
-    {
-        if (streamOCCI_.isNull())
-            objOCCI_->setNull();
-        else
-            objOCCI_->readSQL(streamOCCI_);
-    }
-    catch (oracle::occi::SQLException& excep)
-    {
-        delete objOCCI_;
-        excep.setErrorCtx(ctxOCCI_);
-        return (void *)nullptr;
-    }
-    return (void *)objOCCI_;
-}
-
-void SDOGeometry::readSQL(oracle::occi::AnyData& streamOCCI_)
-{
-    SDO_GTYPE = streamOCCI_.getNumber();
-    SDO_SRID = streamOCCI_.getNumber();
-    SDO_POINT = (SDOPointType *) streamOCCI_.getObject(&SDOPointType::readSQL);
-    oracle::occi::getVector(streamOCCI_, SDO_ELEM_INFO);
-    oracle::occi::getVector(streamOCCI_, SDO_ORDINATES);
-}
-
-void SDOGeometry::writeSQL(void *objectOCCI_, void *ctxOCCI_)
-{
-    SDOGeometry *objOCCI_ = (SDOGeometry *) objectOCCI_;
-    oracle::occi::AnyData streamOCCI_(ctxOCCI_);
-
-    try
-    {
-        if (objOCCI_->isNull())
-            streamOCCI_.setNull();
-        else
-            objOCCI_->writeSQL(streamOCCI_);
-    }
-    catch (oracle::occi::SQLException& excep)
-    {
-        excep.setErrorCtx(ctxOCCI_);
-    }
-    return;
-}
-
-void SDOGeometry::writeSQL(oracle::occi::AnyData& streamOCCI_)
-{
-    streamOCCI_.setNumber(SDO_GTYPE);
-    streamOCCI_.setNumber(SDO_SRID);
-    streamOCCI_.setObject(SDO_POINT);
-    oracle::occi::setVector(streamOCCI_, SDO_ELEM_INFO);
-    oracle::occi::setVector(streamOCCI_, SDO_ORDINATES);
-}
-
-SDOGeometry::~SDOGeometry()
-{
-    delete SDO_POINT;
-}
diff --git a/plugins/input/occi/spatial_types.typ b/plugins/input/occi/spatial_types.typ
deleted file mode 100644
index 5c9c0a7..0000000
--- a/plugins/input/occi/spatial_types.typ
+++ /dev/null
@@ -1,4 +0,0 @@
-TYPE MDSYS.SDO_POINT_TYPE AS SDOPointType
-TYPE MDSYS.SDO_GEOMETRY AS SDOGeometry
-
-
diff --git a/plugins/input/osm/basiccurl.cpp b/plugins/input/osm/basiccurl.cpp
deleted file mode 100755
index fd83614..0000000
--- a/plugins/input/osm/basiccurl.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#include "basiccurl.h"
-
-#include <iostream>
-#include <cstring>
-
-CURL_LOAD_DATA* grab_http_response(const char* url)
-{
-    CURL_LOAD_DATA* data;
-
-    CURL* curl = curl_easy_init();
-
-    if(curl)
-    {
-        data = do_grab(curl, url);
-        curl_easy_cleanup(curl);
-        return data;
-    }
-    return nullptr;
-}
-
-CURL_LOAD_DATA* do_grab(CURL* curl,const char* url)
-{
-    CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)malloc(sizeof(CURL_LOAD_DATA));
-    data->data = nullptr;
-    data->nbytes = 0;
-
-    curl_easy_setopt(curl, CURLOPT_URL, url);
-    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
-    curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
-
-    CURLcode res = curl_easy_perform(curl);
-    if (res !=0) {
-        std::clog << "error grabbing data\n";
-    }
-
-    return data;
-}
-
-size_t response_callback(void* ptr, size_t size, size_t nmemb, void* d)
-{
-    size_t rsize = size * nmemb;
-    CURL_LOAD_DATA* data = (CURL_LOAD_DATA*)d;
-
-    // fprintf(stderr,"rsize is %d\n", rsize);
-
-    data->data = (char*)realloc(data->data, (data->nbytes + rsize) * sizeof(char));
-    std::memcpy(&(data->data[data->nbytes]), ptr, rsize);
-    data->nbytes += rsize;
-
-    // fprintf(stderr,"data->nbytes is %d\n", data->nbytes);
-
-    return rsize;
-}
diff --git a/plugins/input/osm/basiccurl.h b/plugins/input/osm/basiccurl.h
deleted file mode 100755
index 7ab5297..0000000
--- a/plugins/input/osm/basiccurl.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2011 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef BASICCURL_H
-#define BASICCURL_H
-
-#include <curl/curl.h>
-#include <cstdlib>
-#include <cstring>
-
-typedef struct
-{
-  char *data;
-  int nbytes;
-} CURL_LOAD_DATA;
-
-CURL_LOAD_DATA *grab_http_response(const char *url);
-CURL_LOAD_DATA *do_grab(CURL *curl, const char *url);
-size_t response_callback(void *ptr ,size_t size, size_t nmemb, void *data);
-
-#endif // BASICCURL_H
diff --git a/plugins/input/osm/build.py b/plugins/input/osm/build.py
deleted file mode 100644
index 061fc85..0000000
--- a/plugins/input/osm/build.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# This file is part of Mapnik (c++ mapping toolkit)
-#
-# Copyright (C) 2015 Artem Pavlenko
-#
-# Mapnik is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#
-
-Import ('plugin_base')
-Import ('env')
-from copy import copy
-
-PLUGIN_NAME = 'osm'
-
-plugin_env = plugin_base.Clone()
-
-plugin_sources = Split(
-  """
-  %(PLUGIN_NAME)s.cpp
-  %(PLUGIN_NAME)s_datasource.cpp
-  %(PLUGIN_NAME)s_featureset.cpp
-  osmparser.cpp
-  dataset_deliverer.cpp
-  """ % locals()
-)
-
-plugin_env['LIBS'] = []
-plugin_env.Append(LIBS='xml2')
-
-# Link Library to Dependencies
-libraries = copy(plugin_env['LIBS'])
-libraries.append(env['ICU_LIB_NAME'])
-libraries.append('boost_system%s' % env['BOOST_APPEND'])
-
-if env['PLUGIN_LINKING'] == 'shared':
-    libraries.append(env['MAPNIK_NAME'])
-
-    TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
-                                      SHLIBPREFIX='',
-                                      SHLIBSUFFIX='.input',
-                                      source=plugin_sources,
-                                      LIBS=libraries)
-
-    # if the plugin links to libmapnik ensure it is built first
-    Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
-
-    if 'uninstall' not in COMMAND_LINE_TARGETS:
-        env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
-        env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
-
-plugin_obj = {
-  'LIBS': libraries,
-  'SOURCES': plugin_sources,
-}
-
-Return('plugin_obj')
diff --git a/plugins/input/osm/dataset_deliverer.cpp b/plugins/input/osm/dataset_deliverer.cpp
deleted file mode 100644
index 6d7fe31..0000000
--- a/plugins/input/osm/dataset_deliverer.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-// mapnik
-#include <mapnik/debug.hpp>
-#include <mapnik/datasource.hpp>
-#include <mapnik/util/fs.hpp>
-
-// std
-#include <sstream>
-
-#include "dataset_deliverer.h"
-
-osm_dataset * dataset_deliverer::dataset = nullptr;
-std::string dataset_deliverer::last_bbox = "";
-std::string dataset_deliverer::last_filename = "";
-
-osm_dataset* dataset_deliverer::load_from_file(const string& file, const string& parser)
-{
-    // Only actually load from file if we haven't done so already
-    if (dataset == nullptr)
-    {
-        if (!mapnik::util::exists(file))
-        {
-            throw mapnik::datasource_exception("OSM Plugin: '" + file + "' does not exist");
-        }
-
-        dataset = new osm_dataset;
-        if (dataset->load(file.c_str(), parser) == false)
-        {
-            return nullptr;
-        }
-
-        atexit(dataset_deliverer::release);
-        last_filename = file;
-    }
-    else if(file != last_filename)
-    {
-        dataset = new osm_dataset;
-        if (dataset->load(file.c_str(), parser) == false)
-        {
-            return nullptr;
-        }
-        last_filename = file;
-    }
-    return dataset;
-}
diff --git a/plugins/input/osm/dataset_deliverer.h b/plugins/input/osm/dataset_deliverer.h
deleted file mode 100644
index dde269b..0000000
--- a/plugins/input/osm/dataset_deliverer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2011 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef DATASET_DELIVERER_H
-#define DATASET_DELIVERER_H
-
-#include "osm.h"
-#include <string>
-
-using  namespace std;
-
-class dataset_deliverer 
-{
-private:
-    static osm_dataset* dataset; 
-    static std::string last_bbox;
-    static std::string last_filename;
-
-public:
-    static osm_dataset *load_from_file(const string&, const string&);
-
-    static void release()
-    {
-        delete dataset;
-    }
-};
-
-#endif // DATASET_DELIVERER_H
diff --git a/plugins/input/osm/osm.cpp b/plugins/input/osm/osm.cpp
deleted file mode 100644
index 76d3bac..0000000
--- a/plugins/input/osm/osm.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#include "osm.h"
-#include "osmparser.h"
-
-#include <mapnik/debug.hpp>
-
-#include <libxml/parser.h>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <string>
-#include <cstring>
-
-polygon_types osm_way::ptypes;
-
-bool osm_dataset::load(const char* filename,std::string const& parser)
-{
-    if (parser == "libxml2")
-    {
-        return osmparser::parse(this, filename);
-    }
-    return false;
-}
-
-osm_dataset::~osm_dataset()
-{
-    clear();
-}
-
-void osm_dataset::clear()
-{
-    MAPNIK_LOG_DEBUG(osm) << "osm_dataset: Clear";
-
-    MAPNIK_LOG_DEBUG(osm) << "osm_dataset: -- Deleting ways";
-    for (unsigned int count = 0; count < ways.size(); ++count)
-    {
-        delete ways[count];
-        ways[count] = nullptr;
-    }
-    ways.clear();
-
-    MAPNIK_LOG_DEBUG(osm) << "osm_dataset: -- Deleting nodes";
-    for (unsigned int count = 0; count < nodes.size(); ++count)
-    {
-        delete nodes[count];
-        nodes[count] = nullptr;
-    }
-    nodes.clear();
-
-    MAPNIK_LOG_DEBUG(osm) << "osm_dataset: Clear done";
-}
-
-std::string osm_dataset::to_string()
-{
-    std::string result;
-
-    for (unsigned int count = 0; count < nodes.size(); ++count)
-    {
-        result += nodes[count]->to_string();
-    }
-
-    for (unsigned int count = 0; count < ways.size(); ++count)
-    {
-        result += ways[count]->to_string();
-    }
-
-    return result;
-}
-
-bounds osm_dataset::get_bounds()
-{
-    bounds b (-180, -90, 180, 90);
-    for (unsigned int count = 0; count < nodes.size(); ++count)
-    {
-        if(nodes[count]->lon > b.w) b.w = nodes[count]->lon;
-        if(nodes[count]->lon < b.e) b.e = nodes[count]->lon;
-        if(nodes[count]->lat > b.s) b.s = nodes[count]->lat;
-        if(nodes[count]->lat < b.n) b.n = nodes[count]->lat;
-    }
-    return b;
-}
-
-osm_node* osm_dataset::next_node()
-{
-    if (node_i != nodes.end())
-    {
-        return *(node_i++);
-    }
-    return nullptr;
-}
-
-osm_way* osm_dataset::next_way()
-{
-    if (way_i != ways.end())
-    {
-        return *(way_i++);
-    }
-    return nullptr;
-}
-
-osm_item* osm_dataset::next_item()
-{
-    osm_item* item = nullptr;
-    if (next_item_mode == Node)
-    {
-        item = next_node();
-        if (item == nullptr)
-        {
-            next_item_mode = Way;
-            rewind_ways();
-            item = next_way();
-        }
-    }
-    else
-    {
-        item = next_way();
-    }
-    return item;
-}
-
-std::set<std::string> osm_dataset::get_keys()
-{
-    std::set<std::string> keys;
-    for (unsigned int count = 0; count < nodes.size(); ++count)
-    {
-        for (std::map<std::string, std::string>::iterator i = nodes[count]->keyvals.begin();
-             i != nodes[count]->keyvals.end(); i++)
-        {
-            keys.insert(i->first);
-        }
-    }
-
-    for (unsigned int count = 0; count < ways.size(); ++count)
-    {
-        for (std::map<std::string, std::string>::iterator i = ways[count]->keyvals.begin();
-             i != ways[count]->keyvals.end(); i++)
-        {
-            keys.insert(i->first);
-        }
-    }
-    return keys;
-}
-
-
-std::string osm_item::to_string()
-{
-    std::ostringstream strm;
-    strm << "id=" << id << std::endl << "Keyvals: " << std::endl;
-
-    for (std::map<std::string, std::string>::iterator i = keyvals.begin();
-         i != keyvals.end(); i++)
-    {
-        strm << "Key " << i->first << " Value " << i->second << std::endl;
-    }
-
-    return strm.str();
-}
-
-std::string osm_node::to_string()
-{
-    std::ostringstream strm;
-    strm << "Node: " << osm_item::to_string() << " lat=" << lat <<" lon="  <<lon << std::endl;
-    return strm.str();
-}
-
-std::string osm_way::to_string()
-{
-    std::ostringstream strm;
-    strm << "Way: " << osm_item::to_string() << "Nodes in way:";
-
-    for (unsigned int count = 0; count < nodes.size(); ++count)
-    {
-        if (nodes[count] != nullptr)
-        {
-            strm << nodes[count]->id << " ";
-        }
-    }
-
-    strm << std::endl;
-    return strm.str();
-}
-
-bounds osm_way::get_bounds()
-{
-    bounds b (-180, -90, 180, 90);
-
-    for (unsigned int count = 0; count < nodes.size(); ++count)
-    {
-        if(nodes[count]->lon > b.w) b.w = nodes[count]->lon;
-        if(nodes[count]->lon < b.e) b.e = nodes[count]->lon;
-        if(nodes[count]->lat > b.s) b.s = nodes[count]->lat;
-        if(nodes[count]->lat < b.n) b.n = nodes[count]->lat;
-    }
-    return b;
-}
-
-bool osm_way::is_polygon()
-{
-    for (unsigned int count = 0; count < ptypes.ptypes.size(); ++count)
-    {
-        if (keyvals.find(ptypes.ptypes[count].first) != keyvals.end() &&
-            (ptypes.ptypes[count].second.empty() || keyvals[ptypes.ptypes[count].first] == ptypes.ptypes[count].second))
-        {
-            return true;
-        }
-    }
-
-    return false;
-}
diff --git a/plugins/input/osm/osm.h b/plugins/input/osm/osm.h
deleted file mode 100644
index 86a48a9..0000000
--- a/plugins/input/osm/osm.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2011 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef OSM_H
-#define OSM_H
-
-#include <mapnik/value_types.hpp>
-#include <vector>
-#include <string>
-#include <map>
-#include <set>
-#include <utility>
-
-struct bounds
-{
-    double w, s, e, n;
-    bounds() { w = -180; s = -90; e = 180; n = 90; }
-    bounds(double w_, double s_, double e_, double n_)
-    { 
-        this->w = w_;
-        this->s = s_;
-        this->e = e_;
-        this->n = n_;
-    }
-};
-
-class polygon_types
-{
-public:
-    std::vector<std::pair<std::string, std::string> > ptypes;
-
-    polygon_types()
-    {
-        ptypes.push_back(std::pair<std::string, std::string>("water", ""));
-        ptypes.push_back(std::pair<std::string, std::string>("aeroway", ""));
-        ptypes.push_back(std::pair<std::string, std::string>("building", ""));
-        ptypes.push_back(std::pair<std::string, std::string>("natural", "wood"));
-        ptypes.push_back(std::pair<std::string, std::string>("natural", "water"));
-        ptypes.push_back(std::pair<std::string, std::string>("natural", "heath"));
-        ptypes.push_back(std::pair<std::string, std::string>("natural", "marsh"));
-        ptypes.push_back(std::pair<std::string, std::string>("military", "danger_area"));
-        ptypes.push_back(std::pair<std::string, std::string>("landuse", "forest"));
-        ptypes.push_back(std::pair<std::string, std::string>("landuse", "industrial"));
-        ptypes.push_back(std::pair<std::string, std::string>("leisure", "park"));
-        ptypes.push_back(std::pair<std::string, std::string>("area", "yes"));
-    }
-};
-
-struct osm_item
-{
-    mapnik::value_integer id;
-    std::map<std::string, std::string> keyvals;
-    virtual std::string to_string();
-    virtual ~osm_item() {}
-};
-
-struct osm_node : public osm_item
-{
-    double lat, lon;
-    std::string to_string();
-};
-
-struct osm_way : public osm_item
-{
-    std::vector<osm_node*> nodes; 
-    std::string to_string();
-    bounds get_bounds();
-    bool is_polygon();
-    static polygon_types ptypes;
-};
-
-class osm_dataset
-{
-public:
-    osm_dataset()
-    {
-        node_i = nodes.begin();
-        way_i = ways.begin();
-        next_item_mode = Node;
-    }
-
-    osm_dataset(const char* name)
-    {
-        node_i = nodes.begin();
-        way_i = ways.begin();
-        next_item_mode = Node;
-        load(name);
-    }
-
-    ~osm_dataset();
-
-    bool load(const char* name, std::string const& parser = "libxml2");
-    void clear();
-    void add_node(osm_node* n) { nodes.push_back(n); }
-    void add_way(osm_way* w) { ways.push_back(w); }
-    std::string to_string();
-    bounds get_bounds();
-    std::set<std::string> get_keys();
-    void rewind_nodes() { node_i = nodes.begin(); }
-    void rewind_ways() { way_i = ways.begin(); }
-    void rewind() { rewind_nodes(); rewind_ways(); next_item_mode = Node; }
-    osm_node * next_node();
-    osm_way * next_way();
-    osm_item * next_item();
-    bool current_item_is_node() { return next_item_mode == Node; }
-    bool current_item_is_way() { return next_item_mode == Way; }
-
-private:
-    int next_item_mode;
-    enum { Node, Way };
-    std::vector<osm_node*>::iterator node_i;
-    std::vector<osm_way*>::iterator way_i;
-    std::vector<osm_node*> nodes;
-    std::vector<osm_way*> ways;
-};
-
-#endif // OSM_H
diff --git a/plugins/input/osm/osm_datasource.cpp b/plugins/input/osm/osm_datasource.cpp
deleted file mode 100644
index 4bbe1bf..0000000
--- a/plugins/input/osm/osm_datasource.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-// stl
-#include <stdexcept>
-#include <set>
-
-// mapnik
-#include <mapnik/debug.hpp>
-#include <mapnik/geom_util.hpp>
-#include <mapnik/query.hpp>
-#include <mapnik/boolean.hpp>
-
-// boost
-
-#include "osm_datasource.hpp"
-#include "osm_featureset.hpp"
-#include "dataset_deliverer.h"
-#include "osmtagtypes.h"
-#include "osmparser.h"
-
-using mapnik::String;
-using mapnik::Double;
-using mapnik::Integer;
-using mapnik::datasource_exception;
-using mapnik::filter_in_box;
-using mapnik::filter_at_point;
-using mapnik::attribute_descriptor;
-
-DATASOURCE_PLUGIN(osm_datasource)
-
-osm_datasource::osm_datasource(const parameters& params)
-    : datasource (params),
-      extent_(),
-      type_(datasource::Vector),
-      desc_(osm_datasource::name(), *params.get<std::string>("encoding", "utf-8"))
-{
-    osm_data_ = nullptr;
-    std::string osm_filename = *params.get<std::string>("file", "");
-    std::string parser = *params.get<std::string>("parser", "libxml2");
-    std::string url = *params.get<std::string>("url", "");
-    std::string bbox = *params.get<std::string>("bbox", "");
-
-    // load the data
-    if (url != "" && bbox != "")
-    {
-        throw datasource_exception("Error loading from URL is no longer supported (removed in >= Mapnik 2.3.x");
-    }
-    else if (osm_filename != "")
-    {
-        // if we supplied a filename, load from file
-        if ((osm_data_ = dataset_deliverer::load_from_file(osm_filename, parser)) == nullptr)
-        {
-            std::string s("OSM Plugin: Error loading from file '");
-            s += osm_filename + "'";
-            throw datasource_exception(s);
-        }
-    }
-    else
-    {
-        throw datasource_exception("OSM Plugin: Neither 'file' nor 'url' and 'bbox' specified");
-    }
-
-
-    osm_tag_types tagtypes;
-    tagtypes.add_type("maxspeed", mapnik::Integer);
-    tagtypes.add_type("z_order", mapnik::Integer);
-
-    osm_data_->rewind();
-
-    // Need code to get the attributes of all the data
-    std::set<std::string> keys = osm_data_->get_keys();
-
-    // Add the attributes to the datasource descriptor - assume they are
-    // all of type String
-    for (auto const& key : keys)
-    {
-        desc_.add_descriptor(attribute_descriptor(key, tagtypes.get_type(key)));
-    }
-    // Get the bounds of the data and set extent_ accordingly
-    bounds b = osm_data_->get_bounds();
-    extent_ = box2d<double>(b.w,b.s,b.e,b.n);
-}
-
-osm_datasource::~osm_datasource()
-{
-    // Do not do as is now static variable and cleaned up at exit
-    //delete osm_data_;
-}
-
-const char * osm_datasource::name()
-{
-    return "osm";
-}
-
-mapnik::datasource::datasource_t osm_datasource::type() const
-{
-    return type_;
-}
-
-layer_descriptor osm_datasource::get_descriptor() const
-{
-    return desc_;
-}
-
-featureset_ptr osm_datasource::features(const query& q) const
-{
-    filter_in_box filter(q.get_bbox());
-    // so we need to filter osm features by bbox here...
-
-    return std::make_shared<osm_featureset<filter_in_box> >(filter,
-                                                              osm_data_,
-                                                              q.property_names(),
-                                                              desc_.get_encoding());
-}
-
-featureset_ptr osm_datasource::features_at_point(coord2d const& pt, double tol) const
-{
-    filter_at_point filter(pt);
-    // collect all attribute names
-    std::set<std::string> names;
-    for (auto const& elem : desc_.get_descriptors())
-    {
-        names.insert(elem.get_name());
-    }
-    return std::make_shared<osm_featureset<filter_at_point> >(filter,
-                                                              osm_data_,
-                                                              names,
-                                                              desc_.get_encoding());
-}
-
-box2d<double> osm_datasource::envelope() const
-{
-    return extent_;
-}
-
-boost::optional<mapnik::datasource_geometry_t> osm_datasource::get_geometry_type() const
-{
-    return boost::optional<mapnik::datasource_geometry_t>(mapnik::datasource_geometry_t::Collection);
-}
diff --git a/plugins/input/osm/osm_datasource.hpp b/plugins/input/osm/osm_datasource.hpp
deleted file mode 100644
index 1bd8bb3..0000000
--- a/plugins/input/osm/osm_datasource.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef OSM_DATASOURCE_HPP
-#define OSM_DATASOURCE_HPP
-
-// mapnik
-#include <mapnik/datasource.hpp>
-#include <mapnik/params.hpp>
-#include <mapnik/query.hpp>
-#include <mapnik/feature.hpp>
-#include <mapnik/box2d.hpp>
-#include <mapnik/coord.hpp>
-#include <mapnik/feature_layer_desc.hpp>
-
-// boost
-#include <boost/optional.hpp>
-#include <memory>
-
-// stl
-#include <vector>
-#include <string>
-
-#include "osm.h"
-
-using mapnik::datasource;
-using mapnik::parameters;
-using mapnik::query;
-using mapnik::featureset_ptr;
-using mapnik::layer_descriptor;
-using mapnik::coord2d;
-using mapnik::box2d;
-
-class osm_datasource : public datasource
-{
-public:
-    osm_datasource(const parameters& params);
-    virtual ~osm_datasource();
-    mapnik::datasource::datasource_t type() const;
-    static const char * name();
-    featureset_ptr features(const query& q) const;
-    featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const;
-    box2d<double> envelope() const;
-    boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
-    layer_descriptor get_descriptor() const;
-
-private:
-    box2d<double> extent_;
-    osm_dataset* osm_data_;
-    mapnik::datasource::datasource_t type_;
-    layer_descriptor desc_;
-};
-
-#endif // OSM_DATASOURCE_HPP
diff --git a/plugins/input/osm/osm_featureset.cpp b/plugins/input/osm/osm_featureset.cpp
deleted file mode 100644
index 46e7966..0000000
--- a/plugins/input/osm/osm_featureset.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-// mapnik
-#include <mapnik/make_unique.hpp>
-#include <mapnik/geometry.hpp>
-#include <mapnik/feature.hpp>
-#include <mapnik/feature_factory.hpp>
-#include <mapnik/debug.hpp>
-#include <mapnik/unicode.hpp>
-#include <mapnik/geometry_correct.hpp>
-
-#include "osm_featureset.hpp"
-
-using mapnik::feature_ptr;
-using mapnik::feature_factory;
-
-template <typename filterT>
-osm_featureset<filterT>::osm_featureset(const filterT& filter,
-                                        osm_dataset* dataset,
-                                        const std::set<std::string>&
-                                        attribute_names,
-                                        std::string const& encoding)
-    : filter_(filter),
-      query_ext_(),
-      tr_(new transcoder(encoding)),
-      dataset_ (dataset),
-      attribute_names_ (attribute_names),
-      ctx_(std::make_shared<mapnik::context_type>())
-{
-    dataset_->rewind();
-}
-
-template <typename filterT>
-feature_ptr osm_featureset<filterT>::next()
-{
-    feature_ptr feature;
-
-    osm_item* cur_item = dataset_->next_item();
-    if (!cur_item) return feature_ptr();
-    if (dataset_->current_item_is_node())
-    {
-        feature = feature_factory::create(ctx_, cur_item->id);
-        double lat = static_cast<osm_node*>(cur_item)->lat;
-        double lon = static_cast<osm_node*>(cur_item)->lon;
-        feature->set_geometry(mapnik::geometry::point<double>(lon,lat));
-    }
-    else if (dataset_->current_item_is_way())
-    {
-        // Loop until we find a feature which passes the filter
-        while (cur_item)
-        {
-            bounds b = static_cast<osm_way*>(cur_item)->get_bounds();
-            if (filter_.pass(box2d<double>(b.w, b.s, b.e, b.n))
-                    &&
-                static_cast<osm_way*>(cur_item)->nodes.size()) break;
-            cur_item = dataset_->next_item();
-        }
-
-        if (!cur_item) return feature_ptr();
-        feature = feature_factory::create(ctx_, cur_item->id);
-        if (static_cast<osm_way*>(cur_item)->is_polygon())
-        {
-            mapnik::geometry::linear_ring<double> ring;
-            for (unsigned int count = 0;
-                 count < static_cast<osm_way*>(cur_item)->nodes.size();
-                 count++)
-            {
-                ring.add_coord(static_cast<osm_way*>(cur_item)->nodes[count]->lon,
-                                static_cast<osm_way*>(cur_item)->nodes[count]->lat);
-            }
-            mapnik::geometry::polygon<double> geom;
-            geom.set_exterior_ring(std::move(ring));
-            mapnik::geometry::correct(geom);
-            feature->set_geometry(std::move(geom));
-        }
-        else
-        {
-            mapnik::geometry::line_string<double> geom;
-            for (unsigned int count = 0;
-                 count < static_cast<osm_way*>(cur_item)->nodes.size();
-                 count++)
-            {
-                geom.add_coord(static_cast<osm_way*>(cur_item)->nodes[count]->lon,
-                                static_cast<osm_way*>(cur_item)->nodes[count]->lat);
-            }
-            feature->set_geometry(std::move(geom));
-        }
-    }
-    else
-    {
-        MAPNIK_LOG_ERROR(osm_featureset) << "Current item is neither node nor way.\n";
-    }
-
-    std::set<std::string>::const_iterator itr = attribute_names_.begin();
-    std::set<std::string>::const_iterator end = attribute_names_.end();
-    std::map<std::string,std::string>::iterator end_keyvals = cur_item->keyvals.end();
-    for (; itr != end; itr++)
-    {
-        std::map<std::string,std::string>::iterator i = cur_item->keyvals.find(*itr);
-        if (i != end_keyvals)
-        {
-            feature->put_new(i->first, tr_->transcode(i->second.c_str()));
-        }
-    }
-    return feature;
-}
-
-template <typename filterT>
-osm_featureset<filterT>::~osm_featureset() {}
-
-template class osm_featureset<mapnik::filter_in_box>;
-template class osm_featureset<mapnik::filter_at_point>;
diff --git a/plugins/input/osm/osm_featureset.hpp b/plugins/input/osm/osm_featureset.hpp
deleted file mode 100644
index 7eed2e6..0000000
--- a/plugins/input/osm/osm_featureset.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef OSM_FS_HH
-#define OSM_FS_HH
-
-// stl
-#include <set>
-
-// boost
-
-
-// mapnik
-#include <mapnik/geom_util.hpp>
-#include <mapnik/feature.hpp>
-#include <mapnik/query.hpp>
-#include <mapnik/unicode.hpp>
-#include <mapnik/datasource.hpp>
-
-#include "osm.h"
-
-using mapnik::Featureset;
-using mapnik::box2d;
-using mapnik::feature_ptr;
-using mapnik::transcoder;
-
-template <typename filterT>
-class osm_featureset : public Featureset
-{
-public:
-    osm_featureset(const filterT& filter,
-                   osm_dataset* dataset,
-                   const std::set<std::string>& attribute_names,
-                   std::string const& encoding);
-    virtual ~osm_featureset();
-    feature_ptr next();
-
-private:
-    filterT filter_;
-    box2d<double> query_ext_;
-    const std::unique_ptr<transcoder> tr_;
-    std::vector<int> attr_ids_;
-    mutable box2d<double> feature_ext_;
-    mutable int total_geom_size;
-    osm_dataset *dataset_;
-    std::set<std::string> attribute_names_;
-    mapnik::context_ptr ctx_;
-
-    osm_featureset(const osm_featureset&);
-    const osm_featureset& operator=(const osm_featureset&);
-};
-
-#endif // OSM_FS_HH
diff --git a/plugins/input/osm/osmparser.cpp b/plugins/input/osm/osmparser.cpp
deleted file mode 100644
index b6c3d9b..0000000
--- a/plugins/input/osm/osmparser.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-// much of this is based on osm2pgsql
-
-#include "osmparser.h"
-#include "osm.h"
-#include <string>
-#include <cassert>
-#include <mapnik/util/conversions.hpp>
-
-osm_item* osmparser::cur_item=nullptr;
-mapnik::value_integer osmparser::curID=0;
-bool osmparser::in_node=false, osmparser::in_way=false;
-osm_dataset* osmparser::components=nullptr;
-std::string osmparser::error="";
-std::map<mapnik::value_integer,osm_node*> osmparser::tmp_node_store=std::map<mapnik::value_integer,osm_node*>();
-
-void osmparser::processNode(xmlTextReaderPtr reader)
-{
-    xmlChar *name = xmlTextReaderName(reader);
-    if(name==nullptr)
-        name=xmlStrdup(BAD_CAST "--");
-
-    switch(xmlTextReaderNodeType(reader))
-    {
-    case XML_READER_TYPE_ELEMENT:
-        startElement(reader,name);
-        break;
-
-    case XML_READER_TYPE_END_ELEMENT:
-        endElement(name);
-    }
-    xmlFree(name);
-}
-
-void osmparser::startElement(xmlTextReaderPtr reader, const xmlChar *name)
-{
-    std::string tags;
-    xmlChar *xid, *xlat, *xlon, *xk, *xv;
-
-    if(xmlStrEqual(name,BAD_CAST "node"))
-    {
-        curID = 0;
-        in_node = true;
-        osm_node *node=new osm_node;
-        xlat=xmlTextReaderGetAttribute(reader,BAD_CAST "lat");
-        xlon=xmlTextReaderGetAttribute(reader,BAD_CAST "lon");
-        xid=xmlTextReaderGetAttribute(reader,BAD_CAST "id");
-        assert(xlat);
-        assert(xlon);
-        assert(xid);
-        node->lat=atof((char*)xlat);
-        node->lon=atof((char*)xlon);
-        mapnik::util::string2int((char *)xid, node->id);
-        cur_item = node;
-        tmp_node_store[node->id] = node;
-        xmlFree(xid);
-        xmlFree(xlon);
-        xmlFree(xlat);
-    }
-    else if (xmlStrEqual(name,BAD_CAST "way"))
-    {
-        curID=0;
-        in_way = true;
-        osm_way *way=new osm_way;
-        xid=xmlTextReaderGetAttribute(reader,BAD_CAST "id");
-        assert(xid);
-        mapnik::util::string2int((char *)xid, way->id);
-        cur_item  =  way;
-        xmlFree(xid);
-    }
-    else if (xmlStrEqual(name,BAD_CAST "nd"))
-    {
-        xid=xmlTextReaderGetAttribute(reader,BAD_CAST "ref");
-        assert(xid);
-        mapnik::value_integer ndid;
-        mapnik::util::string2int((char *)xid, ndid);
-        if(tmp_node_store.find(ndid)!=tmp_node_store.end())
-        {
-            (static_cast<osm_way*>(cur_item))->nodes.push_back
-                (tmp_node_store[ndid]);
-        }
-        xmlFree(xid);
-    }
-    else if (xmlStrEqual(name,BAD_CAST "tag"))
-    {
-        std::string key="", value="";
-        xk = xmlTextReaderGetAttribute(reader,BAD_CAST "k");
-        xv = xmlTextReaderGetAttribute(reader,BAD_CAST "v");
-        assert(xk);
-        assert(xv);
-        cur_item->keyvals[(char*)xk] = (char*)xv;
-        xmlFree(xk);
-        xmlFree(xv);
-    }
-    if (xmlTextReaderIsEmptyElement(reader))
-    {
-        // Fake endElement for empty nodes
-        endElement(name);
-    }
-}
-
-void osmparser::endElement(const xmlChar* name)
-{
-    if(xmlStrEqual(name,BAD_CAST "node"))
-    {
-        in_node = false;
-        components->add_node(static_cast<osm_node*>(cur_item));
-    }
-    else if(xmlStrEqual(name,BAD_CAST "way"))
-    {
-        in_way = false;
-        components->add_way(static_cast<osm_way*>(cur_item));
-    }
-}
-
-bool osmparser::parse(osm_dataset *ds, const char* filename)
-{
-    components=ds;
-    xmlTextReaderPtr reader = xmlNewTextReaderFilename(filename);
-    int ret=do_parse(reader);
-    xmlFreeTextReader(reader);
-    return (ret==0) ?  true:false;
-}
-
-bool osmparser::parse(osm_dataset *ds,char* data, int nbytes)
-{
-    // from cocoasamurai.blogspot.com/2008/10/getting-some-xml-love-with-
-    // libxml2.html, converted from Objective-C to straight C
-
-    components=ds;
-    xmlTextReaderPtr reader = xmlReaderForMemory(data,nbytes,nullptr,nullptr,0);
-    int ret=do_parse(reader);
-    xmlFreeTextReader(reader);
-    return (ret==0) ? true:false;
-}
-
-
-int osmparser::do_parse(xmlTextReaderPtr reader)
-{
-    int ret=-1;
-    if(reader!=nullptr)
-    {
-        ret = xmlTextReaderRead(reader);
-        while(ret==1)
-        {
-            processNode(reader);
-            ret=xmlTextReaderRead(reader);
-        }
-    }
-    return ret;
-}
diff --git a/plugins/input/osm/osmparser.h b/plugins/input/osm/osmparser.h
deleted file mode 100644
index 9f2aeac..0000000
--- a/plugins/input/osm/osmparser.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2011 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef OSMPARSER_H
-#define OSMPARSER_H
-
-#include <mapnik/value_types.hpp>
-#include <libxml/xmlreader.h>
-#include <cstdio>
-#include <cstdlib>
-#include <string>
-#include "osm.h"
-#include <map>
-
-class osmparser
-{
-public:
-    static void processNode(xmlTextReaderPtr reader);
-    static void startElement(xmlTextReaderPtr reader, const xmlChar* name);
-    static void endElement(const xmlChar* name);
-    static bool parse(osm_dataset* ds, const char* filename);
-    static bool parse(osm_dataset* ds, char* data, int nbytes);
-
-private:
-    static osm_item *cur_item;
-    static mapnik::value_integer curID;
-    static bool in_node, in_way;
-    static osm_dataset* components;
-    static std::string error;
-    static std::map<mapnik::value_integer, osm_node*> tmp_node_store;
-
-    static int do_parse(xmlTextReaderPtr);
-};
-
-#endif // OSMPARSER_H
diff --git a/plugins/input/osm/osmtagtypes.h b/plugins/input/osm/osmtagtypes.h
deleted file mode 100644
index 1915147..0000000
--- a/plugins/input/osm/osmtagtypes.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2011 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef OSMTAGTYPES_H
-#define OSMTAGTYPES_H
-
-// osmtagtypes.h
-// for finding the types of particular tags
-
-// mapnik
-#include <mapnik/feature_layer_desc.hpp>
-
-class osm_tag_types
-{
-public:
-    void add_type(std::string tag, mapnik::eAttributeType type)
-    {
-        types[tag] = type;
-    }
-
-    mapnik::eAttributeType get_type(std::string tag)
-    {
-        std::map<std::string, mapnik::eAttributeType>::iterator i = types.find(tag);
-        return (i == types.end()) ? mapnik::String : i->second;
-    }
-
-private:
-    std::map<std::string, mapnik::eAttributeType> types;
-};
-  
-#endif // OSMTAGTYPES_H
diff --git a/plugins/input/pgraster/pgraster_wkb_reader.cpp b/plugins/input/pgraster/pgraster_wkb_reader.cpp
index 0320fe1..87f71c0 100644
--- a/plugins/input/pgraster/pgraster_wkb_reader.cpp
+++ b/plugins/input/pgraster/pgraster_wkb_reader.cpp
@@ -271,18 +271,30 @@ mapnik::raster_ptr read_grayscale_band(mapnik::box2d<double> const& bbox,
 
 
   int val;
+  int nodataval;
   uint8_t * data = image.bytes();
   int ps = 4; // sizeof(image::pixel_type)
   int off;
-  val = reader(); // nodata value, need to read anyway
+  nodataval = reader(); // nodata value, need to read anyway
   for (int y=0; y<height; ++y) {
     for (int x=0; x<width; ++x) {
       val = reader();
+      // Apply harsh type clipping rules ala GDAL
+      if ( val < 0 ) val = 0;
+      if ( val > 255 ) val = 255;
+      // Calculate pixel offset
       off = y * width * ps + x * ps;
-      // Pixel space is RGBA
+      // Pixel space is RGBA, fill all w/ same value for Grey
       data[off+0] = val;
       data[off+1] = val;
       data[off+2] = val;
+      // Set the alpha channel for transparent nodata values
+      // Nodata handling is *manual* at the driver level
+      if ( hasnodata && val == nodataval ) {
+          data[off+3] = 0x00; // transparent
+      } else {
+          data[off+3] = 0xFF; // opaque
+      }
     }
   }
   mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0);
diff --git a/plugins/input/rasterlite/build.py b/plugins/input/rasterlite/build.py
deleted file mode 100644
index 779a489..0000000
--- a/plugins/input/rasterlite/build.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# This file is part of Mapnik (c++ mapping toolkit)
-#
-# Copyright (C) 2015 Artem Pavlenko
-#
-# Mapnik is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#
-
-Import ('plugin_base')
-Import ('env')
-
-PLUGIN_NAME = 'rasterlite'
-
-plugin_env = plugin_base.Clone()
-
-plugin_sources = Split(
-  """
-  %(PLUGIN_NAME)s_datasource.cpp
-  %(PLUGIN_NAME)s_featureset.cpp
-  """ % locals()
-)
-
-# Link Library to Dependencies
-libraries = [env['PLUGINS']['rasterlite']['lib']]
-libraries.append(env['ICU_LIB_NAME'])
-libraries.append('boost_system%s' % env['BOOST_APPEND'])
-
-if env['RUNTIME_LINK'] == 'static':
-    libraries.append('geotiff')
-    libraries.append('spatialite')
-    libraries.append('sqlite3')
-    libraries.append('geos_c')
-    libraries.append('geos')
-    libraries.append('proj')
-    libraries.append('z')
-
-if env['PLUGIN_LINKING'] == 'shared':
-    libraries.append(env['MAPNIK_NAME'])
-
-    TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
-                                      SHLIBPREFIX='',
-                                      SHLIBSUFFIX='.input',
-                                      source=plugin_sources,
-                                      LIBS=libraries)
-
-    # if the plugin links to libmapnik ensure it is built first
-    Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
-
-    if 'uninstall' not in COMMAND_LINE_TARGETS:
-        env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
-        env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
-
-plugin_obj = {
-  'LIBS': libraries,
-  'SOURCES': plugin_sources,
-}
-
-Return('plugin_obj')
diff --git a/plugins/input/rasterlite/rasterlite_datasource.cpp b/plugins/input/rasterlite/rasterlite_datasource.cpp
deleted file mode 100644
index 0261018..0000000
--- a/plugins/input/rasterlite/rasterlite_datasource.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#include "rasterlite_datasource.hpp"
-#include "rasterlite_featureset.hpp"
-
-// boost
-
-// mapnik
-#include <mapnik/util/fs.hpp>
-#include <mapnik/debug.hpp>
-#include <mapnik/boolean.hpp>
-#include <mapnik/geom_util.hpp>
-
-using mapnik::datasource;
-using mapnik::parameters;
-
-DATASOURCE_PLUGIN(rasterlite_datasource)
-
-using mapnik::box2d;
-using mapnik::coord2d;
-using mapnik::query;
-using mapnik::featureset_ptr;
-using mapnik::layer_descriptor;
-using mapnik::datasource_exception;
-
-
-/*
- * Opens a GDALDataset and returns a pointer to it.
- * Caller is responsible for calling GDALClose on it
- */
-inline void* rasterlite_datasource::open_dataset() const
-{
-    void* dataset = rasterliteOpen (dataset_name_.c_str(), table_name_.c_str());
-
-    if (! dataset)
-    {
-        throw datasource_exception("Rasterlite Plugin: Error opening dataset");
-    }
-
-    if (rasterliteIsError (dataset))
-    {
-        std::string error (rasterliteGetLastError(dataset));
-
-        rasterliteClose (dataset);
-
-        throw datasource_exception(error);
-    }
-
-    return dataset;
-}
-
-
-rasterlite_datasource::rasterlite_datasource(parameters const& params)
-    : datasource(params),
-      desc_(rasterlite_datasource::name(),"utf-8")
-{
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Initializing...";
-
-    boost::optional<std::string> file = params.get<std::string>("file");
-    if (!file) throw datasource_exception("missing <file> parameter");
-
-    boost::optional<std::string> table = params.get<std::string>("table");
-    if (!table) throw datasource_exception("missing <table> parameter");
-
-    table_name_ = *table;
-
-    boost::optional<std::string> base = params.get<std::string>("base");
-    if (base)
-        dataset_name_ = *base + "/" + *file;
-    else
-        dataset_name_ = *file;
-
-    if (!mapnik::util::exists(dataset_name_)) throw datasource_exception(dataset_name_ + " does not exist");
-
-    void *dataset = open_dataset();
-
-    double x0, y0, x1, y1;
-    if (rasterliteGetExtent (dataset, &x0, &y0, &x1, &y1) != RASTERLITE_OK)
-    {
-        std::string error (rasterliteGetLastError(dataset));
-
-        rasterliteClose (dataset);
-
-        throw datasource_exception(error);
-    }
-
-    extent_.init(x0,y0,x1,y1);
-
-#ifdef MAPNIK_LOG
-    int srid, auth_srid;
-    const char *auth_name;
-    const char *ref_sys_name;
-    const char *proj4text;
-
-    int tile_count;
-    double pixel_x_size, pixel_y_size;
-    int levels = rasterliteGetLevels (dataset);
-
-    if (rasterliteGetSrid(dataset, &srid, &auth_name, &auth_srid, &ref_sys_name, &proj4text) != RASTERLITE_OK)
-    {
-        std::string error (rasterliteGetLastError(dataset));
-
-        rasterliteClose (dataset);
-
-        throw datasource_exception(error);
-    }
-
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Data Source=" << rasterliteGetTablePrefix(dataset);
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: SRID=" << srid;
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Authority=" << auth_name;
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: AuthSRID=" << auth_srid;
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: RefSys Name=" << ref_sys_name;
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Proj4Text=" << proj4text;
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Extent=" << x0 << "," << y0 << " " << x1 << "," << y1 << ")";
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Levels=" << levels;
-
-    for (int i = 0; i < levels; i++)
-    {
-        if (rasterliteGetResolution(dataset, i, &pixel_x_size, &pixel_y_size, &tile_count) == RASTERLITE_OK)
-        {
-            MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_datasource: Level=" << i
-                                         << " x=" << pixel_x_size
-                                         << " y=" << pixel_y_size
-                                         << " tiles=" << tile_count;
-        }
-    }
-#endif
-
-    rasterliteClose(dataset);
-}
-
-rasterlite_datasource::~rasterlite_datasource()
-{
-}
-
-const char * rasterlite_datasource::name()
-{
-    return "rasterlite";
-}
-
-mapnik::datasource::datasource_t rasterlite_datasource::type() const
-{
-    return datasource::Raster;
-}
-
-box2d<double> rasterlite_datasource::envelope() const
-{
-    return extent_;
-}
-
-boost::optional<mapnik::datasource_geometry_t> rasterlite_datasource::get_geometry_type() const
-{
-    return boost::optional<mapnik::datasource_geometry_t>();
-}
-
-layer_descriptor rasterlite_datasource::get_descriptor() const
-{
-    return desc_;
-}
-
-featureset_ptr rasterlite_datasource::features(query const& q) const
-{
-    rasterlite_query gq = q;
-    return std::make_shared<rasterlite_featureset>(open_dataset(), gq);
-}
-
-featureset_ptr rasterlite_datasource::features_at_point(coord2d const& pt, double tol) const
-{
-    rasterlite_query gq = pt;
-    return std::make_shared<rasterlite_featureset>(open_dataset(), gq);
-}
diff --git a/plugins/input/rasterlite/rasterlite_datasource.hpp b/plugins/input/rasterlite/rasterlite_datasource.hpp
deleted file mode 100644
index dd30446..0000000
--- a/plugins/input/rasterlite/rasterlite_datasource.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef RASTERLITE_DATASOURCE_HPP
-#define RASTERLITE_DATASOURCE_HPP
-
-// mapnik
-#include <mapnik/datasource.hpp>
-#include <mapnik/params.hpp>
-#include <mapnik/query.hpp>
-#include <mapnik/feature.hpp>
-#include <mapnik/box2d.hpp>
-#include <mapnik/coord.hpp>
-#include <mapnik/feature_layer_desc.hpp>
-
-// boost
-#include <boost/optional.hpp>
-#include <memory>
-
-// stl
-#include <vector>
-#include <string>
-
-#include "rasterlite_include.hpp"
-
-class rasterlite_datasource : public mapnik::datasource
-{
-public:
-    rasterlite_datasource(mapnik::parameters const& params);
-    virtual ~rasterlite_datasource ();
-    mapnik::datasource::datasource_t type() const;
-    static const char * name();
-    mapnik::featureset_ptr features(mapnik::query const& q) const;
-    mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const;
-    mapnik::box2d<double> envelope() const;
-    boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
-    mapnik::layer_descriptor get_descriptor() const;
-
-private:
-    void* open_dataset() const;
-    mapnik::box2d<double> extent_;
-    std::string dataset_name_;
-    std::string table_name_;
-    mapnik::layer_descriptor desc_;
-};
-
-#endif // RASTERLITE_DATASOURCE_HPP
diff --git a/plugins/input/rasterlite/rasterlite_featureset.cpp b/plugins/input/rasterlite/rasterlite_featureset.cpp
deleted file mode 100644
index 270a87e..0000000
--- a/plugins/input/rasterlite/rasterlite_featureset.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#include "rasterlite_featureset.hpp"
-
-// mapnik
-#include <mapnik/debug.hpp>
-#include <mapnik/image.hpp>
-#include <mapnik/image_util.hpp>
-#include <mapnik/query.hpp>
-#include <mapnik/raster.hpp>
-#include <mapnik/feature.hpp>
-#include <mapnik/feature_factory.hpp>
-
-#include <cstring>
-
-using mapnik::coord2d;
-using mapnik::box2d;
-using mapnik::feature_ptr;
-using mapnik::query;
-using mapnik::feature_factory;
-
-
-rasterlite_featureset::rasterlite_featureset(void* dataset,
-                                             rasterlite_query q)
-    : dataset_(dataset),
-      gquery_(q),
-      first_(true),
-      ctx_(std::make_shared<mapnik::context_type>())
-{
-    rasterliteSetBackgroundColor(dataset_, 255, 0, 255);
-    rasterliteSetTransparentColor(dataset_, 255, 0, 255);
-}
-
-rasterlite_featureset::~rasterlite_featureset()
-{
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Closing";
-
-    rasterliteClose(dataset_);
-}
-
-feature_ptr rasterlite_featureset::next()
-{
-    if (first_)
-    {
-        first_ = false;
-        MAPNIK_LOG_DEBUG(gdal) << "rasterlite_featureset: Next feature in Dataset=" << &dataset_;
-        return mapnik::util::apply_visitor(query_dispatch(*this), gquery_);
-    }
-    return feature_ptr();
-}
-
-feature_ptr rasterlite_featureset::get_feature(mapnik::query const& q)
-{
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Running get_feature";
-
-    feature_ptr feature(feature_factory::create(ctx_,1));
-
-    double x0, y0, x1, y1;
-    rasterliteGetExtent (dataset_, &x0, &y0, &x1, &y1);
-
-    box2d<double> raster_extent(x0, y0, x1, y1);
-    box2d<double> intersect = raster_extent.intersect(q.get_bbox());
-
-    const int width = static_cast<int>(std::get<0>(q.resolution()) * intersect.width() + 0.5);
-    const int height = static_cast<int>(std::get<0>(q.resolution()) * intersect.height() + 0.5);
-
-    const double pixel_size = (intersect.width() >= intersect.height()) ?
-        (intersect.width() / (double) width) : (intersect.height() / (double) height);
-
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Raster extent=" << raster_extent;
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: View extent=" << q.get_bbox();
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Intersect extent=" << intersect;
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Query resolution=" << std::get<0>(q.resolution())  << "," << std::get<1>(q.resolution());
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Size=" << width << " " << height;
-    MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Pixel Size=" << pixel_size;
-
-    if (width > 0 && height > 0)
-    {
-        int size = 0;
-        void* raster = 0;
-
-        if (rasterliteGetRawImageByRect(dataset_,
-                                        intersect.minx(),
-                                        intersect.miny(),
-                                        intersect.maxx(),
-                                        intersect.maxy(),
-                                        pixel_size,
-                                        width,
-                                        height,
-                                        GAIA_RGBA_ARRAY,
-                                        &raster,
-                                        &size) == RASTERLITE_OK)
-        {
-            if (size > 0)
-            {
-                mapnik::image_rgba8 image(width,height);
-                unsigned char* raster_data = static_cast<unsigned char*>(raster);
-                std::memcpy(image.bytes(), raster_data, size);
-                feature->set_raster(std::make_shared<mapnik::raster>(intersect, std::move(image), 1.0));
-                MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Done";
-            }
-            else
-            {
-                MAPNIK_LOG_ERROR(rasterlite) << "Rasterlite Plugin: Error " << rasterliteGetLastError (dataset_);
-            }
-        }
-
-        return feature;
-    }
-    return feature_ptr();
-}
-
-feature_ptr rasterlite_featureset::get_feature_at_point(mapnik::coord2d const& pt)
-{
-    return feature_ptr();
-}
diff --git a/plugins/input/rasterlite/rasterlite_featureset.hpp b/plugins/input/rasterlite/rasterlite_featureset.hpp
deleted file mode 100644
index cb251c8..0000000
--- a/plugins/input/rasterlite/rasterlite_featureset.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef RASTERLITE_FEATURESET_HPP
-#define RASTERLITE_FEATURESET_HPP
-
-// mapnik
-#include <mapnik/feature.hpp>
-#include <mapnik/query.hpp>
-#include <mapnik/datasource.hpp>
-#include <mapnik/util/variant.hpp>
-
-#include "rasterlite_include.hpp"
-
-using rasterlite_query = mapnik::util::variant<mapnik::query,mapnik::coord2d>;
-
-class rasterlite_featureset : public mapnik::Featureset
-{
-    struct query_dispatch
-    {
-        query_dispatch( rasterlite_featureset & featureset)
-            : featureset_(featureset) {}
-
-        mapnik::feature_ptr operator() (mapnik::query const& q) const
-        {
-            return featureset_.get_feature(q);
-        }
-
-        mapnik::feature_ptr operator() (mapnik::coord2d const& p) const
-        {
-            return featureset_.get_feature_at_point(p);
-        }
-
-        rasterlite_featureset & featureset_;
-    };
-
-public:
-    rasterlite_featureset(void* dataset,
-                          rasterlite_query q);
-    virtual ~rasterlite_featureset();
-    mapnik::feature_ptr next();
-
-private:
-    mapnik::feature_ptr get_feature(mapnik::query const& q);
-    mapnik::feature_ptr get_feature_at_point(mapnik::coord2d const& p);
-    void* dataset_;
-    rasterlite_query gquery_;
-    bool first_;
-    mapnik::context_ptr ctx_;
-};
-
-#endif // RASTERLITE_FEATURESET_HPP
diff --git a/plugins/input/rasterlite/rasterlite_include.hpp b/plugins/input/rasterlite/rasterlite_include.hpp
deleted file mode 100644
index b6a9dd2..0000000
--- a/plugins/input/rasterlite/rasterlite_include.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*****************************************************************************
- *
- * This file is part of Mapnik (c++ mapping toolkit)
- *
- * Copyright (C) 2015 Artem Pavlenko
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *****************************************************************************/
-
-#ifndef RASTERLITE_INCLUDE_HPP
-#define RASTERLITE_INCLUDE_HPP
-
-extern "C" {
-#include <sqlite3.h>
-#include <rasterlite.h>
-}
-
-#endif // RASTERLITE_INCLUDE_HPP
diff --git a/src/agg/process_group_symbolizer.cpp b/src/agg/process_group_symbolizer.cpp
index 68c54f2..f2c8adf 100644
--- a/src/agg/process_group_symbolizer.cpp
+++ b/src/agg/process_group_symbolizer.cpp
@@ -32,6 +32,7 @@
 #include <mapnik/geom_util.hpp>
 #include <mapnik/symbolizer.hpp>
 #include <mapnik/pixel_position.hpp>
+#include <mapnik/text/glyph_positions.hpp>
 #include <mapnik/renderer_common/process_group_symbolizer.hpp>
 #include <mapnik/renderer_common/clipping_extent.hpp>
 #include <mapnik/svg/svg_renderer_agg.hpp>
diff --git a/src/agg/process_line_pattern_symbolizer.cpp b/src/agg/process_line_pattern_symbolizer.cpp
index 7cdd166..a6be6b1 100644
--- a/src/agg/process_line_pattern_symbolizer.cpp
+++ b/src/agg/process_line_pattern_symbolizer.cpp
@@ -50,7 +50,6 @@
 #include "agg_span_allocator.h"
 #include "agg_span_pattern_rgba.h"
 #include "agg_renderer_outline_image.h"
-#include "agg_conv_clip_polyline.h"
 
 namespace mapnik {
 
diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp
index ab06ed3..cb94282 100644
--- a/src/agg/process_markers_symbolizer.cpp
+++ b/src/agg/process_markers_symbolizer.cpp
@@ -50,7 +50,6 @@
 #include "agg_rasterizer_scanline_aa.h"
 #include "agg_scanline_u.h"
 #include "agg_path_storage.h"
-#include "agg_conv_clip_polyline.h"
 #include "agg_conv_transform.h"
 
 
diff --git a/src/agg/process_shield_symbolizer.cpp b/src/agg/process_shield_symbolizer.cpp
index 67fe8de..3d28eff 100644
--- a/src/agg/process_shield_symbolizer.cpp
+++ b/src/agg/process_shield_symbolizer.cpp
@@ -27,6 +27,7 @@
 #include <mapnik/text/symbolizer_helpers.hpp>
 #include <mapnik/pixel_position.hpp>
 #include <mapnik/text/renderer.hpp>
+#include <mapnik/text/glyph_positions.hpp>
 #include <mapnik/renderer_common/clipping_extent.hpp>
 
 namespace mapnik {
diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp
index 078a7ab..b3794bc 100644
--- a/src/agg/process_text_symbolizer.cpp
+++ b/src/agg/process_text_symbolizer.cpp
@@ -27,6 +27,7 @@
 #include <mapnik/agg_rasterizer.hpp>
 #include <mapnik/text/symbolizer_helpers.hpp>
 #include <mapnik/text/renderer.hpp>
+#include <mapnik/text/glyph_positions.hpp>
 #include <mapnik/renderer_common/clipping_extent.hpp>
 
 namespace mapnik {
diff --git a/src/cairo/process_group_symbolizer.cpp b/src/cairo/process_group_symbolizer.cpp
index d32afcf..a2dc4ab 100644
--- a/src/cairo/process_group_symbolizer.cpp
+++ b/src/cairo/process_group_symbolizer.cpp
@@ -26,6 +26,7 @@
 #include <mapnik/marker.hpp>
 #include <mapnik/svg/svg_path_adapter.hpp>
 #include <mapnik/make_unique.hpp>
+#include <mapnik/text/glyph_positions.hpp>
 #include <mapnik/cairo/cairo_renderer.hpp>
 #include <mapnik/cairo/cairo_render_vector.hpp>
 
diff --git a/src/cairo/process_text_symbolizer.cpp b/src/cairo/process_text_symbolizer.cpp
index 06b56cb..2d34e21 100644
--- a/src/cairo/process_text_symbolizer.cpp
+++ b/src/cairo/process_text_symbolizer.cpp
@@ -27,6 +27,7 @@
 #include <mapnik/text/symbolizer_helpers.hpp>
 #include <mapnik/pixel_position.hpp>
 #include <mapnik/symbolizer.hpp>
+#include <mapnik/text/glyph_positions.hpp>
 
 namespace mapnik
 {
diff --git a/src/color_factory.cpp b/src/color_factory.cpp
index d13a895..dc54e89 100644
--- a/src/color_factory.cpp
+++ b/src/color_factory.cpp
@@ -45,7 +45,7 @@ color parse_color(std::string const& str)
     }
     else
     {
-        throw config_error("Failed to a parse color: \"" + str + "\"");
+        throw config_error("Failed to parse color: \"" + str + "\"");
     }
 }
 
diff --git a/src/grid/process_group_symbolizer.cpp b/src/grid/process_group_symbolizer.cpp
index a672f6b..f731189 100644
--- a/src/grid/process_group_symbolizer.cpp
+++ b/src/grid/process_group_symbolizer.cpp
@@ -33,6 +33,7 @@
 #include <mapnik/text/placement_finder.hpp>
 #include <mapnik/text/symbolizer_helpers.hpp>
 #include <mapnik/text/renderer.hpp>
+#include <mapnik/text/glyph_positions.hpp>
 #include <mapnik/svg/svg_renderer_agg.hpp>
 #include <mapnik/svg/svg_storage.hpp>
 #include <mapnik/svg/svg_path_adapter.hpp>
diff --git a/src/grid/process_shield_symbolizer.cpp b/src/grid/process_shield_symbolizer.cpp
index 7819893..50bc820 100644
--- a/src/grid/process_shield_symbolizer.cpp
+++ b/src/grid/process_shield_symbolizer.cpp
@@ -31,6 +31,7 @@
 #include <mapnik/text/symbolizer_helpers.hpp>
 #include <mapnik/pixel_position.hpp>
 #include <mapnik/text/renderer.hpp>
+#include <mapnik/text/glyph_positions.hpp>
 
 // agg
 #include "agg_trans_affine.h"
diff --git a/src/grid/process_text_symbolizer.cpp b/src/grid/process_text_symbolizer.cpp
index 3df4ad2..7fe0ff3 100644
--- a/src/grid/process_text_symbolizer.cpp
+++ b/src/grid/process_text_symbolizer.cpp
@@ -28,6 +28,7 @@
 #include <mapnik/text/symbolizer_helpers.hpp>
 #include <mapnik/pixel_position.hpp>
 #include <mapnik/text/renderer.hpp>
+#include <mapnik/text/glyph_positions.hpp>
 #include <mapnik/renderer_common/clipping_extent.hpp>
 
 namespace mapnik {
diff --git a/src/group/group_symbolizer_helper.cpp b/src/group/group_symbolizer_helper.cpp
index a8e453a..2ba70ff 100644
--- a/src/group/group_symbolizer_helper.cpp
+++ b/src/group/group_symbolizer_helper.cpp
@@ -34,9 +34,6 @@
 #include <mapnik/vertex_cache.hpp>
 #include <mapnik/tolerance_iterator.hpp>
 
-//agg
-#include "agg_conv_clip_polyline.h"
-
 namespace mapnik { namespace detail {
 
 template <typename Helper>
diff --git a/src/memory_datasource.cpp b/src/memory_datasource.cpp
index c30f674..f7bd61d 100644
--- a/src/memory_datasource.cpp
+++ b/src/memory_datasource.cpp
@@ -82,6 +82,7 @@ void memory_datasource::push(feature_ptr feature)
     // TODO - collect attribute descriptors?
     //desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
     features_.push_back(feature);
+    dirty_extent_ = true;
 }
 
 datasource::datasource_t memory_datasource::type() const
@@ -110,10 +111,11 @@ void memory_datasource::set_envelope(box2d<double> const& box)
 
 box2d<double> memory_datasource::envelope() const
 {
-    if (!extent_.valid())
+    if (!extent_.valid() || dirty_extent_)
     {
         accumulate_extent func(extent_);
         std::for_each(features_.begin(),features_.end(),func);
+        dirty_extent_ = false;
     }
     return extent_;
 }
diff --git a/src/svg/svg_parser.cpp b/src/svg/svg_parser.cpp
index 1ef103c..548ccd2 100644
--- a/src/svg/svg_parser.cpp
+++ b/src/svg/svg_parser.cpp
@@ -135,17 +135,8 @@ double parse_double_optional_percent(const char* str, bool &percent)
     qi::char_type char_;
 
     double val = 0.0;
-    char unit='\0';
-    parse(str, str + std::strlen(str),double_[ref(val)=_1] >> *char_('%')[ref(unit)=_1]);
-    if (unit =='%')
-    {
-        percent = true;
-        val/=100.0;
-    }
-    else
-    {
-        percent = false;
-    }
+    parse(str, str + std::strlen(str),double_[ref(val)=_1, ref(percent) = false]
+          >> -char_('%')[ref(val)/100.0, ref(percent) = true]);
     return val;
 }
 
@@ -498,7 +489,8 @@ void parse_path(svg_parser & parser, xmlTextReaderPtr reader)
             {
                 xmlFree(value);
                 xmlChar *id_value;
-                id_value = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
+                id_value = xmlTextReaderGetAttribute(reader, BAD_CAST "xml:id");
+                if (!id_value) id_value = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
                 if (id_value)
                 {
                     std::string id_string((const char *) id_value);
@@ -688,6 +680,7 @@ void parse_ellipse(svg_parser & parser, xmlTextReaderPtr reader)
 
 void parse_rect(svg_parser & parser, xmlTextReaderPtr reader)
 {
+    // http://www.w3.org/TR/SVGTiny12/shapes.html#RectElement
     xmlChar *value;
     double x = 0.0;
     double y = 0.0;
@@ -728,6 +721,7 @@ void parse_rect(svg_parser & parser, xmlTextReaderPtr reader)
     if (value)
     {
         rx = parse_double((const char*)value);
+        if ( rx > 0.5 * w ) rx = 0.5 * w;
         xmlFree(value);
     }
     else rounded = false;
@@ -736,6 +730,7 @@ void parse_rect(svg_parser & parser, xmlTextReaderPtr reader)
     if (value)
     {
         ry = parse_double((const char*)value);
+        if ( ry > 0.5 * h ) ry = 0.5 * h;
         if (!rounded)
         {
             rx = ry;
@@ -865,7 +860,9 @@ bool parse_common_gradient(svg_parser & parser, xmlTextReaderPtr reader)
     xmlChar *value;
 
     std::string id;
-    value = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
+    value = xmlTextReaderGetAttribute(reader, BAD_CAST "xml:id");
+    if (!value) value = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
+
     if (value)
     {
         // start a new gradient
diff --git a/src/text/face.cpp b/src/text/face.cpp
index 10afa65..79f35d8 100644
--- a/src/text/face.cpp
+++ b/src/text/face.cpp
@@ -36,12 +36,12 @@ font_face::font_face(FT_Face face)
 
 bool font_face::set_character_sizes(double size)
 {
-    return !FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0);
+    return (FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0) == 0);
 }
 
 bool font_face::set_unscaled_character_sizes()
 {
-    return !FT_Set_Char_Size(face_,0,face_->units_per_EM,0,0);
+    return (FT_Set_Char_Size(face_,0,face_->units_per_EM,0,0) == 0);
 }
 
 bool font_face::glyph_dimensions(glyph_info & glyph) const
diff --git a/src/text/placement_finder.cpp b/src/text/placement_finder.cpp
index 7c09e56..53dda7d 100644
--- a/src/text/placement_finder.cpp
+++ b/src/text/placement_finder.cpp
@@ -25,6 +25,7 @@
 #include <mapnik/view_transform.hpp>
 #include <mapnik/expression_evaluator.hpp>
 #include <mapnik/text/placement_finder_impl.hpp>
+#include <mapnik/text/placements/base.hpp>
 #include <mapnik/text/text_layout.hpp>
 #include <mapnik/text/glyph_info.hpp>
 #include <mapnik/text/text_properties.hpp>
@@ -32,9 +33,6 @@
 #include <mapnik/vertex_cache.hpp>
 #include <mapnik/util/math.hpp>
 
-// agg
-#include "agg_conv_clip_polyline.h"
-
 // stl
 #include <vector>
 
diff --git a/src/text/symbolizer_helpers.cpp b/src/text/symbolizer_helpers.cpp
index 99c7c03..860359a 100644
--- a/src/text/symbolizer_helpers.cpp
+++ b/src/text/symbolizer_helpers.cpp
@@ -41,8 +41,6 @@
 #include <mapnik/text/placements/base.hpp>
 #include <mapnik/text/placements/dummy.hpp>
 
-//agg
-#include "agg_conv_clip_polyline.h"
 
 namespace mapnik { namespace detail {
 
@@ -79,11 +77,10 @@ struct split_multi_geometries
 {
     using container_type = T;
     split_multi_geometries(container_type & cont, view_transform const& t,
-                           proj_transform const& prj_trans, double minimum_path_length)
+                           proj_transform const& prj_trans)
         : cont_(cont),
           t_(t),
-          prj_trans_(prj_trans),
-          minimum_path_length_(minimum_path_length) {}
+          prj_trans_(prj_trans) { }
 
     void operator() (geometry::geometry_empty const&) const {}
     void operator() (geometry::multi_point<double> const& multi_pt) const
@@ -95,18 +92,7 @@ struct split_multi_geometries
     }
     void operator() (geometry::line_string<double> const& line) const
     {
-        if (minimum_path_length_ > 0)
-        {
-            box2d<double> bbox = t_.forward(geometry::envelope(line), prj_trans_);
-            if (bbox.width() >= minimum_path_length_)
-            {
-                cont_.push_back(base_symbolizer_helper::geometry_cref(std::cref(line)));
-            }
-        }
-        else
-        {
-            cont_.push_back(base_symbolizer_helper::geometry_cref(std::cref(line)));
-        }
+        cont_.push_back(base_symbolizer_helper::geometry_cref(std::cref(line)));
     }
 
     void operator() (geometry::multi_line_string<double> const& multi_line) const
@@ -119,18 +105,7 @@ struct split_multi_geometries
 
     void operator() (geometry::polygon<double> const& poly) const
     {
-        if (minimum_path_length_ > 0)
-        {
-            box2d<double> bbox = t_.forward(geometry::envelope(poly), prj_trans_);
-            if (bbox.width() >= minimum_path_length_)
-            {
-                cont_.push_back(base_symbolizer_helper::geometry_cref(std::cref(poly)));
-            }
-        }
-        else
-        {
-            cont_.push_back(base_symbolizer_helper::geometry_cref(std::cref(poly)));
-        }
+        cont_.push_back(base_symbolizer_helper::geometry_cref(std::cref(poly)));
     }
 
     void operator() (geometry::multi_polygon<double> const& multi_poly) const
@@ -158,7 +133,6 @@ struct split_multi_geometries
     container_type & cont_;
     view_transform const& t_;
     proj_transform const& prj_trans_;
-    double minimum_path_length_;
 };
 
 } // ns detail
@@ -207,10 +181,9 @@ struct largest_bbox_first
 
 void base_symbolizer_helper::initialize_geometries() const
 {
-    double minimum_path_length = text_props_->minimum_path_length;
     auto const& geom = feature_.get_geometry();
     util::apply_visitor(detail::split_multi_geometries<geometry_container_type>
-                        (geometries_to_process_, t_, prj_trans_, minimum_path_length ), geom);
+                        (geometries_to_process_, t_, prj_trans_), geom);
     if (!geometries_to_process_.empty())
     {
         auto type = geometry::geometry_type(geom);
diff --git a/test/unit/core/copy_move_test.cpp b/test/unit/core/copy_move_test.cpp
index 6905379..a219178 100644
--- a/test/unit/core/copy_move_test.cpp
+++ b/test/unit/core/copy_move_test.cpp
@@ -23,7 +23,6 @@ SECTION("layers") {
         std::string shape_plugin("./plugins/input/shape.input");
         if (mapnik::util::exists(shape_plugin))
         {
-            mapnik::datasource_cache::instance().register_datasources("plugins/input/shape.input");
             mapnik::parameters p;
             p["type"]="shape";
             p["file"]="demo/data/boundaries";
diff --git a/test/unit/core/exceptions_test.cpp b/test/unit/core/exceptions_test.cpp
index 3324600..46abcce 100644
--- a/test/unit/core/exceptions_test.cpp
+++ b/test/unit/core/exceptions_test.cpp
@@ -62,7 +62,6 @@ SECTION("handling") {
     std::string csv_plugin("./plugins/input/csv.input");
     if (mapnik::util::exists(csv_plugin)) {
         try {
-            mapnik::datasource_cache::instance().register_datasource(csv_plugin);
             mapnik::parameters p;
             p["type"]="csv";
             p["inline"]="x,y\n0,0";
@@ -88,7 +87,6 @@ SECTION("handling") {
     std::string shape_plugin("./plugins/input/shape.input");
     if (mapnik::util::exists(shape_plugin)) {
         try {
-            mapnik::datasource_cache::instance().register_datasource(shape_plugin);
             mapnik::parameters p2;
             p2["type"]="shape";
             p2["file"]="foo";
diff --git a/test/unit/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp
new file mode 100644
index 0000000..9bcacca
--- /dev/null
+++ b/test/unit/datasource/geojson.cpp
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2015 Artem Pavlenko
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *****************************************************************************/
+
+#include "catch.hpp"
+
+#include <mapnik/map.hpp>
+#include <mapnik/datasource.hpp>
+#include <mapnik/datasource_cache.hpp>
+#include <mapnik/geometry.hpp>
+#include <mapnik/util/fs.hpp>
+
+TEST_CASE("geojson") {
+
+    std::string geojson_plugin("./plugins/input/geojson.input");
+    if (mapnik::util::exists(geojson_plugin))
+    {
+        SECTION("json feature cache-feature=\"true\"")
+        {
+            // Create datasource
+            mapnik::parameters params;
+            params["type"] = "geojson";
+            params["file"] = "./test/data/json/feature.json";
+            params["cache-features"] = true;
+            auto ds = mapnik::datasource_cache::instance().create(params);
+            REQUIRE(bool(ds));
+            auto fields = ds->get_descriptor().get_descriptors();
+            mapnik::query query(ds->envelope());
+            for (auto const &field : fields)
+            {
+                query.add_property_name(field.get_name());
+            }
+            auto features = ds->features(query);
+            REQUIRE(features != nullptr);
+            auto feature = features->next();
+            REQUIRE(feature != nullptr);
+        }
+
+        SECTION("json feature cache-feature=\"false\"")
+        {
+            mapnik::parameters params;
+            params["type"] = "geojson";
+            params["file"] = "./test/data/json/feature.json";
+            params["cache-features"] = false;
+            auto ds = mapnik::datasource_cache::instance().create(params);
+            REQUIRE(bool(ds));
+            auto fields = ds->get_descriptor().get_descriptors();
+            mapnik::query query(ds->envelope());
+            for (auto const &field : fields)
+            {
+                query.add_property_name(field.get_name());
+            }
+            auto features = ds->features(query);
+            REQUIRE(features != nullptr);
+            auto feature = features->next();
+            REQUIRE(feature != nullptr);
+        }
+
+        SECTION("json extra properties cache-feature=\"true\"")
+        {
+            // Create datasource
+            mapnik::parameters params;
+            params["type"] = "geojson";
+            params["file"] = "./test/data/json/feature_collection_extra_properties.json";
+            params["cache-features"] = true;
+            auto ds = mapnik::datasource_cache::instance().create(params);
+            REQUIRE(bool(ds));
+            auto fields = ds->get_descriptor().get_descriptors();
+            mapnik::query query(ds->envelope());
+            for (auto const &field : fields)
+            {
+                query.add_property_name(field.get_name());
+            }
+            auto features = ds->features(query);
+            REQUIRE(features != nullptr);
+            auto feature = features->next();
+            REQUIRE(feature != nullptr);
+            REQUIRE(feature->envelope() == mapnik::box2d<double>(123,456,123,456));
+        }
+
+        SECTION("json extra properties cache-feature=\"false\"")
+        {
+            // Create datasource
+            mapnik::parameters params;
+            params["type"] = "geojson";
+            params["file"] = "./test/data/json/feature_collection_extra_properties.json";
+            params["cache-features"] = false;
+            auto ds = mapnik::datasource_cache::instance().create(params);
+            REQUIRE(bool(ds));
+            auto fields = ds->get_descriptor().get_descriptors();
+            mapnik::query query(ds->envelope());
+            for (auto const &field : fields)
+            {
+                query.add_property_name(field.get_name());
+            }
+            auto features = ds->features(query);
+            REQUIRE(features != nullptr);
+            auto feature = features->next();
+            REQUIRE(feature != nullptr);
+            REQUIRE(feature->envelope() == mapnik::box2d<double>(123,456,123,456));
+        }
+
+    }
+}
diff --git a/test/unit/imaging/image_painted_test.cpp b/test/unit/imaging/image_painted_test.cpp
index a1fbbc9..5d0b403 100644
--- a/test/unit/imaging/image_painted_test.cpp
+++ b/test/unit/imaging/image_painted_test.cpp
@@ -21,8 +21,6 @@ SECTION("painting") {
         std::string csv_plugin("./plugins/input/csv.input");
         if (mapnik::util::exists(csv_plugin))
         {
-            datasource_cache::instance().register_datasources(csv_plugin);
-
             Map m(256, 256);
 
             feature_type_style lines_style;
diff --git a/test/unit/run.cpp b/test/unit/run.cpp
index 15ad099..8ae4ddc 100644
--- a/test/unit/run.cpp
+++ b/test/unit/run.cpp
@@ -1,10 +1,14 @@
 #define CATCH_CONFIG_RUNNER
 #include "catch.hpp"
 
+#include <mapnik/datasource_cache.hpp>
+
 #include "cleanup.hpp" // run_cleanup()
 
 int main (int argc, char* const argv[])
 {
+    mapnik::datasource_cache::instance().register_datasources("plugins/input/");
+
     int result = Catch::Session().run( argc, argv );
 
     testing::run_cleanup();
diff --git a/test/unit/svg/svg_parser_test.cpp b/test/unit/svg/svg_parser_test.cpp
new file mode 100644
index 0000000..0c2752a
--- /dev/null
+++ b/test/unit/svg/svg_parser_test.cpp
@@ -0,0 +1,295 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2015 Artem Pavlenko
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *****************************************************************************/
+
+#include "catch.hpp"
+
+#include <mapnik/version.hpp>
+#include <mapnik/debug.hpp>
+#include <mapnik/marker.hpp>
+#include <mapnik/marker_cache.hpp>
+#include <mapnik/vertex.hpp>
+#include <mapnik/svg/svg_path_adapter.hpp>
+#include <mapnik/svg/svg_renderer_agg.hpp>
+#include <mapnik/svg/svg_path_attributes.hpp>
+#include <libxml/parser.h> // for xmlInitParser(), xmlCleanupParser()
+#include <cmath>
+
+namespace detail {
+
+template <int N = 6>
+struct vertex_equal
+{
+    template <typename T>
+    bool operator() (T const& lhs, T const& rhs) const
+    {
+        static const double eps = 1.0 / std::pow(10,N);
+        return (std::fabs(std::get<0>(lhs) - std::get<0>(rhs)) < eps)
+            && (std::fabs(std::get<1>(lhs) - std::get<1>(rhs)) < eps)
+            && std::get<2>(lhs) == std::get<2>(rhs);
+    }
+};
+}
+
+TEST_CASE("SVG parser") {
+
+    xmlInitParser();
+    SECTION("SVG <rect>")
+    {
+        //<rect width="20" height="15" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)" />
+        std::string svg_name("./test/data/svg/rect.svg");
+        std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
+        REQUIRE(marker);
+        REQUIRE(marker->is<mapnik::marker_svg>());
+        mapnik::marker_svg const& svg = mapnik::util::get<mapnik::marker_svg>(*marker);
+        auto bbox = svg.bounding_box();
+        REQUIRE(bbox == mapnik::box2d<double>(0, 0, 20, 15));
+        auto storage = svg.get_data();
+        REQUIRE(storage);
+        mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(storage->source());
+        mapnik::svg::svg_path_adapter path(stl_storage);
+        double x,y;
+        unsigned cmd;
+        std::vector<std::tuple<double,double,unsigned>> vec;
+        while ((cmd = path.vertex(&x,&y)) != mapnik::SEG_END)
+        {
+            vec.emplace_back(x, y, cmd);
+            //std::cerr << x << "," << y << " cmd=" << cmd << std::endl;
+        }
+        std::vector<std::tuple<double,double,unsigned>> expected = { std::make_tuple(0, 0, 1),
+                                                                     std::make_tuple(20, 0, 2),
+                                                                     std::make_tuple(20, 15, 2),
+                                                                     std::make_tuple(0, 15, 2),
+                                                                     std::make_tuple(0, 0, 79) };
+        REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin()));
+    }
+    SECTION("SVG rounded <rect>")
+    {
+        //<rect width="20" height="15" rx="5" ry="10" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)" />
+        std::string svg_name("./test/data/svg/rounded_rect.svg");
+        std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
+        REQUIRE(marker);
+        REQUIRE(marker->is<mapnik::marker_svg>());
+        mapnik::marker_svg const& svg = mapnik::util::get<mapnik::marker_svg>(*marker);
+        auto bbox = svg.bounding_box();
+        REQUIRE(bbox == mapnik::box2d<double>(0, 0, 20, 15));
+        auto storage = svg.get_data();
+        REQUIRE(storage);
+        mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(storage->source());
+        mapnik::svg::svg_path_adapter path(stl_storage);
+        double x,y;
+        unsigned cmd;
+        std::vector<std::tuple<double,double,unsigned>> vec;
+
+        while ((cmd = path.vertex(&x,&y)) != mapnik::SEG_END)
+        {
+            vec.emplace_back(x, y, cmd);
+        }
+
+        std::vector<std::tuple<double,double,unsigned>> expected = {std::make_tuple(0, 5,1),
+                                                                    std::make_tuple(0.481856, 2.85842,2),
+                                                                    std::make_tuple(1.83455, 1.12961,2),
+                                                                    std::make_tuple(3.79736, 0.146789,2),
+                                                                    std::make_tuple(5, 0,2),
+                                                                    std::make_tuple(15, 0,2),
+                                                                    std::make_tuple(17.1416, 0.481856,2),
+                                                                    std::make_tuple(18.8704, 1.83455,2),
+                                                                    std::make_tuple(19.8532, 3.79736,2),
+                                                                    std::make_tuple(20, 5,2),
+                                                                    std::make_tuple(20, 10,2),
+                                                                    std::make_tuple(19.5181, 12.1416,2),
+                                                                    std::make_tuple(18.1654, 13.8704,2),
+                                                                    std::make_tuple(16.2026, 14.8532,2),
+                                                                    std::make_tuple(15, 15,2),
+                                                                    std::make_tuple(5, 15,2),
+                                                                    std::make_tuple(2.85842, 14.5181,2),
+                                                                    std::make_tuple(1.12961, 13.1654,2),
+                                                                    std::make_tuple(0.146789, 11.2026,2),
+                                                                    std::make_tuple(0, 10,2),
+                                                                    std::make_tuple(0, 10,95)};
+
+        REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin(),detail::vertex_equal<3>()));
+    }
+
+    SECTION("SVG <line>")
+    {
+        //
+        std::string svg_name("./test/data/svg/line.svg");
+        std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
+        REQUIRE(marker);
+        REQUIRE(marker->is<mapnik::marker_svg>());
+        mapnik::marker_svg const& svg = mapnik::util::get<mapnik::marker_svg>(*marker);
+        auto bbox = svg.bounding_box();
+        REQUIRE(bbox == mapnik::box2d<double>(1.0,1.0,1199.0,399.0));
+        auto storage = svg.get_data();
+        REQUIRE(storage);
+        mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(storage->source());
+        mapnik::svg::svg_path_adapter path(stl_storage);
+        double x,y;
+        unsigned cmd;
+        std::vector<std::tuple<double,double,unsigned>> vec;
+        std::size_t num_vertices = path.total_vertices();
+        //std::cerr << "Num vertices = " << num_vertices << std::endl;
+        //std::cerr << "{";
+        for (std::size_t i = 0; i < num_vertices; ++i)
+        {
+            cmd = path.vertex(&x,&y);
+            vec.emplace_back(x, y, cmd);
+            //if (vec.size() > 1) std::cerr << ",";
+            //std::cerr << std::setprecision(6) << "std::make_tuple(" << x << ", " << y << ", " << cmd << ")";
+        }
+        //std::cerr << "}" << std::endl;
+
+        std::vector<std::tuple<double,double,unsigned>> expected = {std::make_tuple(1, 1, 1),
+                                                                    std::make_tuple(1199, 1, 2),
+                                                                    std::make_tuple(1199, 399, 2),
+                                                                    std::make_tuple(1, 399, 2),
+                                                                    std::make_tuple(1, 1, 79),
+                                                                    std::make_tuple(0, 0, 0),
+                                                                    std::make_tuple(100, 300, 1),
+                                                                    std::make_tuple(300, 100, 2),
+                                                                    std::make_tuple(0, 0, 0),
+                                                                    std::make_tuple(300, 300, 1),
+                                                                    std::make_tuple(500, 100, 2),
+                                                                    std::make_tuple(0, 0, 0),
+                                                                    std::make_tuple(500, 300, 1),
+                                                                    std::make_tuple(700, 100, 2),
+                                                                    std::make_tuple(0, 0, 0),
+                                                                    std::make_tuple(700, 300, 1),
+                                                                    std::make_tuple(900, 100, 2),
+                                                                    std::make_tuple(0, 0, 0),
+                                                                    std::make_tuple(900, 300, 1),
+                                                                    std::make_tuple(1100, 100, 2)};
+
+        REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin()));
+    }
+
+    SECTION("SVG <polyline>")
+    {
+        //
+        std::string svg_name("./test/data/svg/polyline.svg");
+        std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
+        REQUIRE(marker);
+        REQUIRE(marker->is<mapnik::marker_svg>());
+        mapnik::marker_svg const& svg = mapnik::util::get<mapnik::marker_svg>(*marker);
+        auto bbox = svg.bounding_box();
+        REQUIRE(bbox == mapnik::box2d<double>(1.0,1.0,1199.0,399.0));
+        auto storage = svg.get_data();
+        REQUIRE(storage);
+        mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(storage->source());
+        mapnik::svg::svg_path_adapter path(stl_storage);
+        double x,y;
+        unsigned cmd;
+        std::vector<std::tuple<double,double,unsigned>> vec;
+        std::size_t num_vertices = path.total_vertices();
+        for (std::size_t i = 0; i < num_vertices; ++i)
+        {
+            cmd = path.vertex(&x,&y);
+            vec.emplace_back(x, y, cmd);
+        }
+
+        std::vector<std::tuple<double,double,unsigned>> expected = {std::make_tuple(1, 1, 1),
+                                                                    std::make_tuple(1199, 1, 2),
+                                                                    std::make_tuple(1199, 399, 2),
+                                                                    std::make_tuple(1, 399, 2),
+                                                                    std::make_tuple(1, 1, 79),
+                                                                    std::make_tuple(0, 0, 0),
+                                                                    std::make_tuple(50, 375, 1),
+                                                                    std::make_tuple(150, 375, 2),
+                                                                    std::make_tuple(150, 325, 2),
+                                                                    std::make_tuple(250, 325, 2),
+                                                                    std::make_tuple(250, 375, 2),
+                                                                    std::make_tuple(350, 375, 2),
+                                                                    std::make_tuple(350, 250, 2),
+                                                                    std::make_tuple(450, 250, 2),
+                                                                    std::make_tuple(450, 375, 2),
+                                                                    std::make_tuple(550, 375, 2),
+                                                                    std::make_tuple(550, 175, 2),
+                                                                    std::make_tuple(650, 175, 2),
+                                                                    std::make_tuple(650, 375, 2),
+                                                                    std::make_tuple(750, 375, 2),
+                                                                    std::make_tuple(750, 100, 2),
+                                                                    std::make_tuple(850, 100, 2),
+                                                                    std::make_tuple(850, 375, 2),
+                                                                    std::make_tuple(950, 375, 2),
+                                                                    std::make_tuple(950, 25, 2),
+                                                                    std::make_tuple(1050, 25, 2),
+                                                                    std::make_tuple(1050, 375, 2),
+                                                                    std::make_tuple(1150, 375, 2)};
+
+        REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin()));
+    }
+
+    SECTION("SVG <polygon>")
+    {
+        //
+        std::string svg_name("./test/data/svg/polygon.svg");
+        std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
+        REQUIRE(marker);
+        REQUIRE(marker->is<mapnik::marker_svg>());
+        mapnik::marker_svg const& svg = mapnik::util::get<mapnik::marker_svg>(*marker);
+        auto bbox = svg.bounding_box();
+        REQUIRE(bbox == mapnik::box2d<double>(1.0,1.0,1199.0,399.0));
+        auto storage = svg.get_data();
+        REQUIRE(storage);
+        mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(storage->source());
+        mapnik::svg::svg_path_adapter path(stl_storage);
+        double x,y;
+        unsigned cmd;
+        std::vector<std::tuple<double,double,unsigned>> vec;
+        std::size_t num_vertices = path.total_vertices();
+        for (std::size_t i = 0; i < num_vertices; ++i)
+        {
+            cmd = path.vertex(&x,&y);
+            vec.emplace_back(x, y, cmd);
+        }
+
+        std::vector<std::tuple<double,double,unsigned>> expected = {std::make_tuple(1, 1, 1),
+                                                                    std::make_tuple(1199, 1, 2),
+                                                                    std::make_tuple(1199, 399, 2),
+                                                                    std::make_tuple(1, 399, 2),
+                                                                    std::make_tuple(1, 1, 79),
+                                                                    std::make_tuple(0, 0, 0),
+                                                                    std::make_tuple(350, 75, 1),
+                                                                    std::make_tuple(379, 161, 2),
+                                                                    std::make_tuple(469, 161, 2),
+                                                                    std::make_tuple(397, 215, 2),
+                                                                    std::make_tuple(423, 301, 2),
+                                                                    std::make_tuple(350, 250, 2),
+                                                                    std::make_tuple(277, 301, 2),
+                                                                    std::make_tuple(303, 215, 2),
+                                                                    std::make_tuple(231, 161, 2),
+                                                                    std::make_tuple(321, 161, 2),
+                                                                    std::make_tuple(350, 75, 79),
+                                                                    std::make_tuple(0, 0, 0),
+                                                                    std::make_tuple(850, 75, 1),
+                                                                    std::make_tuple(958, 137.5, 2),
+                                                                    std::make_tuple(958, 262.5, 2),
+                                                                    std::make_tuple(850, 325, 2),
+                                                                    std::make_tuple(742, 262.6, 2),
+                                                                    std::make_tuple(742, 137.5, 2),
+                                                                    std::make_tuple(850, 75, 79)};
+
+        REQUIRE(std::equal(expected.begin(),expected.end(), vec.begin()));
+    }
+
+    xmlCleanupParser();
+}
diff --git a/test/unit/text/shaping.cpp b/test/unit/text/shaping.cpp
new file mode 100644
index 0000000..2e2701b
--- /dev/null
+++ b/test/unit/text/shaping.cpp
@@ -0,0 +1,24 @@
+#include "catch.hpp"
+#include <mapnik/text/icu_shaper.hpp>
+#include <mapnik/text/harfbuzz_shaper.hpp>
+#include <mapnik/text/font_library.hpp>
+
+TEST_CASE("shapers compile") {
+
+    mapnik::text_line line(0,0);
+    mapnik::text_itemizer itemizer;
+    std::map<unsigned,double> width_map;
+    double scale_factor = 1;
+    mapnik::font_library fl;
+    mapnik::freetype_engine::font_file_mapping_type font_file_mapping;
+    mapnik::freetype_engine::font_memory_cache_type font_memory_cache;
+    mapnik::face_manager fm(fl,font_file_mapping,font_memory_cache);
+    mapnik::harfbuzz_shaper::shape_text(line,itemizer,
+                                width_map,
+                                fm,
+                                scale_factor);
+    mapnik::icu_shaper::shape_text(line,itemizer,
+                                width_map,
+                                fm,
+                                scale_factor);
+}
\ No newline at end of file
diff --git a/test/visual/report.cpp b/test/visual/report.cpp
index 105ba06..deaf5b9 100644
--- a/test/visual/report.cpp
+++ b/test/visual/report.cpp
@@ -24,6 +24,7 @@
 #include <iomanip>
 #include <fstream>
 #include <numeric>
+#include <map>
 
 #include "report.hpp"
 
@@ -70,6 +71,10 @@ unsigned console_report::summary(result_list const & results)
     unsigned fail = 0;
     unsigned overwrite = 0;
 
+    using namespace std::chrono;
+    using duration_map_type = std::map<std::string, high_resolution_clock::duration>;
+    duration_map_type durations;
+
     for (auto const & r : results)
     {
         switch (r.state)
@@ -79,12 +84,37 @@ unsigned console_report::summary(result_list const & results)
             case STATE_ERROR: error++; break;
             case STATE_OVERWRITE: overwrite++; break;
         }
+
+        if (show_duration)
+        {
+            duration_map_type::iterator duration = durations.find(r.renderer_name);
+            if (duration == durations.end())
+            {
+                durations.emplace(r.renderer_name, r.duration);
+            }
+            else
+            {
+                duration->second += r.duration;
+            }
+        }
     }
 
     s << std::endl;
     s << "Visual rendering: " << fail << " failed / " << ok << " passed / "
         << overwrite << " overwritten / " << error << " errors" << std::endl;
 
+    if (show_duration)
+    {
+        high_resolution_clock::duration total(0);
+        for (auto const & duration : durations)
+        {
+            s << duration.first << ": \t" << duration_cast<milliseconds>(duration.second).count()
+              << " milliseconds" << std::endl;
+            total += duration.second;
+        }
+        s << "total: \t" << duration_cast<milliseconds>(total).count() << " milliseconds" << std::endl;
+    }
+
     return fail + error;
 }
 
diff --git a/test/visual/report.hpp b/test/visual/report.hpp
index 1a7a3c4..837ed5e 100644
--- a/test/visual/report.hpp
+++ b/test/visual/report.hpp
@@ -55,7 +55,7 @@ protected:
 class console_short_report : public console_report
 {
 public:
-    console_short_report() : console_report(false)
+    console_short_report(bool _show_duration) : console_report(_show_duration)
     {
     }
 
diff --git a/test/visual/run.cpp b/test/visual/run.cpp
index 4444869..62ca73b 100644
--- a/test/visual/run.cpp
+++ b/test/visual/run.cpp
@@ -113,8 +113,7 @@ int main(int argc, char** argv)
                vm["iterations"].as<std::size_t>(),
                vm["jobs"].as<std::size_t>());
     bool show_duration = vm.count("duration");
-    bool verbose = vm.count("verbose") | show_duration;
-    report_type report(verbose ? report_type((console_report(show_duration))) : report_type((console_short_report())));
+    report_type report(vm.count("verbose") ? report_type((console_report(show_duration))) : report_type((console_short_report(show_duration))));
     result_list results;
 
     try
diff --git a/utils/svg2png/svg2png.cpp b/utils/svg2png/svg2png.cpp
index 7e3aca5..21041b2 100644
--- a/utils/svg2png/svg2png.cpp
+++ b/utils/svg2png/svg2png.cpp
@@ -52,28 +52,26 @@
 
 struct main_marker_visitor
 {
-    main_marker_visitor(std::string & svg_name,
-                        int & return_value,
+    main_marker_visitor(std::string const& svg_name,
                         bool verbose,
                         bool auto_open)
         : svg_name_(svg_name),
-          return_value_(return_value),
           verbose_(verbose),
           auto_open_(auto_open) {}
 
-    void operator() (mapnik::marker_null const&)
+    int operator() (mapnik::marker_null const&)
     {
         std::clog << "svg2png error: '" << svg_name_ << "' is not a valid vector!\n";
-        return_value_ = -1;
+        return -1;
     }
 
-    void operator() (mapnik::marker_rgba8 const&)
+    int operator() (mapnik::marker_rgba8 const&)
     {
         std::clog << "svg2png error: '" << svg_name_ << "' is not a valid vector!\n";
-        return_value_ = -1;
+        return  -1;
     }
 
-    void operator() (mapnik::marker_svg const& marker)
+    int operator() (mapnik::marker_svg const& marker)
     {
         using pixfmt = agg::pixfmt_rgba32_pre;
         using renderer_base = agg::renderer_base<pixfmt>;
@@ -111,28 +109,29 @@ struct main_marker_visitor
 
         svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox);
 
-        boost::algorithm::ireplace_last(svg_name_,".svg",".png");
+        std::string png_name(svg_name_);
+        boost::algorithm::ireplace_last(png_name,".svg",".png");
         demultiply_alpha(im);
-        mapnik::save_to_file<mapnik::image_rgba8>(im,svg_name_,"png");
+        mapnik::save_to_file<mapnik::image_rgba8>(im,png_name,"png");
+        int status = 0;
         if (auto_open_)
         {
             std::ostringstream s;
 #ifdef DARWIN
-            s << "open " << svg_name_;
+            s << "open " << png_name;
 #else
-            s << "xdg-open " << svg_name_;
+            s << "xdg-open " << png_name;
 #endif
             int ret = system(s.str().c_str());
             if (ret != 0)
-                return_value_ = ret;
+                status = ret;
         }
-        std::clog << "rendered to: " << svg_name_ << "\n";
-
+        std::clog << "rendered to: " << png_name << "\n";
+        return status;
     }
 
   private:
-    std::string & svg_name_;
-    int & return_value_;
+    std::string const& svg_name_;
     bool verbose_;
     bool auto_open_;
 };
@@ -143,7 +142,7 @@ int main (int argc,char** argv)
 
     bool verbose = false;
     bool auto_open = false;
-    int return_value = 0;
+    int status = 0;
     std::vector<std::string> svg_files;
     mapnik::logger::instance().set_severity(mapnik::logger::error);
 
@@ -214,8 +213,8 @@ int main (int argc,char** argv)
             }
 
             std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false);
-            main_marker_visitor visitor(svg_name, return_value, verbose, auto_open);
-            mapnik::util::apply_visitor(visitor, *marker);
+            main_marker_visitor visitor(svg_name, verbose, auto_open);
+            status = mapnik::util::apply_visitor(visitor, *marker);
         }
     }
     catch (...)
@@ -229,5 +228,5 @@ int main (int argc,char** argv)
     // to make sure valgrind output is clean
     // http://xmlsoft.org/xmlmem.html
     xmlCleanupParser();
-    return return_value;
+    return status;
 }

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



More information about the Pkg-grass-devel mailing list