extract bounding boxes from GeoJSON - re-implement grammar to store offset and size of "Feature" elements
This commit is contained in:
parent
f50a34d1b8
commit
15a83ff54d
2 changed files with 23 additions and 32 deletions
|
@ -43,7 +43,7 @@
|
|||
namespace mapnik { namespace json {
|
||||
|
||||
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 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<double>;
|
||||
using result_type = void;
|
||||
template <typename T0, typename T1>
|
||||
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 <typename T>
|
||||
result_type operator() (T & boxes, std::size_t offset, box2d<double> const& box) const
|
||||
template <typename T0, typename T1, typename T2, typename T3>
|
||||
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 <typename T0, typename T1>
|
||||
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<Iterator, void(boxes&) ,space_type>
|
||||
{
|
||||
extract_bounding_box_grammar();
|
||||
// rules
|
||||
qi::rule<Iterator, void(boxes&), space_type> start;
|
||||
qi::rule<Iterator, qi::locals<Iterator,Iterator>, void(boxes&), space_type> features;
|
||||
qi::rule<Iterator, void(boxes&, Iterator const&, Iterator const&), space_type> feature;
|
||||
qi::rule<Iterator, void(boxes&,std::size_t), space_type> bounding_box;
|
||||
qi::rule<Iterator, qi::locals<Iterator>, void(boxes&), space_type> features;
|
||||
qi::rule<Iterator, qi::locals<int, box2d<double>>, void(boxes&, Iterator const&), space_type> feature;
|
||||
qi::rule<Iterator, qi::locals<box2d<double>>, box2d<double>(), space_type> coords;
|
||||
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> rings;
|
||||
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<calculate_bounding_box_impl> calculate_bounding_box;
|
||||
// error handler
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <boost/spirit/include/phoenix_object.hpp>
|
||||
#include <boost/spirit/include/phoenix_stl.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>
|
||||
// stl
|
||||
#include <iostream>
|
||||
|
@ -52,16 +51,15 @@ extract_bounding_box_grammar<Iterator, ErrorHandler>::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<Iterator, ErrorHandler>::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(']')
|
||||
;
|
||||
|
|
Loading…
Reference in a new issue