extract_bounding_box grammar initial impl
This commit is contained in:
parent
39d8d65343
commit
785cf5c09f
2 changed files with 230 additions and 0 deletions
122
include/mapnik/json/extract_bounding_box_grammar.hpp
Normal file
122
include/mapnik/json/extract_bounding_box_grammar.hpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP
|
||||
#define MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/json/error_handler.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// boost
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedef"
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
#include <tuple>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct empty {};
|
||||
using position = std::tuple<double,double>;
|
||||
//using positions = std::vector<position>;
|
||||
using boxes = std::vector<std::tuple<std::size_t,box2d<double>>>;
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace standard_wide = boost::spirit::standard_wide;
|
||||
using standard_wide::space_type;
|
||||
|
||||
struct calculate_bounding_box_impl
|
||||
{
|
||||
using result_type = void;// box2d<double>;
|
||||
template <typename T0, typename T1>
|
||||
result_type operator() (T0 & bbox, T1 const& pos) const
|
||||
{
|
||||
if (pos)
|
||||
{
|
||||
double x = std::get<0>(*pos);
|
||||
double y = std::get<1>(*pos);
|
||||
if (!bbox.valid())
|
||||
{
|
||||
bbox.init(x, y, x, y); // TODO: add init(x,y) convinience method
|
||||
}
|
||||
else
|
||||
{
|
||||
bbox.expand_to_include(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
boxes.emplace_back(offset, box);
|
||||
}
|
||||
};
|
||||
|
||||
struct offset_impl
|
||||
{
|
||||
using result_type = std::size_t;
|
||||
template <typename T0, typename T1>
|
||||
std::size_t operator() (T0 const& begin, T1 const& range) const
|
||||
{
|
||||
//std::cerr << std::distance(range.begin(),range.end()) << std::endl;
|
||||
//std::cerr << std::string(range.begin(),range.end()) << std::endl;
|
||||
return std::distance(begin, range.begin());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
|
||||
struct extract_bounding_box_grammar :
|
||||
qi::grammar<Iterator, void(boxes&) ,space_type>
|
||||
{
|
||||
extract_bounding_box_grammar();
|
||||
qi::rule<Iterator, void(boxes&), space_type> start;
|
||||
qi::rule<Iterator, qi::locals<Iterator,boost::iterator_range<Iterator>>, void(boxes&), space_type> features;
|
||||
qi::rule<Iterator, void(boxes&, Iterator const&, boost::iterator_range<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, 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;
|
||||
boost::phoenix::function<push_box_impl> push_box;
|
||||
boost::phoenix::function<calculate_bounding_box_impl> calculate_bounding_box;
|
||||
// error handler
|
||||
boost::phoenix::function<ErrorHandler> const error_handler;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP
|
108
include/mapnik/json/extract_bounding_box_grammar_impl.hpp
Normal file
108
include/mapnik/json/extract_bounding_box_grammar_impl.hpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/json/extract_bounding_box_grammar.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/spirit/include/qi_omit.hpp>
|
||||
#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>
|
||||
#include <string>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace repo = boost::spirit::repository;
|
||||
|
||||
template <typename Iterator, typename ErrorHandler>
|
||||
extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_grammar()
|
||||
: extract_bounding_box_grammar::base_type(start,"bounding boxes")
|
||||
{
|
||||
qi::lit_type lit;
|
||||
qi::double_type double_;
|
||||
qi::_val_type _val;
|
||||
qi::_1_type _1;
|
||||
qi::_2_type _2;
|
||||
qi::_3_type _3;
|
||||
qi::_4_type _4;
|
||||
qi::omit_type omit;
|
||||
qi::_r1_type _r1;
|
||||
qi::_r2_type _r2;
|
||||
qi::_r3_type _r3;
|
||||
qi::_a_type _a;
|
||||
qi::_b_type _b;
|
||||
using qi::fail;
|
||||
using qi::on_error;
|
||||
using qi::skip;
|
||||
using qi::lexeme;
|
||||
using qi::raw;
|
||||
using boost::phoenix::push_back;
|
||||
using boost::spirit::repository::qi::seek;
|
||||
using boost::spirit::repository::qi::iter_pos;
|
||||
|
||||
start = features(_r1)
|
||||
;
|
||||
|
||||
//features = iter_pos[_a = _1] >> *(iter_pos[_b = _1] >> seek[lexeme[skip[lit('{') >> lit("\"type\"") >> ":" >> "\"Feature\""]]]
|
||||
// >> feature(_r1, _a, _b))
|
||||
// ;
|
||||
|
||||
features = iter_pos[_a = _1] >> -(lit('{') >> -lit("\"type\"") >> lit(':') >> lit("\"FeatureCollection\"")
|
||||
>> lit(',') >> lit("\"features\"") >> lit(':'))
|
||||
>> lit('[') >> *(raw[seek[lexeme[skip[iter_pos > lit('{') > lit("\"type\"") > lit(':') > lit("\"Feature\"")]]]] [_b = _1]
|
||||
> feature(_r1, _a, _b))
|
||||
;
|
||||
//features = iter_pos[_a = _1] >> seek[lexeme[skip[lit("\"type\"") >> lit(':') >> " ]]]
|
||||
// >> iter_pos[_b = _1] >> *(lit(':') >> feature(_r1, _a, _b) | seek["\"type\""] >> iter_pos[_b = _1])
|
||||
// ;
|
||||
|
||||
feature = /*lit("\"Feature\"") >> */bounding_box(_r1, offset(_r2, _r3))
|
||||
;
|
||||
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]
|
||||
;
|
||||
pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']')
|
||||
;
|
||||
ring = lit('[') >> pos[calculate_bounding_box(_r1,_1)] % lit(',') > lit(']')
|
||||
;
|
||||
rings = lit('[') >> ring(_r1) % lit(',') > lit(']')
|
||||
;
|
||||
rings_array = lit('[') >> rings(_r1) % lit(',') > lit(']')
|
||||
;
|
||||
|
||||
coords.name("Coordinates");
|
||||
pos.name("Position");
|
||||
ring.name("Ring");
|
||||
rings.name("Rings");
|
||||
rings_array.name("Rings array");
|
||||
|
||||
// error handler
|
||||
on_error<fail>(coords, error_handler(_1, _2, _3, _4));
|
||||
}
|
||||
|
||||
}}
|
Loading…
Add table
Reference in a new issue