From 053eca1232cf9d0f7689428d029e2e0c2c115794 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 16 Dec 2016 11:21:20 +0100 Subject: [PATCH] JSON - add geometry_grammar_x3 --- include/mapnik/json/geometry_grammar_x3.hpp | 51 ++++++ .../mapnik/json/geometry_grammar_x3_def.hpp | 155 ++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 include/mapnik/json/geometry_grammar_x3.hpp create mode 100644 include/mapnik/json/geometry_grammar_x3_def.hpp diff --git a/include/mapnik/json/geometry_grammar_x3.hpp b/include/mapnik/json/geometry_grammar_x3.hpp new file mode 100644 index 000000000..a630f6b05 --- /dev/null +++ b/include/mapnik/json/geometry_grammar_x3.hpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * 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_GEOMETRY_GRAMMAR_X3_HPP +#define MAPNIK_GEOMETRY_GRAMMAR_X3_HPP + +// mapnik +#include // for geometry_type + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +// mapnik +#include + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using geometry_grammar_type = x3::rule>; + +BOOST_SPIRIT_DECLARE(geometry_grammar_type); + +} + +grammar::geometry_grammar_type const& geometry_grammar(); + +}} + +#endif // MAPNIK_GEOMETRY_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/geometry_grammar_x3_def.hpp b/include/mapnik/json/geometry_grammar_x3_def.hpp new file mode 100644 index 000000000..9ec425e37 --- /dev/null +++ b/include/mapnik/json/geometry_grammar_x3_def.hpp @@ -0,0 +1,155 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +// mapnik +#include +#include +#include +#include +#include +#include +#include +#include +// boost +#include + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; +using x3::lit; +using x3::_pass; +using x3::omit; + +auto create_geometry = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + mapnik::json::create_geometry_impl()(_val(ctx), std::get<0>(attr), std::get<1>(attr)); +}; + +auto assign_element = [] (auto const& ctx) +{ + _val(ctx) = std::move(_attr(ctx)); +}; + +namespace { +template +struct assign_geometry_element_visitor : util::noncopyable +{ + assign_geometry_element_visitor(T & t) + : t_(t) {} + + void operator() (int const& type) + { + std::get<0>(t_) = type; + } + void operator () (::mapnik::json::positions const& p) + { + std::get<1>(t_) = p; + } + + T & t_; +}; + +} + +auto assign_geometry_element = [] (auto const& ctx) +{ + assign_geometry_element_visitor v(_val(ctx)); + mapnik::util::apply_visitor(v, _attr(ctx)); +}; + +auto assign_collection = [] (auto const& ctx) +{ + auto & val = _val(ctx); + std::get<0>(val) = 7; //GeometryCollection + std::get<1>(val) = std::move(_attr(ctx)); +}; + +auto push_geometry = [] (auto const& ctx) +{ + _val(ctx).emplace_back(std::move(_attr(ctx))); +}; + +// start rule +geometry_grammar_type const geometry("Geometry"); +// rules +x3::rule> const geometry_element("Geometry Element"); +x3::rule> const geometry_tuple("Geometry Tuple"); +x3::rule> const geometry_collection("Geometry Collection"); +// import positions rule +namespace { auto const& pos = positions_grammar(); } +// import generic JSON key:value rule +namespace { auto const& json_key_value = generic_json_key_value(); } + +struct geometry_type_ : x3::symbols +{ + geometry_type_() + { + add + ("\"Point\"",1) + ("\"LineString\"",2) + ("\"Polygon\"",3) + ("\"MultiPoint\"",4) + ("\"MultiLineString\"",5) + ("\"MultiPolygon\"",6) + ("\"GeometryCollection\"",7) + ; + } +} geometry_type; + +auto const geometry_def = (lit('{') > (geometry_tuple)[create_geometry] > lit('}')) | lit("null") + ; + +auto const geometry_tuple_def = geometry_element[assign_geometry_element] % lit(',') + ; + +auto const geometry_element_def = + (lit("\"type\"") > lit(":") > geometry_type[assign_element]) + | + (lit("\"coordinates\"") > lit(':') > pos[assign_element]) + | + (lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[assign_collection] > lit(']')) + | + omit[json_key_value] + ; + +auto const geometry_collection_def = geometry[push_geometry] % lit(',') + ; + +BOOST_SPIRIT_DEFINE( + geometry, + geometry_element, + geometry_tuple, + geometry_collection + ); + +}}} + +namespace mapnik { namespace json { +grammar::geometry_grammar_type const& geometry_grammar() +{ + return grammar::geometry; +} +}}