From 15a83ff54dbc5a7479b263df703c0765c0d3e8a6 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 19 Jan 2015 18:09:23 +0100 Subject: [PATCH] extract bounding boxes from GeoJSON - re-implement grammar to store offset and size of "Feature" elements --- .../json/extract_bounding_box_grammar.hpp | 28 ++++++------------- .../extract_bounding_box_grammar_impl.hpp | 27 +++++++++--------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/include/mapnik/json/extract_bounding_box_grammar.hpp b/include/mapnik/json/extract_bounding_box_grammar.hpp index 83d32c7eb..6395e0797 100644 --- a/include/mapnik/json/extract_bounding_box_grammar.hpp +++ b/include/mapnik/json/extract_bounding_box_grammar.hpp @@ -43,7 +43,7 @@ namespace mapnik { namespace json { using position = std::tuple; -using boxes = std::vector, std::size_t>>; +using boxes = std::vector, std::pair>>; namespace qi = boost::spirit::qi; namespace standard_wide = boost::spirit::standard_wide; @@ -51,7 +51,7 @@ using standard_wide::space_type; struct calculate_bounding_box_impl { - using result_type = void;// box2d; + using result_type = void; template result_type operator() (T0 & bbox, T1 const& pos) const { @@ -74,20 +74,10 @@ struct calculate_bounding_box_impl struct push_box_impl { using result_type = void; - template - result_type operator() (T & boxes, std::size_t offset, box2d const& box) const + template + void operator() (T0 & boxes, T1 const& begin, T2 const& box, T3 const& range) const { - boxes.emplace_back(box, offset); - } -}; - -struct offset_impl -{ - using result_type = std::size_t; - template - std::size_t operator() (T0 const& begin, T1 const& itr) const - { - return std::distance(begin, itr); + boxes.emplace_back(box, std::make_pair(std::distance(begin, range.begin()), std::distance(range.begin(), range.end()))); } }; @@ -96,17 +86,17 @@ struct extract_bounding_box_grammar : qi::grammar { extract_bounding_box_grammar(); + // rules qi::rule start; - qi::rule, void(boxes&), space_type> features; - qi::rule feature; - qi::rule bounding_box; + qi::rule, void(boxes&), space_type> features; + qi::rule>, void(boxes&, Iterator const&), space_type> feature; qi::rule>, box2d(), space_type> coords; qi::rule(), space_type> pos; qi::rule&), space_type> ring; qi::rule&), space_type> rings; qi::rule&), space_type> rings_array; - boost::phoenix::function offset; + // phoenix functions boost::phoenix::function push_box; boost::phoenix::function calculate_bounding_box; // error handler diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp index 6c6a54b7a..d30611cc2 100644 --- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp +++ b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp @@ -28,7 +28,6 @@ #include #include #include -#include #include // stl #include @@ -52,16 +51,15 @@ extract_bounding_box_grammar::extract_bounding_box_gramm qi::omit_type omit; qi::_r1_type _r1; qi::_r2_type _r2; - qi::_r3_type _r3; qi::_a_type _a; qi::_b_type _b; - qi::skip_type skip; - qi::lexeme_type lexeme; - boost::spirit::repository::qi::seek_type seek; + qi::eps_type eps; + qi::raw_type raw; + standard_wide::char_type char_; boost::spirit::repository::qi::iter_pos_type iter_pos; using qi::fail; using qi::on_error; - using boost::phoenix::push_back; + start = features(_r1) ; @@ -69,15 +67,18 @@ extract_bounding_box_grammar::extract_bounding_box_gramm >> lit(':') >> lit("\"FeatureCollection\"") >> lit(',') >> lit("\"features\"") >> lit(':')) - >> lit('[') >> *(seek[lexeme[skip[iter_pos[_b = _1] >> lit('{') >> lit("\"type\"") >> lit(':') >> lit("\"Feature\"")]]] - >> feature(_r1, _a, _b)) + >> lit('[') >> (feature(_r1,_a) % lit(',')) >> lit(']') ; - - feature = bounding_box(_r1, offset(_r2, _r3)) + feature = raw[lit('{')[_a = 1] >> lit("\"type\"") >> lit(':') >> lit("\"Feature\"") + >> *(eps(_a > 0) >> (lit('{')[_a += 1] + | + lit('}')[_a -=1] + | + coords[_b = _1] + | + char_))][push_box(_r1, _r2, _b, _1)] ; - bounding_box = seek["\"coordinates\""] >> lit(':') >> coords[push_box(_r1, _r2, _1)] - ; - coords = (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a] + coords = lit("\"coordinates\"") >> lit(':') >> (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a] ; pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']') ;