From 2427daa40399dddfd2d6c551e217cdd11e771fe6 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 27 Sep 2012 16:04:29 +0100 Subject: [PATCH] + make WKT generator templated on geometry type - the goal is to be able to use generator for any type that implements 'vertex' concept --- include/mapnik/util/geometry_to_wkt.hpp | 4 +- .../mapnik/util/geometry_wkt_generator.hpp | 76 +++++++++++-------- src/wkt/wkt_generator.cpp | 45 ++++++----- 3 files changed, 71 insertions(+), 54 deletions(-) diff --git a/include/mapnik/util/geometry_to_wkt.hpp b/include/mapnik/util/geometry_to_wkt.hpp index bd7e0268b..31cd67802 100644 --- a/include/mapnik/util/geometry_to_wkt.hpp +++ b/include/mapnik/util/geometry_to_wkt.hpp @@ -40,7 +40,7 @@ bool to_wkt(std::string & wkt, mapnik::geometry_type const& geom) { typedef std::back_insert_iterator sink_type; sink_type sink(wkt); - wkt_generator generator(true); + wkt_generator generator(true); bool result = karma::generate(sink, generator, geom); return result; } @@ -49,7 +49,7 @@ bool to_wkt(std::string & wkt, mapnik::geometry_container const& geom) { typedef std::back_insert_iterator sink_type; sink_type sink(wkt); - wkt_multi_generator generator; + wkt_multi_generator generator; bool result = karma::generate(sink, generator, geom); return result; } diff --git a/include/mapnik/util/geometry_wkt_generator.hpp b/include/mapnik/util/geometry_wkt_generator.hpp index e2c4eb220..edb17838c 100644 --- a/include/mapnik/util/geometry_wkt_generator.hpp +++ b/include/mapnik/util/geometry_wkt_generator.hpp @@ -25,7 +25,6 @@ // mapnik #include -#include // boost #include @@ -36,17 +35,17 @@ #include #include #include - +#include //#define BOOST_SPIRIT_USE_PHOENIX_V3 1 namespace boost { namespace spirit { namespace traits { // make gcc and darwin toolsets happy. -template <> -struct is_container - : mpl::false_ -{}; +//template <> +//struct is_container +// : mpl::false_ +//{}; }}} @@ -58,34 +57,41 @@ namespace phoenix = boost::phoenix; namespace detail { +template struct get_type { template struct result { typedef int type; }; - int operator() (geometry_type const& geom) const + int operator() (Geometry const& geom) const { return static_cast(geom.type()); } }; +template struct get_first { - template - struct result { typedef geometry_type::value_type const type; }; + typedef T geometry_type; - geometry_type::value_type const operator() (geometry_type const& geom) const + template + struct result { typedef typename geometry_type::value_type const type; }; + + typename 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)); + typename geometry_type::value_type coord; + geom.rewind(0); + boost::get<0>(coord) = geom.vertex(&boost::get<1>(coord),&boost::get<2>(coord)); return coord; } }; - +template struct multi_geometry_ { - template + typedef T geometry_container; + + template struct result { typedef bool type; }; bool operator() (geometry_container const& geom) const @@ -94,9 +100,12 @@ struct multi_geometry_ } }; +template struct multi_geometry_type { - template + typedef T geometry_container; + + template struct result { typedef boost::tuple type; }; boost::tuple operator() (geometry_container const& geom) const; @@ -113,10 +122,13 @@ struct wkt_coordinate_policy : karma::real_policies } -template +template struct wkt_generator : - karma::grammar + karma::grammar { + typedef Geometry geometry_type; + typedef typename boost::remove_pointer::type coord_type; + wkt_generator(bool single = false); // rules karma::rule wkt; @@ -126,33 +138,35 @@ struct wkt_generator : karma::rule coords; karma::rule, geometry_type const& ()> coords2; - karma::rule point_coord; - karma::rule polygon_coord; + karma::rule point_coord; + karma::rule polygon_coord; // phoenix functions - phoenix::function _type; - phoenix::function _first; + phoenix::function > _type; + phoenix::function > _first; // - karma::real_generator > coord_type; + karma::real_generator > coordinate; }; -template +template struct wkt_multi_generator : - karma::grammar >, geometry_container const& ()> + karma::grammar >, GeometryContainer const& ()> { + typedef GeometryContainer geometry_contaner; + typedef boost::remove_pointer::type geometry_type; wkt_multi_generator(); // rules - karma::rule >, geometry_container const& ()> wkt; - karma::rule geometry; + karma::rule >, GeometryContainer const& ()> wkt; + karma::rule geometry; karma::rule single_geometry; - karma::rule multi_geometry; - wkt_generator path; + karma::rule multi_geometry; + wkt_generator path; // phoenix - phoenix::function is_multi; - phoenix::function _multi_type; - phoenix::function _type; + phoenix::function > is_multi; + phoenix::function > _multi_type; + phoenix::function > _type; // karma::symbols geometry_types; }; diff --git a/src/wkt/wkt_generator.cpp b/src/wkt/wkt_generator.cpp index f9d82efb6..e4c82e0a5 100644 --- a/src/wkt/wkt_generator.cpp +++ b/src/wkt/wkt_generator.cpp @@ -24,19 +24,22 @@ #if BOOST_VERSION >= 104700 +#include #include #include #include namespace mapnik { namespace util { -boost::tuple detail::multi_geometry_type::operator() (geometry_container const& geom) const +template +boost::tuple detail::multi_geometry_type::operator() (T const& geom) const { + typedef T geometry_container; unsigned type = 0u; bool collection = false; - geometry_container::const_iterator itr = geom.begin(); - geometry_container::const_iterator end = geom.end(); + typename geometry_container::const_iterator itr = geom.begin(); + typename geometry_container::const_iterator end = geom.end(); for ( ; itr != end; ++itr) { @@ -50,8 +53,8 @@ boost::tuple detail::multi_geometry_type::operator() (geometry_co return boost::tuple(type, collection); } -template -wkt_generator::wkt_generator(bool single) +template +wkt_generator::wkt_generator(bool single) : wkt_generator::base_type(wkt) { using boost::spirit::karma::uint_; @@ -62,50 +65,50 @@ wkt_generator::wkt_generator(bool single) 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 + + point_coord = &uint_ << coordinate << lit(' ') << coordinate ; - + polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1] << string[ if_ (_r1 > 1) [_1 = "),("] .else_[_1 = "("] ] | &uint_ << ",") - << coord_type + << coordinate << lit(' ') - << coord_type + << coordinate ; - + coords2 %= *polygon_coord(_a) ; - + coords = point_coord % lit(',') ; } -template -wkt_multi_generator::wkt_multi_generator() +template +wkt_multi_generator::wkt_multi_generator() : wkt_multi_generator::base_type(wkt) { using boost::spirit::karma::lit; @@ -138,10 +141,10 @@ wkt_multi_generator::wkt_multi_generator() } -template struct mapnik::util::wkt_generator >; -template struct mapnik::util::wkt_multi_generator >; +template struct mapnik::util::wkt_generator, mapnik::geometry_type>; +template struct mapnik::util::wkt_multi_generator, mapnik::geometry_container >; }} -#endif \ No newline at end of file +#endif