extract bounding boxes from GeoJSON - re-implement grammar to store offset and size of "Feature" elements

This commit is contained in:
artemp 2015-01-19 18:09:23 +01:00
parent f50a34d1b8
commit 15a83ff54d
2 changed files with 23 additions and 32 deletions

View file

@ -43,7 +43,7 @@
namespace mapnik { namespace json { namespace mapnik { namespace json {
using position = std::tuple<double,double>; using position = std::tuple<double,double>;
using boxes = std::vector<std::tuple<box2d<double>, std::size_t>>; using boxes = std::vector<std::pair<box2d<double>, std::pair<std::size_t, std::size_t>>>;
namespace qi = boost::spirit::qi; namespace qi = boost::spirit::qi;
namespace standard_wide = boost::spirit::standard_wide; namespace standard_wide = boost::spirit::standard_wide;
@ -51,7 +51,7 @@ using standard_wide::space_type;
struct calculate_bounding_box_impl struct calculate_bounding_box_impl
{ {
using result_type = void;// box2d<double>; using result_type = void;
template <typename T0, typename T1> template <typename T0, typename T1>
result_type operator() (T0 & bbox, T1 const& pos) const result_type operator() (T0 & bbox, T1 const& pos) const
{ {
@ -74,20 +74,10 @@ struct calculate_bounding_box_impl
struct push_box_impl struct push_box_impl
{ {
using result_type = void; using result_type = void;
template <typename T> template <typename T0, typename T1, typename T2, typename T3>
result_type operator() (T & boxes, std::size_t offset, box2d<double> const& box) const void operator() (T0 & boxes, T1 const& begin, T2 const& box, T3 const& range) const
{ {
boxes.emplace_back(box, offset); boxes.emplace_back(box, std::make_pair(std::distance(begin, range.begin()), std::distance(range.begin(), range.end())));
}
};
struct offset_impl
{
using result_type = std::size_t;
template <typename T0, typename T1>
std::size_t operator() (T0 const& begin, T1 const& itr) const
{
return std::distance(begin, itr);
} }
}; };
@ -96,17 +86,17 @@ struct extract_bounding_box_grammar :
qi::grammar<Iterator, void(boxes&) ,space_type> qi::grammar<Iterator, void(boxes&) ,space_type>
{ {
extract_bounding_box_grammar(); extract_bounding_box_grammar();
// rules
qi::rule<Iterator, void(boxes&), space_type> start; qi::rule<Iterator, void(boxes&), space_type> start;
qi::rule<Iterator, qi::locals<Iterator,Iterator>, void(boxes&), space_type> features; qi::rule<Iterator, qi::locals<Iterator>, void(boxes&), space_type> features;
qi::rule<Iterator, void(boxes&, Iterator const&, Iterator const&), space_type> feature; qi::rule<Iterator, qi::locals<int, box2d<double>>, void(boxes&, Iterator const&), space_type> feature;
qi::rule<Iterator, void(boxes&,std::size_t), space_type> bounding_box;
qi::rule<Iterator, qi::locals<box2d<double>>, box2d<double>(), space_type> coords; qi::rule<Iterator, qi::locals<box2d<double>>, box2d<double>(), space_type> coords;
qi::rule<Iterator, boost::optional<position>(), space_type> pos; qi::rule<Iterator, boost::optional<position>(), space_type> pos;
qi::rule<Iterator, void(box2d<double>&), space_type> ring; qi::rule<Iterator, void(box2d<double>&), space_type> ring;
qi::rule<Iterator, void(box2d<double>&), space_type> rings; qi::rule<Iterator, void(box2d<double>&), space_type> rings;
qi::rule<Iterator, void(box2d<double>&), space_type> rings_array; qi::rule<Iterator, void(box2d<double>&), space_type> rings_array;
boost::phoenix::function<offset_impl> offset; // phoenix functions
boost::phoenix::function<push_box_impl> push_box; boost::phoenix::function<push_box_impl> push_box;
boost::phoenix::function<calculate_bounding_box_impl> calculate_bounding_box; boost::phoenix::function<calculate_bounding_box_impl> calculate_bounding_box;
// error handler // error handler

View file

@ -28,7 +28,6 @@
#include <boost/spirit/include/phoenix_object.hpp> #include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp> #include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>
#include <boost/spirit/repository/include/qi_iter_pos.hpp> #include <boost/spirit/repository/include/qi_iter_pos.hpp>
// stl // stl
#include <iostream> #include <iostream>
@ -52,16 +51,15 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_gramm
qi::omit_type omit; qi::omit_type omit;
qi::_r1_type _r1; qi::_r1_type _r1;
qi::_r2_type _r2; qi::_r2_type _r2;
qi::_r3_type _r3;
qi::_a_type _a; qi::_a_type _a;
qi::_b_type _b; qi::_b_type _b;
qi::skip_type skip; qi::eps_type eps;
qi::lexeme_type lexeme; qi::raw_type raw;
boost::spirit::repository::qi::seek_type seek; standard_wide::char_type char_;
boost::spirit::repository::qi::iter_pos_type iter_pos; boost::spirit::repository::qi::iter_pos_type iter_pos;
using qi::fail; using qi::fail;
using qi::on_error; using qi::on_error;
using boost::phoenix::push_back;
start = features(_r1) start = features(_r1)
; ;
@ -69,15 +67,18 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_gramm
>> lit(':') >> lit("\"FeatureCollection\"") >> lit(':') >> lit("\"FeatureCollection\"")
>> lit(',') >> lit("\"features\"") >> lit(',') >> lit("\"features\"")
>> lit(':')) >> lit(':'))
>> lit('[') >> *(seek[lexeme[skip[iter_pos[_b = _1] >> lit('{') >> lit("\"type\"") >> lit(':') >> lit("\"Feature\"")]]] >> lit('[') >> (feature(_r1,_a) % lit(',')) >> lit(']')
>> feature(_r1, _a, _b))
; ;
feature = raw[lit('{')[_a = 1] >> lit("\"type\"") >> lit(':') >> lit("\"Feature\"")
feature = bounding_box(_r1, offset(_r2, _r3)) >> *(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 = lit("\"coordinates\"") >> lit(':') >> (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a]
;
coords = (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a]
; ;
pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']') pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']')
; ;