From b7dda95d843899fe7ba4c443b4589edf7b192ece Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 10 Dec 2013 15:50:03 -0500 Subject: [PATCH] move symbolizer to json into core symbolizer json grammar (needs more work) --- bindings/python/mapnik_symbolizer.cpp | 26 +-- include/mapnik/json/symbolizer_grammar.hpp | 184 +++++++++++++++++++++ include/mapnik/symbolizer_utils.hpp | 25 +++ 3 files changed, 210 insertions(+), 25 deletions(-) create mode 100644 include/mapnik/json/symbolizer_grammar.hpp diff --git a/bindings/python/mapnik_symbolizer.cpp b/bindings/python/mapnik_symbolizer.cpp index 188cd3e8e..b16930471 100644 --- a/bindings/python/mapnik_symbolizer.cpp +++ b/bindings/python/mapnik_symbolizer.cpp @@ -124,33 +124,9 @@ boost::python::object __getitem__(mapnik::symbolizer_base const& sym, std::strin return boost::python::object(); } -struct symbolizer_to_json : public boost::static_visitor -{ - typedef std::string result_type; - - template - auto operator() (T const& sym) const -> result_type - { - std::stringstream ss; - ss << "{\"type\":\"" << mapnik::symbolizer_traits::name() << "\","; - ss << "\"properties\":{"; - bool first = true; - for (auto const& prop : sym.properties) - { - auto const& meta = mapnik::get_meta(prop.first); - if (first) first = false; - else ss << ","; - ss << "\"" << std::get<0>(meta) << "\":"; - ss << boost::apply_visitor(mapnik::symbolizer_property_value_string(meta),prop.second); - } - ss << "}}"; - return ss.str(); - } -}; - std::string __str__(mapnik::symbolizer const& sym) { - return boost::apply_visitor(symbolizer_to_json(), sym); + return boost::apply_visitor(mapnik::symbolizer_to_json(), sym); } std::string get_symbolizer_type(symbolizer const& sym) diff --git a/include/mapnik/json/symbolizer_grammar.hpp b/include/mapnik/json/symbolizer_grammar.hpp new file mode 100644 index 000000000..a2e36cbf4 --- /dev/null +++ b/include/mapnik/json/symbolizer_grammar.hpp @@ -0,0 +1,184 @@ +/***************************************************************************** + * + * 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_SYMBOLIZER_GRAMMAR_HPP +#define MAPNIK_SYMBOLIZER_GRAMMAR_HPP + +// boost +#define BOOST_SPIRIT_USE_PHOENIX_V3 1 +#include +#include + +// mapnik +#include +#include + +namespace mapnik { namespace json { + +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 +struct put_property_visitor : boost::static_visitor<> +{ + typedef T value_type; + + put_property_visitor(mapnik::keys key, value_type const& val) + : key_(key), val_(val) {} + + template + void operator() (Symbolizer & sym) const + { + std::cerr << std::get<0>(get_meta(key_)) << ":" << val_ << std::endl; + // put(sym, key_, val_); + } + + keys key_; + value_type const& val_; +}; + +struct put_property +{ + typedef void result_type; + //explicit put_property(mapnik::transcoder const& tr) + // : tr_(tr) {} + template + result_type operator() (T0 & sym, T1 const& name, T2 const& val) const + { + try + { + boost::apply_visitor(put_property_visitor(get_key(name),val), sym); + } + catch (std::runtime_error const& err) + { + std::cerr << err.what() << std::endl; + } + } +// mapnik::transcoder const& tr_; +}; + +template +struct symbolizer_grammar : qi::grammar +{ + symbolizer_grammar(generic_json & json) + : symbolizer_grammar::base_type(sym, "symbolizer"), + json_(json) + { + using qi::lit; + using qi::double_; + using qi::int_; + using qi::no_skip; + using qi::omit; + using qi::_val; + using qi::_a; + using qi::_r1; + 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 + json_.value = json_.object | json_.array | json_.string_ + | json_.number + ; + + json_.pairs = json_.key_value % lit(',') + ; + + json_.key_value = (json_.string_ >> lit(':') >> json_.value) + ; + + json_.object = lit('{') + >> *json_.pairs + >> lit('}') + ; + + json_.array = lit('[') + >> json_.value >> *(lit(',') >> json_.value) + >> lit(']') + ; + + json_.number %= json_.strict_double + | json_.int__ + | lit("true") [_val = true] + | lit ("false") [_val = false] + | lit("null")[_val = construct()] + ; + json_.unesc_char.add + ("\\\"", '\"') // quotation mark + ("\\\\", '\\') // reverse solidus + ("\\/", '/') // solidus + ("\\b", '\b') // backspace + ("\\f", '\f') // formfeed + ("\\n", '\n') // newline + ("\\r", '\r') // carrige return + ("\\t", '\t') // tab + ; + + json_.string_ %= lit('"') >> no_skip[*(json_.unesc_char | "\\u" >> json_.hex4 | (char_ - lit('"')))] >> lit('"') + ; + + sym = lit('{') + >> lit("\"type\"") >> lit(':') + >> (lit("\"PointSymbolizer\"")[_val = construct()] + | + lit("\"LineSymbolizer\"")[_val = construct()] + | + lit("\"PolygonSymbolizer\"")[_val = construct()] + ) + >> lit(',') + >> lit("\"properties\"") >> lit(':') + >> ((lit('{') >> *property(_val) >> lit('}')) | lit("null")) + >> lit('}') + ; + + property = (json_.string_ [_a = _1] >> lit(':') >> property_value [put_property_(_r1,_a,_1)]) % lit(',') + ; + + property_value %= json.number | json.string_ ; + + + } + + // generic JSON + generic_json & json_; + // symbolizer + qi::rule sym; + qi::rule, void(mapnik::symbolizer&),space_type> property; + qi::rule, space_type> property_value; + + phoenix::function put_property_; + // error + //boost::phoenix::function where_message_; +}; + + +}} + +#endif // MAPNIK_FEATURE_GRAMMAR_HPP diff --git a/include/mapnik/symbolizer_utils.hpp b/include/mapnik/symbolizer_utils.hpp index c0108751a..4ec6c69e6 100644 --- a/include/mapnik/symbolizer_utils.hpp +++ b/include/mapnik/symbolizer_utils.hpp @@ -215,6 +215,31 @@ private: Meta const& meta_; }; +struct symbolizer_to_json : public boost::static_visitor +{ + typedef std::string result_type; + + template + auto operator() (T const& sym) const -> result_type + { + std::stringstream ss; + ss << "{\"type\":\"" << mapnik::symbolizer_traits::name() << "\","; + ss << "\"properties\":{"; + bool first = true; + for (auto const& prop : sym.properties) + { + auto const& meta = mapnik::get_meta(prop.first); + if (first) first = false; + else ss << ","; + ss << "\"" << std::get<0>(meta) << "\":"; + ss << boost::apply_visitor(symbolizer_property_value_string(meta),prop.second); + } + ss << "}}"; + return ss.str(); + } }; + +} + #endif // MAPNIK_SYMBOLIZER_UTILS_HPP