GeoJSON - spirit::x3 based parsing building blocks
This commit is contained in:
parent
f014555913
commit
e46a52c3f0
12 changed files with 972 additions and 0 deletions
243
include/mapnik/json/create_geometry.hpp
Normal file
243
include/mapnik/json/create_geometry.hpp
Normal file
|
@ -0,0 +1,243 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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_CREATE_GEOMETRY_HPP
|
||||
#define MAPNIK_JSON_CREATE_GEOMETRY_HPP
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry/correct.hpp>
|
||||
#include <mapnik/json/positions_x3.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
// geometries
|
||||
template <typename Geometry>
|
||||
struct create_point
|
||||
{
|
||||
explicit create_point(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (point const& pos) const
|
||||
{
|
||||
mapnik::geometry::point<double> point(pos.x, pos.y);
|
||||
geom_ = std::move(point);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
||||
Geometry & geom_;
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct create_linestring
|
||||
{
|
||||
explicit create_linestring(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (ring const& points) const
|
||||
{
|
||||
std::size_t size = points.size();
|
||||
if (size > 1)
|
||||
{
|
||||
mapnik::geometry::line_string<double> line;
|
||||
line.reserve(size);
|
||||
for (auto && pt : points)
|
||||
{
|
||||
line.emplace_back(std::move(pt));
|
||||
}
|
||||
geom_ = std::move(line);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
||||
|
||||
Geometry & geom_;
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct create_polygon
|
||||
{
|
||||
explicit create_polygon(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (rings const& rngs) const
|
||||
{
|
||||
mapnik::geometry::polygon<double> poly;
|
||||
std::size_t num_rings = rngs.size();
|
||||
if (num_rings > 1)
|
||||
{
|
||||
poly.interior_rings.reserve(num_rings - 1);
|
||||
}
|
||||
|
||||
for ( std::size_t i = 0; i < num_rings; ++i)
|
||||
{
|
||||
std::size_t size = rngs[i].size();
|
||||
mapnik::geometry::linear_ring<double> ring;
|
||||
ring.reserve(size);
|
||||
for ( auto && pt : rngs[i])
|
||||
{
|
||||
ring.emplace_back(std::move(pt));
|
||||
}
|
||||
if (i == 0) poly.set_exterior_ring(std::move(ring));
|
||||
else poly.add_hole(std::move(ring));
|
||||
}
|
||||
geom_ = std::move(poly);
|
||||
mapnik::geometry::correct(geom_);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
||||
|
||||
Geometry & geom_;
|
||||
};
|
||||
|
||||
// multi-geometries
|
||||
template <typename Geometry>
|
||||
struct create_multipoint
|
||||
{
|
||||
explicit create_multipoint(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (ring const& points) const
|
||||
{
|
||||
mapnik::geometry::multi_point<double> multi_point;
|
||||
multi_point.reserve(points.size());
|
||||
for (auto && pos : points)
|
||||
{
|
||||
multi_point.emplace_back(std::move(pos));
|
||||
}
|
||||
geom_ = std::move(multi_point);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
||||
|
||||
Geometry & geom_;
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct create_multilinestring
|
||||
{
|
||||
explicit create_multilinestring(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (rings const& rngs) const
|
||||
{
|
||||
mapnik::geometry::multi_line_string<double> multi_line;
|
||||
multi_line.reserve(rngs.size());
|
||||
|
||||
for (auto const& ring : rngs)
|
||||
{
|
||||
mapnik::geometry::line_string<double> line;
|
||||
line.reserve(ring.size());
|
||||
for (auto && pt : ring)
|
||||
{
|
||||
line.emplace_back(std::move(pt));
|
||||
}
|
||||
multi_line.emplace_back(std::move(line));
|
||||
}
|
||||
geom_ = std::move(multi_line);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
||||
|
||||
Geometry & geom_;
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct create_multipolygon
|
||||
{
|
||||
explicit create_multipolygon(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator()(rings_array const& rngs_arr) const
|
||||
{
|
||||
mapnik::geometry::multi_polygon<double> multi_poly;
|
||||
multi_poly.reserve(rngs_arr.size());
|
||||
for (auto const& rings : rngs_arr)
|
||||
{
|
||||
mapnik::geometry::polygon<double> poly;
|
||||
std::size_t num_rings = rings.size();
|
||||
if ( num_rings > 1)
|
||||
poly.interior_rings.reserve(num_rings - 1);
|
||||
|
||||
for ( std::size_t i = 0; i < num_rings; ++i)
|
||||
{
|
||||
std::size_t size = rings[i].size();
|
||||
mapnik::geometry::linear_ring<double> ring;
|
||||
ring.reserve(size);
|
||||
for ( auto && pt : rings[i])
|
||||
{
|
||||
ring.emplace_back(std::move(pt));
|
||||
}
|
||||
if (i == 0) poly.set_exterior_ring(std::move(ring));
|
||||
else poly.add_hole(std::move(ring));
|
||||
}
|
||||
multi_poly.emplace_back(std::move(poly));
|
||||
}
|
||||
geom_ = std::move(multi_poly);
|
||||
mapnik::geometry::correct(geom_);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T const&) const {} // no-op - shouldn't get here
|
||||
|
||||
Geometry & geom_;
|
||||
};
|
||||
|
||||
struct create_geometry_impl
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename Geometry>
|
||||
void operator() (Geometry & geom, int type, mapnik::json::positions const& coords) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1 ://Point
|
||||
util::apply_visitor(create_point<Geometry>(geom), coords);
|
||||
break;
|
||||
case 2 ://LineString
|
||||
util::apply_visitor(create_linestring<Geometry>(geom), coords);
|
||||
break;
|
||||
case 3 ://Polygon
|
||||
util::apply_visitor(create_polygon<Geometry>(geom), coords);
|
||||
break;
|
||||
case 4 ://MultiPoint
|
||||
util::apply_visitor(create_multipoint<Geometry>(geom), coords);
|
||||
break;
|
||||
case 5 ://MultiLineString
|
||||
util::apply_visitor(create_multilinestring<Geometry>(geom), coords);
|
||||
break;
|
||||
case 6 ://MultiPolygon
|
||||
util::apply_visitor(create_multipolygon<Geometry>(geom), coords);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_CREATE_GEOMETRY_HPP
|
84
include/mapnik/json/geojson_grammar_x3.hpp
Normal file
84
include/mapnik/json/geojson_grammar_x3.hpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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_GEOJSON_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_JSON_GEOJSON_GRAMMAR_X3_HPP
|
||||
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
#include <mapnik/json/json_grammar_config.hpp>
|
||||
#include <mapnik/json/positions_x3.hpp>
|
||||
#include <mapnik/geometry/geometry_types.hpp>
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
struct json_value;
|
||||
using json_array = std::vector<json_value>;
|
||||
using json_object_element = std::pair<int, json_value>;
|
||||
using json_object = std::vector<json_object_element>;
|
||||
using json_value_base = mapnik::util::variant<value_null,
|
||||
value_bool,
|
||||
value_integer,
|
||||
value_double,
|
||||
std::string,
|
||||
mapnik::geometry::geometry_types,
|
||||
positions,
|
||||
json_array,
|
||||
json_object>;
|
||||
struct json_value : json_value_base
|
||||
{
|
||||
#if __cpp_inheriting_constructors >= 200802
|
||||
|
||||
using json_value_base::json_value_base;
|
||||
|
||||
#else
|
||||
|
||||
json_value() = default;
|
||||
|
||||
template <typename T>
|
||||
json_value(T && val)
|
||||
: json_value_base(std::forward<T>(val)) {}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace grammar {
|
||||
|
||||
using geojson_grammar_type = x3::rule<class geojson_tag, json_value>;
|
||||
using key_value_type = x3::rule<class key_value_tag, json_object_element>;
|
||||
BOOST_SPIRIT_DECLARE(geojson_grammar_type);
|
||||
BOOST_SPIRIT_DECLARE(key_value_type);
|
||||
}
|
||||
|
||||
grammar::geojson_grammar_type const& geojson_grammar();
|
||||
grammar::key_value_type const& key_value_grammar();
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_GEOJSON_GRAMMAR_X3_HPP
|
182
include/mapnik/json/geojson_grammar_x3_def.hpp
Normal file
182
include/mapnik/json/geojson_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,182 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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_GEOJSON_GRAMMAR_X3_DEF_HPP
|
||||
#define MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
#define BIGINT // int64_t support
|
||||
|
||||
#include <mapnik/json/geojson_grammar_x3.hpp>
|
||||
#include <mapnik/json/unicode_string_grammar_x3.hpp>
|
||||
#include <mapnik/json/positions_grammar_x3.hpp>
|
||||
#include <boost/fusion/include/std_pair.hpp>
|
||||
|
||||
namespace mapnik { namespace json { namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
|
||||
auto make_null = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = mapnik::value_null{};
|
||||
};
|
||||
|
||||
auto make_true = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = true;
|
||||
};
|
||||
|
||||
auto make_false = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = false;
|
||||
};
|
||||
|
||||
auto assign = [](auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(_attr(ctx));
|
||||
};
|
||||
|
||||
auto assign_key = [](auto const& ctx)
|
||||
{
|
||||
std::string const& name = _attr(ctx);
|
||||
keys_map & keys = x3::get<keys_tag>(ctx);
|
||||
auto result = keys.insert(std::make_pair(name, keys.size()));
|
||||
std::get<0>(_val(ctx)) = result.first->second;
|
||||
};
|
||||
|
||||
auto assign_value = [](auto const& ctx)
|
||||
{
|
||||
std::get<1>(_val(ctx)) = std::move(_attr(ctx));
|
||||
};
|
||||
|
||||
using x3::lit;
|
||||
using x3::string;
|
||||
using x3::omit;
|
||||
|
||||
struct geometry_type_ : x3::symbols<mapnik::geometry::geometry_types>
|
||||
{
|
||||
geometry_type_()
|
||||
{
|
||||
add
|
||||
("\"Feature\"",mapnik::geometry::geometry_types(0xff)) // this is a temp hack FIXME
|
||||
("\"Point\"", mapnik::geometry::geometry_types::Point)
|
||||
("\"LineString\"", mapnik::geometry::geometry_types::LineString)
|
||||
("\"Polygon\"", mapnik::geometry::geometry_types::Polygon)
|
||||
("\"MultiPoint\"", mapnik::geometry::geometry_types::MultiPoint)
|
||||
("\"MultiLineString\"", mapnik::geometry::geometry_types::MultiLineString )
|
||||
("\"MultiPolygon\"",mapnik::geometry::geometry_types::MultiPolygon)
|
||||
("\"GeometryCollection\"",mapnik::geometry::geometry_types::GeometryCollection)
|
||||
;
|
||||
}
|
||||
} geometry_type_sym;
|
||||
|
||||
// exported rules
|
||||
// start
|
||||
geojson_grammar_type const value("JSON Value");
|
||||
key_value_type const key_value("JSON key/value");
|
||||
// rules
|
||||
x3::rule<class json_object_tag, json_object> object("JSON Object");
|
||||
x3::rule<class json_array_tag, json_array> array("JSON Array");
|
||||
x3::rule<class json_number_tag, json_value> number("JSON Number");
|
||||
//x3::rule<class key_value_tag, json_object_element> key_value("JSON key/value");
|
||||
// GeoJSON
|
||||
x3::rule<class geojson_coordinates_tag, json_object_element> coordinates("GeoJSON Coordinates");
|
||||
x3::rule<class geojson_geometry_type_tag, json_object_element> geometry_type("GeoJSON Geometry Type");
|
||||
x3::rule<class geojson_key_value_type_tag, json_object_element> geojson_key_value("GeoJSON Key/Value Type");
|
||||
auto const json_double = x3::real_parser<value_double, x3::strict_real_policies<value_double>>();
|
||||
auto const json_integer = x3::int_parser<value_integer, 10, 1, -1>();
|
||||
|
||||
// import unicode string rule
|
||||
namespace { auto const& json_string = mapnik::json::unicode_string_grammar(); }
|
||||
// import positions rule
|
||||
namespace { auto const& positions_rule = mapnik::json::positions_grammar(); }
|
||||
|
||||
// GeoJSON types
|
||||
auto const value_def = object | array | json_string | number
|
||||
;
|
||||
|
||||
auto const coordinates_def = string("\"coordinates\"")[assign_key] > lit(':') > (positions_rule[assign_value] | value[assign_value])
|
||||
;
|
||||
|
||||
auto const geometry_type_def = string("\"type\"")[assign_key] > lit(':') > (geometry_type_sym[assign_value] | value[assign_value])
|
||||
;
|
||||
|
||||
auto const key_value_def = json_string[assign_key] > lit(':') > value[assign_value]
|
||||
;
|
||||
|
||||
auto const geojson_key_value_def =
|
||||
geometry_type
|
||||
|
|
||||
coordinates
|
||||
|
|
||||
key_value
|
||||
;
|
||||
|
||||
auto const object_def = lit('{')
|
||||
> -(geojson_key_value % lit(','))
|
||||
> lit('}')
|
||||
;
|
||||
|
||||
auto const array_def = lit('[')
|
||||
> -(value % lit(','))
|
||||
> lit(']')
|
||||
;
|
||||
|
||||
auto const number_def = json_double[assign]
|
||||
| json_integer[assign]
|
||||
| lit("true") [make_true]
|
||||
| lit ("false") [make_false]
|
||||
| lit("null")[make_null]
|
||||
;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
|
||||
BOOST_SPIRIT_DEFINE(
|
||||
value,
|
||||
geometry_type,
|
||||
coordinates,
|
||||
object,
|
||||
key_value,
|
||||
geojson_key_value,
|
||||
array,
|
||||
number
|
||||
);
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
}}}
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
grammar::geojson_grammar_type const& geojson_grammar()
|
||||
{
|
||||
return grammar::value;
|
||||
}
|
||||
|
||||
grammar::key_value_type const& key_value_grammar()
|
||||
{
|
||||
return grammar::key_value;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_GEOJSON_GRAMMAR_X3_DEF_HPP
|
45
include/mapnik/json/json_grammar_config.hpp
Normal file
45
include/mapnik/json/json_grammar_config.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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_GRAMMAR_CONFIG_HPP
|
||||
#define MAPNIK_JSON_GRAMMAR_CONFIG_HPP
|
||||
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct keys_tag;
|
||||
|
||||
namespace grammar {
|
||||
|
||||
using keys_map = std::unordered_map<std::string, int>;
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
using space_type = x3::standard::space_type;
|
||||
using iterator_type = std::string::const_iterator;
|
||||
using context_type = x3::with_context<keys_tag,
|
||||
std::reference_wrapper<keys_map> const,
|
||||
x3::phrase_parse_context<space_type>::type>::type;
|
||||
}}}
|
||||
|
||||
#endif // MAPNIK_JSON_GRAMMAR_CONFIG_HPP
|
50
include/mapnik/json/positions_grammar_x3.hpp
Normal file
50
include/mapnik/json/positions_grammar_x3.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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_POSITIONS_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_JSON_POSITIONS_GRAMMAR_X3_HPP
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/json/positions_x3.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
using positions_grammar_type = x3::rule<class positions_tag, positions>;
|
||||
|
||||
BOOST_SPIRIT_DECLARE(positions_grammar_type);
|
||||
|
||||
}
|
||||
|
||||
grammar::positions_grammar_type const& positions_grammar();
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_POSITIONS_GRAMMAR_X3_HPP
|
67
include/mapnik/json/positions_grammar_x3_def.hpp
Normal file
67
include/mapnik/json/positions_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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_POSITIONS_GRAMMAR_X3_DEF_HPP
|
||||
#define MAPNIK_JSON_POSITIONS_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
#include <mapnik/json/positions_grammar_x3.hpp>
|
||||
#include <mapnik/geometry/fusion_adapted.hpp>
|
||||
|
||||
namespace mapnik { namespace json { namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
using x3::lit;
|
||||
using x3::double_;
|
||||
using x3::no_case;
|
||||
using x3::omit;
|
||||
|
||||
// start rule
|
||||
positions_grammar_type const positions("Positions");
|
||||
// rules
|
||||
x3::rule<class point_class, point> const point("Position");
|
||||
x3::rule<class ring_class, ring> const ring("Ring");
|
||||
x3::rule<class rings_class, rings> const rings("Rings");
|
||||
x3::rule<class rings_array_class, rings_array> const rings_array("RingsArray");
|
||||
|
||||
auto const positions_def = rings_array | rings | ring | point ;
|
||||
auto const point_def = lit('[') > double_ > lit(',') > double_ > omit[*(lit(',') > double_)] > lit(']');
|
||||
auto const ring_def = lit('[') >> (point % lit(',') > lit(']'));
|
||||
auto const rings_def = lit('[') >> (ring % lit(',') > lit(']'));
|
||||
auto const rings_array_def = lit('[') >> (rings % lit(',') > lit(']'));
|
||||
|
||||
BOOST_SPIRIT_DEFINE(
|
||||
positions,
|
||||
point,
|
||||
ring,
|
||||
rings,
|
||||
rings_array
|
||||
);
|
||||
}}}
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
grammar::positions_grammar_type const& positions_grammar()
|
||||
{
|
||||
return grammar::positions;
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_POSITIONS_GRAMMAR_X3_DEF_HPP
|
41
include/mapnik/json/positions_x3.hpp
Normal file
41
include/mapnik/json/positions_x3.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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_POSITIONS_HPP
|
||||
#define MAPNIK_JSON_POSITIONS_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/util/variant.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct empty {};
|
||||
using point = mapnik::geometry::point<double>;
|
||||
using ring = std::vector<point>;
|
||||
using rings = std::vector<ring>;
|
||||
using rings_array = std::vector<rings>;
|
||||
using positions = util::variant<point, ring, rings, rings_array>;
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_POSITIONS_HPP
|
46
include/mapnik/json/unicode_string_grammar_x3.hpp
Normal file
46
include/mapnik/json/unicode_string_grammar_x3.hpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2015 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_UNICODE_STRING_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_HPP
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
namespace mapnik { namespace json { namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
class unicode_string_tag;
|
||||
using unicode_string_grammar_type = x3::rule<unicode_string_tag, std::string>;
|
||||
|
||||
BOOST_SPIRIT_DECLARE(unicode_string_grammar_type);
|
||||
|
||||
}
|
||||
|
||||
grammar::unicode_string_grammar_type const& unicode_string_grammar();
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_HPP
|
129
include/mapnik/json/unicode_string_grammar_x3_def.hpp
Normal file
129
include/mapnik/json/unicode_string_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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_UNICODE_STRING_GRAMMAR_X3_DEF_HPP
|
||||
#define MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
#include <mapnik/json/unicode_string_grammar_x3.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik { namespace json { namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
|
||||
using uchar = std::uint32_t; // a unicode code point
|
||||
|
||||
auto append = [](auto const& ctx)
|
||||
{
|
||||
_val(ctx) += _attr(ctx);
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
void push_utf8_impl(std::string & str, uchar code_point)
|
||||
{
|
||||
using insert_iterator = std::back_insert_iterator<std::string>;
|
||||
insert_iterator iter(str);
|
||||
boost::utf8_output_iterator<insert_iterator> utf8_iter(iter);
|
||||
*utf8_iter++ = code_point;
|
||||
}
|
||||
}
|
||||
|
||||
auto push_utf8 = [](auto const& ctx) { detail::push_utf8_impl(_val(ctx), _attr(ctx));};
|
||||
|
||||
auto push_esc = [] (auto const& ctx)
|
||||
{
|
||||
std::string & utf8 = _val(ctx);
|
||||
char c = _attr(ctx);
|
||||
switch (c)
|
||||
{
|
||||
case ' ': utf8 += ' '; break;
|
||||
case '\t': utf8 += '\t'; break;
|
||||
case '0': utf8 += char(0); break;
|
||||
case 'a': utf8 += 0x7; break;
|
||||
case 'b': utf8 += 0x8; break;
|
||||
case 't': utf8 += 0x9; break;
|
||||
case 'n': utf8 += 0xA; break;
|
||||
case 'v': utf8 += 0xB; break;
|
||||
case 'f': utf8 += 0xC; break;
|
||||
case 'r': utf8 += 0xD; break;
|
||||
case 'e': utf8 += 0x1B; break;
|
||||
case '"': utf8 += '"'; break;
|
||||
case '/': utf8 += '/'; break;
|
||||
case '\\': utf8 += '\\'; break;
|
||||
case '_': detail::push_utf8_impl(utf8, 0xA0); break;
|
||||
case 'N': detail::push_utf8_impl(utf8, 0x85); break;
|
||||
case 'L': detail::push_utf8_impl(utf8, 0x2028); break;
|
||||
case 'P': detail::push_utf8_impl(utf8, 0x2029); break;
|
||||
}
|
||||
};
|
||||
|
||||
using x3::lit;
|
||||
using x3::char_;
|
||||
using x3::hex;
|
||||
using x3::eol;
|
||||
using x3::no_skip;
|
||||
|
||||
x3::uint_parser<uchar, 16, 4, 4> hex4;
|
||||
x3::uint_parser<uchar, 16, 8, 8> hex8;
|
||||
|
||||
// start rule
|
||||
unicode_string_grammar_type const unicode_string("Unicode String");
|
||||
// rules
|
||||
x3::rule<class double_quoted_tag, std::string> const double_quoted("Double-quoted string");
|
||||
x3::rule<class escaped_tag, std::string> const escaped("Escaped Characted");
|
||||
|
||||
auto unicode_string_def = double_quoted
|
||||
;
|
||||
auto const escaped_def = lit('\\') >
|
||||
(lit('x') > hex[push_utf8]
|
||||
|
|
||||
lit('u') > hex4[push_utf8]
|
||||
|
|
||||
lit('U') > hex8[push_utf8]
|
||||
|
|
||||
char_("0abtnvfre\"/\\N_LP \t")[push_esc]
|
||||
|
|
||||
eol) // continue to next line
|
||||
;
|
||||
|
||||
auto const double_quoted_def = lit('"') > no_skip[*(escaped[append] | (~char_('"'))[append])] > lit('"');
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
|
||||
BOOST_SPIRIT_DEFINE(
|
||||
unicode_string,
|
||||
double_quoted,
|
||||
escaped
|
||||
);
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
}
|
||||
grammar::unicode_string_grammar_type const& unicode_string_grammar()
|
||||
{
|
||||
return grammar::unicode_string;
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_DEF_HPP
|
29
src/json/geojson_grammar_x3.cpp
Normal file
29
src/json/geojson_grammar_x3.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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/json/geojson_grammar_x3_def.hpp>
|
||||
#include <mapnik/json/json_grammar_config.hpp>
|
||||
namespace mapnik { namespace json { namespace grammar {
|
||||
|
||||
BOOST_SPIRIT_INSTANTIATE(geojson_grammar_type, iterator_type, context_type);
|
||||
|
||||
}}}
|
28
src/json/positions_grammar_x3.cpp
Normal file
28
src/json/positions_grammar_x3.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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/json/positions_grammar_x3_def.hpp>
|
||||
#include <mapnik/json/json_grammar_config.hpp>
|
||||
|
||||
namespace mapnik { namespace json { namespace grammar {
|
||||
BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, context_type);
|
||||
}}}
|
28
src/json/unicode_string_grammar_x3.cpp
Normal file
28
src/json/unicode_string_grammar_x3.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 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/json/unicode_string_grammar_x3_def.hpp>
|
||||
#include <mapnik/json/json_grammar_config.hpp>
|
||||
|
||||
namespace mapnik { namespace json { namespace grammar {
|
||||
BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, context_type);
|
||||
}}}
|
Loading…
Reference in a new issue