diff --git a/include/mapnik/util/geometry_to_wkt.hpp b/include/mapnik/util/geometry_to_wkt.hpp index 3c81ef440..2c1c1829d 100644 --- a/include/mapnik/util/geometry_to_wkt.hpp +++ b/include/mapnik/util/geometry_to_wkt.hpp @@ -24,29 +24,13 @@ #define MAPNIK_GEOMETRY_TO_WKT_HPP // mapnik -#include -#include - -// boost -#include +#include +// stl +#include namespace mapnik { namespace util { -inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) -{ - using sink_type = std::back_insert_iterator; - static const mapnik::wkt::wkt_generator_grammar> generator; - sink_type sink(wkt); - return boost::spirit::karma::generate(sink, generator, geom); -} - -inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) -{ - using sink_type = std::back_insert_iterator; - static const mapnik::wkt::wkt_generator_grammar> generator; - sink_type sink(wkt); - return boost::spirit::karma::generate(sink, generator, geom); -} +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom); }} diff --git a/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp index c88f9cfd5..2844833bb 100644 --- a/include/mapnik/wkt/wkt_generator_grammar.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar.hpp @@ -25,8 +25,8 @@ // mapnik #include + #include -#include #pragma GCC diagnostic push #include @@ -43,18 +43,6 @@ namespace phoenix = boost::phoenix; namespace detail { -template -struct get_type -{ - using result_type = mapnik::geometry::geometry_types; - template - result_type operator() (T const& geom) const - { - auto type = mapnik::geometry::geometry_type(geom); - return type; - } -}; - template struct wkt_coordinate_policy : karma::real_policies { @@ -102,31 +90,29 @@ struct coordinate_generator template struct wkt_generator_grammar : - karma::grammar + karma::grammar { using coord_type = typename Geometry::coord_type; wkt_generator_grammar(); // rules - karma::rule geometry; - karma::rule, Geometry const&() > geometry_dispatch; - karma::rule const&()> point; - karma::rule const&()> point_coord; - karma::rule const&()> linestring; - karma::rule const&()> linestring_coord; - karma::rule const&()> polygon; - karma::rule const&()> polygon_coord; - karma::rule const&()> exterior_ring_coord; - karma::rule > const&()> interior_ring_coord; - karma::rule const& ()> multi_point; - karma::rule const& ()> multi_point_coord; - karma::rule const& ()> multi_linestring; - karma::rule const& ()> multi_linestring_coord; - karma::rule const& ()> multi_polygon; - karma::rule const& ()> multi_polygon_coord; - karma::rule const& ()> geometry_collection; - karma::rule const& ()> geometries; - boost::phoenix::function > geometry_type; - karma::symbols empty; + karma::rule geometry; + karma::rule empty; + karma::rule()> point; + karma::rule()> point_coord; + karma::rule()> linestring; + karma::rule()> linestring_coord; + karma::rule()> polygon; + karma::rule()> polygon_coord; + karma::rule()> exterior_ring_coord; + karma::rule >()> interior_ring_coord; + karma::rule()> multi_point; + karma::rule()> multi_point_coord; + karma::rule()> multi_linestring; + karma::rule()> multi_linestring_coord; + karma::rule()> multi_polygon; + karma::rule()> multi_polygon_coord; + karma::rule()> geometry_collection; + karma::rule()> geometries; // typename detail::coordinate_generator::generator coordinate; }; diff --git a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp index 6cb015562..c3b94d2e6 100644 --- a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp @@ -22,9 +22,7 @@ // mapnik #include -#include #include - #pragma GCC diagnostic push #include #include @@ -36,53 +34,26 @@ template wkt_generator_grammar::wkt_generator_grammar() : wkt_generator_grammar::base_type(geometry) { - boost::spirit::karma::_val_type _val; - boost::spirit::karma::_1_type _1; - boost::spirit::karma::_a_type _a; boost::spirit::karma::lit_type lit; - boost::spirit::karma::uint_type uint_; - boost::spirit::karma::eps_type eps; - - empty.add - (geometry::geometry_types::Point, "POINT EMPTY") - (geometry::geometry_types::LineString, "LINESTRING EMPTY") - (geometry::geometry_types::Polygon, "POLYGON EMPTY") - (geometry::geometry_types::MultiPoint, "MULTIPOINT EMPTY") - (geometry::geometry_types::MultiLineString, "MULTILINESTRING EMPTY") - (geometry::geometry_types::MultiPolygon, "MULTIPOLYGON EMPTY") - (geometry::geometry_types::GeometryCollection, "GEOMETRYCOLLECTION EMPTY") + geometry = + point + | + linestring + | + polygon + | + multi_point + | + multi_linestring + | + multi_polygon + | + geometry_collection + | + lit("POINT EMPTY") // special case for geometry_empty ; - geometry = geometry_dispatch.alias() - ; - - geometry_dispatch = eps[_a = geometry_type(_val)] << - (&uint_(geometry::geometry_types::Point)[_1 = _a] - << point) - | - (&uint_(geometry::geometry_types::LineString)[_1 = _a] - << (linestring | empty[_1 = _a])) - | - (&uint_(geometry::geometry_types::Polygon)[_1 = _a] - << (polygon | empty[_1 = _a])) - | - (&uint_(geometry::geometry_types::MultiPoint)[_1 = _a] - << ( multi_point | empty[_1 = _a])) - | - (&uint_(geometry::geometry_types::MultiLineString)[_1 = _a] - << (multi_linestring | empty[_1 = _a])) - | - (&uint_(geometry::geometry_types::MultiPolygon)[_1 = _a] - << (multi_polygon | empty[_1 = _a])) - | - (&uint_(geometry::geometry_types::GeometryCollection)[_1 = _a] - << (geometry_collection | empty[_1 = _a])) - | - (&uint_(geometry::geometry_types::Unknown)[_1 = _a] - << lit("POINT EMPTY")) // special case for geometry_empty as mapnik::geometry::point can't be empty - ; - - point = lit("POINT(") << point_coord << lit(")") + point = lit("POINT(") << coordinate << lit(' ') << coordinate << lit(")") ; linestring = lit("LINESTRING(") << linestring_coord << lit(")") ; @@ -112,7 +83,7 @@ wkt_generator_grammar::wkt_generator_grammar() ; multi_polygon_coord = (lit('(') << polygon_coord << lit(')')) % lit(',') ; - geometries = geometry % lit(',') + geometries = geometry % lit(',') ; } diff --git a/src/wkt/geometry_to_wkt.cpp b/src/wkt/geometry_to_wkt.cpp new file mode 100644 index 000000000..64d652434 --- /dev/null +++ b/src/wkt/geometry_to_wkt.cpp @@ -0,0 +1,48 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 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 +#include +// boost +#include + +namespace mapnik { namespace util { + +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) +{ + using sink_type = std::back_insert_iterator; + static const mapnik::wkt::wkt_generator_grammar> generator; + sink_type sink(wkt); + return boost::spirit::karma::generate(sink, generator, geom); +} + +/* +inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) +{ + using sink_type = std::back_insert_iterator; + static const mapnik::wkt::wkt_generator_grammar> generator; + sink_type sink(wkt); + return boost::spirit::karma::generate(sink, generator, geom); +} +*/ +}} diff --git a/src/wkt/mapnik_wkt_generator_grammar.cpp b/src/wkt/mapnik_wkt_generator_grammar.cpp index 07813fcc8..e27f8aa32 100644 --- a/src/wkt/mapnik_wkt_generator_grammar.cpp +++ b/src/wkt/mapnik_wkt_generator_grammar.cpp @@ -21,9 +21,73 @@ *****************************************************************************/ #include -#include #include +namespace boost { using mapbox::util::get; } + +#include + +namespace boost { namespace spirit { namespace traits +{ +template <> +struct not_is_variant, karma::domain> + : mpl::false_ +{}; + +template <> +struct variant_which< mapnik::geometry::geometry > +{ + static int call(mapnik::geometry::geometry const& v) + { + return v.which(); + } +}; + +namespace detail { + +template +struct has_type; + +template +struct has_type> : std::false_type {}; + +template +struct has_type> : has_type> {}; + +template +struct has_type> : std::true_type {}; + +template +struct index; + +template +struct index> +{ + static const std::size_t value = 0; +}; + +template +struct index> +{ + static const std::size_t value = 1 + index>::value; +}; + +} + +template +struct compute_compatible_component_variant, Expected> + : detail::has_type::types> +{ + using compatible_type = Expected; + static bool is_compatible(int index) + { + return (index == detail::index::types>::value); + } +}; + +}}} + + namespace mapnik { namespace wkt { using sink_type = std::back_insert_iterator;