json grammar - start porting to mapnik-geometry
This commit is contained in:
parent
968ab32c02
commit
fca584de1b
11 changed files with 102 additions and 99 deletions
|
@ -75,7 +75,7 @@ struct feature_collection_grammar :
|
|||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature;
|
||||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature_from_geometry;
|
||||
// phoenix functions
|
||||
phoenix::function<json::extract_geometry> extract_geometry;
|
||||
phoenix::function<json::set_geometry_impl> set_geometry;
|
||||
phoenix::function<apply_feature_callback> on_feature;
|
||||
};
|
||||
|
||||
|
|
|
@ -38,9 +38,10 @@ feature_collection_grammar<Iterator,FeatureType, FeatureCallback>::feature_colle
|
|||
{
|
||||
qi::lit_type lit;
|
||||
qi::eps_type eps;
|
||||
qi::_1_type _1;
|
||||
qi::_2_type _2;
|
||||
qi::_3_type _3;
|
||||
qi::_4_type _4;
|
||||
qi::_3_type _2;
|
||||
qi::_2_type _3;
|
||||
qi::_a_type _a;
|
||||
qi::_r1_type _r1;
|
||||
qi::_r2_type _r2;
|
||||
|
@ -72,7 +73,7 @@ feature_collection_grammar<Iterator,FeatureType, FeatureCallback>::feature_colle
|
|||
|
||||
feature_from_geometry =
|
||||
eps[_a = phoenix::construct<mapnik::feature_ptr>(new_<mapnik::feature_impl>(_r1, _r2))]
|
||||
>> geometry_g(extract_geometry(*_a)) [on_feature(_r3, _a)]
|
||||
>> geometry_g[set_geometry(*_a, _1)] [on_feature(_r3, _a)]
|
||||
;
|
||||
|
||||
start.name("start");
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <mapnik/json/geometry_grammar.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/geometry_container.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/json/generic_json.hpp>
|
||||
|
@ -77,13 +76,13 @@ struct put_property
|
|||
mapnik::transcoder const& tr_;
|
||||
};
|
||||
|
||||
struct extract_geometry
|
||||
struct set_geometry_impl
|
||||
{
|
||||
using result_type = mapnik::geometry_container&;
|
||||
template <typename T>
|
||||
result_type operator() (T & feature) const
|
||||
using result_type = void; //mapnik::geometry_container&;
|
||||
template <typename T0, typename T1>
|
||||
result_type operator() (T0 & feature, T1 && geom) const
|
||||
{
|
||||
return feature.paths();
|
||||
return feature.set_geometry(std::move(geom));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -108,7 +107,7 @@ struct feature_grammar :
|
|||
qi::rule<Iterator, qi::locals<std::int32_t>, std::string(), space_type> stringify_array;
|
||||
// functions
|
||||
phoenix::function<put_property> put_property_;
|
||||
phoenix::function<extract_geometry> extract_geometry_;
|
||||
phoenix::function<set_geometry_impl> set_geometry;
|
||||
// error handler
|
||||
boost::phoenix::function<ErrorHandler> const error_handler;
|
||||
// geometry
|
||||
|
|
|
@ -82,8 +82,8 @@ feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::tran
|
|||
|
||||
feature = lit('{')
|
||||
>> (feature_type | (lit("\"geometry\"") >> lit(':')
|
||||
>> geometry_grammar_(extract_geometry_(_r1))) | properties(_r1) | json_.key_value) % lit(',')
|
||||
>> lit('}')
|
||||
>> geometry_grammar_[set_geometry(_r1, _1)]) | properties(_r1) | json_.key_value) % lit(',')
|
||||
>> lit('}')
|
||||
;
|
||||
|
||||
properties = lit("\"properties\"")
|
||||
|
|
|
@ -24,13 +24,11 @@
|
|||
#define MAPNIK_GEOMETRY_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/geometry.hpp> // for geometry_type
|
||||
#include <mapnik/vertex.hpp> // for CommandType
|
||||
#include <mapnik/geometry_impl.hpp> // for geometry_type
|
||||
#include <mapnik/make_unique.hpp>
|
||||
#include <mapnik/json/generic_json.hpp>
|
||||
#include <mapnik/json/positions_grammar.hpp>
|
||||
#include <mapnik/json/geometry_util.hpp>
|
||||
#include <mapnik/geometry_container.hpp>
|
||||
|
||||
// spirit::qi
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
|
@ -42,14 +40,13 @@ namespace qi = boost::spirit::qi;
|
|||
|
||||
template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
|
||||
struct geometry_grammar :
|
||||
qi::grammar<Iterator,void(mapnik::geometry_container& )
|
||||
, space_type>
|
||||
qi::grammar<Iterator, mapnik::new_geometry::geometry() ,space_type>
|
||||
{
|
||||
geometry_grammar();
|
||||
qi::rule<Iterator,void(mapnik::geometry_container& ), space_type> start;
|
||||
qi::rule<Iterator, qi::locals<int, mapnik::json::coordinates>, void(mapnik::geometry_container& ), space_type> geometry;
|
||||
qi::rule<Iterator, mapnik::new_geometry::geometry(), space_type> start;
|
||||
qi::rule<Iterator, qi::locals<int, mapnik::json::coordinates>, mapnik::new_geometry::geometry(), space_type> geometry;
|
||||
qi::symbols<char, int> geometry_type_dispatch;
|
||||
qi::rule<Iterator,void(mapnik::geometry_container& ),space_type> geometry_collection;
|
||||
qi::rule<Iterator, mapnik::new_geometry::geometry(), space_type> geometry_collection;
|
||||
positions_grammar<Iterator> coordinates;
|
||||
boost::phoenix::function<create_geometry_impl> create_geometry;
|
||||
// error handler
|
||||
|
|
|
@ -42,35 +42,35 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
|
|||
qi::lit_type lit;
|
||||
qi::int_type int_;
|
||||
qi::double_type double_;
|
||||
qi::_val_type _val;
|
||||
qi::_1_type _1;
|
||||
qi::_2_type _2;
|
||||
qi::_3_type _3;
|
||||
qi::_4_type _4;
|
||||
qi::_a_type _a;
|
||||
qi::_b_type _b;
|
||||
qi::_r1_type _r1;
|
||||
qi::eps_type eps;
|
||||
using qi::fail;
|
||||
using qi::on_error;
|
||||
|
||||
start = geometry(_r1) | geometry_collection(_r1);
|
||||
start = geometry.alias() ;// | geometry_collection(_r1);
|
||||
|
||||
geometry = (lit('{')[_a = 0 ]
|
||||
>> (-lit(',') >> lit("\"type\"") >> lit(':') >> geometry_type_dispatch[_a = _1]
|
||||
^
|
||||
(-lit(',') >> lit("\"coordinates\"") >> lit(':') >> coordinates[_b = _1]))[create_geometry(_r1,_a,_b)]
|
||||
(-lit(',') >> lit("\"coordinates\"") >> lit(':') >> coordinates[_b = _1]))[create_geometry(_val,_a,_b)]
|
||||
>> lit('}'))
|
||||
| lit("null")
|
||||
;
|
||||
|
||||
geometry_collection = (lit('{')
|
||||
>> (-lit(',') >> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"")
|
||||
^
|
||||
-lit(',') >> lit("\"geometries\"") >> lit(':')
|
||||
>> lit('[') >> geometry(_r1) % lit(',') >> lit(']'))
|
||||
>> lit('}'))
|
||||
| lit("null")
|
||||
;
|
||||
//geometry_collection = (lit('{')
|
||||
// >> (-lit(',') >> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"")
|
||||
// ^
|
||||
// -lit(',') >> lit("\"geometries\"") >> lit(':')
|
||||
// >> lit('[') >> geometry(_r1) % lit(',') >> lit(']'))
|
||||
// >> lit('}'))
|
||||
// | lit("null")
|
||||
// ;
|
||||
|
||||
geometry_type_dispatch.add
|
||||
("\"Point\"",1)
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
#ifndef MAPNIK_JSON_GEOMETRY_UTIL_HPP
|
||||
#define MAPNIK_JSON_GEOMETRY_UTIL_HPP
|
||||
|
||||
#include <mapnik/geometry.hpp> // for geometry_type
|
||||
#include <mapnik/vertex.hpp> // for CommandType
|
||||
#include <mapnik/make_unique.hpp>
|
||||
#include <mapnik/geometry_impl.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
|
@ -36,11 +34,10 @@ struct create_point
|
|||
explicit create_point(Path & path)
|
||||
: path_(path) {}
|
||||
|
||||
void operator()(position const& pos) const
|
||||
void operator() (position const& pos) const
|
||||
{
|
||||
auto pt = std::make_unique<geometry_type>(geometry_type::types::Point);
|
||||
pt->move_to(std::get<0>(pos), std::get<1>(pos));
|
||||
path_.push_back(pt.release());
|
||||
mapnik::new_geometry::point point(pos.x, pos.y);
|
||||
path_ = std::move(point);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -54,19 +51,18 @@ struct create_linestring
|
|||
explicit create_linestring(Path & path)
|
||||
: path_(path) {}
|
||||
|
||||
void operator()(positions const& ring) const
|
||||
void operator() (positions const& ring) const
|
||||
{
|
||||
std::size_t size = ring.size();
|
||||
if (size > 1)
|
||||
{
|
||||
auto line = std::make_unique<geometry_type>(geometry_type::types::LineString);
|
||||
line->move_to(std::get<0>(ring.front()), std::get<1>(ring.front()));
|
||||
|
||||
for (std::size_t index = 1; index < size; ++index)
|
||||
mapnik::new_geometry::line_string line;
|
||||
line.reserve(size);
|
||||
for (auto && pt : ring)
|
||||
{
|
||||
line->line_to(std::get<0>(ring[index]), std::get<1>(ring[index]));
|
||||
line.emplace_back(std::move(pt));
|
||||
}
|
||||
path_.push_back(line.release());
|
||||
path_ = std::move(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,24 +78,27 @@ struct create_polygon
|
|||
explicit create_polygon(Path & path)
|
||||
: path_(path) {}
|
||||
|
||||
void operator()(std::vector<positions> const& rings) const
|
||||
void operator() (std::vector<positions> const& rings) const
|
||||
{
|
||||
auto poly = std::make_unique<geometry_type>(geometry_type::types::Polygon);
|
||||
mapnik::new_geometry::polygon3 poly;
|
||||
std::size_t num_rings = rings.size();
|
||||
if (num_rings > 1)
|
||||
poly.interior_rings.reserve(num_rings - 1);
|
||||
|
||||
for (auto const& ring : rings)
|
||||
for ( std::size_t i = 0; i < num_rings; ++i)
|
||||
{
|
||||
std::size_t size = ring.size();
|
||||
if (size > 2) // at least 3 vertices to form a ring
|
||||
std::size_t size = rings[i].size();
|
||||
mapnik::new_geometry::linear_ring ring;
|
||||
ring.reserve(size);
|
||||
for ( auto && pt : rings[i])
|
||||
{
|
||||
poly->move_to(std::get<0>(ring.front()), std::get<1>(ring.front()));
|
||||
for (std::size_t index = 1; index < size; ++index)
|
||||
{
|
||||
poly->line_to(std::get<0>(ring[index]), std::get<1>(ring[index]));
|
||||
}
|
||||
poly->close_path();
|
||||
ring.emplace_back(std::move(pt));
|
||||
}
|
||||
if (i == 0) poly.set_exterior_ring(std::move(ring));
|
||||
else poly.add_hole(std::move(ring));
|
||||
}
|
||||
path_.push_back(poly.release());
|
||||
|
||||
path_ = std::move(poly);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -109,21 +108,21 @@ struct create_polygon
|
|||
};
|
||||
|
||||
// multi-geometries
|
||||
|
||||
template <typename Path>
|
||||
struct create_multipoint
|
||||
{
|
||||
explicit create_multipoint(Path & path)
|
||||
: path_(path) {}
|
||||
|
||||
void operator()(positions const& points) const
|
||||
void operator() (positions const& points) const
|
||||
{
|
||||
for (auto const& pos : points)
|
||||
mapnik::new_geometry::multi_point multi_point;
|
||||
multi_point.reserve(points.size());
|
||||
for (auto && pos : points)
|
||||
{
|
||||
auto point = std::make_unique<geometry_type>(geometry_type::types::Point);
|
||||
point->move_to(std::get<0>(pos), std::get<1>(pos));
|
||||
path_.push_back(point.release());
|
||||
multi_point.emplace_back(std::move(pos));
|
||||
}
|
||||
path_ = std::move(multi_point);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -138,22 +137,22 @@ struct create_multilinestring
|
|||
explicit create_multilinestring(Path & path)
|
||||
: path_(path) {}
|
||||
|
||||
void operator()(std::vector<positions> const& rings) const
|
||||
void operator() (std::vector<positions> const& rings) const
|
||||
{
|
||||
mapnik::new_geometry::multi_line_string multi_line;
|
||||
multi_line.reserve(rings.size());
|
||||
|
||||
for (auto const& ring : rings)
|
||||
{
|
||||
auto line = std::make_unique<geometry_type>(geometry_type::types::LineString);
|
||||
std::size_t size = ring.size();
|
||||
if (size > 1) // at least 2 vertices to form a linestring
|
||||
mapnik::new_geometry::line_string line;
|
||||
line.reserve(ring.size());
|
||||
for (auto && pt : ring)
|
||||
{
|
||||
line->move_to(std::get<0>(ring.front()), std::get<1>(ring.front()));
|
||||
for (std::size_t index = 1; index < size; ++index)
|
||||
{
|
||||
line->line_to(std::get<0>(ring[index]), std::get<1>(ring[index]));
|
||||
}
|
||||
line.emplace_back(std::move(pt));
|
||||
}
|
||||
path_.push_back(line.release());
|
||||
multi_line.emplace_back(std::move(line));
|
||||
}
|
||||
path_ = std::move(multi_line);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -170,24 +169,29 @@ struct create_multipolygon
|
|||
|
||||
void operator()(std::vector<std::vector<positions> > const& rings_array) const
|
||||
{
|
||||
mapnik::new_geometry::multi_polygon multi_poly;
|
||||
multi_poly.reserve(rings_array.size());
|
||||
for (auto const& rings : rings_array)
|
||||
{
|
||||
auto poly = std::make_unique<geometry_type>(geometry_type::types::Polygon);
|
||||
for (auto const& ring : rings)
|
||||
mapnik::new_geometry::polygon3 poly;
|
||||
std::size_t num_rings = rings.size();
|
||||
if ( num_rings > 1)
|
||||
poly.interior_rings.reserve(num_rings - 1);
|
||||
|
||||
for ( std::size_t i = 0; i < num_rings; ++i)
|
||||
{
|
||||
std::size_t size = ring.size();
|
||||
if (size > 2) // at least 3 vertices to form a ring
|
||||
std::size_t size = rings[i].size();
|
||||
mapnik::new_geometry::linear_ring ring;
|
||||
ring.reserve(size);
|
||||
for ( auto && pt : rings[i])
|
||||
{
|
||||
poly->move_to(std::get<0>(ring.front()), std::get<1>(ring.front()));
|
||||
for (std::size_t index = 1; index < size; ++index)
|
||||
{
|
||||
poly->line_to(std::get<0>(ring[index]), std::get<1>(ring[index]));
|
||||
}
|
||||
poly->close_path();
|
||||
ring.emplace_back(std::move(pt));
|
||||
}
|
||||
if (i == 0) poly.set_exterior_ring(std::move(ring));
|
||||
else poly.add_hole(std::move(ring));
|
||||
}
|
||||
path_.push_back(poly.release());
|
||||
}
|
||||
path_ = std::move(multi_poly);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -208,8 +212,8 @@ struct create_geometry_impl
|
|||
util::apply_visitor(create_point<T0>(path), coords);
|
||||
break;
|
||||
case 2 ://LineString
|
||||
util::apply_visitor(create_linestring<T0>(path), coords);
|
||||
break;
|
||||
util::apply_visitor(create_linestring<T0>(path), coords);
|
||||
break;
|
||||
case 3 ://Polygon
|
||||
util::apply_visitor(create_polygon<T0>(path), coords);
|
||||
break;
|
||||
|
@ -225,6 +229,7 @@ struct create_geometry_impl
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -41,18 +41,17 @@
|
|||
// stl
|
||||
#include <tuple>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct empty {};
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::new_geometry::point,
|
||||
(double, x)
|
||||
(double, y)
|
||||
)
|
||||
)
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct empty {};
|
||||
|
||||
//BOOST_FUSION_ADAPT_STRUCT(
|
||||
// mapnik::new_geometry::
|
||||
using position = mapnik::new_geometry::point;
|
||||
using positions = std::vector<position>;
|
||||
using coordinates = util::variant<empty, position, positions, std::vector<positions>, std::vector<std::vector<positions> > > ;
|
||||
|
|
|
@ -29,7 +29,7 @@ if 'g++' in env['CXX']:
|
|||
|
||||
name = "mapnik-json"
|
||||
lib = lib_env.StaticLibrary(name, glob('./' + '*.cpp'), LIBS=[])
|
||||
#target = os.path.join(env['MAPNIK_LIB_BASE_DEST'], env.subst('${LIBPREFIX}%s${LIBSUFFIX}' % name))
|
||||
#result = env.InstallAs(target=target, source=lib)
|
||||
#env.Alias(target='install', source=result)
|
||||
#env['create_uninstall_target'](env, target)
|
||||
target = os.path.join(env['MAPNIK_LIB_BASE_DEST'], env.subst('${LIBPREFIX}%s${LIBSUFFIX}' % name))
|
||||
result = env.InstallAs(target=target, source=lib)
|
||||
env.Alias(target='install', source=result)
|
||||
env['create_uninstall_target'](env, target)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#if 0 // FIXME
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_container.hpp>
|
||||
#include <mapnik/json/feature_generator_grammar_impl.hpp>
|
||||
|
@ -33,3 +33,4 @@ template struct mapnik::json::properties_generator_grammar<sink_type, mapnik::fe
|
|||
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
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#if 0 // FIXME
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/json/topojson_grammar_impl.hpp>
|
||||
#include <string>
|
||||
|
||||
using iterator_type = std::string::const_iterator;
|
||||
template struct mapnik::topojson::topojson_grammar<iterator_type> ;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue