Merge branch 'develop-master'
This commit is contained in:
commit
9887270b9e
299 changed files with 6103 additions and 4153 deletions
1
.gitmodules
vendored
1
.gitmodules
vendored
|
@ -9,3 +9,4 @@
|
|||
[submodule "deps/mapbox/variant"]
|
||||
path = deps/mapbox/variant
|
||||
url = https://github.com/mapbox/variant.git
|
||||
branch = master
|
9
Makefile
9
Makefile
|
@ -1,4 +1,3 @@
|
|||
|
||||
OS := $(shell uname -s)
|
||||
|
||||
PYTHON = python
|
||||
|
@ -36,10 +35,10 @@ src/json/libmapnik-json.a:
|
|||
src/renderer_common/render_thunk_extractor.os \
|
||||
src/json/libmapnik-json.a \
|
||||
src/wkt/libmapnik-wkt.a \
|
||||
src/css_color_grammar.os \
|
||||
src/expression_grammar.os \
|
||||
src/transform_expression_grammar.os \
|
||||
src/image_filter_grammar.os \
|
||||
src/css_color_grammar_x3.os \
|
||||
src/expression_grammar_x3.os \
|
||||
src/transform_expression_grammar_x3.os \
|
||||
src/image_filter_grammar_x3.os \
|
||||
src/marker_helpers.os \
|
||||
src/svg/svg_transform_parser.os \
|
||||
src/agg/process_line_symbolizer.os \
|
||||
|
|
|
@ -41,7 +41,7 @@ ICU_LIBS_DEFAULT='/usr/'
|
|||
|
||||
DEFAULT_CC = "cc"
|
||||
DEFAULT_CXX = "c++"
|
||||
DEFAULT_CXX11_CXXFLAGS = " -std=c++11"
|
||||
DEFAULT_CXX11_CXXFLAGS = " -std=c++14"
|
||||
DEFAULT_CXX11_LINKFLAGS = ""
|
||||
if sys.platform == 'darwin':
|
||||
# homebrew default
|
||||
|
@ -1786,8 +1786,7 @@ if not preconfigured:
|
|||
common_cxx_flags = '-fvisibility=hidden -fvisibility-inlines-hidden -Wall %s %s -ftemplate-depth-300 -Wsign-compare -Wshadow ' % (env['WARNING_CXXFLAGS'], pthread)
|
||||
|
||||
if 'clang++' in env['CXX']:
|
||||
common_cxx_flags += ' -Wno-unsequenced -Wtautological-compare -Wheader-hygiene '
|
||||
|
||||
common_cxx_flags += ' -Wno-unsequenced -Wtautological-compare -Wheader-hygiene -Wc++14-extensions '
|
||||
if env['DEBUG']:
|
||||
env.Append(CXXFLAGS = common_cxx_flags + '-O0')
|
||||
else:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/safe_cast.hpp>
|
||||
#include "../test/cleanup.hpp"
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ run test_getline 30 10000000
|
|||
#run test_polygon_clipping 10 1000
|
||||
#run test_polygon_clipping_rendering 10 100
|
||||
run test_proj_transform1 10 100
|
||||
run test_expression_parse 10 1000
|
||||
run test_expression_parse 10 10000
|
||||
run test_face_ptr_creation 10 1000
|
||||
run test_font_registration 10 100
|
||||
run test_offset_converter 10 1000
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "bench_framework.hpp"
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/attribute.hpp>
|
||||
#include <mapnik/expression.hpp>
|
||||
#include <mapnik/expression_string.hpp>
|
||||
#include <mapnik/expression_grammar.hpp>
|
||||
|
||||
class test : public benchmark::test_case
|
||||
{
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/vertex_adapters.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_adapters.hpp>
|
||||
#include <mapnik/geometry_envelope.hpp>
|
||||
#include <mapnik/geometry_correct.hpp>
|
||||
#include <mapnik/geometry_is_empty.hpp>
|
||||
#include <mapnik/geometry/boost_adapters.hpp>
|
||||
#include <mapnik/geometry/envelope.hpp>
|
||||
#include <mapnik/geometry/correct.hpp>
|
||||
#include <mapnik/geometry/is_empty.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
// boost geometry
|
||||
|
|
10
deps/agg/include/agg_vpgen_clip_polygon.h
vendored
10
deps/agg/include/agg_vpgen_clip_polygon.h
vendored
|
@ -43,12 +43,12 @@ namespace agg
|
|||
{
|
||||
}
|
||||
|
||||
void clip_box(double x1, double y1, double x2, double y2)
|
||||
void clip_box(double _x1, double _y1, double _x2, double _y2)
|
||||
{
|
||||
m_clip_box.x1 = x1;
|
||||
m_clip_box.y1 = y1;
|
||||
m_clip_box.x2 = x2;
|
||||
m_clip_box.y2 = y2;
|
||||
m_clip_box.x1 = _x1;
|
||||
m_clip_box.y1 = _y1;
|
||||
m_clip_box.x2 = _x2;
|
||||
m_clip_box.y2 = _y2;
|
||||
m_clip_box.normalize();
|
||||
}
|
||||
|
||||
|
|
10
deps/agg/include/agg_vpgen_clip_polyline.h
vendored
10
deps/agg/include/agg_vpgen_clip_polyline.h
vendored
|
@ -41,12 +41,12 @@ namespace agg
|
|||
{
|
||||
}
|
||||
|
||||
void clip_box(double x1, double y1, double x2, double y2)
|
||||
void clip_box(double _x1, double _y1, double _x2, double _y2)
|
||||
{
|
||||
m_clip_box.x1 = x1;
|
||||
m_clip_box.y1 = y1;
|
||||
m_clip_box.x2 = x2;
|
||||
m_clip_box.y2 = y2;
|
||||
m_clip_box.x1 = _x1;
|
||||
m_clip_box.y1 = _y1;
|
||||
m_clip_box.x2 = _x2;
|
||||
m_clip_box.y2 = _y2;
|
||||
m_clip_box.normalize();
|
||||
}
|
||||
|
||||
|
|
2
deps/mapbox/variant
vendored
2
deps/mapbox/variant
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 9a115c5eb3c09509c70a57b25b283b6e1cbba919
|
||||
Subproject commit 02bd1ac4c07e6db9fe0f01267853e43b41637b74
|
|
@ -38,7 +38,9 @@ subdirs = [
|
|||
'text',
|
||||
'text/placements',
|
||||
'text/formatting',
|
||||
'markers_placements'
|
||||
'markers_placements',
|
||||
'geometry',
|
||||
'value'
|
||||
]
|
||||
|
||||
if env['SVG_RENDERER']:
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_ATTRIBUTE_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/util/geometry_to_ds_type.hpp>
|
||||
// stl
|
||||
|
|
|
@ -51,11 +51,11 @@ template <typename T> class MAPNIK_DECL box2d
|
|||
public:
|
||||
using value_type = T;
|
||||
using box2d_type = box2d<value_type>;
|
||||
private:
|
||||
T minx_;
|
||||
T miny_;
|
||||
T maxx_;
|
||||
T maxy_;
|
||||
private:
|
||||
friend inline void swap(box2d_type & lhs, box2d_type & rhs)
|
||||
{
|
||||
using std::swap;
|
||||
|
|
|
@ -33,24 +33,35 @@
|
|||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/fusion/include/adapt_adt.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/support_adapt_adt_attributes.hpp>
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// agg
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
BOOST_FUSION_ADAPT_TPL_ADT(
|
||||
BOOST_FUSION_ADAPT_TPL_STRUCT(
|
||||
(T),
|
||||
(mapnik::box2d)(T),
|
||||
(T, T, obj.minx(), obj.set_minx(mapnik::safe_cast<T>(val)))
|
||||
(T, T, obj.miny(), obj.set_miny(mapnik::safe_cast<T>(val)))
|
||||
(T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast<T>(val)))
|
||||
(T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast<T>(val))))
|
||||
(T, minx_),
|
||||
(T, miny_),
|
||||
(T, maxx_),
|
||||
(T, maxy_))
|
||||
|
||||
namespace mapnik
|
||||
namespace mapnik { namespace detail { namespace {
|
||||
|
||||
template <typename T>
|
||||
struct assign
|
||||
{
|
||||
template <typename Context>
|
||||
void operator() (Context & ctx) const
|
||||
{
|
||||
_val(ctx) = safe_cast<T>(_attr(ctx));
|
||||
}
|
||||
};
|
||||
} // anonymous
|
||||
} // detail
|
||||
|
||||
template <typename T>
|
||||
box2d<T>::box2d()
|
||||
:minx_( std::numeric_limits<T>::max()),
|
||||
|
@ -61,13 +72,13 @@ box2d<T>::box2d()
|
|||
template <typename T>
|
||||
box2d<T>::box2d(T minx,T miny,T maxx,T maxy)
|
||||
{
|
||||
init(minx,miny,maxx,maxy);
|
||||
init(minx, miny, maxx, maxy);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
box2d<T>::box2d(coord<T,2> const& c0, coord<T,2> const& c1)
|
||||
{
|
||||
init(c0.x,c0.y,c1.x,c1.y);
|
||||
init(c0.x, c0.y, c1.x, c1.y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -350,12 +361,15 @@ void box2d<T>::pad(T padding)
|
|||
template <typename T>
|
||||
bool box2d<T>::from_string(std::string const& str)
|
||||
{
|
||||
boost::spirit::qi::lit_type lit;
|
||||
boost::spirit::qi::double_type double_;
|
||||
boost::spirit::ascii::space_type space;
|
||||
bool r = boost::spirit::qi::phrase_parse(str.begin(),
|
||||
using boost::spirit::x3::lit;
|
||||
boost::spirit::x3::double_type double_;
|
||||
boost::spirit::x3::ascii::space_type space;
|
||||
bool r = boost::spirit::x3::phrase_parse(str.begin(),
|
||||
str.end(),
|
||||
double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_,
|
||||
double_[detail::assign<T>()] >> -lit(',') >>
|
||||
double_[detail::assign<T>()] >> -lit(',') >>
|
||||
double_[detail::assign<T>()] >> -lit(',') >>
|
||||
double_[detail::assign<T>()],
|
||||
space,
|
||||
*this);
|
||||
return r;
|
||||
|
|
|
@ -38,16 +38,15 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
class MAPNIK_DECL color
|
||||
: boost::equality_comparable<color>
|
||||
class MAPNIK_DECL color : boost::equality_comparable<color>
|
||||
{
|
||||
private:
|
||||
public:
|
||||
std::uint8_t red_;
|
||||
std::uint8_t green_;
|
||||
std::uint8_t blue_;
|
||||
std::uint8_t alpha_;
|
||||
bool premultiplied_;
|
||||
public:
|
||||
|
||||
// default ctor
|
||||
color()
|
||||
: red_(0xff),
|
||||
|
|
|
@ -181,6 +181,7 @@ private:
|
|||
};
|
||||
|
||||
using coord2d = coord<double,2>;
|
||||
using coord2f = coord<float,2>;
|
||||
using coord2i = coord<int,2>;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_CSS_COLOR_GRAMMAR_HPP
|
||||
#define MAPNIK_CSS_COLOR_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/util/hsl.hpp>
|
||||
#include <mapnik/safe_cast.hpp>
|
||||
|
||||
// boost
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace ascii = boost::spirit::ascii;
|
||||
|
||||
using ascii_space_type = boost::spirit::ascii::space_type;
|
||||
|
||||
template <typename Iterator>
|
||||
struct css_color_grammar : qi::grammar<Iterator, color(), ascii_space_type>
|
||||
{
|
||||
// ctor
|
||||
css_color_grammar();
|
||||
// rules
|
||||
qi::uint_parser< unsigned, 16, 2, 2 > hex2 ;
|
||||
qi::uint_parser< unsigned, 16, 1, 1 > hex1 ;
|
||||
qi::uint_parser< unsigned, 10, 1, 3 > dec3 ;
|
||||
qi::rule<Iterator, color(), ascii_space_type> rgba_color;
|
||||
qi::rule<Iterator, color(), ascii_space_type> rgba_percent_color;
|
||||
qi::rule<Iterator, qi::locals<double,double,double>,color(), ascii_space_type> hsl_percent_color;
|
||||
qi::rule<Iterator, color(), ascii_space_type> hex_color;
|
||||
qi::rule<Iterator, color(), ascii_space_type> hex_color_small;
|
||||
qi::rule<Iterator, color(), ascii_space_type> css_color;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_CSS_COLOR_GRAMMAR_HPP
|
55
include/mapnik/css_color_grammar_x3.hpp
Normal file
55
include/mapnik/css_color_grammar_x3.hpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_CSS_COLOR_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP
|
||||
|
||||
#include <mapnik/color.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
|
||||
namespace css_color_grammar
|
||||
{
|
||||
|
||||
struct css_color_class;
|
||||
using css_color_grammar_type = x3::rule<css_color_class, mapnik::color>;
|
||||
|
||||
BOOST_SPIRIT_DECLARE(css_color_grammar_type);
|
||||
|
||||
}}
|
||||
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
css_color_grammar::css_color_grammar_type const& color_grammar();
|
||||
}
|
||||
|
||||
|
||||
#endif // MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2015 Artem Pavlenko
|
||||
* 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
|
||||
|
@ -20,84 +20,49 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// NOTE: This is an implementation header file and is only meant to be included
|
||||
// from implementation files. It therefore doesn't have an include guard.
|
||||
// mapnik
|
||||
#include <mapnik/css_color_grammar.hpp>
|
||||
// boost
|
||||
// REF: http://www.w3.org/TR/css3-color/
|
||||
|
||||
#ifndef MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP
|
||||
#define MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
#include <mapnik/css_color_grammar_x3.hpp>
|
||||
#include <mapnik/util/hsl.hpp>
|
||||
#include <mapnik/safe_cast.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <boost/fusion/include/adapt_adt.hpp>
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||
#include <boost/spirit/include/phoenix_fusion.hpp>
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <boost/fusion/adapted/struct.hpp>
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
BOOST_FUSION_ADAPT_ADT(
|
||||
BOOST_FUSION_ADAPT_STRUCT (
|
||||
mapnik::color,
|
||||
(unsigned, unsigned, obj.red(), obj.set_red(mapnik::safe_cast<uint8_t>(val)))
|
||||
(unsigned, unsigned, obj.green(), obj.set_green(mapnik::safe_cast<uint8_t>(val)))
|
||||
(unsigned, unsigned, obj.blue(), obj.set_blue(mapnik::safe_cast<uint8_t>(val)))
|
||||
(unsigned, unsigned, obj.alpha(), obj.set_alpha(mapnik::safe_cast<uint8_t>(val)))
|
||||
(std::uint8_t, red_)
|
||||
(std::uint8_t, green_)
|
||||
(std::uint8_t, blue_)
|
||||
(std::uint8_t, alpha_)
|
||||
)
|
||||
|
||||
namespace mapnik
|
||||
namespace mapnik {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
|
||||
namespace css_color_grammar {
|
||||
|
||||
using x3::lit;
|
||||
using x3::uint_parser;
|
||||
using x3::hex;
|
||||
using x3::symbols;
|
||||
using x3::omit;
|
||||
using x3::attr;
|
||||
using x3::double_;
|
||||
using x3::no_case;
|
||||
using x3::no_skip;
|
||||
|
||||
struct named_colors_ : x3::symbols<color>
|
||||
{
|
||||
namespace phoenix = boost::phoenix;
|
||||
|
||||
struct percent_conv_impl
|
||||
{
|
||||
using result_type = unsigned;
|
||||
unsigned operator() (double val) const
|
||||
{
|
||||
return safe_cast<uint8_t>(std::lround((255.0 * val)/100.0));
|
||||
}
|
||||
};
|
||||
|
||||
struct alpha_conv_impl
|
||||
{
|
||||
using result_type = unsigned;
|
||||
unsigned operator() (double val) const
|
||||
{
|
||||
return safe_cast<uint8_t>(std::lround((255.0 * val)));
|
||||
}
|
||||
};
|
||||
|
||||
struct hsl_conv_impl
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename T0,typename T1, typename T2, typename T3>
|
||||
void operator() (T0 & c, T1 h, T2 s, T3 l) const
|
||||
{
|
||||
double m1,m2;
|
||||
// normalize values
|
||||
h /= 360.0;
|
||||
s /= 100.0;
|
||||
l /= 100.0;
|
||||
|
||||
if (l <= 0.5)
|
||||
{
|
||||
m2 = l * (s + 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m2 = l + s - l*s;
|
||||
}
|
||||
m1 = l * 2 - m2;
|
||||
|
||||
double r = hue_to_rgb(m1, m2, h + 1.0/3.0);
|
||||
double g = hue_to_rgb(m1, m2, h);
|
||||
double b = hue_to_rgb(m1, m2, h - 1.0/3.0);
|
||||
|
||||
c.set_red(safe_cast<uint8_t>(std::lround(255.0 * r)));
|
||||
c.set_green(safe_cast<uint8_t>(std::lround(255.0 * g)));
|
||||
c.set_blue(safe_cast<uint8_t>(std::lround(255.0 * b)));
|
||||
}
|
||||
};
|
||||
|
||||
struct named_colors : qi::symbols<char,color>
|
||||
{
|
||||
named_colors()
|
||||
named_colors_()
|
||||
{
|
||||
add
|
||||
("aliceblue", color(240, 248, 255))
|
||||
|
@ -249,77 +214,241 @@ struct named_colors : qi::symbols<char,color>
|
|||
("transparent", color(0, 0, 0, 0))
|
||||
;
|
||||
}
|
||||
} named_colors;
|
||||
|
||||
x3::uint_parser<std::uint8_t, 16, 2, 2> hex2;
|
||||
x3::uint_parser<std::uint8_t, 16, 1, 1> hex1;
|
||||
x3::uint_parser<std::uint8_t, 10, 1, 3> dec3;
|
||||
|
||||
// starting rule
|
||||
css_color_grammar_type const css_color("css_color");
|
||||
// rules
|
||||
x3::rule<class hex2_color, color> const hex2_color("hex2_color");
|
||||
x3::rule<class hex1_color, color> const hex1_color("hex1_color");
|
||||
x3::rule<class rgb_color, color> const rgb_color("rgb_color");
|
||||
x3::rule<class rgba_color, color> const rgba_color("rgba_color");
|
||||
x3::rule<class rgb_color_percent, color> const rgb_color_percent("rgb_color_percent");
|
||||
x3::rule<class rgba_color_percent, color> const rgba_color_percent("rgba_color_percent");
|
||||
|
||||
struct clip_opacity
|
||||
{
|
||||
static double call(double val)
|
||||
{
|
||||
if (val > 1.0) return 1.0;
|
||||
if (val < 0.0) return 0.0;
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
css_color_grammar<Iterator>::css_color_grammar()
|
||||
: css_color_grammar::base_type(css_color)
|
||||
|
||||
struct percent_converter
|
||||
{
|
||||
qi::lit_type lit;
|
||||
qi::_val_type _val;
|
||||
qi::double_type double_;
|
||||
qi::_1_type _1;
|
||||
qi::_a_type _a;
|
||||
qi::_b_type _b;
|
||||
qi::_c_type _c;
|
||||
qi::lexeme_type lexeme;
|
||||
ascii::no_case_type no_case;
|
||||
using phoenix::at_c;
|
||||
// symbols
|
||||
named_colors named;
|
||||
// functions
|
||||
phoenix::function<percent_conv_impl> percent_converter;
|
||||
phoenix::function<alpha_conv_impl> alpha_converter;
|
||||
phoenix::function<hsl_conv_impl> hsl_converter;
|
||||
static std::uint8_t call(double val)
|
||||
{
|
||||
return safe_cast<std::uint8_t>(std::lround((255.0 * val)/100.0));
|
||||
}
|
||||
};
|
||||
|
||||
css_color %= rgba_color
|
||||
| rgba_percent_color
|
||||
| hsl_percent_color
|
||||
| hex_color
|
||||
| hex_color_small
|
||||
| no_case[named];
|
||||
auto dec_red = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).red_ = _attr(ctx);
|
||||
};
|
||||
|
||||
hex_color = lexeme[ lit('#')
|
||||
>> hex2 [ at_c<0>(_val) = _1 ]
|
||||
>> hex2 [ at_c<1>(_val) = _1 ]
|
||||
>> hex2 [ at_c<2>(_val) = _1 ]
|
||||
>>-hex2 [ at_c<3>(_val) = _1 ] ]
|
||||
;
|
||||
auto dec_green = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).green_ = _attr(ctx);
|
||||
};
|
||||
|
||||
hex_color_small = lexeme[ lit('#')
|
||||
>> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ]
|
||||
>> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ]
|
||||
>> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ]
|
||||
>>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ] ]
|
||||
;
|
||||
auto dec_blue = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).blue_ = _attr(ctx);
|
||||
};
|
||||
|
||||
rgba_color = lit("rgb") >> -lit('a')
|
||||
>> lit('(')
|
||||
>> dec3 [at_c<0>(_val) = _1] >> ','
|
||||
>> dec3 [at_c<1>(_val) = _1] >> ','
|
||||
>> dec3 [at_c<2>(_val) = _1]
|
||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)])
|
||||
>> lit(')')
|
||||
;
|
||||
auto opacity = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).alpha_ = uint8_t((255.0 * clip_opacity::call(_attr(ctx))) + 0.5);
|
||||
};
|
||||
|
||||
rgba_percent_color = lit("rgb") >> -lit('a')
|
||||
>> lit('(')
|
||||
>> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ','
|
||||
>> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ','
|
||||
>> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%'
|
||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)])
|
||||
>> lit(')')
|
||||
;
|
||||
auto percent_red = [] (auto & ctx)
|
||||
{
|
||||
_val(ctx).red_ = percent_converter::call(_attr(ctx));
|
||||
};
|
||||
|
||||
hsl_percent_color = lit("hsl") >> -lit('a')
|
||||
>> lit('(')
|
||||
>> double_ [ _a = _1] >> ',' // hue 0..360
|
||||
>> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100%
|
||||
>> double_ [ _c = _1] >> '%' // lightness 0..100%
|
||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1
|
||||
>> lit (')') [ hsl_converter(_val,_a,_b,_c)]
|
||||
;
|
||||
auto percent_green = [] (auto & ctx)
|
||||
{
|
||||
_val(ctx).green_ = percent_converter::call(_attr(ctx));
|
||||
};
|
||||
|
||||
auto percent_blue = [] (auto & ctx)
|
||||
{
|
||||
_val(ctx).blue_ = percent_converter::call(_attr(ctx));
|
||||
};
|
||||
|
||||
auto hex1_red = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).red_ = _attr(ctx) | _attr(ctx) << 4;
|
||||
};
|
||||
|
||||
auto hex1_green = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).green_ = _attr(ctx) | _attr(ctx) << 4;
|
||||
};
|
||||
|
||||
auto hex1_blue = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).blue_ = _attr(ctx) | _attr(ctx) << 4;
|
||||
};
|
||||
|
||||
auto hex1_opacity = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).alpha_ = _attr(ctx) | _attr(ctx) << 4;
|
||||
};
|
||||
|
||||
auto hex2_red = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).red_ = _attr(ctx);
|
||||
};
|
||||
|
||||
auto hex2_green = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).green_ = _attr(ctx);
|
||||
};
|
||||
|
||||
auto hex2_blue = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).blue_ = _attr(ctx);
|
||||
};
|
||||
|
||||
auto hex2_opacity = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).alpha_ = _attr(ctx);
|
||||
};
|
||||
|
||||
auto hsl_to_rgba = [] (auto& ctx)
|
||||
{
|
||||
double h = std::get<0>(_attr(ctx));
|
||||
double s = std::get<1>(_attr(ctx));
|
||||
double l = std::get<2>(_attr(ctx));
|
||||
double m1;
|
||||
double m2;
|
||||
// normalise values
|
||||
h /= 360.0;
|
||||
s /= 100.0;
|
||||
l /= 100.0;
|
||||
if (l <= 0.5)
|
||||
{
|
||||
m2 = l * (s + 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m2 = l + s - l*s;
|
||||
}
|
||||
m1 = l * 2 - m2;
|
||||
|
||||
double r = hue_to_rgb(m1, m2, h + 1.0/3.0);
|
||||
double g = hue_to_rgb(m1, m2, h);
|
||||
double b = hue_to_rgb(m1, m2, h - 1.0/3.0);
|
||||
uint8_t alpha = uint8_t((255.0 * clip_opacity::call(std::get<3>(_attr(ctx)))) + 0.5);
|
||||
_val(ctx) = color(safe_cast<uint8_t>(std::lround(255.0 * r)),
|
||||
safe_cast<uint8_t>(std::lround(255.0 * g)),
|
||||
safe_cast<uint8_t>(std::lround(255.0 * b)),
|
||||
alpha);
|
||||
};
|
||||
|
||||
auto const hex2_color_def = no_skip[lit('#')
|
||||
>> hex2[hex2_red]
|
||||
>> hex2[hex2_green]
|
||||
>> hex2[hex2_blue]
|
||||
>> (hex2[hex2_opacity] | attr(255)[hex2_opacity])];
|
||||
|
||||
auto const hex1_color_def = no_skip[lit('#')
|
||||
>> hex1[hex1_red]
|
||||
>> hex1[hex1_green]
|
||||
>> hex1[hex1_blue]
|
||||
>> (hex1[hex1_opacity] | attr(15)[hex1_opacity])];
|
||||
|
||||
auto const rgb_color_def = lit("rgb")
|
||||
>> lit('(') >> dec3[dec_red]
|
||||
>> lit(',') >> dec3[dec_green]
|
||||
>> lit(',') >> dec3[dec_blue]
|
||||
>> attr(255) >> lit(')');
|
||||
|
||||
auto const rgb_color_percent_def = lit("rgb")
|
||||
>> lit('(') >> dec3[percent_red] >> lit('%')
|
||||
>> lit(',') >> dec3[percent_green] >> lit('%')
|
||||
>> lit(',') >> dec3[percent_blue] >> lit('%')
|
||||
>> attr(255) >> lit(')');
|
||||
|
||||
auto const rgba_color_def = lit("rgba")
|
||||
>> lit('(') >> dec3[dec_red]
|
||||
>> lit(',') >> dec3[dec_green]
|
||||
>> lit(',') >> dec3[dec_blue]
|
||||
>> lit(',') >> double_[opacity] >> lit(')');
|
||||
|
||||
auto const rgba_color_percent_def = lit("rgba")
|
||||
>> lit('(') >> dec3[percent_red] >> lit('%')
|
||||
>> lit(',') >> dec3[percent_green] >> lit('%')
|
||||
>> lit(',') >> dec3[percent_blue] >> lit('%')
|
||||
>> lit(',') >> double_[opacity] >> lit(')');
|
||||
|
||||
auto const hsl_values = x3::rule<class hsl_values, std::tuple<std::uint8_t,std::uint8_t,std::uint8_t, double >> {} =
|
||||
lit("hsl")
|
||||
>> lit('(') >> dec3
|
||||
>> lit(',') >> dec3 >> lit('%')
|
||||
>> lit(',') >> dec3 >> lit('%')
|
||||
>> attr(1.0) >> lit(')')
|
||||
;
|
||||
|
||||
auto const hsla_values = x3::rule<class hsla_values, std::tuple<std::uint8_t,std::uint8_t,std::uint8_t, double >> {} =
|
||||
lit("hsla")
|
||||
>> lit('(') >> dec3
|
||||
>> lit(',') >> dec3 >> lit('%')
|
||||
>> lit(',') >> dec3 >> lit('%')
|
||||
>> lit(',') >> double_ >> lit(')')
|
||||
;
|
||||
|
||||
auto const hsl_color = x3::rule<class hsl_color, color> {} = hsl_values[hsl_to_rgba];
|
||||
auto const hsla_color = x3::rule<class hsla_color, color> {} = hsla_values[hsl_to_rgba];
|
||||
|
||||
auto const css_color_def =
|
||||
no_case[named_colors]
|
||||
|
|
||||
hex2_color
|
||||
|
|
||||
hex1_color
|
||||
|
|
||||
rgb_color
|
||||
|
|
||||
rgba_color
|
||||
|
|
||||
rgb_color_percent
|
||||
|
|
||||
rgba_color_percent
|
||||
|
|
||||
hsl_color
|
||||
|
|
||||
hsla_color
|
||||
;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
BOOST_SPIRIT_DEFINE(
|
||||
css_color,
|
||||
hex2_color,
|
||||
hex1_color,
|
||||
rgb_color,
|
||||
rgba_color,
|
||||
rgb_color_percent,
|
||||
rgba_color_percent
|
||||
);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
} // ns
|
||||
|
||||
css_color_grammar::css_color_grammar_type const& color_grammar()
|
||||
{
|
||||
return css_color_grammar::css_color;
|
||||
}
|
||||
|
||||
}
|
||||
} //ns mapnik
|
||||
|
||||
#endif //MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP
|
|
@ -1,79 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_CSV_GRAMMAR_HPP
|
||||
#define MAPNIK_CSV_GRAMMAR_HPP
|
||||
|
||||
#include <mapnik/csv/csv_types.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
|
||||
struct csv_white_space_skipper : qi::primitive_parser<csv_white_space_skipper>
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef qi::unused_type type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& /*attr*/) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
if (first != last && *first == ' ')
|
||||
{
|
||||
while (++first != last && *first == ' ')
|
||||
;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
qi::info what(Context& /*context*/) const
|
||||
{
|
||||
return qi::info("csv_white_space_skipper");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Iterator, typename Skipper = csv_white_space_skipper>
|
||||
struct csv_line_grammar : qi::grammar<Iterator, csv_line(char, char), Skipper>
|
||||
{
|
||||
csv_line_grammar();
|
||||
private:
|
||||
qi::rule<Iterator, csv_line(char, char), Skipper> line;
|
||||
qi::rule<Iterator, csv_value(char, char)> column; // no-skip
|
||||
qi::rule<Iterator, csv_value(char)> text; // no-skip
|
||||
qi::rule<Iterator, csv_value(char)> quoted; // no-skip
|
||||
qi::symbols<char const, char const> unesc_char;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_CSV_GRAMMAR_HPP
|
67
include/mapnik/csv/csv_grammar_x3.hpp
Normal file
67
include/mapnik/csv/csv_grammar_x3.hpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_CSV_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_CSV_GRAMMAR_X3_HPP
|
||||
|
||||
#include <mapnik/csv/csv_types.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <iostream>
|
||||
namespace mapnik {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
|
||||
struct csv_white_space_skipper : x3::parser<csv_white_space_skipper>
|
||||
{
|
||||
using attribute_type = x3::unused_type;
|
||||
static bool const has_attribute = false;
|
||||
|
||||
template <typename Iterator, typename Context, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last,
|
||||
Context const& context, x3::unused_type, Attribute& ) const
|
||||
{
|
||||
x3::skip_over(first, last, context);
|
||||
if (first != last && *first == ' ')
|
||||
{
|
||||
while (++first != last && *first == ' ')
|
||||
;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
auto static const csv_white_space = csv_white_space_skipper{};
|
||||
|
||||
namespace grammar {
|
||||
|
||||
struct separator_tag;
|
||||
struct quote_tag;
|
||||
|
||||
struct csv_line_class;
|
||||
using csv_line_grammar_type = x3::rule<csv_line_class, csv_line>;
|
||||
|
||||
BOOST_SPIRIT_DECLARE(csv_line_grammar_type);
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_CSV_GRAMMAR_X3_HPP
|
113
include/mapnik/csv/csv_grammar_x3_def.hpp
Normal file
113
include/mapnik/csv/csv_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <mapnik/csv/csv_grammar_x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
#include <iostream>
|
||||
namespace mapnik { namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
namespace ascii = boost::spirit::x3::ascii;
|
||||
|
||||
using x3::lit;
|
||||
using x3::lexeme;
|
||||
using ascii::char_;
|
||||
|
||||
struct unesc_char_ : x3::symbols<char>
|
||||
{
|
||||
unesc_char_()
|
||||
{
|
||||
add("\\a", '\a')
|
||||
("\\b", '\b')
|
||||
("\\f", '\f')
|
||||
("\\n", '\n')
|
||||
("\\r", '\r')
|
||||
("\\t", '\t')
|
||||
("\\v", '\v')
|
||||
("\\\\",'\\')
|
||||
("\\\'", '\'')
|
||||
("\\\"", '\"')
|
||||
("\"\"", '\"') // double quote
|
||||
;
|
||||
}
|
||||
} unesc_char;
|
||||
|
||||
template <typename T>
|
||||
struct literal : x3::parser<literal<T>>
|
||||
{
|
||||
using attribute_type = x3::unused_type;
|
||||
using context_tag = T;
|
||||
static bool const has_attribute = false;
|
||||
|
||||
template <typename Iterator, typename Context, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last,
|
||||
Context const& context, x3::unused_type, Attribute& ) const
|
||||
{
|
||||
x3::skip_over(first, last, context);
|
||||
if (first != last && *first == x3::get<context_tag>(context))
|
||||
{
|
||||
++first;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
auto static const separator = literal<separator_tag>{};
|
||||
auto static const quote = literal<quote_tag>{};
|
||||
|
||||
// starting rule
|
||||
csv_line_grammar_type const line("csv-line");
|
||||
// rules
|
||||
x3::rule<class csv_column, csv_value> column("csv-column");
|
||||
x3::rule<class csv_text, csv_value> text("csv-text");
|
||||
x3::rule<class csc_quoted_text, csv_value> quoted_text("csv-quoted-text");
|
||||
|
||||
auto const line_def = -lit('\r') > -lit('\n') > lexeme[column] % separator
|
||||
;
|
||||
|
||||
auto const column_def = quoted_text | *(char_ - separator)
|
||||
;
|
||||
|
||||
auto const quoted_text_def = quote > text > quote // support unmatched quotes or not (??)
|
||||
;
|
||||
|
||||
auto const text_def = *(unesc_char | (char_ - quote))
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEFINE (
|
||||
line,
|
||||
column,
|
||||
quoted_text,
|
||||
text
|
||||
);
|
||||
|
||||
} // grammar
|
||||
|
||||
grammar::csv_line_grammar_type const& csv_line_grammar()
|
||||
{
|
||||
return grammar::line;
|
||||
}
|
||||
|
||||
} // namespace mapnik
|
|
@ -69,8 +69,8 @@ public:
|
|||
Raster
|
||||
};
|
||||
|
||||
datasource (parameters const& params)
|
||||
: params_(params) {}
|
||||
datasource (parameters const& _params)
|
||||
: params_(_params) {}
|
||||
|
||||
/*!
|
||||
* @brief Get the configuration parameters of the data source.
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <mapnik/debug.hpp>
|
||||
|
||||
// stl
|
||||
#include <bitset>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
@ -190,6 +189,8 @@ public:
|
|||
for (unsigned i = 0; i < THE_MAX; ++i)
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||
if (str_copy == our_strings_[i])
|
||||
#pragma GCC diagnostic pop
|
||||
|
@ -203,6 +204,8 @@ public:
|
|||
}
|
||||
}
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||
throw illegal_enum_value(std::string("Illegal enumeration value '") +
|
||||
str + "' for enum " + our_name_);
|
||||
|
@ -213,6 +216,8 @@ public:
|
|||
std::string as_string() const
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||
return our_strings_[value_];
|
||||
#pragma GCC diagnostic pop
|
||||
|
|
|
@ -43,8 +43,8 @@ struct evaluate_expression
|
|||
{
|
||||
using value_type = T;
|
||||
|
||||
explicit evaluate_expression(Attributes const& attributes)
|
||||
: attributes_(attributes) {}
|
||||
explicit evaluate_expression(Attributes const& _attributes)
|
||||
: attributes_(_attributes) {}
|
||||
|
||||
value_type operator() (attribute const&) const
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/attribute.hpp>
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/expression_node.hpp>
|
||||
#include <mapnik/function_call.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_EXPRESSIONS_GRAMMAR_HPP
|
||||
#define MAPNIK_EXPRESSIONS_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/expression_node.hpp>
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace standard_wide = boost::spirit::standard_wide;
|
||||
using standard_wide::space_type;
|
||||
|
||||
template <typename T>
|
||||
struct integer_parser
|
||||
{
|
||||
using type = qi::int_parser<T,10,1,-1>;
|
||||
};
|
||||
|
||||
struct unary_function_types : qi::symbols<char, unary_function_impl>
|
||||
{
|
||||
unary_function_types();
|
||||
};
|
||||
|
||||
struct binary_function_types : qi::symbols<char, binary_function_impl>
|
||||
{
|
||||
binary_function_types();
|
||||
};
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
template <typename Iterator>
|
||||
struct MAPNIK_DECL expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
||||
#else
|
||||
template <typename Iterator>
|
||||
struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
||||
#endif
|
||||
{
|
||||
using rule_type = qi::rule<Iterator, expr_node(), space_type>;
|
||||
|
||||
explicit expression_grammar(std::string const& encoding = "utf-8");
|
||||
|
||||
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
|
||||
typename integer_parser<mapnik::value_integer>::type int__;
|
||||
mapnik::transcoder tr_;
|
||||
|
||||
rule_type expr;
|
||||
rule_type equality_expr;
|
||||
rule_type cond_expr;
|
||||
rule_type relational_expr;
|
||||
rule_type logical_expr;
|
||||
rule_type additive_expr;
|
||||
rule_type multiplicative_expr;
|
||||
rule_type unary_expr;
|
||||
rule_type not_expr;
|
||||
rule_type primary_expr;
|
||||
qi::rule<Iterator, unary_function_call() , space_type> unary_function_expr;
|
||||
qi::rule<Iterator, binary_function_call() , space_type> binary_function_expr;
|
||||
qi::rule<Iterator, std::string() > regex_match_expr;
|
||||
qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
|
||||
qi::rule<Iterator, std::string() , space_type> attr;
|
||||
qi::rule<Iterator, std::string() , space_type> global_attr;
|
||||
qi::rule<Iterator, std::string(), qi::locals<char> > quoted_ustring;
|
||||
qi::rule<Iterator, std::string()> unquoted_ustring;
|
||||
qi::rule<Iterator, std::string(), space_type> ustring;
|
||||
|
||||
qi::symbols<char const, char const> unesc_char;
|
||||
qi::rule<Iterator, char() > quote_char;
|
||||
qi::symbols<char, expr_node> constant;
|
||||
unary_function_types unary_func_type;
|
||||
binary_function_types binary_func_type;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // MAPNIK_EXPRESSIONS_GRAMMAR_HPP
|
|
@ -1,280 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// NOTE: This is an implementation header file and is only meant to be included
|
||||
// from implementation files. It therefore doesn't have an include guard.
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/expression_node.hpp>
|
||||
#include <mapnik/expression_grammar.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/function_call.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/fusion/adapted/struct.hpp>
|
||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||
#include <boost/spirit/include/phoenix_object.hpp>
|
||||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call,
|
||||
(mapnik::unary_function_impl, fun)
|
||||
(mapnik::unary_function_call::argument_type, arg))
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call,
|
||||
(mapnik::binary_function_impl, fun)
|
||||
(mapnik::binary_function_call::argument_type, arg1)
|
||||
(mapnik::binary_function_call::argument_type, arg2))
|
||||
|
||||
// fwd declare
|
||||
namespace mapnik {
|
||||
struct attribute;
|
||||
struct geometry_type_attribute;
|
||||
}
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
struct unicode_impl
|
||||
{
|
||||
using result_type = mapnik::value_unicode_string;
|
||||
explicit unicode_impl(mapnik::transcoder const& tr)
|
||||
: tr_(tr) {}
|
||||
|
||||
mapnik::value_unicode_string operator()(std::string const& str) const
|
||||
{
|
||||
return tr_.transcode(str.c_str());
|
||||
}
|
||||
|
||||
mapnik::transcoder const& tr_;
|
||||
};
|
||||
|
||||
struct regex_match_impl
|
||||
{
|
||||
using result_type = expr_node;
|
||||
explicit regex_match_impl(mapnik::transcoder const& tr)
|
||||
: tr_(tr) {}
|
||||
|
||||
template <typename T0,typename T1>
|
||||
expr_node operator() (T0 & node, T1 const& pattern) const;
|
||||
|
||||
mapnik::transcoder const& tr_;
|
||||
};
|
||||
|
||||
struct regex_replace_impl
|
||||
{
|
||||
using result_type = expr_node;
|
||||
explicit regex_replace_impl(mapnik::transcoder const& tr)
|
||||
: tr_(tr) {}
|
||||
|
||||
template <typename T0,typename T1,typename T2>
|
||||
expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const;
|
||||
|
||||
mapnik::transcoder const& tr_;
|
||||
};
|
||||
|
||||
unary_function_types::unary_function_types()
|
||||
{
|
||||
add
|
||||
("sin", sin_impl())
|
||||
("cos", cos_impl())
|
||||
("tan", tan_impl())
|
||||
("atan", atan_impl())
|
||||
("exp", exp_impl())
|
||||
("log", log_impl())
|
||||
("abs", abs_impl())
|
||||
("length",length_impl())
|
||||
;
|
||||
}
|
||||
|
||||
binary_function_types::binary_function_types()
|
||||
{
|
||||
add
|
||||
("min", binary_function_impl(min_impl))
|
||||
("max", binary_function_impl(max_impl))
|
||||
("pow", binary_function_impl(pow_impl))
|
||||
;
|
||||
}
|
||||
|
||||
template <typename T0,typename T1>
|
||||
expr_node regex_match_impl::operator() (T0 & node, T1 const& pattern) const
|
||||
{
|
||||
return regex_match_node(tr_,node,pattern);
|
||||
}
|
||||
|
||||
template <typename T0,typename T1,typename T2>
|
||||
expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const& format) const
|
||||
{
|
||||
return regex_replace_node(tr_,node,pattern,format);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
expression_grammar<Iterator>::expression_grammar(std::string const& encoding)
|
||||
: expression_grammar::base_type(expr),
|
||||
tr_(encoding)
|
||||
{
|
||||
qi::_1_type _1;
|
||||
qi::_a_type _a;
|
||||
qi::_b_type _b;
|
||||
qi::_r1_type _r1;
|
||||
qi::no_skip_type no_skip;
|
||||
qi::_val_type _val;
|
||||
qi::lit_type lit;
|
||||
qi::double_type double_;
|
||||
qi::hex_type hex;
|
||||
qi::omit_type omit;
|
||||
qi::alpha_type alpha;
|
||||
qi::alnum_type alnum;
|
||||
standard_wide::char_type char_;
|
||||
standard_wide::no_case_type no_case;
|
||||
using boost::phoenix::construct;
|
||||
using boost::phoenix::if_else;
|
||||
|
||||
boost::phoenix::function<unicode_impl> unicode = unicode_impl(tr_);
|
||||
boost::phoenix::function<regex_match_impl> regex_match = regex_match_impl(tr_);
|
||||
boost::phoenix::function<regex_replace_impl> regex_replace = regex_replace_impl(tr_);
|
||||
|
||||
constant.add
|
||||
("null", mapnik::value_null())
|
||||
("false", mapnik::value_bool(false))
|
||||
("true", mapnik::value_bool(true))
|
||||
("point", mapnik::value_integer(1))
|
||||
("linestring", mapnik::value_integer(2))
|
||||
("polygon", mapnik::value_integer(3))
|
||||
("collection", mapnik::value_integer(4))
|
||||
("pi", mapnik::value_double(3.1415926535897932384626433832795))
|
||||
("deg_to_rad", mapnik::value_double(0.017453292519943295769236907684886))
|
||||
("rad_to_deg", mapnik::value_double(57.295779513082320876798154814105))
|
||||
;
|
||||
|
||||
expr = logical_expr [_val = _1]
|
||||
//| ustring [_val = unicode(_1)]
|
||||
;
|
||||
|
||||
logical_expr = not_expr [_val = _1]
|
||||
>>
|
||||
*( ( ( lit("and") | lit("&&")) >> not_expr [_val && _1] )
|
||||
| (( lit("or") | lit("||")) >> not_expr [_val || _1])
|
||||
)
|
||||
;
|
||||
|
||||
not_expr =
|
||||
cond_expr [_val = _1 ]
|
||||
| ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ])
|
||||
;
|
||||
|
||||
cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1]
|
||||
;
|
||||
|
||||
equality_expr =
|
||||
relational_expr [_val = _1]
|
||||
>> *( ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1])
|
||||
| (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1])
|
||||
)
|
||||
;
|
||||
|
||||
regex_match_expr = lit(".match")
|
||||
>> lit('(')
|
||||
>> quoted_ustring [_val = _1]
|
||||
>> lit(')')
|
||||
;
|
||||
|
||||
regex_replace_expr =
|
||||
lit(".replace")
|
||||
>> lit('(')
|
||||
>> quoted_ustring [_a = _1]
|
||||
>> lit(',')
|
||||
>> quoted_ustring [_b = _1]
|
||||
>> lit(')') [_val = regex_replace(_r1,_a,_b)]
|
||||
;
|
||||
|
||||
relational_expr = additive_expr[_val = _1]
|
||||
>>
|
||||
*( ( (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ])
|
||||
| ( (lit('<') | lit("lt") ) >> additive_expr [ _val < _1 ])
|
||||
| ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ])
|
||||
| ( (lit('>') | lit("gt") ) >> additive_expr [ _val > _1 ])
|
||||
)
|
||||
;
|
||||
|
||||
additive_expr = multiplicative_expr [_val = _1]
|
||||
>> * ( '+' >> multiplicative_expr[_val += _1]
|
||||
| '-' >> multiplicative_expr[_val -= _1]
|
||||
)
|
||||
;
|
||||
|
||||
multiplicative_expr = unary_expr [_val = _1]
|
||||
>> *( '*' >> unary_expr [_val *= _1]
|
||||
| '/' >> unary_expr [_val /= _1]
|
||||
| '%' >> unary_expr [_val %= construct<mapnik::expr_node>(_1)] //needed by clang++ with -std=c++11
|
||||
| regex_match_expr[_val = regex_match(_val, _1)]
|
||||
| regex_replace_expr(_val) [_val = _1]
|
||||
)
|
||||
;
|
||||
|
||||
unary_function_expr = unary_func_type >> '(' > logical_expr > ')'
|
||||
;
|
||||
|
||||
binary_function_expr = binary_func_type >> '(' > logical_expr > ','
|
||||
> logical_expr > ')'
|
||||
;
|
||||
|
||||
unary_expr = primary_expr [_val = _1]
|
||||
| '+' >> primary_expr [_val = _1]
|
||||
| '-' >> primary_expr [_val = -_1]
|
||||
;
|
||||
|
||||
primary_expr = strict_double [_val = _1]
|
||||
| int__[_val = _1]
|
||||
| no_case[constant] [_val = _1]
|
||||
| quoted_ustring [_val = unicode(_1)]
|
||||
| attr [if_else(_1 == "mapnik::geometry_type",
|
||||
_val = construct<mapnik::geometry_type_attribute>(),
|
||||
_val = construct<mapnik::attribute>(_1))]
|
||||
| global_attr [_val = construct<mapnik::global_attribute>( _1 )]
|
||||
| unary_function_expr [_val = _1]
|
||||
| binary_function_expr [_val = _1]
|
||||
| '(' > logical_expr [_val = _1 ] > ')'
|
||||
// TODO: this is a backward compatibility hack to allow unquoted strings
|
||||
| unquoted_ustring [_val = unicode(_1)]
|
||||
// ^ https://github.com/mapnik/mapnik/pull/3389
|
||||
;
|
||||
|
||||
unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n')
|
||||
("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\')
|
||||
("\\\'", '\'')("\\\"", '\"')
|
||||
;
|
||||
|
||||
ustring %= no_skip[alpha >> *alnum];
|
||||
quote_char %= char_('\'') | char_('"');
|
||||
quoted_ustring %= omit[quote_char[_a = _1]]
|
||||
>> *(unesc_char | "\\x" >> hex | (char_ - lit(_a)))
|
||||
>> lit(_a);
|
||||
unquoted_ustring %= no_skip[alpha >> *alnum] - lit("not");
|
||||
attr %= '[' >> no_skip[+~char_(']')] >> ']';
|
||||
global_attr %= '@' >> no_skip[alpha >> * (alnum | char_('-'))];
|
||||
|
||||
}
|
||||
|
||||
}
|
51
include/mapnik/expression_grammar_x3.hpp
Normal file
51
include/mapnik/expression_grammar_x3.hpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_EXPRESSIONS_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP
|
||||
|
||||
#include <mapnik/expression_node.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik { namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
struct transcoder_tag;
|
||||
struct expression_class; // top-most ID
|
||||
using expression_grammar_type = x3::rule<expression_class, expr_node>;
|
||||
|
||||
BOOST_SPIRIT_DECLARE(expression_grammar_type);
|
||||
|
||||
}}
|
||||
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
grammar::expression_grammar_type const& expression_grammar();
|
||||
}
|
||||
|
||||
|
||||
#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP
|
43
include/mapnik/expression_grammar_x3_config.hpp
Normal file
43
include/mapnik/expression_grammar_x3_config.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP
|
||||
#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP
|
||||
|
||||
#include <mapnik/expression_grammar_x3.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace mapnik { namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
using iterator_type = std::string::const_iterator;
|
||||
using phrase_context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;
|
||||
|
||||
// define combined context
|
||||
using context_type = x3::with_context<transcoder_tag,
|
||||
std::reference_wrapper<mapnik::transcoder const> const,
|
||||
phrase_context_type>::type;
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP
|
433
include/mapnik/expression_grammar_x3_def.hpp
Normal file
433
include/mapnik/expression_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,433 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_EXPRESSIONS_GRAMMAR_X3_DEF_HPP
|
||||
#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
#include <mapnik/expression_grammar_x3.hpp>
|
||||
#include <mapnik/expression_node.hpp>
|
||||
#include <mapnik/function_call.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <boost/spirit/home/x3/support/ast/variant.hpp>
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
#include <boost/fusion/include/std_pair.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call,
|
||||
(mapnik::unary_function_impl, fun)
|
||||
(mapnik::unary_function_call::argument_type, arg))
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call,
|
||||
(mapnik::binary_function_impl, fun)
|
||||
(mapnik::binary_function_call::argument_type, arg1)
|
||||
(mapnik::binary_function_call::argument_type, arg2))
|
||||
|
||||
|
||||
namespace mapnik { namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
namespace ascii = boost::spirit::x3::ascii;
|
||||
using ascii::char_;
|
||||
using ascii::string;
|
||||
using x3::lit;
|
||||
using x3::double_;
|
||||
using x3::int_;
|
||||
using x3::bool_;
|
||||
using x3::_attr;
|
||||
using x3::_val;
|
||||
using x3::no_skip;
|
||||
using x3::lexeme;
|
||||
using x3::no_case;
|
||||
using x3::alpha;
|
||||
using x3::alnum;
|
||||
using x3::hex;
|
||||
|
||||
auto do_assign = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(_attr(ctx));
|
||||
};
|
||||
|
||||
auto do_negate = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(unary_node<mapnik::tags::negate>(_attr(ctx)));
|
||||
};
|
||||
|
||||
auto do_attribute = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(attribute(_attr(ctx)));
|
||||
};
|
||||
|
||||
auto do_global_attribute = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(global_attribute(_attr(ctx)));
|
||||
};
|
||||
|
||||
auto do_geometry_type_attribute = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(geometry_type_attribute());
|
||||
};
|
||||
|
||||
auto do_add = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::plus>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_subt = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::minus>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_mult = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::mult>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_div = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::div>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_mod = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::mod>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_unicode = [] (auto const& ctx)
|
||||
{
|
||||
auto & tr = x3::get<transcoder_tag>(ctx).get();
|
||||
_val(ctx) = std::move(tr.transcode(_attr(ctx).c_str()));
|
||||
};
|
||||
|
||||
auto do_null = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::value_null());
|
||||
};
|
||||
|
||||
auto do_not = [] (auto const& ctx)
|
||||
{
|
||||
mapnik::unary_node<mapnik::tags::logical_not> node(_attr(ctx));
|
||||
_val(ctx) = std::move(node);
|
||||
};
|
||||
|
||||
auto do_and = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::logical_and>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_or = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::logical_or>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_equal = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::equal_to>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_not_equal = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::not_equal_to>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_less = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::less>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_less_equal = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::less_equal>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_greater = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::greater>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_greater_equal = [] (auto const& ctx)
|
||||
{
|
||||
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::greater_equal>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
// regex
|
||||
auto do_regex_match = [] (auto const& ctx)
|
||||
{
|
||||
auto const& tr = x3::get<transcoder_tag>(ctx).get();
|
||||
_val(ctx) = std::move(mapnik::regex_match_node(tr, std::move(_val(ctx)) , std::move(_attr(ctx))));
|
||||
};
|
||||
|
||||
auto do_regex_replace = [] (auto const& ctx)
|
||||
{
|
||||
auto const& tr = x3::get<transcoder_tag>(ctx).get();
|
||||
auto const& pair = _attr(ctx);
|
||||
auto const& pattern = std::get<0>(pair);
|
||||
auto const& format = std::get<1>(pair);
|
||||
_val(ctx) = mapnik::regex_replace_node(tr, _val(ctx) , pattern, format);
|
||||
};
|
||||
|
||||
// mapnik::value_integer
|
||||
auto const mapnik_int = x3::int_parser<value_integer,10,1,-1>();
|
||||
// mapnik::value_double
|
||||
auto const mapnik_double = x3::real_parser<value_double, x3::strict_real_policies<value_double>>();
|
||||
// mapnik::value_bool
|
||||
struct boolean_ : x3::symbols<mapnik::value_bool>
|
||||
{
|
||||
boolean_()
|
||||
{
|
||||
add
|
||||
("true", true)
|
||||
("false", false)
|
||||
;
|
||||
}
|
||||
} boolean;
|
||||
|
||||
struct floating_point_constants : x3::symbols<mapnik::value_double>
|
||||
{
|
||||
floating_point_constants()
|
||||
{
|
||||
add
|
||||
("pi", 3.1415926535897932384626433832795)
|
||||
("deg_to_rad",0.017453292519943295769236907684886)
|
||||
("rad_to_deg",57.295779513082320876798154814105)
|
||||
;
|
||||
}
|
||||
} float_const;
|
||||
|
||||
// unary functions
|
||||
struct unary_function_types_ : x3::symbols<unary_function_impl>
|
||||
{
|
||||
unary_function_types_()
|
||||
{
|
||||
add
|
||||
("sin", sin_impl())
|
||||
("cos", cos_impl())
|
||||
("tan", tan_impl())
|
||||
("atan", atan_impl())
|
||||
("exp", exp_impl())
|
||||
("log", log_impl())
|
||||
("abs", abs_impl())
|
||||
("length",length_impl())
|
||||
;
|
||||
}
|
||||
} unary_func_types ;
|
||||
|
||||
|
||||
// binary functions
|
||||
|
||||
struct binary_function_types_ : x3::symbols<binary_function_impl>
|
||||
{
|
||||
binary_function_types_()
|
||||
{
|
||||
add
|
||||
("min", binary_function_impl(min_impl))
|
||||
("max", binary_function_impl(max_impl))
|
||||
("pow", binary_function_impl(pow_impl))
|
||||
;
|
||||
}
|
||||
} binary_func_types;
|
||||
|
||||
// geometry types
|
||||
struct geometry_types_ : x3::symbols<mapnik::value_integer>
|
||||
{
|
||||
geometry_types_()
|
||||
{
|
||||
add
|
||||
("point", 1)
|
||||
("linestring", 2)
|
||||
("polygon",3)
|
||||
("collection",4)
|
||||
;
|
||||
}
|
||||
} geometry_type;
|
||||
|
||||
struct unesc_chars_ : x3::symbols<char>
|
||||
{
|
||||
unesc_chars_()
|
||||
{
|
||||
add
|
||||
("\\a", '\a')
|
||||
("\\b", '\b')
|
||||
("\\f", '\f')
|
||||
("\\n", '\n')
|
||||
("\\r", '\r')
|
||||
("\\t", '\t')
|
||||
("\\v", '\v')
|
||||
("\\\\", '\\')
|
||||
("\\\'", '\'')
|
||||
("\\\"", '\"')
|
||||
;
|
||||
}
|
||||
} unesc_char;
|
||||
// starting rule
|
||||
expression_grammar_type const expression("expression");
|
||||
// rules
|
||||
x3::rule<class logical_expression, mapnik::expr_node> const logical_expression("logical expression");
|
||||
x3::rule<class not_expression, mapnik::expr_node> const not_expression("not expression");
|
||||
x3::rule<class conditional_expression, mapnik::expr_node> const conditional_expression("conditional expression");
|
||||
x3::rule<class equality_expression, mapnik::expr_node> const equality_expression("equality expression");
|
||||
x3::rule<class relational_expression, mapnik::expr_node> const relational_expression("relational expression");
|
||||
x3::rule<class additive_expression, mapnik::expr_node> const additive_expression("additive expression");
|
||||
x3::rule<class multiplicative_expression, mapnik::expr_node> const multiplicative_expression("multiplicative expression");
|
||||
x3::rule<class unary_func_expression, mapnik::unary_function_call> const unary_func_expression("unary function expression");
|
||||
x3::rule<class binary_func_expression, mapnik::binary_function_call> const binary_func_expression("binary function expression");
|
||||
x3::rule<class unary_expression, mapnik::expr_node> const unary_expression("unary expression");
|
||||
x3::rule<class primary_expression, mapnik::expr_node> const primary_expression("primary expression");
|
||||
x3::rule<class regex_match_expression, std::string> const regex_match_expression("regex match expression");
|
||||
x3::rule<class regex_replace_expression, std::pair<std::string,std::string> > const regex_replace_expression("regex replace expression");
|
||||
|
||||
// strings
|
||||
auto const single_quoted_string = x3::rule<class single_quoted_string, std::string> {} = lit('\'') >> no_skip[*(unesc_char | ("\\x" > hex) | (char_ - '\''))] > '\'';
|
||||
auto const double_quoted_string = x3::rule<class double_quoted_string, std::string> {} = lit('"') >> no_skip[*(unesc_char | ("\\x" > hex) | (char_ - '"'))] > '"';
|
||||
auto const quoted_string = x3::rule<class quoted_string, std::string> {} = single_quoted_string | double_quoted_string;
|
||||
|
||||
auto const unquoted_ustring = x3::rule<class ustring, std::string> {} = no_skip[alpha > *alnum] - lit("not");
|
||||
|
||||
// start
|
||||
auto const expression_def = logical_expression [do_assign]
|
||||
;
|
||||
|
||||
auto const logical_expression_def = not_expression[do_assign] >
|
||||
*(((lit("and") | lit("&&")) > not_expression[do_and])
|
||||
|
|
||||
((lit("or") | lit("||")) > not_expression[do_or]));
|
||||
|
||||
auto const not_expression_def = conditional_expression[do_assign]
|
||||
|
|
||||
(lit("not") | lit('!')) > conditional_expression[do_not]
|
||||
;
|
||||
|
||||
auto const conditional_expression_def = equality_expression[do_assign]
|
||||
|
|
||||
additive_expression[do_assign]
|
||||
;
|
||||
|
||||
auto const equality_expression_def = relational_expression[do_assign] >
|
||||
*( ( ( lit("=") | lit("eq") | lit("is")) > relational_expression [do_equal])
|
||||
| (( lit( "!=") | lit("<>") | lit("neq") ) > relational_expression [do_not_equal])
|
||||
);
|
||||
|
||||
auto const relational_expression_def = additive_expression[do_assign] >
|
||||
*( ( (lit("<=") | lit("le")) > additive_expression [do_less_equal])
|
||||
|
|
||||
( (lit("<") | lit("lt")) >> additive_expression[do_less]) // allow backtracking to be able to handle '<' and '<>' correctly
|
||||
|
|
||||
( (lit(">=") | lit("ge")) > additive_expression [do_greater_equal])
|
||||
|
|
||||
( (lit(">") | lit("gt")) > additive_expression [do_greater]));
|
||||
|
||||
|
||||
auto const additive_expression_def = multiplicative_expression[do_assign]
|
||||
> *( ('+' > multiplicative_expression[do_add])
|
||||
|
|
||||
('-' > multiplicative_expression[do_subt]));
|
||||
|
||||
auto const feature_attr = lexeme['[' > +~char_(']') > ']'];
|
||||
auto const global_attr = x3::rule<class global_attr, std::string> {} = lexeme[lit('@') > alpha > *alnum];
|
||||
|
||||
auto const regex_match_expression_def = lit(".match") > '(' > quoted_string > ')';
|
||||
auto const regex_replace_expression_def = lit(".replace") > '(' > quoted_string > ',' > quoted_string > ')';
|
||||
auto const multiplicative_expression_def = unary_expression [do_assign]
|
||||
> *( '*' > unary_expression [do_mult]
|
||||
|
|
||||
'/' > unary_expression [do_div]
|
||||
|
|
||||
'%' > unary_expression [do_mod]
|
||||
|
|
||||
regex_match_expression[do_regex_match]
|
||||
|
|
||||
regex_replace_expression[do_regex_replace]
|
||||
);
|
||||
|
||||
auto const unary_func_expression_def = unary_func_types > '(' > expression > ')';
|
||||
auto const binary_func_expression_def = binary_func_types > '(' > expression > ',' > expression > ')';
|
||||
|
||||
auto const unary_expression_def =
|
||||
primary_expression[do_assign]
|
||||
|
|
||||
'+' > primary_expression[do_assign]
|
||||
|
|
||||
'-' > primary_expression[do_negate]
|
||||
;
|
||||
|
||||
auto const primary_expression_def =
|
||||
mapnik_double[do_assign]
|
||||
|
|
||||
mapnik_int[do_assign]
|
||||
|
|
||||
no_case[boolean][do_assign]
|
||||
|
|
||||
no_case["null"][do_null]
|
||||
|
|
||||
no_case[geometry_type][do_assign]
|
||||
|
|
||||
float_const[do_assign]
|
||||
|
|
||||
quoted_string[do_unicode]
|
||||
|
|
||||
lit("[mapnik::geometry_type]")[do_geometry_type_attribute]
|
||||
|
|
||||
feature_attr[do_attribute]
|
||||
|
|
||||
global_attr[do_global_attribute]
|
||||
|
|
||||
unary_func_expression[do_assign]
|
||||
|
|
||||
binary_func_expression[do_assign]
|
||||
|
|
||||
('(' > logical_expression[do_assign] > ')')
|
||||
|
|
||||
unquoted_ustring[do_unicode]
|
||||
// ^ https://github.com/mapnik/mapnik/pull/3389
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEFINE (
|
||||
expression,
|
||||
logical_expression,
|
||||
not_expression,
|
||||
conditional_expression,
|
||||
equality_expression,
|
||||
relational_expression,
|
||||
additive_expression,
|
||||
regex_match_expression,
|
||||
regex_replace_expression,
|
||||
multiplicative_expression,
|
||||
unary_func_expression,
|
||||
binary_func_expression,
|
||||
unary_expression,
|
||||
primary_expression
|
||||
);
|
||||
|
||||
}}
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
grammar::expression_grammar_type const& expression_grammar()
|
||||
{
|
||||
return grammar::expression;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_EXPRESSION_NODE_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
|
@ -59,6 +59,9 @@ template <> struct make_op<mapnik::tags::logical_or> { using type = std::logica
|
|||
template <typename Tag>
|
||||
struct unary_node
|
||||
{
|
||||
unary_node (expr_node && a)
|
||||
: expr(std::move(a)) {}
|
||||
|
||||
unary_node (expr_node const& a)
|
||||
: expr(a) {}
|
||||
|
||||
|
@ -73,6 +76,10 @@ struct unary_node
|
|||
template <typename Tag>
|
||||
struct binary_node
|
||||
{
|
||||
binary_node(expr_node && a, expr_node && b)
|
||||
: left(std::move(a)),
|
||||
right(std::move(b)) {}
|
||||
|
||||
binary_node(expr_node const& a, expr_node const& b)
|
||||
: left(a),
|
||||
right(b) {}
|
||||
|
@ -130,81 +137,6 @@ struct MAPNIK_DECL regex_replace_node
|
|||
std::shared_ptr<_regex_replace_impl> impl_;
|
||||
};
|
||||
|
||||
inline expr_node & operator- (expr_node& expr)
|
||||
{
|
||||
return expr = unary_node<mapnik::tags::negate>(expr);
|
||||
}
|
||||
|
||||
inline expr_node & operator += ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::plus>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator -= ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::minus>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator *= ( expr_node &left , expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::mult>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator /= ( expr_node &left , expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::div>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator %= ( expr_node &left , expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::mod>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator < ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::less>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator <= ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::less_equal>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator > ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::greater>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator >= ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::greater_equal>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator == ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::equal_to>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator != ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::not_equal_to>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator ! (expr_node & expr)
|
||||
{
|
||||
return expr = unary_node<mapnik::tags::logical_not>(expr);
|
||||
}
|
||||
|
||||
inline expr_node & operator && ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::logical_and>(left,right);
|
||||
}
|
||||
|
||||
inline expr_node & operator || ( expr_node &left, expr_node const& right)
|
||||
{
|
||||
return left = binary_node<mapnik::tags::logical_or>(left,right);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
namespace mapnik
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_envelope.hpp>
|
||||
#include <mapnik/geometry/envelope.hpp>
|
||||
//
|
||||
#include <mapnik/feature_kv_iterator.hpp>
|
||||
#include <mapnik/util/noncopyable.hpp>
|
||||
|
@ -208,6 +208,11 @@ public:
|
|||
return geom_;
|
||||
}
|
||||
|
||||
inline geometry::geometry<double> & get_geometry()
|
||||
{
|
||||
return geom_;
|
||||
}
|
||||
|
||||
inline box2d<double> envelope() const
|
||||
{
|
||||
return mapnik::geometry::envelope(geom_);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
|
||||
// boost
|
||||
//#include <boost/pool/pool_alloc.hpp>
|
||||
|
|
|
@ -368,10 +368,10 @@ void feature_style_processor<Processor>::prepare_layer(layer_rendering_material
|
|||
continue;
|
||||
}
|
||||
|
||||
std::vector<rule> const& rules = style->get_rules();
|
||||
std::vector<rule> const& style_rules = style->get_rules();
|
||||
bool active_rules = false;
|
||||
rule_cache rc;
|
||||
for(rule const& r : rules)
|
||||
for(rule const& r : style_rules)
|
||||
{
|
||||
if (r.active(scale_denom))
|
||||
{
|
||||
|
|
|
@ -47,7 +47,6 @@ struct exp_impl
|
|||
{
|
||||
return std::exp(val.to_double());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// log
|
||||
|
@ -58,7 +57,6 @@ struct log_impl
|
|||
{
|
||||
return std::log(val.to_double());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// sin
|
||||
|
@ -102,7 +100,7 @@ struct abs_impl
|
|||
{
|
||||
value_type operator() (value_type const& val) const
|
||||
{
|
||||
return std::fabs(val.to_double());
|
||||
return std::abs(val.to_double());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/geometry_types.hpp>
|
||||
#include <mapnik/geometry/geometry_types.hpp>
|
||||
// stl
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
|
|
@ -46,11 +46,13 @@
|
|||
|
||||
// register point
|
||||
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<double>, double, boost::geometry::cs::cartesian, x, y)
|
||||
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<float>, float, boost::geometry::cs::cartesian, x, y)
|
||||
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<std::int64_t>, std::int64_t, boost::geometry::cs::cartesian, x, y)
|
||||
// ring
|
||||
BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(mapnik::geometry::linear_ring)
|
||||
// needed by box2d<double>
|
||||
// needed by box2d<T>
|
||||
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y)
|
||||
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2f, float, boost::geometry::cs::cartesian, x, y)
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
@ -120,6 +122,42 @@ struct indexed_access<mapnik::box2d<double>, max_corner, 1>
|
|||
static inline void set(mapnik::box2d<double> &b , ct const& value) { b.set_maxy(value); }
|
||||
};
|
||||
|
||||
// box2d<float>
|
||||
template<> struct tag<mapnik::box2d<float> > { using type = box_tag; };
|
||||
template<> struct point_type<mapnik::box2d<float> > { using type = mapnik::coord2f; };
|
||||
|
||||
template <>
|
||||
struct indexed_access<mapnik::box2d<float>, min_corner, 0>
|
||||
{
|
||||
using ct = coordinate_type<mapnik::coord2f>::type;
|
||||
static inline ct get(mapnik::box2d<float> const& b) { return b.minx();}
|
||||
static inline void set(mapnik::box2d<float> &b, ct const& value) { b.set_minx(value); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct indexed_access<mapnik::box2d<float>, min_corner, 1>
|
||||
{
|
||||
using ct = coordinate_type<mapnik::coord2f>::type;
|
||||
static inline ct get(mapnik::box2d<float> const& b) { return b.miny();}
|
||||
static inline void set(mapnik::box2d<float> &b, ct const& value) { b.set_miny(value); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct indexed_access<mapnik::box2d<float>, max_corner, 0>
|
||||
{
|
||||
using ct = coordinate_type<mapnik::coord2f>::type;
|
||||
static inline ct get(mapnik::box2d<float> const& b) { return b.maxx();}
|
||||
static inline void set(mapnik::box2d<float> &b, ct const& value) { b.set_maxx(value); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct indexed_access<mapnik::box2d<float>, max_corner, 1>
|
||||
{
|
||||
using ct = coordinate_type<mapnik::coord2f>::type;
|
||||
static inline ct get(mapnik::box2d<float> const& b) { return b.maxy();}
|
||||
static inline void set(mapnik::box2d<float> &b , ct const& value) { b.set_maxy(value); }
|
||||
};
|
||||
|
||||
// mapnik::geometry::line_string
|
||||
template<typename CoordinateType>
|
||||
struct tag<mapnik::geometry::line_string<CoordinateType> >
|
121
include/mapnik/geometry/boost_spirit_karma_adapter.hpp
Normal file
121
include/mapnik/geometry/boost_spirit_karma_adapter.hpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_BOOST_SPIRIT_KARMA_ADAPTER_HPP
|
||||
#define MAPNIK_BOOST_SPIRIT_KARMA_ADAPTER_HPP
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
|
||||
namespace boost { using mapbox::util::get; }
|
||||
|
||||
#include <boost/spirit/home/karma/domain.hpp>
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <>
|
||||
struct not_is_variant<mapnik::geometry::geometry<double>, karma::domain>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct not_is_variant<mapnik::geometry::geometry<std::int64_t>, karma::domain>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct variant_which< mapnik::geometry::geometry<double> >
|
||||
{
|
||||
static int call(mapnik::geometry::geometry<double> const& v)
|
||||
{
|
||||
return v.which();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct variant_which< mapnik::geometry::geometry<std::int64_t> >
|
||||
{
|
||||
static int call(mapnik::geometry::geometry<std::int64_t> const& v)
|
||||
{
|
||||
return v.which();
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename Tuple>
|
||||
struct has_type;
|
||||
|
||||
template <typename T>
|
||||
struct has_type<T, std::tuple<>> : std::false_type {};
|
||||
|
||||
template <typename T, typename U, typename... Types>
|
||||
struct has_type<T, std::tuple<U, Types...>> : has_type<T, std::tuple<Types...>> {};
|
||||
|
||||
template <typename T, typename... Types>
|
||||
struct has_type<T, std::tuple<T, Types...>> : std::true_type {};
|
||||
|
||||
template <typename T, typename Tuple>
|
||||
struct index;
|
||||
|
||||
template <typename T, typename... Types>
|
||||
struct index<T, std::tuple<T, Types...>>
|
||||
{
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
template <typename T, typename U, typename... Types>
|
||||
struct index<T, std::tuple<U, Types...>>
|
||||
{
|
||||
static const std::size_t value = 1 + index<T, std::tuple<Types...>>::value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename Expected>
|
||||
struct compute_compatible_component_variant<mapnik::geometry::geometry<double>, Expected>
|
||||
: detail::has_type<Expected, mapnik::geometry::geometry<double>::types>
|
||||
{
|
||||
using compatible_type = Expected;
|
||||
static bool is_compatible(int index)
|
||||
{
|
||||
return (index == detail::index<compatible_type, mapnik::geometry::geometry<double>::types>::value);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Expected>
|
||||
struct compute_compatible_component_variant<mapnik::geometry::geometry<std::int64_t>, Expected>
|
||||
: detail::has_type<Expected, mapnik::geometry::geometry<std::int64_t>::types>
|
||||
{
|
||||
using compatible_type = Expected;
|
||||
static bool is_compatible(int index)
|
||||
{
|
||||
return (index == detail::index<compatible_type, mapnik::geometry::geometry<std::int64_t>::types>::value);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
#endif //MAPNIK_BOOST_SPIRIT_KARMA_ADAPTER_HPP
|
|
@ -24,10 +24,10 @@
|
|||
#define MAPNIK_GEOMETRY_CENTROID_HPP
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_adapters.hpp>
|
||||
#include <mapnik/geometry/boost_adapters.hpp>
|
||||
#include <boost/geometry/algorithms/centroid.hpp>
|
||||
#include <mapnik/geometry_is_empty.hpp>
|
||||
#include <mapnik/geometry_remove_empty.hpp>
|
||||
#include <mapnik/geometry/is_empty.hpp>
|
||||
#include <mapnik/geometry/remove_empty.hpp>
|
||||
|
||||
namespace mapnik { namespace geometry {
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_GEOMETRY_CORRECT_HPP
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_adapters.hpp>
|
||||
#include <mapnik/geometry/boost_adapters.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/geometry_envelope.hpp>
|
||||
#include <mapnik/geometry/envelope.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_types.hpp>
|
||||
#include <mapnik/geometry/geometry_types.hpp>
|
||||
|
||||
namespace mapnik { namespace geometry { namespace detail {
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
#if BOOST_VERSION >= 105600
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_adapters.hpp>
|
||||
#include <mapnik/geometry/boost_adapters.hpp>
|
||||
#include <boost/geometry/algorithms/is_simple.hpp>
|
||||
|
||||
namespace mapnik { namespace geometry {
|
|
@ -29,7 +29,7 @@
|
|||
#if BOOST_VERSION >= 105800
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_adapters.hpp>
|
||||
#include <mapnik/geometry/boost_adapters.hpp>
|
||||
#include <boost/geometry/algorithms/is_valid.hpp>
|
||||
#include <boost/geometry/algorithms/validity_failure_type.hpp>
|
||||
|
||||
|
@ -102,7 +102,7 @@ struct geometry_is_valid
|
|||
struct geometry_is_valid_reason
|
||||
{
|
||||
using result_type = bool;
|
||||
|
||||
|
||||
boost::geometry::validity_failure_type & failure_;
|
||||
|
||||
geometry_is_valid_reason(boost::geometry::validity_failure_type & failure):
|
||||
|
@ -170,7 +170,7 @@ struct geometry_is_valid_reason
|
|||
struct geometry_is_valid_string
|
||||
{
|
||||
using result_type = bool;
|
||||
|
||||
|
||||
std::string & message_;
|
||||
|
||||
geometry_is_valid_string(std::string & message):
|
||||
|
@ -257,7 +257,7 @@ inline bool is_valid(T const& geom, boost::geometry::validity_failure_type & fai
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool is_valid(mapnik::geometry::geometry<T> const& geom,
|
||||
inline bool is_valid(mapnik::geometry::geometry<T> const& geom,
|
||||
boost::geometry::validity_failure_type & failure)
|
||||
{
|
||||
return util::apply_visitor(detail::geometry_is_valid_reason(failure), geom);
|
||||
|
@ -270,7 +270,7 @@ inline bool is_valid(T const& geom, std::string & message)
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool is_valid(mapnik::geometry::geometry<T> const& geom,
|
||||
inline bool is_valid(mapnik::geometry::geometry<T> const& geom,
|
||||
std::string & message)
|
||||
{
|
||||
return util::apply_visitor(detail::geometry_is_valid_string(message), geom);
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_GEOMETRY_REMOVE_EMPTY_HPP
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_is_empty.hpp>
|
||||
#include <mapnik/geometry/is_empty.hpp>
|
||||
|
||||
namespace mapnik { namespace geometry {
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/geometry_reprojection.hpp>
|
||||
#include <mapnik/geometry/reprojection.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
|
||||
namespace mapnik {
|
|
@ -23,20 +23,20 @@
|
|||
#ifndef MAPNIK_GEOMETRY_STRATEGY_HPP
|
||||
#define MAPNIK_GEOMETRY_STRATEGY_HPP
|
||||
|
||||
#include <mapnik/geometry_adapters.hpp>
|
||||
#include <mapnik/geometry/boost_adapters.hpp>
|
||||
#include <mapnik/util/rounding_cast.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
namespace mapnik {
|
||||
namespace geometry {
|
||||
|
||||
namespace helper
|
||||
{
|
||||
template <std::size_t... Ts>
|
||||
struct index {};
|
||||
|
||||
|
||||
template <std::size_t N, std::size_t... Ts>
|
||||
struct gen_seq : gen_seq<N - 1, N - 1, Ts...> {};
|
||||
|
||||
|
||||
template <std::size_t... Ts>
|
||||
struct gen_seq<0, Ts...> : index<Ts...> {};
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ struct strategy_group
|
|||
|
||||
template <typename P1, typename P2, typename T, typename ...Args>
|
||||
inline P2 execute(P1 const& p, bool & status, T const& strat, Args const& ... args) const
|
||||
{
|
||||
{
|
||||
return execute<P1,P2>(strat.template execute<P1,P1>(p, status), status, args...);
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ struct strategy_group
|
|||
{
|
||||
return strat.template execute<P1,P2>(p, status);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::tuple<Strategies const& ...> ops_;
|
||||
|
||||
|
@ -87,7 +87,7 @@ private:
|
|||
|
||||
|
||||
// The difference between this strategy group and the previous is that the conversion from P1 to P2 happens
|
||||
// in the first strategy rather then the last strategy.
|
||||
// in the first strategy rather then the last strategy.
|
||||
template <typename... Strategies>
|
||||
struct strategy_group_first
|
||||
{
|
||||
|
@ -116,13 +116,13 @@ struct strategy_group_first
|
|||
|
||||
template <typename P1, typename P2, typename T, typename ...Args>
|
||||
inline P2 execute_first(P1 const& p, bool & status, T const& strat, Args const& ... args) const
|
||||
{
|
||||
{
|
||||
return execute<P2>(strat.template execute<P1,P2>(p, status), status, args...);
|
||||
}
|
||||
|
||||
template <typename P2, typename T, typename ...Args>
|
||||
inline P2 execute(P2 const& p, bool & status, T const& strat, Args const& ... args) const
|
||||
{
|
||||
{
|
||||
return execute<P2>(strat.template execute<P2,P2>(p, status), status, args...);
|
||||
}
|
||||
|
||||
|
@ -131,13 +131,13 @@ struct strategy_group_first
|
|||
{
|
||||
return strat.template execute<P2,P2>(p, status);
|
||||
}
|
||||
|
||||
|
||||
template <typename P2>
|
||||
inline P2 execute(P2 const& p, bool & status) const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::tuple<Strategies const& ...> ops_;
|
||||
|
||||
|
@ -151,7 +151,7 @@ struct scale_strategy
|
|||
template <typename P1, typename P2>
|
||||
inline bool apply(P1 const & p1, P2 & p2) const
|
||||
{
|
||||
|
||||
|
||||
using p2_type = typename boost::geometry::coordinate_type<P2>::type;
|
||||
double x = (boost::geometry::get<0>(p1) * scale_) + offset_;
|
||||
double y = (boost::geometry::get<1>(p1) * scale_) + offset_;
|
||||
|
@ -159,7 +159,7 @@ struct scale_strategy
|
|||
boost::geometry::set<1>(p2, static_cast<p2_type>(y));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename P1, typename P2>
|
||||
inline P2 execute(P1 const& p1, bool & status) const
|
||||
{
|
||||
|
@ -181,7 +181,7 @@ struct scale_rounding_strategy
|
|||
template <typename P1, typename P2>
|
||||
inline bool apply(P1 const & p1, P2 & p2) const
|
||||
{
|
||||
|
||||
|
||||
using p2_type = typename boost::geometry::coordinate_type<P2>::type;
|
||||
double x = (boost::geometry::get<0>(p1) * scale_) + offset_;
|
||||
double y = (boost::geometry::get<1>(p1) * scale_) + offset_;
|
||||
|
@ -189,7 +189,7 @@ struct scale_rounding_strategy
|
|||
boost::geometry::set<1>(p2, static_cast<p2_type>(std::round(y)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename P1, typename P2>
|
||||
inline P2 execute(P1 const& p1, bool & status) const
|
||||
{
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_GEOMETRY_TRANSFORM_HPP
|
||||
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_adapters.hpp>
|
||||
#include <mapnik/geometry/boost_adapters.hpp>
|
||||
#include <boost/geometry/algorithms/transform.hpp>
|
||||
|
||||
namespace mapnik { namespace geometry { namespace detail {
|
|
@ -124,9 +124,9 @@ public:
|
|||
return pixmap_.painted();
|
||||
}
|
||||
|
||||
void painted(bool painted)
|
||||
void painted(bool _painted)
|
||||
{
|
||||
pixmap_.painted(painted);
|
||||
pixmap_.painted(_painted);
|
||||
}
|
||||
|
||||
inline eAttributeCollectionPolicy attribute_collection_policy() const
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
|
||||
hit_grid_view(unsigned x, unsigned y,
|
||||
unsigned width, unsigned height,
|
||||
T const& data,
|
||||
T const& _data,
|
||||
std::string const& key,
|
||||
std::string const& id_name,
|
||||
std::set<std::string> const& names,
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
y_(y),
|
||||
width_(width),
|
||||
height_(height),
|
||||
data_(data),
|
||||
data_(_data),
|
||||
key_(key),
|
||||
id_name_(id_name),
|
||||
names_(names),
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
//mapnik
|
||||
#include <mapnik/text/symbolizer_helpers.hpp>
|
||||
#include <mapnik/text/placements/base.hpp>
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/pixel_position.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
|
|
@ -681,7 +681,7 @@ void apply_filter(Src & src, scale_hsla const& transform, double /*scale_factor*
|
|||
}
|
||||
|
||||
template <typename Src, typename ColorBlindFilter>
|
||||
void color_blind_filter(Src & src, ColorBlindFilter const& op)
|
||||
void apply_color_blind_filter(Src & src, ColorBlindFilter const& op)
|
||||
{
|
||||
using namespace boost::gil;
|
||||
rgba8_view_t src_view = rgba8_view(src);
|
||||
|
@ -804,19 +804,19 @@ void color_blind_filter(Src & src, ColorBlindFilter const& op)
|
|||
template <typename Src>
|
||||
void apply_filter(Src & src, color_blind_protanope const& op, double /*scale_factor*/)
|
||||
{
|
||||
color_blind_filter(src, op);
|
||||
apply_color_blind_filter(src, op);
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
void apply_filter(Src & src, color_blind_deuteranope const& op, double /*scale_factor*/)
|
||||
{
|
||||
color_blind_filter(src, op);
|
||||
apply_color_blind_filter(src, op);
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
void apply_filter(Src & src, color_blind_tritanope const& op, double /*scale_factor*/)
|
||||
{
|
||||
color_blind_filter(src, op);
|
||||
apply_color_blind_filter(src, op);
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_IMAGE_FILTER_GRAMMAR_HPP
|
||||
#define MAPNIK_IMAGE_FILTER_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/css_color_grammar.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
#include <cmath>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
namespace filter {
|
||||
struct color_stop;
|
||||
struct colorize_alpha;
|
||||
}
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
|
||||
struct percent_offset_impl
|
||||
{
|
||||
using result_type = double;
|
||||
double operator() (double val) const
|
||||
{
|
||||
double result = std::abs(val/100.0);
|
||||
if (result > 1.0) result = 1.0;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Iterator, typename ContType>
|
||||
struct image_filter_grammar :
|
||||
qi::grammar<Iterator, ContType(), qi::ascii::space_type>
|
||||
{
|
||||
using alternative_type = qi::rule<Iterator, ContType(), qi::ascii::space_type>;
|
||||
|
||||
image_filter_grammar();
|
||||
|
||||
qi::rule<Iterator, ContType(), qi::ascii::space_type> start;
|
||||
qi::rule<Iterator, ContType(), qi::ascii::space_type,
|
||||
qi::locals<alternative_type*>> filter;
|
||||
qi::rule<Iterator, qi::ascii::space_type> no_args;
|
||||
qi::symbols<char, alternative_type*> alternatives;
|
||||
qi::uint_parser< unsigned, 10, 1, 3 > radius_;
|
||||
css_color_grammar<Iterator> css_color_;
|
||||
qi::rule<Iterator, filter::color_stop(), qi::ascii::space_type> color_stop_;
|
||||
qi::rule<Iterator, double(), qi::ascii::space_type> color_stop_offset;
|
||||
|
||||
private:
|
||||
alternative_type & add(std::string const& symbol);
|
||||
static constexpr unsigned max_alternatives = 16;
|
||||
unsigned num_alternatives = 0;
|
||||
alternative_type alternative_storage[max_alternatives];
|
||||
};
|
||||
|
||||
} // namespace mapnik
|
||||
|
||||
#endif // MAPNIK_IMAGE_FILTER_GRAMMAR_HPP
|
|
@ -1,141 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/image_filter_types.hpp>
|
||||
#include <mapnik/image_filter_grammar.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace { // internal
|
||||
|
||||
BOOST_PHOENIX_ADAPT_FUNCTION(
|
||||
typename std::remove_reference<A1>::type, ovo, // = optional_value_or
|
||||
boost::get_optional_value_or, 2)
|
||||
|
||||
} // namespace internal
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace phoenix = boost::phoenix;
|
||||
|
||||
template <typename Iterator, typename ContType>
|
||||
image_filter_grammar<Iterator,ContType>::image_filter_grammar()
|
||||
: image_filter_grammar::base_type(start)
|
||||
{
|
||||
qi::lit_type lit;
|
||||
qi::_val_type _val;
|
||||
qi::_1_type _1;
|
||||
qi::_2_type _2;
|
||||
qi::_3_type _3;
|
||||
qi::_4_type _4;
|
||||
qi::_5_type _5;
|
||||
qi::_6_type _6;
|
||||
qi::_7_type _7;
|
||||
qi::_8_type _8;
|
||||
qi::_a_type _a;
|
||||
qi::attr_type attr;
|
||||
qi::double_type double_;
|
||||
qi::hold_type hold;
|
||||
qi::omit_type omit;
|
||||
using phoenix::push_back;
|
||||
using phoenix::construct;
|
||||
|
||||
// functions
|
||||
phoenix::function<percent_offset_impl> percent_offset;
|
||||
|
||||
start = -(filter % *lit(','))
|
||||
;
|
||||
|
||||
filter = omit[alternatives[_a = _1]] >> qi::lazy(*_a)
|
||||
;
|
||||
|
||||
add("emboss") = no_args >> attr(construct<mapnik::filter::emboss>());
|
||||
add("blur") = no_args >> attr(construct<mapnik::filter::blur>());
|
||||
add("gray") = no_args >> attr(construct<mapnik::filter::gray>());
|
||||
add("edge-detect") = no_args >> attr(construct<mapnik::filter::edge_detect>());
|
||||
add("sobel") = no_args >> attr(construct<mapnik::filter::sobel>());
|
||||
add("sharpen") = no_args >> attr(construct<mapnik::filter::sharpen>());
|
||||
add("x-gradient") = no_args >> attr(construct<mapnik::filter::x_gradient>());
|
||||
add("y-gradient") = no_args >> attr(construct<mapnik::filter::y_gradient>());
|
||||
add("invert") = no_args >> attr(construct<mapnik::filter::invert>());
|
||||
add("color-blind-protanope") = no_args >> attr(construct<mapnik::filter::color_blind_protanope>());
|
||||
add("color-blind-deuteranope") = no_args >> attr(construct<mapnik::filter::color_blind_deuteranope>());
|
||||
add("color-blind-tritanope") = no_args >> attr(construct<mapnik::filter::color_blind_tritanope>());
|
||||
|
||||
add("agg-stack-blur") =
|
||||
(lit('(') >> radius_ >> -( lit(',') >> radius_ ) >> lit(')'))
|
||||
[push_back(_val, construct<filter::agg_stack_blur>(_1, ovo(_2, _1)))]
|
||||
|
|
||||
no_args
|
||||
[push_back(_val, construct<filter::agg_stack_blur>(1, 1))]
|
||||
;
|
||||
|
||||
add("scale-hsla") =
|
||||
(lit('(')
|
||||
>> double_ >> lit(',') >> double_ >> lit(',')
|
||||
>> double_ >> lit(',') >> double_ >> lit(',')
|
||||
>> double_ >> lit(',') >> double_ >> lit(',')
|
||||
>> double_ >> lit(',') >> double_ >> lit(')'))
|
||||
[push_back(_val, construct<filter::scale_hsla>(_1,_2,_3,_4,_5,_6,_7,_8))]
|
||||
;
|
||||
|
||||
add("colorize-alpha") = qi::as<filter::colorize_alpha>()
|
||||
[lit('(') >> color_stop_ % lit(',') >> lit(')')]
|
||||
[push_back(_val, _1)]
|
||||
;
|
||||
|
||||
color_stop_ = (css_color_ >> -color_stop_offset)
|
||||
[_val = construct<filter::color_stop>(_1, ovo(_2, 0.0))]
|
||||
;
|
||||
|
||||
color_stop_offset = double_[_val = _1]
|
||||
>> -lit('%')[_val = percent_offset(_val)]
|
||||
;
|
||||
|
||||
add("color-to-alpha") =
|
||||
hold[lit('(') >> css_color_ >> lit(')')]
|
||||
[push_back(_val, construct<filter::color_to_alpha>(_1))]
|
||||
;
|
||||
|
||||
no_args = -(lit('(') >> lit(')'));
|
||||
}
|
||||
|
||||
template <typename Iterator, typename ContType>
|
||||
auto image_filter_grammar<Iterator, ContType>::add(std::string const& symbol)
|
||||
-> alternative_type &
|
||||
{
|
||||
if (num_alternatives >= max_alternatives)
|
||||
{
|
||||
throw std::length_error("too many alternatives in image_filter_grammar");
|
||||
}
|
||||
|
||||
alternative_storage[num_alternatives].name(symbol);
|
||||
alternatives.add(symbol, &alternative_storage[num_alternatives]);
|
||||
return alternative_storage[num_alternatives++];
|
||||
}
|
||||
|
||||
} // namespace mapnik
|
56
include/mapnik/image_filter_grammar_x3.hpp
Normal file
56
include/mapnik/image_filter_grammar_x3.hpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_IMAGE_FILTER_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP
|
||||
|
||||
//#include <mapnik/image_filter.hpp>
|
||||
#include <mapnik/image_filter_types.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
|
||||
namespace image_filter
|
||||
{
|
||||
|
||||
struct image_filter_class;
|
||||
using image_filter_grammar_type = x3::rule<image_filter_class, std::vector<filter::filter_type> >;
|
||||
|
||||
BOOST_SPIRIT_DECLARE(image_filter_grammar_type);
|
||||
|
||||
|
||||
}}
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
image_filter::image_filter_grammar_type const& image_filter_grammar();
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP
|
261
include/mapnik/image_filter_grammar_x3_def.hpp
Normal file
261
include/mapnik/image_filter_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP
|
||||
#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
|
||||
#include <mapnik/image_filter_grammar_x3.hpp>
|
||||
#include <mapnik/image_filter_types.hpp>
|
||||
#include <mapnik/css_color_grammar_x3.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <boost/spirit/home/x3/support/ast/variant.hpp>
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
#include <boost/fusion/adapted/std_tuple.hpp> // spirit support
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::filter::scale_hsla,
|
||||
(double, h0)
|
||||
(double, h1)
|
||||
(double, s0)
|
||||
(double, s1)
|
||||
(double, l0)
|
||||
(double, l1)
|
||||
(double, a0)
|
||||
(double, a1)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::filter::color_stop,
|
||||
(mapnik::color, color )
|
||||
(double, offset)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
mapnik::filter::color_to_alpha,
|
||||
(mapnik::color, color)
|
||||
)
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
|
||||
namespace image_filter {
|
||||
|
||||
using x3::lit;
|
||||
using x3::uint_parser;
|
||||
using x3::hex;
|
||||
using x3::symbols;
|
||||
using x3::omit;
|
||||
using x3::attr;
|
||||
using x3::double_;
|
||||
using x3::no_case;
|
||||
using x3::no_skip;
|
||||
using x3::char_;
|
||||
|
||||
auto push_back = [](auto& ctx)
|
||||
{
|
||||
_val(ctx).push_back(_attr(ctx));
|
||||
|
||||
};
|
||||
|
||||
auto set_rx_ry = [](auto & ctx)
|
||||
{
|
||||
_val(ctx).rx = _val(ctx).ry = _attr(ctx);
|
||||
};
|
||||
|
||||
auto set_ry = [](auto & ctx)
|
||||
{
|
||||
_val(ctx).ry = _attr(ctx);
|
||||
};
|
||||
|
||||
auto offset_value = [](auto & ctx)
|
||||
{
|
||||
_val(ctx) = _attr(ctx);
|
||||
};
|
||||
|
||||
auto percent = [](auto & ctx)
|
||||
{
|
||||
double val = std::abs(_val(ctx)/100.0);
|
||||
if (val > 1.0) val = 1.0;
|
||||
_val(ctx) = val;
|
||||
};
|
||||
|
||||
x3::uint_parser<unsigned, 10, 1, 3> radius;
|
||||
|
||||
// Import the expression rule
|
||||
namespace { auto const& css_color = color_grammar(); }
|
||||
|
||||
// starting rule
|
||||
image_filter_grammar_type const start("start");
|
||||
// rules
|
||||
x3::rule<class filter_class, filter::filter_type > const filter("filter");
|
||||
|
||||
x3::rule<class emboss_class, filter::emboss> const emboss_filter("emboss");
|
||||
x3::rule<class blur_class, filter::blur> const blur_filter("blur");
|
||||
x3::rule<class gray_class, filter::gray> const gray_filter("gray");
|
||||
x3::rule<class edge_detect_class, filter::edge_detect> const edge_detect_filter("edge-detect");
|
||||
x3::rule<class sobel_class, filter::sobel> const sobel_filter("sobel");
|
||||
x3::rule<class sharpen_class, filter::sharpen> const sharpen_filter("sharpen");
|
||||
x3::rule<class x_gradient_class, filter::x_gradient> const x_gradient_filter("x-gradient");
|
||||
x3::rule<class y_gradient_class, filter::y_gradient> const y_gradient_filter("y-gradient");
|
||||
x3::rule<class invert_class, filter::invert> const invert_filter("invert");
|
||||
x3::rule<class color_blind_protanope_class, filter::color_blind_protanope> const color_blind_protanope_filter("color-blind-protanope");
|
||||
x3::rule<class color_blind_deuteranope_class, filter::color_blind_deuteranope> const color_blind_deuteranope_filter("color-blind-deuteranope");
|
||||
x3::rule<class color_blind_tritanope_class, filter::color_blind_tritanope> const color_blind_tritanope_filter("color-blind-tritanope");
|
||||
|
||||
x3::rule<class agg_blur_class, filter::agg_stack_blur> const agg_blur_filter("agg blur filter");
|
||||
x3::rule<class scale_hsla_class, filter::scale_hsla> const scale_hsla_filter("scale-hsla");
|
||||
x3::rule<class colorize_alpha_class, filter::colorize_alpha> const colorize_alpha_filter("colorize-alpha");
|
||||
x3::rule<class color_stop_class, filter::color_stop> const color_stop("color-stop");
|
||||
x3::rule<class offset_class, double> const offset("color-stop-offset");
|
||||
x3::rule<class color_to_alpha_class, filter::color_to_alpha> const color_to_alpha_filter("color-to-alpha");
|
||||
|
||||
auto const no_args = -(lit('(') > lit(')'));
|
||||
|
||||
auto const start_def = -(filter[push_back] % *lit(','));
|
||||
|
||||
auto const filter_def = (emboss_filter
|
||||
|
|
||||
blur_filter
|
||||
|
|
||||
gray_filter
|
||||
|
|
||||
edge_detect_filter
|
||||
|
|
||||
sobel_filter
|
||||
|
|
||||
sharpen_filter
|
||||
|
|
||||
x_gradient_filter
|
||||
|
|
||||
y_gradient_filter
|
||||
|
|
||||
invert_filter
|
||||
|
|
||||
color_blind_protanope_filter
|
||||
|
|
||||
color_blind_deuteranope_filter
|
||||
|
|
||||
color_blind_tritanope_filter
|
||||
|
|
||||
agg_blur_filter
|
||||
|
|
||||
scale_hsla_filter
|
||||
|
|
||||
colorize_alpha_filter
|
||||
|
|
||||
color_to_alpha_filter
|
||||
)
|
||||
;
|
||||
|
||||
auto const emboss_filter_def = lit("emboss") > no_args;
|
||||
|
||||
auto const blur_filter_def = lit("blur") > no_args;
|
||||
|
||||
auto const gray_filter_def = lit("gray") > no_args;
|
||||
|
||||
auto const edge_detect_filter_def = lit("edge-detect") > no_args;
|
||||
|
||||
auto const sobel_filter_def = lit("sobel") > no_args;
|
||||
|
||||
auto const sharpen_filter_def = lit("sharpen") > no_args;
|
||||
|
||||
auto const x_gradient_filter_def = lit("x-gradient") > no_args;
|
||||
|
||||
auto const y_gradient_filter_def = lit("y-gradient") > no_args;
|
||||
|
||||
auto const invert_filter_def = lit("invert") > no_args;
|
||||
|
||||
auto const color_blind_protanope_filter_def = lit("color-blind-protanope") > no_args;
|
||||
|
||||
auto const color_blind_deuteranope_filter_def = lit("color-blind-deuteranope") > no_args;
|
||||
|
||||
auto const color_blind_tritanope_filter_def = lit("color-blind-tritanope") > no_args;
|
||||
|
||||
auto const agg_blur_filter_def = lit("agg-stack-blur")
|
||||
> -(lit('(') > -(radius[set_rx_ry] > -(lit(',') > radius[set_ry])) > lit(')'));
|
||||
|
||||
auto const scale_hsla_filter_def = lit("scale-hsla") > lit('(')
|
||||
> double_ > ','
|
||||
> double_ > ','
|
||||
> double_ > ','
|
||||
> double_ > ','
|
||||
> double_ > ','
|
||||
> double_ > ','
|
||||
> double_ > ','
|
||||
> double_ > ')' ;
|
||||
|
||||
|
||||
auto const offset_def = double_[offset_value] > -lit('%')[percent];
|
||||
auto const color_stop_def = css_color > -offset;
|
||||
|
||||
auto const colorize_alpha_filter_def = lit("colorize-alpha")
|
||||
> lit('(')
|
||||
> color_stop > *(lit(',') > color_stop)
|
||||
> lit(')') ;
|
||||
|
||||
auto const color_to_alpha_filter_def = lit("color-to-alpha") > lit('(')
|
||||
> -css_color > lit(')');
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
|
||||
BOOST_SPIRIT_DEFINE(
|
||||
start,
|
||||
filter,
|
||||
emboss_filter,
|
||||
blur_filter,
|
||||
gray_filter,
|
||||
edge_detect_filter,
|
||||
sobel_filter,
|
||||
sharpen_filter,
|
||||
x_gradient_filter,
|
||||
y_gradient_filter,
|
||||
invert_filter,
|
||||
agg_blur_filter,
|
||||
color_blind_protanope_filter,
|
||||
color_blind_deuteranope_filter,
|
||||
color_blind_tritanope_filter,
|
||||
scale_hsla_filter,
|
||||
colorize_alpha_filter,
|
||||
color_stop,
|
||||
offset,
|
||||
color_to_alpha_filter
|
||||
);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
} // image_filter
|
||||
|
||||
image_filter::image_filter_grammar_type const& image_filter_grammar()
|
||||
{
|
||||
return image_filter::start;
|
||||
}
|
||||
|
||||
} //ns mapnik
|
||||
|
||||
#endif //MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP
|
|
@ -56,32 +56,41 @@ struct y_gradient : image_filter_base {};
|
|||
struct invert : image_filter_base {};
|
||||
|
||||
// http://vision.psychol.cam.ac.uk/jdmollon/papers/colourmaps.pdf
|
||||
struct color_blind_protanope : image_filter_base
|
||||
struct color_blind_filter : image_filter_base
|
||||
{
|
||||
const double x = 0.7465;
|
||||
const double y = 0.2535;
|
||||
const double m = 1.273463;
|
||||
const double yint = -0.073894;
|
||||
color_blind_filter(double x_, double y_, double m_, double yint_)
|
||||
: x(x_), y(y_), m(m_), yint(yint_) {}
|
||||
double x;
|
||||
double y;
|
||||
double m;
|
||||
double yint;
|
||||
};
|
||||
|
||||
struct color_blind_deuteranope : image_filter_base
|
||||
struct color_blind_protanope : color_blind_filter
|
||||
{
|
||||
const double x = 1.4;
|
||||
const double y = -0.4;
|
||||
const double m = 0.968437;
|
||||
const double yint = 0.003331;
|
||||
color_blind_protanope()
|
||||
: color_blind_filter(0.7465, 0.2535, 1.273463, -0.073894) {}
|
||||
};
|
||||
|
||||
struct color_blind_tritanope : image_filter_base
|
||||
struct color_blind_deuteranope : color_blind_filter
|
||||
{
|
||||
const double x = 0.1748;
|
||||
const double y = 0.0;
|
||||
const double m = 0.062921;
|
||||
const double yint = 0.292119;
|
||||
color_blind_deuteranope()
|
||||
: color_blind_filter(1.4, -0.4, 0.968437, 0.003331) {}
|
||||
};
|
||||
|
||||
struct color_blind_tritanope : color_blind_filter
|
||||
{
|
||||
color_blind_tritanope()
|
||||
: color_blind_filter(0.1748, 0.0, 0.062921, 0.292119) {}
|
||||
};
|
||||
|
||||
|
||||
struct agg_stack_blur : image_filter_base
|
||||
{
|
||||
agg_stack_blur()
|
||||
: rx(1), ry(1) {}
|
||||
agg_stack_blur(unsigned r)
|
||||
: rx(r), ry(r) {}
|
||||
agg_stack_blur(unsigned rx_, unsigned ry_)
|
||||
: rx(rx_),ry(ry_) {}
|
||||
inline bool operator==(agg_stack_blur const& rhs) const
|
||||
|
@ -94,6 +103,7 @@ struct agg_stack_blur : image_filter_base
|
|||
|
||||
struct color_to_alpha : image_filter_base
|
||||
{
|
||||
color_to_alpha() {}
|
||||
color_to_alpha(mapnik::color const& c)
|
||||
: color(c) {}
|
||||
inline bool operator==(color_to_alpha const& rhs) const
|
||||
|
@ -105,6 +115,7 @@ struct color_to_alpha : image_filter_base
|
|||
|
||||
struct scale_hsla : image_filter_base
|
||||
{
|
||||
scale_hsla() {}
|
||||
scale_hsla(double _h0, double _h1,
|
||||
double _s0, double _s1,
|
||||
double _l0, double _l1,
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/json/stringifier.hpp>
|
||||
#include <mapnik/json/value_converters.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
|
|
242
include/mapnik/json/create_feature.hpp
Normal file
242
include/mapnik/json/create_feature.hpp
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_FEATURE_HPP
|
||||
#define MAPNIK_JSON_CREATE_FEATURE_HPP
|
||||
|
||||
#include <mapnik/json/json_grammar_config.hpp>
|
||||
#include <mapnik/json/geojson_grammar_x3.hpp>
|
||||
#include <mapnik/json/create_geometry.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct stringifier
|
||||
{
|
||||
stringifier(keys_map const& keys)
|
||||
: keys_(keys) {}
|
||||
|
||||
std::string operator()(std::string const& val) const
|
||||
{
|
||||
return "\"" + val + "\"";
|
||||
}
|
||||
|
||||
std::string operator()(value_null) const
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
|
||||
std::string operator()(value_bool val) const
|
||||
{
|
||||
return val ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string operator()(value_integer val) const
|
||||
{
|
||||
std::string str;
|
||||
util::to_string(str, val);
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string operator()(value_double val) const
|
||||
{
|
||||
std::string str;
|
||||
util::to_string(str, val);
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string operator()(mapnik::json::geojson_array const& array) const
|
||||
{
|
||||
std::string str = "[";
|
||||
bool first = true;
|
||||
for (auto const& val : array)
|
||||
{
|
||||
if (first) first = false;
|
||||
else str += ",";
|
||||
str += mapnik::util::apply_visitor(*this, val);
|
||||
}
|
||||
str += "]";
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string operator()(mapnik::json::geojson_object const& object) const
|
||||
{
|
||||
std::string str = "{";
|
||||
bool first = true;
|
||||
for (auto const& kv : object)
|
||||
{
|
||||
auto itr = keys_.right.find(std::get<0>(kv));
|
||||
if (itr != keys_.right.end())
|
||||
{
|
||||
if (first) first = false;
|
||||
else str += ",";
|
||||
str += "\"" + itr->second + "\"";
|
||||
str += ":";
|
||||
str += mapnik::util::apply_visitor(*this, kv.second);
|
||||
}
|
||||
}
|
||||
str += "}";
|
||||
return str;
|
||||
}
|
||||
template <typename T>
|
||||
std::string operator()(T const&) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
keys_map const& keys_;
|
||||
};
|
||||
|
||||
struct attribute_value_visitor
|
||||
{
|
||||
public:
|
||||
attribute_value_visitor(mapnik::transcoder const& tr, keys_map const& keys)
|
||||
: tr_(tr),
|
||||
keys_(keys) {}
|
||||
|
||||
mapnik::value operator()(std::string const& val) const
|
||||
{
|
||||
return mapnik::value(tr_.transcode(val.c_str()));
|
||||
}
|
||||
|
||||
mapnik::value operator()(mapnik::json::geojson_array const& array) const
|
||||
{
|
||||
std::string str = stringifier(keys_)(array);
|
||||
return mapnik::value(tr_.transcode(str.c_str()));
|
||||
}
|
||||
|
||||
mapnik::value operator()(mapnik::json::geojson_object const& object) const
|
||||
{
|
||||
std::string str = stringifier(keys_)(object);
|
||||
return mapnik::value(tr_.transcode(str.c_str()));
|
||||
}
|
||||
|
||||
mapnik::value operator() (mapnik::value_bool val) const
|
||||
{
|
||||
return mapnik::value(val);
|
||||
}
|
||||
|
||||
mapnik::value operator() (mapnik::value_integer val) const
|
||||
{
|
||||
return mapnik::value(val);
|
||||
}
|
||||
|
||||
mapnik::value operator() (mapnik::value_double val) const
|
||||
{
|
||||
return mapnik::value(val);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
mapnik::value operator()(T const& val) const
|
||||
{
|
||||
return mapnik::value_null{};
|
||||
}
|
||||
|
||||
mapnik::transcoder const& tr_;
|
||||
mapnik::json::keys_map const& keys_;
|
||||
};
|
||||
|
||||
void create_feature(feature_impl & feature,
|
||||
mapnik::json::geojson_value const& value,
|
||||
mapnik::json::keys_map const& keys,
|
||||
mapnik::transcoder const& tr)
|
||||
{
|
||||
|
||||
if (!value.is<mapnik::json::geojson_object>())
|
||||
{
|
||||
throw std::runtime_error("Expecting an GeoJSON object");
|
||||
}
|
||||
mapnik::json::geojson_object const& feature_value = mapnik::util::get<mapnik::json::geojson_object>(value);
|
||||
for (auto const& elem : feature_value)
|
||||
{
|
||||
auto const key = std::get<0>(elem);
|
||||
if (key == mapnik::json::well_known_names::geometry)
|
||||
{
|
||||
auto const& geom_value = std::get<1>(elem);
|
||||
if (!geom_value.is<mapnik::json::geojson_object>())
|
||||
{
|
||||
throw std::runtime_error("\"geometry\": xxx <-- expecting an JSON object here");
|
||||
}
|
||||
auto const& geometry = mapnik::util::get<mapnik::json::geojson_object>(geom_value);
|
||||
mapnik::geometry::geometry_types geom_type;
|
||||
mapnik::json::positions const* coordinates = nullptr;
|
||||
for (auto & elem2 : geometry)
|
||||
{
|
||||
auto const key2 = std::get<0>(elem2);
|
||||
if (key2 == mapnik::json::well_known_names::type)
|
||||
{
|
||||
auto const& geom_type_value = std::get<1>(elem2);
|
||||
if (!geom_type_value.is<mapnik::geometry::geometry_types>())
|
||||
{
|
||||
throw std::runtime_error("\"type\": xxx <-- expecting an GeoJSON geometry type here");
|
||||
}
|
||||
geom_type = mapnik::util::get<mapnik::geometry::geometry_types>(geom_type_value);
|
||||
if (geom_type == mapnik::geometry::geometry_types::GeometryCollection)
|
||||
{
|
||||
throw std::runtime_error("GeometryCollections are not allowed");
|
||||
}
|
||||
}
|
||||
else if (key2 == mapnik::json::well_known_names::coordinates)
|
||||
{
|
||||
auto const& coordinates_value = std::get<1>(elem2);
|
||||
if (!coordinates_value.is<mapnik::json::positions>())
|
||||
{
|
||||
throw std::runtime_error("\"coordinates\": xxx <-- expecting an GeoJSON positions here");
|
||||
}
|
||||
coordinates = &mapnik::util::get<mapnik::json::positions>(coordinates_value);
|
||||
}
|
||||
}
|
||||
|
||||
mapnik::geometry::geometry<double> geom;
|
||||
mapnik::json::create_geometry(geom, geom_type, *coordinates);
|
||||
feature.set_geometry(std::move(geom));
|
||||
}
|
||||
else if (key == mapnik::json::well_known_names::properties)
|
||||
{
|
||||
auto const& prop_value = std::get<1>(elem);
|
||||
if (!prop_value.is<mapnik::json::geojson_object>())
|
||||
{
|
||||
throw std::runtime_error("\"properties\": xxx <-- expecting an JSON object here");
|
||||
}
|
||||
auto const& properties = mapnik::util::get<mapnik::json::geojson_object>(prop_value);
|
||||
auto end = keys.right.end();
|
||||
for (auto const& kv : properties)
|
||||
{
|
||||
auto itr = keys.right.find(std::get<0>(kv));
|
||||
if (itr != end)
|
||||
{
|
||||
feature.put_new(itr->second,
|
||||
mapnik::util::apply_visitor(mapnik::json::attribute_value_visitor(tr, keys),
|
||||
std::get<1>(kv)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif //MAPNIK_JSON_CREATE_FEATURE_HPP
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2015 Artem Pavlenko
|
||||
* 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
|
||||
|
@ -20,15 +20,16 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_JSON_GEOMETRY_UTIL_HPP
|
||||
#define MAPNIK_JSON_GEOMETRY_UTIL_HPP
|
||||
#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.hpp>
|
||||
#include <mapnik/geometry/correct.hpp>
|
||||
#include <mapnik/json/positions_x3.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace {
|
||||
// geometries
|
||||
template <typename Geometry>
|
||||
struct create_point
|
||||
|
@ -36,7 +37,7 @@ struct create_point
|
|||
explicit create_point(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (position const& pos) const
|
||||
void operator() (point const& pos) const
|
||||
{
|
||||
mapnik::geometry::point<double> point(pos.x, pos.y);
|
||||
geom_ = std::move(point);
|
||||
|
@ -53,14 +54,14 @@ struct create_linestring
|
|||
explicit create_linestring(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (positions const& ring) const
|
||||
void operator() (ring const& points) const
|
||||
{
|
||||
std::size_t size = ring.size();
|
||||
std::size_t size = points.size();
|
||||
if (size > 1)
|
||||
{
|
||||
mapnik::geometry::line_string<double> line;
|
||||
line.reserve(size);
|
||||
for (auto && pt : ring)
|
||||
for (auto && pt : points)
|
||||
{
|
||||
line.emplace_back(std::move(pt));
|
||||
}
|
||||
|
@ -80,10 +81,10 @@ struct create_polygon
|
|||
explicit create_polygon(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (std::vector<positions> const& rings) const
|
||||
void operator() (rings const& rngs) const
|
||||
{
|
||||
mapnik::geometry::polygon<double> poly;
|
||||
std::size_t num_rings = rings.size();
|
||||
std::size_t num_rings = rngs.size();
|
||||
if (num_rings > 1)
|
||||
{
|
||||
poly.interior_rings.reserve(num_rings - 1);
|
||||
|
@ -91,10 +92,10 @@ struct create_polygon
|
|||
|
||||
for ( std::size_t i = 0; i < num_rings; ++i)
|
||||
{
|
||||
std::size_t size = rings[i].size();
|
||||
std::size_t size = rngs[i].size();
|
||||
mapnik::geometry::linear_ring<double> ring;
|
||||
ring.reserve(size);
|
||||
for ( auto && pt : rings[i])
|
||||
for ( auto && pt : rngs[i])
|
||||
{
|
||||
ring.emplace_back(std::move(pt));
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ struct create_multipoint
|
|||
explicit create_multipoint(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (positions const& points) const
|
||||
void operator() (ring const& points) const
|
||||
{
|
||||
mapnik::geometry::multi_point<double> multi_point;
|
||||
multi_point.reserve(points.size());
|
||||
|
@ -141,12 +142,12 @@ struct create_multilinestring
|
|||
explicit create_multilinestring(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator() (std::vector<positions> const& rings) const
|
||||
void operator() (rings const& rngs) const
|
||||
{
|
||||
mapnik::geometry::multi_line_string<double> multi_line;
|
||||
multi_line.reserve(rings.size());
|
||||
multi_line.reserve(rngs.size());
|
||||
|
||||
for (auto const& ring : rings)
|
||||
for (auto const& ring : rngs)
|
||||
{
|
||||
mapnik::geometry::line_string<double> line;
|
||||
line.reserve(ring.size());
|
||||
|
@ -171,11 +172,11 @@ struct create_multipolygon
|
|||
explicit create_multipolygon(Geometry & geom)
|
||||
: geom_(geom) {}
|
||||
|
||||
void operator()(std::vector<std::vector<positions> > const& rings_array) const
|
||||
void operator()(rings_array const& rngs_arr) const
|
||||
{
|
||||
mapnik::geometry::multi_polygon<double> multi_poly;
|
||||
multi_poly.reserve(rings_array.size());
|
||||
for (auto const& rings : rings_array)
|
||||
multi_poly.reserve(rngs_arr.size());
|
||||
for (auto const& rings : rngs_arr)
|
||||
{
|
||||
mapnik::geometry::polygon<double> poly;
|
||||
std::size_t num_rings = rings.size();
|
||||
|
@ -205,40 +206,36 @@ struct create_multipolygon
|
|||
|
||||
Geometry & geom_;
|
||||
};
|
||||
} // anonymous ns
|
||||
|
||||
struct create_geometry_impl
|
||||
template <typename Geometry>
|
||||
void create_geometry (Geometry & geom, int type, mapnik::json::positions const& coords)
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename Geometry>
|
||||
void operator() (Geometry & geom, int type, mapnik::json::coordinates const& coords) const
|
||||
switch (type)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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_GEOMETRY_UTIL_HPP
|
||||
#endif // MAPNIK_JSON_CREATE_GEOMETRY_HPP
|
|
@ -1,64 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP
|
||||
#define MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/json/generic_json.hpp>
|
||||
#include <mapnik/json/error_handler.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
|
||||
template <typename Iterator, typename Boxes, typename ErrorHandler = error_handler<Iterator> >
|
||||
struct extract_bounding_box_grammar :
|
||||
qi::grammar<Iterator, void(Boxes&), space_type>
|
||||
{
|
||||
using position_type = mapnik::geometry::point<double>;
|
||||
using boxes_type = Boxes;
|
||||
using box_type = typename Boxes::value_type::first_type;
|
||||
extract_bounding_box_grammar();
|
||||
// rules
|
||||
qi::rule<Iterator, void(boxes_type&), space_type> start;
|
||||
qi::rule<Iterator, qi::locals<Iterator>, void(boxes_type&), space_type> features;
|
||||
qi::rule<Iterator, qi::locals<int, box_type>, void(boxes_type&, Iterator const&), space_type> feature;
|
||||
qi::rule<Iterator, qi::locals<box_type>, box_type(), space_type> coords;
|
||||
qi::rule<Iterator, boost::optional<position_type>(), space_type> pos;
|
||||
qi::rule<Iterator, void(box_type&), space_type> ring;
|
||||
qi::rule<Iterator, void(box_type&), space_type> rings;
|
||||
qi::rule<Iterator, void(box_type&), space_type> rings_array;
|
||||
// generic JSON support
|
||||
json::generic_json<Iterator> json;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP
|
|
@ -1,157 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/json/extract_bounding_box_grammar.hpp>
|
||||
#include <mapnik/geometry_fusion_adapted.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_iter_pos.hpp>
|
||||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
// stl
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct calculate_bounding_box_impl
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename T0, typename T1>
|
||||
result_type operator() (T0 & bbox, T1 const& pos) const
|
||||
{
|
||||
if (pos)
|
||||
{
|
||||
typename T0::value_type x = pos->x;
|
||||
typename T0::value_type y = pos->y;
|
||||
if (!bbox.valid())
|
||||
{
|
||||
bbox.init(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
bbox.expand_to_include(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct push_box_impl
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename T0, typename T1, typename T2, typename T3>
|
||||
void operator() (T0 & boxes, T1 const& begin, T2 const& box, T3 const& range) const
|
||||
{
|
||||
if (box.valid()) boxes.emplace_back(box,
|
||||
std::make_pair(std::distance(begin,
|
||||
range.begin()),
|
||||
std::distance(range.begin(), range.end())));
|
||||
}
|
||||
};
|
||||
|
||||
namespace repo = boost::spirit::repository;
|
||||
|
||||
template <typename Iterator, typename Boxes, typename ErrorHandler>
|
||||
extract_bounding_box_grammar<Iterator, Boxes, ErrorHandler>::extract_bounding_box_grammar()
|
||||
: extract_bounding_box_grammar::base_type(start, "GeoJSON 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::_a_type _a;
|
||||
qi::_b_type _b;
|
||||
qi::eps_type eps;
|
||||
qi::raw_type raw;
|
||||
qi::char_type char_;
|
||||
qi::no_skip_type no_skip;
|
||||
boost::spirit::repository::qi::iter_pos_type iter_pos;
|
||||
using qi::fail;
|
||||
using qi::on_error;
|
||||
|
||||
// phoenix functions
|
||||
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;
|
||||
|
||||
start = features(_r1)
|
||||
;
|
||||
|
||||
features = no_skip[iter_pos[_a = _1]] >> -(lit('{')
|
||||
>> *((json.key_value - lit("\"features\"")) >> lit(','))
|
||||
>> lit("\"features\"")
|
||||
>> lit(':'))
|
||||
>> lit('[') >> -(feature(_r1,_a) % lit(',')) >> lit(']')
|
||||
;
|
||||
|
||||
feature = raw[lit('{')[_a = 1]
|
||||
>> *(eps(_a > 0) >> (
|
||||
lit("\"FeatureCollection\"") > eps(false) // fail if nested FeatureCollection
|
||||
|
|
||||
lit('{')[_a += 1]
|
||||
|
|
||||
lit('}')[_a -= 1]
|
||||
|
|
||||
coords[_b = _1]
|
||||
|
|
||||
json.string_
|
||||
|
|
||||
char_))][push_box(_r1, _r2, _b, _1)]
|
||||
;
|
||||
|
||||
coords = lit("\"coordinates\"")
|
||||
>> lit(':') >> (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));
|
||||
}
|
||||
|
||||
}}
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2015 Artem Pavlenko
|
||||
* 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
|
||||
|
@ -20,9 +20,16 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/json/feature_grammar_impl.hpp>
|
||||
#include <string>
|
||||
|
||||
using iterator_type = char const*;
|
||||
template struct mapnik::json::feature_grammar<iterator_type,mapnik::feature_impl>;
|
||||
#ifndef MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_X3_HPP
|
||||
#define MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_X3_HPP
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
template <typename Iterator, typename Boxes>
|
||||
void extract_bounding_boxes(Iterator & start, Iterator const& end, Boxes & boxes);
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_X3_HPP
|
114
include/mapnik/json/extract_bounding_boxes_x3_config.hpp
Normal file
114
include/mapnik/json/extract_bounding_boxes_x3_config.hpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_EXTRACT_BOUNDING_BOXES_CONFIG_HPP
|
||||
#define MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_CONFIG_HPP
|
||||
|
||||
#include <mapnik/json/json_grammar_config.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
//auto feature_collection_impl = x3::with<mapnik::json::grammar::bracket_tag>(std::ref(bracket_counter))
|
||||
// [x3::with<mapnik::json::grammar::keys_tag>(std::ref(keys))
|
||||
// [x3::with<mapnik::json::grammar::feature_callback_tag>(std::ref(callback))
|
||||
// [mapnik::json::grammar::feature_collection]
|
||||
// ]];
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
template <typename Iterator, typename Boxes>
|
||||
struct extract_positions
|
||||
{
|
||||
using boxes_type = Boxes;
|
||||
using box_type = typename boxes_type::value_type::first_type;
|
||||
|
||||
extract_positions(Iterator start, Boxes & boxes)
|
||||
: start_(start),
|
||||
boxes_(boxes) {}
|
||||
|
||||
template <typename T>
|
||||
void operator() (T const& val) const
|
||||
{
|
||||
auto const& r = std::get<0>(val);
|
||||
auto const& b = std::get<1>(val);
|
||||
auto offset = std::distance(start_, r.begin());
|
||||
auto size = std::distance(r.begin(), r.end());
|
||||
boxes_.emplace_back(std::make_pair(box_type(b.minx(), b.miny(), b.maxx(), b.maxy()), std::make_pair(offset, size)));
|
||||
//boxes_.emplace_back(std::make_tuple(bbox,offset, size));
|
||||
}
|
||||
Iterator start_;
|
||||
Boxes & boxes_;
|
||||
};
|
||||
|
||||
using box_type = mapnik::box2d<double>;
|
||||
using boxes_type = std::vector<std::pair<box_type, std::pair<std::size_t, std::size_t>>>;
|
||||
using callback_type = extract_positions<grammar::iterator_type, boxes_type>;
|
||||
|
||||
using box_type_f = mapnik::box2d<float>;
|
||||
using boxes_type_f = std::vector<std::pair<box_type_f, std::pair<std::size_t, std::size_t>>>;
|
||||
using callback_type_f = extract_positions<grammar::iterator_type, boxes_type_f>;
|
||||
|
||||
|
||||
namespace grammar {
|
||||
|
||||
struct bracket_tag;
|
||||
struct feature_callback_tag;
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
using space_type = x3::standard::space_type;
|
||||
//using iterator_type = char const*;
|
||||
|
||||
using phrase_parse_context_type = x3::phrase_parse_context<space_type>::type;
|
||||
|
||||
using context_type = x3::with_context<keys_tag, std::reference_wrapper<keys_map> const,
|
||||
phrase_parse_context_type>::type;
|
||||
|
||||
using extract_bounding_boxes_context_type =
|
||||
x3::with_context<bracket_tag, std::reference_wrapper<std::size_t> const,
|
||||
x3::with_context<feature_callback_tag, std::reference_wrapper<callback_type> const,
|
||||
context_type>::type>::type;
|
||||
|
||||
using extract_bounding_boxes_reverse_context_type =
|
||||
x3::with_context<keys_tag, std::reference_wrapper<keys_map> const,
|
||||
x3::with_context<feature_callback_tag, std::reference_wrapper<callback_type> const,
|
||||
x3::with_context<bracket_tag, std::reference_wrapper<std::size_t> const,
|
||||
phrase_parse_context_type>::type>::type>::type;
|
||||
|
||||
|
||||
using extract_bounding_boxes_context_type_f =
|
||||
x3::with_context<bracket_tag, std::reference_wrapper<std::size_t> const,
|
||||
x3::with_context<feature_callback_tag, std::reference_wrapper<callback_type_f> const,
|
||||
context_type>::type>::type;
|
||||
|
||||
using extract_bounding_boxes_reverse_context_type_f =
|
||||
x3::with_context<keys_tag, std::reference_wrapper<keys_map> const,
|
||||
x3::with_context<feature_callback_tag, std::reference_wrapper<callback_type_f> const,
|
||||
x3::with_context<bracket_tag, std::reference_wrapper<std::size_t> const,
|
||||
phrase_parse_context_type>::type>::type>::type;
|
||||
|
||||
}}}
|
||||
|
||||
#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_CONFIG_HPP
|
|
@ -1,103 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_FEATURE_COLLECTION_GRAMMAR_HPP
|
||||
#define MAPNIK_FEATURE_COLLECTION_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/json/geometry_grammar.hpp>
|
||||
#include <mapnik/json/feature_grammar.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
||||
// spirit::qi
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace phoenix = boost::phoenix;
|
||||
|
||||
struct default_feature_callback
|
||||
{
|
||||
default_feature_callback(std::vector<feature_ptr> & features)
|
||||
: features_(features) {}
|
||||
void operator() (feature_ptr const& feature)
|
||||
{
|
||||
features_.push_back(feature);
|
||||
}
|
||||
std::vector<feature_ptr> & features_;
|
||||
};
|
||||
|
||||
struct apply_feature_callback
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename Callback, typename Feature>
|
||||
void operator() (Callback & callback, Feature const& feature) const
|
||||
{
|
||||
callback(feature);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator, typename FeatureType, typename FeatureCallback = default_feature_callback, typename ErrorHandler = error_handler<Iterator> >
|
||||
struct feature_collection_grammar :
|
||||
qi::grammar<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback &), space_type>
|
||||
{
|
||||
feature_collection_grammar(mapnik::transcoder const& tr);
|
||||
// grammars
|
||||
feature_grammar<Iterator, FeatureType, ErrorHandler> feature_g;
|
||||
// rules
|
||||
qi::rule<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback&), space_type> start; // START
|
||||
qi::rule<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback&), space_type> feature_collection;
|
||||
qi::rule<Iterator, space_type> type;
|
||||
qi::rule<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback&), space_type> features;
|
||||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature;
|
||||
// phoenix functions
|
||||
phoenix::function<apply_feature_callback> on_feature;
|
||||
// error handler
|
||||
boost::phoenix::function<ErrorHandler> const error_handler;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename FeatureType, typename FeatureCallback = default_feature_callback, typename ErrorHandler = error_handler<Iterator> >
|
||||
struct feature_grammar_callback :
|
||||
qi::grammar<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback &), space_type>
|
||||
{
|
||||
feature_grammar_callback(mapnik::transcoder const& tr);
|
||||
// grammars
|
||||
feature_grammar<Iterator, FeatureType> feature_g;
|
||||
geometry_grammar<Iterator> geometry_g;
|
||||
// rules
|
||||
qi::rule<Iterator, void(context_ptr const&, std::size_t&, FeatureCallback&), space_type> start; // START
|
||||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature;
|
||||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature_from_geometry;
|
||||
// phoenix functions
|
||||
phoenix::function<json::set_geometry_impl> set_geometry;
|
||||
phoenix::function<apply_feature_callback> on_feature;
|
||||
// error handler
|
||||
boost::phoenix::function<ErrorHandler> const error_handler;
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_FEATURE_COLLECTION_GRAMMAR_HPP
|
|
@ -1,122 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/json/error_handler.hpp>
|
||||
#include <mapnik/json/feature_collection_grammar.hpp>
|
||||
|
||||
// spirit::qi
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
template <typename Iterator, typename FeatureType, typename FeatureCallback, typename ErrorHandler>
|
||||
feature_collection_grammar<Iterator,FeatureType, FeatureCallback,ErrorHandler>::feature_collection_grammar(mapnik::transcoder const& tr)
|
||||
: feature_collection_grammar::base_type(start,"start"),
|
||||
feature_g(tr)
|
||||
{
|
||||
qi::lit_type lit;
|
||||
qi::eps_type eps;
|
||||
qi::_1_type _1;
|
||||
qi::_2_type _2;
|
||||
qi::_3_type _3;
|
||||
qi::_4_type _4;
|
||||
qi::_a_type _a;
|
||||
qi::_r1_type _r1;
|
||||
qi::_r2_type _r2;
|
||||
qi::_r3_type _r3;
|
||||
using phoenix::construct;
|
||||
using phoenix::new_;
|
||||
using phoenix::val;
|
||||
using qi::on_error;
|
||||
using qi::fail;
|
||||
start = feature_collection(_r1, _r2, _r3)
|
||||
;
|
||||
|
||||
feature_collection = lit('{') > (type | features(_r1, _r2, _r3) | feature_g.json_.key_value) % lit(',') > lit('}')
|
||||
;
|
||||
|
||||
type = lit("\"type\"") > lit(':') > lit("\"FeatureCollection\"")
|
||||
;
|
||||
|
||||
features = lit("\"features\"")
|
||||
> lit(':') > lit('[') >
|
||||
( lit(']') | ((feature(_r1, _r2, _r3) [_r2 +=1] % lit(',')) > lit(']')))
|
||||
;
|
||||
|
||||
feature = eps[_a = phoenix::construct<mapnik::feature_ptr>(new_<mapnik::feature_impl>(_r1, _r2))]
|
||||
> feature_g(*_a)[on_feature(_r3,_a)]
|
||||
;
|
||||
|
||||
start.name("start");
|
||||
feature_collection.name("FeatureCollection");
|
||||
type.name("type");
|
||||
features.name("features");
|
||||
feature.name("feature");
|
||||
feature_g.name("feature-grammar");
|
||||
on_error<fail>(feature_collection, error_handler(_1, _2, _3, _4));
|
||||
}
|
||||
|
||||
|
||||
template <typename Iterator, typename FeatureType, typename FeatureCallback, typename ErrorHandler>
|
||||
feature_grammar_callback<Iterator,FeatureType, FeatureCallback,ErrorHandler>::feature_grammar_callback(mapnik::transcoder const& tr)
|
||||
: feature_grammar_callback::base_type(start,"start"),
|
||||
feature_g(tr)
|
||||
{
|
||||
qi::lit_type lit;
|
||||
qi::eps_type eps;
|
||||
qi::_1_type _1;
|
||||
qi::_2_type _2;
|
||||
qi::_3_type _3;
|
||||
qi::_4_type _4;
|
||||
qi::_a_type _a;
|
||||
qi::_r1_type _r1;
|
||||
qi::_r2_type _r2;
|
||||
qi::_r3_type _r3;
|
||||
using phoenix::construct;
|
||||
using phoenix::new_;
|
||||
using phoenix::val;
|
||||
using qi::on_error;
|
||||
using qi::fail;
|
||||
start = feature_from_geometry(_r1, _r2, _r3) | feature(_r1, _r2, _r3)
|
||||
;
|
||||
|
||||
feature = eps[_a = phoenix::construct<mapnik::feature_ptr>(new_<mapnik::feature_impl>(_r1, _r2))]
|
||||
>> feature_g(*_a)[on_feature(_r3,_a)]
|
||||
;
|
||||
|
||||
feature_from_geometry =
|
||||
eps[_a = phoenix::construct<mapnik::feature_ptr>(new_<mapnik::feature_impl>(_r1, _r2))]
|
||||
>> geometry_g[set_geometry(*_a, _1)] [on_feature(_r3, _a)]
|
||||
;
|
||||
|
||||
start.name("start");
|
||||
feature.name("feature");
|
||||
feature_from_geometry.name("feature-from-geometry");
|
||||
feature_g.name("feature-grammar");
|
||||
geometry_g.name("geometry-grammar");
|
||||
on_error<fail>(feature, error_handler(_1, _2, _3, _4));
|
||||
}
|
||||
|
||||
}}
|
|
@ -63,17 +63,6 @@ struct end_container<mapnik::feature_impl const>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct transform_attribute<const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>,
|
||||
mapnik::geometry::geometry<double> const& , karma::domain>
|
||||
{
|
||||
using type = mapnik::geometry::geometry<double> const&;
|
||||
static type pre(const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>& f)
|
||||
{
|
||||
return boost::fusion::at<mpl::int_<0> >(f).get_geometry();
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
@ -91,6 +80,15 @@ struct get_id
|
|||
}
|
||||
};
|
||||
|
||||
struct extract_geometry
|
||||
{
|
||||
using result_type = mapnik::geometry::geometry<double> const&;
|
||||
template <typename T>
|
||||
result_type operator() (T const& f) const
|
||||
{
|
||||
return f.get_geometry();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OutputIterator, typename FeatureType>
|
||||
struct feature_generator_grammar :
|
||||
|
@ -101,6 +99,7 @@ struct feature_generator_grammar :
|
|||
geometry_generator_grammar<OutputIterator, mapnik::geometry::geometry<double> > geometry;
|
||||
properties_generator_grammar<OutputIterator, FeatureType> properties;
|
||||
boost::phoenix::function<get_id<FeatureType> > id_;
|
||||
boost::phoenix::function<extract_geometry> geom_;
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -40,7 +40,7 @@ feature_generator_grammar<OutputIterator, FeatureType>::feature_generator_gramma
|
|||
|
||||
feature = lit("{\"type\":\"Feature\",\"id\":")
|
||||
<< uint_[_1 = id_(_val)]
|
||||
<< lit(",\"geometry\":") << geometry
|
||||
<< lit(",\"geometry\":") << geometry[_1 = geom_(_val)]
|
||||
<< lit(",\"properties\":") << properties
|
||||
<< lit('}')
|
||||
;
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_FEATURE_GRAMMAR_HPP
|
||||
#define MAPNIK_FEATURE_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/json/geometry_grammar.hpp>
|
||||
#include <mapnik/json/attribute_value_visitor.hpp>
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
#include <boost/spirit/include/support_line_pos_iterator.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace phoenix = boost::phoenix;
|
||||
namespace fusion = boost::fusion;
|
||||
|
||||
struct put_property
|
||||
{
|
||||
using result_type = void;
|
||||
explicit put_property(mapnik::transcoder const& tr)
|
||||
: tr_(tr) {}
|
||||
template <typename T0,typename T1, typename T2>
|
||||
result_type operator() (T0 & feature, T1 const& key, T2 && val) const
|
||||
{
|
||||
feature.put_new(key, mapnik::util::apply_visitor(attribute_value_visitor(tr_),val));
|
||||
}
|
||||
mapnik::transcoder const& tr_;
|
||||
};
|
||||
|
||||
struct set_geometry_impl
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename T0, typename T1>
|
||||
result_type operator() (T0 & feature, T1 && geom) const
|
||||
{
|
||||
return feature.set_geometry(std::move(geom));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator, typename FeatureType, typename ErrorHandler = error_handler<Iterator>>
|
||||
struct feature_grammar : qi::grammar<Iterator, void(FeatureType&), space_type>
|
||||
{
|
||||
explicit feature_grammar(mapnik::transcoder const& tr);
|
||||
// generic JSON
|
||||
generic_json<Iterator> json_;
|
||||
// geoJSON
|
||||
qi::rule<Iterator, void(FeatureType&),space_type> start;
|
||||
qi::rule<Iterator, qi::locals<bool>, void(FeatureType&), space_type> feature;
|
||||
qi::rule<Iterator, void(FeatureType&, bool&), space_type> feature_part;
|
||||
qi::rule<Iterator, space_type> feature_type;
|
||||
qi::rule<Iterator,void(FeatureType &),space_type> properties;
|
||||
qi::rule<Iterator,qi::locals<std::string>, void(FeatureType &),space_type> attributes;
|
||||
// functions
|
||||
phoenix::function<put_property> put_property_;
|
||||
phoenix::function<set_geometry_impl> set_geometry;
|
||||
// error handler
|
||||
boost::phoenix::function<ErrorHandler> const error_handler;
|
||||
// geometry
|
||||
geometry_grammar<Iterator> geometry_grammar_;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_FEATURE_GRAMMAR_HPP
|
|
@ -1,87 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/json/feature_grammar.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
template <typename Iterator, typename FeatureType, typename ErrorHandler>
|
||||
feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::transcoder const& tr)
|
||||
: feature_grammar::base_type(start,"feature"),
|
||||
json_(),
|
||||
put_property_(put_property(tr))
|
||||
{
|
||||
qi::lit_type lit;
|
||||
qi::long_long_type long_long;
|
||||
qi::double_type double_;
|
||||
qi::_1_type _1;
|
||||
qi::_2_type _2;
|
||||
qi::_3_type _3;
|
||||
qi::_4_type _4;
|
||||
qi::_a_type _a;
|
||||
qi::_r1_type _r1;
|
||||
qi::_r2_type _r2;
|
||||
qi::eps_type eps;
|
||||
qi::char_type char_;
|
||||
using qi::fail;
|
||||
using qi::on_error;
|
||||
using phoenix::new_;
|
||||
using phoenix::construct;
|
||||
|
||||
// geojson types
|
||||
feature_type = lit("\"type\"") > lit(':') > lit("\"Feature\"")
|
||||
;
|
||||
|
||||
start = feature(_r1);
|
||||
|
||||
feature = eps[_a = false] > lit('{') >
|
||||
feature_part(_r1, _a) % lit(',')
|
||||
> eps(_a) > lit('}')
|
||||
;
|
||||
|
||||
feature_part = feature_type[_r2 = true]
|
||||
|
|
||||
(lit("\"geometry\"") > lit(':') > geometry_grammar_[set_geometry(_r1, _1)])
|
||||
|
|
||||
properties(_r1)
|
||||
|
|
||||
json_.key_value
|
||||
;
|
||||
|
||||
properties = lit("\"properties\"")
|
||||
> lit(':') > ((lit('{') > -attributes(_r1) > lit('}')) | lit("null"))
|
||||
;
|
||||
|
||||
attributes = (json_.string_ [_a = _1] > lit(':') > json_.value [put_property_(_r1,_a,_1)]) % lit(',')
|
||||
;
|
||||
|
||||
feature.name("Feature");
|
||||
feature_type.name("type");
|
||||
properties.name("properties");
|
||||
attributes.name("Attributes");
|
||||
on_error<fail>(feature, error_handler(_1, _2, _3, _4));
|
||||
|
||||
}
|
||||
|
||||
}}
|
48
include/mapnik/json/feature_grammar_x3.hpp
Normal file
48
include/mapnik/json/feature_grammar_x3.hpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_FEATURE_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_JSON_FEATURE_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;
|
||||
using feature_grammar_type = x3::rule<class feature_rule_tag>;
|
||||
using geometry_grammar_type = x3::rule<class geometry_rule_tag>;
|
||||
|
||||
BOOST_SPIRIT_DECLARE(feature_grammar_type);
|
||||
BOOST_SPIRIT_DECLARE(geometry_grammar_type);
|
||||
|
||||
}
|
||||
|
||||
grammar::feature_grammar_type const& feature_grammar();
|
||||
grammar::geometry_grammar_type const& geometry_grammar();
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_FEATURE_GRAMMAR_X3_HPP
|
317
include/mapnik/json/feature_grammar_x3_def.hpp
Normal file
317
include/mapnik/json/feature_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_FEATURE_GRAMMAR_X3_DEF_HPP
|
||||
#define MAPNIK_JSON_FEATURE_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
#include <mapnik/json/json_grammar_config.hpp>
|
||||
#include <mapnik/json/feature_grammar_x3.hpp>
|
||||
#include <mapnik/json/generic_json_grammar_x3.hpp>
|
||||
#include <mapnik/json/unicode_string_grammar_x3.hpp>
|
||||
#include <mapnik/json/positions_grammar_x3.hpp>
|
||||
#include <mapnik/json/positions_x3.hpp>
|
||||
|
||||
#include <mapnik/json/create_geometry.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/geometry/geometry_types.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct stringifier
|
||||
{
|
||||
std::string operator()(std::string const& val) const
|
||||
{
|
||||
return "\"" + val + "\"";
|
||||
}
|
||||
|
||||
std::string operator()(value_null) const
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
|
||||
std::string operator()(value_bool val) const
|
||||
{
|
||||
return val ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string operator()(value_integer val) const
|
||||
{
|
||||
std::string str;
|
||||
util::to_string(str, val);
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string operator()(value_double val) const
|
||||
{
|
||||
std::string str;
|
||||
util::to_string(str, val);
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string operator()(std::vector<mapnik::json::json_value> const& array) const
|
||||
{
|
||||
std::string str = "[";
|
||||
bool first = true;
|
||||
for (auto const& val : array)
|
||||
{
|
||||
if (first) first = false;
|
||||
else str += ",";
|
||||
str += mapnik::util::apply_visitor(*this, val);
|
||||
}
|
||||
str += "]";
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string operator()(std::vector<std::pair<std::string, mapnik::json::json_value>> const& object) const
|
||||
{
|
||||
std::string str = "{";
|
||||
bool first = true;
|
||||
for (auto const& kv : object)
|
||||
{
|
||||
if (first) first = false;
|
||||
else str += ",";
|
||||
str += "\"" + kv.first + "\"";
|
||||
str += ":";
|
||||
str += mapnik::util::apply_visitor(*this, kv.second);
|
||||
}
|
||||
str += "}";
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
struct attribute_value_visitor
|
||||
{
|
||||
public:
|
||||
attribute_value_visitor(mapnik::transcoder const& tr)
|
||||
: tr_(tr) {}
|
||||
|
||||
mapnik::value operator()(std::string const& val) const
|
||||
{
|
||||
return mapnik::value(tr_.transcode(val.c_str()));
|
||||
}
|
||||
|
||||
mapnik::value operator()(std::vector<mapnik::json::json_value> const& array) const
|
||||
{
|
||||
std::string str = stringifier()(array);
|
||||
return mapnik::value(tr_.transcode(str.c_str()));
|
||||
}
|
||||
|
||||
mapnik::value operator()(std::vector<std::pair<std::string, mapnik::json::json_value> > const& object) const
|
||||
{
|
||||
std::string str = stringifier()(object);
|
||||
return mapnik::value(tr_.transcode(str.c_str()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
mapnik::value operator()(T const& val) const
|
||||
{
|
||||
return mapnik::value(val);
|
||||
}
|
||||
|
||||
mapnik::transcoder const& tr_;
|
||||
};
|
||||
|
||||
namespace grammar {
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
using x3::lit;
|
||||
using x3::omit;
|
||||
using x3::char_;
|
||||
|
||||
namespace {
|
||||
auto const& value = generic_json_grammar();
|
||||
// import unicode string rule
|
||||
auto const& geojson_string = unicode_string_grammar();
|
||||
// import positions rule
|
||||
auto const& positions_rule = positions_grammar();
|
||||
}
|
||||
|
||||
// geometry types symbols
|
||||
struct geometry_type_ : x3::symbols<mapnik::geometry::geometry_types>
|
||||
{
|
||||
geometry_type_()
|
||||
{
|
||||
add
|
||||
("\"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_symbols;
|
||||
|
||||
auto assign_name = [](auto const& ctx)
|
||||
{
|
||||
std::get<0>(_val(ctx)) = std::move(_attr(ctx));
|
||||
};
|
||||
auto assign_value = [](auto const& ctx)
|
||||
{
|
||||
std::get<1>(_val(ctx)) = std::move(_attr(ctx));
|
||||
};
|
||||
|
||||
auto const assign_geometry_type = [] (auto const& ctx)
|
||||
{
|
||||
std::get<0>(_val(ctx)) = _attr(ctx);
|
||||
};
|
||||
|
||||
auto const create_collection = [] (auto const& ctx)
|
||||
{
|
||||
mapnik::feature_impl & feature = x3::get<grammar::feature_tag>(ctx);
|
||||
feature.set_geometry(mapnik::geometry::geometry_collection<double>());
|
||||
};
|
||||
|
||||
auto const assign_geometry = [] (auto const& ctx)
|
||||
{
|
||||
mapnik::feature_impl & feature = x3::get<grammar::feature_tag>(ctx);
|
||||
// first check if we're not dealing with GeometryCollection
|
||||
if (feature.get_geometry().is<mapnik::geometry::geometry_empty>())
|
||||
{
|
||||
mapnik::geometry::geometry<double> geom;
|
||||
auto const type = std::get<0>(_attr(ctx));
|
||||
auto const& coordinates = std::get<1>(_attr(ctx));
|
||||
mapnik::json::create_geometry(geom, type, coordinates);
|
||||
feature.set_geometry(std::move(geom));
|
||||
}
|
||||
};
|
||||
|
||||
auto const push_geometry = [] (auto const& ctx)
|
||||
{
|
||||
mapnik::geometry::geometry<double> geom;
|
||||
auto const type = std::get<0>(_attr(ctx));
|
||||
auto const& coordinates = std::get<1>(_attr(ctx));
|
||||
mapnik::json::create_geometry(geom, type, coordinates);
|
||||
mapnik::feature_impl & feature = x3::get<grammar::feature_tag>(ctx);
|
||||
geometry::geometry<double> & collection = feature.get_geometry();
|
||||
|
||||
if (collection.is<mapnik::geometry::geometry_collection<double>>())
|
||||
{
|
||||
auto & col = collection.get<mapnik::geometry::geometry_collection<double>>();
|
||||
col.push_back(std::move(geom));
|
||||
}
|
||||
};
|
||||
|
||||
auto const assign_positions = [] (auto const& ctx)
|
||||
{
|
||||
std::get<1>(_val(ctx)) = std::move(_attr(ctx));
|
||||
};
|
||||
|
||||
auto assign_property = [](auto const& ctx)
|
||||
{
|
||||
mapnik::feature_impl & feature = x3::get<grammar::feature_tag>(ctx);
|
||||
mapnik::transcoder const& tr = x3::get<grammar::transcoder_tag>(ctx);
|
||||
feature.put_new(std::get<0>(_attr(ctx)),
|
||||
mapnik::util::apply_visitor(attribute_value_visitor(tr),
|
||||
std::get<1>(_attr(ctx))));
|
||||
};
|
||||
|
||||
|
||||
//exported rules
|
||||
feature_grammar_type const feature_rule = "Feature";
|
||||
geometry_grammar_type const geometry_rule = "Geometry";
|
||||
// rules
|
||||
x3::rule<struct feature_type_tag> const feature_type = "Feature Type";
|
||||
x3::rule<struct geometry_type_tag, mapnik::geometry::geometry_types> const geometry_type = "Geometry Type";
|
||||
x3::rule<struct coordinates_tag, mapnik::json::positions> const coordinates = "Coordinates";
|
||||
x3::rule<struct geometry_tag, std::tuple<mapnik::geometry::geometry_types, mapnik::json::positions>> const geometry_tuple = "Geometry";
|
||||
x3::rule<struct property_tag, std::tuple<std::string, json_value>> const property = "Property";
|
||||
x3::rule<struct properties_tag> const properties = "Properties";
|
||||
x3::rule<struct feature_part_rule_tag> const feature_part = "Feature part";
|
||||
x3::rule<struct geometry_collection> const geometry_collection = "GeometryCollection";
|
||||
|
||||
auto const feature_type_def = lit("\"type\"") > lit(':') > lit("\"Feature\"");
|
||||
|
||||
auto const geometry_type_def = lit("\"type\"") > lit(':') > geometry_type_symbols;
|
||||
|
||||
auto const coordinates_def = lit("\"coordinates\"") > lit(':') > positions_rule;
|
||||
|
||||
auto const geometry_collection_def = lit("\"geometries\"")[create_collection] > lit(':')
|
||||
> lit('[')
|
||||
> ((lit('{') > geometry_tuple[push_geometry] > lit('}')) % lit(','))
|
||||
> lit(']');
|
||||
|
||||
|
||||
auto const geometry_tuple_def = (geometry_type[assign_geometry_type]
|
||||
|
|
||||
coordinates[assign_positions]
|
||||
|
|
||||
geometry_collection
|
||||
|
|
||||
(omit[geojson_string] > lit(':') > omit[value])) % lit(',');
|
||||
|
||||
|
||||
auto const property_def = geojson_string[assign_name] > lit(':') > value[assign_value];
|
||||
|
||||
auto const properties_def = property[assign_property] % lit(',');
|
||||
|
||||
auto const feature_part_def = feature_type
|
||||
|
|
||||
(lit("\"geometry\"") > lit(':') > lit('{') > geometry_tuple[assign_geometry] > lit('}'))
|
||||
|
|
||||
(lit("\"properties\"") > lit(':') > lit('{') > -properties > lit('}'))
|
||||
|
|
||||
omit[geojson_string] > lit(':') > omit[value]
|
||||
;
|
||||
|
||||
|
||||
auto const feature_rule_def = lit('{') > feature_part % lit(',') > lit('}');
|
||||
|
||||
auto const geometry_rule_def = lit('{') > geometry_tuple[assign_geometry] > lit('}');
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
|
||||
BOOST_SPIRIT_DEFINE(
|
||||
feature_type,
|
||||
geometry_type,
|
||||
coordinates,
|
||||
geometry_tuple,
|
||||
property,
|
||||
properties,
|
||||
feature_part,
|
||||
feature_rule,
|
||||
geometry_rule,
|
||||
geometry_collection
|
||||
);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
grammar::feature_grammar_type const& feature_grammar()
|
||||
{
|
||||
return grammar::feature_rule;
|
||||
}
|
||||
|
||||
grammar::geometry_grammar_type const& geometry_grammar()
|
||||
{
|
||||
return grammar::geometry_rule;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_FEATURE_GRAMMAR_X3_DEF_HPP
|
|
@ -25,25 +25,12 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/json/feature_grammar.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
inline bool from_geojson(std::string const& json, mapnik::feature_impl & feature)
|
||||
{
|
||||
static const mapnik::transcoder tr("utf8");
|
||||
using iterator_type = char const*;
|
||||
static const mapnik::json::feature_grammar<iterator_type,mapnik::feature_impl> g(tr);
|
||||
using namespace boost::spirit;
|
||||
standard::space_type space;
|
||||
iterator_type start = json.c_str();
|
||||
iterator_type end = start + json.length();
|
||||
return qi::phrase_parse(start, end, (g)(boost::phoenix::ref(feature)), space);
|
||||
}
|
||||
bool from_geojson(std::string const& json, mapnik::feature_impl & feature);
|
||||
|
||||
}}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef MAPNIK_GENERIC_JSON_HPP
|
||||
#define MAPNIK_GENERIC_JSON_HPP
|
||||
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
#include <mapnik/json/value_converters.hpp>
|
||||
|
||||
|
@ -53,8 +53,8 @@ using json_value_base = mapnik::util::variant<value_null,
|
|||
value_integer,
|
||||
value_double,
|
||||
std::string,
|
||||
mapnik::util::recursive_wrapper<json_array>,
|
||||
mapnik::util::recursive_wrapper<json_object> >;
|
||||
json_array,
|
||||
json_object>;
|
||||
struct json_value : json_value_base
|
||||
{
|
||||
#if __cpp_inheriting_constructors >= 200802
|
||||
|
|
82
include/mapnik/json/generic_json_grammar_x3.hpp
Normal file
82
include/mapnik/json/generic_json_grammar_x3.hpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_GENERIC_JSON_GRAMMAR_X3_HPP
|
||||
#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP
|
||||
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/util/variant.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<std::string, 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,
|
||||
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 generic_json_grammar_type = x3::rule<class generic_json_tag, json_value>;
|
||||
using generic_json_key_value_type = x3::rule<class json_object_element_tag, json_object_element>;
|
||||
BOOST_SPIRIT_DECLARE(generic_json_grammar_type);
|
||||
BOOST_SPIRIT_DECLARE(generic_json_key_value_type);
|
||||
}
|
||||
|
||||
grammar::generic_json_grammar_type const& generic_json_grammar();
|
||||
grammar::generic_json_key_value_type const& generic_json_key_value();
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP
|
133
include/mapnik/json/generic_json_grammar_x3_def.hpp
Normal file
133
include/mapnik/json/generic_json_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_GENERIC_JSON_GRAMMAR_X3_DEF_HPP
|
||||
#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
#include <boost/fusion/include/std_pair.hpp>
|
||||
#include <mapnik/json/generic_json_grammar_x3.hpp>
|
||||
#include <mapnik/json/unicode_string_grammar_x3.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) = _attr(ctx);
|
||||
};
|
||||
|
||||
auto assign_key = [](auto const& ctx)
|
||||
{
|
||||
std::get<0>(_val(ctx)) = _attr(ctx);
|
||||
};
|
||||
|
||||
auto assign_value = [](auto const& ctx)
|
||||
{
|
||||
std::get<1>(_val(ctx)) = _attr(ctx);
|
||||
};
|
||||
|
||||
|
||||
using x3::lit;
|
||||
using x3::string;
|
||||
// exported rules
|
||||
// start
|
||||
generic_json_grammar_type const value("JSON Value");
|
||||
generic_json_key_value_type const key_value("JSON Object element");
|
||||
// rules
|
||||
x3::rule<class json_object_tag, json_object> const object("JSON Object");
|
||||
x3::rule<class json_array_tag, json_array> const array("JSON Array");
|
||||
x3::rule<class json_number_tag, json_value> const number("JSON Number");
|
||||
|
||||
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(); }
|
||||
// generic json types
|
||||
auto const value_def = object | array | json_string | number
|
||||
;
|
||||
|
||||
auto const key_value_def = json_string[assign_key] > lit(':') > value[assign_value]
|
||||
;
|
||||
|
||||
auto const object_def = lit('{')
|
||||
> -(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,
|
||||
object,
|
||||
key_value,
|
||||
array,
|
||||
number
|
||||
);
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
}}}
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
grammar::generic_json_grammar_type const& generic_json_grammar()
|
||||
{
|
||||
return grammar::value;
|
||||
}
|
||||
grammar::generic_json_key_value_type const& generic_json_key_value()
|
||||
{
|
||||
return grammar::key_value;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_DEF_HPP
|
83
include/mapnik/json/geojson_grammar_x3.hpp
Normal file
83
include/mapnik/json/geojson_grammar_x3.hpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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 geojson_value;
|
||||
using geojson_array = std::vector<geojson_value>;
|
||||
using geojson_object_element = std::pair<int, geojson_value>;
|
||||
using geojson_object = std::vector<geojson_object_element>;
|
||||
using geojson_value_base = mapnik::util::variant<value_null,
|
||||
value_bool,
|
||||
value_integer,
|
||||
value_double,
|
||||
std::string,
|
||||
mapnik::geometry::geometry_types,
|
||||
positions,
|
||||
geojson_array,
|
||||
geojson_object>;
|
||||
struct geojson_value : geojson_value_base
|
||||
{
|
||||
#if __cpp_inheriting_constructors >= 200802
|
||||
|
||||
using geojson_value_base::geojson_value_base;
|
||||
|
||||
#else
|
||||
|
||||
geojson_value() = default;
|
||||
|
||||
template <typename T>
|
||||
geojson_value(T && val)
|
||||
: geojson_value_base(std::forward<T>(val)) {}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace grammar {
|
||||
|
||||
using geojson_grammar_type = x3::rule<class geojson_tag, geojson_value>;
|
||||
using key_value_type = x3::rule<class key_value_tag, geojson_object_element>;
|
||||
BOOST_SPIRIT_DECLARE(geojson_grammar_type, 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
|
183
include/mapnik/json/geojson_grammar_x3_def.hpp
Normal file
183
include/mapnik/json/geojson_grammar_x3_def.hpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
|
||||
|
||||
#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(keys_map::value_type(name, keys.size() + 1));
|
||||
std::get<0>(_val(ctx)) = result.first->right;
|
||||
};
|
||||
|
||||
auto assign_value = [](auto const& ctx)
|
||||
{
|
||||
std::get<1>(_val(ctx)) = std::move(_attr(ctx));
|
||||
};
|
||||
|
||||
using x3::lit;
|
||||
using x3::string;
|
||||
using x3::lexeme;
|
||||
|
||||
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, geojson_object> const object("JSON Object");
|
||||
x3::rule<class json_array_tag, geojson_array> const array("JSON Array");
|
||||
x3::rule<class json_number_tag, geojson_value> const number("JSON Number");
|
||||
//x3::rule<class key_value_tag, geojson_object_element> key_value("JSON key/value");
|
||||
// GeoJSON
|
||||
x3::rule<class geojson_coordinates_tag, geojson_object_element> const coordinates("GeoJSON Coordinates");
|
||||
x3::rule<class geojson_geometry_type_tag, geojson_object_element> const geometry_type("GeoJSON Geometry Type");
|
||||
x3::rule<class geojson_key_value_type_tag, geojson_object_element> const geojson_key_value("GeoJSON Key/Value Type");
|
||||
auto const geojson_double = x3::real_parser<value_double, x3::strict_real_policies<value_double>>();
|
||||
auto const geojson_integer = x3::int_parser<value_integer, 10, 1, -1>();
|
||||
|
||||
// import unicode string rule
|
||||
namespace { auto const& geojson_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 | geojson_string | number
|
||||
;
|
||||
|
||||
auto const coordinates_def = lexeme[lit('"') >> (string("coordinates") > lit('"'))][assign_key]
|
||||
> lit(':') > (positions_rule[assign_value] | value[assign_value])
|
||||
;
|
||||
|
||||
auto const geometry_type_def = lexeme[lit('"') >> (string("type") > lit('"'))][assign_key]
|
||||
> lit(':') > (geometry_type_sym[assign_value] | value[assign_value])
|
||||
;
|
||||
|
||||
auto const key_value_def = geojson_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 = geojson_double[assign]
|
||||
| geojson_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
|
|
@ -26,13 +26,10 @@
|
|||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/geometry_type.hpp>
|
||||
// boost
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/karma.hpp>
|
||||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
#include <boost/math/special_functions/trunc.hpp> // for vc++ and android whose c++11 libs lack std::trunc
|
||||
#include <boost/spirit/home/karma/domain.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
@ -43,18 +40,6 @@ namespace karma = boost::spirit::karma;
|
|||
|
||||
namespace detail {
|
||||
|
||||
template <typename Geometry>
|
||||
struct get_type
|
||||
{
|
||||
using result_type = mapnik::geometry::geometry_types;
|
||||
template <typename T>
|
||||
result_type operator() (T const& geom) const
|
||||
{
|
||||
auto type = mapnik::geometry::geometry_type(geom);
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct json_coordinate_policy : karma::real_policies<T>
|
||||
{
|
||||
|
@ -88,29 +73,29 @@ struct json_coordinate_policy : karma::real_policies<T>
|
|||
|
||||
template <typename OutputIterator, typename Geometry>
|
||||
struct geometry_generator_grammar :
|
||||
karma::grammar<OutputIterator, Geometry const&()>
|
||||
karma::grammar<OutputIterator, Geometry()>
|
||||
{
|
||||
using coord_type = typename Geometry::coord_type;
|
||||
geometry_generator_grammar();
|
||||
karma::rule<OutputIterator, Geometry const&()> geometry;
|
||||
karma::rule<OutputIterator, karma::locals<mapnik::geometry::geometry_types>, Geometry const&() > geometry_dispatch;
|
||||
karma::rule<OutputIterator, geometry::geometry<double> const&()> point;
|
||||
karma::rule<OutputIterator, geometry::point<double> const&()> point_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<double> const&()> linestring;
|
||||
karma::rule<OutputIterator, geometry::line_string<double> const&()> linestring_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<double> const&()> polygon;
|
||||
karma::rule<OutputIterator, geometry::polygon<double> const&()> polygon_coord;
|
||||
karma::rule<OutputIterator, geometry::linear_ring<double> const&()> exterior_ring_coord;
|
||||
karma::rule<OutputIterator, geometry::polygon<double>::rings_container const&()> interior_ring_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<double> const& ()> multi_point;
|
||||
karma::rule<OutputIterator, geometry::multi_point<double> const& ()> multi_point_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<double> const& ()> multi_linestring;
|
||||
karma::rule<OutputIterator, geometry::multi_line_string<double> const& ()> multi_linestring_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<double> const& ()> multi_polygon;
|
||||
karma::rule<OutputIterator, geometry::multi_polygon<double> const& ()> multi_polygon_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry<double> const& ()> geometry_collection;
|
||||
karma::rule<OutputIterator, geometry::geometry_collection<double> const& ()> geometries;
|
||||
boost::phoenix::function<detail::get_type<Geometry> > geometry_type;
|
||||
karma::real_generator<double, detail::json_coordinate_policy<double> > coordinate;
|
||||
karma::rule<OutputIterator, Geometry()> geometry;
|
||||
karma::rule<OutputIterator, geometry::point<coord_type>()> point;
|
||||
karma::rule<OutputIterator, geometry::point<coord_type>()> point_coord;
|
||||
karma::rule<OutputIterator, geometry::line_string<coord_type>()> linestring;
|
||||
karma::rule<OutputIterator, geometry::line_string<coord_type>()> linestring_coord;
|
||||
karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon;
|
||||
karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon_coord;
|
||||
karma::rule<OutputIterator, geometry::linear_ring<coord_type>()> exterior_ring_coord;
|
||||
karma::rule<OutputIterator, std::vector<geometry::linear_ring<coord_type> >()> interior_ring_coord;
|
||||
karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point;
|
||||
karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point_coord;
|
||||
karma::rule<OutputIterator, geometry::multi_line_string<coord_type>()> multi_linestring;
|
||||
karma::rule<OutputIterator, geometry::multi_line_string<coord_type> ()> multi_linestring_coord;
|
||||
karma::rule<OutputIterator, geometry::multi_polygon<coord_type>()> multi_polygon;
|
||||
karma::rule<OutputIterator, geometry::multi_polygon<coord_type>()> multi_polygon_coord;
|
||||
karma::rule<OutputIterator, geometry::geometry_collection<coord_type>()> geometry_collection;
|
||||
karma::rule<OutputIterator, geometry::geometry_collection<coord_type>()> geometries;
|
||||
//
|
||||
karma::real_generator<coord_type, detail::json_coordinate_policy<coord_type> > coordinate;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -22,60 +22,33 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/json/geometry_generator_grammar.hpp>
|
||||
#include <mapnik/util/spirit_transform_attribute.hpp>
|
||||
#include <mapnik/geometry_types.hpp>
|
||||
#include <mapnik/geometry_fusion_adapted.hpp>
|
||||
#include <mapnik/geometry/fusion_adapted.hpp>
|
||||
|
||||
// boost
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/karma.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/spirit/include/phoenix_fusion.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace karma = boost::spirit::karma;
|
||||
namespace phoenix = boost::phoenix;
|
||||
|
||||
template <typename OutputIterator, typename Geometry>
|
||||
geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar()
|
||||
: geometry_generator_grammar::base_type(geometry)
|
||||
{
|
||||
boost::spirit::karma::_val_type _val;
|
||||
boost::spirit::karma::_1_type _1;
|
||||
boost::spirit::karma::_a_type _a;
|
||||
boost::spirit::karma::lit_type lit;
|
||||
boost::spirit::karma::uint_type uint_;
|
||||
boost::spirit::karma::eps_type eps;
|
||||
|
||||
geometry = geometry_dispatch.alias()
|
||||
;
|
||||
|
||||
geometry_dispatch = eps[_a = geometry_type(_val)] <<
|
||||
(&uint_(geometry::geometry_types::Point)[_1 = _a]
|
||||
<< (point | lit("null")))
|
||||
geometry =
|
||||
point
|
||||
|
|
||||
(&uint_(geometry::geometry_types::LineString)[_1 = _a]
|
||||
<< (linestring | lit("null")))
|
||||
linestring
|
||||
|
|
||||
(&uint_(geometry::geometry_types::Polygon)[_1 = _a]
|
||||
<< (polygon | lit("null")))
|
||||
polygon
|
||||
|
|
||||
(&uint_(geometry::geometry_types::MultiPoint)[_1 = _a]
|
||||
<< (multi_point | lit("null")))
|
||||
multi_point
|
||||
|
|
||||
(&uint_(geometry::geometry_types::MultiLineString)[_1 = _a]
|
||||
<< (multi_linestring | lit("null")))
|
||||
multi_linestring
|
||||
|
|
||||
(&uint_(geometry::geometry_types::MultiPolygon)[_1 = _a]
|
||||
<< (multi_polygon | lit("null")))
|
||||
multi_polygon
|
||||
|
|
||||
(&uint_(geometry::geometry_types::GeometryCollection)[_1 = _a]
|
||||
<< (geometry_collection | lit("null")))
|
||||
geometry_collection
|
||||
|
|
||||
lit("null")
|
||||
;
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_GEOMETRY_GRAMMAR_HPP
|
||||
#define MAPNIK_GEOMETRY_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/geometry.hpp> // for geometry_type
|
||||
#include <mapnik/make_unique.hpp>
|
||||
#include <mapnik/json/generic_json.hpp>
|
||||
#include <mapnik/json/positions_grammar.hpp>
|
||||
#include <mapnik/json/geometry_util.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
|
||||
template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
|
||||
struct geometry_grammar :
|
||||
qi::grammar<Iterator, mapnik::geometry::geometry<double>() ,space_type>
|
||||
{
|
||||
geometry_grammar();
|
||||
qi::rule<Iterator, mapnik::geometry::geometry<double>(), space_type> start;
|
||||
qi::rule<Iterator, qi::locals<int, mapnik::json::coordinates>, mapnik::geometry::geometry<double>(), space_type> geometry;
|
||||
qi::rule<Iterator, void(int&, mapnik::json::coordinates&, mapnik::geometry::geometry<double>&), space_type> geometry_part;
|
||||
qi::rule<Iterator, mapnik::geometry::geometry_collection<double>(), space_type> geometry_collection;
|
||||
qi::symbols<char, int> geometry_type_dispatch;
|
||||
positions_grammar<Iterator> coordinates;
|
||||
boost::phoenix::function<create_geometry_impl> create_geometry;
|
||||
// generic JSON
|
||||
generic_json<Iterator> json_;
|
||||
// error handler
|
||||
ErrorHandler error_handler;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_GEOMETRY_GRAMMAR_HPP
|
|
@ -1,94 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/json/error_handler.hpp>
|
||||
#include <mapnik/json/geometry_grammar.hpp>
|
||||
#include <mapnik/geometry_fusion_adapted.hpp>
|
||||
// boost
|
||||
#include <boost/spirit/include/phoenix_stl.hpp>
|
||||
#include <boost/spirit/include/phoenix_function.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
template <typename Iterator, typename ErrorHandler >
|
||||
geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
|
||||
: geometry_grammar::base_type(start,"geometry"),
|
||||
coordinates(error_handler)
|
||||
{
|
||||
qi::lit_type lit;
|
||||
qi::int_type int_;
|
||||
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::_a_type _a;
|
||||
qi::_b_type _b;
|
||||
qi::_r1_type _r1;
|
||||
qi::_r2_type _r2;
|
||||
qi::_r3_type _r3;
|
||||
qi::eps_type eps;
|
||||
using qi::fail;
|
||||
using qi::on_error;
|
||||
using phoenix::push_back;
|
||||
|
||||
start = geometry.alias() | lit("null");
|
||||
|
||||
geometry = lit('{')[_a = 0]
|
||||
> (geometry_part(_a, _b, _val) % lit(','))[create_geometry(_val, _a, _b)]
|
||||
> lit('}');
|
||||
|
||||
geometry_part = ((lit("\"type\"") > lit(':') > geometry_type_dispatch[_r1 = _1])
|
||||
|
|
||||
(lit("\"coordinates\"") > lit(':') > coordinates[_r2 = _1])
|
||||
|
|
||||
(lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[_r3 = _1] > lit(']'))
|
||||
|
|
||||
json_.key_value)
|
||||
;
|
||||
|
||||
geometry_collection = geometry[push_back(_val, _1)] % lit(',')
|
||||
;
|
||||
geometry_type_dispatch.add
|
||||
("\"Point\"",1)
|
||||
("\"LineString\"",2)
|
||||
("\"Polygon\"",3)
|
||||
("\"MultiPoint\"",4)
|
||||
("\"MultiLineString\"",5)
|
||||
("\"MultiPolygon\"",6)
|
||||
("\"GeometryCollection\"",7)
|
||||
;
|
||||
|
||||
// give some rules names
|
||||
geometry.name("Geometry");
|
||||
geometry_collection.name("GeometryCollection");
|
||||
geometry_type_dispatch.name("type: (Point|LineString|Polygon|MultiPoint|MultiLineString|MultiPolygon|GeometryCollection)");
|
||||
coordinates.name("coordinates");
|
||||
// error handler
|
||||
auto error_handler_function = boost::phoenix::function<ErrorHandler>(error_handler);
|
||||
on_error<fail>(start, error_handler_function(_1, _2, _3, _4));
|
||||
}
|
||||
|
||||
}}
|
120
include/mapnik/json/json_grammar_config.hpp
Normal file
120
include/mapnik/json/json_grammar_config.hpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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 <mapnik/feature.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <boost/bimap.hpp>
|
||||
#include <boost/bimap/set_of.hpp>
|
||||
#include <boost/bimap/unordered_set_of.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
enum well_known_names
|
||||
{
|
||||
id = 1,
|
||||
type,
|
||||
features,
|
||||
geometry,
|
||||
coordinates,
|
||||
properties
|
||||
};
|
||||
|
||||
constexpr char const* wkn_to_string(well_known_names val)
|
||||
{
|
||||
switch(val)
|
||||
{
|
||||
case id: return "id";
|
||||
case type: return "type";
|
||||
case features: return "features";
|
||||
case geometry: return "geometry";
|
||||
case coordinates: return "coordinates";
|
||||
case properties: return "properties";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
using keys_map = boost::bimap<boost::bimaps::unordered_set_of<std::string>,
|
||||
boost::bimaps::set_of<int>>;
|
||||
|
||||
inline keys_map get_keys()
|
||||
{
|
||||
keys_map keys = boost::assign::list_of<keys_map::relation>
|
||||
("type", well_known_names::type)
|
||||
("features", well_known_names::features)
|
||||
("geometry", well_known_names::geometry)
|
||||
("coordinates", well_known_names::coordinates)
|
||||
("properties", well_known_names::properties)
|
||||
("id", well_known_names::id)
|
||||
;
|
||||
return keys;
|
||||
}
|
||||
|
||||
namespace grammar {
|
||||
|
||||
struct keys_tag;
|
||||
struct transcoder_tag;
|
||||
struct feature_tag;
|
||||
|
||||
namespace x3 = boost::spirit::x3;
|
||||
using space_type = x3::standard::space_type;
|
||||
using iterator_type = char const*;
|
||||
|
||||
using phrase_parse_context_type = x3::phrase_parse_context<space_type>::type;
|
||||
using context_type = x3::with_context<keys_tag,
|
||||
std::reference_wrapper<keys_map> const,
|
||||
phrase_parse_context_type>::type;
|
||||
|
||||
using geometry_context_type = x3::with_context<feature_tag,
|
||||
std::reference_wrapper<mapnik::feature_impl> const,
|
||||
phrase_parse_context_type>::type;
|
||||
|
||||
using feature_context_type = x3::with_context<transcoder_tag,
|
||||
std::reference_wrapper<mapnik::transcoder> const,
|
||||
geometry_context_type>::type;
|
||||
|
||||
// our spirit x3 grammars needs this one with changed order of feature_impl and transcoder (??)
|
||||
using feature_context_const_type = x3::with_context<feature_tag,
|
||||
std::reference_wrapper<mapnik::feature_impl> const,
|
||||
x3::with_context<transcoder_tag,
|
||||
std::reference_wrapper<mapnik::transcoder const> const,
|
||||
phrase_parse_context_type>::type>::type;
|
||||
|
||||
// helper macro
|
||||
#define BOOST_SPIRIT_INSTANTIATE_UNUSED(rule_type, Iterator, Context) \
|
||||
template bool parse_rule<Iterator, Context, boost::spirit::x3::unused_type const>( \
|
||||
rule_type rule_ \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, boost::spirit::x3::unused_type const& ); \
|
||||
/***/
|
||||
|
||||
}}}
|
||||
|
||||
#endif // MAPNIK_JSON_GRAMMAR_CONFIG_HPP
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2015 Artem Pavlenko
|
||||
* 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
|
||||
|
@ -20,10 +20,22 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/json/feature_collection_grammar_impl.hpp>
|
||||
#include <string>
|
||||
|
||||
using iterator_type = char const*;
|
||||
template struct mapnik::json::feature_collection_grammar<iterator_type,mapnik::feature_impl, mapnik::json::default_feature_callback> ;
|
||||
template struct mapnik::json::feature_grammar_callback<iterator_type,mapnik::feature_impl, mapnik::json::default_feature_callback> ;
|
||||
#ifndef MAPNIK_JSON_PARSE_FEATURE_HPP
|
||||
#define MAPNIK_JSON_PARSE_FEATURE_HPP
|
||||
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
template <typename Iterator>
|
||||
void parse_feature(Iterator start, Iterator end, feature_impl& feature, mapnik::transcoder const& tr = mapnik::transcoder("utf8"));
|
||||
|
||||
template <typename Iterator>
|
||||
void parse_geometry(Iterator start, Iterator end, feature_impl& feature);
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif // MAPNIK_JSON_PARSE_FEATURE_HPP
|
|
@ -1,55 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_POSITIONS_GRAMMAR_HPP
|
||||
#define MAPNIK_JSON_POSITIONS_GRAMMAR_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/json/positions.hpp>
|
||||
#include <mapnik/json/error_handler.hpp>
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace standard = boost::spirit::standard;
|
||||
using space_type = standard::space_type;
|
||||
|
||||
template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
|
||||
struct positions_grammar :
|
||||
qi::grammar<Iterator,coordinates(),space_type>
|
||||
{
|
||||
positions_grammar(ErrorHandler & error_handler);
|
||||
qi::rule<Iterator, coordinates(),space_type> coords;
|
||||
qi::rule<Iterator, boost::optional<position>(), space_type> pos;
|
||||
qi::rule<Iterator, positions(), space_type> ring;
|
||||
qi::rule<Iterator, std::vector<positions>(), space_type> rings;
|
||||
qi::rule<Iterator, std::vector<std::vector<positions> >(), space_type> rings_array;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_JSON_POSITIONS_GRAMMAR_HPP
|
|
@ -1,97 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/json/positions_grammar.hpp>
|
||||
#include <mapnik/geometry_fusion_adapted.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/include/phoenix_function.hpp>
|
||||
// stl
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
struct set_position_impl
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename T0,typename T1>
|
||||
result_type operator() (T0 & coords, T1 const& pos) const
|
||||
{
|
||||
if (pos) coords = *pos;
|
||||
}
|
||||
};
|
||||
|
||||
struct push_position_impl
|
||||
{
|
||||
using result_type = void;
|
||||
template <typename T0, typename T1>
|
||||
result_type operator() (T0 & coords, T1 const& pos) const
|
||||
{
|
||||
if (pos) coords.emplace_back(*pos);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator, typename ErrorHandler>
|
||||
positions_grammar<Iterator, ErrorHandler>::positions_grammar(ErrorHandler & error_handler)
|
||||
: positions_grammar::base_type(coords,"coordinates")
|
||||
{
|
||||
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;
|
||||
using qi::fail;
|
||||
using qi::on_error;
|
||||
|
||||
boost::phoenix::function<set_position_impl> set_position;
|
||||
boost::phoenix::function<push_position_impl> push_position;
|
||||
|
||||
coords = rings_array[_val = _1] | rings [_val = _1] | ring[_val = _1] | pos[set_position(_val,_1)]
|
||||
;
|
||||
pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']')
|
||||
;
|
||||
ring = lit('[') >> pos[push_position(_val,_1)] % lit(',') > lit(']')
|
||||
;
|
||||
rings = lit('[') >> ring % lit(',') > lit(']')
|
||||
;
|
||||
rings_array = lit('[') >> rings % lit(',') > lit(']')
|
||||
;
|
||||
coords.name("Coordinates");
|
||||
pos.name("Position");
|
||||
ring.name("Ring");
|
||||
rings.name("Rings");
|
||||
rings_array.name("Rings array");
|
||||
|
||||
// error handler
|
||||
auto error_handler_function = boost::phoenix::function<ErrorHandler>(error_handler);
|
||||
on_error<fail>(coords, error_handler_function(_1, _2, _3, _4));
|
||||
}
|
||||
|
||||
}}
|
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
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2015 Artem Pavlenko
|
||||
* 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
|
||||
|
@ -30,10 +30,11 @@
|
|||
namespace mapnik { namespace json {
|
||||
|
||||
struct empty {};
|
||||
|
||||
using position = mapnik::geometry::point<double>;
|
||||
using positions = std::vector<position>;
|
||||
using coordinates = util::variant<empty, position, positions, std::vector<positions>, std::vector<std::vector<positions> > > ;
|
||||
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>;
|
||||
|
||||
}}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef MAPNIK_JSON_PROPERTIES_GENERATOR_GRAMMAR_HPP
|
||||
#define MAPNIK_JSON_PROPERTIES_GENERATOR_GRAMMAR_HPP
|
||||
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/value/types.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
|
|
|
@ -23,6 +23,14 @@
|
|||
|
||||
#include <mapnik/json/properties_generator_grammar.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
#include <boost/spirit/include/phoenix_fusion.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
namespace karma = boost::spirit::karma;
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
#include <mapnik/json/topology.hpp>
|
||||
#include <mapnik/json/attribute_value_visitor.hpp>
|
||||
#include <mapnik/feature_factory.hpp>
|
||||
#include <mapnik/geometry_adapters.hpp>
|
||||
#include <mapnik/geometry_correct.hpp>
|
||||
#include <mapnik/geometry/boost_adapters.hpp>
|
||||
#include <mapnik/geometry/correct.hpp>
|
||||
|
||||
namespace mapnik { namespace topojson {
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue