parent
2b50c105c3
commit
c860ed4d99
3 changed files with 488 additions and 0 deletions
100
include/mapnik/json/topojson_grammar.hpp
Normal file
100
include/mapnik/json/topojson_grammar.hpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2013 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_TOPOJSON_GRAMMAR_HPP
|
||||
#define MAPNIK_TOPOJSON_GRAMMAR_HPP
|
||||
|
||||
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
//
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/topology.hpp>
|
||||
//
|
||||
#include <string>
|
||||
|
||||
namespace mapnik { namespace topojson {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace phoenix = boost::phoenix;
|
||||
namespace fusion = boost::fusion;
|
||||
namespace standard_wide = boost::spirit::standard_wide;
|
||||
using standard_wide::space_type;
|
||||
|
||||
struct where_message
|
||||
{
|
||||
typedef std::string result_type;
|
||||
|
||||
template <typename Iterator>
|
||||
std::string operator() (Iterator first, Iterator last, std::size_t size) const
|
||||
{
|
||||
std::string str(first, last);
|
||||
if (str.length() > size)
|
||||
return str.substr(0, size) + "..." ;
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct topojson_grammar : qi::grammar<Iterator, space_type, topology()>
|
||||
|
||||
{
|
||||
topojson_grammar();
|
||||
private:
|
||||
// generic JSON support
|
||||
qi::rule<Iterator,space_type> value;
|
||||
qi::symbols<char const, char const> unesc_char;
|
||||
qi::uint_parser< unsigned, 16, 4, 4 > hex4 ;
|
||||
qi::int_parser<mapnik::value_integer,10,1,-1> int__;
|
||||
qi::rule<Iterator,std::string(), space_type> string_;
|
||||
qi::rule<Iterator,space_type> key_value;
|
||||
qi::rule<Iterator,space_type> number;
|
||||
qi::rule<Iterator,space_type> object;
|
||||
qi::rule<Iterator,space_type> array;
|
||||
qi::rule<Iterator,space_type> pairs;
|
||||
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
|
||||
|
||||
// topoJSON
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::topology()> topology;
|
||||
qi::rule<Iterator, space_type, std::vector<mapnik::topojson::geometry>()> objects;
|
||||
qi::rule<Iterator, space_type, std::vector<mapnik::topojson::arc>()> arcs;
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::arc()> arc;
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::coordinate()> coordinate;
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::transform()> transform;
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::bounding_box()> bbox;
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::geometry()> geometry;
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::point()> point;
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::linestring()> linestring;
|
||||
qi::rule<Iterator, space_type, mapnik::topojson::polygon()> polygon;
|
||||
qi::rule<Iterator, space_type, std::vector<index_type>()> ring;
|
||||
|
||||
// properties
|
||||
qi::rule<Iterator,space_type, mapnik::topojson::properties()> properties;
|
||||
|
||||
// error
|
||||
boost::phoenix::function<where_message> where_message_;
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif //MAPNIK_TOPOJSON_GRAMMAR_HPP
|
192
include/mapnik/json/topojson_grammar_impl.hpp
Normal file
192
include/mapnik/json/topojson_grammar_impl.hpp
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2013 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/topojson_grammar.hpp>
|
||||
|
||||
//#define BOOST_SPIRIT_USE_PHOENIX_V3 1
|
||||
//#include <boost/spirit/include/qi.hpp>
|
||||
//#include <boost/spirit/include/phoenix.hpp>
|
||||
//
|
||||
//#include <mapnik/value.hpp>
|
||||
//#include <mapnik/topology.hpp>
|
||||
//
|
||||
//#include <string>
|
||||
|
||||
namespace mapnik { namespace topojson {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace phoenix = boost::phoenix;
|
||||
namespace fusion = boost::fusion;
|
||||
namespace standard_wide = boost::spirit::standard_wide;
|
||||
using standard_wide::space_type;
|
||||
|
||||
template <typename Iterator>
|
||||
topojson_grammar<Iterator>::topojson_grammar()
|
||||
: topojson_grammar::base_type(topology, "topojson")
|
||||
{
|
||||
using qi::lit;
|
||||
using qi::double_;
|
||||
using qi::int_;
|
||||
using qi::no_skip;
|
||||
using qi::omit;
|
||||
using qi::_val;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_4;
|
||||
using qi::fail;
|
||||
using qi::on_error;
|
||||
|
||||
using standard_wide::char_;
|
||||
using phoenix::construct;
|
||||
|
||||
// generic json types
|
||||
value = object | array | string_ | number
|
||||
;
|
||||
|
||||
pairs = key_value % lit(',')
|
||||
;
|
||||
|
||||
key_value = (string_ >> lit(':') >> value)
|
||||
;
|
||||
|
||||
object = lit('{') >> *pairs >> lit('}')
|
||||
;
|
||||
|
||||
array = lit('[')
|
||||
>> value >> *(lit(',') >> value)
|
||||
>> lit(']')
|
||||
;
|
||||
|
||||
number %= strict_double
|
||||
| int__
|
||||
| lit("true")[_val = true]
|
||||
| lit("false")[_val = false]
|
||||
| lit("null")
|
||||
;
|
||||
|
||||
unesc_char.add
|
||||
("\\\"", '\"') // quotation mark
|
||||
("\\\\", '\\') // reverse solidus
|
||||
("\\/", '/') // solidus
|
||||
("\\b", '\b') // backspace
|
||||
("\\f", '\f') // formfeed
|
||||
("\\n", '\n') // newline
|
||||
("\\r", '\r') // carrige return
|
||||
("\\t", '\t') // tab
|
||||
;
|
||||
|
||||
string_ %= lit('"') >> no_skip[*(unesc_char | "\\u" >> hex4 | (char_ - lit('"')))] >> lit('"')
|
||||
;
|
||||
|
||||
// topo json
|
||||
topology = lit('{') >> lit("\"type\"") >> lit(':') >> lit("\"Topology\"")
|
||||
>> ( (lit(',') >> objects) ^ ( lit(',') >> arcs) ^ (lit(',') >> transform) ^ (lit(',') >> bbox))
|
||||
>> lit('}')
|
||||
;
|
||||
|
||||
transform = lit("\"transform\"") >> lit(':') >> lit('{')
|
||||
>> lit("\"scale\"") >> lit(':')
|
||||
>> lit('[')
|
||||
>> double_ >> lit(',')
|
||||
>> double_ >> lit(']') >> lit(',')
|
||||
>> lit("\"translate\"") >> lit(':')
|
||||
>> lit('[') >> double_ >> lit(',') >> double_ >> lit(']')
|
||||
>> lit('}')
|
||||
;
|
||||
|
||||
bbox = lit("\"bbox\"") >> lit(':')
|
||||
>> lit('[') >> double_ >> lit(',') >> double_
|
||||
>> lit(',') >> double_ >> lit(',') >> double_
|
||||
>> lit(']')
|
||||
;
|
||||
|
||||
objects = lit("\"objects\"") >> lit(':') >> lit('{')
|
||||
>> omit[string_] >> lit(':') >> lit('{')
|
||||
>> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"") >> lit(',')
|
||||
>> lit("\"geometries\"") >> lit(':') >> lit('[') >> -(geometry % lit(','))
|
||||
>> lit(']') >> lit('}') >> lit('}')
|
||||
;
|
||||
|
||||
geometry = point | linestring | polygon | omit[object]
|
||||
;
|
||||
|
||||
point = lit('{')
|
||||
>> lit("\"type\"") >> lit(':') >> lit("\"Point\"")
|
||||
>> ((lit(',') >> lit("\"coordinates\"") >> lit(':') >> coordinate) ^ (lit(',') >> properties))
|
||||
>> lit('}')
|
||||
;
|
||||
|
||||
linestring = lit('{')
|
||||
>> lit("\"type\"") >> lit(':') >> lit("\"LineString\"")
|
||||
>> ((lit(',') >> lit("\"arcs\"") >> lit(':') >> lit('[') >> int_ >> lit(']')) ^ (lit(',') >> properties))
|
||||
>> lit('}')
|
||||
;
|
||||
|
||||
polygon = lit('{')
|
||||
>> lit("\"type\"") >> lit(':') >> lit("\"Polygon\"")
|
||||
>> ((lit(',') >> lit("\"arcs\"") >> lit(':') >> lit('[') >> -(ring % lit(',')) >> lit(']')) ^ (lit(',') >> properties))
|
||||
>> lit('}')
|
||||
;
|
||||
|
||||
ring = lit('[') >> -(int_ % lit(',')) >> lit(']')
|
||||
;
|
||||
|
||||
properties = lit("\"properties\"")
|
||||
>> lit(':')
|
||||
>> object
|
||||
;
|
||||
|
||||
arcs = lit("\"arcs\"") >> lit(':')
|
||||
>> lit('[') >> -( arc % lit(',')) >> lit(']') ;
|
||||
|
||||
arc = lit('[') >> -(coordinate % lit(',')) >> lit(']') ;
|
||||
|
||||
coordinate = lit('[') >> double_ >> lit(',') >> double_ >> lit(']');
|
||||
|
||||
topology.name("topology");
|
||||
transform.name("transform");
|
||||
objects.name("objects");
|
||||
arc.name("arc");
|
||||
arcs.name("arcs");
|
||||
value.name("value");
|
||||
coordinate.name("coordinate");
|
||||
|
||||
point.name("point");
|
||||
linestring.name("linestring");
|
||||
polygon.name("polygon");
|
||||
|
||||
on_error<fail>
|
||||
(
|
||||
topology
|
||||
, std::clog
|
||||
<< phoenix::val("Error! Expecting ")
|
||||
<< _4 // what failed?
|
||||
<< phoenix::val(" here: \"")
|
||||
<< where_message_(_3, _2, 16) // where? 16 is max chars to output
|
||||
<< phoenix::val("\"")
|
||||
<< std::endl
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}}
|
196
include/mapnik/json/topology.hpp
Normal file
196
include/mapnik/json/topology.hpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2013 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_TOPOLOGY_HPP
|
||||
#define MAPNIK_TOPOLOGY_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
#include <boost/spirit/include/support_utree.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace mapnik { namespace topojson {
|
||||
|
||||
typedef int index_type;
|
||||
|
||||
struct coordinate
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
typedef boost::spirit::utree properties;
|
||||
|
||||
struct point
|
||||
{
|
||||
coordinate coord;
|
||||
boost::optional<properties> props;
|
||||
};
|
||||
|
||||
struct multi_point
|
||||
{
|
||||
std::vector<coordinate> points;
|
||||
boost::optional<properties> props;
|
||||
};
|
||||
|
||||
struct linestring
|
||||
{
|
||||
index_type ring ;
|
||||
boost::optional<properties> props;
|
||||
};
|
||||
|
||||
struct multi_linestring
|
||||
{
|
||||
std::vector<index_type> rings;
|
||||
boost::optional<properties> props;
|
||||
};
|
||||
|
||||
struct polygon
|
||||
{
|
||||
std::vector<std::vector<index_type> > rings;
|
||||
boost::optional<properties> props;
|
||||
};
|
||||
|
||||
struct multi_polygon
|
||||
{
|
||||
std::vector<polygon> polygons;//FIXME
|
||||
boost::optional<properties> props;
|
||||
};
|
||||
|
||||
struct invalid {};
|
||||
|
||||
typedef boost::variant<invalid,
|
||||
point,
|
||||
linestring,
|
||||
polygon,
|
||||
multi_point,
|
||||
multi_linestring,
|
||||
multi_polygon> geometry;
|
||||
|
||||
typedef std::tuple<double,double> pair_type;
|
||||
|
||||
struct arc
|
||||
{
|
||||
std::list<coordinate> coordinates;
|
||||
};
|
||||
|
||||
struct transform
|
||||
{
|
||||
double scale_x = 1.0;
|
||||
double scale_y = 1.0;
|
||||
double translate_x = 0.0;
|
||||
double translate_y = 0.0;
|
||||
};
|
||||
|
||||
struct bounding_box
|
||||
{
|
||||
double minx;
|
||||
double miny;
|
||||
double maxx;
|
||||
double maxy;
|
||||
};
|
||||
|
||||
struct topology
|
||||
{
|
||||
std::vector<geometry> geometries;
|
||||
std::vector<arc> arcs;
|
||||
transform tr;
|
||||
boost::optional<bounding_box> bbox;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::coordinate,
|
||||
(double, x)
|
||||
(double, y)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::arc,
|
||||
(std::list<mapnik::topojson::coordinate>, coordinates)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::transform,
|
||||
(double, scale_x)
|
||||
(double, scale_y)
|
||||
(double, translate_x)
|
||||
(double, translate_y)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::bounding_box,
|
||||
(double, minx)
|
||||
(double, miny)
|
||||
(double, maxx)
|
||||
(double, maxy)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::point,
|
||||
(mapnik::topojson::coordinate, coord)
|
||||
(boost::optional<mapnik::topojson::properties>, props)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::multi_point,
|
||||
(std::vector<mapnik::topojson::coordinate>, points)
|
||||
(boost::optional<mapnik::topojson::properties>, props)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::linestring,
|
||||
(mapnik::topojson::index_type, ring)
|
||||
(boost::optional<mapnik::topojson::properties>, props)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::multi_linestring,
|
||||
(std::vector<mapnik::topojson::index_type>, rings)
|
||||
(boost::optional<mapnik::topojson::properties>, props)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::polygon,
|
||||
(std::vector<std::vector<mapnik::topojson::index_type> >, rings)
|
||||
(boost::optional<mapnik::topojson::properties>, props)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::multi_polygon,
|
||||
(std::vector<mapnik::topojson::polygon>, polygons)
|
||||
(boost::optional<mapnik::topojson::properties>, props)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::topojson::topology,
|
||||
(std::vector<mapnik::topojson::geometry>, geometries)
|
||||
(std::vector<mapnik::topojson::arc>, arcs)
|
||||
(mapnik::topojson::transform, tr)
|
||||
(boost::optional<mapnik::topojson::bounding_box>, bbox)
|
||||
)
|
||||
|
||||
#endif // MAPNIK_TOPOLOGY_HPP
|
Loading…
Add table
Reference in a new issue