json - make feature_collection_grammar "on-feature" callback based
This commit is contained in:
parent
d60e2da44e
commit
4e3ac8ff0c
4 changed files with 46 additions and 19 deletions
|
@ -40,20 +40,45 @@ namespace phoenix = boost::phoenix;
|
|||
namespace standard_wide = boost::spirit::standard_wide;
|
||||
using standard_wide::space_type;
|
||||
|
||||
template <typename Iterator, typename FeatureType>
|
||||
struct default_feature_callback
|
||||
{
|
||||
default_feature_callback(std::vector<feature_ptr> & features)
|
||||
: features_(features) {}
|
||||
void operator() (feature_ptr const& feature)
|
||||
{
|
||||
features_.push_back(feature);
|
||||
}
|
||||
std::vector<feature_ptr> & features_;
|
||||
};
|
||||
|
||||
struct apply_feature_callback
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename Callback, typename Feature>
|
||||
void operator() (Callback & callback, Feature const& feature) const
|
||||
{
|
||||
callback(feature);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator, typename FeatureType, typename FeatureCallback = default_feature_callback>
|
||||
struct feature_collection_grammar :
|
||||
qi::grammar<Iterator, std::vector<feature_ptr>(context_ptr const&, std::size_t& ), space_type>
|
||||
qi::grammar<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback &), space_type>
|
||||
{
|
||||
feature_collection_grammar(mapnik::transcoder const& tr);
|
||||
// grammars
|
||||
feature_grammar<Iterator,FeatureType> feature_g;
|
||||
geometry_grammar<Iterator> geometry_g;
|
||||
phoenix::function<extract_geometry> extract_geometry_;
|
||||
qi::rule<Iterator, std::vector<feature_ptr>(context_ptr const&, std::size_t&), space_type> start; // START
|
||||
qi::rule<Iterator, std::vector<feature_ptr>(context_ptr const&, std::size_t&), space_type> feature_collection;
|
||||
// rules
|
||||
qi::rule<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback&), space_type> start; // START
|
||||
qi::rule<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback&), space_type> feature_collection;
|
||||
qi::rule<Iterator, space_type> type;
|
||||
qi::rule<Iterator, std::vector<feature_ptr>(context_ptr const&, std::size_t&), space_type> features;
|
||||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& ctx, std::size_t, std::vector<feature_ptr>&), space_type> feature;
|
||||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& ctx, std::size_t, std::vector<feature_ptr>&), space_type> feature_from_geometry;
|
||||
qi::rule<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback&), space_type> features;
|
||||
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<extract_geometry> extract_geometry;
|
||||
phoenix::function<apply_feature_callback> on_feature;
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
template <typename Iterator, typename FeatureType>
|
||||
feature_collection_grammar<Iterator,FeatureType>::feature_collection_grammar(mapnik::transcoder const& tr)
|
||||
template <typename Iterator, typename FeatureType, typename FeatureCallback>
|
||||
feature_collection_grammar<Iterator,FeatureType, FeatureCallback>::feature_collection_grammar(mapnik::transcoder const& tr)
|
||||
: feature_collection_grammar::base_type(start,"start"),
|
||||
feature_g(tr)
|
||||
{
|
||||
|
@ -42,7 +42,6 @@ feature_collection_grammar<Iterator,FeatureType>::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<Iterator,FeatureType>::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<Iterator,FeatureType>::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<mapnik::feature_ptr>(new_<mapnik::feature_impl>(_r1, _r2))]
|
||||
>> feature_g(*_a)[push_back(_r3,_a)]
|
||||
>> feature_g(*_a)[on_feature(_r3,_a)]
|
||||
;
|
||||
|
||||
feature_from_geometry =
|
||||
eps[_a = phoenix::construct<mapnik::feature_ptr>(new_<mapnik::feature_impl>(_r1, _r2))]
|
||||
>> geometry_g(extract_geometry_(*_a)) [push_back(_r3, _a)]
|
||||
>> geometry_g(extract_geometry(*_a)) [on_feature(_r3, _a)]
|
||||
;
|
||||
|
||||
start.name("start");
|
||||
|
|
|
@ -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<mapnik::context_type>();
|
||||
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");
|
||||
|
|
|
@ -25,4 +25,4 @@
|
|||
#include <string>
|
||||
|
||||
using iterator_type = std::string::const_iterator;
|
||||
template struct mapnik::json::feature_collection_grammar<iterator_type,mapnik::feature_impl> ;
|
||||
template struct mapnik::json::feature_collection_grammar<iterator_type,mapnik::feature_impl, mapnik::json::default_feature_callback> ;
|
||||
|
|
Loading…
Reference in a new issue