diff --git a/include/mapnik/json/feature_collection_grammar.hpp b/include/mapnik/json/feature_collection_grammar.hpp index 6ffcd2bde..35ce34a1f 100644 --- a/include/mapnik/json/feature_collection_grammar.hpp +++ b/include/mapnik/json/feature_collection_grammar.hpp @@ -40,20 +40,45 @@ namespace phoenix = boost::phoenix; namespace standard_wide = boost::spirit::standard_wide; using standard_wide::space_type; -template +struct default_feature_callback +{ + default_feature_callback(std::vector & features) + : features_(features) {} + void operator() (feature_ptr const& feature) + { + features_.push_back(feature); + } + std::vector & features_; +}; + +struct apply_feature_callback +{ + using result_type = void; + template + void operator() (Callback & callback, Feature const& feature) const + { + callback(feature); + } +}; + +template struct feature_collection_grammar : - qi::grammar(context_ptr const&, std::size_t& ), space_type> + qi::grammar { feature_collection_grammar(mapnik::transcoder const& tr); + // grammars feature_grammar feature_g; geometry_grammar geometry_g; - phoenix::function extract_geometry_; - qi::rule(context_ptr const&, std::size_t&), space_type> start; // START - qi::rule(context_ptr const&, std::size_t&), space_type> feature_collection; + // rules + qi::rule start; // START + qi::rule feature_collection; qi::rule type; - qi::rule(context_ptr const&, std::size_t&), space_type> features; - qi::rule, void(context_ptr const& ctx, std::size_t, std::vector&), space_type> feature; - qi::rule, void(context_ptr const& ctx, std::size_t, std::vector&), space_type> feature_from_geometry; + qi::rule features; + qi::rule, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature; + qi::rule, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature_from_geometry; + // phoenix functions + phoenix::function extract_geometry; + phoenix::function on_feature; }; }} diff --git a/include/mapnik/json/feature_collection_grammar_impl.hpp b/include/mapnik/json/feature_collection_grammar_impl.hpp index 7d1c77819..7ef81c76d 100644 --- a/include/mapnik/json/feature_collection_grammar_impl.hpp +++ b/include/mapnik/json/feature_collection_grammar_impl.hpp @@ -31,8 +31,8 @@ namespace mapnik { namespace json { -template -feature_collection_grammar::feature_collection_grammar(mapnik::transcoder const& tr) +template +feature_collection_grammar::feature_collection_grammar(mapnik::transcoder const& tr) : feature_collection_grammar::base_type(start,"start"), feature_g(tr) { @@ -42,7 +42,6 @@ feature_collection_grammar::feature_collection_grammar(map qi::_3_type _2; qi::_2_type _3; qi::_a_type _a; - qi::_val_type _val; qi::_r1_type _r1; qi::_r2_type _r2; qi::_r3_type _r3; @@ -51,10 +50,10 @@ feature_collection_grammar::feature_collection_grammar(map using phoenix::new_; using phoenix::val; - start = feature_collection(_r1, _r2) | feature_from_geometry(_r1, _r2, _val) | feature(_r1, _r2, _val) + start = feature_collection(_r1, _r2, _r3) | feature_from_geometry(_r1, _r2, _r3) | feature(_r1, _r2, _r3) ; - feature_collection = lit('{') >> (type | features(_r1, _r2) | feature_g.json_.key_value) % lit(',') >> lit('}') + feature_collection = lit('{') >> (type | features(_r1, _r2, _r3) | feature_g.json_.key_value) % lit(',') >> lit('}') ; type = lit("\"type\"") >> lit(':') >> lit("\"FeatureCollection\"") @@ -63,17 +62,17 @@ feature_collection_grammar::feature_collection_grammar(map features = lit("\"features\"") >> lit(':') >> lit('[') - >> -(feature(_r1, _r2, _val) [_r2 +=1] % lit(',')) + >> -(feature(_r1, _r2, _r3) [_r2 +=1] % lit(',')) >> lit(']') ; feature = eps[_a = phoenix::construct(new_(_r1, _r2))] - >> feature_g(*_a)[push_back(_r3,_a)] + >> feature_g(*_a)[on_feature(_r3,_a)] ; feature_from_geometry = eps[_a = phoenix::construct(new_(_r1, _r2))] - >> geometry_g(extract_geometry_(*_a)) [push_back(_r3, _a)] + >> geometry_g(extract_geometry(*_a)) [on_feature(_r3, _a)] ; start.name("start"); diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 87930d63c..6b96865f2 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -219,9 +219,12 @@ void geojson_datasource::parse_geojson(T const& buffer) boost::spirit::standard_wide::space_type space; mapnik::context_ptr ctx = std::make_shared(); std::size_t start_id = 1; + + mapnik::json::default_feature_callback callback(features_); + bool result = boost::spirit::qi::phrase_parse(buffer.begin(), buffer.end(), (fc_grammar) - (boost::phoenix::ref(ctx),boost::phoenix::ref(start_id)), - space, features_); + (boost::phoenix::ref(ctx),boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), + space); if (!result) { if (!inline_string_.empty()) throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file from in-memory string"); diff --git a/src/json/mapnik_json_feature_collection_grammar.cpp b/src/json/mapnik_json_feature_collection_grammar.cpp index 779c2e364..fb29b54d1 100644 --- a/src/json/mapnik_json_feature_collection_grammar.cpp +++ b/src/json/mapnik_json_feature_collection_grammar.cpp @@ -25,4 +25,4 @@ #include using iterator_type = std::string::const_iterator; -template struct mapnik::json::feature_collection_grammar ; +template struct mapnik::json::feature_collection_grammar ;