From 3f444302f04424292cd7e26cd1acc7dc3a0aebd6 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 24 Jul 2012 15:04:39 -0700 Subject: [PATCH] move wkb_generator.cpp to cpp to reduce grammar compilation burden in the python bindings --- .../mapnik/util/geometry_wkt_generator.hpp | 236 +++++------------- src/build.py | 1 + src/wkb_generator.cpp | 141 +++++++++++ 3 files changed, 207 insertions(+), 171 deletions(-) create mode 100644 src/wkb_generator.cpp diff --git a/include/mapnik/util/geometry_wkt_generator.hpp b/include/mapnik/util/geometry_wkt_generator.hpp index 46780e5fd..969b932d6 100644 --- a/include/mapnik/util/geometry_wkt_generator.hpp +++ b/include/mapnik/util/geometry_wkt_generator.hpp @@ -26,8 +26,6 @@ // mapnik #include #include -#include -#include // boost #include @@ -55,161 +53,88 @@ struct is_container namespace mapnik { namespace util { - namespace karma = boost::spirit::karma; - namespace phoenix = boost::phoenix; - - namespace { - - struct get_type - { - template - struct result { typedef int type; }; - - int operator() (geometry_type const& geom) const - { - return static_cast(geom.type()); - } - }; - - struct get_first - { - template - struct result { typedef geometry_type::value_type const type; }; - - geometry_type::value_type const operator() (geometry_type const& geom) const - { - geometry_type::value_type coord; - boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord)); - return coord; - } - }; - - - struct multi_geometry_ - { - template - struct result { typedef bool type; }; - - bool operator() (geometry_container const& geom) const - { - return geom.size() > 1 ? true : false; - } - }; - - struct multi_geometry_type - { - template - struct result { typedef boost::tuple type; }; - - boost::tuple operator() (geometry_container const& geom) const - { - unsigned type = 0u; - bool collection = false; - - geometry_container::const_iterator itr = geom.begin(); - geometry_container::const_iterator end = geom.end(); - - for ( ; itr != end; ++itr) - { - if (type != 0 && itr->type() != type) - { - collection = true; - break; - } - type = itr->type(); - } - return boost::tuple(type, collection); - } - }; +namespace karma = boost::spirit::karma; +namespace phoenix = boost::phoenix; +namespace { +struct get_type +{ template - struct wkt_coordinate_policy : karma::real_policies - { - typedef boost::spirit::karma::real_policies base_type; - static int floatfield(T n) { return base_type::fmtflags::fixed; } - static unsigned precision(T n) { return 6 ;} - }; + struct result { typedef int type; }; + int operator() (geometry_type const& geom) const + { + return static_cast(geom.type()); } +}; - template - struct wkt_generator : - karma::grammar +struct get_first +{ + template + struct result { typedef geometry_type::value_type const type; }; + + geometry_type::value_type const operator() (geometry_type const& geom) const { + geometry_type::value_type coord; + boost::get<0>(coord) = geom.vertex(0,&boost::get<1>(coord),&boost::get<2>(coord)); + return coord; + } +}; - wkt_generator(bool single = false) - : wkt_generator::base_type(wkt) - { - using boost::spirit::karma::uint_; - using boost::spirit::karma::_val; - using boost::spirit::karma::_1; - using boost::spirit::karma::lit; - using boost::spirit::karma::_a; - using boost::spirit::karma::_r1; - using boost::spirit::karma::eps; - using boost::spirit::karma::string; - wkt = point | linestring | polygon - ; +struct multi_geometry_ +{ + template + struct result { typedef bool type; }; - point = &uint_(mapnik::Point)[_1 = _type(_val)] - << string[ phoenix::if_ (single) [_1 = "Point("] - .else_[_1 = "("]] - << point_coord [_1 = _first(_val)] << lit(')') - ; + bool operator() (geometry_container const& geom) const + { + return geom.size() > 1 ? true : false; + } +}; - linestring = &uint_(mapnik::LineString)[_1 = _type(_val)] - << string[ phoenix::if_ (single) [_1 = "LineString("] - .else_[_1 = "("]] - << coords - << lit(')') - ; +struct multi_geometry_type +{ + template + struct result { typedef boost::tuple type; }; - polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)] - << string[ phoenix::if_ (single) [_1 = "Polygon("] - .else_[_1 = "("]] - << coords2 - << lit("))") - ; + boost::tuple operator() (geometry_container const& geom) const; +}; - point_coord = &uint_ << coord_type << lit(' ') << coord_type - ; - polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1] - << string[ if_ (_r1 > 1) [_1 = "),("] - .else_[_1 = "("] ] | &uint_ << ",") - << coord_type - << lit(' ') - << coord_type - ; +template +struct wkt_coordinate_policy : karma::real_policies +{ + typedef boost::spirit::karma::real_policies base_type; + static int floatfield(T n) { return base_type::fmtflags::fixed; } + static unsigned precision(T n) { return 6 ;} +}; - coords2 %= *polygon_coord(_a) - ; +} - coords = point_coord % lit(',') - ; +template +struct wkt_generator : + karma::grammar +{ + wkt_generator(bool single = false); + // rules + karma::rule wkt; + karma::rule point; + karma::rule linestring; + karma::rule polygon; - } - // rules - karma::rule wkt; - karma::rule point; - karma::rule linestring; - karma::rule polygon; - - karma::rule coords; - karma::rule, geometry_type const& ()> coords2; - karma::rule point_coord; - karma::rule polygon_coord; - - // phoenix functions - phoenix::function _type; - phoenix::function _first; - // - karma::real_generator > coord_type; - - }; + karma::rule coords; + karma::rule, geometry_type const& ()> coords2; + karma::rule point_coord; + karma::rule polygon_coord; + // phoenix functions + phoenix::function _type; + phoenix::function _first; + // + karma::real_generator > coord_type; +}; template @@ -217,38 +142,7 @@ struct wkt_multi_generator : karma::grammar >, geometry_container const& ()> { - wkt_multi_generator() - : wkt_multi_generator::base_type(wkt) - { - using boost::spirit::karma::lit; - using boost::spirit::karma::eps; - using boost::spirit::karma::_val; - using boost::spirit::karma::_1; - using boost::spirit::karma::_a; - - geometry_types.add - (mapnik::Point,"Point") - (mapnik::LineString,"LineString") - (mapnik::Polygon,"Polygon") - ; - - wkt = eps(phoenix::at_c<1>(_a))[_a = _multi_type(_val)] - << lit("GeometryCollection(") << geometry << lit(")") - | eps(is_multi(_val)) << lit("Multi") << geometry_types[_1 = phoenix::at_c<0>(_a)] - << "(" << multi_geometry << ")" - | geometry - ; - - geometry = -(single_geometry % lit(',')) - ; - - single_geometry = geometry_types[_1 = _type(_val)] << path - ; - - multi_geometry = -(path % lit(',')) - ; - - } + wkt_multi_generator(); // rules karma::rule >, geometry_container const& ()> wkt; karma::rule geometry; diff --git a/src/build.py b/src/build.py index 1ad71687b..cf75e6b20 100644 --- a/src/build.py +++ b/src/build.py @@ -144,6 +144,7 @@ source = Split( text_symbolizer.cpp tiff_reader.cpp wkb.cpp + wkb_generator.cpp projection.cpp proj_transform.cpp distance.cpp diff --git a/src/wkb_generator.cpp b/src/wkb_generator.cpp new file mode 100644 index 000000000..68decfc9e --- /dev/null +++ b/src/wkb_generator.cpp @@ -0,0 +1,141 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#include +#include +#include + +namespace mapnik { namespace util { + +boost::tuple multi_geometry_type::operator() (geometry_container const& geom) const +{ + unsigned type = 0u; + bool collection = false; + + geometry_container::const_iterator itr = geom.begin(); + geometry_container::const_iterator end = geom.end(); + + for ( ; itr != end; ++itr) + { + if (type != 0 && itr->type() != type) + { + collection = true; + break; + } + type = itr->type(); + } + return boost::tuple(type, collection); +} + +template +wkt_generator::wkt_generator(bool single) + : wkt_generator::base_type(wkt) +{ + using boost::spirit::karma::uint_; + using boost::spirit::karma::_val; + using boost::spirit::karma::_1; + using boost::spirit::karma::lit; + using boost::spirit::karma::_a; + using boost::spirit::karma::_r1; + using boost::spirit::karma::eps; + using boost::spirit::karma::string; + + wkt = point | linestring | polygon + ; + + point = &uint_(mapnik::Point)[_1 = _type(_val)] + << string[ phoenix::if_ (single) [_1 = "Point("] + .else_[_1 = "("]] + << point_coord [_1 = _first(_val)] << lit(')') + ; + + linestring = &uint_(mapnik::LineString)[_1 = _type(_val)] + << string[ phoenix::if_ (single) [_1 = "LineString("] + .else_[_1 = "("]] + << coords + << lit(')') + ; + + polygon = &uint_(mapnik::Polygon)[_1 = _type(_val)] + << string[ phoenix::if_ (single) [_1 = "Polygon("] + .else_[_1 = "("]] + << coords2 + << lit("))") + ; + + point_coord = &uint_ << coord_type << lit(' ') << coord_type + ; + + polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1] + << string[ if_ (_r1 > 1) [_1 = "),("] + .else_[_1 = "("] ] | &uint_ << ",") + << coord_type + << lit(' ') + << coord_type + ; + + coords2 %= *polygon_coord(_a) + ; + + coords = point_coord % lit(',') + ; +} + +template +wkt_multi_generator::wkt_multi_generator() + : wkt_multi_generator::base_type(wkt) +{ + using boost::spirit::karma::lit; + using boost::spirit::karma::eps; + using boost::spirit::karma::_val; + using boost::spirit::karma::_1; + using boost::spirit::karma::_a; + + geometry_types.add + (mapnik::Point,"Point") + (mapnik::LineString,"LineString") + (mapnik::Polygon,"Polygon") + ; + + wkt = eps(phoenix::at_c<1>(_a))[_a = _multi_type(_val)] + << lit("GeometryCollection(") << geometry << lit(")") + | eps(is_multi(_val)) << lit("Multi") << geometry_types[_1 = phoenix::at_c<0>(_a)] + << "(" << multi_geometry << ")" + | geometry + ; + + geometry = -(single_geometry % lit(',')) + ; + + single_geometry = geometry_types[_1 = _type(_val)] << path + ; + + multi_geometry = -(path % lit(',')) + ; + +} + +template struct mapnik::util::wkt_generator >; +template struct mapnik::util::wkt_multi_generator >; + + +}} \ No newline at end of file