refactor spirit grammars

This commit is contained in:
Dane Springmeyer 2014-07-24 14:31:59 -07:00
parent 11b0816d2a
commit c5be70ff65
62 changed files with 976 additions and 1394 deletions

View file

@ -6,6 +6,7 @@
#include <mapnik/ctrans.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/wkt/wkt_grammar_impl.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/proj_transform.hpp>

View file

@ -30,7 +30,6 @@
#include <boost/python.hpp>
#include <boost/noncopyable.hpp>
// mapnik
#include <mapnik/value_types.hpp>
#include <mapnik/feature.hpp>
@ -40,8 +39,7 @@
#include <mapnik/wkb.hpp>
#include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/json/feature_parser.hpp>
#include <mapnik/json/geojson_generator.hpp>
#include <mapnik/json/generic_json.hpp>
#include <mapnik/json/feature_generator.hpp>
// stl
#include <stdexcept>
@ -49,7 +47,6 @@
namespace {
using mapnik::geometry_utils;
using mapnik::from_wkt;
using mapnik::context_type;
using mapnik::context_ptr;
using mapnik::feature_kv_iterator;
@ -57,13 +54,13 @@ using mapnik::feature_kv_iterator;
mapnik::geometry_type const& (mapnik::feature_impl::*get_geometry_by_const_ref)(std::size_t) const = &mapnik::feature_impl::get_geometry;
boost::ptr_vector<mapnik::geometry_type> const& (mapnik::feature_impl::*get_paths_by_const_ref)() const = &mapnik::feature_impl::paths;
void feature_add_geometries_from_wkb(mapnik::feature_impl &feature, std::string wkb)
void feature_add_geometries_from_wkb(mapnik::feature_impl & feature, std::string wkb)
{
bool result = geometry_utils::from_wkb(feature.paths(), wkb.c_str(), wkb.size());
if (!result) throw std::runtime_error("Failed to parse WKB");
}
void feature_add_geometries_from_wkt(mapnik::feature_impl &feature, std::string wkt)
void feature_add_geometries_from_wkt(mapnik::feature_impl & feature, std::string const& wkt)
{
bool result = mapnik::from_wkt(wkt, feature.paths());
if (!result) throw std::runtime_error("Failed to parse WKT");
@ -71,11 +68,8 @@ void feature_add_geometries_from_wkt(mapnik::feature_impl &feature, std::string
mapnik::feature_ptr from_geojson_impl(std::string const& json, mapnik::context_ptr const& ctx)
{
mapnik::transcoder tr("utf8");
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1));
mapnik::json::generic_json<std::string::const_iterator> json_base;
mapnik::json::feature_parser<std::string::const_iterator> parser(json_base, tr);
if (!parser.parse(json.begin(), json.end(), *feature))
if (!mapnik::json::from_geojson(json,*feature))
{
throw std::runtime_error("Failed to parse geojson feature");
}
@ -85,8 +79,7 @@ mapnik::feature_ptr from_geojson_impl(std::string const& json, mapnik::context_p
std::string feature_to_geojson(mapnik::feature_impl const& feature)
{
std::string json;
mapnik::json::feature_generator g;
if (!g.generate(json,feature))
if (!mapnik::json::to_geojson(json,feature))
{
throw std::runtime_error("Failed to generate GeoJSON");
}

View file

@ -28,31 +28,24 @@
#include <boost/python/iterator.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/noncopyable.hpp>
#include <boost/version.hpp>
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/json/geometry_parser.hpp>
#include <mapnik/json/geojson_generator.hpp>
#include <boost/version.hpp>
#include <mapnik/util/geometry_to_wkb.hpp>
#include <mapnik/wkt/wkt_factory.hpp> // from_wkt
#include <mapnik/util/geometry_to_wkt.hpp>
#include <mapnik/json/geometry_parser.hpp> // from_geojson
#include <mapnik/util/geometry_to_geojson.hpp>
#include <mapnik/util/geometry_to_svg.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/util/geometry_to_wkb.hpp>
// stl
#include <stdexcept>
namespace {
using mapnik::from_wkt;
using mapnik::geometry_type;
using path_type = boost::ptr_vector<geometry_type>;
geometry_type const& getitem_impl(path_type & p, int key)
mapnik::geometry_type const& getitem_impl(mapnik::geometry_container & p, int key)
{
if (key >=0 && key < static_cast<int>(p.size()))
return p[key];
@ -60,49 +53,49 @@ geometry_type const& getitem_impl(path_type & p, int key)
throw boost::python::error_already_set();
}
void add_wkt_impl(path_type& p, std::string const& wkt)
void add_wkt_impl(mapnik::geometry_container& p, std::string const& wkt)
{
if (!mapnik::from_wkt(wkt , p))
throw std::runtime_error("Failed to parse WKT");
}
void add_wkb_impl(path_type& p, std::string const& wkb)
void add_wkb_impl(mapnik::geometry_container& p, std::string const& wkb)
{
if (!mapnik::geometry_utils::from_wkb(p, wkb.c_str(), wkb.size()))
throw std::runtime_error("Failed to parse WKB");
}
void add_geojson_impl(path_type& p, std::string const& json)
void add_geojson_impl(mapnik::geometry_container& paths, std::string const& json)
{
if (!mapnik::json::from_geojson(json, p))
if (!mapnik::json::from_geojson(json, paths))
throw std::runtime_error("Failed to parse geojson geometry");
}
std::shared_ptr<path_type> from_wkt_impl(std::string const& wkt)
std::shared_ptr<mapnik::geometry_container> from_wkt_impl(std::string const& wkt)
{
std::shared_ptr<path_type> paths = std::make_shared<path_type>();
std::shared_ptr<mapnik::geometry_container> paths = std::make_shared<mapnik::geometry_container>();
if (!mapnik::from_wkt(wkt, *paths))
throw std::runtime_error("Failed to parse WKT");
return paths;
}
std::shared_ptr<path_type> from_wkb_impl(std::string const& wkb)
std::shared_ptr<mapnik::geometry_container> from_wkb_impl(std::string const& wkb)
{
std::shared_ptr<path_type> paths = std::make_shared<path_type>();
std::shared_ptr<mapnik::geometry_container> paths = std::make_shared<mapnik::geometry_container>();
if (!mapnik::geometry_utils::from_wkb(*paths, wkb.c_str(), wkb.size()))
throw std::runtime_error("Failed to parse WKB");
return paths;
}
std::shared_ptr<path_type> from_geojson_impl(std::string const& json)
std::shared_ptr<mapnik::geometry_container> from_geojson_impl(std::string const& json)
{
std::shared_ptr<path_type> paths = std::make_shared<path_type>();
if (! mapnik::json::from_geojson(json, *paths))
std::shared_ptr<mapnik::geometry_container> paths = std::make_shared<mapnik::geometry_container>();
if (!mapnik::json::from_geojson(json, *paths))
throw std::runtime_error("Failed to parse geojson geometry");
return paths;
}
mapnik::box2d<double> envelope_impl(path_type & p)
mapnik::box2d<double> envelope_impl(mapnik::geometry_container & p)
{
mapnik::box2d<double> b;
bool first = true;
@ -130,7 +123,7 @@ inline std::string boost_version()
return s.str();
}
PyObject* to_wkb( geometry_type const& geom, mapnik::util::wkbByteOrder byte_order)
PyObject* to_wkb(mapnik::geometry_type const& geom, mapnik::util::wkbByteOrder byte_order)
{
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,byte_order);
if (wkb)
@ -149,7 +142,7 @@ PyObject* to_wkb( geometry_type const& geom, mapnik::util::wkbByteOrder byte_ord
}
}
PyObject* to_wkb2( path_type const& p, mapnik::util::wkbByteOrder byte_order)
PyObject* to_wkb2( mapnik::geometry_container const& p, mapnik::util::wkbByteOrder byte_order)
{
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(p,byte_order);
if (wkb)
@ -168,44 +161,50 @@ PyObject* to_wkb2( path_type const& p, mapnik::util::wkbByteOrder byte_order)
}
}
std::string to_wkt( geometry_type const& geom)
std::string to_wkt(mapnik::geometry_type const& geom)
{
std::string wkt; // Use Python String directly ?
bool result = mapnik::util::to_wkt(wkt,geom);
if (!result)
std::string wkt;
if (!mapnik::util::to_wkt(wkt,geom))
{
throw std::runtime_error("Generate WKT failed");
}
return wkt;
}
std::string to_wkt2( path_type const& geom)
std::string to_wkt2(mapnik::geometry_container const& geom)
{
std::string wkt; // Use Python String directly ?
bool result = mapnik::util::to_wkt(wkt,geom);
if (!result)
std::string wkt;
if (!mapnik::util::to_wkt(wkt,geom))
{
throw std::runtime_error("Generate WKT failed");
}
return wkt;
}
std::string to_geojson( path_type const& geom)
std::string to_geojson(mapnik::geometry_type const& geom)
{
std::string json;
mapnik::json::geometry_generator g;
if (!g.generate(json,geom))
std::string wkt;
if (!mapnik::util::to_geojson(wkt,geom))
{
throw std::runtime_error("Failed to generate GeoJSON");
throw std::runtime_error("Generate JSON failed");
}
return json;
return wkt;
}
std::string to_svg( geometry_type const& geom)
std::string to_geojson2(mapnik::geometry_container const& geom)
{
std::string svg; // Use Python String directly ?
bool result = mapnik::util::to_svg(svg,geom);
if (!result)
std::string wkt;
if (!mapnik::util::to_geojson(wkt,geom))
{
throw std::runtime_error("Generate JSON failed");
}
return wkt;
}
std::string to_svg(mapnik::geometry_type const& geom)
{
std::string svg;
if (!mapnik::util::to_svg(svg,geom))
{
throw std::runtime_error("Generate SVG failed");
}
@ -214,7 +213,7 @@ std::string to_svg( geometry_type const& geom)
/*
// https://github.com/mapnik/mapnik/issues/1437
std::string to_svg2( path_type const& geom)
std::string to_svg2( mapnik::geometry_container const& geom)
{
std::string svg; // Use Python String directly ?
bool result = mapnik::util::to_svg(svg,geom);
@ -242,19 +241,20 @@ void export_geometry()
;
using mapnik::geometry_type;
class_<geometry_type, std::shared_ptr<geometry_type>, boost::noncopyable>("Geometry2d",no_init)
.def("envelope",&geometry_type::envelope)
// .def("__str__",&geometry_type::to_string)
.def("type",&geometry_type::type)
class_<mapnik::geometry_type, std::shared_ptr<mapnik::geometry_type>, boost::noncopyable>("Geometry2d",no_init)
.def("envelope",&mapnik::geometry_type::envelope)
// .def("__str__",&mapnik::geometry_type::to_string)
.def("type",&mapnik::geometry_type::type)
.def("to_wkb",&to_wkb)
.def("to_wkt",&to_wkt)
.def("to_geojson",&to_geojson)
.def("to_svg",&to_svg)
// TODO add other geometry_type methods
;
class_<path_type, std::shared_ptr<path_type>, boost::noncopyable>("Path")
class_<mapnik::geometry_container, std::shared_ptr<mapnik::geometry_container>, boost::noncopyable>("Path")
.def("__getitem__", getitem_impl,return_value_policy<reference_existing_object>())
.def("__len__", &path_type::size)
.def("__len__", &mapnik::geometry_container::size)
.def("envelope",envelope_impl)
.def("add_wkt",add_wkt_impl)
.def("add_wkb",add_wkb_impl)
@ -265,7 +265,7 @@ void export_geometry()
.def("from_wkt",from_wkt_impl)
.def("from_wkb",from_wkb_impl)
.def("from_geojson",from_geojson_impl)
.def("to_geojson",to_geojson)
.def("to_geojson",&to_geojson2)
.staticmethod("from_wkt")
.staticmethod("from_wkb")
.staticmethod("from_geojson")

View file

@ -84,7 +84,6 @@ void export_view_transform();
void export_raster_colorizer();
void export_label_collision_detector();
void export_logger();
void export_wkt_reader();
#include <mapnik/version.hpp>
#include <mapnik/map.hpp>
@ -601,7 +600,6 @@ BOOST_PYTHON_MODULE(_mapnik)
export_raster_colorizer();
export_label_collision_detector();
export_logger();
export_wkt_reader();
def("clear_cache", &clear_cache,
"\n"

View file

@ -1,56 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2013 Artem Pavlenko, Jean-Francois Doyon
*
* 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 "boost_std_shared_shim.hpp"
// boost
#include <boost/python.hpp>
#include <boost/noncopyable.hpp>
#include <memory>
#include <boost/ptr_container/ptr_vector.hpp>
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_factory.hpp>
namespace impl {
using path_type = boost::ptr_vector<mapnik::geometry_type>;
std::shared_ptr<path_type> from_wkt(mapnik::wkt_parser & p, std::string const& wkt)
{
std::shared_ptr<path_type> paths = std::make_shared<path_type>();
if (!p.parse(wkt, *paths))
throw std::runtime_error("Failed to parse WKT");
return paths;
}
}
void export_wkt_reader()
{
using mapnik::wkt_parser;
using namespace boost::python;
class_<wkt_parser, boost::noncopyable>("WKTReader",init<>())
.def("read",&impl::from_wkt)
;
}

View file

@ -62,7 +62,158 @@ using ascii_space_type = boost::spirit::ascii::space_type;
struct named_colors_ : qi::symbols<char,color>
{
named_colors_();
named_colors_()
{
add
("aliceblue", color(240, 248, 255))
("antiquewhite", color(250, 235, 215))
("aqua", color(0, 255, 255))
("aquamarine", color(127, 255, 212))
("azure", color(240, 255, 255))
("beige", color(245, 245, 220))
("bisque", color(255, 228, 196))
("black", color(0, 0, 0))
("blanchedalmond", color(255,235,205))
("blue", color(0, 0, 255))
("blueviolet", color(138, 43, 226))
("brown", color(165, 42, 42))
("burlywood", color(222, 184, 135))
("cadetblue", color(95, 158, 160))
("chartreuse", color(127, 255, 0))
("chocolate", color(210, 105, 30))
("coral", color(255, 127, 80))
("cornflowerblue", color(100, 149, 237))
("cornsilk", color(255, 248, 220))
("crimson", color(220, 20, 60))
("cyan", color(0, 255, 255))
("darkblue", color(0, 0, 139))
("darkcyan", color(0, 139, 139))
("darkgoldenrod", color(184, 134, 11))
("darkgray", color(169, 169, 169))
("darkgreen", color(0, 100, 0))
("darkgrey", color(169, 169, 169))
("darkkhaki", color(189, 183, 107))
("darkmagenta", color(139, 0, 139))
("darkolivegreen", color(85, 107, 47))
("darkorange", color(255, 140, 0))
("darkorchid", color(153, 50, 204))
("darkred", color(139, 0, 0))
("darksalmon", color(233, 150, 122))
("darkseagreen", color(143, 188, 143))
("darkslateblue", color(72, 61, 139))
("darkslategrey", color(47, 79, 79))
("darkturquoise", color(0, 206, 209))
("darkviolet", color(148, 0, 211))
("deeppink", color(255, 20, 147))
("deepskyblue", color(0, 191, 255))
("dimgray", color(105, 105, 105))
("dimgrey", color(105, 105, 105))
("dodgerblue", color(30, 144, 255))
("firebrick", color(178, 34, 34))
("floralwhite", color(255, 250, 240))
("forestgreen", color(34, 139, 34))
("fuchsia", color(255, 0, 255))
("gainsboro", color(220, 220, 220))
("ghostwhite", color(248, 248, 255))
("gold", color(255, 215, 0))
("goldenrod", color(218, 165, 32))
("gray", color(128, 128, 128))
("grey", color(128, 128, 128))
("green", color(0, 128, 0))
("greenyellow", color(173, 255, 47))
("honeydew", color(240, 255, 240))
("hotpink", color(255, 105, 180))
("indianred", color(205, 92, 92))
("indigo", color(75, 0, 130))
("ivory", color(255, 255, 240))
("khaki", color(240, 230, 140))
("lavender", color(230, 230, 250))
("lavenderblush", color(255, 240, 245))
("lawngreen", color(124, 252, 0))
("lemonchiffon", color(255, 250, 205))
("lightblue", color(173, 216, 230))
("lightcoral", color(240, 128, 128))
("lightcyan", color(224, 255, 255))
("lightgoldenrodyellow", color(250, 250, 210))
("lightgray", color(211, 211, 211))
("lightgreen", color(144, 238, 144))
("lightgrey", color(211, 211, 211))
("lightpink", color(255, 182, 193))
("lightsalmon", color(255, 160, 122))
("lightseagreen", color(32, 178, 170))
("lightskyblue", color(135, 206, 250))
("lightslategray", color(119, 136, 153))
("lightslategrey", color(119, 136, 153))
("lightsteelblue", color(176, 196, 222))
("lightyellow", color(255, 255, 224))
("lime", color(0, 255, 0))
("limegreen", color(50, 205, 50))
("linen", color(250, 240, 230))
("magenta", color(255, 0, 255))
("maroon", color(128, 0, 0))
("mediumaquamarine", color(102, 205, 170))
("mediumblue", color(0, 0, 205))
("mediumorchid", color(186, 85, 211))
("mediumpurple", color(147, 112, 219))
("mediumseagreen", color(60, 179, 113))
("mediumslateblue", color(123, 104, 238))
("mediumspringgreen", color(0, 250, 154))
("mediumturquoise", color(72, 209, 204))
("mediumvioletred", color(199, 21, 133))
("midnightblue", color(25, 25, 112))
("mintcream", color(245, 255, 250))
("mistyrose", color(255, 228, 225))
("moccasin", color(255, 228, 181))
("navajowhite", color(255, 222, 173))
("navy", color(0, 0, 128))
("oldlace", color(253, 245, 230))
("olive", color(128, 128, 0))
("olivedrab", color(107, 142, 35))
("orange", color(255, 165, 0))
("orangered", color(255, 69, 0))
("orchid", color(218, 112, 214))
("palegoldenrod", color(238, 232, 170))
("palegreen", color(152, 251, 152))
("paleturquoise", color(175, 238, 238))
("palevioletred", color(219, 112, 147))
("papayawhip", color(255, 239, 213))
("peachpuff", color(255, 218, 185))
("peru", color(205, 133, 63))
("pink", color(255, 192, 203))
("plum", color(221, 160, 221))
("powderblue", color(176, 224, 230))
("purple", color(128, 0, 128))
("red", color(255, 0, 0))
("rosybrown", color(188, 143, 143))
("royalblue", color(65, 105, 225))
("saddlebrown", color(139, 69, 19))
("salmon", color(250, 128, 114))
("sandybrown", color(244, 164, 96))
("seagreen", color(46, 139, 87))
("seashell", color(255, 245, 238))
("sienna", color(160, 82, 45))
("silver", color(192, 192, 192))
("skyblue", color(135, 206, 235))
("slateblue", color(106, 90, 205))
("slategray", color(112, 128, 144))
("slategrey", color(112, 128, 144))
("snow", color(255, 250, 250))
("springgreen", color(0, 255, 127))
("steelblue", color(70, 130, 180))
("tan", color(210, 180, 140))
("teal", color(0, 128, 128))
("thistle", color(216, 191, 216))
("tomato", color(255, 99, 71))
("turquoise", color(64, 224, 208))
("violet", color(238, 130, 238))
("wheat", color(245, 222, 179))
("white", color(255, 255, 255))
("whitesmoke", color(245, 245, 245))
("yellow", color(255, 255, 0))
("yellowgreen", color(154, 205, 50))
("transparent", color(0, 0, 0, 0))
;
}
} ;
// clipper helper

View file

@ -32,9 +32,6 @@
#include <mapnik/feature_kv_iterator.hpp>
#include <mapnik/noncopyable.hpp>
// boost
#include <boost/ptr_container/ptr_vector.hpp>
// stl
#include <memory>
#include <vector>
@ -196,12 +193,12 @@ public:
return ctx_;
}
inline boost::ptr_vector<geometry_type> const& paths() const
inline geometry_container const& paths() const
{
return geom_cont_;
}
inline boost::ptr_vector<geometry_type> & paths()
inline geometry_container & paths()
{
return geom_cont_;
}
@ -294,7 +291,7 @@ private:
mapnik::value_integer id_;
context_ptr ctx_;
cont_type data_;
boost::ptr_vector<geometry_type> geom_cont_;
geometry_container geom_cont_;
raster_ptr raster_;
};

View file

@ -126,6 +126,4 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
no_args = -(lit('(') >> lit(')'));
}
template struct mapnik::image_filter_grammar<std::string::const_iterator,std::vector<mapnik::filter::filter_type> >;
}

View file

@ -59,9 +59,9 @@ template <typename Iterator, typename FeatureType>
struct feature_collection_grammar :
qi::grammar<Iterator, std::vector<feature_ptr>(), space_type>
{
feature_collection_grammar( generic_json<Iterator> & json, context_ptr const& ctx, mapnik::transcoder const& tr)
feature_collection_grammar(context_ptr const& ctx, mapnik::transcoder const& tr)
: feature_collection_grammar::base_type(start,"start"),
feature_g(json,tr),
feature_g(tr),
ctx_(ctx),
generate_id_(1)
{
@ -81,7 +81,7 @@ struct feature_collection_grammar :
start = feature_collection | feature_from_geometry(_val) | feature(_val)
;
feature_collection = lit('{') >> (type | features | json.key_value) % lit(',') >> lit('}')
feature_collection = lit('{') >> (type | features | feature_g.json_.key_value) % lit(',') >> lit('}')
;
type = lit("\"type\"") >> lit(':') >> lit("\"FeatureCollection\"")

View file

@ -1,55 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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 MAPNIK_FEATURE_COLLECTION_PARSER_HPP
#define MAPNIK_FEATURE_COLLECTION_PARSER_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/noncopyable.hpp>
#include <mapnik/unicode.hpp>
// stl
#include <vector>
namespace mapnik { namespace json {
template <typename Iterator, typename FeatureType> struct feature_collection_grammar;
template <typename Iterator> struct generic_json;
template <typename Iterator>
class MAPNIK_DECL feature_collection_parser : private mapnik::noncopyable
{
using iterator_type = Iterator;
using feature_type = mapnik::feature_impl;
public:
feature_collection_parser(generic_json<Iterator> & json, mapnik::context_ptr const& ctx, mapnik::transcoder const& tr);
~feature_collection_parser();
bool parse(iterator_type first, iterator_type last, std::vector<mapnik::feature_ptr> & features);
private:
const std::unique_ptr<feature_collection_grammar<iterator_type,feature_type> > grammar_;
};
}}
#endif //MAPNIK_FEATURE_COLLECTION_PARSER_HPP

View file

@ -20,13 +20,26 @@
*
*****************************************************************************/
#ifndef MAPNIK_JSON_FEATURE_GENERATOR_HPP
#define MAPNIK_JSON_FEATURE_GENERATOR_HPP
// mapnik
#include <mapnik/expression_grammar_impl.hpp>
// stl
#include <string>
#include <mapnik/feature.hpp>
#include <mapnik/json/feature_generator_grammar.hpp>
namespace mapnik {
// boost
#include <boost/spirit/include/karma.hpp>
template struct mapnik::expression_grammar<std::string::const_iterator>;
namespace mapnik { namespace json {
inline bool to_geojson(std::string & json, mapnik::feature_impl const& feature)
{
using sink_type = std::back_insert_iterator<std::string>;
static const mapnik::json::feature_generator_grammar<sink_type> grammar;
sink_type sink(json);
return boost::spirit::karma::generate(sink, grammar, feature);
}
}}
#endif // MAPNIK_JSON_FEATURE_GENERATOR_HPP

View file

@ -24,7 +24,6 @@
#define MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/value.hpp>
#include <mapnik/feature.hpp>
@ -34,10 +33,10 @@
// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/cons.hpp>
@ -89,7 +88,6 @@ struct transform_attribute<const boost::fusion::cons<mapnik::feature_impl const&
namespace mapnik { namespace json {
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
struct get_id
{
@ -115,7 +113,6 @@ struct make_properties_range
}
};
struct utf8
{
template <typename T>
@ -144,36 +141,9 @@ template <typename OutputIterator>
struct escaped_string
: karma::grammar<OutputIterator, std::string(char const*)>
{
escaped_string()
: escaped_string::base_type(esc_str)
{
karma::lit_type lit;
karma::_r1_type _r1;
karma::hex_type hex;
karma::right_align_type right_align;
karma::print_type kprint;
esc_char.add
('"', "\\\"")
('\\', "\\\\")
('\b', "\\b")
('\f', "\\f")
('\n', "\\n")
('\r', "\\r")
('\t', "\\t")
;
esc_str = lit(_r1)
<< *(esc_char
| kprint
| "\\u" << right_align(4,lit('0'))[hex])
<< lit(_r1)
;
}
escaped_string();
karma::rule<OutputIterator, std::string(char const*)> esc_str;
karma::symbols<char, char const*> esc_char;
};
template <typename OutputIterator>
@ -183,50 +153,7 @@ struct feature_generator_grammar:
using pair_type = std::tuple<std::string, mapnik::value>;
using range_type = make_properties_range::properties_range_type;
feature_generator_grammar()
: feature_generator_grammar::base_type(feature)
, quote_("\"")
{
boost::spirit::karma::lit_type lit;
boost::spirit::karma::uint_type uint_;
boost::spirit::karma::bool_type bool_;
boost::spirit::karma::double_type double_;
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::_r1_type _r1;
boost::spirit::karma::string_type kstring;
boost::spirit::karma::eps_type eps;
feature = lit("{\"type\":\"Feature\",\"id\":")
<< uint_[_1 = id_(_val)]
<< lit(",\"geometry\":") << geometry
<< lit(",\"properties\":") << properties
<< lit('}')
;
properties = lit('{')
<< -(pair % lit(','))
<< lit('}')
;
pair = lit('"')
<< kstring[_1 = phoenix::at_c<0>(_val)] << lit('"')
<< lit(':')
<< value(phoenix::at_c<1>(_val))
;
value = (value_null_| bool_ | int__ | double_ | ustring)[_1 = value_base_(_r1)]
;
value_null_ = kstring[_1 = "null"]
;
ustring = escaped_string_(quote_.c_str())[_1 = utf8_(_val)]
;
}
// rules
feature_generator_grammar();
karma::rule<OutputIterator, mapnik::feature_impl const&()> feature;
multi_geometry_generator_grammar<OutputIterator> geometry;
escaped_string<OutputIterator> escaped_string_;
@ -236,10 +163,9 @@ struct feature_generator_grammar:
karma::rule<OutputIterator, mapnik::value_null()> value_null_;
karma::rule<OutputIterator, mapnik::value_unicode_string()> ustring;
typename karma::int_generator<mapnik::value_integer,10, false> int__;
// phoenix functions
phoenix::function<get_id> id_;
phoenix::function<value_base> value_base_;
phoenix::function<utf8> utf8_;
boost::phoenix::function<get_id> id_;
boost::phoenix::function<value_base> value_base_;
boost::phoenix::function<utf8> utf8_;
std::string quote_;
};

View file

@ -0,0 +1,105 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2014 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 <mapnik/json/feature_generator_grammar.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/fusion/include/at.hpp>
namespace mapnik { namespace json {
namespace karma = boost::spirit::karma;
template <typename OutputIterator>
escaped_string<OutputIterator>::escaped_string()
: escaped_string::base_type(esc_str)
{
karma::lit_type lit;
karma::_r1_type _r1;
karma::hex_type hex;
karma::right_align_type right_align;
karma::print_type kprint;
esc_char.add
('"', "\\\"")
('\\', "\\\\")
('\b', "\\b")
('\f', "\\f")
('\n', "\\n")
('\r', "\\r")
('\t', "\\t")
;
esc_str = lit(_r1)
<< *(esc_char
| kprint
| "\\u" << right_align(4,lit('0'))[hex])
<< lit(_r1)
;
}
template <typename OutputIterator>
feature_generator_grammar<OutputIterator>::feature_generator_grammar()
: feature_generator_grammar::base_type(feature),
quote_("\"")
{
boost::spirit::karma::lit_type lit;
boost::spirit::karma::uint_type uint_;
boost::spirit::karma::bool_type bool_;
boost::spirit::karma::double_type double_;
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::_r1_type _r1;
boost::spirit::karma::string_type kstring;
boost::spirit::karma::eps_type eps;
feature = lit("{\"type\":\"Feature\",\"id\":")
<< uint_[_1 = id_(_val)]
<< lit(",\"geometry\":") << geometry
<< lit(",\"properties\":") << properties
<< lit('}')
;
properties = lit('{')
<< -(pair % lit(','))
<< lit('}')
;
pair = lit('"')
<< kstring[_1 = boost::phoenix::at_c<0>(_val)] << lit('"')
<< lit(':')
<< value(boost::phoenix::at_c<1>(_val))
;
value = (value_null_| bool_ | int__ | double_ | ustring)[_1 = value_base_(_r1)]
;
value_null_ = kstring[_1 = "null"]
;
ustring = escaped_string_(quote_.c_str())[_1 = utf8_(_val)]
;
}
}}

View file

@ -82,7 +82,7 @@ struct put_property
struct extract_geometry
{
using result_type = boost::ptr_vector<mapnik::geometry_type>&;
using result_type = mapnik::geometry_container&;
template <typename T>
result_type operator() (T & feature) const
{
@ -95,11 +95,11 @@ struct feature_grammar :
qi::grammar<Iterator, void(FeatureType&),
space_type>
{
feature_grammar(generic_json<Iterator> & json, mapnik::transcoder const& tr);
feature_grammar(mapnik::transcoder const& tr);
// start
// generic JSON
generic_json<Iterator> & json_;
generic_json<Iterator> json_;
// geoJSON
qi::rule<Iterator,void(FeatureType&),space_type> feature; // START

View file

@ -30,9 +30,9 @@
namespace mapnik { namespace json {
template <typename Iterator, typename FeatureType>
feature_grammar<Iterator,FeatureType>::feature_grammar(generic_json<Iterator> & json, mapnik::transcoder const& tr)
feature_grammar<Iterator,FeatureType>::feature_grammar(mapnik::transcoder const& tr)
: feature_grammar::base_type(feature,"feature"),
json_(json),
json_(),
put_property_(put_property(tr))
{
qi::lit_type lit;
@ -134,7 +134,4 @@ feature_grammar<Iterator,FeatureType>::feature_grammar(generic_json<Iterator> &
}
template struct mapnik::json::feature_grammar<std::string::const_iterator,mapnik::feature_impl>;
template struct mapnik::json::feature_grammar<boost::spirit::multi_pass<std::istreambuf_iterator<char> >,mapnik::feature_impl>;
}}

View file

@ -20,39 +20,30 @@
*
*****************************************************************************/
#ifndef MAPNIK_FEATURE_PARSER_HPP
#define MAPNIK_FEATURE_PARSER_HPP
#ifndef MAPNIK_JSON_FEATURE_PARSER_HPP
#define MAPNIK_JSON_FEATURE_PARSER_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/noncopyable.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/json/feature_grammar.hpp>
// boost
// stl
#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
namespace mapnik { namespace json {
template <typename Iterator, typename FeatureType> struct feature_grammar;
template <typename Iterator> struct generic_json;
template <typename Iterator>
class MAPNIK_DECL feature_parser : private mapnik::noncopyable
inline bool from_geojson(std::string const& json, mapnik::feature_impl & feature)
{
using iterator_type = Iterator;
using feature_type = mapnik::feature_impl;
public:
feature_parser(generic_json<Iterator> & json, mapnik::transcoder const& tr);
~feature_parser();
bool parse(iterator_type first, iterator_type last, mapnik::feature_impl & f);
private:
const std::unique_ptr<feature_grammar<iterator_type,feature_type> > grammar_;
};
static const mapnik::transcoder tr("utf8");
using iterator_type = std::string::const_iterator;
static const mapnik::json::feature_grammar<iterator_type,mapnik::feature_impl> g(tr);
using namespace boost::spirit;
standard_wide::space_type space;
return qi::phrase_parse(json.begin(), json.end(), (g)(boost::phoenix::ref(feature)), space);
}
}}
#endif //MAPNIK_FEATURE_PARSER_HPP
#endif // MAPNIK_JSON_FEATURE_PARSER_HPP

View file

@ -1,63 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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 MAPNIK_GEOJSON_GENERATOR_HPP
#define MAPNIK_GEOJSON_GENERATOR_HPP
#include <mapnik/config.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/noncopyable.hpp>
#include <string>
#include <iterator>
namespace mapnik { namespace json {
template <typename OutputIterator> struct feature_generator_grammar;
template <typename OutputIterator> struct multi_geometry_generator_grammar;
class MAPNIK_DECL feature_generator : private mapnik::noncopyable
{
using sink_type = std::back_insert_iterator<std::string>;
public:
feature_generator();
~feature_generator();
bool generate(std::string & geojson, mapnik::feature_impl const& f);
private:
const std::unique_ptr<feature_generator_grammar<sink_type> > grammar_;
};
class MAPNIK_DECL geometry_generator : private mapnik::noncopyable
{
using sink_type = std::back_insert_iterator<std::string>;
public:
geometry_generator();
~geometry_generator();
bool generate(std::string & geojson, mapnik::geometry_container const& g);
private:
const std::unique_ptr<multi_geometry_generator_grammar<sink_type> > grammar_;
};
}}
#endif // MAPNIK_GEOJSON_GENERATOR_HPP

View file

@ -32,31 +32,16 @@
// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunct
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunc
//stl
#include <tuple>
namespace boost { namespace spirit { namespace traits {
// make gcc and darwin toolsets happy.
template <>
struct is_container<mapnik::geometry_container>
: mpl::false_
{};
}}}
namespace mapnik { namespace json {
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
namespace {
@ -149,61 +134,7 @@ template <typename OutputIterator>
struct geometry_generator_grammar :
karma::grammar<OutputIterator, geometry_type const& ()>
{
geometry_generator_grammar()
: geometry_generator_grammar::base_type(coordinates)
{
boost::spirit::karma::uint_type uint_;
boost::spirit::bool_type bool_;
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::lit_type lit;
boost::spirit::karma::_a_type _a;
boost::spirit::karma::_r1_type _r1;
boost::spirit::karma::eps_type eps;
boost::spirit::karma::string_type kstring;
coordinates = point | linestring | polygon
;
point = &uint_(mapnik::geometry_type::types::Point)[_1 = _type(_val)]
<< point_coord [_1 = _first(_val)]
;
linestring = &uint_(mapnik::geometry_type::types::LineString)[_1 = _type(_val)]
<< lit('[')
<< coords
<< lit(']')
;
polygon = &uint_(mapnik::geometry_type::types::Polygon)[_1 = _type(_val)]
<< lit('[')
<< coords2
<< lit("]]")
;
point_coord = &uint_
<< lit('[')
<< coord_type << lit(',') << coord_type
<< lit(']')
;
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1]
<< kstring[ if_ (_r1 > 1) [_1 = "],["]
.else_[_1 = '[' ]]
|
&uint_(mapnik::SEG_LINETO)
<< lit(',')) << lit('[') << coord_type << lit(',') << coord_type << lit(']')
;
coords2 %= *polygon_coord(_a)
;
coords = point_coord % lit(',')
;
}
// rules
geometry_generator_grammar();
karma::rule<OutputIterator, geometry_type const& ()> coordinates;
karma::rule<OutputIterator, geometry_type const& ()> point;
karma::rule<OutputIterator, geometry_type const& ()> linestring;
@ -212,13 +143,9 @@ struct geometry_generator_grammar :
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
karma::rule<OutputIterator, geometry_type::value_type (unsigned& )> polygon_coord;
// phoenix functions
phoenix::function<get_type > _type;
phoenix::function<get_first> _first;
//
boost::phoenix::function<get_type > _type;
boost::phoenix::function<get_first> _first;
karma::real_generator<double, json_coordinate_policy<double> > coord_type;
};
@ -227,59 +154,7 @@ struct multi_geometry_generator_grammar :
karma::grammar<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
geometry_container const& ()>
{
multi_geometry_generator_grammar()
: multi_geometry_generator_grammar::base_type(start)
{
boost::spirit::karma::uint_type uint_;
boost::spirit::bool_type bool_;
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::lit_type lit;
boost::spirit::karma::_a_type _a;
boost::spirit::karma::eps_type eps;
boost::spirit::karma::string_type kstring;
geometry_types.add
(mapnik::geometry_type::types::Point,"\"Point\"")
(mapnik::geometry_type::types::LineString,"\"LineString\"")
(mapnik::geometry_type::types::Polygon,"\"Polygon\"")
(mapnik::geometry_type::types::Point + 3,"\"MultiPoint\"")
(mapnik::geometry_type::types::LineString + 3,"\"MultiLineString\"")
(mapnik::geometry_type::types::Polygon + 3,"\"MultiPolygon\"")
;
start %= ( eps(phoenix::at_c<1>(_a))[_a = multi_type_(_val)]
<< lit("{\"type\":\"GeometryCollection\",\"geometries\":[")
<< geometry_collection << lit("]}")
|
geometry)
;
geometry_collection = -(geometry2 % lit(','))
;
geometry = ( &bool_(true)[_1 = not_empty_(_val)] << lit("{\"type\":")
<< geometry_types[_1 = phoenix::at_c<0>(_a)][_a = multi_type_(_val)]
<< lit(",\"coordinates\":")
<< kstring[ phoenix::if_ (phoenix::at_c<0>(_a) > 3) [_1 = '['].else_[_1 = ""]]
<< coordinates
<< kstring[ phoenix::if_ (phoenix::at_c<0>(_a) > 3) [_1 = ']'].else_[_1 = ""]]
<< lit('}')) | lit("null")
;
geometry2 = lit("{\"type\":")
<< geometry_types[_1 = _a][_a = type_(_val)]
<< lit(",\"coordinates\":")
<< path
<< lit('}')
;
coordinates %= path % lit(',')
;
}
// rules
multi_geometry_generator_grammar();
karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
geometry_container const&()> start;
karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
@ -290,11 +165,9 @@ struct multi_geometry_generator_grammar :
geometry_type const&()> geometry2;
karma::rule<OutputIterator, geometry_container const&()> coordinates;
geometry_generator_grammar<OutputIterator> path;
// phoenix
phoenix::function<multi_geometry_type> multi_type_;
phoenix::function<get_type > type_;
phoenix::function<not_empty> not_empty_;
// symbols table
boost::phoenix::function<multi_geometry_type> multi_type_;
boost::phoenix::function<get_type > type_;
boost::phoenix::function<not_empty> not_empty_;
karma::symbols<unsigned, char const*> geometry_types;
};

View file

@ -0,0 +1,141 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2014 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/json/geometry_generator_grammar.hpp>
// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/fusion/include/at.hpp>
namespace mapnik { namespace json {
namespace karma = boost::spirit::karma;
template <typename OutputIterator>
geometry_generator_grammar<OutputIterator>::geometry_generator_grammar()
: geometry_generator_grammar::base_type(coordinates)
{
boost::spirit::karma::uint_type uint_;
boost::spirit::bool_type bool_;
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::lit_type lit;
boost::spirit::karma::_a_type _a;
boost::spirit::karma::_r1_type _r1;
boost::spirit::karma::eps_type eps;
boost::spirit::karma::string_type kstring;
coordinates = point | linestring | polygon
;
point = &uint_(mapnik::geometry_type::types::Point)[_1 = _type(_val)]
<< point_coord [_1 = _first(_val)]
;
linestring = &uint_(mapnik::geometry_type::types::LineString)[_1 = _type(_val)]
<< lit('[')
<< coords
<< lit(']')
;
polygon = &uint_(mapnik::geometry_type::types::Polygon)[_1 = _type(_val)]
<< lit('[')
<< coords2
<< lit("]]")
;
point_coord = &uint_
<< lit('[')
<< coord_type << lit(',') << coord_type
<< lit(']')
;
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1]
<< kstring[ if_ (_r1 > 1) [_1 = "],["]
.else_[_1 = '[' ]]
|
&uint_(mapnik::SEG_LINETO)
<< lit(',')) << lit('[') << coord_type << lit(',') << coord_type << lit(']')
;
coords2 %= *polygon_coord(_a)
;
coords = point_coord % lit(',')
;
}
template <typename OutputIterator>
multi_geometry_generator_grammar<OutputIterator>::multi_geometry_generator_grammar()
: multi_geometry_generator_grammar::base_type(start)
{
boost::spirit::karma::uint_type uint_;
boost::spirit::bool_type bool_;
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::lit_type lit;
boost::spirit::karma::_a_type _a;
boost::spirit::karma::eps_type eps;
boost::spirit::karma::string_type kstring;
geometry_types.add
(mapnik::geometry_type::types::Point,"\"Point\"")
(mapnik::geometry_type::types::LineString,"\"LineString\"")
(mapnik::geometry_type::types::Polygon,"\"Polygon\"")
(mapnik::geometry_type::types::Point + 3,"\"MultiPoint\"")
(mapnik::geometry_type::types::LineString + 3,"\"MultiLineString\"")
(mapnik::geometry_type::types::Polygon + 3,"\"MultiPolygon\"")
;
start %= ( eps(boost::phoenix::at_c<1>(_a))[_a = multi_type_(_val)]
<< lit("{\"type\":\"GeometryCollection\",\"geometries\":[")
<< geometry_collection << lit("]}")
|
geometry)
;
geometry_collection = -(geometry2 % lit(','))
;
geometry = ( &bool_(true)[_1 = not_empty_(_val)] << lit("{\"type\":")
<< geometry_types[_1 = boost::phoenix::at_c<0>(_a)][_a = multi_type_(_val)]
<< lit(",\"coordinates\":")
<< kstring[ boost::phoenix::if_ (boost::phoenix::at_c<0>(_a) > 3) [_1 = '['].else_[_1 = ""]]
<< coordinates
<< kstring[ boost::phoenix::if_ (boost::phoenix::at_c<0>(_a) > 3) [_1 = ']'].else_[_1 = ""]]
<< lit('}')) | lit("null")
;
geometry2 = lit("{\"type\":")
<< geometry_types[_1 = _a][_a = type_(_val)]
<< lit(",\"coordinates\":")
<< path
<< lit('}')
;
coordinates %= path % lit(',')
;
}
}}

View file

@ -90,28 +90,28 @@ struct where_message
template <typename Iterator>
struct geometry_grammar :
qi::grammar<Iterator,qi::locals<int>, void(boost::ptr_vector<mapnik::geometry_type>& )
qi::grammar<Iterator,qi::locals<int>, void(mapnik::geometry_container& )
, space_type>
{
geometry_grammar();
qi::rule<Iterator, qi::locals<int>, void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> geometry;
qi::rule<Iterator, qi::locals<int>, void(mapnik::geometry_container& ),space_type> geometry;
qi::symbols<char, int> geometry_dispatch;
qi::rule<Iterator,void(CommandType,geometry_type*),space_type> point;
qi::rule<Iterator,qi::locals<CommandType>,void(geometry_type*),space_type> points;
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>&,int),space_type> coordinates;
qi::rule<Iterator,void(mapnik::geometry_container&,int),space_type> coordinates;
//
qi::rule<Iterator,qi::locals<geometry_type*>,
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> point_coordinates;
void(mapnik::geometry_container& ),space_type> point_coordinates;
qi::rule<Iterator,qi::locals<geometry_type*>,
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> linestring_coordinates;
void(mapnik::geometry_container& ),space_type> linestring_coordinates;
qi::rule<Iterator,qi::locals<geometry_type*>,
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> polygon_coordinates;
void(mapnik::geometry_container& ),space_type> polygon_coordinates;
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multipoint_coordinates;
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multilinestring_coordinates;
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multipolygon_coordinates;
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> geometry_collection;
qi::rule<Iterator,void(mapnik::geometry_container& ),space_type> multipoint_coordinates;
qi::rule<Iterator,void(mapnik::geometry_container& ),space_type> multilinestring_coordinates;
qi::rule<Iterator,void(mapnik::geometry_container& ),space_type> multipolygon_coordinates;
qi::rule<Iterator,void(mapnik::geometry_container& ),space_type> geometry_collection;
// Nabialek trick //////////////////////////////////////
//using dispatch_rule = typename qi::rule<Iterator,void(FeatureType &), space_type>;

View file

@ -158,7 +158,4 @@ geometry_grammar<Iterator>::geometry_grammar()
);
}
template struct mapnik::json::geometry_grammar<std::string::const_iterator>;
template struct mapnik::json::geometry_grammar<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >;
}}

View file

@ -24,34 +24,26 @@
#define MAPNIK_JSON_GEOMETRY_PARSER_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/noncopyable.hpp>
#include <mapnik/json/geometry_grammar.hpp>
// boost
// stl
//#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
namespace mapnik { namespace json {
template <typename Iterator> struct geometry_grammar;
MAPNIK_DECL bool from_geojson(std::string const& json, boost::ptr_vector<geometry_type> & paths);
template <typename Iterator>
class MAPNIK_DECL geometry_parser : private mapnik::noncopyable
inline bool from_geojson(std::string const& json, boost::ptr_vector<geometry_type> & paths)
{
using iterator_type = Iterator;
public:
geometry_parser();
~geometry_parser();
bool parse(iterator_type first, iterator_type last, boost::ptr_vector<mapnik::geometry_type>&);
private:
const std::unique_ptr<geometry_grammar<iterator_type> > grammar_;
};
using namespace boost::spirit;
static const geometry_grammar<std::string::const_iterator> g;
standard_wide::space_type space;
std::string::const_iterator start = json.begin();
std::string::const_iterator end = json.end();
return qi::phrase_parse(start, end, (g)(boost::phoenix::ref(paths)), space);
}
}}
#endif //MAPNIK_FEATURE_COLLECTION_PARSER_HPP
#endif // MAPNIK_JSON_GEOMETRY_PARSER_HPP

View file

@ -116,9 +116,9 @@ template <typename Iterator>
struct symbolizer_grammar : qi::grammar<Iterator, space_type, symbolizer()>
{
using json_value_type = boost::variant<value_null,value_bool,value_integer,value_double, std::string>;
symbolizer_grammar(generic_json<Iterator> & json)
symbolizer_grammar()
: symbolizer_grammar::base_type(sym, "symbolizer"),
json_(json)
json_()
{
using qi::lit;
using qi::double_;
@ -201,7 +201,7 @@ struct symbolizer_grammar : qi::grammar<Iterator, space_type, symbolizer()>
}
// generic JSON
generic_json<Iterator> & json_;
generic_json<Iterator> json_;
// symbolizer
qi::rule<Iterator, space_type, mapnik::symbolizer()> sym;
qi::rule<Iterator,qi::locals<std::string>, void(mapnik::symbolizer&),space_type> property;

View file

@ -56,6 +56,4 @@ path_expression_grammar<Iterator>::path_expression_grammar()
str %= lexeme[+(char_ -'[')];
}
template struct mapnik::path_expression_grammar<std::string::const_iterator>;
}

View file

@ -20,8 +20,8 @@
*
*****************************************************************************/
#ifndef MAPNIK_GEOMETRY_SVG_GENERATOR_HPP
#define MAPNIK_GEOMETRY_SVG_GENERATOR_HPP
#ifndef MAPNIK_GEOMETRY_SVG_PATH_GENERATOR_HPP
#define MAPNIK_GEOMETRY_SVG_PATH_GENERATOR_HPP
// mapnik
@ -83,7 +83,7 @@ struct end_container<path_type const>
}}}
namespace mapnik { namespace util {
namespace mapnik { namespace svg {
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
@ -124,52 +124,14 @@ namespace mapnik { namespace util {
}
template <typename OutputIterator, typename Geometry>
struct svg_generator :
struct svg_path_generator :
karma::grammar<OutputIterator, Geometry const& ()>
{
using geometry_type = Geometry;
using coord_type = typename boost::remove_pointer<typename geometry_type::value_type>::type;
svg_generator()
: svg_generator::base_type(svg)
{
boost::spirit::karma::uint_type uint_;
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::lit_type lit;
boost::spirit::karma::_a_type _a;
boost::spirit::karma::string_type kstring;
svg = point | linestring | polygon
;
point = &uint_(mapnik::geometry_type::types::Point)[_1 = _type(_val)]
<< svg_point [_1 = _first(_val)]
;
svg_point = &uint_
<< lit("cx=\"") << coordinate
<< lit("\" cy=\"") << coordinate
<< lit('\"')
;
linestring = &uint_(mapnik::geometry_type::types::LineString)[_1 = _type(_val)]
<< lit("d=\"") << svg_path << lit("\"")
;
polygon = &uint_(mapnik::geometry_type::types::Polygon)[_1 = _type(_val)]
<< lit("d=\"") << svg_path << lit("\"")
;
svg_path %= ((&uint_(mapnik::SEG_MOVETO) << lit('M')
| &uint_(mapnik::SEG_LINETO) [_a +=1] << kstring [if_(_a == 1) [_1 = "L" ].else_[_1 =""]])
<< lit(' ') << coordinate << lit(' ') << coordinate) % lit(' ')
;
}
svg_path_generator();
// rules
karma::rule<OutputIterator, geometry_type const& ()> svg;
karma::rule<OutputIterator, geometry_type const& ()> point;
@ -189,4 +151,4 @@ namespace mapnik { namespace util {
}}
#endif // MAPNIK_GEOMETRY_SVG_GENERATOR_HPP
#endif // MAPNIK_GEOMETRY_SVG_PATH_GENERATOR_HPP

View file

@ -0,0 +1,71 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
// mapnik
#include <mapnik/svg/geometry_svg_generator.hpp>
namespace mapnik { namespace svg {
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
template <typename OutputIterator, typename Geometry>
svg_path_generator<OutputIterator,Geometry>::svg_path_generator()
: svg_path_generator::base_type(svg)
{
boost::spirit::karma::uint_type uint_;
boost::spirit::karma::_val_type _val;
boost::spirit::karma::_1_type _1;
boost::spirit::karma::lit_type lit;
boost::spirit::karma::_a_type _a;
boost::spirit::karma::string_type kstring;
svg = point | linestring | polygon
;
point = &uint_(mapnik::geometry_type::types::Point)[_1 = _type(_val)]
<< svg_point [_1 = _first(_val)]
;
svg_point = &uint_
<< lit("cx=\"") << coordinate
<< lit("\" cy=\"") << coordinate
<< lit('\"')
;
linestring = &uint_(mapnik::geometry_type::types::LineString)[_1 = _type(_val)]
<< lit("d=\"") << svg_path << lit("\"")
;
polygon = &uint_(mapnik::geometry_type::types::Polygon)[_1 = _type(_val)]
<< lit("d=\"") << svg_path << lit("\"")
;
svg_path %= ((&uint_(mapnik::SEG_MOVETO) << lit('M')
| &uint_(mapnik::SEG_LINETO) [_a +=1] << kstring [if_(_a == 1) [_1 = "L" ].else_[_1 =""]])
<< lit(' ') << coordinate << lit(' ') << coordinate) % lit(' ')
;
}
}}

View file

@ -35,8 +35,7 @@ boost/spirit/repository/home/karma/directive/confix.hpp:49:23: error: no member
#include <mapnik/ctrans.hpp>
#include <mapnik/color.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/util/geometry_svg_generator.hpp>
#include <mapnik/svg/output/svg_output_grammars.hpp>
#include <mapnik/svg/geometry_svg_generator.hpp>
#include <mapnik/svg/output/svg_output_attributes.hpp>
#include <mapnik/noncopyable.hpp>
#include <mapnik/value_types.hpp>
@ -53,11 +52,6 @@ namespace mapnik { namespace svg {
template <typename OutputIterator>
class svg_generator : private mapnik::noncopyable
{
using root_attributes_grammar = svg::svg_root_attributes_grammar<OutputIterator>;
using rect_attributes_grammar = svg::svg_rect_attributes_grammar<OutputIterator>;
using path_attributes_grammar = svg::svg_path_attributes_grammar<OutputIterator>;
using path_dash_array_grammar = svg::svg_path_dash_array_grammar<OutputIterator>;
public:
explicit svg_generator(OutputIterator& output_iterator);
~svg_generator();
@ -69,19 +63,6 @@ namespace mapnik { namespace svg {
void generate_opening_group(mapnik::value_integer val);
void generate_opening_group(std::string const& val);
void generate_closing_group();
template <typename PathType>
void generate_path(PathType const& path, path_output_attributes const& path_attributes)
{
karma::lit_type lit;
util::svg_generator<OutputIterator,PathType> svg_path_grammer;
karma::generate(output_iterator_, lit("<path ") << svg_path_grammer, path);
path_attributes_grammar attributes_grammar;
path_dash_array_grammar dash_array_grammar;
karma::generate(output_iterator_, lit(" ") << dash_array_grammar, path_attributes.stroke_dasharray());
karma::generate(output_iterator_, lit(" ") << attributes_grammar << lit("/>\n"), path_attributes);
}
private:
OutputIterator& output_iterator_;
};
}}

View file

@ -24,11 +24,14 @@
#define MAPNIK_TRANSFORM_EXPRESSION_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/expression_node_types.hpp>
#include <mapnik/expression_node.hpp>
// boost
#include <boost/optional.hpp>
#include <memory>
#include <boost/variant/variant.hpp>
// fusion
@ -37,6 +40,7 @@
// stl
#include <vector>
#include <memory>
namespace mapnik {

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/expression_grammar.hpp>
#include <mapnik/expression_node_types.hpp>
#include <mapnik/transform_expression.hpp>
// spirit

View file

@ -22,6 +22,7 @@
// mapnik
#include <mapnik/transform_expression_grammar.hpp>
#include <mapnik/expression_grammar_impl.hpp>
// boost
#include <boost/spirit/include/qi.hpp>
@ -127,6 +128,4 @@ transform_expression_grammar<Iterator>::transform_expression_grammar()
expr = g_.expr.alias();
}
template struct mapnik::transform_expression_grammar<std::string::const_iterator>;
}

View file

@ -33,7 +33,6 @@
#include <mapnik/expression_evaluator.hpp>
// boost
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/range/adaptor/reversed.hpp>

View file

@ -35,6 +35,10 @@ namespace boost { namespace spirit { namespace traits {
template <>
struct is_container<mapnik::geometry_type const> : mpl::true_ {} ;
// make gcc and darwin toolsets happy.
template <>
struct is_container<mapnik::geometry_container const> : mpl::false_ {} ;
template <>
struct container_iterator<mapnik::geometry_type const>
{

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 Artem Pavlenko
* 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
@ -20,36 +20,31 @@
*
*****************************************************************************/
// boost
#include <mapnik/feature.hpp>
#include <mapnik/json/geojson_generator.hpp>
#include <mapnik/json/feature_generator_grammar.hpp>
#ifndef MAPNIK_GEOMETRY_TO_GEOJSON_HPP
#define MAPNIK_GEOMETRY_TO_GEOJSON_HPP
// mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <boost/spirit/include/karma.hpp>
namespace mapnik { namespace util {
namespace mapnik { namespace json {
feature_generator::feature_generator()
: grammar_(new feature_generator_grammar<sink_type>()) {}
feature_generator::~feature_generator() {}
bool feature_generator::generate(std::string & geojson, mapnik::feature_impl const& f)
inline bool to_geojson(std::string & json, mapnik::geometry_type const& geom)
{
sink_type sink(geojson);
return karma::generate(sink, *grammar_,f);
using sink_type = std::back_insert_iterator<std::string>;
static const mapnik::json::geometry_generator_grammar<sink_type> grammar;
sink_type sink(json);
return boost::spirit::karma::generate(sink, grammar, geom);
}
geometry_generator::geometry_generator()
: grammar_(new multi_geometry_generator_grammar<sink_type>()) {}
geometry_generator::~geometry_generator() {}
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
inline bool to_geojson(std::string & json, mapnik::geometry_container const& geom)
{
sink_type sink(geojson);
return karma::generate(sink, *grammar_,g);
using sink_type = std::back_insert_iterator<std::string>;
static const mapnik::json::multi_geometry_generator_grammar<sink_type> grammar;
sink_type sink(json);
return boost::spirit::karma::generate(sink, grammar, geom);
}
}}
#endif // MAPNIK_GEOMETRY_TO_GEOJSON_HPP

View file

@ -26,7 +26,7 @@
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/util/geometry_svg_generator.hpp>
#include <mapnik/svg/geometry_svg_generator.hpp>
// boost
#include <boost/spirit/include/karma.hpp>
@ -35,11 +35,11 @@ namespace mapnik { namespace util {
namespace karma = boost::spirit::karma;
bool to_svg(std::string & svg, mapnik::geometry_type const& geom)
inline bool to_svg(std::string & svg, mapnik::geometry_type const& geom)
{
using sink_type = std::back_insert_iterator<std::string>;
sink_type sink(svg);
svg_generator<sink_type, mapnik::geometry_type> generator;
static const svg::svg_path_generator<sink_type, mapnik::geometry_type> generator;
bool result = karma::generate(sink, generator, geom);
return result;
}

View file

@ -24,16 +24,27 @@
#define MAPNIK_GEOMETRY_TO_WKT_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_generator_grammar.hpp>
namespace mapnik { namespace util {
MAPNIK_DECL bool to_wkt(std::string & wkt, mapnik::geometry_type const& geom);
inline bool to_wkt(std::string & wkt, mapnik::geometry_type const& geom)
{
using sink_type = std::back_insert_iterator<std::string>;
sink_type sink(wkt);
static const mapnik::wkt::wkt_generator<sink_type, mapnik::geometry_type> generator(true);
return boost::spirit::karma::generate(sink, generator, geom);
}
MAPNIK_DECL bool to_wkt(std::string & wkt, mapnik::geometry_container const& geom);
inline bool to_wkt(std::string & wkt, mapnik::geometry_container const& geom)
{
using sink_type = std::back_insert_iterator<std::string>;
sink_type sink(wkt);
static const mapnik::wkt::wkt_multi_generator<sink_type, mapnik::geometry_container> generator;
return boost::spirit::karma::generate(sink, generator, geom);
}
}}
#endif // MAPNIK_GEOMETRY_TO_WKT_HPP

View file

@ -52,7 +52,7 @@ class MAPNIK_DECL geometry_utils : private mapnik::noncopyable
{
public:
static bool from_wkb (boost::ptr_vector<geometry_type>& paths,
static bool from_wkb(mapnik::geometry_container& paths,
const char* wkb,
unsigned size,
wkbFormat format = wkbGeneric);

View file

@ -24,33 +24,24 @@
#define MAPNIK_WKT_FACTORY_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_grammar.hpp>
#include <mapnik/noncopyable.hpp>
// boost
#include <boost/ptr_container/ptr_vector.hpp>
// stl
#include <string>
#include <memory>
namespace mapnik {
MAPNIK_DECL bool from_wkt(std::string const& wkt, boost::ptr_vector<geometry_type> & paths);
class MAPNIK_DECL wkt_parser : mapnik::noncopyable
inline bool from_wkt(std::string const& wkt, mapnik::geometry_container & paths)
{
using iterator_type = std::string::const_iterator;
public:
wkt_parser();
bool parse(std::string const& wkt, boost::ptr_vector<geometry_type> & paths);
private:
const std::unique_ptr<mapnik::wkt::wkt_collection_grammar<iterator_type> > grammar_;
};
using namespace boost::spirit;
static const mapnik::wkt::wkt_collection_grammar<std::string::const_iterator> g;
ascii::space_type space;
std::string::const_iterator first = wkt.begin();
std::string::const_iterator last = wkt.end();
return qi::phrase_parse(first, last, g, space, paths);
}
}
#endif // MAPNIK_WKT_FACTORY_HPP

View file

@ -27,6 +27,7 @@
#include <mapnik/global.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/vertex.hpp> // for CommandType::SEG_MOVETO
#include <mapnik/util/container_adapter.hpp>
// boost
#include <boost/spirit/include/karma.hpp>
@ -37,22 +38,12 @@
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunct
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunc
// stl
#include <tuple>
namespace boost { namespace spirit { namespace traits {
// make gcc and darwin toolsets happy.
template <>
struct is_container<mapnik::geometry_container>
: mpl::false_
{};
}}}
namespace mapnik { namespace util {
namespace mapnik { namespace wkt {
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;

View file

@ -21,12 +21,11 @@
*****************************************************************************/
#include <mapnik/geometry.hpp>
#include <mapnik/util/geometry_wkt_generator.hpp>
#include <mapnik/util/geometry_to_wkt.hpp>
#include <mapnik/wkt/wkt_generator_grammar.hpp>
#include <mapnik/util/path_iterator.hpp>
#include <mapnik/util/container_adapter.hpp>
namespace mapnik { namespace util {
namespace mapnik { namespace wkt {
template <typename T>
std::tuple<unsigned,bool> detail::multi_geometry_type<T>::operator() (T const& geom) const
@ -145,25 +144,4 @@ wkt_multi_generator<OutputIterator, GeometryContainer>::wkt_multi_generator()
}
template struct mapnik::util::wkt_generator<std::back_insert_iterator<std::string>, mapnik::geometry_type>;
template struct mapnik::util::wkt_multi_generator<std::back_insert_iterator<std::string>, mapnik::geometry_container >;
bool to_wkt(std::string & wkt, mapnik::geometry_type const& geom)
{
using sink_type = std::back_insert_iterator<std::string>;
sink_type sink(wkt);
wkt_generator<sink_type, mapnik::geometry_type> generator(true);
bool result = karma::generate(sink, generator, geom);
return result;
}
bool to_wkt(std::string & wkt, mapnik::geometry_container const& geom)
{
using sink_type = std::back_insert_iterator<std::string>;
sink_type sink(wkt);
wkt_multi_generator<sink_type, mapnik::geometry_container> generator;
bool result = karma::generate(sink, generator, geom);
return result;
}
}}

View file

@ -24,16 +24,8 @@
#define MAPNIK_WKT_GRAMMAR_HPP
#include <boost/assert.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
// spirit::qi
#include <boost/spirit/include/qi.hpp>
// spirit::phoenix
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
// mapnik
#include <mapnik/geometry.hpp>
@ -41,215 +33,86 @@
namespace mapnik { namespace wkt {
using namespace boost::spirit;
using namespace boost::phoenix;
using namespace boost::spirit;
struct push_vertex
{
template <typename T>
struct result
{
using type = void;
};
template <typename T0,typename T1, typename T2, typename T3>
void operator() (T0 c, T1 path, T2 x, T3 y) const
{
BOOST_ASSERT( path!=0 );
path->push_vertex(x,y,c);
}
};
struct close_path
{
template <typename T>
struct result
{
using type = void;
};
template <typename T>
void operator() (T path) const
{
BOOST_ASSERT( path!=0 );
path->close_path();
}
};
struct cleanup
{
template <typename T0>
struct result
{
using type = void;
};
template <typename T0>
void operator() (T0 & path) const
{
if (path) delete path,path=0;
}
};
template <typename Iterator>
struct wkt_grammar : qi::grammar<Iterator, boost::ptr_vector<mapnik::geometry_type>() , ascii::space_type>
{
wkt_grammar()
: wkt_grammar::base_type(geometry_tagged_text)
{
qi::_r1_type _r1;
qi::_r2_type _r2;
qi::_pass_type _pass;
qi::eps_type eps;
qi::_val_type _val;
qi::lit_type lit;
qi::no_case_type no_case;
qi::double_type double_;
qi::_1_type _1;
qi::_2_type _2;
qi::_a_type _a;
using boost::phoenix::push_back;
geometry_tagged_text = point_tagged_text
| linestring_tagged_text
| polygon_tagged_text
| multipoint_tagged_text
| multilinestring_tagged_text
| multipolygon_tagged_text
;
// <point tagged text> ::= point <point text>
point_tagged_text = no_case[lit("POINT")] [ _a = new_<geometry_type>(geometry_type::types::Point) ]
>> ( point_text(_a) [push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false])
;
// <point text> ::= <empty set> | <left paren> <point> <right paren>
point_text = (lit("(") >> point(SEG_MOVETO,_r1) >> lit(')'))
| empty_set
;
// <linestring tagged text> ::= linestring <linestring text>
linestring_tagged_text = no_case[lit("LINESTRING")] [ _a = new_<geometry_type>(geometry_type::types::LineString) ]
>> (linestring_text(_a)[push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false])
;
// <linestring text> ::= <empty set> | <left paren> <point> {<comma> <point>}* <right paren>
linestring_text = points(_r1) | empty_set
;
// <polygon tagged text> ::= polygon <polygon text>
polygon_tagged_text = no_case[lit("POLYGON")] [ _a = new_<geometry_type>(geometry_type::types::Polygon) ]
>> ( polygon_text(_a)[push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false])
;
// <polygon text> ::= <empty set> | <left paren> <linestring text> {<comma> <linestring text>}* <right paren>
polygon_text = (lit('(') >> linestring_text(_r1)[close_path_(_r1)] % lit(',') >> lit(')')) | empty_set;
//<multipoint tagged text> ::= multipoint <multipoint text>
multipoint_tagged_text = no_case[lit("MULTIPOINT")]
>> multipoint_text
;
// <multipoint text> ::= <empty set> | <left paren> <point text> {<comma> <point text>}* <right paren>
multipoint_text = (lit('(')
>> ((eps[_a = new_<geometry_type>(geometry_type::types::Point)]
>> (point_text(_a) | empty_set) [push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false]) % lit(','))
>> lit(')')) | empty_set
;
// <multilinestring tagged text> ::= multilinestring <multilinestring text>
multilinestring_tagged_text = no_case[lit("MULTILINESTRING")]
>> multilinestring_text ;
// <multilinestring text> ::= <empty set> | <left paren> <linestring text> {<comma> <linestring text>}* <right paren>
multilinestring_text = (lit('(')
>> ((eps[_a = new_<geometry_type>(geometry_type::types::LineString)]
>> ( points(_a)[push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false]))
% lit(','))
>> lit(')')) | empty_set;
// <multipolygon tagged text> ::= multipolygon <multipolygon text>
multipolygon_tagged_text = no_case[lit("MULTIPOLYGON")]
>> multipolygon_text ;
// <multipolygon text> ::= <empty set> | <left paren> <polygon text> {<comma> <polygon text>}* <right paren>
multipolygon_text = (lit('(')
>> ((eps[_a = new_<geometry_type>(geometry_type::types::Polygon)]
>> ( polygon_text(_a)[push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false]))
% lit(','))
>> lit(')')) | empty_set;
// points
points = lit('(')[_a = SEG_MOVETO] >> point (_a,_r1) % lit(',') [_a = SEG_LINETO] >> lit(')');
// point
point = (double_ >> double_) [push_vertex_(_r1,_r2,_1,_2)];
// <empty set>
empty_set = no_case[lit("EMPTY")];
}
// start
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> geometry_tagged_text;
qi::rule<Iterator,qi::locals<geometry_type*>,boost::ptr_vector<geometry_type>(),ascii::space_type> point_tagged_text;
qi::rule<Iterator,qi::locals<geometry_type*>,boost::ptr_vector<geometry_type>(),ascii::space_type> linestring_tagged_text;
qi::rule<Iterator,qi::locals<geometry_type*>,boost::ptr_vector<geometry_type>(),ascii::space_type> polygon_tagged_text;
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> multipoint_tagged_text;
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> multilinestring_tagged_text;
qi::rule<Iterator,boost::ptr_vector<geometry_type>(),ascii::space_type> multipolygon_tagged_text;
//
qi::rule<Iterator,void(geometry_type*),ascii::space_type> point_text;
qi::rule<Iterator,void(geometry_type*),ascii::space_type> linestring_text;
qi::rule<Iterator,void(geometry_type*),ascii::space_type> polygon_text;
qi::rule<Iterator, qi::locals<geometry_type*>, boost::ptr_vector<geometry_type>(),ascii::space_type> multipoint_text;
qi::rule<Iterator, qi::locals<geometry_type*>, boost::ptr_vector<geometry_type>(),ascii::space_type> multilinestring_text;
qi::rule<Iterator, qi::locals<geometry_type*>, boost::ptr_vector<geometry_type>(),ascii::space_type> multipolygon_text;
//
qi::rule<Iterator,void(CommandType,geometry_type*),ascii::space_type> point;
qi::rule<Iterator,qi::locals<CommandType>,void(geometry_type*),ascii::space_type> points;
qi::rule<Iterator,ascii::space_type> empty_set;
boost::phoenix::function<push_vertex> push_vertex_;
boost::phoenix::function<close_path> close_path_;
boost::phoenix::function<cleanup> cleanup_;
};
template <typename Iterator>
struct wkt_collection_grammar : qi::grammar<Iterator, boost::ptr_vector<mapnik::geometry_type>(), ascii::space_type>
struct push_vertex
{
wkt_collection_grammar()
: wkt_collection_grammar::base_type(start)
template <typename T>
struct result
{
qi::lit_type lit;
qi::no_case_type no_case;
start = wkt | no_case[lit("GEOMETRYCOLLECTION")]
>> (lit("(") >> wkt % lit(",") >> lit(")"));
}
using type = void;
};
qi::rule<Iterator,boost::ptr_vector<mapnik::geometry_type>(),ascii::space_type> start;
wkt_grammar<Iterator> wkt;
template <typename T0,typename T1, typename T2, typename T3>
void operator() (T0 c, T1 path, T2 x, T3 y) const
{
BOOST_ASSERT( path!=0 );
path->push_vertex(x,y,c);
}
};
struct close_path
{
template <typename T>
struct result
{
using type = void;
};
template <typename T>
void operator() (T path) const
{
BOOST_ASSERT( path!=0 );
path->close_path();
}
};
struct cleanup
{
template <typename T0>
struct result
{
using type = void;
};
template <typename T0>
void operator() (T0 & path) const
{
if (path) delete path,path=0;
}
};
template <typename Iterator>
struct wkt_stream_grammar : qi::grammar<Iterator, boost::ptr_vector<mapnik::geometry_type>(), ascii::space_type>
struct wkt_grammar : qi::grammar<Iterator, mapnik::geometry_container() , ascii::space_type>
{
wkt_stream_grammar()
: wkt_stream_grammar::base_type(start)
{
start = *wkt_collection;
}
wkt_grammar();
qi::rule<Iterator,mapnik::geometry_container(),ascii::space_type> geometry_tagged_text;
qi::rule<Iterator,qi::locals<geometry_type*>,mapnik::geometry_container(),ascii::space_type> point_tagged_text;
qi::rule<Iterator,qi::locals<geometry_type*>,mapnik::geometry_container(),ascii::space_type> linestring_tagged_text;
qi::rule<Iterator,qi::locals<geometry_type*>,mapnik::geometry_container(),ascii::space_type> polygon_tagged_text;
qi::rule<Iterator,mapnik::geometry_container(),ascii::space_type> multipoint_tagged_text;
qi::rule<Iterator,mapnik::geometry_container(),ascii::space_type> multilinestring_tagged_text;
qi::rule<Iterator,mapnik::geometry_container(),ascii::space_type> multipolygon_tagged_text;
qi::rule<Iterator,void(geometry_type*),ascii::space_type> point_text;
qi::rule<Iterator,void(geometry_type*),ascii::space_type> linestring_text;
qi::rule<Iterator,void(geometry_type*),ascii::space_type> polygon_text;
qi::rule<Iterator, qi::locals<geometry_type*>, mapnik::geometry_container(),ascii::space_type> multipoint_text;
qi::rule<Iterator, qi::locals<geometry_type*>, mapnik::geometry_container(),ascii::space_type> multilinestring_text;
qi::rule<Iterator, qi::locals<geometry_type*>, mapnik::geometry_container(),ascii::space_type> multipolygon_text;
qi::rule<Iterator,void(CommandType,geometry_type*),ascii::space_type> point;
qi::rule<Iterator,qi::locals<CommandType>,void(geometry_type*),ascii::space_type> points;
qi::rule<Iterator,ascii::space_type> empty_set;
boost::phoenix::function<push_vertex> push_vertex_;
boost::phoenix::function<close_path> close_path_;
boost::phoenix::function<cleanup> cleanup_;
};
qi::rule<Iterator,boost::ptr_vector<mapnik::geometry_type>(),ascii::space_type> start;
wkt_collection_grammar<Iterator> wkt_collection;
template <typename Iterator>
struct wkt_collection_grammar : qi::grammar<Iterator, mapnik::geometry_container(), ascii::space_type>
{
wkt_collection_grammar();
qi::rule<Iterator,mapnik::geometry_container(),ascii::space_type> start;
wkt_grammar<Iterator> wkt;
};
}}

View file

@ -0,0 +1,149 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#include <mapnik/wkt/wkt_grammar.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
namespace mapnik { namespace wkt {
using namespace boost::spirit;
template <typename Iterator>
wkt_grammar<Iterator>::wkt_grammar()
: wkt_grammar::base_type(geometry_tagged_text)
{
qi::_r1_type _r1;
qi::_r2_type _r2;
qi::_pass_type _pass;
qi::eps_type eps;
qi::_val_type _val;
qi::lit_type lit;
qi::no_case_type no_case;
qi::double_type double_;
qi::_1_type _1;
qi::_2_type _2;
qi::_a_type _a;
using boost::phoenix::push_back;
using boost::phoenix::new_;
geometry_tagged_text = point_tagged_text
| linestring_tagged_text
| polygon_tagged_text
| multipoint_tagged_text
| multilinestring_tagged_text
| multipolygon_tagged_text
;
// <point tagged text> ::= point <point text>
point_tagged_text = no_case[lit("POINT")] [ _a = new_<geometry_type>(geometry_type::types::Point) ]
>> ( point_text(_a) [push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false])
;
// <point text> ::= <empty set> | <left paren> <point> <right paren>
point_text = (lit("(") >> point(SEG_MOVETO,_r1) >> lit(')'))
| empty_set
;
// <linestring tagged text> ::= linestring <linestring text>
linestring_tagged_text = no_case[lit("LINESTRING")] [ _a = new_<geometry_type>(geometry_type::types::LineString) ]
>> (linestring_text(_a)[push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false])
;
// <linestring text> ::= <empty set> | <left paren> <point> {<comma> <point>}* <right paren>
linestring_text = points(_r1) | empty_set
;
// <polygon tagged text> ::= polygon <polygon text>
polygon_tagged_text = no_case[lit("POLYGON")] [ _a = new_<geometry_type>(geometry_type::types::Polygon) ]
>> ( polygon_text(_a)[push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false])
;
// <polygon text> ::= <empty set> | <left paren> <linestring text> {<comma> <linestring text>}* <right paren>
polygon_text = (lit('(') >> linestring_text(_r1)[close_path_(_r1)] % lit(',') >> lit(')')) | empty_set;
//<multipoint tagged text> ::= multipoint <multipoint text>
multipoint_tagged_text = no_case[lit("MULTIPOINT")]
>> multipoint_text
;
// <multipoint text> ::= <empty set> | <left paren> <point text> {<comma> <point text>}* <right paren>
multipoint_text = (lit('(')
>> ((eps[_a = new_<geometry_type>(geometry_type::types::Point)]
>> (point_text(_a) | empty_set) [push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false]) % lit(','))
>> lit(')')) | empty_set
;
// <multilinestring tagged text> ::= multilinestring <multilinestring text>
multilinestring_tagged_text = no_case[lit("MULTILINESTRING")]
>> multilinestring_text ;
// <multilinestring text> ::= <empty set> | <left paren> <linestring text> {<comma> <linestring text>}* <right paren>
multilinestring_text = (lit('(')
>> ((eps[_a = new_<geometry_type>(geometry_type::types::LineString)]
>> ( points(_a)[push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false]))
% lit(','))
>> lit(')')) | empty_set;
// <multipolygon tagged text> ::= multipolygon <multipolygon text>
multipolygon_tagged_text = no_case[lit("MULTIPOLYGON")]
>> multipolygon_text ;
// <multipolygon text> ::= <empty set> | <left paren> <polygon text> {<comma> <polygon text>}* <right paren>
multipolygon_text = (lit('(')
>> ((eps[_a = new_<geometry_type>(geometry_type::types::Polygon)]
>> ( polygon_text(_a)[push_back(_val,_a)]
| eps[cleanup_(_a)][_pass = false]))
% lit(','))
>> lit(')')) | empty_set;
// points
points = lit('(')[_a = SEG_MOVETO] >> point (_a,_r1) % lit(',') [_a = SEG_LINETO] >> lit(')');
// point
point = (double_ >> double_) [push_vertex_(_r1,_r2,_1,_2)];
// <empty set>
empty_set = no_case[lit("EMPTY")];
}
template <typename Iterator>
wkt_collection_grammar<Iterator>::wkt_collection_grammar()
: wkt_collection_grammar::base_type(start)
{
qi::lit_type lit;
qi::no_case_type no_case;
start = wkt | no_case[lit("GEOMETRYCOLLECTION")]
>> (lit("(") >> wkt % lit(",") >> lit(")"));
}
}}

View file

@ -42,6 +42,8 @@
#include <mapnik/boolean.hpp>
#include <mapnik/util/trim.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/wkt/wkt_grammar_impl.hpp>
#include <mapnik/json/geometry_grammar_impl.hpp>
// stl
#include <sstream>

View file

@ -47,8 +47,11 @@
#include <mapnik/proj_transform.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/util/geometry_to_ds_type.hpp>
#include <mapnik/json/feature_collection_parser.hpp>
#include <mapnik/json/generic_json.hpp>
#include <mapnik/json/feature_collection_grammar.hpp>
#include <mapnik/json/feature_grammar_impl.hpp>
#include <mapnik/json/geometry_grammar_impl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
using mapnik::datasource;
using mapnik::parameters;
@ -100,7 +103,6 @@ geojson_datasource::geojson_datasource(parameters const& params)
*params.get<std::string>("encoding","utf-8")),
file_(*params.get<std::string>("file","")),
extent_(),
tr_(new mapnik::transcoder(*params.get<std::string>("encoding","utf-8"))),
features_(),
tree_(16,1)
{
@ -131,11 +133,10 @@ geojson_datasource::geojson_datasource(parameters const& params)
boost::spirit::make_default_multi_pass(base_iterator_type());
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
mapnik::json::generic_json<boost::spirit::multi_pass<base_iterator_type> > json;
// TODO - make it possible for this to be static const
// by avoiding ctor taking arg - https://github.com/mapnik/mapnik/pull/2231
mapnik::json::feature_collection_parser<boost::spirit::multi_pass<base_iterator_type> > p(json, ctx,*tr_);
bool result = p.parse(begin,end, features_);
static const mapnik::transcoder tr("utf8");
static const mapnik::json::feature_collection_grammar<boost::spirit::multi_pass<base_iterator_type>,mapnik::feature_impl> fc_grammar(ctx, tr);
boost::spirit::standard_wide::space_type space;
bool result = boost::spirit::qi::phrase_parse(begin, end, fc_grammar, space, features_);
if (!result)
{
throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + file_ + "'");

View file

@ -71,7 +71,6 @@ private:
mapnik::layer_descriptor desc_;
std::string file_;
mapnik::box2d<double> extent_;
std::shared_ptr<mapnik::transcoder> tr_;
std::vector<mapnik::feature_ptr> features_;
spatial_index_type tree_;
};

View file

@ -31,7 +31,6 @@ plugin_sources = Split(
"""
%(PLUGIN_NAME)s_datasource.cpp
%(PLUGIN_NAME)s_featureset.cpp
%(PLUGIN_NAME)s_grammar.cpp
""" % locals()
)

View file

@ -41,6 +41,7 @@
#include <mapnik/value_types.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/json/topojson_grammar.hpp>
#include <mapnik/json/topojson_grammar_impl.hpp>
#include <mapnik/json/topojson_utils.hpp>
using mapnik::datasource;

View file

@ -1,35 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2013 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/json/topojson_grammar_impl.hpp>
// stl
#include <string>
// boost
#include <boost/spirit/include/support_multi_pass.hpp>
namespace mapnik { namespace topojson {
//template struct topojson_grammar<std::string::const_iterator>;
template struct topojson_grammar<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >;
}}

View file

@ -154,17 +154,14 @@ source = Split(
css_color_grammar.cpp
conversions.cpp
image_compositing.cpp
image_filter_grammar.cpp
image_scaling.cpp
box2d.cpp
datasource_cache.cpp
datasource_cache_static.cpp
debug.cpp
expression_node.cpp
expression_grammar.cpp
expression_string.cpp
expression.cpp
transform_expression_grammar.cpp
transform_expression.cpp
feature_kv_iterator.cpp
feature_style_processor.cpp
@ -183,7 +180,6 @@ source = Split(
parse_path.cpp
parse_transform.cpp
palette.cpp
path_expression_grammar.cpp
plugin.cpp
rule.cpp
save_map.cpp
@ -198,8 +194,6 @@ source = Split(
symbolizer_enumerations.cpp
unicode.cpp
raster_colorizer.cpp
wkt/wkt_factory.cpp
wkt/wkt_generator.cpp
mapped_memory_cache.cpp
marker_cache.cpp
svg/svg_parser.cpp
@ -207,12 +201,6 @@ source = Split(
svg/svg_points_parser.cpp
svg/svg_transform_parser.cpp
warp.cpp
json/geometry_grammar.cpp
json/geometry_parser.cpp
json/feature_grammar.cpp
json/feature_parser.cpp
json/feature_collection_parser.cpp
json/geojson_generator.cpp
text/vertex_cache.cpp
text/layout.cpp
text/text_line.cpp

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
* Copyright (C) 2014 Artem Pavlenko, Jean-Francois Doyon
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,164 +20,12 @@
*
*****************************************************************************/
// NOTE: we define this here in a cpp because def is needed twice:
// once by src/color_factory.cpp and once by include/mapnik/image_filter_grammar.hpp
// otherwise it would make sense to simply do `#include <mapnik/css_color_grammar_impl.hpp>`
// in a single file
#include <mapnik/color.hpp>
#include <mapnik/css_color_grammar_impl.hpp>
namespace mapnik
{
named_colors_::named_colors_()
{
add
("aliceblue", color(240, 248, 255))
("antiquewhite", color(250, 235, 215))
("aqua", color(0, 255, 255))
("aquamarine", color(127, 255, 212))
("azure", color(240, 255, 255))
("beige", color(245, 245, 220))
("bisque", color(255, 228, 196))
("black", color(0, 0, 0))
("blanchedalmond", color(255,235,205))
("blue", color(0, 0, 255))
("blueviolet", color(138, 43, 226))
("brown", color(165, 42, 42))
("burlywood", color(222, 184, 135))
("cadetblue", color(95, 158, 160))
("chartreuse", color(127, 255, 0))
("chocolate", color(210, 105, 30))
("coral", color(255, 127, 80))
("cornflowerblue", color(100, 149, 237))
("cornsilk", color(255, 248, 220))
("crimson", color(220, 20, 60))
("cyan", color(0, 255, 255))
("darkblue", color(0, 0, 139))
("darkcyan", color(0, 139, 139))
("darkgoldenrod", color(184, 134, 11))
("darkgray", color(169, 169, 169))
("darkgreen", color(0, 100, 0))
("darkgrey", color(169, 169, 169))
("darkkhaki", color(189, 183, 107))
("darkmagenta", color(139, 0, 139))
("darkolivegreen", color(85, 107, 47))
("darkorange", color(255, 140, 0))
("darkorchid", color(153, 50, 204))
("darkred", color(139, 0, 0))
("darksalmon", color(233, 150, 122))
("darkseagreen", color(143, 188, 143))
("darkslateblue", color(72, 61, 139))
("darkslategrey", color(47, 79, 79))
("darkturquoise", color(0, 206, 209))
("darkviolet", color(148, 0, 211))
("deeppink", color(255, 20, 147))
("deepskyblue", color(0, 191, 255))
("dimgray", color(105, 105, 105))
("dimgrey", color(105, 105, 105))
("dodgerblue", color(30, 144, 255))
("firebrick", color(178, 34, 34))
("floralwhite", color(255, 250, 240))
("forestgreen", color(34, 139, 34))
("fuchsia", color(255, 0, 255))
("gainsboro", color(220, 220, 220))
("ghostwhite", color(248, 248, 255))
("gold", color(255, 215, 0))
("goldenrod", color(218, 165, 32))
("gray", color(128, 128, 128))
("grey", color(128, 128, 128))
("green", color(0, 128, 0))
("greenyellow", color(173, 255, 47))
("honeydew", color(240, 255, 240))
("hotpink", color(255, 105, 180))
("indianred", color(205, 92, 92))
("indigo", color(75, 0, 130))
("ivory", color(255, 255, 240))
("khaki", color(240, 230, 140))
("lavender", color(230, 230, 250))
("lavenderblush", color(255, 240, 245))
("lawngreen", color(124, 252, 0))
("lemonchiffon", color(255, 250, 205))
("lightblue", color(173, 216, 230))
("lightcoral", color(240, 128, 128))
("lightcyan", color(224, 255, 255))
("lightgoldenrodyellow", color(250, 250, 210))
("lightgray", color(211, 211, 211))
("lightgreen", color(144, 238, 144))
("lightgrey", color(211, 211, 211))
("lightpink", color(255, 182, 193))
("lightsalmon", color(255, 160, 122))
("lightseagreen", color(32, 178, 170))
("lightskyblue", color(135, 206, 250))
("lightslategray", color(119, 136, 153))
("lightslategrey", color(119, 136, 153))
("lightsteelblue", color(176, 196, 222))
("lightyellow", color(255, 255, 224))
("lime", color(0, 255, 0))
("limegreen", color(50, 205, 50))
("linen", color(250, 240, 230))
("magenta", color(255, 0, 255))
("maroon", color(128, 0, 0))
("mediumaquamarine", color(102, 205, 170))
("mediumblue", color(0, 0, 205))
("mediumorchid", color(186, 85, 211))
("mediumpurple", color(147, 112, 219))
("mediumseagreen", color(60, 179, 113))
("mediumslateblue", color(123, 104, 238))
("mediumspringgreen", color(0, 250, 154))
("mediumturquoise", color(72, 209, 204))
("mediumvioletred", color(199, 21, 133))
("midnightblue", color(25, 25, 112))
("mintcream", color(245, 255, 250))
("mistyrose", color(255, 228, 225))
("moccasin", color(255, 228, 181))
("navajowhite", color(255, 222, 173))
("navy", color(0, 0, 128))
("oldlace", color(253, 245, 230))
("olive", color(128, 128, 0))
("olivedrab", color(107, 142, 35))
("orange", color(255, 165, 0))
("orangered", color(255, 69, 0))
("orchid", color(218, 112, 214))
("palegoldenrod", color(238, 232, 170))
("palegreen", color(152, 251, 152))
("paleturquoise", color(175, 238, 238))
("palevioletred", color(219, 112, 147))
("papayawhip", color(255, 239, 213))
("peachpuff", color(255, 218, 185))
("peru", color(205, 133, 63))
("pink", color(255, 192, 203))
("plum", color(221, 160, 221))
("powderblue", color(176, 224, 230))
("purple", color(128, 0, 128))
("red", color(255, 0, 0))
("rosybrown", color(188, 143, 143))
("royalblue", color(65, 105, 225))
("saddlebrown", color(139, 69, 19))
("salmon", color(250, 128, 114))
("sandybrown", color(244, 164, 96))
("seagreen", color(46, 139, 87))
("seashell", color(255, 245, 238))
("sienna", color(160, 82, 45))
("silver", color(192, 192, 192))
("skyblue", color(135, 206, 235))
("slateblue", color(106, 90, 205))
("slategray", color(112, 128, 144))
("slategrey", color(112, 128, 144))
("snow", color(255, 250, 250))
("springgreen", color(0, 255, 127))
("steelblue", color(70, 130, 180))
("tan", color(210, 180, 140))
("teal", color(0, 128, 128))
("thistle", color(216, 191, 216))
("tomato", color(255, 99, 71))
("turquoise", color(64, 224, 208))
("violet", color(238, 130, 238))
("wheat", color(245, 222, 179))
("white", color(255, 255, 255))
("whitesmoke", color(245, 245, 245))
("yellow", color(255, 255, 0))
("yellowgreen", color(154, 205, 50))
("transparent", color(0, 0, 0, 0))
;
}
#include <string>
template struct mapnik::css_color_grammar<std::string::const_iterator>;
}

View file

@ -26,6 +26,7 @@
#include <mapnik/unicode.hpp>
#include <mapnik/expression_node_types.hpp>
#include <mapnik/expression_grammar.hpp>
#include <mapnik/expression_grammar_impl.hpp>
// boost
#include <boost/spirit/include/qi.hpp>

View file

@ -21,7 +21,8 @@
*****************************************************************************/
// mapnik
#include <mapnik/image_filter_types.hpp>
#include <mapnik/image_filter_grammar.hpp> // image_filter_grammar
#include <mapnik/image_filter_grammar.hpp>
#include <mapnik/image_filter_grammar_impl.hpp>
// boost
#include <boost/spirit/include/karma.hpp>

View file

@ -1,56 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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/json/feature_collection_parser.hpp>
#include <mapnik/json/feature_collection_grammar.hpp>
// boost
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
// stl
#include <stdexcept>
namespace mapnik { namespace json {
template <typename Iterator>
feature_collection_parser<Iterator>::feature_collection_parser(generic_json<Iterator> & json,
mapnik::context_ptr const& ctx,
mapnik::transcoder const& tr)
: grammar_(new feature_collection_grammar<iterator_type,feature_type>(json, ctx,tr)) {}
template <typename Iterator>
feature_collection_parser<Iterator>::~feature_collection_parser() {}
template <typename Iterator>
bool feature_collection_parser<Iterator>::parse(iterator_type first, iterator_type last, std::vector<mapnik::feature_ptr> & features)
{
using namespace boost::spirit;
standard_wide::space_type space;
return qi::phrase_parse(first, last, *grammar_, space, features);
}
template class feature_collection_parser<std::string::const_iterator> ;
template class feature_collection_parser<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >;
}}

View file

@ -1,50 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2013 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/json/feature_parser.hpp>
#include <mapnik/json/feature_grammar.hpp>
// boost
#include <boost/version.hpp>
#include <boost/spirit/include/qi.hpp>
namespace mapnik { namespace json {
template <typename Iterator>
feature_parser<Iterator>::feature_parser(generic_json<Iterator> & json, mapnik::transcoder const& tr)
: grammar_(new feature_grammar<iterator_type,feature_type>(json, tr)) {}
template <typename Iterator>
feature_parser<Iterator>::~feature_parser() {}
template <typename Iterator>
bool feature_parser<Iterator>::parse(iterator_type first, iterator_type last, mapnik::feature_impl & f)
{
using namespace boost::spirit;
standard_wide::space_type space;
return qi::phrase_parse(first, last, (*grammar_)(boost::phoenix::ref(f)), space);
}
template class feature_parser<std::string::const_iterator>;
}}

View file

@ -1,65 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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/json/geometry_parser.hpp>
#include <mapnik/json/geometry_grammar.hpp>
// boost
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
// stl
#include <stdexcept>
namespace mapnik { namespace json {
template <typename Iterator>
geometry_parser<Iterator>::geometry_parser()
: grammar_(new geometry_grammar<iterator_type>()) {}
template <typename Iterator>
geometry_parser<Iterator>::~geometry_parser() {}
template <typename Iterator>
bool geometry_parser<Iterator>::parse(iterator_type first, iterator_type last, boost::ptr_vector<mapnik::geometry_type>& paths)
{
using namespace boost::spirit;
standard_wide::space_type space;
return qi::phrase_parse(first, last, (*grammar_)(boost::phoenix::ref(paths)), space);
}
bool from_geojson(std::string const& json, boost::ptr_vector<geometry_type> & paths)
{
using namespace boost::spirit;
static const geometry_grammar<std::string::const_iterator> g;
standard_wide::space_type space;
std::string::const_iterator start = json.begin();
std::string::const_iterator end = json.end();
return qi::phrase_parse(start, end, (g)(boost::phoenix::ref(paths)), space);
}
template class geometry_parser<std::string::const_iterator> ;
template class geometry_parser<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >;
}}

View file

@ -22,7 +22,7 @@
#include <mapnik/parse_path.hpp>
#include <mapnik/path_expression_grammar.hpp>
#include <mapnik/path_expression_grammar_impl.hpp>
#include <mapnik/config.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/feature.hpp>

View file

@ -22,7 +22,7 @@
#include <mapnik/parse_transform.hpp>
#include <mapnik/transform_expression_grammar.hpp>
#include <mapnik/transform_processor.hpp>
#include <mapnik/transform_expression_grammar_impl.hpp>
// stl
#include <string>

View file

@ -25,6 +25,10 @@
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/svg/output/svg_renderer.hpp>
#include <mapnik/svg/geometry_svg_generator_impl.hpp>
#include <mapnik/svg/output/svg_output_grammars.hpp>
#include <boost/spirit/include/karma.hpp>
#include <mapnik/svg/output/svg_output_attributes.hpp>
namespace mapnik {
@ -50,6 +54,20 @@ bool is_path_based(symbolizer const& sym)
return boost::apply_visitor(symbol_type_dispatch(), sym);
}
template <typename OutputIterator, typename PathType>
void generate_path(OutputIterator & output_iterator, PathType const& path, svg::path_output_attributes const& path_attributes)
{
using path_dash_array_grammar = svg::svg_path_dash_array_grammar<OutputIterator>;
using path_attributes_grammar = svg::svg_path_attributes_grammar<OutputIterator>;
static const path_attributes_grammar attributes_grammar;
static const path_dash_array_grammar dash_array_grammar;
static const svg::svg_path_generator<OutputIterator,PathType> svg_path_grammer;
boost::spirit::karma::lit_type lit;
boost::spirit::karma::generate(output_iterator, lit("<path ") << svg_path_grammer, path);
boost::spirit::karma::generate(output_iterator, lit(" ") << dash_array_grammar, path_attributes.stroke_dasharray());
boost::spirit::karma::generate(output_iterator, lit(" ") << attributes_grammar << lit("/>\n"), path_attributes);
}
template <typename OutputIterator>
bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms,
mapnik::feature_impl & feature,
@ -79,7 +97,7 @@ bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms,
if(geom.size() > 0)
{
path_type path(common_.t_, geom, prj_trans);
generator_.generate_path(path, path_attributes_);
generate_path(generator_.output_iterator_, path, path_attributes_);
}
}
// set the previously collected values back to their defaults

View file

@ -26,6 +26,7 @@
#include <mapnik/svg/output/svg_generator.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/svg/output/svg_output_grammars.hpp>
// boost
#include <boost/spirit/include/karma.hpp>
@ -52,7 +53,8 @@ namespace mapnik { namespace svg {
template <typename OutputIterator>
void svg_generator<OutputIterator>::generate_opening_root(root_output_attributes const& root_attributes)
{
root_attributes_grammar attributes_grammar;
using root_attributes_grammar = svg::svg_root_attributes_grammar<OutputIterator>;
static const root_attributes_grammar attributes_grammar;
karma::lit_type lit;
karma::generate(output_iterator_, lit("<svg ") << attributes_grammar << lit(">\n"), root_attributes);
}
@ -67,7 +69,8 @@ namespace mapnik { namespace svg {
template <typename OutputIterator>
void svg_generator<OutputIterator>::generate_rect(rect_output_attributes const& rect_attributes)
{
rect_attributes_grammar attributes_grammar;
using rect_attributes_grammar = svg::svg_rect_attributes_grammar<OutputIterator>;
static const rect_attributes_grammar attributes_grammar;
karma::lit_type lit;
karma::generate(output_iterator_, lit("<rect ") << attributes_grammar << lit("/>\n"), rect_attributes);
}

View file

@ -24,9 +24,6 @@
#include <mapnik/expression_string.hpp>
#include <mapnik/transform_expression.hpp>
// boost
// stl
#include <sstream>

View file

@ -1,59 +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
*
*****************************************************************************/
// mapnik
#include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/wkt/wkt_grammar.hpp>
// stl
#include <string>
#include <sstream>
#include <stdexcept>
namespace mapnik
{
wkt_parser::wkt_parser()
: grammar_(new mapnik::wkt::wkt_collection_grammar<iterator_type>)
{}
bool wkt_parser::parse(std::string const& wkt, boost::ptr_vector<geometry_type> & paths)
{
using namespace boost::spirit;
ascii::space_type space;
iterator_type first = wkt.begin();
iterator_type last = wkt.end();
return qi::phrase_parse(first, last, *grammar_, space, paths);
}
bool from_wkt(std::string const& wkt, boost::ptr_vector<geometry_type> & paths)
{
using namespace boost::spirit;
static const mapnik::wkt::wkt_collection_grammar<std::string::const_iterator> g;
ascii::space_type space;
std::string::const_iterator first = wkt.begin();
std::string::const_iterator last = wkt.end();
return qi::phrase_parse(first, last, g, space, paths);
}
}

View file

@ -13,10 +13,10 @@
#include <mapnik/vertex_converters.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/wkt/wkt_grammar_impl.hpp>
#include <mapnik/well_known_srs.hpp>
#include <mapnik/util/geometry_to_wkb.hpp>
#include <mapnik/util/geometry_to_wkt.hpp>
#include <mapnik/util/geometry_to_svg.hpp>
#include <mapnik/wkt/wkt_generator_grammar.hpp>
#include <mapnik/wkt/wkt_generator_grammar_impl.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/proj_transform.hpp>
@ -25,7 +25,7 @@
struct output_geometry_backend
{
output_geometry_backend(boost::ptr_vector<mapnik::geometry_type> & paths, mapnik::geometry_type::types type)
output_geometry_backend(mapnik::geometry_container & paths, mapnik::geometry_type::types type)
: paths_(paths),
type_(type) {}
@ -43,7 +43,7 @@ struct output_geometry_backend
}
paths_.push_back(geom_ptr.release());
}
boost::ptr_vector<mapnik::geometry_type> & paths_;
mapnik::geometry_container & paths_;
mapnik::geometry_type::types type_;
};
@ -57,7 +57,7 @@ boost::optional<std::string> linestring_bbox_clipping(mapnik::box2d<double> bbox
proj_transform prj_trans(src,dst);
line_symbolizer sym;
CoordTransform t(bbox.width(),bbox.height(), bbox);
boost::ptr_vector<mapnik::geometry_type> output_paths;
mapnik::geometry_container output_paths;
output_geometry_backend backend(output_paths, mapnik::geometry_type::types::LineString);
using conv_types = boost::mpl::vector<clip_line_tag>;
@ -69,7 +69,7 @@ boost::optional<std::string> linestring_bbox_clipping(mapnik::box2d<double> bbox
converter.set<clip_line_tag>();
boost::ptr_vector<geometry_type> p;
mapnik::geometry_container p;
if (!mapnik::from_wkt(wkt_in , p))
{
throw std::runtime_error("Failed to parse WKT");
@ -80,12 +80,14 @@ boost::optional<std::string> linestring_bbox_clipping(mapnik::box2d<double> bbox
converter.apply(geom);
}
std::string wkt_out;
if (mapnik::util::to_wkt(wkt_out, output_paths))
using sink_type = std::back_insert_iterator<std::string>;
std::string wkt; // Use Python String directly ?
sink_type sink(wkt);
static const mapnik::wkt::wkt_multi_generator<sink_type, mapnik::geometry_container> generator;
if (boost::spirit::karma::generate(sink, generator, output_paths))
{
return boost::optional<std::string>(wkt_out);
return boost::optional<std::string>(wkt);
}
return boost::optional<std::string>();
}
@ -99,7 +101,7 @@ boost::optional<std::string> polygon_bbox_clipping(mapnik::box2d<double> bbox,
proj_transform prj_trans(src,dst);
polygon_symbolizer sym;
CoordTransform t(bbox.width(),bbox.height(), bbox);
boost::ptr_vector<mapnik::geometry_type> output_paths;
mapnik::geometry_container output_paths;
output_geometry_backend backend(output_paths, mapnik::geometry_type::types::Polygon);
using conv_types = boost::mpl::vector<clip_poly_tag>;
@ -111,7 +113,7 @@ boost::optional<std::string> polygon_bbox_clipping(mapnik::box2d<double> bbox,
converter.set<clip_poly_tag>();
boost::ptr_vector<geometry_type> p;
mapnik::geometry_container p;
if (!mapnik::from_wkt(wkt_in , p))
{
throw std::runtime_error("Failed to parse WKT");
@ -122,10 +124,13 @@ boost::optional<std::string> polygon_bbox_clipping(mapnik::box2d<double> bbox,
converter.apply(geom);
}
std::string wkt_out;
if (mapnik::util::to_wkt(wkt_out, output_paths))
using sink_type = std::back_insert_iterator<std::string>;
std::string wkt; // Use Python String directly ?
sink_type sink(wkt);
static const mapnik::wkt::wkt_multi_generator<sink_type, mapnik::geometry_container> generator;
if (boost::spirit::karma::generate(sink, generator, output_paths))
{
return boost::optional<std::string>(wkt_out);
return boost::optional<std::string>(wkt);
}
return boost::optional<std::string>();

View file

@ -122,15 +122,10 @@ def test_geojson_parsing():
pass
eq_(count,len(path))
reader = mapnik.WKTReader()
def compare_wkb_from_wkt(wkt,num=None):
# create a Path from geometry(s)
# easy api, but slower
#paths = mapnik.Path.from_wkt(wkt)
# fast api
paths = reader.read(wkt);
paths = mapnik.Path.from_wkt(wkt)
# add geometry(s) to feature from wkt
f = mapnik.Feature(mapnik.Context(),1)
@ -160,11 +155,7 @@ def compare_wkb_from_wkt(wkt,num=None):
eq_(f.geometries()[idx].to_wkb(mapnik.wkbByteOrder.XDR),path.to_wkb(mapnik.wkbByteOrder.XDR))
def compare_wkt_from_wkt(wkt,num=None):
# create a Path from geometry(s)
# easy api, but slower
#paths = mapnik.Path.from_wkt(wkt)
# fast api
paths = reader.read(wkt);
paths = mapnik.Path.from_wkt(wkt)
# add geometry(s) to feature from wkt
f = mapnik.Feature(mapnik.Context(),1)
@ -197,7 +188,7 @@ def compare_wkt_from_wkt(wkt,num=None):
eq_(f.geometries()[idx].to_wkb(mapnik.wkbByteOrder.XDR),path.to_wkb(mapnik.wkbByteOrder.XDR))
def compare_wkt_to_geojson(idx,wkt,num=None):
paths = reader.read(wkt);
paths = mapnik.Path.from_wkt(wkt)
# ensure both have same result
if num:
eq_(len(paths),num)
@ -233,10 +224,7 @@ def test_wkt_to_geojson():
@raises(IndexError)
def test_geometry_index_error():
wkt = 'Point (0 0)'
# easy api, but slower
#paths = mapnik.Path.from_wkt(wkt)
# fast api
paths = reader.read(wkt);
paths = mapnik.Path.from_wkt(wkt)
paths[3]
f = mapnik.Feature(mapnik.Context(),1)
f.add_geometries_from_wkt(wkt)