Merge pull request #2314 from mapnik/grammar-refactor

Grammar refactor
This commit is contained in:
Dane Springmeyer 2014-07-24 17:20:51 -07:00
commit ea5b4f56d0
65 changed files with 1004 additions and 1354 deletions

View file

@ -1,8 +1,8 @@
language: cpp language: cpp
compiler: compiler:
- gcc
- clang - clang
- gcc
addons: addons:
postgresql: "9.3" postgresql: "9.3"
@ -29,7 +29,7 @@ before_install:
install: install:
- if [[ "${CXX}" == 'g++' ]]; then export CXX="g++-4.8" && export CC="gcc-4.8"; fi; - if [[ "${CXX}" == 'g++' ]]; then export CXX="g++-4.8" && export CC="gcc-4.8"; fi;
- ./configure CXX="${CXX}" CC="${CC}" DEMO=True BENCHMARK=True CPP_TESTS=True CAIRO=True FAST=True - ./configure CXX="${CXX}" CC="${CC}" DEMO=True BENCHMARK=True CPP_TESTS=True CAIRO=True FAST=True
- JOBS=2 make - if [[ "${CXX}" == 'g++-4.8' ]]; then JOBS=3 make; else JOBS=8 make; fi;
before_script: before_script:
- make test - make test

View file

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

View file

@ -30,7 +30,6 @@
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
// mapnik // mapnik
#include <mapnik/value_types.hpp> #include <mapnik/value_types.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
@ -40,8 +39,7 @@
#include <mapnik/wkb.hpp> #include <mapnik/wkb.hpp>
#include <mapnik/wkt/wkt_factory.hpp> #include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/json/feature_parser.hpp> #include <mapnik/json/feature_parser.hpp>
#include <mapnik/json/geojson_generator.hpp> #include <mapnik/json/feature_generator.hpp>
#include <mapnik/json/generic_json.hpp>
// stl // stl
#include <stdexcept> #include <stdexcept>
@ -49,7 +47,6 @@
namespace { namespace {
using mapnik::geometry_utils; using mapnik::geometry_utils;
using mapnik::from_wkt;
using mapnik::context_type; using mapnik::context_type;
using mapnik::context_ptr; using mapnik::context_ptr;
using mapnik::feature_kv_iterator; 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; 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; 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()); bool result = geometry_utils::from_wkb(feature.paths(), wkb.c_str(), wkb.size());
if (!result) throw std::runtime_error("Failed to parse WKB"); 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()); bool result = mapnik::from_wkt(wkt, feature.paths());
if (!result) throw std::runtime_error("Failed to parse WKT"); 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::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::feature_ptr feature(mapnik::feature_factory::create(ctx,1));
mapnik::json::generic_json<std::string::const_iterator> json_base; if (!mapnik::json::from_geojson(json,*feature))
mapnik::json::feature_parser<std::string::const_iterator> parser(json_base, tr);
if (!parser.parse(json.begin(), json.end(), *feature))
{ {
throw std::runtime_error("Failed to parse geojson 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 feature_to_geojson(mapnik::feature_impl const& feature)
{ {
std::string json; std::string json;
mapnik::json::feature_generator g; if (!mapnik::json::to_geojson(json,feature))
if (!g.generate(json,feature))
{ {
throw std::runtime_error("Failed to generate GeoJSON"); throw std::runtime_error("Failed to generate GeoJSON");
} }

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2013 Artem Pavlenko, Jean-Francois Doyon * Copyright (C) 2014 Artem Pavlenko, Jean-Francois Doyon
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,37 +20,17 @@
* *
*****************************************************************************/ *****************************************************************************/
#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/geometry.hpp>
#include <mapnik/wkt/wkt_factory.hpp> #include <mapnik/wkt/wkt_generator_grammar_impl.hpp>
#include <mapnik/json/feature_generator_grammar_impl.hpp>
#include <mapnik/json/geometry_generator_grammar_impl.hpp>
#include <mapnik/svg/geometry_svg_generator_impl.hpp>
#include <string>
namespace impl { using sink_type = std::back_insert_iterator<std::string>;
template struct mapnik::json::feature_generator_grammar<sink_type>;
using path_type = boost::ptr_vector<mapnik::geometry_type>; template struct mapnik::json::geometry_generator_grammar<sink_type>;
template struct mapnik::json::multi_geometry_generator_grammar<sink_type>;
std::shared_ptr<path_type> from_wkt(mapnik::wkt_parser & p, std::string const& wkt) template struct mapnik::svg::svg_path_generator<sink_type, mapnik::geometry_type>;
{ template struct mapnik::wkt::wkt_generator<sink_type, mapnik::geometry_type>;
std::shared_ptr<path_type> paths = std::make_shared<path_type>(); template struct mapnik::wkt::wkt_multi_generator<sink_type, mapnik::geometry_container>;
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

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

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2012 Artem Pavlenko * Copyright (C) 2014 Artem Pavlenko, Jean-Francois Doyon
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,13 +20,13 @@
* *
*****************************************************************************/ *****************************************************************************/
// mapnik #include <mapnik/feature.hpp>
#include <mapnik/expression_grammar_impl.hpp> #include <mapnik/wkt/wkt_grammar_impl.hpp>
// stl #include <mapnik/json/feature_grammar_impl.hpp>
#include <mapnik/json/geometry_grammar_impl.hpp>
#include <string> #include <string>
namespace mapnik { using iterator_type = std::string::const_iterator;
template struct mapnik::wkt::wkt_collection_grammar<iterator_type>;
template struct mapnik::expression_grammar<std::string::const_iterator>; template struct mapnik::json::feature_grammar<iterator_type,mapnik::feature_impl>;
template struct mapnik::json::geometry_grammar<iterator_type>;
}

View file

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

View file

@ -62,7 +62,158 @@ using ascii_space_type = boost::spirit::ascii::space_type;
struct named_colors_ : qi::symbols<char,color> 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 // clipper helper

View file

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

View file

@ -126,6 +126,4 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
no_args = -(lit('(') >> lit(')')); 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 : struct feature_collection_grammar :
qi::grammar<Iterator, std::vector<feature_ptr>(), space_type> 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_collection_grammar::base_type(start,"start"),
feature_g(json,tr), feature_g(tr),
ctx_(ctx), ctx_(ctx),
generate_id_(1) generate_id_(1)
{ {
@ -81,7 +81,7 @@ struct feature_collection_grammar :
start = feature_collection | feature_from_geometry(_val) | feature(_val) 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\"") 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

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2013 Artem Pavlenko * Copyright (C) 2012 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,16 +20,26 @@
* *
*****************************************************************************/ *****************************************************************************/
#ifndef MAPNIK_JSON_FEATURE_GENERATOR_HPP
#define MAPNIK_JSON_FEATURE_GENERATOR_HPP
// mapnik // mapnik
#include <mapnik/json/topojson_grammar_impl.hpp> #include <mapnik/feature.hpp>
// stl #include <mapnik/json/feature_generator_grammar.hpp>
#include <string>
// boost // boost
#include <boost/spirit/include/support_multi_pass.hpp> #include <boost/spirit/include/karma.hpp>
namespace mapnik { namespace topojson { namespace mapnik { namespace json {
//template struct topojson_grammar<std::string::const_iterator>; inline bool to_geojson(std::string & json, mapnik::feature_impl const& feature)
template struct topojson_grammar<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >; {
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 #define MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
// mapnik // mapnik
#include <mapnik/global.hpp>
#include <mapnik/value_types.hpp> #include <mapnik/value_types.hpp>
#include <mapnik/value.hpp> #include <mapnik/value.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
@ -34,10 +33,10 @@
// boost // boost
#include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.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_core.hpp>
#include <boost/spirit/include/phoenix_operator.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/adapted/std_tuple.hpp>
#include <boost/fusion/include/at.hpp> #include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/cons.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 mapnik { namespace json {
namespace karma = boost::spirit::karma; namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
struct get_id struct get_id
{ {
@ -115,7 +113,6 @@ struct make_properties_range
} }
}; };
struct utf8 struct utf8
{ {
template <typename T> template <typename T>
@ -144,36 +141,9 @@ template <typename OutputIterator>
struct escaped_string struct escaped_string
: karma::grammar<OutputIterator, std::string(char const*)> : karma::grammar<OutputIterator, std::string(char const*)>
{ {
escaped_string() 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)
;
}
karma::rule<OutputIterator, std::string(char const*)> esc_str; karma::rule<OutputIterator, std::string(char const*)> esc_str;
karma::symbols<char, char const*> esc_char; karma::symbols<char, char const*> esc_char;
}; };
template <typename OutputIterator> template <typename OutputIterator>
@ -183,50 +153,7 @@ struct feature_generator_grammar:
using pair_type = std::tuple<std::string, mapnik::value>; using pair_type = std::tuple<std::string, mapnik::value>;
using range_type = make_properties_range::properties_range_type; using range_type = make_properties_range::properties_range_type;
feature_generator_grammar() 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
karma::rule<OutputIterator, mapnik::feature_impl const&()> feature; karma::rule<OutputIterator, mapnik::feature_impl const&()> feature;
multi_geometry_generator_grammar<OutputIterator> geometry; multi_geometry_generator_grammar<OutputIterator> geometry;
escaped_string<OutputIterator> escaped_string_; 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_null()> value_null_;
karma::rule<OutputIterator, mapnik::value_unicode_string()> ustring; karma::rule<OutputIterator, mapnik::value_unicode_string()> ustring;
typename karma::int_generator<mapnik::value_integer,10, false> int__; typename karma::int_generator<mapnik::value_integer,10, false> int__;
// phoenix functions boost::phoenix::function<get_id> id_;
phoenix::function<get_id> id_; boost::phoenix::function<value_base> value_base_;
phoenix::function<value_base> value_base_; boost::phoenix::function<utf8> utf8_;
phoenix::function<utf8> utf8_;
std::string quote_; 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 struct extract_geometry
{ {
using result_type = boost::ptr_vector<mapnik::geometry_type>&; using result_type = mapnik::geometry_container&;
template <typename T> template <typename T>
result_type operator() (T & feature) const result_type operator() (T & feature) const
{ {
@ -95,11 +95,11 @@ struct feature_grammar :
qi::grammar<Iterator, void(FeatureType&), qi::grammar<Iterator, void(FeatureType&),
space_type> space_type>
{ {
feature_grammar(generic_json<Iterator> & json, mapnik::transcoder const& tr); feature_grammar(mapnik::transcoder const& tr);
// start // start
// generic JSON // generic JSON
generic_json<Iterator> & json_; generic_json<Iterator> json_;
// geoJSON // geoJSON
qi::rule<Iterator,void(FeatureType&),space_type> feature; // START qi::rule<Iterator,void(FeatureType&),space_type> feature; // START

View file

@ -30,9 +30,9 @@
namespace mapnik { namespace json { namespace mapnik { namespace json {
template <typename Iterator, typename FeatureType> 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"), : feature_grammar::base_type(feature,"feature"),
json_(json), json_(),
put_property_(put_property(tr)) put_property_(put_property(tr))
{ {
qi::lit_type lit; 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 #ifndef MAPNIK_JSON_FEATURE_PARSER_HPP
#define MAPNIK_FEATURE_PARSER_HPP #define MAPNIK_JSON_FEATURE_PARSER_HPP
// mapnik // mapnik
#include <mapnik/config.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/noncopyable.hpp> #include <mapnik/json/feature_grammar.hpp>
#include <mapnik/unicode.hpp>
// boost // boost
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
// stl #include <boost/spirit/include/phoenix_core.hpp>
#include <vector>
namespace mapnik { namespace json { namespace mapnik { namespace json {
template <typename Iterator, typename FeatureType> struct feature_grammar; inline bool from_geojson(std::string const& json, mapnik::feature_impl & feature)
template <typename Iterator> struct generic_json;
template <typename Iterator>
class MAPNIK_DECL feature_parser : private mapnik::noncopyable
{ {
using iterator_type = Iterator; static const mapnik::transcoder tr("utf8");
using feature_type = mapnik::feature_impl; using iterator_type = std::string::const_iterator;
public: static const mapnik::json::feature_grammar<iterator_type,mapnik::feature_impl> g(tr);
feature_parser(generic_json<Iterator> & json, mapnik::transcoder const& tr); using namespace boost::spirit;
~feature_parser(); standard_wide::space_type space;
bool parse(iterator_type first, iterator_type last, mapnik::feature_impl & f); return qi::phrase_parse(json.begin(), json.end(), (g)(boost::phoenix::ref(feature)), space);
private: }
const std::unique_ptr<feature_grammar<iterator_type,feature_type> > grammar_;
};
}} }}
#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 // boost
#include <boost/spirit/include/karma.hpp> #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_function.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/fusion/adapted/std_tuple.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 //stl
#include <tuple> #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 mapnik { namespace json {
namespace karma = boost::spirit::karma; namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
namespace { namespace {
@ -149,61 +134,7 @@ template <typename OutputIterator>
struct geometry_generator_grammar : struct geometry_generator_grammar :
karma::grammar<OutputIterator, geometry_type const& ()> karma::grammar<OutputIterator, geometry_type const& ()>
{ {
geometry_generator_grammar();
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
karma::rule<OutputIterator, geometry_type const& ()> coordinates; karma::rule<OutputIterator, geometry_type const& ()> coordinates;
karma::rule<OutputIterator, geometry_type const& ()> point; karma::rule<OutputIterator, geometry_type const& ()> point;
karma::rule<OutputIterator, geometry_type const& ()> linestring; 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, karma::locals<unsigned>, geometry_type const& ()> coords2;
karma::rule<OutputIterator, geometry_type::value_type ()> point_coord; karma::rule<OutputIterator, geometry_type::value_type ()> point_coord;
karma::rule<OutputIterator, geometry_type::value_type (unsigned& )> polygon_coord; karma::rule<OutputIterator, geometry_type::value_type (unsigned& )> polygon_coord;
boost::phoenix::function<get_type > _type;
// phoenix functions boost::phoenix::function<get_first> _first;
phoenix::function<get_type > _type;
phoenix::function<get_first> _first;
//
karma::real_generator<double, json_coordinate_policy<double> > coord_type; 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> >, karma::grammar<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
geometry_container const& ()> geometry_container const& ()>
{ {
multi_geometry_generator_grammar();
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
karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >, karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
geometry_container const&()> start; geometry_container const&()> start;
karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >, karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
@ -290,11 +165,9 @@ struct multi_geometry_generator_grammar :
geometry_type const&()> geometry2; geometry_type const&()> geometry2;
karma::rule<OutputIterator, geometry_container const&()> coordinates; karma::rule<OutputIterator, geometry_container const&()> coordinates;
geometry_generator_grammar<OutputIterator> path; geometry_generator_grammar<OutputIterator> path;
// phoenix boost::phoenix::function<multi_geometry_type> multi_type_;
phoenix::function<multi_geometry_type> multi_type_; boost::phoenix::function<get_type > type_;
phoenix::function<get_type > type_; boost::phoenix::function<not_empty> not_empty_;
phoenix::function<not_empty> not_empty_;
// symbols table
karma::symbols<unsigned, char const*> geometry_types; 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> template <typename Iterator>
struct geometry_grammar : 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> , space_type>
{ {
geometry_grammar(); 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::symbols<char, int> geometry_dispatch;
qi::rule<Iterator,void(CommandType,geometry_type*),space_type> point; 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,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*>, 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*>, 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*>, 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(mapnik::geometry_container& ),space_type> multipoint_coordinates;
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multilinestring_coordinates; qi::rule<Iterator,void(mapnik::geometry_container& ),space_type> multilinestring_coordinates;
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multipolygon_coordinates; qi::rule<Iterator,void(mapnik::geometry_container& ),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> geometry_collection;
// Nabialek trick ////////////////////////////////////// // Nabialek trick //////////////////////////////////////
//using dispatch_rule = typename qi::rule<Iterator,void(FeatureType &), space_type>; //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 #define MAPNIK_JSON_GEOMETRY_PARSER_HPP
// mapnik // mapnik
#include <mapnik/config.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/noncopyable.hpp> #include <mapnik/json/geometry_grammar.hpp>
// boost // boost
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
// stl #include <boost/spirit/include/phoenix_core.hpp>
//#include <vector>
namespace mapnik { namespace json { namespace mapnik { namespace json {
template <typename Iterator> struct geometry_grammar; inline bool from_geojson(std::string const& json, boost::ptr_vector<geometry_type> & paths)
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
{ {
using iterator_type = Iterator; using namespace boost::spirit;
public: static const geometry_grammar<std::string::const_iterator> g;
geometry_parser(); standard_wide::space_type space;
~geometry_parser(); std::string::const_iterator start = json.begin();
bool parse(iterator_type first, iterator_type last, boost::ptr_vector<mapnik::geometry_type>&); std::string::const_iterator end = json.end();
private: return qi::phrase_parse(start, end, (g)(boost::phoenix::ref(paths)), space);
const std::unique_ptr<geometry_grammar<iterator_type> > grammar_; }
};
}} }}
#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()> 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>; 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"), : symbolizer_grammar::base_type(sym, "symbolizer"),
json_(json) json_()
{ {
using qi::lit; using qi::lit;
using qi::double_; using qi::double_;
@ -201,7 +201,7 @@ struct symbolizer_grammar : qi::grammar<Iterator, space_type, symbolizer()>
} }
// generic JSON // generic JSON
generic_json<Iterator> & json_; generic_json<Iterator> json_;
// symbolizer // symbolizer
qi::rule<Iterator, space_type, mapnik::symbolizer()> sym; qi::rule<Iterator, space_type, mapnik::symbolizer()> sym;
qi::rule<Iterator,qi::locals<std::string>, void(mapnik::symbolizer&),space_type> property; 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_ -'[')]; 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 #ifndef MAPNIK_GEOMETRY_SVG_PATH_GENERATOR_HPP
#define MAPNIK_GEOMETRY_SVG_GENERATOR_HPP #define MAPNIK_GEOMETRY_SVG_PATH_GENERATOR_HPP
// mapnik // 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 karma = boost::spirit::karma;
namespace phoenix = boost::phoenix; namespace phoenix = boost::phoenix;
@ -124,52 +124,14 @@ namespace mapnik { namespace util {
} }
template <typename OutputIterator, typename Geometry> template <typename OutputIterator, typename Geometry>
struct svg_generator : struct svg_path_generator :
karma::grammar<OutputIterator, Geometry const& ()> karma::grammar<OutputIterator, Geometry const& ()>
{ {
using geometry_type = Geometry; using geometry_type = Geometry;
using coord_type = typename boost::remove_pointer<typename geometry_type::value_type>::type; using coord_type = typename boost::remove_pointer<typename geometry_type::value_type>::type;
svg_generator() svg_path_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(' ')
;
}
// rules // rules
karma::rule<OutputIterator, geometry_type const& ()> svg; karma::rule<OutputIterator, geometry_type const& ()> svg;
karma::rule<OutputIterator, geometry_type const& ()> point; 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/ctrans.hpp>
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/util/geometry_svg_generator.hpp> #include <mapnik/svg/geometry_svg_generator.hpp>
#include <mapnik/svg/output/svg_output_grammars.hpp>
#include <mapnik/svg/output/svg_output_attributes.hpp> #include <mapnik/svg/output/svg_output_attributes.hpp>
#include <mapnik/noncopyable.hpp> #include <mapnik/noncopyable.hpp>
#include <mapnik/value_types.hpp> #include <mapnik/value_types.hpp>
@ -53,11 +52,6 @@ namespace mapnik { namespace svg {
template <typename OutputIterator> template <typename OutputIterator>
class svg_generator : private mapnik::noncopyable 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: public:
explicit svg_generator(OutputIterator& output_iterator); explicit svg_generator(OutputIterator& output_iterator);
~svg_generator(); ~svg_generator();
@ -69,19 +63,6 @@ namespace mapnik { namespace svg {
void generate_opening_group(mapnik::value_integer val); void generate_opening_group(mapnik::value_integer val);
void generate_opening_group(std::string const& val); void generate_opening_group(std::string const& val);
void generate_closing_group(); 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_; OutputIterator& output_iterator_;
}; };
}} }}

View file

@ -24,11 +24,14 @@
#define MAPNIK_TRANSFORM_EXPRESSION_HPP #define MAPNIK_TRANSFORM_EXPRESSION_HPP
// mapnik // 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> #include <mapnik/expression_node.hpp>
// boost // boost
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <memory>
#include <boost/variant/variant.hpp> #include <boost/variant/variant.hpp>
// fusion // fusion
@ -37,6 +40,7 @@
// stl // stl
#include <vector> #include <vector>
#include <memory>
namespace mapnik { namespace mapnik {

View file

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

View file

@ -22,6 +22,7 @@
// mapnik // mapnik
#include <mapnik/transform_expression_grammar.hpp> #include <mapnik/transform_expression_grammar.hpp>
#include <mapnik/expression_grammar_impl.hpp>
// boost // boost
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
@ -127,6 +128,4 @@ transform_expression_grammar<Iterator>::transform_expression_grammar()
expr = g_.expr.alias(); 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> #include <mapnik/expression_evaluator.hpp>
// boost // boost
#include <boost/variant/static_visitor.hpp> #include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp> #include <boost/variant/apply_visitor.hpp>
#include <boost/range/adaptor/reversed.hpp> #include <boost/range/adaptor/reversed.hpp>

View file

@ -35,6 +35,10 @@ namespace boost { namespace spirit { namespace traits {
template <> template <>
struct is_container<mapnik::geometry_type const> : mpl::true_ {} ; 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 <> template <>
struct container_iterator<mapnik::geometry_type const> struct container_iterator<mapnik::geometry_type const>
{ {

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,36 +20,31 @@
* *
*****************************************************************************/ *****************************************************************************/
// boost #ifndef MAPNIK_GEOMETRY_TO_GEOJSON_HPP
#include <mapnik/feature.hpp> #define MAPNIK_GEOMETRY_TO_GEOJSON_HPP
#include <mapnik/json/geojson_generator.hpp>
#include <mapnik/json/feature_generator_grammar.hpp> // mapnik
#include <mapnik/geometry.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp> #include <mapnik/json/geometry_generator_grammar.hpp>
#include <boost/spirit/include/karma.hpp> namespace mapnik { namespace util {
namespace mapnik { namespace json { inline bool to_geojson(std::string & json, mapnik::geometry_type const& geom)
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)
{ {
sink_type sink(geojson); using sink_type = std::back_insert_iterator<std::string>;
return karma::generate(sink, *grammar_,f); 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() inline bool to_geojson(std::string & json, mapnik::geometry_container const& geom)
: grammar_(new multi_geometry_generator_grammar<sink_type>()) {}
geometry_generator::~geometry_generator() {}
bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
{ {
sink_type sink(geojson); using sink_type = std::back_insert_iterator<std::string>;
return karma::generate(sink, *grammar_,g); 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 // mapnik
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/util/geometry_svg_generator.hpp> #include <mapnik/svg/geometry_svg_generator.hpp>
// boost // boost
#include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma.hpp>
@ -35,11 +35,11 @@ namespace mapnik { namespace util {
namespace karma = boost::spirit::karma; 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>; using sink_type = std::back_insert_iterator<std::string>;
sink_type sink(svg); 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); bool result = karma::generate(sink, generator, geom);
return result; return result;
} }

View file

@ -24,16 +24,27 @@
#define MAPNIK_GEOMETRY_TO_WKT_HPP #define MAPNIK_GEOMETRY_TO_WKT_HPP
// mapnik // mapnik
#include <mapnik/config.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_generator_grammar.hpp>
namespace mapnik { namespace util { 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 #endif // MAPNIK_GEOMETRY_TO_WKT_HPP

View file

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

View file

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

View file

@ -27,6 +27,7 @@
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/vertex.hpp> // for CommandType::SEG_MOVETO #include <mapnik/vertex.hpp> // for CommandType::SEG_MOVETO
#include <mapnik/util/container_adapter.hpp>
// boost // boost
#include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma.hpp>
@ -37,22 +38,12 @@
#include <boost/spirit/include/phoenix_statement.hpp> #include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/fusion/adapted/std_tuple.hpp> #include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/type_traits/remove_pointer.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 // stl
#include <tuple> #include <tuple>
namespace boost { namespace spirit { namespace traits { namespace mapnik { namespace wkt {
// make gcc and darwin toolsets happy.
template <>
struct is_container<mapnik::geometry_container>
: mpl::false_
{};
}}}
namespace mapnik { namespace util {
namespace karma = boost::spirit::karma; namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix; namespace phoenix = boost::phoenix;

View file

@ -21,12 +21,11 @@
*****************************************************************************/ *****************************************************************************/
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/util/geometry_wkt_generator.hpp> #include <mapnik/wkt/wkt_generator_grammar.hpp>
#include <mapnik/util/geometry_to_wkt.hpp>
#include <mapnik/util/path_iterator.hpp> #include <mapnik/util/path_iterator.hpp>
#include <mapnik/util/container_adapter.hpp> #include <mapnik/util/container_adapter.hpp>
namespace mapnik { namespace util { namespace mapnik { namespace wkt {
template <typename T> template <typename T>
std::tuple<unsigned,bool> detail::multi_geometry_type<T>::operator() (T const& geom) const 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 #define MAPNIK_WKT_GRAMMAR_HPP
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
// spirit::qi
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
// spirit::phoenix
#include <boost/spirit/include/phoenix_function.hpp> #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 // mapnik
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
@ -41,215 +33,86 @@
namespace mapnik { namespace wkt { namespace mapnik { namespace wkt {
using namespace boost::spirit; using namespace boost::spirit;
using namespace boost::phoenix;
struct push_vertex 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>
{ {
wkt_collection_grammar() template <typename T>
: wkt_collection_grammar::base_type(start) struct result
{ {
qi::lit_type lit; using type = void;
qi::no_case_type no_case; };
start = wkt | no_case[lit("GEOMETRYCOLLECTION")]
>> (lit("(") >> wkt % lit(",") >> lit(")"));
}
qi::rule<Iterator,boost::ptr_vector<mapnik::geometry_type>(),ascii::space_type> start; template <typename T0,typename T1, typename T2, typename T3>
wkt_grammar<Iterator> wkt; 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> 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_grammar();
: wkt_stream_grammar::base_type(start) 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;
start = *wkt_collection; 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; template <typename Iterator>
wkt_collection_grammar<Iterator> wkt_collection; 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/boolean.hpp>
#include <mapnik/util/trim.hpp> #include <mapnik/util/trim.hpp>
#include <mapnik/value_types.hpp> #include <mapnik/value_types.hpp>
#include <mapnik/wkt/wkt_grammar_impl.hpp>
#include <mapnik/json/geometry_grammar_impl.hpp>
// stl // stl
#include <sstream> #include <sstream>

View file

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

View file

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

View file

@ -444,7 +444,7 @@ boost::optional<mapnik::datasource::geometry_t> sqlite_datasource::get_geometry_
const char* data = (const char*) rs->column_blob(0, size); const char* data = (const char*) rs->column_blob(0, size);
if (data) if (data)
{ {
boost::ptr_vector<mapnik::geometry_type> paths; mapnik::geometry_container paths;
if (mapnik::geometry_utils::from_wkb(paths, data, size, format_)) if (mapnik::geometry_utils::from_wkb(paths, data, size, format_))
{ {
mapnik::util::to_ds_type(paths,result); mapnik::util::to_ds_type(paths,result);

View file

@ -191,7 +191,7 @@ public:
const char* data = static_cast<const char*>(rs->column_blob(0, size)); const char* data = static_cast<const char*>(rs->column_blob(0, size));
if (data) if (data)
{ {
boost::ptr_vector<mapnik::geometry_type> paths; mapnik::geometry_container paths;
if (mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto)) if (mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto))
{ {
for (unsigned i=0; i<paths.size(); ++i) for (unsigned i=0; i<paths.size(); ++i)
@ -278,7 +278,7 @@ public:
const char* data = (const char*) rs->column_blob(0, size); const char* data = (const char*) rs->column_blob(0, size);
if (data) if (data)
{ {
boost::ptr_vector<mapnik::geometry_type> paths; mapnik::geometry_container paths;
mapnik::box2d<double> bbox; mapnik::box2d<double> bbox;
if (mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto)) if (mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto))
{ {
@ -365,7 +365,7 @@ public:
const char* data = static_cast<const char*>(rs->column_blob(0, size)); const char* data = static_cast<const char*>(rs->column_blob(0, size));
if (data) if (data)
{ {
boost::ptr_vector<mapnik::geometry_type> paths; mapnik::geometry_container paths;
if (mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto)) if (mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto))
{ {
for (unsigned i=0; i<paths.size(); ++i) for (unsigned i=0; i<paths.size(); ++i)

View file

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

View file

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

View file

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

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * 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> #include <mapnik/css_color_grammar_impl.hpp>
#include <string>
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))
;
}
template struct mapnik::css_color_grammar<std::string::const_iterator>; template struct mapnik::css_color_grammar<std::string::const_iterator>;
}

View file

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

View file

@ -21,7 +21,8 @@
*****************************************************************************/ *****************************************************************************/
// mapnik // mapnik
#include <mapnik/image_filter_types.hpp> #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 // boost
#include <boost/spirit/include/karma.hpp> #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/parse_path.hpp>
#include <mapnik/path_expression_grammar.hpp> #include <mapnik/path_expression_grammar.hpp>
#include <mapnik/path_expression_grammar_impl.hpp>
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/attribute.hpp> #include <mapnik/attribute.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>

View file

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

View file

@ -25,6 +25,10 @@
// mapnik // mapnik
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/svg/output/svg_renderer.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 { namespace mapnik {
@ -50,6 +54,20 @@ bool is_path_based(symbolizer const& sym)
return boost::apply_visitor(symbol_type_dispatch(), 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> template <typename OutputIterator>
bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms, bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
@ -79,7 +97,7 @@ bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms,
if(geom.size() > 0) if(geom.size() > 0)
{ {
path_type path(common_.t_, geom, prj_trans); 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 // set the previously collected values back to their defaults

View file

@ -26,6 +26,7 @@
#include <mapnik/svg/output/svg_generator.hpp> #include <mapnik/svg/output/svg_generator.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/util/conversions.hpp> #include <mapnik/util/conversions.hpp>
#include <mapnik/svg/output/svg_output_grammars.hpp>
// boost // boost
#include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma.hpp>
@ -52,7 +53,8 @@ namespace mapnik { namespace svg {
template <typename OutputIterator> template <typename OutputIterator>
void svg_generator<OutputIterator>::generate_opening_root(root_output_attributes const& root_attributes) 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::lit_type lit;
karma::generate(output_iterator_, lit("<svg ") << attributes_grammar << lit(">\n"), root_attributes); karma::generate(output_iterator_, lit("<svg ") << attributes_grammar << lit(">\n"), root_attributes);
} }
@ -67,7 +69,8 @@ namespace mapnik { namespace svg {
template <typename OutputIterator> template <typename OutputIterator>
void svg_generator<OutputIterator>::generate_rect(rect_output_attributes const& rect_attributes) 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::lit_type lit;
karma::generate(output_iterator_, lit("<rect ") << attributes_grammar << lit("/>\n"), rect_attributes); 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/expression_string.hpp>
#include <mapnik/transform_expression.hpp> #include <mapnik/transform_expression.hpp>
// boost
// stl // stl
#include <sstream> #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/vertex_converters.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/wkt/wkt_factory.hpp> #include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/wkt/wkt_grammar_impl.hpp>
#include <mapnik/well_known_srs.hpp> #include <mapnik/well_known_srs.hpp>
#include <mapnik/util/geometry_to_wkb.hpp> #include <mapnik/wkt/wkt_generator_grammar.hpp>
#include <mapnik/util/geometry_to_wkt.hpp> #include <mapnik/wkt/wkt_generator_grammar_impl.hpp>
#include <mapnik/util/geometry_to_svg.hpp>
#include <mapnik/projection.hpp> #include <mapnik/projection.hpp>
#include <mapnik/proj_transform.hpp> #include <mapnik/proj_transform.hpp>
@ -25,7 +25,7 @@
struct output_geometry_backend 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), : paths_(paths),
type_(type) {} type_(type) {}
@ -43,7 +43,7 @@ struct output_geometry_backend
} }
paths_.push_back(geom_ptr.release()); paths_.push_back(geom_ptr.release());
} }
boost::ptr_vector<mapnik::geometry_type> & paths_; mapnik::geometry_container & paths_;
mapnik::geometry_type::types type_; 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); proj_transform prj_trans(src,dst);
line_symbolizer sym; line_symbolizer sym;
CoordTransform t(bbox.width(),bbox.height(), bbox); 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); output_geometry_backend backend(output_paths, mapnik::geometry_type::types::LineString);
using conv_types = boost::mpl::vector<clip_line_tag>; 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>(); converter.set<clip_line_tag>();
boost::ptr_vector<geometry_type> p; mapnik::geometry_container p;
if (!mapnik::from_wkt(wkt_in , p)) if (!mapnik::from_wkt(wkt_in , p))
{ {
throw std::runtime_error("Failed to parse WKT"); 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); converter.apply(geom);
} }
std::string wkt_out; using sink_type = std::back_insert_iterator<std::string>;
if (mapnik::util::to_wkt(wkt_out, output_paths)) 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>(); 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); proj_transform prj_trans(src,dst);
polygon_symbolizer sym; polygon_symbolizer sym;
CoordTransform t(bbox.width(),bbox.height(), bbox); 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); output_geometry_backend backend(output_paths, mapnik::geometry_type::types::Polygon);
using conv_types = boost::mpl::vector<clip_poly_tag>; 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>(); converter.set<clip_poly_tag>();
boost::ptr_vector<geometry_type> p; mapnik::geometry_container p;
if (!mapnik::from_wkt(wkt_in , p)) if (!mapnik::from_wkt(wkt_in , p))
{ {
throw std::runtime_error("Failed to parse WKT"); 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); converter.apply(geom);
} }
std::string wkt_out; using sink_type = std::back_insert_iterator<std::string>;
if (mapnik::util::to_wkt(wkt_out, output_paths)) 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>(); return boost::optional<std::string>();

View file

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