json : geometry_generator_grammar for mapnik-geometry (TODO)
This commit is contained in:
parent
a3b7328936
commit
c58a5b4151
3 changed files with 187 additions and 163 deletions
|
@ -25,10 +25,12 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/util/path_iterator.hpp>
|
||||
#include <mapnik/util/container_adapter.hpp>
|
||||
#include <mapnik/vertex.hpp> // for CommandType::SEG_MOVETO
|
||||
#include <mapnik/util/variant.hpp>
|
||||
#include <mapnik/geometry_impl.hpp>
|
||||
#include <mapnik/geometry_type.hpp>
|
||||
//#include <mapnik/util/path_iterator.hpp>
|
||||
//#include <mapnik/util/container_adapter.hpp>
|
||||
//#include <mapnik/vertex.hpp> // for CommandType::SEG_MOVETO
|
||||
|
||||
// boost
|
||||
#pragma GCC diagnostic push
|
||||
|
@ -36,12 +38,20 @@
|
|||
#pragma GCC diagnostic ignored "-Wunused-local-typedef"
|
||||
#include <boost/spirit/include/karma.hpp>
|
||||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
//#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunc
|
||||
#include <boost/spirit/home/karma/domain.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
//stl
|
||||
#include <tuple>
|
||||
//#include <tuple>
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::new_geometry::polygon,
|
||||
(mapnik::new_geometry::linear_ring const&, exterior_ring)
|
||||
(std::vector<mapnik::new_geometry::linear_ring> const& , interior_rings)
|
||||
)
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
|
@ -52,44 +62,110 @@ namespace detail {
|
|||
template <typename Geometry>
|
||||
struct get_type
|
||||
{
|
||||
using result_type = int;
|
||||
using result_type = mapnik::new_geometry::geometry_types;
|
||||
result_type operator() (Geometry const& geom) const
|
||||
{
|
||||
return static_cast<int>(geom.type());
|
||||
return mapnik::new_geometry::geometry_type(geom);
|
||||
}
|
||||
};
|
||||
|
||||
struct get_x
|
||||
{
|
||||
using result_type = double;
|
||||
double operator() (mapnik::new_geometry::point const& pt) const
|
||||
{
|
||||
return pt.x;
|
||||
}
|
||||
};
|
||||
|
||||
struct get_y
|
||||
{
|
||||
using result_type = double;
|
||||
double operator() (mapnik::new_geometry::point const& pt) const
|
||||
{
|
||||
return pt.y;
|
||||
}
|
||||
};
|
||||
|
||||
struct debug
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename T0, typename T1>
|
||||
void operator() (T0 & first, T1 const& second) const
|
||||
{
|
||||
std::cerr << typeid(first).name() << std::endl;
|
||||
std::cerr << typeid(second).name() << std::endl << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct extract_point
|
||||
{
|
||||
using result_type = mapnik::new_geometry::point;
|
||||
result_type const& operator() (Geometry const& geom) const
|
||||
{
|
||||
return geom.template get<mapnik::new_geometry::point>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct get_first
|
||||
struct extract_linestring
|
||||
{
|
||||
using result_type = typename Geometry::value_type const;
|
||||
result_type operator() (Geometry const& geom) const
|
||||
using result_type = mapnik::new_geometry::line_string;
|
||||
result_type const& operator() (Geometry const& geom) const
|
||||
{
|
||||
typename Geometry::value_type coord;
|
||||
std::get<0>(coord) = geom.cont_.get_vertex(0, &std::get<1>(coord),&std::get<2>(coord));
|
||||
return coord;
|
||||
return geom.template get<mapnik::new_geometry::line_string>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GeometryContainer>
|
||||
struct multi_geometry_type
|
||||
template <typename Geometry>
|
||||
struct extract_polygon
|
||||
{
|
||||
using result_type = std::tuple<unsigned,bool> ;
|
||||
result_type operator() (GeometryContainer const& cont) const
|
||||
using result_type = mapnik::new_geometry::polygon;
|
||||
result_type const& operator() (Geometry const& geom) const
|
||||
{
|
||||
unsigned type = 0u;
|
||||
bool collection = false;
|
||||
for (auto const& geom : cont)
|
||||
{
|
||||
if (type != 0u && geom.type() != type)
|
||||
{
|
||||
collection = true;
|
||||
break;
|
||||
}
|
||||
type = geom.type();
|
||||
}
|
||||
if (cont.size() > 1) type +=3;
|
||||
return std::tuple<unsigned,bool>(type, collection);
|
||||
return geom.template get<mapnik::new_geometry::polygon>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct extract_multipoint
|
||||
{
|
||||
using result_type = mapnik::new_geometry::multi_point;
|
||||
result_type const& operator() (Geometry const& geom) const
|
||||
{
|
||||
return geom.template get<mapnik::new_geometry::multi_point>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct extract_multilinestring
|
||||
{
|
||||
using result_type = mapnik::new_geometry::multi_line_string;
|
||||
result_type const& operator() (Geometry const& geom) const
|
||||
{
|
||||
return geom.template get<mapnik::new_geometry::multi_line_string>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct extract_multipolygon
|
||||
{
|
||||
using result_type = mapnik::new_geometry::multi_polygon;
|
||||
result_type const& operator() (Geometry const& geom) const
|
||||
{
|
||||
return geom.template get<mapnik::new_geometry::multi_polygon>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct extract_collection
|
||||
{
|
||||
using result_type = mapnik::new_geometry::geometry_collection;
|
||||
result_type const& operator() (Geometry const& geom) const
|
||||
{
|
||||
return geom.template get<mapnik::new_geometry::geometry_collection>();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -142,45 +218,31 @@ template <typename OutputIterator, typename Geometry>
|
|||
struct geometry_generator_grammar :
|
||||
karma::grammar<OutputIterator, Geometry const& ()>
|
||||
{
|
||||
using geometry_type = Geometry;
|
||||
using coord_type = typename std::remove_pointer<typename geometry_type::value_type>::type;
|
||||
|
||||
geometry_generator_grammar();
|
||||
karma::rule<OutputIterator, geometry_type const& ()> coordinates;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> point;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> linestring;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> polygon;
|
||||
karma::rule<OutputIterator, geometry_type const& ()> coords;
|
||||
karma::rule<OutputIterator, karma::locals<unsigned>, geometry_type const& ()> coords2;
|
||||
karma::rule<OutputIterator, coord_type()> point_coord;
|
||||
karma::rule<OutputIterator, coord_type(unsigned& )> polygon_coord;
|
||||
boost::phoenix::function<detail::get_type<geometry_type> > _type;
|
||||
boost::phoenix::function<detail::get_first<geometry_type> > _first;
|
||||
karma::rule<OutputIterator, Geometry const& ()> start;
|
||||
karma::rule<OutputIterator, karma::locals<new_geometry::geometry_types>, Geometry const&()> geometry;
|
||||
karma::rule<OutputIterator, void(new_geometry::geometry_types, Geometry const&) > coordinates;
|
||||
karma::rule<OutputIterator, new_geometry::point()> point;
|
||||
karma::rule<OutputIterator, new_geometry::line_string()> linestring;
|
||||
karma::rule<OutputIterator, new_geometry::polygon()> polygon;
|
||||
karma::rule<OutputIterator, new_geometry::multi_point ()> multi_point;
|
||||
karma::rule<OutputIterator, new_geometry::multi_line_string()> multi_linestring;
|
||||
karma::rule<OutputIterator, new_geometry::multi_polygon()> multi_polygon;
|
||||
karma::rule<OutputIterator, new_geometry::geometry_collection()> geometry_collection;
|
||||
boost::phoenix::function<detail::get_type<Geometry> > geometry_type;
|
||||
boost::phoenix::function<detail::get_x> get_x;
|
||||
boost::phoenix::function<detail::get_y> get_y;
|
||||
boost::phoenix::function<detail::extract_point<Geometry> > extract_point;
|
||||
boost::phoenix::function<detail::extract_linestring<Geometry> > extract_linestring;
|
||||
boost::phoenix::function<detail::extract_polygon<Geometry> > extract_polygon;
|
||||
boost::phoenix::function<detail::extract_multipoint<Geometry> > extract_multipoint;
|
||||
boost::phoenix::function<detail::extract_multilinestring<Geometry> > extract_multilinestring;
|
||||
boost::phoenix::function<detail::extract_multipolygon<Geometry> > extract_multipolygon;
|
||||
boost::phoenix::function<detail::extract_collection<Geometry> > extract_collection;
|
||||
boost::phoenix::function<detail::debug> debug;
|
||||
karma::real_generator<double, detail::json_coordinate_policy<double> > coordinate;
|
||||
};
|
||||
|
||||
|
||||
template <typename OutputIterator, typename GeometryContainer>
|
||||
struct multi_geometry_generator_grammar :
|
||||
karma::grammar<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
|
||||
GeometryContainer const& ()>
|
||||
{
|
||||
using geometry_type = typename std::remove_pointer<typename GeometryContainer::value_type>::type;
|
||||
multi_geometry_generator_grammar();
|
||||
karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
|
||||
GeometryContainer const&()> start;
|
||||
karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
|
||||
GeometryContainer const&()> geometry_collection;
|
||||
karma::rule<OutputIterator, karma::locals<std::tuple<unsigned,bool> >,
|
||||
GeometryContainer const&()> geometry;
|
||||
karma::rule<OutputIterator, karma::locals<unsigned>,
|
||||
geometry_type const&()> geometry2;
|
||||
karma::rule<OutputIterator, GeometryContainer const&()> coordinates;
|
||||
geometry_generator_grammar<OutputIterator, geometry_type> path;
|
||||
// phoenix functions
|
||||
boost::phoenix::function<detail::multi_geometry_type<GeometryContainer> > multi_type_;
|
||||
boost::phoenix::function<detail::get_type<geometry_type> > type_;
|
||||
boost::phoenix::function<detail::not_empty<GeometryContainer> > not_empty_;
|
||||
karma::symbols<unsigned, char const*> geometry_types;
|
||||
karma::symbols<new_geometry::geometry_types, char const*> geometry_types;
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 Artem Pavlenko
|
||||
* Copyright (C) 2015 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -36,107 +36,70 @@ namespace karma = boost::spirit::karma;
|
|||
|
||||
template <typename OutputIterator, typename Geometry>
|
||||
geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar()
|
||||
: geometry_generator_grammar::base_type(coordinates)
|
||||
: geometry_generator_grammar::base_type(start)
|
||||
{
|
||||
boost::spirit::karma::uint_type uint_;
|
||||
boost::spirit::bool_type bool_;
|
||||
boost::spirit::karma::_val_type _val;
|
||||
boost::spirit::karma::_1_type _1;
|
||||
boost::spirit::karma::lit_type lit;
|
||||
boost::spirit::karma::_a_type _a;
|
||||
boost::spirit::karma::_r1_type _r1;
|
||||
boost::spirit::karma::eps_type eps;
|
||||
boost::spirit::karma::string_type kstring;
|
||||
|
||||
coordinates = point | linestring | polygon
|
||||
;
|
||||
|
||||
point = &uint_(mapnik::geometry_type::types::Point)[_1 = _type(_val)]
|
||||
<< point_coord [_1 = _first(_val)]
|
||||
;
|
||||
|
||||
linestring = &uint_(mapnik::geometry_type::types::LineString)[_1 = _type(_val)]
|
||||
<< lit('[')
|
||||
<< coords
|
||||
<< lit(']')
|
||||
;
|
||||
|
||||
polygon = &uint_(mapnik::geometry_type::types::Polygon)[_1 = _type(_val)]
|
||||
<< lit('[')
|
||||
<< coords2
|
||||
<< lit("]]")
|
||||
;
|
||||
|
||||
point_coord = &uint_
|
||||
<< lit('[')
|
||||
<< coordinate << lit(',') << coordinate
|
||||
<< lit(']')
|
||||
;
|
||||
|
||||
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) << eps[_r1 += 1]
|
||||
<< kstring[ if_ (_r1 > 1u) [_1 = "],["]
|
||||
.else_[_1 = '[' ]]
|
||||
|
|
||||
&uint_(mapnik::SEG_LINETO)
|
||||
<< lit(',')) << lit('[') << coordinate << lit(',') << coordinate << lit(']')
|
||||
;
|
||||
|
||||
coords2 %= *polygon_coord(_a)
|
||||
;
|
||||
|
||||
coords = point_coord % lit(',')
|
||||
;
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename GeometryContainer>
|
||||
multi_geometry_generator_grammar<OutputIterator, GeometryContainer>::multi_geometry_generator_grammar()
|
||||
: multi_geometry_generator_grammar::base_type(start)
|
||||
{
|
||||
boost::spirit::karma::uint_type uint_;
|
||||
boost::spirit::bool_type bool_;
|
||||
boost::spirit::karma::_val_type _val;
|
||||
boost::spirit::karma::_1_type _1;
|
||||
boost::spirit::karma::_r2_type _r2;
|
||||
boost::spirit::karma::lit_type lit;
|
||||
boost::spirit::karma::_a_type _a;
|
||||
boost::spirit::karma::eps_type eps;
|
||||
boost::spirit::karma::string_type kstring;
|
||||
boost::spirit::karma::uint_type uint_;
|
||||
|
||||
geometry_types.add
|
||||
(mapnik::geometry_type::types::Point,"\"Point\"")
|
||||
(mapnik::geometry_type::types::LineString,"\"LineString\"")
|
||||
(mapnik::geometry_type::types::Polygon,"\"Polygon\"")
|
||||
(mapnik::geometry_type::types::Point + 3,"\"MultiPoint\"")
|
||||
(mapnik::geometry_type::types::LineString + 3,"\"MultiLineString\"")
|
||||
(mapnik::geometry_type::types::Polygon + 3,"\"MultiPolygon\"")
|
||||
(mapnik::new_geometry::geometry_types::Point,"\"Point\"")
|
||||
(mapnik::new_geometry::geometry_types::LineString,"\"LineString\"")
|
||||
(mapnik::new_geometry::geometry_types::Polygon,"\"Polygon\"")
|
||||
(mapnik::new_geometry::geometry_types::MultiPoint,"\"MultiPoint\"")
|
||||
(mapnik::new_geometry::geometry_types::MultiLineString,"\"MultiLineString\"")
|
||||
(mapnik::new_geometry::geometry_types::MultiPolygon,"\"MultiPolygon\"")
|
||||
(mapnik::new_geometry::geometry_types::GeometryCollection,"\"GeometryCollection\"")
|
||||
;
|
||||
|
||||
start %= ( eps(boost::phoenix::at_c<1>(_a))[_a = multi_type_(_val)]
|
||||
<< lit("{\"type\":\"GeometryCollection\",\"geometries\":[")
|
||||
<< geometry_collection << lit("]}")
|
||||
|
|
||||
geometry)
|
||||
start = geometry.alias()
|
||||
;
|
||||
|
||||
geometry_collection = -(geometry2 % lit(','))
|
||||
;
|
||||
|
||||
geometry = ( &bool_(true)[_1 = not_empty_(_val)] << lit("{\"type\":")
|
||||
<< geometry_types[_1 = boost::phoenix::at_c<0>(_a)][_a = multi_type_(_val)]
|
||||
<< lit(",\"coordinates\":")
|
||||
<< kstring[ boost::phoenix::if_ (boost::phoenix::at_c<0>(_a) > 3u) [_1 = '['].else_[_1 = ""]]
|
||||
<< coordinates
|
||||
<< kstring[ boost::phoenix::if_ (boost::phoenix::at_c<0>(_a) > 3u) [_1 = ']'].else_[_1 = ""]]
|
||||
<< lit('}')) | lit("null")
|
||||
;
|
||||
|
||||
geometry2 = lit("{\"type\":")
|
||||
<< geometry_types[_1 = _a][_a = type_(_val)]
|
||||
geometry = lit("{\"type\":")
|
||||
<< geometry_types[_1 = _a][_a = geometry_type(_val)]
|
||||
<< lit(",\"coordinates\":")
|
||||
<< path
|
||||
<< coordinates(_a,_val)
|
||||
<< lit('}')
|
||||
;
|
||||
|
||||
coordinates %= path % lit(',')
|
||||
coordinates = (&uint_(new_geometry::geometry_types::Point)[_1 = _r1] << point[_1 = extract_point(_r2)])
|
||||
|
|
||||
(&uint_(new_geometry::geometry_types::LineString)[_1 = _r1] << linestring[_1 = extract_linestring(_r2)])
|
||||
|
|
||||
(&uint_(new_geometry::geometry_types::Polygon)[_1 = _r1] << polygon[_1 = extract_polygon(_r2)])
|
||||
|
|
||||
(&uint_(new_geometry::geometry_types::MultiPoint)[_1 = _r1] << multi_point[_1 = extract_multipoint(_r2)])
|
||||
|
|
||||
(&uint_(new_geometry::geometry_types::MultiLineString)[_1 = _r1] << multi_linestring[_1 = extract_multilinestring(_r2)])
|
||||
|
|
||||
(&uint_(new_geometry::geometry_types::MultiPolygon)[_1 = _r1] << multi_polygon[_1 = extract_multipolygon(_r2)])
|
||||
//|
|
||||
//(&uint_(new_geometry::geometry_types::GeometryCollection)[_1 = _r1] << geometry_collection)[_1 = extract_collection(_r2)])
|
||||
;
|
||||
|
||||
point = lit('[') << coordinate[_1 = get_x(_val)] << lit(',') << coordinate[_1 = get_y(_val)] << lit(']')
|
||||
;
|
||||
|
||||
linestring = lit('[') << point % lit(',') << lit(']')
|
||||
;
|
||||
|
||||
polygon = lit('[') << linestring << *(lit(',') << linestring) << lit(']')
|
||||
;
|
||||
|
||||
multi_point = lit('[') << point % lit(',') << lit(']')
|
||||
;
|
||||
|
||||
multi_linestring = lit('[') << linestring % lit(',') << lit(']')
|
||||
;
|
||||
|
||||
multi_polygon = lit('[') << polygon % lit(',') << lit(']')
|
||||
;
|
||||
|
||||
geometry_collection = lit("{\"type\":\"GeometryCollection\",\"geometries\":[") /*<< geometry % lit(',')*/ << lit("]}")
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,18 +19,17 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if 0 // FIXME
|
||||
#include <mapnik/geometry.hpp>
|
||||
|
||||
#include <mapnik/json/feature_generator_grammar_impl.hpp>
|
||||
#include <mapnik/geometry_impl.hpp>
|
||||
|
||||
//#include <mapnik/json/feature_generator_grammar_impl.hpp>
|
||||
#include <mapnik/json/geometry_generator_grammar_impl.hpp>
|
||||
#include <mapnik/json/properties_generator_grammar_impl.hpp>
|
||||
//#include <mapnik/json/properties_generator_grammar_impl.hpp>
|
||||
#include <string>
|
||||
|
||||
using sink_type = std::back_insert_iterator<std::string>;
|
||||
|
||||
template struct mapnik::json::properties_generator_grammar<sink_type, mapnik::feature_impl>;
|
||||
template struct mapnik::json::feature_generator_grammar<sink_type, mapnik::feature_impl>;
|
||||
template struct mapnik::json::geometry_generator_grammar<sink_type, mapnik::geometry_type>;
|
||||
template struct mapnik::json::multi_geometry_generator_grammar<sink_type, mapnik::geometry_container>;
|
||||
#endif
|
||||
//template struct mapnik::json::properties_generator_grammar<sink_type, mapnik::feature_impl>;
|
||||
//template struct mapnik::json::feature_generator_grammar<sink_type, mapnik::feature_impl>;
|
||||
template struct mapnik::json::geometry_generator_grammar<sink_type, mapnik::new_geometry::geometry>;
|
||||
//template struct mapnik::json::multi_geometry_generator_grammar<sink_type, mapnik::geometry_container>;
|
||||
|
|
Loading…
Reference in a new issue