diff --git a/include/mapnik/util/geometry_wkt_generator.hpp b/include/mapnik/util/geometry_wkt_generator.hpp index df7bab059..6c2df624b 100644 --- a/include/mapnik/util/geometry_wkt_generator.hpp +++ b/include/mapnik/util/geometry_wkt_generator.hpp @@ -89,23 +89,32 @@ struct multi_geometry_ struct multi_geometry_type { template - struct result { typedef unsigned type; }; + struct result { typedef boost::tuple type; }; - unsigned operator() (geometry_container const& geom) const + 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 type; + return boost::tuple(type, collection); } }; + template -struct coordinate_policy : karma::real_policies +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; } @@ -187,14 +196,15 @@ struct wkt_generator : phoenix::function _type; phoenix::function _first; // - karma::real_generator > coord_type; + karma::real_generator > coord_type; }; + template struct wkt_multi_generator : - karma::grammar + karma::grammar >, geometry_container const& ()> { wkt_multi_generator() @@ -204,6 +214,7 @@ struct wkt_multi_generator : 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") @@ -211,27 +222,34 @@ struct wkt_multi_generator : (mapnik::Polygon,"Polygon") ; - wkt = eps(_multi(_val)) << "Multi" << geometry_types[_1 = _type(_val)] - << "(" << multi_geometry << ")" | geometry_types[_1 = _type(_val)] - << geometry + 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 = *path + + geometry = -(single_geometry % lit(',')) ; + single_geometry = geometry_types[_1 = _type(_val)] << path + ; + multi_geometry = -(path % lit(',')) ; } // rules - karma::rule wkt; + karma::rule >, geometry_container const& ()> wkt; karma::rule geometry; + karma::rule single_geometry; karma::rule multi_geometry; wkt_generator path; // phoenix - phoenix::function _multi; - phoenix::function _type; - // + phoenix::function is_multi; + phoenix::function _multi_type; + phoenix::function _type; + // karma::symbols geometry_types; };