adapt mapnik::geometry::geometry<double>
to work with boost::spirit::karma
+ simplify and optimise WKT generator
This commit is contained in:
parent
bdaef2cc91
commit
9853353353
5 changed files with 155 additions and 102 deletions
|
@ -24,29 +24,13 @@
|
|||
#define MAPNIK_GEOMETRY_TO_WKT_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/wkt/wkt_factory.hpp>
|
||||
#include <mapnik/wkt/wkt_generator_grammar.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/spirit/include/karma.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry<double> const& geom)
|
||||
{
|
||||
using sink_type = std::back_insert_iterator<std::string>;
|
||||
static const mapnik::wkt::wkt_generator_grammar<sink_type, mapnik::geometry::geometry<double>> generator;
|
||||
sink_type sink(wkt);
|
||||
return boost::spirit::karma::generate(sink, generator, geom);
|
||||
}
|
||||
|
||||
inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry<std::int64_t> const& geom)
|
||||
{
|
||||
using sink_type = std::back_insert_iterator<std::string>;
|
||||
static const mapnik::wkt::wkt_generator_grammar<sink_type, mapnik::geometry::geometry<std::int64_t>> generator;
|
||||
sink_type sink(wkt);
|
||||
return boost::spirit::karma::generate(sink, generator, geom);
|
||||
}
|
||||
bool to_wkt(std::string & wkt, mapnik::geometry::geometry<double> const& geom);
|
||||
|
||||
}}
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry/geometry_type.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
|
@ -43,18 +43,6 @@ namespace phoenix = boost::phoenix;
|
|||
|
||||
namespace detail {
|
||||
|
||||
template <typename Geometry>
|
||||
struct get_type
|
||||
{
|
||||
using result_type = mapnik::geometry::geometry_types;
|
||||
template <typename T>
|
||||
result_type operator() (T const& geom) const
|
||||
{
|
||||
auto type = mapnik::geometry::geometry_type(geom);
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct wkt_coordinate_policy : karma::real_policies<T>
|
||||
{
|
||||
|
@ -102,31 +90,29 @@ struct coordinate_generator<std::int64_t>
|
|||
|
||||
template <typename OutputIterator, typename Geometry>
|
||||
struct wkt_generator_grammar :
|
||||
karma::grammar<OutputIterator, Geometry const& ()>
|
||||
karma::grammar<OutputIterator, Geometry()>
|
||||
{
|
||||
using coord_type = typename Geometry::coord_type;
|
||||
wkt_generator_grammar();
|
||||
// rules
|
||||
karma::rule<OutputIterator, Geometry const&()> geometry;
|
||||
karma::rule<OutputIterator, karma::locals<mapnik::geometry::geometry_types>, Geometry const&() > geometry_dispatch;
|
||||
karma::rule<OutputIterator, geometry::geometry<coord_type> const&()> point;
|
||||
karma::rule<OutputIterator, geometry::point<coord_type> const&()> point_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<coord_type> const&()> linestring;
|
||||
karma::rule<OutputIterator, geometry::line_string<coord_type> const&()> linestring_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<coord_type> const&()> polygon;
|
||||
karma::rule<OutputIterator, geometry::polygon<coord_type> const&()> polygon_coord;
|
||||
karma::rule<OutputIterator, geometry::linear_ring<coord_type> const&()> exterior_ring_coord;
|
||||
karma::rule<OutputIterator, std::vector<geometry::linear_ring<coord_type> > const&()> interior_ring_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<coord_type> const& ()> multi_point;
|
||||
karma::rule<OutputIterator, geometry::multi_point<coord_type> const& ()> multi_point_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<coord_type> const& ()> multi_linestring;
|
||||
karma::rule<OutputIterator, geometry::multi_line_string<coord_type> const& ()> multi_linestring_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<coord_type> const& ()> multi_polygon;
|
||||
karma::rule<OutputIterator, geometry::multi_polygon<coord_type> const& ()> multi_polygon_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<coord_type> const& ()> geometry_collection;
|
||||
karma::rule<OutputIterator, geometry::geometry_collection<coord_type> const& ()> geometries;
|
||||
boost::phoenix::function<detail::get_type<Geometry> > geometry_type;
|
||||
karma::symbols<mapnik::geometry::geometry_types, char const*> empty;
|
||||
karma::rule<OutputIterator, Geometry()> geometry;
|
||||
karma::rule<OutputIterator, geometry::geometry_empty()> empty;
|
||||
karma::rule<OutputIterator, geometry::point<coord_type>()> point;
|
||||
karma::rule<OutputIterator, geometry::point<coord_type>()> point_coord;
|
||||
karma::rule<OutputIterator, geometry::line_string<coord_type>()> linestring;
|
||||
karma::rule<OutputIterator, geometry::line_string<coord_type>()> linestring_coord;
|
||||
karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon;
|
||||
karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon_coord;
|
||||
karma::rule<OutputIterator, geometry::linear_ring<coord_type>()> exterior_ring_coord;
|
||||
karma::rule<OutputIterator, std::vector<geometry::linear_ring<coord_type> >()> interior_ring_coord;
|
||||
karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point;
|
||||
karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point_coord;
|
||||
karma::rule<OutputIterator, geometry::multi_line_string<coord_type>()> multi_linestring;
|
||||
karma::rule<OutputIterator, geometry::multi_line_string<coord_type>()> multi_linestring_coord;
|
||||
karma::rule<OutputIterator, geometry::multi_polygon<coord_type>()> multi_polygon;
|
||||
karma::rule<OutputIterator, geometry::multi_polygon<coord_type>()> multi_polygon_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry_collection<coord_type>()> geometry_collection;
|
||||
karma::rule<OutputIterator, geometry::geometry_collection<coord_type>()> geometries;
|
||||
//
|
||||
typename detail::coordinate_generator<coord_type>::generator coordinate;
|
||||
};
|
||||
|
|
|
@ -22,9 +22,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/wkt/wkt_generator_grammar.hpp>
|
||||
#include <mapnik/util/spirit_transform_attribute.hpp>
|
||||
#include <mapnik/geometry/fusion_adapted.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
|
@ -36,53 +34,26 @@ template <typename OutputIterator, typename Geometry>
|
|||
wkt_generator_grammar<OutputIterator, Geometry>::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<double> can't be empty
|
||||
;
|
||||
|
||||
point = lit("POINT(") << point_coord << lit(")")
|
||||
point = lit("POINT(") << coordinate << lit(' ') << coordinate << lit(")")
|
||||
;
|
||||
linestring = lit("LINESTRING(") << linestring_coord << lit(")")
|
||||
;
|
||||
|
|
48
src/wkt/geometry_to_wkt.cpp
Normal file
48
src/wkt/geometry_to_wkt.cpp
Normal file
|
@ -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 <mapnik/util/geometry_to_wkt.hpp>
|
||||
#include <mapnik/wkt/wkt_generator_grammar.hpp>
|
||||
// boost
|
||||
#include <boost/spirit/include/karma.hpp>
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
bool to_wkt(std::string & wkt, mapnik::geometry::geometry<double> const& geom)
|
||||
{
|
||||
using sink_type = std::back_insert_iterator<std::string>;
|
||||
static const mapnik::wkt::wkt_generator_grammar<sink_type, mapnik::geometry::geometry<double>> generator;
|
||||
sink_type sink(wkt);
|
||||
return boost::spirit::karma::generate(sink, generator, geom);
|
||||
}
|
||||
|
||||
/*
|
||||
inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry<std::int64_t> const& geom)
|
||||
{
|
||||
using sink_type = std::back_insert_iterator<std::string>;
|
||||
static const mapnik::wkt::wkt_generator_grammar<sink_type, mapnik::geometry::geometry<std::int64_t>> generator;
|
||||
sink_type sink(wkt);
|
||||
return boost::spirit::karma::generate(sink, generator, geom);
|
||||
}
|
||||
*/
|
||||
}}
|
|
@ -21,9 +21,73 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/wkt/wkt_generator_grammar_impl.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost { using mapbox::util::get; }
|
||||
|
||||
#include <mapnik/wkt/wkt_generator_grammar_impl.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <>
|
||||
struct not_is_variant<mapnik::geometry::geometry<double>, karma::domain>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct variant_which< mapnik::geometry::geometry<double> >
|
||||
{
|
||||
static int call(mapnik::geometry::geometry<double> const& v)
|
||||
{
|
||||
return v.which();
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename Tuple>
|
||||
struct has_type;
|
||||
|
||||
template <typename T>
|
||||
struct has_type<T, std::tuple<>> : std::false_type {};
|
||||
|
||||
template <typename T, typename U, typename... Types>
|
||||
struct has_type<T, std::tuple<U, Types...>> : has_type<T, std::tuple<Types...>> {};
|
||||
|
||||
template <typename T, typename... Types>
|
||||
struct has_type<T, std::tuple<T, Types...>> : std::true_type {};
|
||||
|
||||
template <typename T, typename Tuple>
|
||||
struct index;
|
||||
|
||||
template <typename T, typename... Types>
|
||||
struct index<T, std::tuple<T, Types...>>
|
||||
{
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
template <typename T, typename U, typename... Types>
|
||||
struct index<T, std::tuple<U, Types...>>
|
||||
{
|
||||
static const std::size_t value = 1 + index<T, std::tuple<Types...>>::value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename Expected>
|
||||
struct compute_compatible_component_variant<mapnik::geometry::geometry<double>, Expected>
|
||||
: detail::has_type<Expected, mapnik::geometry::geometry<double>::types>
|
||||
{
|
||||
using compatible_type = Expected;
|
||||
static bool is_compatible(int index)
|
||||
{
|
||||
return (index == detail::index<compatible_type, mapnik::geometry::geometry<double>::types>::value);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
namespace mapnik { namespace wkt {
|
||||
|
||||
using sink_type = std::back_insert_iterator<std::string>;
|
||||
|
|
Loading…
Reference in a new issue