From 0f711c0863578a2a4c8a97116d953add7e535c84 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 11 Apr 2016 12:23:11 +0200 Subject: [PATCH 01/51] geometry - move point/line_string/polygon into separate headers --- include/mapnik/geometry.hpp | 80 ++----------------------- include/mapnik/geometry/line_string.hpp | 45 ++++++++++++++ include/mapnik/geometry/point.hpp | 54 +++++++++++++++++ include/mapnik/geometry/polygon.hpp | 76 +++++++++++++++++++++++ src/text/placements/list.cpp | 1 + 5 files changed, 181 insertions(+), 75 deletions(-) create mode 100644 include/mapnik/geometry/line_string.hpp create mode 100644 include/mapnik/geometry/point.hpp create mode 100644 include/mapnik/geometry/polygon.hpp diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 69c03e7a5..d2e3d2a42 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -23,88 +23,18 @@ #ifndef MAPNIK_GEOMETRY_HPP #define MAPNIK_GEOMETRY_HPP +// mapnik +#include +#include +#include #include +// stl #include #include #include namespace mapnik { namespace geometry { -template -struct point -{ - using value_type = T; - point() {} - point(T x_, T y_) - : x(x_), y(y_) - {} - - value_type x; - value_type y; -}; - -template -bool operator==(point const& lhs, point const& rhs) -{ - return lhs.x == rhs.x && lhs.y == rhs.y; -} - -template -bool operator!=(point const& lhs, point const& rhs) -{ - return !(lhs == rhs); -} - -template -struct line_string : std::vector > -{ - line_string() = default; - explicit line_string(std::size_t size) - : std::vector >(size) {} - inline std::size_t num_points() const { return std::vector>::size(); } - inline void add_coord(T x, T y) { std::vector>::template emplace_back(x,y);} -}; - -template -struct linear_ring : line_string -{ - linear_ring() = default; - explicit linear_ring(std::size_t size) - : line_string(size) {} - linear_ring(line_string && other) - : line_string(std::move(other)) {} - linear_ring(line_string const& other) - : line_string(other) {} -}; - -template -using rings_container = std::vector>; - -template class InteriorRings = rings_container> -struct polygon -{ - linear_ring exterior_ring; - using rings_container = InteriorRings; - rings_container interior_rings; - - inline void set_exterior_ring(linear_ring && ring) - { - exterior_ring = std::move(ring); - } - - inline void add_hole(linear_ring && ring) - { - interior_rings.emplace_back(std::move(ring)); - } - - inline bool empty() const { return exterior_ring.empty(); } - - inline std::size_t num_rings() const - { - return 1 + interior_rings.size(); - } -}; - template struct multi_point : line_string {}; diff --git a/include/mapnik/geometry/line_string.hpp b/include/mapnik/geometry/line_string.hpp new file mode 100644 index 000000000..8bf86c82f --- /dev/null +++ b/include/mapnik/geometry/line_string.hpp @@ -0,0 +1,45 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_GEOMETRY_LINE_STRING_HPP +#define MAPNIK_GEOMETRY_LINE_STRING_HPP + +// mapnik +#include +// stl +#include + +namespace mapnik { namespace geometry { + +template +struct line_string : std::vector > +{ + line_string() = default; + explicit line_string(std::size_t size) + : std::vector >(size) {} + inline std::size_t num_points() const { return std::vector>::size(); } + inline void add_coord(T x, T y) { std::vector>::template emplace_back(x,y);} +}; + +}} + +#endif // MAPNIK_GEOMETRY_LINE_STRING_HPP diff --git a/include/mapnik/geometry/point.hpp b/include/mapnik/geometry/point.hpp new file mode 100644 index 000000000..dba911b28 --- /dev/null +++ b/include/mapnik/geometry/point.hpp @@ -0,0 +1,54 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_GEOMETRY_POINT_HPP +#define MAPNIK_GEOMETRY_POINT_HPP + +namespace mapnik { namespace geometry { + +template +struct point +{ + using value_type = T; + point() {} + point(T x_, T y_) + : x(x_), y(y_) + {} + value_type x; + value_type y; +}; + +template +bool operator==(point const& lhs, point const& rhs) +{ + return lhs.x == rhs.x && lhs.y == rhs.y; +} + +template +bool operator!=(point const& lhs, point const& rhs) +{ + return lhs.x != rhs.x || lhs.y != rhs.y; +} + +}} + +#endif // MAPNIK_GEOMETRY_POINT_HPP diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp new file mode 100644 index 000000000..4ac744633 --- /dev/null +++ b/include/mapnik/geometry/polygon.hpp @@ -0,0 +1,76 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_GEOMETRY_POLYGON_HPP +#define MAPNIK_GEOMETRY_POLYGON_HPP + +// mapnik +#include + +// stl +#include + +namespace mapnik { namespace geometry { + +template +struct linear_ring : line_string +{ + linear_ring() = default; + explicit linear_ring(std::size_t size) + : line_string(size) {} + linear_ring(line_string && other) + : line_string(std::move(other)) {} + linear_ring(line_string const& other) + : line_string(other) {} +}; + +template +using rings_container = std::vector>; + +template class InteriorRings = rings_container> +struct polygon +{ + linear_ring exterior_ring; + using rings_container = InteriorRings; + rings_container interior_rings; + + inline void set_exterior_ring(linear_ring && ring) + { + exterior_ring = std::move(ring); + } + + inline void add_hole(linear_ring && ring) + { + interior_rings.emplace_back(std::move(ring)); + } + + inline bool empty() const { return exterior_ring.empty(); } + + inline std::size_t num_rings() const + { + return 1 + interior_rings.size(); + } +}; + +}} + +#endif // MAPNIK_GEOMETRY_POLYGON_HPP diff --git a/src/text/placements/list.cpp b/src/text/placements/list.cpp index 7d609f2c4..eab2b1664 100644 --- a/src/text/placements/list.cpp +++ b/src/text/placements/list.cpp @@ -95,6 +95,7 @@ text_placements_ptr text_placements_list::from_xml(xml_node const& node, fontset { auto list = std::make_shared(); list->defaults.from_xml(node, fontsets, is_shield); + int count = 0; for( auto const& child : node) { if (child.is_text() || !child.is("Placement")) continue; From fb385180cff6d2e46e9bb63034741ccfdaaa2770 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 12 Apr 2016 09:27:37 +0200 Subject: [PATCH 02/51] include what you need --- include/mapnik/geometry/fusion_adapted.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/geometry/fusion_adapted.hpp b/include/mapnik/geometry/fusion_adapted.hpp index e3bdd7ef8..8bc53046d 100644 --- a/include/mapnik/geometry/fusion_adapted.hpp +++ b/include/mapnik/geometry/fusion_adapted.hpp @@ -24,7 +24,7 @@ #ifndef MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP #define MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP -#include +#include #include BOOST_FUSION_ADAPT_STRUCT( From 2e0d83aa91f201e99c5f61316b71adecfa3aa39d Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 12 Apr 2016 10:12:16 +0200 Subject: [PATCH 03/51] geometry::multi_point - derive from std::vector> instead of line_string --- include/mapnik/geometry.hpp | 9 ++++++++- include/mapnik/geometry_reprojection_impl.hpp | 6 +++++- include/mapnik/proj_transform.hpp | 7 ++++--- include/mapnik/well_known_srs.hpp | 9 +++++---- src/proj_transform.cpp | 4 ++-- test/unit/geometry/geometry_equal.hpp | 11 +++++++++-- 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index d2e3d2a42..e94f760a2 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -36,7 +36,14 @@ namespace mapnik { namespace geometry { template -struct multi_point : line_string {}; +struct multi_point : std::vector> +{ + multi_point() = default; + explicit multi_point(std::size_t size) + : std::vector >(size) {} + inline std::size_t num_points() const { return std::vector>::size(); } + inline void add_coord(T x, T y) { std::vector>::template emplace_back(x,y);} +}; template struct multi_line_string : std::vector> {}; diff --git a/include/mapnik/geometry_reprojection_impl.hpp b/include/mapnik/geometry_reprojection_impl.hpp index ff01bd451..02b7846fd 100644 --- a/include/mapnik/geometry_reprojection_impl.hpp +++ b/include/mapnik/geometry_reprojection_impl.hpp @@ -332,7 +332,11 @@ struct geom_reproj_visitor { template bool operator() (multi_point & mp) const { - return (*this) (static_cast &>(mp)); + if (proj_trans_.forward(mp) > 0) + { + return false; + } + return true; } template diff --git a/include/mapnik/proj_transform.hpp b/include/mapnik/proj_transform.hpp index 3247a15e3..82b732f4b 100644 --- a/include/mapnik/proj_transform.hpp +++ b/include/mapnik/proj_transform.hpp @@ -26,12 +26,13 @@ // mapnik #include #include +// stl +#include namespace mapnik { namespace geometry { template struct point; -template struct line_string; } class projection; template class box2d; @@ -50,8 +51,8 @@ public: bool backward (double *x, double *y , double *z, int point_count, int offset = 1) const; bool forward (geometry::point & p) const; bool backward (geometry::point & p) const; - unsigned int forward (geometry::line_string & ls) const; - unsigned int backward (geometry::line_string & ls) const; + unsigned int forward (std::vector> & ls) const; + unsigned int backward (std::vector> & ls) const; bool forward (box2d & box) const; bool backward (box2d & box) const; bool forward (box2d & box, int points) const; diff --git a/include/mapnik/well_known_srs.hpp b/include/mapnik/well_known_srs.hpp index e8349e709..d175ef528 100644 --- a/include/mapnik/well_known_srs.hpp +++ b/include/mapnik/well_known_srs.hpp @@ -26,7 +26,7 @@ // mapnik #include // for M_PI on windows #include -#include +#include #pragma GCC diagnostic push #include @@ -35,6 +35,7 @@ // stl #include +#include namespace mapnik { @@ -93,9 +94,9 @@ static inline bool merc2lonlat(double * x, double * y , int point_count) return true; } -static inline bool lonlat2merc(geometry::line_string & ls) +static inline bool lonlat2merc(std::vector> & ls) { - for(auto & p : ls) + for (auto& p : ls) { if (p.x > 180) p.x = 180; else if (p.x < -180) p.x = -180; @@ -108,7 +109,7 @@ static inline bool lonlat2merc(geometry::line_string & ls) return true; } -static inline bool merc2lonlat(geometry::line_string & ls) +static inline bool merc2lonlat(std::vector> & ls) { for (auto & p : ls) { diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp index 108e3f97c..a418d5d21 100644 --- a/src/proj_transform.cpp +++ b/src/proj_transform.cpp @@ -102,7 +102,7 @@ bool proj_transform::forward (geometry::point & p) const return forward(&(p.x), &(p.y), &z, 1); } -unsigned int proj_transform::forward (geometry::line_string & ls) const +unsigned int proj_transform::forward (std::vector> & ls) const { std::size_t size = ls.size(); if (size == 0) return 0; @@ -242,7 +242,7 @@ bool proj_transform::backward (geometry::point & p) const return backward(&(p.x), &(p.y), &z, 1); } -unsigned int proj_transform::backward (geometry::line_string & ls) const +unsigned int proj_transform::backward (std::vector> & ls) const { std::size_t size = ls.size(); if (size == 0) return 0; diff --git a/test/unit/geometry/geometry_equal.hpp b/test/unit/geometry/geometry_equal.hpp index 4ff80abab..6a510ced0 100644 --- a/test/unit/geometry/geometry_equal.hpp +++ b/test/unit/geometry/geometry_equal.hpp @@ -119,7 +119,7 @@ struct geometry_equal_visitor } template - void operator() (line_string const& ls1, line_string const& ls2) const + void operator() (std::vector> const& ls1, std::vector> const& ls2) const { if (ls1.size() != ls2.size()) { @@ -149,12 +149,19 @@ struct geometry_equal_visitor } } + template + void operator() (line_string const& ls1, line_string const& ls2) const + { + (*this)(static_cast> const&>(ls1), static_cast> const&>(ls2)); + } + template void operator() (multi_point const& mp1, multi_point const& mp2) const { - (*this)(static_cast const&>(mp1), static_cast const&>(mp2)); + (*this)(static_cast> const&>(mp1), static_cast> const&>(mp2)); } + template void operator() (multi_line_string const& mls1, multi_line_string const& mls2) const { From 2106d7b16206cc82b1050eb0fa0dd788dcbc1280 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 12 Apr 2016 14:41:36 +0200 Subject: [PATCH 04/51] remove debug stderr --- src/text/placements/list.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/text/placements/list.cpp b/src/text/placements/list.cpp index eab2b1664..7d609f2c4 100644 --- a/src/text/placements/list.cpp +++ b/src/text/placements/list.cpp @@ -95,7 +95,6 @@ text_placements_ptr text_placements_list::from_xml(xml_node const& node, fontset { auto list = std::make_shared(); list->defaults.from_xml(node, fontsets, is_shield); - int count = 0; for( auto const& child : node) { if (child.is_text() || !child.is("Placement")) continue; From 271b70f960f66202fb07ad3d4cc3cbeb6a88fee2 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 12 Apr 2016 14:49:23 +0200 Subject: [PATCH 05/51] geometry - template on container type + move multi geometries into separate headers --- include/mapnik/geometry.hpp | 27 ++++------- include/mapnik/geometry/line_string.hpp | 12 +++-- include/mapnik/geometry/multi_line_string.hpp | 38 +++++++++++++++ include/mapnik/geometry/multi_point.hpp | 47 +++++++++++++++++++ include/mapnik/geometry/multi_polygon.hpp | 38 +++++++++++++++ 5 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 include/mapnik/geometry/multi_line_string.hpp create mode 100644 include/mapnik/geometry/multi_point.hpp create mode 100644 include/mapnik/geometry/multi_polygon.hpp diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index e94f760a2..558c2f3db 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -27,31 +27,20 @@ #include #include #include +#include +#include +#include +// #include // stl #include +#include #include #include namespace mapnik { namespace geometry { -template -struct multi_point : std::vector> -{ - multi_point() = default; - explicit multi_point(std::size_t size) - : std::vector >(size) {} - inline std::size_t num_points() const { return std::vector>::size(); } - inline void add_coord(T x, T y) { std::vector>::template emplace_back(x,y);} -}; - -template -struct multi_line_string : std::vector> {}; - -template -struct multi_polygon : std::vector> {}; - -template +template class Cont = std::vector> struct geometry_collection; struct geometry_empty {}; @@ -80,8 +69,8 @@ struct geometry : geometry_base }; -template -struct geometry_collection : std::vector> {}; +template class Cont> +struct geometry_collection : Cont> {}; }} diff --git a/include/mapnik/geometry/line_string.hpp b/include/mapnik/geometry/line_string.hpp index 8bf86c82f..681ee0405 100644 --- a/include/mapnik/geometry/line_string.hpp +++ b/include/mapnik/geometry/line_string.hpp @@ -30,14 +30,16 @@ namespace mapnik { namespace geometry { -template -struct line_string : std::vector > +template class Cont = std::vector> +struct line_string : Cont > { + using point_type = point; + using container_type = Cont; line_string() = default; explicit line_string(std::size_t size) - : std::vector >(size) {} - inline std::size_t num_points() const { return std::vector>::size(); } - inline void add_coord(T x, T y) { std::vector>::template emplace_back(x,y);} + : container_type(size) {} + inline std::size_t num_points() const { return container_type::size(); } + inline void add_coord(T x, T y) { container_type::template emplace_back(x,y);} }; }} diff --git a/include/mapnik/geometry/multi_line_string.hpp b/include/mapnik/geometry/multi_line_string.hpp new file mode 100644 index 000000000..fdd1b00a8 --- /dev/null +++ b/include/mapnik/geometry/multi_line_string.hpp @@ -0,0 +1,38 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_GEOMETRY_MULTI_LINE_STRING_HPP +#define MAPNIK_GEOMETRY_MULTI_LINE_STRING_HPP + +// mapnik +#include +// stl +#include + +namespace mapnik { namespace geometry { + +template class Cont = std::vector> +struct multi_line_string : Cont> {}; + +}} + +#endif // MAPNIK_GEOMETRY_MULTI_LINE_STRING_HPP diff --git a/include/mapnik/geometry/multi_point.hpp b/include/mapnik/geometry/multi_point.hpp new file mode 100644 index 000000000..4eaef2866 --- /dev/null +++ b/include/mapnik/geometry/multi_point.hpp @@ -0,0 +1,47 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_GEOMETRY_MULTI_POINT_HPP +#define MAPNIK_GEOMETRY_MULTI_POINT_HPP + +// mapnik +#include +// stl +#include + +namespace mapnik { namespace geometry { + +template class Cont = std::vector> +struct multi_point : Cont> +{ + using point_type = point; + using container_type = Cont; + multi_point() = default; + explicit multi_point(std::size_t size) + : container_type(size) {} + inline std::size_t num_points() const { return container_type::size(); } + inline void add_coord(T x, T y) { container_type::template emplace_back(x, y);} +}; + +}} + +#endif // MAPNIK_GEOMETRY_MULTI_POINT_HPP diff --git a/include/mapnik/geometry/multi_polygon.hpp b/include/mapnik/geometry/multi_polygon.hpp new file mode 100644 index 000000000..94e3e8287 --- /dev/null +++ b/include/mapnik/geometry/multi_polygon.hpp @@ -0,0 +1,38 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_GEOMETRY_MULTI_POLYGON_HPP +#define MAPNIK_GEOMETRY_MULTI_POLYGON_HPP + +// mapnik +#include +// stl +#include + +namespace mapnik { namespace geometry { + +template class Cont = std::vector> +struct multi_polygon : Cont> {}; + +}} + +#endif // MAPNIK_GEOMETRY_MULTI_POLYGON_HPP From 9caac23d3c823a9c91292f7c75384ba09525d21b Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 12 Apr 2016 14:56:32 +0200 Subject: [PATCH 06/51] remove bogus fwd decl --- include/mapnik/proj_strategy.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/mapnik/proj_strategy.hpp b/include/mapnik/proj_strategy.hpp index 064f3669b..a8366fc5a 100644 --- a/include/mapnik/proj_strategy.hpp +++ b/include/mapnik/proj_strategy.hpp @@ -35,13 +35,8 @@ #include #pragma GCC diagnostic pop - namespace mapnik { -namespace geometry { -template struct point; -template struct line_string; -} class projection; template class box2d; From 51069fe88a3d3844c04e6f7dc80a6dee38f24465 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 22 Apr 2016 12:50:32 +0200 Subject: [PATCH 07/51] c++ style : prefix increment --- src/text/symbolizer_helpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text/symbolizer_helpers.cpp b/src/text/symbolizer_helpers.cpp index 1d0fe48d2..c20f51c86 100644 --- a/src/text/symbolizer_helpers.cpp +++ b/src/text/symbolizer_helpers.cpp @@ -389,7 +389,7 @@ bool text_symbolizer_helper::next_point_placement() const return true; } //No placement for this point. Keep it in points_ for next try. - point_itr_++; + ++point_itr_; } return false; } From a89c3fc007fbf1d1d7a3223019c2bb57545ba610 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 22 Apr 2016 12:51:20 +0200 Subject: [PATCH 08/51] c++ - make bbox standalone method --- include/mapnik/text/placement_finder.hpp | 1 - src/text/placement_finder.cpp | 68 ++++++++++++------------ 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/include/mapnik/text/placement_finder.hpp b/include/mapnik/text/placement_finder.hpp index f35a5d50b..3b02d8924 100644 --- a/include/mapnik/text/placement_finder.hpp +++ b/include/mapnik/text/placement_finder.hpp @@ -78,7 +78,6 @@ private: // Maps upright==auto, left-only and right-only to left,right to simplify processing. // angle = angle of at start of line (to estimate best option for upright==auto) text_upright_e simplify_upright(text_upright_e upright, double angle) const; - box2d get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot); feature_impl const& feature_; attributes const& attr_; DetectorType & detector_; diff --git a/src/text/placement_finder.cpp b/src/text/placement_finder.cpp index 04a290757..e4adddf3e 100644 --- a/src/text/placement_finder.cpp +++ b/src/text/placement_finder.cpp @@ -39,6 +39,41 @@ namespace mapnik { +namespace { +box2d get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot) +{ + /* + + (0/ymax) (width/ymax) + *************** + * * + (0/0)* * + * * + *************** + (0/ymin) (width/ymin) + Add glyph offset in y direction, but not in x direction (as we use the full cluster width anyways)! + */ + double width = layout.cluster_width(glyph.char_index); + if (glyph.advance() <= 0) width = -width; + pixel_position tmp, tmp2; + tmp.set(0, glyph.ymax()); + tmp = tmp.rotate(rot); + tmp2.set(width, glyph.ymax()); + tmp2 = tmp2.rotate(rot); + box2d bbox(tmp.x, -tmp.y, + tmp2.x, -tmp2.y); + tmp.set(width, glyph.ymin()); + tmp = tmp.rotate(rot); + bbox.expand_to_include(tmp.x, -tmp.y); + tmp.set(0, glyph.ymin()); + tmp = tmp.rotate(rot); + bbox.expand_to_include(tmp.x, -tmp.y); + pixel_position pos2 = pos + pixel_position(0, glyph.offset.y).rotate(rot); + bbox.move(pos2.x , -pos2.y); + return bbox; +} +} // anonymous namespace + placement_finder::placement_finder(feature_impl const& feature, attributes const& attr, DetectorType &detector, @@ -432,37 +467,4 @@ bool placement_finder::add_marker(glyph_positions_ptr & glyphs, pixel_position c return true; } -box2d placement_finder::get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot) -{ - /* - - (0/ymax) (width/ymax) - *************** - * * - (0/0)* * - * * - *************** - (0/ymin) (width/ymin) - Add glyph offset in y direction, but not in x direction (as we use the full cluster width anyways)! - */ - double width = layout.cluster_width(glyph.char_index); - if (glyph.advance() <= 0) width = -width; - pixel_position tmp, tmp2; - tmp.set(0, glyph.ymax()); - tmp = tmp.rotate(rot); - tmp2.set(width, glyph.ymax()); - tmp2 = tmp2.rotate(rot); - box2d bbox(tmp.x, -tmp.y, - tmp2.x, -tmp2.y); - tmp.set(width, glyph.ymin()); - tmp = tmp.rotate(rot); - bbox.expand_to_include(tmp.x, -tmp.y); - tmp.set(0, glyph.ymin()); - tmp = tmp.rotate(rot); - bbox.expand_to_include(tmp.x, -tmp.y); - pixel_position pos2 = pos + pixel_position(0, glyph.offset.y).rotate(rot); - bbox.move(pos2.x , -pos2.y); - return bbox; -} - }// ns mapnik From 31840344149c783b370bf09653b6ba0c5ab8b10c Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 29 Apr 2016 14:24:57 +0200 Subject: [PATCH 09/51] refactor geometry core and algorithms templates + add missing typedefs + prepare for geometry update --- include/mapnik/feature.hpp | 2 +- include/mapnik/geometry.hpp | 16 +++-- include/mapnik/geometry/line_string.hpp | 5 +- include/mapnik/geometry/multi_line_string.hpp | 5 +- include/mapnik/geometry/multi_point.hpp | 3 +- include/mapnik/geometry/multi_polygon.hpp | 5 +- include/mapnik/geometry/point.hpp | 6 +- include/mapnik/geometry/polygon.hpp | 4 +- include/mapnik/geometry_centroid.hpp | 6 +- include/mapnik/geometry_envelope.hpp | 4 +- include/mapnik/geometry_envelope_impl.hpp | 27 ++++---- include/mapnik/geometry_is_empty.hpp | 64 ++++++++++--------- include/mapnik/geometry_is_simple.hpp | 21 +++--- include/mapnik/geometry_is_valid.hpp | 57 ++++++----------- include/mapnik/geometry_reprojection_impl.hpp | 14 ++-- include/mapnik/geometry_to_path.hpp | 17 ++--- include/mapnik/geometry_transform.hpp | 5 +- include/mapnik/geometry_type.hpp | 16 ++--- include/mapnik/hit_test_filter.hpp | 2 +- include/mapnik/text/symbolizer_helpers.hpp | 5 ++ include/mapnik/util/geometry_to_ds_type.hpp | 2 +- include/mapnik/util/geometry_to_wkb.hpp | 2 +- include/mapnik/vertex_adapters.hpp | 19 +++--- include/mapnik/vertex_processor.hpp | 3 +- include/mapnik/wkt/wkt_generator_grammar.hpp | 2 +- .../mapnik/wkt/wkt_generator_grammar_impl.hpp | 2 +- include/mapnik/wkt/wkt_grammar_impl.hpp | 2 +- plugins/input/csv/csv_featureset.cpp | 2 +- plugins/input/csv/csv_index_featureset.cpp | 2 +- plugins/input/csv/csv_inline_featureset.cpp | 2 +- plugins/input/csv/csv_utils.cpp | 2 +- src/box2d.cpp | 1 + src/geometry_envelope.cpp | 23 +++---- src/geometry_reprojection.cpp | 8 +-- src/text/symbolizer_helpers.cpp | 36 ++++++++++- src/twkb.cpp | 2 +- src/vertex_adapters.cpp | 8 +-- src/wkb.cpp | 2 +- test/unit/datasource/ds_test_util.hpp | 43 +++++++------ test/unit/geometry/centroid.cpp | 3 +- test/unit/geometry/geometry_envelope_test.cpp | 3 +- test/unit/geometry/geometry_equal.hpp | 3 +- test/unit/geometry/geometry_is_simple.cpp | 45 +++++++------ test/unit/geometry/geometry_is_valid.cpp | 3 +- test/unit/geometry/geometry_reprojection.cpp | 25 ++++---- test/unit/geometry/has_empty.cpp | 5 +- test/unit/geometry/is_empty.cpp | 5 +- test/unit/serialization/wkb_formats_test.cpp | 4 +- test/unit/serialization/wkb_test.cpp | 2 +- 49 files changed, 279 insertions(+), 266 deletions(-) diff --git a/include/mapnik/feature.hpp b/include/mapnik/feature.hpp index f340c83d6..3b7dafac1 100644 --- a/include/mapnik/feature.hpp +++ b/include/mapnik/feature.hpp @@ -105,7 +105,7 @@ public: : id_(_id), ctx_(ctx), data_(ctx_->mapping_.size()), - geom_(geometry::geometry_empty()), + geom_(geometry::geometry_empty()), raster_() {} inline mapnik::value_integer id() const { return id_;} diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 558c2f3db..6c0322ebf 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -43,11 +43,15 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct geometry_collection; -struct geometry_empty {}; +template +struct geometry_empty +{ + using coord_type = T; +}; template -using geometry_base = mapnik::util::variant, point, line_string, polygon, @@ -58,8 +62,7 @@ using geometry_base = mapnik::util::variant struct geometry : geometry_base { - using value_type = T; - + using coord_type = T; geometry() : geometry_base() {} // empty @@ -70,7 +73,10 @@ struct geometry : geometry_base }; template class Cont> -struct geometry_collection : Cont> {}; +struct geometry_collection : Cont> +{ + using coord_type = T; +}; }} diff --git a/include/mapnik/geometry/line_string.hpp b/include/mapnik/geometry/line_string.hpp index 681ee0405..b614c5b75 100644 --- a/include/mapnik/geometry/line_string.hpp +++ b/include/mapnik/geometry/line_string.hpp @@ -33,13 +33,14 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct line_string : Cont > { - using point_type = point; + using coord_type = T; + using point_type = point; using container_type = Cont; line_string() = default; explicit line_string(std::size_t size) : container_type(size) {} inline std::size_t num_points() const { return container_type::size(); } - inline void add_coord(T x, T y) { container_type::template emplace_back(x,y);} + inline void add_coord(coord_type x, coord_type y) { container_type::template emplace_back(x,y);} }; }} diff --git a/include/mapnik/geometry/multi_line_string.hpp b/include/mapnik/geometry/multi_line_string.hpp index fdd1b00a8..ca08726d3 100644 --- a/include/mapnik/geometry/multi_line_string.hpp +++ b/include/mapnik/geometry/multi_line_string.hpp @@ -31,7 +31,10 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> -struct multi_line_string : Cont> {}; +struct multi_line_string : Cont> +{ + using coord_type = T; +}; }} diff --git a/include/mapnik/geometry/multi_point.hpp b/include/mapnik/geometry/multi_point.hpp index 4eaef2866..0ca018b4c 100644 --- a/include/mapnik/geometry/multi_point.hpp +++ b/include/mapnik/geometry/multi_point.hpp @@ -33,7 +33,8 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct multi_point : Cont> { - using point_type = point; + using coord_type = T; + using point_type = point; using container_type = Cont; multi_point() = default; explicit multi_point(std::size_t size) diff --git a/include/mapnik/geometry/multi_polygon.hpp b/include/mapnik/geometry/multi_polygon.hpp index 94e3e8287..f197ddf79 100644 --- a/include/mapnik/geometry/multi_polygon.hpp +++ b/include/mapnik/geometry/multi_polygon.hpp @@ -31,7 +31,10 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> -struct multi_polygon : Cont> {}; +struct multi_polygon : Cont> +{ + using coord_type = T; +}; }} diff --git a/include/mapnik/geometry/point.hpp b/include/mapnik/geometry/point.hpp index dba911b28..5cf6e3795 100644 --- a/include/mapnik/geometry/point.hpp +++ b/include/mapnik/geometry/point.hpp @@ -28,13 +28,13 @@ namespace mapnik { namespace geometry { template struct point { - using value_type = T; + using coord_type = T; point() {} point(T x_, T y_) : x(x_), y(y_) {} - value_type x; - value_type y; + coord_type x; + coord_type y; }; template diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp index 4ac744633..e1ce1e6dc 100644 --- a/include/mapnik/geometry/polygon.hpp +++ b/include/mapnik/geometry/polygon.hpp @@ -34,6 +34,7 @@ namespace mapnik { namespace geometry { template struct linear_ring : line_string { + using coord_type = T; linear_ring() = default; explicit linear_ring(std::size_t size) : line_string(size) {} @@ -49,8 +50,9 @@ using rings_container = std::vector>; template class InteriorRings = rings_container> struct polygon { + using coord_type = T; + using rings_container = InteriorRings; linear_ring exterior_ring; - using rings_container = InteriorRings; rings_container interior_rings; inline void set_exterior_ring(linear_ring && ring) diff --git a/include/mapnik/geometry_centroid.hpp b/include/mapnik/geometry_centroid.hpp index 590ba4898..5dc7735b1 100644 --- a/include/mapnik/geometry_centroid.hpp +++ b/include/mapnik/geometry_centroid.hpp @@ -41,13 +41,13 @@ struct geometry_centroid geometry_centroid(point & pt) : pt_(pt) {} - template - result_type operator() (T1 const& geom) const + template + result_type operator() (U const& geom) const { return util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const&) const + result_type operator() (geometry_empty const&) const { return false; } diff --git a/include/mapnik/geometry_envelope.hpp b/include/mapnik/geometry_envelope.hpp index 17b8fcb44..981b97849 100644 --- a/include/mapnik/geometry_envelope.hpp +++ b/include/mapnik/geometry_envelope.hpp @@ -26,11 +26,11 @@ #include #include -namespace mapnik { +namespace mapnik { namespace geometry { template -MAPNIK_DECL mapnik::box2d envelope(T const& geom); +MAPNIK_DECL auto envelope(T const& geom) -> box2d; } // end ns geometry } // end ns mapnik diff --git a/include/mapnik/geometry_envelope_impl.hpp b/include/mapnik/geometry_envelope_impl.hpp index 5c39bc386..0e539675d 100644 --- a/include/mapnik/geometry_envelope_impl.hpp +++ b/include/mapnik/geometry_envelope_impl.hpp @@ -28,23 +28,24 @@ namespace mapnik { namespace geometry { namespace detail { +template struct geometry_envelope { - using bbox_type = box2d; + using coord_type = T; + using bbox_type = box2d; bbox_type & bbox; - geometry_envelope(bbox_type & bbox_) + explicit geometry_envelope(bbox_type & bbox_) : bbox(bbox_) {} - template - void operator() (T const& geom) const + template + void operator() (U const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - void operator() (mapnik::geometry::geometry_empty const&) const {} + void operator() (mapnik::geometry::geometry_empty const&) const {} - template void operator() (mapnik::geometry::point const& pt) const { if (!bbox.valid()) @@ -54,7 +55,6 @@ struct geometry_envelope bbox.expand_to_include(pt.x, pt.y); } - template void operator() (mapnik::geometry::line_string const& line) const { bool first = true; @@ -72,13 +72,11 @@ struct geometry_envelope } } - template void operator() (mapnik::geometry::linear_ring const& ring) const { (*this)(static_cast const&>(ring)); } - template void operator() (mapnik::geometry::polygon const& poly) const { bool first = true; @@ -96,7 +94,6 @@ struct geometry_envelope } } - template void operator() (mapnik::geometry::multi_point const& multi_point) const { bool first = true; @@ -114,7 +111,6 @@ struct geometry_envelope } } - template void operator() (mapnik::geometry::multi_line_string const& multi_line) const { for (auto const& line : multi_line) @@ -123,7 +119,6 @@ struct geometry_envelope } } - template void operator() (mapnik::geometry::multi_polygon const& multi_poly) const { for (auto const& poly : multi_poly) @@ -132,7 +127,6 @@ struct geometry_envelope } } - template void operator() (mapnik::geometry::geometry_collection const& collection) const { for (auto const& geom : collection) @@ -145,10 +139,11 @@ struct geometry_envelope } // end ns detail template -mapnik::box2d envelope(T const& geom) +auto envelope(T const& geom) -> box2d { - box2d bbox; - detail::geometry_envelope op(bbox); + using coord_type = typename T::coord_type; + box2d bbox; + detail::geometry_envelope op(bbox); op(geom); return bbox; } diff --git a/include/mapnik/geometry_is_empty.hpp b/include/mapnik/geometry_is_empty.hpp index 953bddc22..d70e506d9 100644 --- a/include/mapnik/geometry_is_empty.hpp +++ b/include/mapnik/geometry_is_empty.hpp @@ -29,103 +29,105 @@ namespace mapnik { namespace geometry { namespace detail { +template struct geometry_is_empty { - bool operator() (mapnik::geometry::geometry const& geom) const + bool operator() (mapnik::geometry::geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - bool operator() (mapnik::geometry::point const&) const + bool operator() (mapnik::geometry::point const&) const { return false; } - bool operator() (mapnik::geometry::line_string const& geom) const + bool operator() (mapnik::geometry::line_string const& geom) const { return geom.empty(); } - bool operator() (mapnik::geometry::polygon const& geom) const + bool operator() (mapnik::geometry::polygon const& geom) const { return geom.empty(); } - bool operator() (mapnik::geometry::multi_point const& geom) const + bool operator() (mapnik::geometry::multi_point const& geom) const { return geom.empty(); } - bool operator() (mapnik::geometry::multi_line_string const& geom) const + bool operator() (mapnik::geometry::multi_line_string const& geom) const { return geom.empty(); } - bool operator() (mapnik::geometry::multi_polygon const& geom) const + bool operator() (mapnik::geometry::multi_polygon const& geom) const { return geom.empty(); } - bool operator() (mapnik::geometry::geometry_collection const& geom) const + bool operator() (mapnik::geometry::geometry_collection const& geom) const { return geom.empty(); } - template - bool operator() (T const&) const + template + bool operator() (U const&) const { return true; } }; +template struct geometry_has_empty { - bool operator() (mapnik::geometry::geometry const& geom) const + bool operator() (mapnik::geometry::geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - bool operator() (mapnik::geometry::geometry_empty const&) const + bool operator() (mapnik::geometry::geometry_empty const&) const { return false; } - bool operator() (mapnik::geometry::point const&) const + bool operator() (mapnik::geometry::point const&) const { return false; } - bool operator() (mapnik::geometry::line_string const&) const + bool operator() (mapnik::geometry::line_string const&) const { return false; } - bool operator() (mapnik::geometry::polygon const&) const + bool operator() (mapnik::geometry::polygon const&) const { return false; } - bool operator() (mapnik::geometry::multi_point const&) const + bool operator() (mapnik::geometry::multi_point const&) const { return false; } - bool operator() (mapnik::geometry::multi_line_string const& geom) const + bool operator() (mapnik::geometry::multi_line_string const& geom) const { return test_multigeometry(geom); } - bool operator() (mapnik::geometry::multi_polygon const& geom) const + bool operator() (mapnik::geometry::multi_polygon const& geom) const { return test_multigeometry(geom); } - bool operator() (mapnik::geometry::geometry_collection const& geom) const + bool operator() (mapnik::geometry::geometry_collection const& geom) const { for (auto const & item : geom) { - if (geometry_is_empty()(item) || (*this)(item)) + if (geometry_is_empty()(item) || (*this)(item)) { return true; } @@ -133,15 +135,15 @@ struct geometry_has_empty return false; } - template - bool operator() (T const&) const + template + bool operator() (U const&) const { return true; } private: - template - bool test_multigeometry(T const & geom) const + template + bool test_multigeometry(U const & geom) const { for (auto const & item : geom) { @@ -156,16 +158,18 @@ private: } -template -inline bool is_empty(GeomType const& geom) +template +inline bool is_empty(G const& geom) { - return detail::geometry_is_empty()(geom); + using coord_type = typename G::coord_type; + return detail::geometry_is_empty()(geom); } -template -inline bool has_empty(GeomType const& geom) +template +inline bool has_empty(G const& geom) { - return detail::geometry_has_empty()(geom); + using coord_type = typename G::coord_type; + return detail::geometry_has_empty()(geom); } }} diff --git a/include/mapnik/geometry_is_simple.hpp b/include/mapnik/geometry_is_simple.hpp index 868b41afd..b5e7038a5 100644 --- a/include/mapnik/geometry_is_simple.hpp +++ b/include/mapnik/geometry_is_simple.hpp @@ -36,24 +36,23 @@ namespace mapnik { namespace geometry { namespace detail { +template struct geometry_is_simple { using result_type = bool; - template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { // An empty geometry has no anomalous geometric points, such as self intersection or self tangency. // Therefore, we will return true return true; } - template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -63,12 +62,11 @@ struct geometry_is_simple return true; } - template result_type operator() (point const& pt) const { return boost::geometry::is_simple(pt); } - template + result_type operator() (line_string const& line) const { if (line.empty()) @@ -80,12 +78,12 @@ struct geometry_is_simple } return boost::geometry::is_simple(line); } - template + result_type operator() (polygon const& poly) const { return boost::geometry::is_simple(poly); } - template + result_type operator() (multi_point const& multi_pt) const { if (multi_pt.empty()) @@ -96,7 +94,7 @@ struct geometry_is_simple } return boost::geometry::is_simple(multi_pt); } - template + result_type operator() (multi_line_string const& multi_line) const { if (multi_line.empty()) @@ -111,7 +109,7 @@ struct geometry_is_simple } return true; } - template + result_type operator() (multi_polygon const& multi_poly) const { if (multi_poly.empty()) @@ -134,13 +132,14 @@ struct geometry_is_simple template inline bool is_simple(T const& geom) { - return detail::geometry_is_simple() (geom); + using coord_type = typename T::coord_type; + return detail::geometry_is_simple() (geom); } template inline bool is_simple(mapnik::geometry::geometry const& geom) { - return util::apply_visitor(detail::geometry_is_simple(), geom); + return util::apply_visitor(detail::geometry_is_simple(), geom); } }} diff --git a/include/mapnik/geometry_is_valid.hpp b/include/mapnik/geometry_is_valid.hpp index 95319cce9..33d702cde 100644 --- a/include/mapnik/geometry_is_valid.hpp +++ b/include/mapnik/geometry_is_valid.hpp @@ -37,22 +37,21 @@ namespace mapnik { namespace geometry { namespace detail { +template struct geometry_is_valid { using result_type = bool; - template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { return true; } - template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -62,65 +61,58 @@ struct geometry_is_valid return true; } - template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt); } - template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line); } - template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly); } - template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt); } - template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line); } - template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly); } }; +template 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): failure_(failure) {} - template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { failure_ = boost::geometry::no_failure; return true; } - template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -130,65 +122,58 @@ struct geometry_is_valid_reason return true; } - template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt, failure_); } - template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line, failure_); } - template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly, failure_); } - template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt, failure_); } - template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line, failure_); } - template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly, failure_); } }; +template struct geometry_is_valid_string { using result_type = bool; - + std::string & message_; geometry_is_valid_string(std::string & message): message_(message) {} - template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { message_ = "Geometry is valid"; return true; } - template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -198,82 +183,78 @@ struct geometry_is_valid_string return true; } - template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt, message_); } - template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line, message_); } - template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly, message_); } - template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt, message_); } - template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line, message_); } - template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly, message_); } }; - } template inline bool is_valid(T const& geom) { - return detail::geometry_is_valid() (geom); + using coord_type = typename T::coord_type; + return detail::geometry_is_valid() (geom); } template inline bool is_valid(mapnik::geometry::geometry const& geom) { - return util::apply_visitor(detail::geometry_is_valid(), geom); + return util::apply_visitor(detail::geometry_is_valid(), geom); } template inline bool is_valid(T const& geom, boost::geometry::validity_failure_type & failure) { - return detail::geometry_is_valid_reason(failure) (geom); + using coord_type = typename T::coord_type; + return detail::geometry_is_valid_reason(failure) (geom); } template -inline bool is_valid(mapnik::geometry::geometry const& geom, +inline bool is_valid(mapnik::geometry::geometry const& geom, boost::geometry::validity_failure_type & failure) { - return util::apply_visitor(detail::geometry_is_valid_reason(failure), geom); + return util::apply_visitor(detail::geometry_is_valid_reason(failure), geom); } template inline bool is_valid(T const& geom, std::string & message) { - return detail::geometry_is_valid_string(message) (geom); + using coord_type = typename T::coord_type; + return detail::geometry_is_valid_string(message) (geom); } template -inline bool is_valid(mapnik::geometry::geometry const& geom, +inline bool is_valid(mapnik::geometry::geometry const& geom, std::string & message) { - return util::apply_visitor(detail::geometry_is_valid_string(message), geom); + return util::apply_visitor(detail::geometry_is_valid_string(message), geom); } }} diff --git a/include/mapnik/geometry_reprojection_impl.hpp b/include/mapnik/geometry_reprojection_impl.hpp index 02b7846fd..7c20f6830 100644 --- a/include/mapnik/geometry_reprojection_impl.hpp +++ b/include/mapnik/geometry_reprojection_impl.hpp @@ -30,9 +30,10 @@ namespace geometry { namespace detail { -geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &) +template +geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &) { - return geometry_empty(); + return geometry_empty(); } template @@ -162,7 +163,7 @@ geometry_collection reproject_internal(geometry_collection const & c, proj { geometry new_g = reproject_copy(g, proj_trans, n_err); - if (!new_g.template is()) + if (!new_g.template is>()) { new_c.emplace_back(std::move(new_g)); } @@ -178,9 +179,9 @@ struct geom_reproj_copy_visitor : proj_trans_(proj_trans), n_err_(n_err) {} - geometry operator() (geometry_empty const&) const + geometry operator() (geometry_empty) const { - return geometry_empty(); + return geometry_empty(); } geometry operator() (point const& p) const @@ -289,7 +290,8 @@ struct geom_reproj_visitor { return mapnik::util::apply_visitor((*this), geom); } - bool operator() (geometry_empty &) const { return true; } + template + bool operator() (geometry_empty &) const { return true; } template bool operator() (point & p) const diff --git a/include/mapnik/geometry_to_path.hpp b/include/mapnik/geometry_to_path.hpp index d443158a6..75208adb3 100644 --- a/include/mapnik/geometry_to_path.hpp +++ b/include/mapnik/geometry_to_path.hpp @@ -28,24 +28,22 @@ namespace mapnik { namespace geometry { namespace detail { -//template +template struct geometry_to_path { geometry_to_path(path_type & p) : p_(p) {} - template void operator() (geometry const& geom) const { mapnik::util::apply_visitor(*this, geom); } - void operator() (geometry_empty const&) const + void operator() (geometry_empty const&) const { // no-op } // point - template void operator() (point const& pt) const { //point pt_new; @@ -54,7 +52,6 @@ struct geometry_to_path } // line_string - template void operator() (line_string const& line) const { bool first = true; @@ -68,7 +65,6 @@ struct geometry_to_path } // polygon - template void operator() (polygon const& poly) const { // exterior @@ -112,7 +108,6 @@ struct geometry_to_path } // multi point - template void operator() (multi_point const& multi_pt) const { for (auto const& pt : multi_pt) @@ -121,7 +116,6 @@ struct geometry_to_path } } // multi_line_string - template void operator() (multi_line_string const& multi_line) const { for (auto const& line : multi_line) @@ -131,7 +125,6 @@ struct geometry_to_path } // multi_polygon - template void operator() (multi_polygon const& multi_poly) const { for (auto const& poly : multi_poly) @@ -139,8 +132,7 @@ struct geometry_to_path (*this)(poly); } } - - template + // geometry_collection void operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -157,7 +149,8 @@ struct geometry_to_path template void to_path(T const& geom, path_type & p) { - detail::geometry_to_path func(p); + using coord_type = typename T::coord_type; + detail::geometry_to_path func(p); func(geom); } diff --git a/include/mapnik/geometry_transform.hpp b/include/mapnik/geometry_transform.hpp index a7bb2f13d..4004d6083 100644 --- a/include/mapnik/geometry_transform.hpp +++ b/include/mapnik/geometry_transform.hpp @@ -103,9 +103,10 @@ struct geometry_transform using result_type = geometry; - geometry operator() (geometry_empty const& empty) const + template + geometry operator() (geometry_empty const& empty) const { - return empty; + return geometry_empty(); } template diff --git a/include/mapnik/geometry_type.hpp b/include/mapnik/geometry_type.hpp index b052446cd..b231c1a8e 100644 --- a/include/mapnik/geometry_type.hpp +++ b/include/mapnik/geometry_type.hpp @@ -29,56 +29,49 @@ namespace mapnik { namespace geometry { namespace detail { +template struct geometry_type { - template - mapnik::geometry::geometry_types operator () (T const& geom) const + mapnik::geometry::geometry_types operator () (mapnik::geometry::geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - mapnik::geometry::geometry_types operator() (geometry_empty const& ) const + mapnik::geometry::geometry_types operator() (geometry_empty const& ) const { return mapnik::geometry::geometry_types::Unknown; } - template mapnik::geometry::geometry_types operator () (mapnik::geometry::point const&) const { return mapnik::geometry::geometry_types::Point; } - template mapnik::geometry::geometry_types operator () (mapnik::geometry::line_string const&) const { return mapnik::geometry::geometry_types::LineString; } - template mapnik::geometry::geometry_types operator () (mapnik::geometry::polygon const&) const { return mapnik::geometry::geometry_types::Polygon; } - template mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_point const&) const { return mapnik::geometry::geometry_types::MultiPoint; } - template mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_line_string const&) const { return mapnik::geometry::geometry_types::MultiLineString; } - template mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_polygon const&) const { return mapnik::geometry::geometry_types::MultiPolygon; } - template mapnik::geometry::geometry_types operator () (mapnik::geometry::geometry_collection const&) const { return mapnik::geometry::geometry_types::GeometryCollection; @@ -89,7 +82,8 @@ struct geometry_type template static inline mapnik::geometry::geometry_types geometry_type(T const& geom) { - return detail::geometry_type()(geom); + using coord_type = typename T::coord_type; + return detail::geometry_type()(geom); } }} diff --git a/include/mapnik/hit_test_filter.hpp b/include/mapnik/hit_test_filter.hpp index d4b850496..4d960ce34 100644 --- a/include/mapnik/hit_test_filter.hpp +++ b/include/mapnik/hit_test_filter.hpp @@ -49,7 +49,7 @@ struct hit_test_visitor y_(y), tol_(tol) {} - bool operator() (geometry::geometry_empty const& ) const + bool operator() (geometry::geometry_empty const& ) const { return false; } diff --git a/include/mapnik/text/symbolizer_helpers.hpp b/include/mapnik/text/symbolizer_helpers.hpp index 6d6fbdc49..f4a56387d 100644 --- a/include/mapnik/text/symbolizer_helpers.hpp +++ b/include/mapnik/text/symbolizer_helpers.hpp @@ -69,6 +69,7 @@ public: using line_string_cref = std::reference_wrapper const>; using polygon_cref = std::reference_wrapper const>; using geometry_cref = util::variant; + // Using list instead of vector, because we delete random elements and need iterators to stay valid. using geometry_container_type = std::list; base_symbolizer_helper(symbolizer_base const& sym, @@ -110,6 +111,10 @@ protected: evaluated_text_properties_ptr text_props_; }; +namespace geometry { +MAPNIK_DECL mapnik::box2d envelope(mapnik::base_symbolizer_helper::geometry_cref const& geom); +} + // Helper object that does all the TextSymbolizer placement finding // work except actually rendering the object. diff --git a/include/mapnik/util/geometry_to_ds_type.hpp b/include/mapnik/util/geometry_to_ds_type.hpp index e09808f3e..7791285ac 100644 --- a/include/mapnik/util/geometry_to_ds_type.hpp +++ b/include/mapnik/util/geometry_to_ds_type.hpp @@ -42,7 +42,7 @@ namespace detail { struct datasource_geometry_type { - mapnik::datasource_geometry_t operator () (mapnik::geometry::geometry_empty const&) const + mapnik::datasource_geometry_t operator () (mapnik::geometry::geometry_empty const&) const { return mapnik::datasource_geometry_t::Unknown; } diff --git a/include/mapnik/util/geometry_to_wkb.hpp b/include/mapnik/util/geometry_to_wkb.hpp index bb9d05b34..8ba82e212 100644 --- a/include/mapnik/util/geometry_to_wkb.hpp +++ b/include/mapnik/util/geometry_to_wkb.hpp @@ -238,7 +238,7 @@ struct geometry_to_wkb return util::apply_visitor(*this, geom); } - result_type operator() (geometry::geometry_empty const&) const + result_type operator() (geometry::geometry_empty const&) const { return result_type(); } diff --git a/include/mapnik/vertex_adapters.hpp b/include/mapnik/vertex_adapters.hpp index 3a41beee0..c0a2520e1 100644 --- a/include/mapnik/vertex_adapters.hpp +++ b/include/mapnik/vertex_adapters.hpp @@ -32,10 +32,9 @@ namespace mapnik { namespace geometry { template struct point_vertex_adapter { - using value_type = typename point::value_type; - + using coord_type = T; point_vertex_adapter(point const& pt); - unsigned vertex(value_type * x, value_type * y) const; + unsigned vertex(coord_type * x, coord_type * y) const; void rewind(unsigned) const; geometry_types type () const; point const& pt_; @@ -45,23 +44,23 @@ struct point_vertex_adapter template struct line_string_vertex_adapter { - using value_type = typename point::value_type; + using coord_type = T; line_string_vertex_adapter(line_string const& line); - unsigned vertex(value_type * x, value_type * y) const; + unsigned vertex(coord_type * x, coord_type * y) const; void rewind(unsigned) const; geometry_types type () const; line_string const& line_; mutable std::size_t current_index_; - const std::size_t end_index_; + const std::size_t end_index_; }; template struct polygon_vertex_adapter { - using value_type = typename point::value_type; + using coord_type = T; polygon_vertex_adapter(polygon const& poly); void rewind(unsigned) const; - unsigned vertex(value_type * x, value_type * y) const; + unsigned vertex(coord_type * x, coord_type * y) const; geometry_types type () const; private: polygon const& poly_; @@ -75,10 +74,10 @@ private: template struct ring_vertex_adapter { - using value_type = typename point::value_type; + using coord_type = T; ring_vertex_adapter(linear_ring const& ring); void rewind(unsigned) const; - unsigned vertex(value_type * x, value_type * y) const; + unsigned vertex(coord_type * x, coord_type * y) const; geometry_types type () const; private: linear_ring const& ring_; diff --git a/include/mapnik/vertex_processor.hpp b/include/mapnik/vertex_processor.hpp index 7cd2c40a4..57f6b4112 100644 --- a/include/mapnik/vertex_processor.hpp +++ b/include/mapnik/vertex_processor.hpp @@ -39,7 +39,8 @@ struct vertex_processor { util::apply_visitor(*this, geom); } - void operator() (geometry_empty const&) const + template + void operator() (geometry_empty const&) const { // no-op } diff --git a/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp index 892e55137..f31fcc08e 100644 --- a/include/mapnik/wkt/wkt_generator_grammar.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar.hpp @@ -104,7 +104,7 @@ template struct wkt_generator_grammar : karma::grammar { - using coord_type = typename Geometry::value_type; + using coord_type = typename Geometry::coord_type; wkt_generator_grammar(); // rules karma::rule geometry; diff --git a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp index 8d950edd0..e6a5bfc97 100644 --- a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp @@ -79,7 +79,7 @@ wkt_generator_grammar::wkt_generator_grammar() << (geometry_collection | empty[_1 = _a])) | (&uint_(geometry::geometry_types::Unknown)[_1 = _a] - << lit("POINT EMPTY")) // special case for geometry_empty as mapnik::geometry::point can't be empty + << lit("POINT EMPTY")) // special case for geometry_empty as mapnik::geometry::point can't be empty ; point = lit("POINT(") << point_coord << lit(")") diff --git a/include/mapnik/wkt/wkt_grammar_impl.hpp b/include/mapnik/wkt/wkt_grammar_impl.hpp index d2444130a..74d2e7ea6 100644 --- a/include/mapnik/wkt/wkt_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_grammar_impl.hpp @@ -62,7 +62,7 @@ wkt_grammar::wkt_grammar() // ::= point point_tagged_text = no_case[lit("POINT")] - >> (point_text[assign(_r1,_1)] | empty_set[assign(_r1,construct())]) + >> (point_text[assign(_r1,_1)] | empty_set[assign(_r1,construct>())]) ; // ::= | point_text = (lit("(") >> point >> lit(')')) diff --git a/plugins/input/csv/csv_featureset.cpp b/plugins/input/csv/csv_featureset.cpp index 151811201..f73b52a54 100644 --- a/plugins/input/csv/csv_featureset.cpp +++ b/plugins/input/csv/csv_featureset.cpp @@ -73,7 +73,7 @@ mapnik::feature_ptr csv_featureset::parse_feature(char const* beg, char const* e { auto values = csv_utils::parse_line(beg, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is()) + if (!geom.is>()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); diff --git a/plugins/input/csv/csv_index_featureset.cpp b/plugins/input/csv/csv_index_featureset.cpp index e94f41bc5..493d65daf 100644 --- a/plugins/input/csv/csv_index_featureset.cpp +++ b/plugins/input/csv/csv_index_featureset.cpp @@ -90,7 +90,7 @@ mapnik::feature_ptr csv_index_featureset::parse_feature(char const* beg, char co { auto values = csv_utils::parse_line(beg, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is()) + if (!geom.is>()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); diff --git a/plugins/input/csv/csv_inline_featureset.cpp b/plugins/input/csv/csv_inline_featureset.cpp index 2d91efcf4..54c8f14f9 100644 --- a/plugins/input/csv/csv_inline_featureset.cpp +++ b/plugins/input/csv/csv_inline_featureset.cpp @@ -58,7 +58,7 @@ mapnik::feature_ptr csv_inline_featureset::parse_feature(std::string const& str) auto const* end = start + str.size(); auto values = csv_utils::parse_line(start, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is()) + if (!geom.is>()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); diff --git a/plugins/input/csv/csv_utils.cpp b/plugins/input/csv/csv_utils.cpp index 217276f6a..b35942d4c 100644 --- a/plugins/input/csv/csv_utils.cpp +++ b/plugins/input/csv/csv_utils.cpp @@ -406,7 +406,7 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) } auto geom = extract_geometry(values, locator_); - if (!geom.is()) + if (!geom.is>()) { auto box = mapnik::geometry::envelope(geom); if (!extent_initialized_) diff --git a/src/box2d.cpp b/src/box2d.cpp index 407c054ba..2a87553ce 100644 --- a/src/box2d.cpp +++ b/src/box2d.cpp @@ -26,6 +26,7 @@ namespace mapnik { template class box2d; +template class box2d; template class box2d; template class box2d; diff --git a/src/geometry_envelope.cpp b/src/geometry_envelope.cpp index 5b3ade6f2..00420fce7 100644 --- a/src/geometry_envelope.cpp +++ b/src/geometry_envelope.cpp @@ -23,30 +23,23 @@ #include #include #include -namespace mapnik { -namespace geometry { + +namespace mapnik { namespace geometry { template MAPNIK_DECL mapnik::box2d envelope(geometry const& geom); -template MAPNIK_DECL mapnik::box2d envelope(mapnik::base_symbolizer_helper::geometry_cref const& geom); -template MAPNIK_DECL mapnik::box2d envelope(geometry_empty const& geom); +// single template MAPNIK_DECL mapnik::box2d envelope(point const& geom); template MAPNIK_DECL mapnik::box2d envelope(line_string const& geom); -template MAPNIK_DECL mapnik::box2d envelope(linear_ring const& geom); template MAPNIK_DECL mapnik::box2d envelope(polygon const& geom); +template MAPNIK_DECL mapnik::box2d envelope(linear_ring const& geom); +// multi template MAPNIK_DECL mapnik::box2d envelope(multi_point const& geom); template MAPNIK_DECL mapnik::box2d envelope(multi_line_string const& geom); template MAPNIK_DECL mapnik::box2d envelope(multi_polygon const& geom); +// collection template MAPNIK_DECL mapnik::box2d envelope(geometry_collection const& geom); - -template MAPNIK_DECL mapnik::box2d envelope(geometry const& geom); -template MAPNIK_DECL mapnik::box2d envelope(point const& geom); -template MAPNIK_DECL mapnik::box2d envelope(line_string const& geom); -template MAPNIK_DECL mapnik::box2d envelope(linear_ring const& geom); -template MAPNIK_DECL mapnik::box2d envelope(polygon const& geom); -template MAPNIK_DECL mapnik::box2d envelope(multi_point const& geom); -template MAPNIK_DECL mapnik::box2d envelope(multi_line_string const& geom); -template MAPNIK_DECL mapnik::box2d envelope(multi_polygon const& geom); -template MAPNIK_DECL mapnik::box2d envelope(geometry_collection const& geom); +// +template MAPNIK_DECL mapnik::box2d envelope(geometry const& geom); } // end ns geometry } // end ns mapnik diff --git a/src/geometry_reprojection.cpp b/src/geometry_reprojection.cpp index 7cd3ff08d..fad2c5b6f 100644 --- a/src/geometry_reprojection.cpp +++ b/src/geometry_reprojection.cpp @@ -29,7 +29,7 @@ namespace mapnik { namespace geometry { template MAPNIK_DECL geometry reproject_copy(geometry const& geom, proj_transform const& proj_trans, unsigned int & n_err); -template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, proj_transform const& proj_trans, unsigned int & n_err); +template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL point reproject_copy(point const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL line_string reproject_copy(line_string const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL polygon reproject_copy(polygon const& geom, proj_transform const& proj_trans, unsigned int & n_err); @@ -39,7 +39,7 @@ template MAPNIK_DECL multi_polygon reproject_copy(multi_polygon template MAPNIK_DECL geometry_collection reproject_copy(geometry_collection const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL geometry reproject_copy(geometry const& geom, projection const& source, projection const& dest, unsigned int & n_err); -template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, projection const& source, projection const& dest, unsigned int & n_err); +template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL point reproject_copy(point const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL line_string reproject_copy(line_string const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL polygon reproject_copy(polygon const& geom, projection const& source, projection const& dest, unsigned int & n_err); @@ -49,7 +49,7 @@ template MAPNIK_DECL multi_polygon reproject_copy(multi_polygon template MAPNIK_DECL geometry_collection reproject_copy(geometry_collection const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL bool reproject(geometry & geom, proj_transform const& proj_trans); -template MAPNIK_DECL bool reproject(geometry_empty & geom, proj_transform const& proj_trans); +template MAPNIK_DECL bool reproject(geometry_empty & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(point & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(line_string & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(polygon & geom, proj_transform const& proj_trans); @@ -59,7 +59,7 @@ template MAPNIK_DECL bool reproject(multi_polygon & geom, proj_transform template MAPNIK_DECL bool reproject(geometry_collection & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(geometry & geom, projection const& source, projection const& dest); -template MAPNIK_DECL bool reproject(geometry_empty & geom, projection const& source, projection const& dest); +template MAPNIK_DECL bool reproject(geometry_empty & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(point & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(line_string & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(polygon & geom, projection const& source, projection const& dest); diff --git a/src/text/symbolizer_helpers.cpp b/src/text/symbolizer_helpers.cpp index c20f51c86..741733073 100644 --- a/src/text/symbolizer_helpers.cpp +++ b/src/text/symbolizer_helpers.cpp @@ -41,8 +41,39 @@ #include #include +namespace mapnik { +namespace geometry { -namespace mapnik { namespace detail { +struct envelope_impl +{ + template + box2d operator() (T const& ref) const + { + return envelope(ref); + } +}; + +mapnik::box2d envelope(mapnik::base_symbolizer_helper::geometry_cref const& geom) +{ + return mapnik::util::apply_visitor(envelope_impl(), geom); +} + +struct geometry_type_impl +{ + template + auto operator() (T const& ref) const -> decltype(geometry_type(ref)) + { + return geometry_type(ref); + } +}; + +mapnik::geometry::geometry_types geometry_type(mapnik::base_symbolizer_helper::geometry_cref const& geom) +{ + return mapnik::util::apply_visitor(geometry_type_impl(), geom); +} + +} // geometry +namespace detail { template struct apply_vertex_placement @@ -79,7 +110,7 @@ struct split_multi_geometries split_multi_geometries(container_type & cont) : cont_(cont) { } - void operator() (geometry::geometry_empty const&) const {} + void operator() (geometry::geometry_empty const&) const {} void operator() (geometry::multi_point const& multi_pt) const { for ( auto const& pt : multi_pt ) @@ -460,7 +491,6 @@ void text_symbolizer_helper::init_marker() const finder_.set_marker(std::make_shared(marker, trans), bbox, unlock_image, marker_displacement); } - template text_symbolizer_helper::text_symbolizer_helper( text_symbolizer const& sym, feature_impl const& feature, diff --git a/src/twkb.cpp b/src/twkb.cpp index f1928e5a6..10ddedbd2 100644 --- a/src/twkb.cpp +++ b/src/twkb.cpp @@ -82,7 +82,7 @@ public: mapnik::geometry::geometry read() { - mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); + mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); // Read the metadata bytes, populating all the // information about optional fields, extended (z/m) dimensions // expansion factors and so on diff --git a/src/vertex_adapters.cpp b/src/vertex_adapters.cpp index 06be6c2f4..e96a9e25e 100644 --- a/src/vertex_adapters.cpp +++ b/src/vertex_adapters.cpp @@ -34,7 +34,7 @@ point_vertex_adapter::point_vertex_adapter(point const& pt) first_(true) {} template -unsigned point_vertex_adapter::vertex(value_type * x, value_type * y) const +unsigned point_vertex_adapter::vertex(coord_type * x, coord_type * y) const { if (first_) { @@ -67,7 +67,7 @@ line_string_vertex_adapter::line_string_vertex_adapter(line_string const& {} template -unsigned line_string_vertex_adapter::vertex(value_type * x, value_type * y) const +unsigned line_string_vertex_adapter::vertex(coord_type * x, coord_type * y) const { if (current_index_ != end_index_) { @@ -117,7 +117,7 @@ void polygon_vertex_adapter::rewind(unsigned) const start_loop_ = true; } template -unsigned polygon_vertex_adapter::vertex(value_type * x, value_type * y) const +unsigned polygon_vertex_adapter::vertex(coord_type * x, coord_type * y) const { if (rings_itr_ == rings_end_) { @@ -177,7 +177,7 @@ void ring_vertex_adapter::rewind(unsigned) const } template -unsigned ring_vertex_adapter::vertex(value_type * x, value_type * y) const +unsigned ring_vertex_adapter::vertex(coord_type * x, coord_type * y) const { if (current_index_ < end_index_) { diff --git a/src/wkb.cpp b/src/wkb.cpp index 94c1fccde..33c98002e 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -119,7 +119,7 @@ public: mapnik::geometry::geometry read() { - mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); + mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); int type = read_integer(); switch (type) { diff --git a/test/unit/datasource/ds_test_util.hpp b/test/unit/datasource/ds_test_util.hpp index 6e1c222b4..824aa8193 100644 --- a/test/unit/datasource/ds_test_util.hpp +++ b/test/unit/datasource/ds_test_util.hpp @@ -116,48 +116,53 @@ inline void require_attributes(mapnik::feature_ptr feature, } namespace detail { -struct feature_count { - template - std::size_t operator()(T const &geom) const { + +template +struct feature_count +{ + template + std::size_t operator()(U const &geom) const + { return mapnik::util::apply_visitor(*this, geom); } - std::size_t operator()(mapnik::geometry::geometry_empty const &) const { + std::size_t operator()(mapnik::geometry::geometry_empty const &) const + { return 0; } - template - std::size_t operator()(mapnik::geometry::point const &) const { + std::size_t operator()(mapnik::geometry::point const &) const + { return 1; } - template - std::size_t operator()(mapnik::geometry::line_string const &) const { + std::size_t operator()(mapnik::geometry::line_string const &) const + { return 1; } - template - std::size_t operator()(mapnik::geometry::polygon const &) const { + std::size_t operator()(mapnik::geometry::polygon const &) const + { return 1; } - template - std::size_t operator()(mapnik::geometry::multi_point const &mp) const { + std::size_t operator()(mapnik::geometry::multi_point const &mp) const + { return mp.size(); } - template - std::size_t operator()(mapnik::geometry::multi_line_string const &mls) const { + std::size_t operator()(mapnik::geometry::multi_line_string const &mls) const + { return mls.size(); } - template - std::size_t operator()(mapnik::geometry::multi_polygon const &mp) const { + std::size_t operator()(mapnik::geometry::multi_polygon const &mp) const + { return mp.size(); } - template - std::size_t operator()(mapnik::geometry::geometry_collection const &col) const { + std::size_t operator()(mapnik::geometry::geometry_collection const &col) const + { std::size_t sum = 0; for (auto const &geom : col) { sum += operator()(geom); @@ -169,7 +174,7 @@ struct feature_count { template inline std::size_t feature_count(mapnik::geometry::geometry const &g) { - return detail::feature_count()(g); + return detail::feature_count()(g); } inline void require_geometry(mapnik::feature_ptr feature, diff --git a/test/unit/geometry/centroid.cpp b/test/unit/geometry/centroid.cpp index cdfbd6e4b..9d0741d52 100644 --- a/test/unit/geometry/centroid.cpp +++ b/test/unit/geometry/centroid.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -7,7 +6,7 @@ TEST_CASE("geometry centroid") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; mapnik::geometry::point centroid; REQUIRE(!mapnik::geometry::centroid(geom, centroid)); } diff --git a/test/unit/geometry/geometry_envelope_test.cpp b/test/unit/geometry/geometry_envelope_test.cpp index fd5d78fbd..7d5bc9d05 100644 --- a/test/unit/geometry/geometry_envelope_test.cpp +++ b/test/unit/geometry/geometry_envelope_test.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -19,7 +18,7 @@ SECTION("envelope_test - double") { } { // Test empty geom - geometry geom = mapnik::geometry::geometry_empty(); + geometry geom = mapnik::geometry::geometry_empty(); mapnik::box2d bbox = mapnik::geometry::envelope(geom); REQUIRE_FALSE( bbox.valid() ); } diff --git a/test/unit/geometry/geometry_equal.hpp b/test/unit/geometry/geometry_equal.hpp index 6a510ced0..cdcdb0470 100644 --- a/test/unit/geometry/geometry_equal.hpp +++ b/test/unit/geometry/geometry_equal.hpp @@ -106,7 +106,8 @@ struct geometry_equal_visitor REQUIRE(false); } - void operator() (geometry_empty const&, geometry_empty const&) const + template + void operator() (geometry_empty const&, geometry_empty const&) const { REQUIRE(true); } diff --git a/test/unit/geometry/geometry_is_simple.cpp b/test/unit/geometry/geometry_is_simple.cpp index 55480585c..6522866b5 100644 --- a/test/unit/geometry/geometry_is_simple.cpp +++ b/test/unit/geometry/geometry_is_simple.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -11,7 +10,7 @@ TEST_CASE("geometry is_simple") { #if BOOST_VERSION >= 105800 SECTION("point") { - mapnik::geometry::geometry_empty empty; + mapnik::geometry::geometry_empty empty; CHECK( mapnik::geometry::is_simple(empty) ); } @@ -53,7 +52,7 @@ SECTION("point Infinity") { SECTION("multi point") { mapnik::geometry::multi_point mpt; - mpt.add_coord(0,0); + mpt.add_coord(0,0); mpt.add_coord(1,1); CHECK( mapnik::geometry::is_simple(mpt) ); } @@ -65,7 +64,7 @@ SECTION("multi point empty") { SECTION("line_string") { mapnik::geometry::line_string line; - line.add_coord(0,0); + line.add_coord(0,0); line.add_coord(1,1); CHECK( mapnik::geometry::is_simple(line) ); } @@ -73,7 +72,7 @@ SECTION("line_string") { // This fails while is_valid will not fail! SECTION("line_string repeated points") { mapnik::geometry::line_string line; - line.add_coord(0,0); + line.add_coord(0,0); line.add_coord(1,1); line.add_coord(1,1); line.add_coord(2,2); @@ -87,10 +86,10 @@ SECTION("line_string empty") { SECTION("multi_line_string") { mapnik::geometry::line_string line1; - line1.add_coord(0,0); + line1.add_coord(0,0); line1.add_coord(1,1); mapnik::geometry::line_string line2; - line2.add_coord(0,1); + line2.add_coord(0,1); line2.add_coord(1,2); mapnik::geometry::multi_line_string lines; lines.emplace_back(line1); @@ -113,7 +112,7 @@ SECTION("multi_line_string empty") { SECTION("polygon") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(1,0); ring.add_coord(1,1); ring.add_coord(0,1); @@ -125,7 +124,7 @@ SECTION("polygon") { SECTION("polygon invalid winding order") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(0,1); ring.add_coord(1,1); ring.add_coord(1,0); @@ -139,7 +138,7 @@ SECTION("polygon invalid winding order") { SECTION("polygon 2 repeated points") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(1,0); ring.add_coord(1,1); ring.add_coord(1,1); @@ -153,7 +152,7 @@ SECTION("polygon 2 repeated points") { SECTION("polygon 3 repeated points") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(1,0); ring.add_coord(1,1); ring.add_coord(1,1); @@ -181,7 +180,7 @@ SECTION("polygon that has empty exterior ring") { SECTION("polygon that has empty interior ring") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(1,0); ring.add_coord(1,1); ring.add_coord(0,1); @@ -209,7 +208,7 @@ SECTION("polygon that has empty exterior ring") { SECTION("polygon that has empty interior ring") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(1,0); ring.add_coord(1,1); ring.add_coord(0,1); @@ -226,7 +225,7 @@ SECTION("polygon that has empty interior ring") { SECTION("polygon with spike") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(1,0); ring.add_coord(1,1); ring.add_coord(2,2); @@ -240,14 +239,14 @@ SECTION("polygon with spike") { SECTION("polygon with hole") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(3,0); ring.add_coord(3,3); ring.add_coord(0,3); ring.add_coord(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; - hole.add_coord(1,1); + hole.add_coord(1,1); hole.add_coord(1,2); hole.add_coord(2,2); hole.add_coord(2,1); @@ -260,14 +259,14 @@ SECTION("polygon with hole") { SECTION("polygon with hole with invalid winding order") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(3,0); ring.add_coord(3,3); ring.add_coord(0,3); ring.add_coord(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; - hole.add_coord(1,1); + hole.add_coord(1,1); hole.add_coord(2,1); hole.add_coord(2,2); hole.add_coord(1,2); @@ -280,7 +279,7 @@ SECTION("multi polygon") { mapnik::geometry::multi_polygon mp; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(1,0); ring.add_coord(1,1); ring.add_coord(0,1); @@ -288,7 +287,7 @@ SECTION("multi polygon") { poly.set_exterior_ring(std::move(ring)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; - ring2.add_coord(0,0); + ring2.add_coord(0,0); ring2.add_coord(-1,0); ring2.add_coord(-1,-1); ring2.add_coord(0,-1); @@ -303,7 +302,7 @@ SECTION("multi polygon with hole") { mapnik::geometry::multi_polygon mp; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); + ring.add_coord(0,0); ring.add_coord(3,0); ring.add_coord(3,3); ring.add_coord(0,3); @@ -318,14 +317,14 @@ SECTION("multi polygon with hole") { poly.add_hole(std::move(hole)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; - ring2.add_coord(0,0); + ring2.add_coord(0,0); ring2.add_coord(-3,0); ring2.add_coord(-3,-3); ring2.add_coord(0,-3); ring2.add_coord(0,0); poly2.set_exterior_ring(std::move(ring2)); mapnik::geometry::linear_ring hole2; - hole2.add_coord(-1,-1); + hole2.add_coord(-1,-1); hole2.add_coord(-1,-2); hole2.add_coord(-2,-2); hole2.add_coord(-2,-1); diff --git a/test/unit/geometry/geometry_is_valid.cpp b/test/unit/geometry/geometry_is_valid.cpp index de1ee4c04..e64ee30ad 100644 --- a/test/unit/geometry/geometry_is_valid.cpp +++ b/test/unit/geometry/geometry_is_valid.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -11,7 +10,7 @@ TEST_CASE("geometry is_valid") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty empty; + mapnik::geometry::geometry_empty empty; CHECK( mapnik::geometry::is_valid(empty) ); std::string message; CHECK( mapnik::geometry::is_valid(empty, message) ); diff --git a/test/unit/geometry/geometry_reprojection.cpp b/test/unit/geometry/geometry_reprojection.cpp index c8ec36243..32a4008c6 100644 --- a/test/unit/geometry/geometry_reprojection.cpp +++ b/test/unit/geometry/geometry_reprojection.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include "geometry_equal.hpp" @@ -16,10 +15,10 @@ SECTION("test_projection_4326_3857 - Empty Geometry Object") { mapnik::projection dest("+init=epsg:3857"); mapnik::proj_transform proj_trans(source, dest); { - geometry_empty geom; + geometry_empty geom; unsigned int err = 0; // Test Standard Transform - geometry_empty new_geom = reproject_copy(geom, proj_trans, err); + geometry_empty new_geom = reproject_copy(geom, proj_trans, err); REQUIRE(err == 0); // Transform providing projections not transfrom new_geom = reproject_copy(geom, source, dest, err); @@ -42,20 +41,20 @@ SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant") { mapnik::projection dest("+init=epsg:3857"); mapnik::proj_transform proj_trans(source, dest); { - geometry geom = geometry_empty(); + geometry geom = geometry_empty(); unsigned int err = 0; // Test Standard Transform geometry new_geom = reproject_copy(geom, proj_trans, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); // Transform providing projections not transfrom new_geom = reproject_copy(geom, source, dest, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); // Transform providing projections in reverse new_geom = reproject_copy(geom, dest, source, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); // Transform in place REQUIRE(reproject(new_geom, proj_trans)); // Transform in place providing projections @@ -269,7 +268,7 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") { // Reprojecting empty line string will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); } { // Test Standard Transform @@ -443,7 +442,7 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); } { // Test Standard Transform @@ -583,7 +582,7 @@ SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") { // Reprojecting empty multi point will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); } { // Test Standard Transform @@ -739,7 +738,7 @@ SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object") // Reprojecting empty line string will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); } { // Test Standard Transform @@ -921,7 +920,7 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); } { // Test Standard Transform @@ -1103,7 +1102,7 @@ SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is()); + REQUIRE(new_geom.is>()); } { // Test Standard Transform diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp index b7fcab14e..06fe1afd9 100644 --- a/test/unit/geometry/has_empty.cpp +++ b/test/unit/geometry/has_empty.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -7,7 +6,7 @@ TEST_CASE("geometry has_empty") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; REQUIRE(!mapnik::geometry::has_empty(geom)); } @@ -19,7 +18,7 @@ SECTION("geometry collection") { } { mapnik::geometry::geometry_collection geom; - mapnik::geometry::geometry_empty geom1; + mapnik::geometry::geometry_empty geom1; geom.emplace_back(std::move(geom1)); REQUIRE(mapnik::geometry::has_empty(geom)); } diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp index 949b2b285..af67fe21a 100644 --- a/test/unit/geometry/is_empty.cpp +++ b/test/unit/geometry/is_empty.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -7,7 +6,7 @@ TEST_CASE("geometry is_empty") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; REQUIRE(mapnik::geometry::is_empty(geom)); } @@ -19,7 +18,7 @@ SECTION("geometry collection") { } { mapnik::geometry::geometry_collection geom; - mapnik::geometry::geometry_empty geom1; + mapnik::geometry::geometry_empty geom1; geom.emplace_back(std::move(geom1)); REQUIRE(!mapnik::geometry::is_empty(geom)); } diff --git a/test/unit/serialization/wkb_formats_test.cpp b/test/unit/serialization/wkb_formats_test.cpp index bc0c17198..6d1a0ea2c 100644 --- a/test/unit/serialization/wkb_formats_test.cpp +++ b/test/unit/serialization/wkb_formats_test.cpp @@ -79,7 +79,7 @@ SECTION("wkb") { geom = mapnik::geometry_utils::from_wkb((const char*)sp_invalid_blob, sizeof(sp_invalid_blob) / sizeof(sp_invalid_blob[0]), mapnik::wkbAuto); - REQUIRE(geom.is()); // returns geometry_empty + REQUIRE(geom.is>()); // returns geometry_empty // sqlite generic wkb blob @@ -103,7 +103,7 @@ SECTION("wkb") { geom = mapnik::geometry_utils::from_wkb((const char*)sq_invalid_blob, sizeof(sq_invalid_blob) / sizeof(sq_invalid_blob[0]), mapnik::wkbGeneric); - REQUIRE(geom.is()); // returns geometry_empty + REQUIRE(geom.is>()); // returns geometry_empty } catch (std::exception const& ex) diff --git a/test/unit/serialization/wkb_test.cpp b/test/unit/serialization/wkb_test.cpp index 8a617df26..2dbb49cca 100644 --- a/test/unit/serialization/wkb_test.cpp +++ b/test/unit/serialization/wkb_test.cpp @@ -23,7 +23,7 @@ struct spatially_equal_visitor { using result_type = bool; - result_type operator() (mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const + result_type operator() (mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const { return true; } From c4fcee7b669aab16f1884b7cefea0263d7c0bb17 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 29 Apr 2016 17:08:17 +0200 Subject: [PATCH 10/51] add geometry dir --- include/build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/include/build.py b/include/build.py index 9c225a767..ec705419a 100644 --- a/include/build.py +++ b/include/build.py @@ -27,6 +27,7 @@ Import('env') base = './mapnik/' subdirs = [ '', + 'geometry', 'csv', 'svg', 'wkt', From 80176a6c83ee91a17365b6bb5fb968892c8c32c1 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 29 Apr 2016 18:09:32 +0200 Subject: [PATCH 11/51] fix `geometry_type' call --- include/mapnik/util/geometry_to_wkb.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/util/geometry_to_wkb.hpp b/include/mapnik/util/geometry_to_wkb.hpp index 8ba82e212..5be50cc5b 100644 --- a/include/mapnik/util/geometry_to_wkb.hpp +++ b/include/mapnik/util/geometry_to_wkb.hpp @@ -288,7 +288,7 @@ wkb_buffer_ptr multi_geom_wkb(MultiGeometry const& multi_geom, wkbByteOrder byte wkb_buffer_ptr multi_wkb = std::make_unique(multi_size); wkb_stream ss(multi_wkb->buffer(), multi_wkb->size()); ss.write(reinterpret_cast(&byte_order),1); - write(ss, static_cast(geometry::detail::geometry_type()(multi_geom)) , 4, byte_order); + write(ss, static_cast(geometry::detail::geometry_type()(multi_geom)) , 4, byte_order); write(ss, multi_geom.size(), 4 ,byte_order); for ( wkb_buffer_ptr const& wkb : wkb_cont) From d169fb473efbef72a63286264ead145318234532 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 27 Jun 2016 09:44:52 +0100 Subject: [PATCH 12/51] add geometry.hpp as submodule --- .gitmodules | 3 +++ SConstruct | 1 + deps/mapbox/geometry | 1 + 3 files changed, 5 insertions(+) create mode 160000 deps/mapbox/geometry diff --git a/.gitmodules b/.gitmodules index dfcbea536..7846a4f6c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,3 +9,6 @@ [submodule "deps/mapbox/variant"] path = deps/mapbox/variant url = https://github.com/mapbox/variant.git +[submodule "deps/mapbox/geometry"] + path = deps/mapbox/geometry + url = https://github.com/mapbox/geometry.hpp.git diff --git a/SConstruct b/SConstruct index 0523e184d..85713c694 100644 --- a/SConstruct +++ b/SConstruct @@ -1598,6 +1598,7 @@ if not preconfigured: env.Prepend(CPPPATH = '#deps/agg/include') env.Prepend(LIBPATH = '#deps/agg') env.Prepend(CPPPATH = '#deps/mapbox/variant/include') + env.Prepend(CPPPATH = '#deps/mapbox/geometry/include') # prepend deps dir for auxillary headers env.Prepend(CPPPATH = '#deps') diff --git a/deps/mapbox/geometry b/deps/mapbox/geometry new file mode 160000 index 000000000..d463e6c8a --- /dev/null +++ b/deps/mapbox/geometry @@ -0,0 +1 @@ +Subproject commit d463e6c8a24178490317fa341e5cc29c3281d4f6 From 19d376b7e6c3127984a1d3831c6af6cfe0413311 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 27 Jun 2016 09:45:37 +0100 Subject: [PATCH 13/51] make mapnik::geometry::point an alias to mapbox::geometry::point --- include/mapnik/geometry.hpp | 6 ++-- include/mapnik/geometry/line_string.hpp | 6 ++-- include/mapnik/geometry/multi_line_string.hpp | 2 +- include/mapnik/geometry/multi_point.hpp | 4 +-- include/mapnik/geometry/multi_polygon.hpp | 2 +- include/mapnik/geometry/point.hpp | 25 ++----------- include/mapnik/geometry/polygon.hpp | 6 ++-- include/mapnik/geometry_envelope.hpp | 2 +- include/mapnik/geometry_envelope_impl.hpp | 12 +++---- include/mapnik/geometry_is_empty.hpp | 8 ++--- include/mapnik/geometry_is_simple.hpp | 4 +-- include/mapnik/geometry_is_valid.hpp | 12 +++---- include/mapnik/geometry_to_path.hpp | 4 +-- include/mapnik/geometry_type.hpp | 4 +-- include/mapnik/path.hpp | 10 +++--- include/mapnik/proj_transform.hpp | 4 +-- include/mapnik/svg/geometry_svg_generator.hpp | 4 +-- .../mapnik/svg/output/svg_path_iterator.hpp | 6 ++-- include/mapnik/vertex.hpp | 14 ++++---- include/mapnik/vertex_adapters.hpp | 16 ++++----- include/mapnik/vertex_vector.hpp | 24 ++++++------- include/mapnik/wkt/wkt_generator_grammar.hpp | 36 +++++++++---------- src/vertex_adapters.cpp | 8 ++--- 23 files changed, 99 insertions(+), 120 deletions(-) diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 436f6611d..1d947fba7 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -46,7 +46,7 @@ struct geometry_collection; template struct geometry_empty { - using coord_type = T; + using coordinate_type = T; }; template @@ -61,7 +61,7 @@ using geometry_base = mapnik::util::variant, template struct geometry : geometry_base { - using coord_type = T; + using coordinate_type = T; geometry() : geometry_base() {} // empty @@ -76,7 +76,7 @@ struct geometry : geometry_base template class Cont> struct geometry_collection : Cont> { - using coord_type = T; + using coordinate_type = T; }; }} diff --git a/include/mapnik/geometry/line_string.hpp b/include/mapnik/geometry/line_string.hpp index b614c5b75..d04c6439a 100644 --- a/include/mapnik/geometry/line_string.hpp +++ b/include/mapnik/geometry/line_string.hpp @@ -33,14 +33,14 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct line_string : Cont > { - using coord_type = T; - using point_type = point; + using coordinate_type = T; + using point_type = point; using container_type = Cont; line_string() = default; explicit line_string(std::size_t size) : container_type(size) {} inline std::size_t num_points() const { return container_type::size(); } - inline void add_coord(coord_type x, coord_type y) { container_type::template emplace_back(x,y);} + inline void add_coord(coordinate_type x, coordinate_type y) { container_type::template emplace_back(x,y);} }; }} diff --git a/include/mapnik/geometry/multi_line_string.hpp b/include/mapnik/geometry/multi_line_string.hpp index ca08726d3..f6a9a7ae1 100644 --- a/include/mapnik/geometry/multi_line_string.hpp +++ b/include/mapnik/geometry/multi_line_string.hpp @@ -33,7 +33,7 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct multi_line_string : Cont> { - using coord_type = T; + using coordinate_type = T; }; }} diff --git a/include/mapnik/geometry/multi_point.hpp b/include/mapnik/geometry/multi_point.hpp index 0ca018b4c..78cf504c3 100644 --- a/include/mapnik/geometry/multi_point.hpp +++ b/include/mapnik/geometry/multi_point.hpp @@ -33,8 +33,8 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct multi_point : Cont> { - using coord_type = T; - using point_type = point; + using coordinate_type = T; + using point_type = point; using container_type = Cont; multi_point() = default; explicit multi_point(std::size_t size) diff --git a/include/mapnik/geometry/multi_polygon.hpp b/include/mapnik/geometry/multi_polygon.hpp index f197ddf79..44127cdd8 100644 --- a/include/mapnik/geometry/multi_polygon.hpp +++ b/include/mapnik/geometry/multi_polygon.hpp @@ -33,7 +33,7 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct multi_polygon : Cont> { - using coord_type = T; + using coordinate_type = T; }; }} diff --git a/include/mapnik/geometry/point.hpp b/include/mapnik/geometry/point.hpp index 5cf6e3795..ba1050cb4 100644 --- a/include/mapnik/geometry/point.hpp +++ b/include/mapnik/geometry/point.hpp @@ -23,31 +23,12 @@ #ifndef MAPNIK_GEOMETRY_POINT_HPP #define MAPNIK_GEOMETRY_POINT_HPP +#include + namespace mapnik { namespace geometry { template -struct point -{ - using coord_type = T; - point() {} - point(T x_, T y_) - : x(x_), y(y_) - {} - coord_type x; - coord_type y; -}; - -template -bool operator==(point const& lhs, point const& rhs) -{ - return lhs.x == rhs.x && lhs.y == rhs.y; -} - -template -bool operator!=(point const& lhs, point const& rhs) -{ - return lhs.x != rhs.x || lhs.y != rhs.y; -} +using point = mapbox::geometry::point; }} diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp index e1ce1e6dc..193aac485 100644 --- a/include/mapnik/geometry/polygon.hpp +++ b/include/mapnik/geometry/polygon.hpp @@ -34,7 +34,7 @@ namespace mapnik { namespace geometry { template struct linear_ring : line_string { - using coord_type = T; + using coordinate_type = T; linear_ring() = default; explicit linear_ring(std::size_t size) : line_string(size) {} @@ -50,8 +50,8 @@ using rings_container = std::vector>; template class InteriorRings = rings_container> struct polygon { - using coord_type = T; - using rings_container = InteriorRings; + using coordinate_type = T; + using rings_container = InteriorRings; linear_ring exterior_ring; rings_container interior_rings; diff --git a/include/mapnik/geometry_envelope.hpp b/include/mapnik/geometry_envelope.hpp index 981b97849..1621fd22f 100644 --- a/include/mapnik/geometry_envelope.hpp +++ b/include/mapnik/geometry_envelope.hpp @@ -30,7 +30,7 @@ namespace mapnik { namespace geometry { template -MAPNIK_DECL auto envelope(T const& geom) -> box2d; +MAPNIK_DECL auto envelope(T const& geom) -> box2d; } // end ns geometry } // end ns mapnik diff --git a/include/mapnik/geometry_envelope_impl.hpp b/include/mapnik/geometry_envelope_impl.hpp index 0e539675d..bcce1cefb 100644 --- a/include/mapnik/geometry_envelope_impl.hpp +++ b/include/mapnik/geometry_envelope_impl.hpp @@ -31,8 +31,8 @@ namespace detail { template struct geometry_envelope { - using coord_type = T; - using bbox_type = box2d; + using coordinate_type = T; + using bbox_type = box2d; bbox_type & bbox; explicit geometry_envelope(bbox_type & bbox_) @@ -139,11 +139,11 @@ struct geometry_envelope } // end ns detail template -auto envelope(T const& geom) -> box2d +auto envelope(T const& geom) -> box2d { - using coord_type = typename T::coord_type; - box2d bbox; - detail::geometry_envelope op(bbox); + using coordinate_type = typename T::coordinate_type; + box2d bbox; + detail::geometry_envelope op(bbox); op(geom); return bbox; } diff --git a/include/mapnik/geometry_is_empty.hpp b/include/mapnik/geometry_is_empty.hpp index d70e506d9..d3c0fa548 100644 --- a/include/mapnik/geometry_is_empty.hpp +++ b/include/mapnik/geometry_is_empty.hpp @@ -161,15 +161,15 @@ private: template inline bool is_empty(G const& geom) { - using coord_type = typename G::coord_type; - return detail::geometry_is_empty()(geom); + using coordinate_type = typename G::coordinate_type; + return detail::geometry_is_empty()(geom); } template inline bool has_empty(G const& geom) { - using coord_type = typename G::coord_type; - return detail::geometry_has_empty()(geom); + using coordinate_type = typename G::coordinate_type; + return detail::geometry_has_empty()(geom); } }} diff --git a/include/mapnik/geometry_is_simple.hpp b/include/mapnik/geometry_is_simple.hpp index b5e7038a5..b73cc733f 100644 --- a/include/mapnik/geometry_is_simple.hpp +++ b/include/mapnik/geometry_is_simple.hpp @@ -132,8 +132,8 @@ struct geometry_is_simple template inline bool is_simple(T const& geom) { - using coord_type = typename T::coord_type; - return detail::geometry_is_simple() (geom); + using coordinate_type = typename T::coordinate_type; + return detail::geometry_is_simple() (geom); } template diff --git a/include/mapnik/geometry_is_valid.hpp b/include/mapnik/geometry_is_valid.hpp index 33d702cde..fbaef63c4 100644 --- a/include/mapnik/geometry_is_valid.hpp +++ b/include/mapnik/geometry_is_valid.hpp @@ -219,8 +219,8 @@ struct geometry_is_valid_string template inline bool is_valid(T const& geom) { - using coord_type = typename T::coord_type; - return detail::geometry_is_valid() (geom); + using coordinate_type = typename T::coordinate_type; + return detail::geometry_is_valid() (geom); } template @@ -232,8 +232,8 @@ inline bool is_valid(mapnik::geometry::geometry const& geom) template inline bool is_valid(T const& geom, boost::geometry::validity_failure_type & failure) { - using coord_type = typename T::coord_type; - return detail::geometry_is_valid_reason(failure) (geom); + using coordinate_type = typename T::coordinate_type; + return detail::geometry_is_valid_reason(failure) (geom); } template @@ -246,8 +246,8 @@ inline bool is_valid(mapnik::geometry::geometry const& geom, template inline bool is_valid(T const& geom, std::string & message) { - using coord_type = typename T::coord_type; - return detail::geometry_is_valid_string(message) (geom); + using coordinate_type = typename T::coordinate_type; + return detail::geometry_is_valid_string(message) (geom); } template diff --git a/include/mapnik/geometry_to_path.hpp b/include/mapnik/geometry_to_path.hpp index 75208adb3..361747d08 100644 --- a/include/mapnik/geometry_to_path.hpp +++ b/include/mapnik/geometry_to_path.hpp @@ -149,8 +149,8 @@ struct geometry_to_path template void to_path(T const& geom, path_type & p) { - using coord_type = typename T::coord_type; - detail::geometry_to_path func(p); + using coordinate_type = typename T::coordinate_type; + detail::geometry_to_path func(p); func(geom); } diff --git a/include/mapnik/geometry_type.hpp b/include/mapnik/geometry_type.hpp index b231c1a8e..c0055c5b4 100644 --- a/include/mapnik/geometry_type.hpp +++ b/include/mapnik/geometry_type.hpp @@ -82,8 +82,8 @@ struct geometry_type template static inline mapnik::geometry::geometry_types geometry_type(T const& geom) { - using coord_type = typename T::coord_type; - return detail::geometry_type()(geom); + using coordinate_type = typename T::coordinate_type; + return detail::geometry_type()(geom); } }} diff --git a/include/mapnik/path.hpp b/include/mapnik/path.hpp index 6d253466d..fc1cdab1a 100644 --- a/include/mapnik/path.hpp +++ b/include/mapnik/path.hpp @@ -44,8 +44,8 @@ public: PolygonExterior = Polygon, PolygonInterior = Polygon | ( 1 << geometry_bits) }; - using coord_type = T; - using container_type = Container; + using coordinate_type = T; + using container_type = Container; using value_type = typename container_type::value_type; using size_type = typename container_type::size_type; container_type cont_; @@ -84,17 +84,17 @@ public: { return cont_.size(); } - void push_vertex(coord_type x, coord_type y, CommandType c) + void push_vertex(coordinate_type x, coordinate_type y, CommandType c) { cont_.push_back(x,y,c); } - void line_to(coord_type x,coord_type y) + void line_to(coordinate_type x,coordinate_type y) { push_vertex(x,y,SEG_LINETO); } - void move_to(coord_type x,coord_type y) + void move_to(coordinate_type x,coordinate_type y) { push_vertex(x,y,SEG_MOVETO); } diff --git a/include/mapnik/proj_transform.hpp b/include/mapnik/proj_transform.hpp index 82b732f4b..71d678ef4 100644 --- a/include/mapnik/proj_transform.hpp +++ b/include/mapnik/proj_transform.hpp @@ -26,14 +26,12 @@ // mapnik #include #include +#include // stl #include namespace mapnik { -namespace geometry { -template struct point; -} class projection; template class box2d; diff --git a/include/mapnik/svg/geometry_svg_generator.hpp b/include/mapnik/svg/geometry_svg_generator.hpp index 7594c26dd..24135e5a6 100644 --- a/include/mapnik/svg/geometry_svg_generator.hpp +++ b/include/mapnik/svg/geometry_svg_generator.hpp @@ -145,7 +145,7 @@ struct svg_path_generator : { using path_type = Path; - using coord_type = typename boost::remove_pointer::type; + using coordinate_type = typename boost::remove_pointer::type; svg_path_generator(); // rules @@ -153,7 +153,7 @@ struct svg_path_generator : karma::rule point; karma::rule linestring; karma::rule polygon; - karma::rule svg_point; + karma::rule svg_point; karma::rule svg_path; // phoenix functions diff --git a/include/mapnik/svg/output/svg_path_iterator.hpp b/include/mapnik/svg/output/svg_path_iterator.hpp index b773888cd..639788ae4 100644 --- a/include/mapnik/svg/output/svg_path_iterator.hpp +++ b/include/mapnik/svg/output/svg_path_iterator.hpp @@ -117,8 +117,8 @@ private: void increment() { // variables used to extract vertex components. - geometry_type::coord_type x; - geometry_type::coord_type y; + geometry_type::coordinate_type x; + geometry_type::coordinate_type y; // extract next vertex components. unsigned cmd = path_.vertex(&x, &y); @@ -170,7 +170,7 @@ private: // Specialization of geometry_iterator, as needed by mapnik::svg::svg_path_data_grammar. // The Value type is a std::tuple that holds 5 elements, the command and the x and y coordinate. // Each coordinate is stored twice to match the needs of the grammar. -//using path_iterator_type = path_iterator, +//using path_iterator_type = path_iterator, // transform_path_adapter >; }} diff --git a/include/mapnik/vertex.hpp b/include/mapnik/vertex.hpp index 2e1d37844..92b6a0b4f 100644 --- a/include/mapnik/vertex.hpp +++ b/include/mapnik/vertex.hpp @@ -39,7 +39,7 @@ enum CommandType : std::uint8_t { template struct vertex { - using coord_type = T; + using coordinate_type = T; }; template @@ -47,9 +47,9 @@ struct vertex { enum no_init_t : std::uint8_t { no_init }; - using coord_type = T; - coord_type x; - coord_type y; + using coordinate_type = T; + coordinate_type x; + coordinate_type y; unsigned cmd; vertex() @@ -58,13 +58,13 @@ struct vertex explicit vertex(no_init_t) {} - vertex(coord_type x_,coord_type y_,unsigned cmd_) + vertex(coordinate_type x_,coordinate_type y_,unsigned cmd_) : x(x_),y(y_),cmd(cmd_) {} template vertex(vertex const& rhs) - : x(coord_type(rhs.x)), - y(coord_type(rhs.y)), + : x(coordinate_type(rhs.x)), + y(coordinate_type(rhs.y)), cmd(rhs.cmd) {} template diff --git a/include/mapnik/vertex_adapters.hpp b/include/mapnik/vertex_adapters.hpp index c0a2520e1..4dbdcd2e5 100644 --- a/include/mapnik/vertex_adapters.hpp +++ b/include/mapnik/vertex_adapters.hpp @@ -32,9 +32,9 @@ namespace mapnik { namespace geometry { template struct point_vertex_adapter { - using coord_type = T; + using coordinate_type = T; point_vertex_adapter(point const& pt); - unsigned vertex(coord_type * x, coord_type * y) const; + unsigned vertex(coordinate_type * x, coordinate_type * y) const; void rewind(unsigned) const; geometry_types type () const; point const& pt_; @@ -44,9 +44,9 @@ struct point_vertex_adapter template struct line_string_vertex_adapter { - using coord_type = T; + using coordinate_type = T; line_string_vertex_adapter(line_string const& line); - unsigned vertex(coord_type * x, coord_type * y) const; + unsigned vertex(coordinate_type * x, coordinate_type * y) const; void rewind(unsigned) const; geometry_types type () const; line_string const& line_; @@ -57,10 +57,10 @@ struct line_string_vertex_adapter template struct polygon_vertex_adapter { - using coord_type = T; + using coordinate_type = T; polygon_vertex_adapter(polygon const& poly); void rewind(unsigned) const; - unsigned vertex(coord_type * x, coord_type * y) const; + unsigned vertex(coordinate_type * x, coordinate_type * y) const; geometry_types type () const; private: polygon const& poly_; @@ -74,10 +74,10 @@ private: template struct ring_vertex_adapter { - using coord_type = T; + using coordinate_type = T; ring_vertex_adapter(linear_ring const& ring); void rewind(unsigned) const; - unsigned vertex(coord_type * x, coord_type * y) const; + unsigned vertex(coordinate_type * x, coordinate_type * y) const; geometry_types type () const; private: linear_ring const& ring_; diff --git a/include/mapnik/vertex_vector.hpp b/include/mapnik/vertex_vector.hpp index 67e30fc54..a55f5ec20 100644 --- a/include/mapnik/vertex_vector.hpp +++ b/include/mapnik/vertex_vector.hpp @@ -42,7 +42,7 @@ namespace mapnik template class vertex_vector : private util::noncopyable { - using coord_type = T; + using coordinate_type = T; enum block_e { block_shift = 8, block_size = 1<; + using value_type = std::tuple; using size_type = std::size_t; using command_size = std::uint8_t; private: unsigned num_blocks_; unsigned max_blocks_; - coord_type** vertices_; + coordinate_type** vertices_; command_size** commands_; size_type pos_; @@ -74,7 +74,7 @@ public: { if ( num_blocks_ ) { - coord_type** vertices=vertices_ + num_blocks_ - 1; + coordinate_type** vertices=vertices_ + num_blocks_ - 1; while ( num_blocks_-- ) { ::operator delete(*vertices); @@ -88,14 +88,14 @@ public: return pos_; } - void push_back (coord_type x,coord_type y,command_size command) + void push_back (coordinate_type x,coordinate_type y,command_size command) { size_type block = pos_ >> block_shift; if (block >= num_blocks_) { allocate_block(block); } - coord_type* vertex = vertices_[block] + ((pos_ & block_mask) << 1); + coordinate_type* vertex = vertices_[block] + ((pos_ & block_mask) << 1); command_size* cmd= commands_[block] + (pos_ & block_mask); *cmd = static_cast(command); @@ -103,11 +103,11 @@ public: *vertex = y; ++pos_; } - unsigned get_vertex(unsigned pos,coord_type* x,coord_type* y) const + unsigned get_vertex(unsigned pos,coordinate_type* x,coordinate_type* y) const { if (pos >= pos_) return SEG_END; size_type block = pos >> block_shift; - const coord_type* vertex = vertices_[block] + (( pos & block_mask) << 1); + const coordinate_type* vertex = vertices_[block] + (( pos & block_mask) << 1); *x = (*vertex++); *y = (*vertex); return commands_[block] [pos & block_mask]; @@ -126,8 +126,8 @@ private: { if (block >= max_blocks_) { - coord_type** new_vertices = - static_cast(::operator new (sizeof(coord_type*)*((max_blocks_ + grow_by) * 2))); + coordinate_type** new_vertices = + static_cast(::operator new (sizeof(coordinate_type*)*((max_blocks_ + grow_by) * 2))); command_size** new_commands = (command_size**)(new_vertices + max_blocks_ + grow_by); if (vertices_) { @@ -139,8 +139,8 @@ private: commands_ = new_commands; max_blocks_ += grow_by; } - vertices_[block] = static_cast - (::operator new(sizeof(coord_type)*(block_size * 2 + block_size / (sizeof(coord_type))))); + vertices_[block] = static_cast + (::operator new(sizeof(coordinate_type)*(block_size * 2 + block_size / (sizeof(coordinate_type))))); commands_[block] = (command_size*)(vertices_[block] + block_size*2); ++num_blocks_; diff --git a/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp index f31fcc08e..e303c1e29 100644 --- a/include/mapnik/wkt/wkt_generator_grammar.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar.hpp @@ -104,31 +104,31 @@ template struct wkt_generator_grammar : karma::grammar { - using coord_type = typename Geometry::coord_type; + using coordinate_type = typename Geometry::coordinate_type; wkt_generator_grammar(); // rules karma::rule geometry; karma::rule, Geometry const&() > geometry_dispatch; - karma::rule const&()> point; - karma::rule const&()> point_coord; - karma::rule const&()> linestring; - karma::rule const&()> linestring_coord; - karma::rule const&()> polygon; - karma::rule const&()> polygon_coord; - karma::rule const&()> exterior_ring_coord; - karma::rule > const&()> interior_ring_coord; - karma::rule const& ()> multi_point; - karma::rule const& ()> multi_point_coord; - karma::rule const& ()> multi_linestring; - karma::rule const& ()> multi_linestring_coord; - karma::rule const& ()> multi_polygon; - karma::rule const& ()> multi_polygon_coord; - karma::rule const& ()> geometry_collection; - karma::rule const& ()> geometries; + karma::rule const&()> point; + karma::rule const&()> point_coord; + karma::rule const&()> linestring; + karma::rule const&()> linestring_coord; + karma::rule const&()> polygon; + karma::rule const&()> polygon_coord; + karma::rule const&()> exterior_ring_coord; + karma::rule > const&()> interior_ring_coord; + karma::rule const& ()> multi_point; + karma::rule const& ()> multi_point_coord; + karma::rule const& ()> multi_linestring; + karma::rule const& ()> multi_linestring_coord; + karma::rule const& ()> multi_polygon; + karma::rule const& ()> multi_polygon_coord; + karma::rule const& ()> geometry_collection; + karma::rule const& ()> geometries; boost::phoenix::function > geometry_type; karma::symbols empty; // - typename detail::coordinate_generator::generator coordinate; + typename detail::coordinate_generator::generator coordinate; }; }} diff --git a/src/vertex_adapters.cpp b/src/vertex_adapters.cpp index e96a9e25e..566818074 100644 --- a/src/vertex_adapters.cpp +++ b/src/vertex_adapters.cpp @@ -34,7 +34,7 @@ point_vertex_adapter::point_vertex_adapter(point const& pt) first_(true) {} template -unsigned point_vertex_adapter::vertex(coord_type * x, coord_type * y) const +unsigned point_vertex_adapter::vertex(coordinate_type * x, coordinate_type * y) const { if (first_) { @@ -67,7 +67,7 @@ line_string_vertex_adapter::line_string_vertex_adapter(line_string const& {} template -unsigned line_string_vertex_adapter::vertex(coord_type * x, coord_type * y) const +unsigned line_string_vertex_adapter::vertex(coordinate_type * x, coordinate_type * y) const { if (current_index_ != end_index_) { @@ -117,7 +117,7 @@ void polygon_vertex_adapter::rewind(unsigned) const start_loop_ = true; } template -unsigned polygon_vertex_adapter::vertex(coord_type * x, coord_type * y) const +unsigned polygon_vertex_adapter::vertex(coordinate_type * x, coordinate_type * y) const { if (rings_itr_ == rings_end_) { @@ -177,7 +177,7 @@ void ring_vertex_adapter::rewind(unsigned) const } template -unsigned ring_vertex_adapter::vertex(coord_type * x, coord_type * y) const +unsigned ring_vertex_adapter::vertex(coordinate_type * x, coordinate_type * y) const { if (current_index_ < end_index_) { From 3b1c7308cc157a799c021280895843cdc876e25f Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 27 Jun 2016 10:23:13 +0100 Subject: [PATCH 14/51] make mapnik::geometry::line_string an alias to mapbox::geometry::line_string --- benchmark/test_polygon_clipping.cpp | 28 +-- include/mapnik/geometry/line_string.hpp | 19 +- include/mapnik/hit_test_filter.hpp | 4 +- include/mapnik/json/topojson_utils.hpp | 10 +- plugins/input/ogr/ogr_converter.cpp | 2 +- plugins/input/shape/shape_io.cpp | 4 +- test/unit/geometry/centroid.cpp | 70 +++--- test/unit/geometry/geometry_envelope_test.cpp | 58 ++--- test/unit/geometry/geometry_hit_test.cpp | 53 +++-- test/unit/geometry/geometry_is_simple.cpp | 204 +++++++++--------- test/unit/geometry/geometry_is_valid.cpp | 194 ++++++++--------- test/unit/geometry/has_empty.cpp | 28 +-- test/unit/geometry/is_empty.cpp | 22 +- test/unit/geometry/remove_empty.cpp | 17 +- test/unit/vertex_adapter/vertex_adapter.cpp | 39 ++-- 15 files changed, 368 insertions(+), 384 deletions(-) diff --git a/benchmark/test_polygon_clipping.cpp b/benchmark/test_polygon_clipping.cpp index b189a0443..b9ded3eea 100644 --- a/benchmark/test_polygon_clipping.cpp +++ b/benchmark/test_polygon_clipping.cpp @@ -123,10 +123,10 @@ public: if (cmd == mapnik::SEG_CLOSE) { - ring.add_coord(x0, y0); + ring.emplace_back(x0, y0); break; } - ring.add_coord(x,y); + ring.emplace_back(x,y); } poly2.set_exterior_ring(std::move(ring)); // interior rings @@ -139,12 +139,12 @@ public: } else if (cmd == mapnik::SEG_CLOSE) { - ring.add_coord(x0,y0); + ring.emplace_back(x0,y0); poly2.add_hole(std::move(ring)); ring.clear(); continue; } - ring.add_coord(x,y); + ring.emplace_back(x,y); } std::string expect = expected_+".png"; @@ -243,11 +243,11 @@ public: mapnik::geometry::correct(poly); mapnik::geometry::linear_ring bbox; - bbox.add_coord(extent_.minx(), extent_.miny()); - bbox.add_coord(extent_.minx(), extent_.maxy()); - bbox.add_coord(extent_.maxx(), extent_.maxy()); - bbox.add_coord(extent_.maxx(), extent_.miny()); - bbox.add_coord(extent_.minx(), extent_.miny()); + bbox.emplace_back(extent_.minx(), extent_.miny()); + bbox.emplace_back(extent_.minx(), extent_.maxy()); + bbox.emplace_back(extent_.maxx(), extent_.maxy()); + bbox.emplace_back(extent_.maxx(), extent_.miny()); + bbox.emplace_back(extent_.minx(), extent_.miny()); std::deque > result; boost::geometry::intersection(bbox, poly, result); @@ -291,11 +291,11 @@ public: mapnik::geometry::correct(poly); mapnik::geometry::linear_ring bbox; - bbox.add_coord(extent_.minx(), extent_.miny()); - bbox.add_coord(extent_.minx(), extent_.maxy()); - bbox.add_coord(extent_.maxx(), extent_.maxy()); - bbox.add_coord(extent_.maxx(), extent_.miny()); - bbox.add_coord(extent_.minx(), extent_.miny()); + bbox.emplace_back(extent_.minx(), extent_.miny()); + bbox.emplace_back(extent_.minx(), extent_.maxy()); + bbox.emplace_back(extent_.maxx(), extent_.maxy()); + bbox.emplace_back(extent_.maxx(), extent_.miny()); + bbox.emplace_back(extent_.minx(), extent_.miny()); bool valid = true; for (unsigned i=0;i -// stl -#include +#include namespace mapnik { namespace geometry { -template class Cont = std::vector> -struct line_string : Cont > -{ - using coordinate_type = T; - using point_type = point; - using container_type = Cont; - line_string() = default; - explicit line_string(std::size_t size) - : container_type(size) {} - inline std::size_t num_points() const { return container_type::size(); } - inline void add_coord(coordinate_type x, coordinate_type y) { container_type::template emplace_back(x,y);} -}; - +template +using line_string = mapbox::geometry::line_string; }} #endif // MAPNIK_GEOMETRY_LINE_STRING_HPP diff --git a/include/mapnik/hit_test_filter.hpp b/include/mapnik/hit_test_filter.hpp index 4d960ce34..a74910e70 100644 --- a/include/mapnik/hit_test_filter.hpp +++ b/include/mapnik/hit_test_filter.hpp @@ -68,7 +68,7 @@ struct hit_test_visitor } bool operator() (geometry::line_string const& geom) const { - std::size_t num_points = geom.num_points(); + std::size_t num_points = geom.size(); if (num_points > 1) { for (std::size_t i = 1; i < num_points; ++i) @@ -92,7 +92,7 @@ struct hit_test_visitor bool operator() (geometry::polygon const& geom) const { auto const& exterior = geom.exterior_ring; - std::size_t num_points = exterior.num_points(); + std::size_t num_points = exterior.size(); if (num_points < 4) return false; bool inside = false; for (std::size_t i = 1; i < num_points; ++i) diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp index 40a2c91ff..0ff3262e9 100644 --- a/include/mapnik/json/topojson_utils.hpp +++ b/include/mapnik/json/topojson_utils.hpp @@ -313,7 +313,7 @@ struct feature_generator x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x; y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y; } - multi_point.add_coord(x, y); + multi_point.emplace_back(x, y); } feature->set_geometry(std::move(multi_point)); assign_properties(*feature, multi_pt, tr_); @@ -344,7 +344,7 @@ struct feature_generator x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x; y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y; } - line_string.add_coord(x,y); + line_string.emplace_back(x,y); } } } @@ -383,7 +383,7 @@ struct feature_generator x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x; y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y; } - line_string.add_coord(x, y); + line_string.emplace_back(x, y); } } @@ -524,14 +524,14 @@ struct feature_generator { for (auto const& c : (processed_coords | reversed)) { - linear_ring.add_coord(c.x, c.y); + linear_ring.emplace_back(c.x, c.y); } } else { for (auto const& c : processed_coords) { - linear_ring.add_coord(c.x, c.y); + linear_ring.emplace_back(c.x, c.y); } } } diff --git a/plugins/input/ogr/ogr_converter.cpp b/plugins/input/ogr/ogr_converter.cpp index 207c0e1e4..1a9d58738 100644 --- a/plugins/input/ogr/ogr_converter.cpp +++ b/plugins/input/ogr/ogr_converter.cpp @@ -98,7 +98,7 @@ mapnik::geometry::line_string ogr_converter::convert_linestring(OGRLineS geom.reserve(num_points); for (int i = 0; i < num_points; ++i) { - geom.add_coord(ogr_geom->getX(i), ogr_geom->getY(i)); + geom.emplace_back(ogr_geom->getX(i), ogr_geom->getY(i)); } return geom; } diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index 5dd591996..bbd53a408 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -114,7 +114,7 @@ mapnik::geometry::geometry shape_io::read_polyline(shape_file::record_ty { double x = record.read_double(); double y = record.read_double(); - line.add_coord(x, y); + line.emplace_back(x, y); } geom = std::move(line); } @@ -144,7 +144,7 @@ mapnik::geometry::geometry shape_io::read_polyline(shape_file::record_ty { double x = record.read_double(); double y = record.read_double(); - line.add_coord(x, y); + line.emplace_back(x, y); } multi_line.push_back(std::move(line)); } diff --git a/test/unit/geometry/centroid.cpp b/test/unit/geometry/centroid.cpp index 9d0741d52..f867cd74c 100644 --- a/test/unit/geometry/centroid.cpp +++ b/test/unit/geometry/centroid.cpp @@ -30,9 +30,9 @@ SECTION("point") { SECTION("linestring") { mapnik::geometry::line_string line; - line.add_coord(0, 0); - line.add_coord(25, 25); - line.add_coord(50, 50); + line.emplace_back(0, 0); + line.emplace_back(25, 25); + line.emplace_back(50, 50); mapnik::geometry::point centroid; REQUIRE(mapnik::geometry::centroid(line, centroid)); REQUIRE(centroid.x == 25); @@ -50,11 +50,11 @@ SECTION("polygon") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0, 0); - ring.add_coord(1, 0); - ring.add_coord(1, 1); - ring.add_coord(0, 1); - ring.add_coord(0, 0); + ring.emplace_back(0, 0); + ring.emplace_back(1, 0); + ring.emplace_back(1, 1); + ring.emplace_back(0, 1); + ring.emplace_back(0, 0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::point centroid; @@ -83,9 +83,9 @@ SECTION("empty polygon") { SECTION("multi-point") { mapnik::geometry::multi_point geom; - geom.add_coord(0, 0); - geom.add_coord(25, 25); - geom.add_coord(50, 50); + geom.emplace_back(0, 0); + geom.emplace_back(25, 25); + geom.emplace_back(50, 50); mapnik::geometry::point centroid; REQUIRE(mapnik::geometry::centroid(geom, centroid)); REQUIRE(centroid.x == 25); @@ -104,16 +104,16 @@ SECTION("multi-linestring") { mapnik::geometry::multi_line_string geom; { mapnik::geometry::line_string line; - line.add_coord(0, 0); - line.add_coord(0, 25); - line.add_coord(0, 50); + line.emplace_back(0, 0); + line.emplace_back(0, 25); + line.emplace_back(0, 50); geom.emplace_back(std::move(line)); } { mapnik::geometry::line_string line; - line.add_coord(0, 0); - line.add_coord(25, 0); - line.add_coord(50, 0); + line.emplace_back(0, 0); + line.emplace_back(25, 0); + line.emplace_back(50, 0); geom.emplace_back(std::move(line)); } mapnik::geometry::point centroid; @@ -126,9 +126,9 @@ SECTION("multi-linestring: one component empty") { mapnik::geometry::multi_line_string geom; mapnik::geometry::line_string line; - line.add_coord(0, 0); - line.add_coord(0, 25); - line.add_coord(0, 50); + line.emplace_back(0, 0); + line.emplace_back(0, 25); + line.emplace_back(0, 50); geom.emplace_back(std::move(line)); geom.emplace_back(); mapnik::geometry::point centroid; @@ -150,22 +150,22 @@ SECTION("multi-polygon") { { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0, 0); - ring.add_coord(1, 0); - ring.add_coord(1, 1); - ring.add_coord(0, 1); - ring.add_coord(0, 0); + ring.emplace_back(0, 0); + ring.emplace_back(1, 0); + ring.emplace_back(1, 1); + ring.emplace_back(0, 1); + ring.emplace_back(0, 0); poly.set_exterior_ring(std::move(ring)); geom.emplace_back(std::move(poly)); } { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(1, 1); - ring.add_coord(2, 1); - ring.add_coord(2, 2); - ring.add_coord(1, 2); - ring.add_coord(1, 1); + ring.emplace_back(1, 1); + ring.emplace_back(2, 1); + ring.emplace_back(2, 2); + ring.emplace_back(1, 2); + ring.emplace_back(1, 1); poly.set_exterior_ring(std::move(ring)); geom.emplace_back(std::move(poly)); } @@ -181,11 +181,11 @@ SECTION("multi-polygon: one component empty") { mapnik::geometry::multi_polygon geom; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0, 0); - ring.add_coord(1, 0); - ring.add_coord(1, 1); - ring.add_coord(0, 1); - ring.add_coord(0, 0); + ring.emplace_back(0, 0); + ring.emplace_back(1, 0); + ring.emplace_back(1, 1); + ring.emplace_back(0, 1); + ring.emplace_back(0, 0); poly.set_exterior_ring(std::move(ring)); geom.emplace_back(std::move(poly)); geom.emplace_back(); diff --git a/test/unit/geometry/geometry_envelope_test.cpp b/test/unit/geometry/geometry_envelope_test.cpp index d8904dd5f..77c2e2b85 100644 --- a/test/unit/geometry/geometry_envelope_test.cpp +++ b/test/unit/geometry/geometry_envelope_test.cpp @@ -27,9 +27,9 @@ void envelope_test() } { line_string line; - line.add_coord(0,0); - line.add_coord(1,1); - line.add_coord(2,2); + line.emplace_back(0,0); + line.emplace_back(1,1); + line.emplace_back(2,2); geometry geom(line); mapnik::box2d bbox = mapnik::geometry::envelope(geom); REQUIRE( bbox.minx() == 0 ); @@ -39,13 +39,13 @@ void envelope_test() } { line_string line; - line.add_coord(0,0); - line.add_coord(1,1); - line.add_coord(2,2); + line.emplace_back(0,0); + line.emplace_back(1,1); + line.emplace_back(2,2); line_string line2; - line2.add_coord(0,0); - line2.add_coord(-1,-1); - line2.add_coord(-2,-2); + line2.emplace_back(0,0); + line2.emplace_back(-1,-1); + line2.emplace_back(-2,-2); multi_line_string multi_line; multi_line.emplace_back(std::move(line)); multi_line.emplace_back(std::move(line2)); @@ -59,11 +59,11 @@ void envelope_test() { polygon poly; linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(-10,0); - ring.add_coord(-10,10); - ring.add_coord(0,10); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(-10,0); + ring.emplace_back(-10,10); + ring.emplace_back(0,10); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); geometry geom(poly); mapnik::box2d bbox = mapnik::geometry::envelope(geom); @@ -102,18 +102,18 @@ void envelope_test() // polygon with hole polygon poly; linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(-10,0); - ring.add_coord(-10,10); - ring.add_coord(0,10); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(-10,0); + ring.emplace_back(-10,10); + ring.emplace_back(0,10); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); linear_ring hole; - hole.add_coord(-7,7); - hole.add_coord(-7,3); - hole.add_coord(-3,3); - hole.add_coord(-3,7); - hole.add_coord(-7,7); + hole.emplace_back(-7,7); + hole.emplace_back(-7,3); + hole.emplace_back(-3,3); + hole.emplace_back(-3,7); + hole.emplace_back(-7,7); poly.add_hole(std::move(hole)); geometry geom(poly); mapnik::box2d bbox = mapnik::geometry::envelope(poly); @@ -124,11 +124,11 @@ void envelope_test() // add another hole inside the first hole // which should be considered a hit linear_ring fill; - fill.add_coord(-6,4); - fill.add_coord(-6,6); - fill.add_coord(-4,6); - fill.add_coord(-4,4); - fill.add_coord(-6,4); + fill.emplace_back(-6,4); + fill.emplace_back(-6,6); + fill.emplace_back(-4,6); + fill.emplace_back(-4,4); + fill.emplace_back(-6,4); poly.add_hole(std::move(fill)); bbox = mapnik::geometry::envelope(poly); REQUIRE( bbox.minx() == -10 ); diff --git a/test/unit/geometry/geometry_hit_test.cpp b/test/unit/geometry/geometry_hit_test.cpp index 3b21407f6..72695d849 100644 --- a/test/unit/geometry/geometry_hit_test.cpp +++ b/test/unit/geometry/geometry_hit_test.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -27,17 +26,17 @@ SECTION("hit_test_filter - double") { } { line_string line; - line.add_coord(0,0); - line.add_coord(1,1); - line.add_coord(2,2); + line.emplace_back(0,0); + line.emplace_back(1,1); + line.emplace_back(2,2); geometry geom(line); REQUIRE( mapnik::hit_test(geom,0,0,1.5) ); } { line_string line; - line.add_coord(0,0); - line.add_coord(1,1); - line.add_coord(2,2); + line.emplace_back(0,0); + line.emplace_back(1,1); + line.emplace_back(2,2); multi_line_string multi_line; multi_line.emplace_back(std::move(line)); geometry geom(multi_line); @@ -46,11 +45,11 @@ SECTION("hit_test_filter - double") { { polygon poly; linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(-10,0); - ring.add_coord(-10,10); - ring.add_coord(0,10); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(-10,0); + ring.emplace_back(-10,10); + ring.emplace_back(0,10); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); geometry geom(poly); REQUIRE( mapnik::hit_test(geom,-5,5,0) ); @@ -78,29 +77,29 @@ SECTION("hit_test_filter - double") { // polygon with hole polygon poly; linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(-10,0); - ring.add_coord(-10,10); - ring.add_coord(0,10); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(-10,0); + ring.emplace_back(-10,10); + ring.emplace_back(0,10); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); linear_ring hole; - hole.add_coord(-7,7); - hole.add_coord(-7,3); - hole.add_coord(-3,3); - hole.add_coord(-3,7); - hole.add_coord(-7,7); + hole.emplace_back(-7,7); + hole.emplace_back(-7,3); + hole.emplace_back(-3,3); + hole.emplace_back(-3,7); + hole.emplace_back(-7,7); poly.add_hole(std::move(hole)); geometry geom(poly); REQUIRE( !mapnik::hit_test(geom,-5,5,0) ); // add another hole inside the first hole // which should be considered a hit linear_ring fill; - fill.add_coord(-6,4); - fill.add_coord(-6,6); - fill.add_coord(-4,6); - fill.add_coord(-4,4); - fill.add_coord(-6,4); + fill.emplace_back(-6,4); + fill.emplace_back(-6,6); + fill.emplace_back(-4,6); + fill.emplace_back(-4,4); + fill.emplace_back(-6,4); poly.add_hole(std::move(fill)); REQUIRE( mapnik::hit_test(geometry(poly),-5,5,0) ); } diff --git a/test/unit/geometry/geometry_is_simple.cpp b/test/unit/geometry/geometry_is_simple.cpp index 6522866b5..2177dea68 100644 --- a/test/unit/geometry/geometry_is_simple.cpp +++ b/test/unit/geometry/geometry_is_simple.cpp @@ -52,8 +52,8 @@ SECTION("point Infinity") { SECTION("multi point") { mapnik::geometry::multi_point mpt; - mpt.add_coord(0,0); - mpt.add_coord(1,1); + mpt.emplace_back(0,0); + mpt.emplace_back(1,1); CHECK( mapnik::geometry::is_simple(mpt) ); } @@ -64,18 +64,18 @@ SECTION("multi point empty") { SECTION("line_string") { mapnik::geometry::line_string line; - line.add_coord(0,0); - line.add_coord(1,1); + line.emplace_back(0,0); + line.emplace_back(1,1); CHECK( mapnik::geometry::is_simple(line) ); } // This fails while is_valid will not fail! SECTION("line_string repeated points") { mapnik::geometry::line_string line; - line.add_coord(0,0); - line.add_coord(1,1); - line.add_coord(1,1); - line.add_coord(2,2); + line.emplace_back(0,0); + line.emplace_back(1,1); + line.emplace_back(1,1); + line.emplace_back(2,2); CHECK( !mapnik::geometry::is_simple(line) ); } @@ -86,11 +86,11 @@ SECTION("line_string empty") { SECTION("multi_line_string") { mapnik::geometry::line_string line1; - line1.add_coord(0,0); - line1.add_coord(1,1); + line1.emplace_back(0,0); + line1.emplace_back(1,1); mapnik::geometry::line_string line2; - line2.add_coord(0,1); - line2.add_coord(1,2); + line2.emplace_back(0,1); + line2.emplace_back(1,2); mapnik::geometry::multi_line_string lines; lines.emplace_back(line1); lines.emplace_back(line2); @@ -112,11 +112,11 @@ SECTION("multi_line_string empty") { SECTION("polygon") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -124,11 +124,11 @@ SECTION("polygon") { SECTION("polygon invalid winding order") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(0,1); - ring.add_coord(1,1); - ring.add_coord(1,0); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(0,1); + ring.emplace_back(1,1); + ring.emplace_back(1,0); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -138,12 +138,12 @@ SECTION("polygon invalid winding order") { SECTION("polygon 2 repeated points") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( !mapnik::geometry::is_simple(poly) ); } @@ -152,13 +152,13 @@ SECTION("polygon 2 repeated points") { SECTION("polygon 3 repeated points") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(1,1); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(1,1); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( !mapnik::geometry::is_simple(poly) ); } @@ -180,11 +180,11 @@ SECTION("polygon that has empty exterior ring") { SECTION("polygon that has empty interior ring") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring ring2; poly.add_hole(std::move(ring2)); @@ -208,11 +208,11 @@ SECTION("polygon that has empty exterior ring") { SECTION("polygon that has empty interior ring") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring ring2; poly.add_hole(std::move(ring2)); @@ -225,13 +225,13 @@ SECTION("polygon that has empty interior ring") { SECTION("polygon with spike") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(2,2); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(2,2); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -239,18 +239,18 @@ SECTION("polygon with spike") { SECTION("polygon with hole") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(3,0); - ring.add_coord(3,3); - ring.add_coord(0,3); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(3,0); + ring.emplace_back(3,3); + ring.emplace_back(0,3); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; - hole.add_coord(1,1); - hole.add_coord(1,2); - hole.add_coord(2,2); - hole.add_coord(2,1); - hole.add_coord(1,1); + hole.emplace_back(1,1); + hole.emplace_back(1,2); + hole.emplace_back(2,2); + hole.emplace_back(2,1); + hole.emplace_back(1,1); poly.add_hole(std::move(hole)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -259,18 +259,18 @@ SECTION("polygon with hole") { SECTION("polygon with hole with invalid winding order") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(3,0); - ring.add_coord(3,3); - ring.add_coord(0,3); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(3,0); + ring.emplace_back(3,3); + ring.emplace_back(0,3); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; - hole.add_coord(1,1); - hole.add_coord(2,1); - hole.add_coord(2,2); - hole.add_coord(1,2); - hole.add_coord(1,1); + hole.emplace_back(1,1); + hole.emplace_back(2,1); + hole.emplace_back(2,2); + hole.emplace_back(1,2); + hole.emplace_back(1,1); poly.add_hole(std::move(hole)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -279,19 +279,19 @@ SECTION("multi polygon") { mapnik::geometry::multi_polygon mp; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; - ring2.add_coord(0,0); - ring2.add_coord(-1,0); - ring2.add_coord(-1,-1); - ring2.add_coord(0,-1); - ring2.add_coord(0,0); + ring2.emplace_back(0,0); + ring2.emplace_back(-1,0); + ring2.emplace_back(-1,-1); + ring2.emplace_back(0,-1); + ring2.emplace_back(0,0); poly2.set_exterior_ring(std::move(ring2)); mp.emplace_back(poly); mp.emplace_back(poly2); @@ -302,33 +302,33 @@ SECTION("multi polygon with hole") { mapnik::geometry::multi_polygon mp; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(3,0); - ring.add_coord(3,3); - ring.add_coord(0,3); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(3,0); + ring.emplace_back(3,3); + ring.emplace_back(0,3); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; - hole.add_coord(1,1); - hole.add_coord(1,2); - hole.add_coord(2,2); - hole.add_coord(2,1); - hole.add_coord(1,1); + hole.emplace_back(1,1); + hole.emplace_back(1,2); + hole.emplace_back(2,2); + hole.emplace_back(2,1); + hole.emplace_back(1,1); poly.add_hole(std::move(hole)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; - ring2.add_coord(0,0); - ring2.add_coord(-3,0); - ring2.add_coord(-3,-3); - ring2.add_coord(0,-3); - ring2.add_coord(0,0); + ring2.emplace_back(0,0); + ring2.emplace_back(-3,0); + ring2.emplace_back(-3,-3); + ring2.emplace_back(0,-3); + ring2.emplace_back(0,0); poly2.set_exterior_ring(std::move(ring2)); mapnik::geometry::linear_ring hole2; - hole2.add_coord(-1,-1); - hole2.add_coord(-1,-2); - hole2.add_coord(-2,-2); - hole2.add_coord(-2,-1); - hole2.add_coord(-1,-1); + hole2.emplace_back(-1,-1); + hole2.emplace_back(-1,-2); + hole2.emplace_back(-2,-2); + hole2.emplace_back(-2,-1); + hole2.emplace_back(-1,-1); poly2.add_hole(std::move(hole2)); mp.emplace_back(poly); mp.emplace_back(poly2); diff --git a/test/unit/geometry/geometry_is_valid.cpp b/test/unit/geometry/geometry_is_valid.cpp index e64ee30ad..63c2f348b 100644 --- a/test/unit/geometry/geometry_is_valid.cpp +++ b/test/unit/geometry/geometry_is_valid.cpp @@ -123,8 +123,8 @@ SECTION("point Infinity") { SECTION("multi point") { mapnik::geometry::multi_point mpt; - mpt.add_coord(0,0); - mpt.add_coord(1,1); + mpt.emplace_back(0,0); + mpt.emplace_back(1,1); CHECK( mapnik::geometry::is_valid(mpt) ); std::string message; CHECK( mapnik::geometry::is_valid(mpt, message) ); @@ -148,8 +148,8 @@ SECTION("multi point empty") { SECTION("line_string") { mapnik::geometry::line_string line; - line.add_coord(0,0); - line.add_coord(1,1); + line.emplace_back(0,0); + line.emplace_back(1,1); CHECK( mapnik::geometry::is_valid(line) ); std::string message; CHECK( mapnik::geometry::is_valid(line, message) ); @@ -162,10 +162,10 @@ SECTION("line_string") { // This shouldn't fail -- test added in case logic ever changes SECTION("line_string repeated points") { mapnik::geometry::line_string line; - line.add_coord(0,0); - line.add_coord(1,1); - line.add_coord(1,1); - line.add_coord(2,2); + line.emplace_back(0,0); + line.emplace_back(1,1); + line.emplace_back(1,1); + line.emplace_back(2,2); CHECK( mapnik::geometry::is_valid(line) ); std::string message; CHECK( mapnik::geometry::is_valid(line, message) ); @@ -188,11 +188,11 @@ SECTION("line_string empty") { SECTION("multi_line_string") { mapnik::geometry::line_string line1; - line1.add_coord(0,0); - line1.add_coord(1,1); + line1.emplace_back(0,0); + line1.emplace_back(1,1); mapnik::geometry::line_string line2; - line2.add_coord(0,1); - line2.add_coord(1,2); + line2.emplace_back(0,1); + line2.emplace_back(1,2); mapnik::geometry::multi_line_string lines; lines.emplace_back(line1); lines.emplace_back(line2); @@ -219,11 +219,11 @@ SECTION("multi_line_string empty") { SECTION("polygon") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; @@ -237,11 +237,11 @@ SECTION("polygon") { SECTION("polygon invalid winding order") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(0,1); - ring.add_coord(1,1); - ring.add_coord(1,0); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(0,1); + ring.emplace_back(1,1); + ring.emplace_back(1,0); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; @@ -256,12 +256,12 @@ SECTION("polygon invalid winding order") { SECTION("polygon 2 repeated points") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; @@ -275,13 +275,13 @@ SECTION("polygon 2 repeated points") { SECTION("polygon 3 repeated points") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(1,1); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(1,1); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; @@ -306,13 +306,13 @@ SECTION("polygon that is empty") { SECTION("polygon with spike") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(2,2); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(2,2); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; @@ -326,18 +326,18 @@ SECTION("polygon with spike") { SECTION("polygon with hole") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(3,0); - ring.add_coord(3,3); - ring.add_coord(0,3); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(3,0); + ring.emplace_back(3,3); + ring.emplace_back(0,3); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; - hole.add_coord(1,1); - hole.add_coord(1,2); - hole.add_coord(2,2); - hole.add_coord(2,1); - hole.add_coord(1,1); + hole.emplace_back(1,1); + hole.emplace_back(1,2); + hole.emplace_back(2,2); + hole.emplace_back(2,1); + hole.emplace_back(1,1); poly.add_hole(std::move(hole)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; @@ -351,11 +351,11 @@ SECTION("polygon with hole") { SECTION("polygon with empty hole") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(3,0); - ring.add_coord(3,3); - ring.add_coord(0,3); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(3,0); + ring.emplace_back(3,3); + ring.emplace_back(0,3); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; poly.add_hole(std::move(hole)); @@ -372,18 +372,18 @@ SECTION("polygon with empty hole") { SECTION("polygon with hole with invalid winding order") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(3,0); - ring.add_coord(3,3); - ring.add_coord(0,3); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(3,0); + ring.emplace_back(3,3); + ring.emplace_back(0,3); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; - hole.add_coord(1,1); - hole.add_coord(2,1); - hole.add_coord(2,2); - hole.add_coord(1,2); - hole.add_coord(1,1); + hole.emplace_back(1,1); + hole.emplace_back(2,1); + hole.emplace_back(2,2); + hole.emplace_back(1,2); + hole.emplace_back(1,1); poly.add_hole(std::move(hole)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; @@ -398,19 +398,19 @@ SECTION("multi polygon") { mapnik::geometry::multi_polygon mp; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(1,0); - ring.add_coord(1,1); - ring.add_coord(0,1); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(1,0); + ring.emplace_back(1,1); + ring.emplace_back(0,1); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; - ring2.add_coord(0,0); - ring2.add_coord(-1,0); - ring2.add_coord(-1,-1); - ring2.add_coord(0,-1); - ring2.add_coord(0,0); + ring2.emplace_back(0,0); + ring2.emplace_back(-1,0); + ring2.emplace_back(-1,-1); + ring2.emplace_back(0,-1); + ring2.emplace_back(0,0); poly2.set_exterior_ring(std::move(ring2)); mp.emplace_back(poly); mp.emplace_back(poly2); @@ -427,33 +427,33 @@ SECTION("multi polygon with hole") { mapnik::geometry::multi_polygon mp; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0,0); - ring.add_coord(3,0); - ring.add_coord(3,3); - ring.add_coord(0,3); - ring.add_coord(0,0); + ring.emplace_back(0,0); + ring.emplace_back(3,0); + ring.emplace_back(3,3); + ring.emplace_back(0,3); + ring.emplace_back(0,0); poly.set_exterior_ring(std::move(ring)); mapnik::geometry::linear_ring hole; - hole.add_coord(1,1); - hole.add_coord(1,2); - hole.add_coord(2,2); - hole.add_coord(2,1); - hole.add_coord(1,1); + hole.emplace_back(1,1); + hole.emplace_back(1,2); + hole.emplace_back(2,2); + hole.emplace_back(2,1); + hole.emplace_back(1,1); poly.add_hole(std::move(hole)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; - ring2.add_coord(0,0); - ring2.add_coord(-3,0); - ring2.add_coord(-3,-3); - ring2.add_coord(0,-3); - ring2.add_coord(0,0); + ring2.emplace_back(0,0); + ring2.emplace_back(-3,0); + ring2.emplace_back(-3,-3); + ring2.emplace_back(0,-3); + ring2.emplace_back(0,0); poly2.set_exterior_ring(std::move(ring2)); mapnik::geometry::linear_ring hole2; - hole2.add_coord(-1,-1); - hole2.add_coord(-1,-2); - hole2.add_coord(-2,-2); - hole2.add_coord(-2,-1); - hole2.add_coord(-1,-1); + hole2.emplace_back(-1,-1); + hole2.emplace_back(-1,-2); + hole2.emplace_back(-2,-2); + hole2.emplace_back(-2,-1); + hole2.emplace_back(-1,-1); poly2.add_hole(std::move(hole2)); mp.emplace_back(poly); mp.emplace_back(poly2); diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp index 06fe1afd9..669081d57 100644 --- a/test/unit/geometry/has_empty.cpp +++ b/test/unit/geometry/has_empty.cpp @@ -34,7 +34,7 @@ SECTION("geometry collection") { mapnik::geometry::geometry_collection geom; mapnik::geometry::multi_line_string mls; mapnik::geometry::line_string line; - line.add_coord(0, 0); + line.emplace_back(0, 0); mls.emplace_back(std::move(line)); geom.emplace_back(std::move(mls)); REQUIRE(!mapnik::geometry::has_empty(geom)); @@ -55,9 +55,9 @@ SECTION("linestring") { } { mapnik::geometry::line_string line; - line.add_coord(0, 0); - line.add_coord(25, 25); - line.add_coord(50, 50); + line.emplace_back(0, 0); + line.emplace_back(25, 25); + line.emplace_back(50, 50); REQUIRE(!mapnik::geometry::has_empty(line)); } } @@ -77,11 +77,11 @@ SECTION("polygon") { { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0, 0); - ring.add_coord(1, 0); - ring.add_coord(1, 1); - ring.add_coord(0, 1); - ring.add_coord(0, 0); + ring.emplace_back(0, 0); + ring.emplace_back(1, 0); + ring.emplace_back(1, 1); + ring.emplace_back(0, 1); + ring.emplace_back(0, 0); poly.set_exterior_ring(std::move(ring)); REQUIRE(!mapnik::geometry::has_empty(poly)); } @@ -95,9 +95,9 @@ SECTION("multi-point") { } { mapnik::geometry::multi_point geom; - geom.add_coord(0, 0); - geom.add_coord(25, 25); - geom.add_coord(50, 50); + geom.emplace_back(0, 0); + geom.emplace_back(25, 25); + geom.emplace_back(50, 50); REQUIRE(!mapnik::geometry::has_empty(geom)); } } @@ -117,7 +117,7 @@ SECTION("multi-linestring") { { mapnik::geometry::multi_line_string geom; mapnik::geometry::line_string line; - line.add_coord(0, 0); + line.emplace_back(0, 0); geom.emplace_back(std::move(line)); REQUIRE(!mapnik::geometry::has_empty(geom)); } @@ -141,7 +141,7 @@ SECTION("multi-polygon") { mapnik::geometry::multi_polygon geom; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0, 0); + ring.emplace_back(0, 0); poly.set_exterior_ring(std::move(ring)); geom.emplace_back(std::move(poly)); REQUIRE(!mapnik::geometry::has_empty(geom)); diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp index af67fe21a..2a440ecfa 100644 --- a/test/unit/geometry/is_empty.cpp +++ b/test/unit/geometry/is_empty.cpp @@ -38,9 +38,9 @@ SECTION("linestring") { } { mapnik::geometry::line_string line; - line.add_coord(0, 0); - line.add_coord(25, 25); - line.add_coord(50, 50); + line.emplace_back(0, 0); + line.emplace_back(25, 25); + line.emplace_back(50, 50); REQUIRE(!mapnik::geometry::is_empty(line)); } } @@ -60,11 +60,11 @@ SECTION("polygon") { { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0, 0); - ring.add_coord(1, 0); - ring.add_coord(1, 1); - ring.add_coord(0, 1); - ring.add_coord(0, 0); + ring.emplace_back(0, 0); + ring.emplace_back(1, 0); + ring.emplace_back(1, 1); + ring.emplace_back(0, 1); + ring.emplace_back(0, 0); poly.set_exterior_ring(std::move(ring)); REQUIRE(!mapnik::geometry::is_empty(poly)); } @@ -78,9 +78,9 @@ SECTION("multi-point") { } { mapnik::geometry::multi_point geom; - geom.add_coord(0, 0); - geom.add_coord(25, 25); - geom.add_coord(50, 50); + geom.emplace_back(0, 0); + geom.emplace_back(25, 25); + geom.emplace_back(50, 50); REQUIRE(!mapnik::geometry::is_empty(geom)); } } diff --git a/test/unit/geometry/remove_empty.cpp b/test/unit/geometry/remove_empty.cpp index 93881c854..9f277ef95 100644 --- a/test/unit/geometry/remove_empty.cpp +++ b/test/unit/geometry/remove_empty.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -19,9 +18,9 @@ SECTION("multi-linestring") { using geom_type = mapnik::geometry::multi_line_string; geom_type geom; mapnik::geometry::line_string line; - line.add_coord(0, 0); - line.add_coord(0, 25); - line.add_coord(0, 50); + line.emplace_back(0, 0); + line.emplace_back(0, 25); + line.emplace_back(0, 50); geom.emplace_back(std::move(line)); geom.emplace_back(); @@ -37,11 +36,11 @@ SECTION("multi-polygon") { geom_type geom; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - ring.add_coord(0, 0); - ring.add_coord(1, 0); - ring.add_coord(1, 1); - ring.add_coord(0, 1); - ring.add_coord(0, 0); + ring.emplace_back(0, 0); + ring.emplace_back(1, 0); + ring.emplace_back(1, 1); + ring.emplace_back(0, 1); + ring.emplace_back(0, 0); poly.set_exterior_ring(std::move(ring)); geom.emplace_back(std::move(poly)); geom.emplace_back(); diff --git a/test/unit/vertex_adapter/vertex_adapter.cpp b/test/unit/vertex_adapter/vertex_adapter.cpp index da3e815fa..53acdd7a0 100644 --- a/test/unit/vertex_adapter/vertex_adapter.cpp +++ b/test/unit/vertex_adapter/vertex_adapter.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -8,10 +7,10 @@ TEST_CASE("vertex_adapters") { SECTION("polygon") { mapnik::geometry::polygon g; - g.exterior_ring.add_coord(1,1); - g.exterior_ring.add_coord(2,2); - g.exterior_ring.add_coord(100,100); - g.exterior_ring.add_coord(1,1); + g.exterior_ring.emplace_back(1,1); + g.exterior_ring.emplace_back(2,2); + g.exterior_ring.emplace_back(100,100); + g.exterior_ring.emplace_back(1,1); mapnik::geometry::polygon_vertex_adapter va(g); double x,y; @@ -47,26 +46,26 @@ SECTION("polygon") { SECTION("polygon with hole") { mapnik::geometry::polygon g; - g.exterior_ring.add_coord(0,0); - g.exterior_ring.add_coord(-10,0); - g.exterior_ring.add_coord(-10,10); - g.exterior_ring.add_coord(0,10); - g.exterior_ring.add_coord(0,0); + g.exterior_ring.emplace_back(0,0); + g.exterior_ring.emplace_back(-10,0); + g.exterior_ring.emplace_back(-10,10); + g.exterior_ring.emplace_back(0,10); + g.exterior_ring.emplace_back(0,0); std::vector > interior_rings; mapnik::geometry::linear_ring hole; - hole.add_coord(-7,7); - hole.add_coord(-7,3); - hole.add_coord(-3,3); - hole.add_coord(-3,7); - hole.add_coord(-7,7); + hole.emplace_back(-7,7); + hole.emplace_back(-7,3); + hole.emplace_back(-3,3); + hole.emplace_back(-3,7); + hole.emplace_back(-7,7); g.add_hole(std::move(hole)); mapnik::geometry::linear_ring hole_in_hole; - hole_in_hole.add_coord(-6,4); - hole_in_hole.add_coord(-6,6); - hole_in_hole.add_coord(-4,6); - hole_in_hole.add_coord(-4,4); - hole_in_hole.add_coord(-6,4); + hole_in_hole.emplace_back(-6,4); + hole_in_hole.emplace_back(-6,6); + hole_in_hole.emplace_back(-4,6); + hole_in_hole.emplace_back(-4,4); + hole_in_hole.emplace_back(-6,4); g.add_hole(std::move(hole_in_hole)); mapnik::geometry::polygon_vertex_adapter va(g); From 66da9cdb182944978c2778589169e07a31d0b800 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 27 Jun 2016 10:56:38 +0100 Subject: [PATCH 15/51] using linear_ring = mapbox::geometry::linear_ring; --- include/mapnik/geometry/polygon.hpp | 16 ++---- include/mapnik/geometry_envelope_impl.hpp | 63 +++++++++-------------- test/unit/geometry/geometry_equal.hpp | 12 +++-- 3 files changed, 34 insertions(+), 57 deletions(-) diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp index 193aac485..cbbf3542a 100644 --- a/include/mapnik/geometry/polygon.hpp +++ b/include/mapnik/geometry/polygon.hpp @@ -23,8 +23,8 @@ #ifndef MAPNIK_GEOMETRY_POLYGON_HPP #define MAPNIK_GEOMETRY_POLYGON_HPP -// mapnik -#include +// geometry +#include // stl #include @@ -32,17 +32,7 @@ namespace mapnik { namespace geometry { template -struct linear_ring : line_string -{ - using coordinate_type = T; - linear_ring() = default; - explicit linear_ring(std::size_t size) - : line_string(size) {} - linear_ring(line_string && other) - : line_string(std::move(other)) {} - linear_ring(line_string const& other) - : line_string(other) {} -}; +using linear_ring = mapbox::geometry::linear_ring; template using rings_container = std::vector>; diff --git a/include/mapnik/geometry_envelope_impl.hpp b/include/mapnik/geometry_envelope_impl.hpp index bcce1cefb..c41c8390d 100644 --- a/include/mapnik/geometry_envelope_impl.hpp +++ b/include/mapnik/geometry_envelope_impl.hpp @@ -57,58 +57,22 @@ struct geometry_envelope void operator() (mapnik::geometry::line_string const& line) const { - bool first = true; - for (auto const& pt : line) - { - if (first && !bbox.valid()) - { - bbox.init(pt.x, pt.y, pt.x, pt.y); - first = false; - } - else - { - bbox.expand_to_include(pt.x, pt.y); - } - } + _envelope_impl(line, bbox); } void operator() (mapnik::geometry::linear_ring const& ring) const { - (*this)(static_cast const&>(ring)); + _envelope_impl(ring, bbox); } void operator() (mapnik::geometry::polygon const& poly) const { - bool first = true; - for (auto const& pt : poly.exterior_ring) - { - if (first && !bbox.valid()) - { - bbox.init(pt.x, pt.y, pt.x, pt.y); - first = false; - } - else - { - bbox.expand_to_include(pt.x, pt.y); - } - } + _envelope_impl(poly.exterior_ring, bbox); } void operator() (mapnik::geometry::multi_point const& multi_point) const { - bool first = true; - for (auto const& pt : multi_point) - { - if (first && !bbox.valid()) - { - bbox.init(pt.x, pt.y, pt.x, pt.y); - first = false; - } - else - { - bbox.expand_to_include(pt.x, pt.y); - } - } + _envelope_impl(multi_point, bbox); } void operator() (mapnik::geometry::multi_line_string const& multi_line) const @@ -134,6 +98,25 @@ struct geometry_envelope (*this)(geom); } } + +private: + template + void _envelope_impl(Points const& points, bbox_type & b) const + { + bool first = true; + for (auto const& pt : points) + { + if (first && !b.valid()) + { + b.init(pt.x, pt.y, pt.x, pt.y); + first = false; + } + else + { + b.expand_to_include(pt.x, pt.y); + } + } + } }; } // end ns detail diff --git a/test/unit/geometry/geometry_equal.hpp b/test/unit/geometry/geometry_equal.hpp index cdcdb0470..770e9079e 100644 --- a/test/unit/geometry/geometry_equal.hpp +++ b/test/unit/geometry/geometry_equal.hpp @@ -137,7 +137,8 @@ struct geometry_equal_visitor template void operator() (polygon const& p1, polygon const& p2) const { - (*this)(static_cast const&>(p1.exterior_ring), static_cast const&>(p2.exterior_ring)); + (*this)(static_cast> const&>(p1.exterior_ring), + static_cast> const&>(p2.exterior_ring)); if (p1.interior_rings.size() != p2.interior_rings.size()) { @@ -146,20 +147,23 @@ struct geometry_equal_visitor for (auto const& p : zip_crange(p1.interior_rings, p2.interior_rings)) { - (*this)(static_cast const&>(p.template get<0>()),static_cast const&>(p.template get<1>())); + (*this)(static_cast> const&>(p.template get<0>()), + static_cast> const&>(p.template get<1>())); } } template void operator() (line_string const& ls1, line_string const& ls2) const { - (*this)(static_cast> const&>(ls1), static_cast> const&>(ls2)); + (*this)(static_cast> const&>(ls1), + static_cast> const&>(ls2)); } template void operator() (multi_point const& mp1, multi_point const& mp2) const { - (*this)(static_cast> const&>(mp1), static_cast> const&>(mp2)); + (*this)(static_cast> const&>(mp1), + static_cast> const&>(mp2)); } From 71496e78282b21f3cf411b8fd9a2425fc6beb16e Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 27 Jun 2016 16:49:30 -0700 Subject: [PATCH 16/51] install geometry.hpp --- deps/mapnik/build.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deps/mapnik/build.py b/deps/mapnik/build.py index 76529fbda..dff5f70e7 100644 --- a/deps/mapnik/build.py +++ b/deps/mapnik/build.py @@ -7,7 +7,9 @@ subdirs = { './sparsehash':{'dir':'sparsehash','glob':'*'}, './sparsehash/internal':{'dir':'sparsehash/internal','glob':'*'}, '../agg/include':{'dir':'agg','glob':'agg*'}, - '../mapbox/variant/include':{'dir':'mapbox','glob':'*/*.hpp'} + '../mapbox/variant/include':{'dir':'mapbox','glob':'*/*.hpp'}, + '../mapbox/geometry/include':{'dir':'mapbox','glob':'*/*.hpp'}, + '../mapbox/geometry/include/mapbox':{'dir':'mapbox/geometry','glob':'*/*.hpp'} } if 'install' in COMMAND_LINE_TARGETS: From efabcc80810ea9917c3aa37ea160ae01726bb554 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 29 Jun 2016 12:37:32 +0100 Subject: [PATCH 17/51] make all mapnik::geometries aliases to mapbox::geometry and attempt to adapt new polygon model (one std::vector) NOTE: some boost.geometry algorithms are broken as a result --- benchmark/build.py | 2 +- benchmark/test_polygon_clipping.cpp | 9 +- include/mapnik/geometry/multi_line_string.hpp | 13 +- include/mapnik/geometry/multi_point.hpp | 20 +- include/mapnik/geometry/multi_polygon.hpp | 13 +- include/mapnik/geometry/polygon.hpp | 8 +- include/mapnik/geometry_adapters.hpp | 30 +- include/mapnik/geometry_envelope_impl.hpp | 2 +- include/mapnik/geometry_fusion_adapted.hpp | 16 +- include/mapnik/geometry_is_empty.hpp | 12 +- include/mapnik/geometry_reprojection_impl.hpp | 49 +-- include/mapnik/geometry_to_path.hpp | 27 +- include/mapnik/hit_test_filter.hpp | 53 +-- .../json/geometry_generator_grammar.hpp | 6 +- .../json/geometry_generator_grammar_impl.hpp | 10 +- include/mapnik/json/geometry_util.hpp | 16 +- include/mapnik/json/topojson_utils.hpp | 26 +- include/mapnik/util/geometry_to_wkb.hpp | 21 +- .../util/spirit_transform_attribute.hpp | 40 +-- include/mapnik/wkt/wkt_generator_grammar.hpp | 4 +- .../mapnik/wkt/wkt_generator_grammar_impl.hpp | 6 +- include/mapnik/wkt/wkt_grammar.hpp | 16 +- include/mapnik/wkt/wkt_grammar_impl.hpp | 6 +- plugins/input/ogr/ogr_converter.cpp | 4 +- plugins/input/shape/shape_io.cpp | 16 +- src/agg/process_debug_symbolizer.cpp | 28 +- src/twkb.cpp | 9 +- src/vertex_adapters.cpp | 15 +- src/wkb.cpp | 9 +- test/unit/datasource/geojson.cpp | 11 +- test/unit/geometry/centroid.cpp | 13 +- test/unit/geometry/geometry_envelope_test.cpp | 8 +- test/unit/geometry/geometry_equal.hpp | 7 +- test/unit/geometry/geometry_hit_test.cpp | 8 +- test/unit/geometry/geometry_is_simple.cpp | 43 +-- test/unit/geometry/geometry_is_valid.cpp | 35 +- test/unit/geometry/geometry_reprojection.cpp | 319 ++++++++++-------- test/unit/geometry/geometry_strategy_test.cpp | 5 +- test/unit/geometry/has_empty.cpp | 10 +- test/unit/geometry/is_empty.cpp | 8 +- test/unit/geometry/remove_empty.cpp | 6 +- test/unit/vertex_adapter/vertex_adapter.cpp | 26 +- 42 files changed, 477 insertions(+), 508 deletions(-) diff --git a/benchmark/build.py b/benchmark/build.py index 37ba86707..b964ea78e 100644 --- a/benchmark/build.py +++ b/benchmark/build.py @@ -35,7 +35,7 @@ benchmarks = [ #"test_to_double.cpp", #"test_to_int.cpp", #"test_utf_encoding.cpp" - "test_polygon_clipping.cpp", + #"test_polygon_clipping.cpp", #"test_polygon_clipping_rendering.cpp", "test_proj_transform1.cpp", "test_expression_parse.cpp", diff --git a/benchmark/test_polygon_clipping.cpp b/benchmark/test_polygon_clipping.cpp index b9ded3eea..d10911a42 100644 --- a/benchmark/test_polygon_clipping.cpp +++ b/benchmark/test_polygon_clipping.cpp @@ -128,7 +128,7 @@ public: } ring.emplace_back(x,y); } - poly2.set_exterior_ring(std::move(ring)); + poly2.push_back(std::move(ring)); // interior rings ring.clear(); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) @@ -140,7 +140,7 @@ public: else if (cmd == mapnik::SEG_CLOSE) { ring.emplace_back(x0,y0); - poly2.add_hole(std::move(ring)); + poly2.push_back(std::move(ring)); ring.clear(); continue; } @@ -520,7 +520,7 @@ int main(int argc, char** argv) // RECT : POLYGON ((181 106, 181 470, 631 470, 631 106, 181 106)) // OUT (expected) // POLYGON ((181 286.6666666666667, 233 454, 315 340, 421 446, 463 324, 559 466, 631 321.3207547169811, 631 234.38686131386862, 528 178, 394 229, 329 138, 212 134, 183 228, 200 264, 181 238.24444444444444, 181 286.6666666666667),(313 190, 440 256, 470 248, 510 305, 533 237, 613 263, 553 397, 455 262, 405 378, 343 287, 249 334, 229 191, 313 190)) - +#if 0 mapnik::box2d clipping_box(181,106,631,470); std::string filename_("./benchmark/data/polygon.wkt"); std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary); @@ -543,5 +543,6 @@ int main(int argc, char** argv) return_value = return_value | run(test_runner,"clipping polygon with clipper_tree"); } */ - return return_value; +#endif + return 0;// return_value; } diff --git a/include/mapnik/geometry/multi_line_string.hpp b/include/mapnik/geometry/multi_line_string.hpp index f6a9a7ae1..7c77229e2 100644 --- a/include/mapnik/geometry/multi_line_string.hpp +++ b/include/mapnik/geometry/multi_line_string.hpp @@ -23,18 +23,13 @@ #ifndef MAPNIK_GEOMETRY_MULTI_LINE_STRING_HPP #define MAPNIK_GEOMETRY_MULTI_LINE_STRING_HPP -// mapnik -#include -// stl -#include +// geometry +#include namespace mapnik { namespace geometry { -template class Cont = std::vector> -struct multi_line_string : Cont> -{ - using coordinate_type = T; -}; +template +using multi_line_string = mapbox::geometry::multi_line_string; }} diff --git a/include/mapnik/geometry/multi_point.hpp b/include/mapnik/geometry/multi_point.hpp index 78cf504c3..908e7c011 100644 --- a/include/mapnik/geometry/multi_point.hpp +++ b/include/mapnik/geometry/multi_point.hpp @@ -23,25 +23,13 @@ #ifndef MAPNIK_GEOMETRY_MULTI_POINT_HPP #define MAPNIK_GEOMETRY_MULTI_POINT_HPP -// mapnik -#include -// stl -#include +// geometry +#include namespace mapnik { namespace geometry { -template class Cont = std::vector> -struct multi_point : Cont> -{ - using coordinate_type = T; - using point_type = point; - using container_type = Cont; - multi_point() = default; - explicit multi_point(std::size_t size) - : container_type(size) {} - inline std::size_t num_points() const { return container_type::size(); } - inline void add_coord(T x, T y) { container_type::template emplace_back(x, y);} -}; +template +using multi_point = mapbox::geometry::multi_point; }} diff --git a/include/mapnik/geometry/multi_polygon.hpp b/include/mapnik/geometry/multi_polygon.hpp index 44127cdd8..fdf28437a 100644 --- a/include/mapnik/geometry/multi_polygon.hpp +++ b/include/mapnik/geometry/multi_polygon.hpp @@ -23,18 +23,13 @@ #ifndef MAPNIK_GEOMETRY_MULTI_POLYGON_HPP #define MAPNIK_GEOMETRY_MULTI_POLYGON_HPP -// mapnik -#include -// stl -#include +// geometry +#include namespace mapnik { namespace geometry { -template class Cont = std::vector> -struct multi_polygon : Cont> -{ - using coordinate_type = T; -}; +template +using multi_polygon = mapbox::geometry::multi_polygon; }} diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp index cbbf3542a..378e8ae8d 100644 --- a/include/mapnik/geometry/polygon.hpp +++ b/include/mapnik/geometry/polygon.hpp @@ -27,13 +27,18 @@ #include // stl -#include +//#include namespace mapnik { namespace geometry { template using linear_ring = mapbox::geometry::linear_ring; +template +using polygon = mapbox::geometry::polygon; + + +/* template using rings_container = std::vector>; @@ -62,6 +67,7 @@ struct polygon return 1 + interior_rings.size(); } }; +*/ }} diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp index 7a708463a..c102b138f 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry_adapters.hpp @@ -37,7 +37,7 @@ // and once we do that the compile time is == to just including boost/geometry.hpp #include #pragma GCC diagnostic pop - +#include #include #include #include @@ -82,7 +82,9 @@ template inline typename mapnik::geometry::line_string::const_iterator range_end(mapnik::geometry::line_string const& line) {return line.end();} -namespace geometry { namespace traits { +namespace geometry { + +namespace traits { // register mapnik::box2d template<> struct tag > { using type = box_tag; }; @@ -175,13 +177,13 @@ struct ring_mutable_type > template struct interior_const_type > { - using type = typename mapnik::geometry::polygon::rings_container const&; + using type = boost::iterator_range::const_iterator>; }; template struct interior_mutable_type > { - using type = typename mapnik::geometry::polygon::rings_container&; + using type = boost::iterator_range::iterator>; }; // exterior @@ -190,27 +192,33 @@ struct exterior_ring > { static mapnik::geometry::linear_ring & get(mapnik::geometry::polygon & p) { - return p.exterior_ring; + if (p.empty()) p.emplace_back(); + return p.at(0); } static mapnik::geometry::linear_ring const& get(mapnik::geometry::polygon const& p) { - return p.exterior_ring; + return p.at(0); } }; template struct interior_rings > { - using holes_type = typename mapnik::geometry::polygon::rings_container; - static holes_type& get(mapnik::geometry::polygon & p) + using ring_iterator = typename mapbox::geometry::polygon::iterator; + using const_ring_iterator = typename mapbox::geometry::polygon::const_iterator; + using holes_type = boost::iterator_range; + using const_holes_type = boost::iterator_range; + static holes_type get(mapnik::geometry::polygon & p) + // -> decltype(boost::make_iterator_range(p.begin() + 1, p.end())) { - return p.interior_rings; + return boost::make_iterator_range(p.begin() + 1, p.end()); } - static holes_type const& get(mapnik::geometry::polygon const& p) + static const_holes_type get(mapnik::geometry::polygon const& p) + // -> decltype(boost::make_iterator_range(p.begin() + 1, p.end())) const { - return p.interior_rings; + return boost::make_iterator_range(p.begin() + 1, p.end()); } }; diff --git a/include/mapnik/geometry_envelope_impl.hpp b/include/mapnik/geometry_envelope_impl.hpp index c41c8390d..692481131 100644 --- a/include/mapnik/geometry_envelope_impl.hpp +++ b/include/mapnik/geometry_envelope_impl.hpp @@ -67,7 +67,7 @@ struct geometry_envelope void operator() (mapnik::geometry::polygon const& poly) const { - _envelope_impl(poly.exterior_ring, bbox); + if (!poly.empty()) _envelope_impl(poly[0], bbox); } void operator() (mapnik::geometry::multi_point const& multi_point) const diff --git a/include/mapnik/geometry_fusion_adapted.hpp b/include/mapnik/geometry_fusion_adapted.hpp index 8bc53046d..8430d4f48 100644 --- a/include/mapnik/geometry_fusion_adapted.hpp +++ b/include/mapnik/geometry_fusion_adapted.hpp @@ -39,14 +39,14 @@ BOOST_FUSION_ADAPT_STRUCT( (std::int64_t, y) ) -BOOST_FUSION_ADAPT_STRUCT( - mapnik::geometry::polygon, - (mapnik::geometry::linear_ring const&, exterior_ring) - (mapnik::geometry::polygon::rings_container const& , interior_rings)) +//BOOST_FUSION_ADAPT_STRUCT( +// mapnik::geometry::polygon, +// (mapnik::geometry::linear_ring const&, exterior_ring) +// (mapnik::geometry::polygon::rings_container const& , interior_rings)) -BOOST_FUSION_ADAPT_STRUCT( - mapnik::geometry::polygon, - (mapnik::geometry::linear_ring const&, exterior_ring) - (mapnik::geometry::polygon::rings_container const& , interior_rings)) +//BOOST_FUSION_ADAPT_STRUCT( +// mapnik::geometry::polygon, +// (mapnik::geometry::linear_ring const&, exterior_ring) +// (mapnik::geometry::polygon::rings_container const& , interior_rings)) #endif // MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP diff --git a/include/mapnik/geometry_is_empty.hpp b/include/mapnik/geometry_is_empty.hpp index d3c0fa548..3315d317d 100644 --- a/include/mapnik/geometry_is_empty.hpp +++ b/include/mapnik/geometry_is_empty.hpp @@ -47,6 +47,11 @@ struct geometry_is_empty return geom.empty(); } + bool operator() (mapnik::geometry::linear_ring const& geom) const + { + return geom.empty(); + } + bool operator() (mapnik::geometry::polygon const& geom) const { return geom.empty(); @@ -103,6 +108,11 @@ struct geometry_has_empty return false; } + bool operator() (mapnik::geometry::linear_ring const&) const + { + return false; + } + bool operator() (mapnik::geometry::polygon const&) const { return false; @@ -145,7 +155,7 @@ private: template bool test_multigeometry(U const & geom) const { - for (auto const & item : geom) + for (auto const& item : geom) { if (item.empty()) { diff --git a/include/mapnik/geometry_reprojection_impl.hpp b/include/mapnik/geometry_reprojection_impl.hpp index 7c20f6830..d76e84081 100644 --- a/include/mapnik/geometry_reprojection_impl.hpp +++ b/include/mapnik/geometry_reprojection_impl.hpp @@ -20,8 +20,7 @@ * *****************************************************************************/ -// mapnik -#include +// mapnik #include namespace mapnik { @@ -63,31 +62,22 @@ template polygon reproject_internal(polygon const& poly, proj_transform const& proj_trans, unsigned int & n_err) { polygon new_poly; - linear_ring new_ext(poly.exterior_ring); - unsigned int err = proj_trans.forward(new_ext); - // If the exterior ring doesn't transform don't bother with the holes. - if (err > 0 || new_ext.empty()) + new_poly.reserve(poly.size()); + bool exterior = true; + for (auto const& lr : poly) { - n_err += err; - } - else - { - new_poly.set_exterior_ring(std::move(new_ext)); - new_poly.interior_rings.reserve(poly.interior_rings.size()); - - for (auto const& lr : poly.interior_rings) + linear_ring new_lr(lr); + unsigned int err = proj_trans.forward(new_lr); + if (err > 0 || new_lr.empty()) { - linear_ring new_lr(lr); - err = proj_trans.forward(new_lr); - if (err > 0 || new_lr.empty()) - { - n_err += err; - // If there is an error in interior ring drop - // it from polygon. - continue; - } - new_poly.add_hole(std::move(new_lr)); + n_err += err; + // If there is an error in interior ring drop + // it from polygon. + if (!exterior) continue; } + if (exterior) exterior = false; + new_poly.push_back(std::move(new_lr)); + } return new_poly; } @@ -146,7 +136,7 @@ multi_polygon reproject_internal(multi_polygon const & mpoly, proj_transfo for (auto const& poly : mpoly) { polygon new_poly = reproject_internal(poly, proj_trans, n_err); - if (!new_poly.exterior_ring.empty()) + if (new_poly.size() > 0 && !new_poly[0].empty()) { new_mpoly.emplace_back(std::move(new_poly)); } @@ -208,7 +198,7 @@ struct geom_reproj_copy_visitor { geometry geom; // default empty polygon new_poly = reproject_internal(poly, proj_trans_, n_err_); - if (new_poly.exterior_ring.empty()) return geom; + if (new_poly.size() == 0 || new_poly[0].size() == 0) return geom; geom = std::move(new_poly); return geom; } @@ -316,12 +306,7 @@ struct geom_reproj_visitor { template bool operator() (polygon & poly) const { - if (proj_trans_.forward(poly.exterior_ring) > 0) - { - return false; - } - - for (auto & lr : poly.interior_rings) + for (auto & lr : poly) { if (proj_trans_.forward(lr) > 0) { diff --git a/include/mapnik/geometry_to_path.hpp b/include/mapnik/geometry_to_path.hpp index 361747d08..2aadbc200 100644 --- a/include/mapnik/geometry_to_path.hpp +++ b/include/mapnik/geometry_to_path.hpp @@ -67,31 +67,14 @@ struct geometry_to_path // polygon void operator() (polygon const& poly) const { - // exterior - bool first = true; - for (auto const& pt : poly.exterior_ring) + // rings: exterior *interior + for (auto const& ring : poly) { - if (first) - { - p_.move_to(pt.x, pt.y); - first=false; - } - else - { - p_.line_to(pt.x, pt.y); - } - } - if (!first) - { - p_.close_path(); - } - // interior - for (auto const& ring : poly.interior_rings) - { - first = true; + bool first = true; for (auto const& pt : ring) { - if (first) { + if (first) + { p_.move_to(pt.x, pt.y); first=false; } diff --git a/include/mapnik/hit_test_filter.hpp b/include/mapnik/hit_test_filter.hpp index a74910e70..fd9fb443c 100644 --- a/include/mapnik/hit_test_filter.hpp +++ b/include/mapnik/hit_test_filter.hpp @@ -89,41 +89,48 @@ struct hit_test_visitor } return false; } - bool operator() (geometry::polygon const& geom) const + bool operator() (geometry::polygon const& poly) const { - auto const& exterior = geom.exterior_ring; - std::size_t num_points = exterior.size(); - if (num_points < 4) return false; - bool inside = false; - for (std::size_t i = 1; i < num_points; ++i) - { - auto const& pt0 = exterior[i-1]; - auto const& pt1 = exterior[i]; + //auto const& exterior = geom.exterior_ring; + //std::size_t num_points = exterior.size(); + //if (num_points < 4) return false; + + //for (std::size_t i = 1; i < num_points; ++i) + //{ + // auto const& pt0 = exterior[i-1]; + // auto const& pt1 = exterior[i]; // todo - account for tolerance - if (pip(pt0.x,pt0.y,pt1.x,pt1.y,x_,y_)) - { - inside = !inside; - } - } - if (!inside) return false; - for (auto const& ring : geom.interior_rings) + // if (pip(pt0.x,pt0.y,pt1.x,pt1.y,x_,y_)) + // { + // inside = !inside; + // } + //} + //if (!inside) return false; + + //// FIXME !!! + bool inside = false; + bool exterior = true; + for (auto const& ring : poly) { - std::size_t num_interior_points = ring.size(); - if (num_interior_points < 4) + std::size_t num_points = ring.size(); + if (num_points < 4) { - continue; + if (exterior) return false; + else continue; } - for (std::size_t j = 1; j < num_interior_points; ++j) + + for (std::size_t j = 1; j < num_points; ++j) { - auto const& pt0 = ring[j-1]; + auto const& pt0 = ring[j - 1]; auto const& pt1 = ring[j]; - if (pip(pt0.x,pt0.y,pt1.x,pt1.y,x_,y_)) + if (pip(pt0.x, pt0.y, pt1.x, pt1.y, x_, y_)) { // TODO - account for tolerance - inside=!inside; + inside = !inside; } } } + //////////////////////////// return inside; } bool operator() (geometry::multi_polygon const& geom) const diff --git a/include/mapnik/json/geometry_generator_grammar.hpp b/include/mapnik/json/geometry_generator_grammar.hpp index 0e314650b..8e24ebaf0 100644 --- a/include/mapnik/json/geometry_generator_grammar.hpp +++ b/include/mapnik/json/geometry_generator_grammar.hpp @@ -96,11 +96,11 @@ struct geometry_generator_grammar : karma::rule const&()> point; karma::rule const&()> point_coord; karma::rule const&()> linestring; - karma::rule const&()> linestring_coord; + karma::rule::container_type const&()> linestring_coord; karma::rule const&()> polygon; karma::rule const&()> polygon_coord; - karma::rule const&()> exterior_ring_coord; - karma::rule::rings_container const&()> interior_ring_coord; + //karma::rule const&()> exterior_ring_coord; + //karma::rule const&()> polygon_coord; karma::rule const& ()> multi_point; karma::rule const& ()> multi_point_coord; karma::rule const& ()> multi_linestring; diff --git a/include/mapnik/json/geometry_generator_grammar_impl.hpp b/include/mapnik/json/geometry_generator_grammar_impl.hpp index 87a60db70..dc37a76d7 100644 --- a/include/mapnik/json/geometry_generator_grammar_impl.hpp +++ b/include/mapnik/json/geometry_generator_grammar_impl.hpp @@ -98,12 +98,12 @@ geometry_generator_grammar::geometry_generator_grammar ; linestring_coord = point_coord % lit(',') ; - polygon_coord = lit('[') << exterior_ring_coord << lit(']') << interior_ring_coord - ; - exterior_ring_coord = linestring_coord.alias() - ; - interior_ring_coord = *(lit(",[") << exterior_ring_coord << lit(']')) + polygon_coord = (lit('[') << linestring_coord << lit(']')) % lit(',') //<< interior_ring_coord ; + //exterior_ring_coord = linestring_coord.alias() + // ; + //interior_ring_coord = *(lit(",[") << exterior_ring_coord << lit(']')) + // ; multi_point_coord = linestring_coord.alias() ; multi_linestring_coord = (lit('[') << linestring_coord << lit(']')) % lit(',') diff --git a/include/mapnik/json/geometry_util.hpp b/include/mapnik/json/geometry_util.hpp index cf538ae73..82c4158b0 100644 --- a/include/mapnik/json/geometry_util.hpp +++ b/include/mapnik/json/geometry_util.hpp @@ -84,10 +84,7 @@ struct create_polygon { mapnik::geometry::polygon poly; std::size_t num_rings = rings.size(); - if (num_rings > 1) - { - poly.interior_rings.reserve(num_rings - 1); - } + poly.reserve(num_rings); for ( std::size_t i = 0; i < num_rings; ++i) { @@ -98,8 +95,7 @@ struct create_polygon { ring.emplace_back(std::move(pt)); } - if (i == 0) poly.set_exterior_ring(std::move(ring)); - else poly.add_hole(std::move(ring)); + poly.push_back(std::move(ring)); } geom_ = std::move(poly); mapnik::geometry::correct(geom_); @@ -179,9 +175,7 @@ struct create_multipolygon { mapnik::geometry::polygon poly; std::size_t num_rings = rings.size(); - if ( num_rings > 1) - poly.interior_rings.reserve(num_rings - 1); - + poly.reserve(num_rings); for ( std::size_t i = 0; i < num_rings; ++i) { std::size_t size = rings[i].size(); @@ -191,8 +185,8 @@ struct create_multipolygon { ring.emplace_back(std::move(pt)); } - if (i == 0) poly.set_exterior_ring(std::move(ring)); - else poly.add_hole(std::move(ring)); + + poly.push_back(std::move(ring)); } multi_poly.emplace_back(std::move(poly)); } diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp index 0ff3262e9..dc4166475 100644 --- a/include/mapnik/json/topojson_utils.hpp +++ b/include/mapnik/json/topojson_utils.hpp @@ -406,8 +406,7 @@ struct feature_generator { std::vector processed_coords; mapnik::geometry::polygon polygon; - if (poly.rings.size() > 1) polygon.interior_rings.reserve(poly.rings.size() - 1); - bool first = true; + polygon.reserve(poly.rings.size()); bool hit = false; for (auto const& ring : poly.rings) { @@ -454,15 +453,7 @@ struct feature_generator } } } - if (first) - { - first = false; - polygon.set_exterior_ring(std::move(linear_ring)); - } - else - { - polygon.add_hole(std::move(linear_ring)); - } + polygon.push_back(std::move(linear_ring)); } if (hit) { @@ -485,9 +476,8 @@ struct feature_generator bool hit = false; for (auto const& poly : multi_poly.polygons) { - bool first = true; mapnik::geometry::polygon polygon; - if (poly.size() > 1) polygon.interior_rings.reserve(poly.size() - 1); + polygon.reserve(poly.size()); for (auto const& ring : poly) { @@ -536,15 +526,7 @@ struct feature_generator } } } - if (first) - { - first = false; - polygon.set_exterior_ring(std::move(linear_ring)); - } - else - { - polygon.add_hole(std::move(linear_ring)); - } + polygon.push_back(std::move(linear_ring)); } multi_polygon.push_back(std::move(polygon)); } diff --git a/include/mapnik/util/geometry_to_wkb.hpp b/include/mapnik/util/geometry_to_wkb.hpp index 5be50cc5b..f16ad240a 100644 --- a/include/mapnik/util/geometry_to_wkb.hpp +++ b/include/mapnik/util/geometry_to_wkb.hpp @@ -133,7 +133,7 @@ using wkb_buffer_ptr = std::unique_ptr; wkb_buffer_ptr point_wkb( geometry::point const& pt, wkbByteOrder byte_order) { - std::size_t size = 1 + 4 + 8 * 2 ; // byteOrder + wkbType + Point + std::size_t const size = 1 + 4 + 8 * 2 ; // byteOrder + wkbType + Point wkb_buffer_ptr wkb = std::make_unique(size); wkb_stream ss(wkb->buffer(), wkb->size()); ss.write(reinterpret_cast(&byte_order),1); @@ -148,7 +148,7 @@ wkb_buffer_ptr line_string_wkb(geometry::line_string const& line, wkbByt { std::size_t num_points = line.size(); assert(num_points > 1); - std::size_t size = 1 + 4 + 4 + 8 * 2 * num_points ; // byteOrder + wkbType + numPoints + Point*numPoints + std::size_t const size = 1 + 4 + 4 + 8 * 2 * num_points ; // byteOrder + wkbType + numPoints + Point*numPoints wkb_buffer_ptr wkb = std::make_unique(size); wkb_stream ss(wkb->buffer(), wkb->size()); ss.write(reinterpret_cast(&byte_order),1); @@ -167,10 +167,8 @@ wkb_buffer_ptr line_string_wkb(geometry::line_string const& line, wkbByt wkb_buffer_ptr polygon_wkb( geometry::polygon const& poly, wkbByteOrder byte_order) { std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings - size += 4 + 2 * 8 * poly.exterior_ring.size(); - for ( auto const& ring : poly.interior_rings) + for ( auto const& ring : poly) { - size += 4 + 2 * 8 * ring.size(); } @@ -178,17 +176,10 @@ wkb_buffer_ptr polygon_wkb( geometry::polygon const& poly, wkbByteOrder wkb_stream ss(wkb->buffer(), wkb->size()); ss.write(reinterpret_cast(&byte_order),1); write(ss, static_cast(mapnik::geometry::geometry_types::Polygon), 4, byte_order); - write(ss, poly.num_rings(), 4, byte_order); + write(ss, poly.size(), 4, byte_order); - // exterior - write(ss, poly.exterior_ring.size(), 4, byte_order); - for (auto const& pt : poly.exterior_ring) - { - write(ss, pt.x, 8, byte_order); - write(ss, pt.y, 8, byte_order); - } - // interiors - for (auto const& ring : poly.interior_rings) + // exterior *interior + for (auto const& ring : poly) { write(ss, ring.size(), 4, byte_order); for ( auto const& pt : ring) diff --git a/include/mapnik/util/spirit_transform_attribute.hpp b/include/mapnik/util/spirit_transform_attribute.hpp index c4176f1fa..e53d335a1 100644 --- a/include/mapnik/util/spirit_transform_attribute.hpp +++ b/include/mapnik/util/spirit_transform_attribute.hpp @@ -68,16 +68,16 @@ namespace boost { namespace spirit { namespace traits { } }; - template <> - struct transform_attribute const, - mapnik::geometry::polygon::rings_container const&, karma::domain> - { - using type = mapnik::geometry::polygon::rings_container const&; - static type pre(mapnik::geometry::polygon const& poly) - { - return poly.interior_rings; - } - }; +//template <> +// struct transform_attribute const, +// mapnik::geometry::polygon::rings_container const&, karma::domain> +// { +// using type = mapnik::geometry::polygon::rings_container const&; +// static type pre(mapnik::geometry::polygon const& poly) +// { +// return poly.interior_rings; +// } +// }; template <> struct transform_attribute const, @@ -156,16 +156,16 @@ namespace boost { namespace spirit { namespace traits { } }; - template <> - struct transform_attribute const, - mapnik::geometry::polygon::rings_container const&, karma::domain> - { - using type = mapnik::geometry::polygon::rings_container const&; - static type pre(mapnik::geometry::polygon const& poly) - { - return poly.interior_rings; - } - }; +//template <> +// struct transform_attribute const, +// mapnik::geometry::polygon::rings_container const&, karma::domain> +// { +// using type = mapnik::geometry::polygon::rings_container const&; +// static type pre(mapnik::geometry::polygon const& poly) +// { +// return poly.interior_rings; +// } +// }; template <> struct transform_attribute const, diff --git a/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp index e303c1e29..2df1bd7cc 100644 --- a/include/mapnik/wkt/wkt_generator_grammar.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar.hpp @@ -115,8 +115,8 @@ struct wkt_generator_grammar : karma::rule const&()> linestring_coord; karma::rule const&()> polygon; karma::rule const&()> polygon_coord; - karma::rule const&()> exterior_ring_coord; - karma::rule > const&()> interior_ring_coord; + karma::rule const&()> ring; + //karma::rule > const&()> interior_ring_coord; karma::rule const& ()> multi_point; karma::rule const& ()> multi_point_coord; karma::rule const& ()> multi_linestring; diff --git a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp index e6a5bfc97..ea000ca92 100644 --- a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp @@ -100,11 +100,9 @@ wkt_generator_grammar::wkt_generator_grammar() ; linestring_coord = point_coord % lit(',') ; - polygon_coord = lit('(') << exterior_ring_coord << lit(')') << interior_ring_coord + polygon_coord = ring % lit(',')//<< interior_ring_coord ; - exterior_ring_coord = linestring_coord.alias() - ; - interior_ring_coord = *(lit(",(") << exterior_ring_coord << lit(')')) + ring = lit('(') << linestring_coord << lit(')') ; multi_point_coord = linestring_coord.alias() ; diff --git a/include/mapnik/wkt/wkt_grammar.hpp b/include/mapnik/wkt/wkt_grammar.hpp index 9d23f81ca..55750b838 100644 --- a/include/mapnik/wkt/wkt_grammar.hpp +++ b/include/mapnik/wkt/wkt_grammar.hpp @@ -60,23 +60,14 @@ struct move_part } }; -struct set_exterior -{ - using result_type = void; - template - void operator() (Polygon & poly, Ring && ring) const - { - poly.set_exterior_ring(std::move(ring)); - } -}; -struct add_hole +struct set_ring { using result_type = void; template void operator() (Polygon & poly, Ring && ring) const { - poly.add_hole(std::move(ring)); + poly.push_back(std::move(ring)); } }; @@ -109,8 +100,7 @@ struct wkt_grammar : qi::grammar empty_set; boost::phoenix::function assign; boost::phoenix::function move_part; - boost::phoenix::function set_exterior; - boost::phoenix::function add_hole; + boost::phoenix::function set_ring; }; }} diff --git a/include/mapnik/wkt/wkt_grammar_impl.hpp b/include/mapnik/wkt/wkt_grammar_impl.hpp index 74d2e7ea6..33caab6bc 100644 --- a/include/mapnik/wkt/wkt_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_grammar_impl.hpp @@ -86,12 +86,14 @@ wkt_grammar::wkt_grammar() // ::= | { }* polygon_text = - (lit('(') >> linearring_text[set_exterior(_val,_1)] >> *(lit(',') >> linearring_text[add_hole(_val,_1)]) >> lit(')')) + lit('(') >> linearring_text[set_ring(_val,_1)] % lit(',') >> lit(')') | empty_set ; - linearring_text = ring_points | empty_set + linearring_text = ring_points + | + empty_set ; // ::= multipoint multipoint_tagged_text = no_case[lit("MULTIPOINT")] diff --git a/plugins/input/ogr/ogr_converter.cpp b/plugins/input/ogr/ogr_converter.cpp index 1a9d58738..e409e81a0 100644 --- a/plugins/input/ogr/ogr_converter.cpp +++ b/plugins/input/ogr/ogr_converter.cpp @@ -127,7 +127,7 @@ mapnik::geometry::polygon ogr_converter::convert_polygon(OGRPolygon* ogr { exterior.emplace_back(ogr_exterior->getX(i), ogr_exterior->getY(i)); } - geom.set_exterior_ring(std::move(exterior)); + geom.push_back(std::move(exterior)); int num_interior = ogr_geom->getNumInteriorRings(); for (int r = 0; r < num_interior; ++r) @@ -140,7 +140,7 @@ mapnik::geometry::polygon ogr_converter::convert_polygon(OGRPolygon* ogr { interior.emplace_back(ogr_interior->getX(i), ogr_interior->getY(i)); } - geom.add_hole(std::move(interior)); + geom.push_back(std::move(interior)); } return geom; } diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index bbd53a408..b5d3776e4 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -210,17 +210,17 @@ mapnik::geometry::geometry shape_io::read_polygon(shape_file::record_typ } if (k == 0) { - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); } else if (mapnik::util::is_clockwise(ring)) { multi_poly.emplace_back(std::move(poly)); - poly.interior_rings.clear(); - poly.set_exterior_ring(std::move(ring)); + poly.clear(); + poly.push_back(std::move(ring)); } else { - poly.add_hole(std::move(ring)); + poly.push_back(std::move(ring)); } } @@ -260,17 +260,17 @@ mapnik::geometry::geometry shape_io::read_polygon_parts(shape_file::reco } if (k == 0) { - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); } else if (mapnik::util::is_clockwise(ring)) { multi_poly.emplace_back(std::move(poly)); - poly.interior_rings.clear(); - poly.set_exterior_ring(std::move(ring)); + poly.clear(); + poly.push_back(std::move(ring)); } else { - poly.add_hole(std::move(ring)); + poly.push_back(std::move(ring)); } } diff --git a/src/agg/process_debug_symbolizer.cpp b/src/agg/process_debug_symbolizer.cpp index 3c3f898f8..137c2457d 100644 --- a/src/agg/process_debug_symbolizer.cpp +++ b/src/agg/process_debug_symbolizer.cpp @@ -180,22 +180,30 @@ struct render_ring_visitor } } - void operator()(mapnik::geometry::polygon const& geom) const + void operator()(mapnik::geometry::polygon const& poly) const { agg::rgba8 red(255,0,0,255); agg::rgba8 green(0,255,255,255); agg::rgba8 black(0,0,0,255); - renderer_.draw_ring(geom.exterior_ring,red); - if (mapnik::util::is_clockwise(geom.exterior_ring)) + bool exterior = true; + for (auto const& ring : poly) { - renderer_.draw_outline(geom.exterior_ring,black); - } - for (auto const& ring : geom.interior_rings) - { - renderer_.draw_ring(ring,green); - if (!mapnik::util::is_clockwise(ring)) + if (exterior) { - renderer_.draw_outline(ring,black); + exterior = false; + renderer_.draw_ring(ring, red); + if (mapnik::util::is_clockwise(ring)) + { + renderer_.draw_outline(ring,black); + } + } + else + { + renderer_.draw_ring(ring,green); + if (!mapnik::util::is_clockwise(ring)) + { + renderer_.draw_outline(ring,black); + } } } } diff --git a/src/twkb.cpp b/src/twkb.cpp index 10ddedbd2..64ef6aa34 100644 --- a/src/twkb.cpp +++ b/src/twkb.cpp @@ -328,11 +328,7 @@ private: { unsigned int num_rings = read_unsigned_integer(); mapnik::geometry::polygon poly; - if (num_rings > 1) - { - poly.interior_rings.reserve(num_rings - 1); - } - + poly.reserve(num_rings); for (unsigned int i = 0; i < num_rings; ++i) { mapnik::geometry::linear_ring ring; @@ -342,8 +338,7 @@ private: ring.reserve(num_points); read_coords>(ring, num_points); } - if ( i == 0) poly.set_exterior_ring(std::move(ring)); - else poly.add_hole(std::move(ring)); + poly.push_back(std::move(ring)); } return poly; } diff --git a/src/vertex_adapters.cpp b/src/vertex_adapters.cpp index 566818074..dd7b0202f 100644 --- a/src/vertex_adapters.cpp +++ b/src/vertex_adapters.cpp @@ -102,18 +102,18 @@ template polygon_vertex_adapter::polygon_vertex_adapter(polygon const& poly) : poly_(poly), rings_itr_(0), - rings_end_(poly_.interior_rings.size() + 1), + rings_end_(poly_.size()), current_index_(0), - end_index_((rings_itr_ < rings_end_) ? poly_.exterior_ring.size() : 0), + end_index_(poly_.empty() ? 0 : poly_[0].size()), start_loop_(true) {} template void polygon_vertex_adapter::rewind(unsigned) const { rings_itr_ = 0; - rings_end_ = poly_.interior_rings.size() + 1; + rings_end_ = poly_.size(); current_index_ = 0; - end_index_ = (rings_itr_ < rings_end_) ? poly_.exterior_ring.size() : 0; + end_index_ = poly_.empty() ? 0 : poly_[0].size(); start_loop_ = true; } template @@ -125,8 +125,7 @@ unsigned polygon_vertex_adapter::vertex(coordinate_type * x, coordinate_type } if (current_index_ < end_index_) { - point const& coord = (rings_itr_ == 0) ? - poly_.exterior_ring[current_index_++] : poly_.interior_rings[rings_itr_- 1][current_index_++]; + point const& coord = poly_[rings_itr_][current_index_++]; *x = coord.x; *y = coord.y; if (start_loop_) @@ -145,8 +144,8 @@ unsigned polygon_vertex_adapter::vertex(coordinate_type * x, coordinate_type else if (++rings_itr_ != rings_end_) { current_index_ = 0; - end_index_ = poly_.interior_rings[rings_itr_ - 1].size(); - point const& coord = poly_.interior_rings[rings_itr_ - 1][current_index_++]; + end_index_ = poly_[rings_itr_].size(); + point const& coord = poly_[rings_itr_][current_index_++]; *x = coord.x; *y = coord.y; return mapnik::SEG_MOVETO; diff --git a/src/wkb.cpp b/src/wkb.cpp index 33c98002e..21a07fd97 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -329,11 +329,7 @@ private: { int num_rings = read_integer(); mapnik::geometry::polygon poly; - if (num_rings > 1) - { - poly.interior_rings.reserve(num_rings - 1); - } - + poly.reserve(num_rings); for (int i = 0; i < num_rings; ++i) { mapnik::geometry::linear_ring ring; @@ -343,8 +339,7 @@ private: ring.reserve(num_points); read_coords, M, Z>(ring, num_points); } - if ( i == 0) poly.set_exterior_ring(std::move(ring)); - else poly.add_hole(std::move(ring)); + poly.push_back(std::move(ring)); } return poly; } diff --git a/test/unit/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp index 1edeb4b55..de0b96da5 100644 --- a/test/unit/datasource/geojson.cpp +++ b/test/unit/datasource/geojson.cpp @@ -152,10 +152,9 @@ TEST_CASE("geojson") { auto const& geometry = feature->get_geometry(); REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::Polygon); auto const& poly = mapnik::util::get >(geometry); - REQUIRE(poly.num_rings() == 2); - REQUIRE(poly.exterior_ring.size() == 5); - REQUIRE(poly.interior_rings.size() == 1); - REQUIRE(poly.interior_rings[0].size() == 5); + REQUIRE(poly.size() == 2); + REQUIRE(poly[0].size() == 5); + REQUIRE(poly[1].size() == 5); REQUIRE(mapnik::geometry::envelope(poly) == mapnik::box2d(100,0,101,1)); } @@ -209,8 +208,8 @@ TEST_CASE("geojson") { REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiPolygon); auto const& multi_poly = mapnik::util::get >(geometry); REQUIRE(multi_poly.size() == 2); - REQUIRE(multi_poly[0].num_rings() == 1); - REQUIRE(multi_poly[1].num_rings() == 2); + REQUIRE(multi_poly[0].size() == 1); + REQUIRE(multi_poly[1].size() == 2); REQUIRE(mapnik::geometry::envelope(multi_poly) == mapnik::box2d(100,0,103,3)); } diff --git a/test/unit/geometry/centroid.cpp b/test/unit/geometry/centroid.cpp index f867cd74c..52a02bf72 100644 --- a/test/unit/geometry/centroid.cpp +++ b/test/unit/geometry/centroid.cpp @@ -55,7 +55,7 @@ SECTION("polygon") { ring.emplace_back(1, 1); ring.emplace_back(0, 1); ring.emplace_back(0, 0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::point centroid; REQUIRE(mapnik::geometry::centroid(poly, centroid)); @@ -67,7 +67,7 @@ SECTION("polygon with empty exterior ring") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::point centroid; REQUIRE(!mapnik::geometry::centroid(poly, centroid)); @@ -76,6 +76,7 @@ SECTION("polygon with empty exterior ring") { SECTION("empty polygon") { mapnik::geometry::polygon poly; + poly.emplace_back(); mapnik::geometry::point centroid; REQUIRE(!mapnik::geometry::centroid(poly, centroid)); } @@ -155,7 +156,7 @@ SECTION("multi-polygon") { ring.emplace_back(1, 1); ring.emplace_back(0, 1); ring.emplace_back(0, 0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); } { @@ -166,7 +167,7 @@ SECTION("multi-polygon") { ring.emplace_back(2, 2); ring.emplace_back(1, 2); ring.emplace_back(1, 1); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); } @@ -186,10 +187,10 @@ SECTION("multi-polygon: one component empty") { ring.emplace_back(1, 1); ring.emplace_back(0, 1); ring.emplace_back(0, 0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); geom.emplace_back(); - + geom.back().emplace_back(); mapnik::geometry::point centroid; REQUIRE(mapnik::geometry::centroid(geom, centroid)); REQUIRE(centroid.x == 0.5); diff --git a/test/unit/geometry/geometry_envelope_test.cpp b/test/unit/geometry/geometry_envelope_test.cpp index 77c2e2b85..10551d363 100644 --- a/test/unit/geometry/geometry_envelope_test.cpp +++ b/test/unit/geometry/geometry_envelope_test.cpp @@ -64,7 +64,7 @@ void envelope_test() ring.emplace_back(-10,10); ring.emplace_back(0,10); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geometry geom(poly); mapnik::box2d bbox = mapnik::geometry::envelope(geom); REQUIRE( bbox.minx() == -10 ); @@ -107,14 +107,14 @@ void envelope_test() ring.emplace_back(-10,10); ring.emplace_back(0,10); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); linear_ring hole; hole.emplace_back(-7,7); hole.emplace_back(-7,3); hole.emplace_back(-3,3); hole.emplace_back(-3,7); hole.emplace_back(-7,7); - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); geometry geom(poly); mapnik::box2d bbox = mapnik::geometry::envelope(poly); REQUIRE( bbox.minx() == -10 ); @@ -129,7 +129,7 @@ void envelope_test() fill.emplace_back(-4,6); fill.emplace_back(-4,4); fill.emplace_back(-6,4); - poly.add_hole(std::move(fill)); + poly.push_back(std::move(fill)); bbox = mapnik::geometry::envelope(poly); REQUIRE( bbox.minx() == -10 ); REQUIRE( bbox.miny() == 0 ); diff --git a/test/unit/geometry/geometry_equal.hpp b/test/unit/geometry/geometry_equal.hpp index 770e9079e..97e0bf26a 100644 --- a/test/unit/geometry/geometry_equal.hpp +++ b/test/unit/geometry/geometry_equal.hpp @@ -137,15 +137,12 @@ struct geometry_equal_visitor template void operator() (polygon const& p1, polygon const& p2) const { - (*this)(static_cast> const&>(p1.exterior_ring), - static_cast> const&>(p2.exterior_ring)); - - if (p1.interior_rings.size() != p2.interior_rings.size()) + if (p1.size() != p2.size()) { REQUIRE(false); } - for (auto const& p : zip_crange(p1.interior_rings, p2.interior_rings)) + for (auto const& p : zip_crange(p1, p2)) { (*this)(static_cast> const&>(p.template get<0>()), static_cast> const&>(p.template get<1>())); diff --git a/test/unit/geometry/geometry_hit_test.cpp b/test/unit/geometry/geometry_hit_test.cpp index 72695d849..afc7dfa9c 100644 --- a/test/unit/geometry/geometry_hit_test.cpp +++ b/test/unit/geometry/geometry_hit_test.cpp @@ -50,7 +50,7 @@ SECTION("hit_test_filter - double") { ring.emplace_back(-10,10); ring.emplace_back(0,10); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geometry geom(poly); REQUIRE( mapnik::hit_test(geom,-5,5,0) ); @@ -82,14 +82,14 @@ SECTION("hit_test_filter - double") { ring.emplace_back(-10,10); ring.emplace_back(0,10); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); linear_ring hole; hole.emplace_back(-7,7); hole.emplace_back(-7,3); hole.emplace_back(-3,3); hole.emplace_back(-3,7); hole.emplace_back(-7,7); - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); geometry geom(poly); REQUIRE( !mapnik::hit_test(geom,-5,5,0) ); // add another hole inside the first hole @@ -100,7 +100,7 @@ SECTION("hit_test_filter - double") { fill.emplace_back(-4,6); fill.emplace_back(-4,4); fill.emplace_back(-6,4); - poly.add_hole(std::move(fill)); + poly.push_back(std::move(fill)); REQUIRE( mapnik::hit_test(geometry(poly),-5,5,0) ); } } diff --git a/test/unit/geometry/geometry_is_simple.cpp b/test/unit/geometry/geometry_is_simple.cpp index 2177dea68..936c3caae 100644 --- a/test/unit/geometry/geometry_is_simple.cpp +++ b/test/unit/geometry/geometry_is_simple.cpp @@ -117,7 +117,7 @@ SECTION("polygon") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -129,7 +129,7 @@ SECTION("polygon invalid winding order") { ring.emplace_back(1,1); ring.emplace_back(1,0); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -144,7 +144,7 @@ SECTION("polygon 2 repeated points") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_simple(poly) ); } // repeated points are not considered invalid in a polygon @@ -159,7 +159,7 @@ SECTION("polygon 3 repeated points") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_simple(poly) ); } @@ -167,13 +167,14 @@ SECTION("polygon 3 repeated points") { SECTION("polygon that is empty") { mapnik::geometry::polygon poly; + poly.emplace_back(); CHECK( !mapnik::geometry::is_simple(poly) ); } SECTION("polygon that has empty exterior ring") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_simple(poly) ); } @@ -185,9 +186,9 @@ SECTION("polygon that has empty interior ring") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring ring2; - poly.add_hole(std::move(ring2)); + poly.push_back(std::move(ring2)); CHECK( !mapnik::geometry::is_simple(poly) ); } @@ -201,7 +202,7 @@ SECTION("polygon that is empty") { SECTION("polygon that has empty exterior ring") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -213,9 +214,9 @@ SECTION("polygon that has empty interior ring") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring ring2; - poly.add_hole(std::move(ring2)); + poly.push_back(std::move(ring2)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -232,7 +233,7 @@ SECTION("polygon with spike") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -244,14 +245,14 @@ SECTION("polygon with hole") { ring.emplace_back(3,3); ring.emplace_back(0,3); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring hole; hole.emplace_back(1,1); hole.emplace_back(1,2); hole.emplace_back(2,2); hole.emplace_back(2,1); hole.emplace_back(1,1); - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -264,14 +265,14 @@ SECTION("polygon with hole with invalid winding order") { ring.emplace_back(3,3); ring.emplace_back(0,3); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring hole; hole.emplace_back(1,1); hole.emplace_back(2,1); hole.emplace_back(2,2); hole.emplace_back(1,2); hole.emplace_back(1,1); - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -284,7 +285,7 @@ SECTION("multi polygon") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; ring2.emplace_back(0,0); @@ -292,7 +293,7 @@ SECTION("multi polygon") { ring2.emplace_back(-1,-1); ring2.emplace_back(0,-1); ring2.emplace_back(0,0); - poly2.set_exterior_ring(std::move(ring2)); + poly2.push_back(std::move(ring2)); mp.emplace_back(poly); mp.emplace_back(poly2); CHECK( mapnik::geometry::is_simple(mp) ); @@ -307,14 +308,14 @@ SECTION("multi polygon with hole") { ring.emplace_back(3,3); ring.emplace_back(0,3); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring hole; hole.emplace_back(1,1); hole.emplace_back(1,2); hole.emplace_back(2,2); hole.emplace_back(2,1); hole.emplace_back(1,1); - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; ring2.emplace_back(0,0); @@ -322,14 +323,14 @@ SECTION("multi polygon with hole") { ring2.emplace_back(-3,-3); ring2.emplace_back(0,-3); ring2.emplace_back(0,0); - poly2.set_exterior_ring(std::move(ring2)); + poly2.push_back(std::move(ring2)); mapnik::geometry::linear_ring hole2; hole2.emplace_back(-1,-1); hole2.emplace_back(-1,-2); hole2.emplace_back(-2,-2); hole2.emplace_back(-2,-1); hole2.emplace_back(-1,-1); - poly2.add_hole(std::move(hole2)); + poly2.push_back(std::move(hole2)); mp.emplace_back(poly); mp.emplace_back(poly2); CHECK( mapnik::geometry::is_simple(mp) ); diff --git a/test/unit/geometry/geometry_is_valid.cpp b/test/unit/geometry/geometry_is_valid.cpp index 63c2f348b..f8227b050 100644 --- a/test/unit/geometry/geometry_is_valid.cpp +++ b/test/unit/geometry/geometry_is_valid.cpp @@ -224,7 +224,7 @@ SECTION("polygon") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; CHECK( mapnik::geometry::is_valid(poly, message) ); @@ -242,7 +242,7 @@ SECTION("polygon invalid winding order") { ring.emplace_back(1,1); ring.emplace_back(1,0); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; CHECK( !mapnik::geometry::is_valid(poly, message) ); @@ -262,7 +262,7 @@ SECTION("polygon 2 repeated points") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; CHECK( mapnik::geometry::is_valid(poly, message) ); @@ -282,7 +282,7 @@ SECTION("polygon 3 repeated points") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; CHECK( mapnik::geometry::is_valid(poly, message) ); @@ -294,6 +294,7 @@ SECTION("polygon 3 repeated points") { SECTION("polygon that is empty") { mapnik::geometry::polygon poly; + poly.emplace_back(); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; CHECK( !mapnik::geometry::is_valid(poly, message) ); @@ -313,7 +314,7 @@ SECTION("polygon with spike") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; CHECK( !mapnik::geometry::is_valid(poly, message) ); @@ -331,14 +332,14 @@ SECTION("polygon with hole") { ring.emplace_back(3,3); ring.emplace_back(0,3); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring hole; hole.emplace_back(1,1); hole.emplace_back(1,2); hole.emplace_back(2,2); hole.emplace_back(2,1); hole.emplace_back(1,1); - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; CHECK( mapnik::geometry::is_valid(poly, message) ); @@ -356,9 +357,9 @@ SECTION("polygon with empty hole") { ring.emplace_back(3,3); ring.emplace_back(0,3); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring hole; - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; CHECK( !mapnik::geometry::is_valid(poly, message) ); @@ -377,14 +378,14 @@ SECTION("polygon with hole with invalid winding order") { ring.emplace_back(3,3); ring.emplace_back(0,3); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring hole; hole.emplace_back(1,1); hole.emplace_back(2,1); hole.emplace_back(2,2); hole.emplace_back(1,2); hole.emplace_back(1,1); - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; CHECK( !mapnik::geometry::is_valid(poly, message) ); @@ -403,7 +404,7 @@ SECTION("multi polygon") { ring.emplace_back(1,1); ring.emplace_back(0,1); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; ring2.emplace_back(0,0); @@ -411,7 +412,7 @@ SECTION("multi polygon") { ring2.emplace_back(-1,-1); ring2.emplace_back(0,-1); ring2.emplace_back(0,0); - poly2.set_exterior_ring(std::move(ring2)); + poly2.push_back(std::move(ring2)); mp.emplace_back(poly); mp.emplace_back(poly2); CHECK( mapnik::geometry::is_valid(mp) ); @@ -432,14 +433,14 @@ SECTION("multi polygon with hole") { ring.emplace_back(3,3); ring.emplace_back(0,3); ring.emplace_back(0,0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); mapnik::geometry::linear_ring hole; hole.emplace_back(1,1); hole.emplace_back(1,2); hole.emplace_back(2,2); hole.emplace_back(2,1); hole.emplace_back(1,1); - poly.add_hole(std::move(hole)); + poly.push_back(std::move(hole)); mapnik::geometry::polygon poly2; mapnik::geometry::linear_ring ring2; ring2.emplace_back(0,0); @@ -447,14 +448,14 @@ SECTION("multi polygon with hole") { ring2.emplace_back(-3,-3); ring2.emplace_back(0,-3); ring2.emplace_back(0,0); - poly2.set_exterior_ring(std::move(ring2)); + poly2.push_back(std::move(ring2)); mapnik::geometry::linear_ring hole2; hole2.emplace_back(-1,-1); hole2.emplace_back(-1,-2); hole2.emplace_back(-2,-2); hole2.emplace_back(-2,-1); hole2.emplace_back(-1,-1); - poly2.add_hole(std::move(hole2)); + poly2.push_back(std::move(hole2)); mp.emplace_back(poly); mp.emplace_back(poly2); CHECK( mapnik::geometry::is_valid(mp) ); diff --git a/test/unit/geometry/geometry_reprojection.cpp b/test/unit/geometry/geometry_reprojection.cpp index 32a4008c6..95bfdb099 100644 --- a/test/unit/geometry/geometry_reprojection.cpp +++ b/test/unit/geometry/geometry_reprojection.cpp @@ -321,43 +321,49 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Object") { mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1; - geom1.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1.exterior_ring.emplace_back(point(-97.79067993164062, 35.43941441533686)); - geom1.exterior_ring.emplace_back(point(-97.60391235351562, 35.34425514918409)); - geom1.exterior_ring.emplace_back(point(-97.42813110351562, 35.48191987272801)); - geom1.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1.interior_rings.emplace_back(); - geom1.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); - geom1.interior_rings.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); - geom1.interior_rings.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); - geom1.interior_rings.back().emplace_back(point(-97.62451171875, 35.42598697382711)); - geom1.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + // exterior + geom1.emplace_back(); + geom1.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + geom1.back().emplace_back(point(-97.79067993164062, 35.43941441533686)); + geom1.back().emplace_back(point(-97.60391235351562, 35.34425514918409)); + geom1.back().emplace_back(point(-97.42813110351562, 35.48191987272801)); + geom1.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + // interior + geom1.emplace_back(); + geom1.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + geom1.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); + geom1.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); + geom1.back().emplace_back(point(-97.62451171875, 35.42598697382711)); + geom1.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); polygon geom2; - geom2.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2.exterior_ring.emplace_back(point(-10886008.694318, 4223757.308982)); - geom2.exterior_ring.emplace_back(point(-10865217.822625, 4210763.014174)); - geom2.exterior_ring.emplace_back(point(-10845649.943384, 4229566.523132)); - geom2.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2.interior_rings.emplace_back(); - geom2.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); - geom2.interior_rings.back().emplace_back(point(-10866440.815077, 4237668.848130)); - geom2.interior_rings.back().emplace_back(point(-10857879.867909, 4226509.042001)); - geom2.interior_rings.back().emplace_back(point(-10867510.933473, 4221922.820303)); - geom2.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); + // interior + geom2.emplace_back(); + geom2.back().emplace_back(point(-10867663.807530, 4249745.898599)); + geom2.back().emplace_back(point(-10886008.694318, 4223757.308982)); + geom2.back().emplace_back(point(-10865217.822625, 4210763.014174)); + geom2.back().emplace_back(point(-10845649.943384, 4229566.523132)); + geom2.back().emplace_back(point(-10867663.807530, 4249745.898599)); + // exterior + geom2.emplace_back(); + geom2.back().emplace_back(point(-10872097.155170, 4227732.034453)); + geom2.back().emplace_back(point(-10866440.815077, 4237668.848130)); + geom2.back().emplace_back(point(-10857879.867909, 4226509.042001)); + geom2.back().emplace_back(point(-10867510.933473, 4221922.820303)); + geom2.back().emplace_back(point(-10872097.155170, 4227732.034453)); unsigned int err = 0; { // Test Standard Transform // Add extra vector to outer ring. - geom1.interior_rings.emplace_back(); - REQUIRE(geom1.interior_rings.size() == 2); + geom1.emplace_back(); + REQUIRE(geom1.size() == 3); polygon new_geom = reproject_copy(geom1, proj_trans1, err); REQUIRE(err == 0); // Should remove the empty ring added to back of geom1 - REQUIRE(new_geom.interior_rings.size() == 1); + REQUIRE(new_geom.size() == 2); assert_g_equal(new_geom, geom2); // Remove extra ring for future validity tests. - geom1.interior_rings.pop_back(); - REQUIRE(geom1.interior_rings.size() == 1); + geom1.pop_back(); + REQUIRE(geom1.size() == 2); } { // Transform in reverse @@ -380,13 +386,13 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Object") { { // Transform in place polygon geom3(geom1); - geom3.interior_rings.emplace_back(); + geom3.emplace_back(); REQUIRE(reproject(geom3, proj_trans1)); // Should NOT remove the empty ring added to back of geom1 - REQUIRE(geom3.interior_rings.size() == 2); + REQUIRE(geom3.size() == 3); // Remove so asserts that geometries are the same - geom3.interior_rings.pop_back(); - REQUIRE(geom3.interior_rings.size() == 1); + geom3.pop_back(); + REQUIRE(geom3.size() == 2); assert_g_equal(geom3, geom2); // Transform in place reverse REQUIRE(reproject(geom3, proj_trans2)); @@ -410,29 +416,36 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") { mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1_; - geom1_.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1_.exterior_ring.emplace_back(point(-97.79067993164062, 35.43941441533686)); - geom1_.exterior_ring.emplace_back(point(-97.60391235351562, 35.34425514918409)); - geom1_.exterior_ring.emplace_back(point(-97.42813110351562, 35.48191987272801)); - geom1_.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1_.interior_rings.emplace_back(); - geom1_.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); - geom1_.interior_rings.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); - geom1_.interior_rings.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); - geom1_.interior_rings.back().emplace_back(point(-97.62451171875, 35.42598697382711)); - geom1_.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + // exterior + geom1_.emplace_back(); + geom1_.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + geom1_.back().emplace_back(point(-97.79067993164062, 35.43941441533686)); + geom1_.back().emplace_back(point(-97.60391235351562, 35.34425514918409)); + geom1_.back().emplace_back(point(-97.42813110351562, 35.48191987272801)); + geom1_.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + // interior + geom1_.emplace_back(); + geom1_.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + geom1_.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); + geom1_.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); + geom1_.back().emplace_back(point(-97.62451171875, 35.42598697382711)); + geom1_.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + polygon geom2_; - geom2_.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2_.exterior_ring.emplace_back(point(-10886008.694318, 4223757.308982)); - geom2_.exterior_ring.emplace_back(point(-10865217.822625, 4210763.014174)); - geom2_.exterior_ring.emplace_back(point(-10845649.943384, 4229566.523132)); - geom2_.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2_.interior_rings.emplace_back(); - geom2_.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); - geom2_.interior_rings.back().emplace_back(point(-10866440.815077, 4237668.848130)); - geom2_.interior_rings.back().emplace_back(point(-10857879.867909, 4226509.042001)); - geom2_.interior_rings.back().emplace_back(point(-10867510.933473, 4221922.820303)); - geom2_.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); + // exterior + geom2_.emplace_back(); + geom2_.back().emplace_back(point(-10867663.807530, 4249745.898599)); + geom2_.back().emplace_back(point(-10886008.694318, 4223757.308982)); + geom2_.back().emplace_back(point(-10865217.822625, 4210763.014174)); + geom2_.back().emplace_back(point(-10845649.943384, 4229566.523132)); + geom2_.back().emplace_back(point(-10867663.807530, 4249745.898599)); + // interior + geom2_.emplace_back(); + geom2_.back().emplace_back(point(-10872097.155170, 4227732.034453)); + geom2_.back().emplace_back(point(-10866440.815077, 4237668.848130)); + geom2_.back().emplace_back(point(-10857879.867909, 4226509.042001)); + geom2_.back().emplace_back(point(-10867510.933473, 4221922.820303)); + geom2_.back().emplace_back(point(-10872097.155170, 4227732.034453)); polygon geom0_; geometry geom0(geom0_); geometry geom1(geom1_); @@ -791,31 +804,37 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object") { mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1a; - geom1a.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1a.exterior_ring.emplace_back(point(-97.79067993164062, 35.43941441533686)); - geom1a.exterior_ring.emplace_back(point(-97.60391235351562, 35.34425514918409)); - geom1a.exterior_ring.emplace_back(point(-97.42813110351562, 35.48191987272801)); - geom1a.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1a.interior_rings.emplace_back(); - geom1a.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); - geom1a.interior_rings.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); - geom1a.interior_rings.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); - geom1a.interior_rings.back().emplace_back(point(-97.62451171875, 35.42598697382711)); - geom1a.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + // exterior + geom1a.emplace_back(); + geom1a.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + geom1a.back().emplace_back(point(-97.79067993164062, 35.43941441533686)); + geom1a.back().emplace_back(point(-97.60391235351562, 35.34425514918409)); + geom1a.back().emplace_back(point(-97.42813110351562, 35.48191987272801)); + geom1a.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + // interior + geom1a.emplace_back(); + geom1a.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + geom1a.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); + geom1a.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); + geom1a.back().emplace_back(point(-97.62451171875, 35.42598697382711)); + geom1a.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); multi_polygon geom1; geom1.emplace_back(geom1a); polygon geom2a; - geom2a.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2a.exterior_ring.emplace_back(point(-10886008.694318, 4223757.308982)); - geom2a.exterior_ring.emplace_back(point(-10865217.822625, 4210763.014174)); - geom2a.exterior_ring.emplace_back(point(-10845649.943384, 4229566.523132)); - geom2a.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2a.interior_rings.emplace_back(); - geom2a.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); - geom2a.interior_rings.back().emplace_back(point(-10866440.815077, 4237668.848130)); - geom2a.interior_rings.back().emplace_back(point(-10857879.867909, 4226509.042001)); - geom2a.interior_rings.back().emplace_back(point(-10867510.933473, 4221922.820303)); - geom2a.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); + // exterior + geom2a.emplace_back(); + geom2a.back().emplace_back(point(-10867663.807530, 4249745.898599)); + geom2a.back().emplace_back(point(-10886008.694318, 4223757.308982)); + geom2a.back().emplace_back(point(-10865217.822625, 4210763.014174)); + geom2a.back().emplace_back(point(-10845649.943384, 4229566.523132)); + geom2a.back().emplace_back(point(-10867663.807530, 4249745.898599)); + // interior + geom2a.emplace_back(); + geom2a.back().emplace_back(point(-10872097.155170, 4227732.034453)); + geom2a.back().emplace_back(point(-10866440.815077, 4237668.848130)); + geom2a.back().emplace_back(point(-10857879.867909, 4226509.042001)); + geom2a.back().emplace_back(point(-10867510.933473, 4221922.820303)); + geom2a.back().emplace_back(point(-10872097.155170, 4227732.034453)); multi_polygon geom2; geom2.emplace_back(geom2a); unsigned int err = 0; @@ -884,31 +903,37 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") { mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1a_; - geom1a_.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1a_.exterior_ring.emplace_back(point(-97.79067993164062, 35.43941441533686)); - geom1a_.exterior_ring.emplace_back(point(-97.60391235351562, 35.34425514918409)); - geom1a_.exterior_ring.emplace_back(point(-97.42813110351562, 35.48191987272801)); - geom1a_.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1a_.interior_rings.emplace_back(); - geom1a_.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); - geom1a_.interior_rings.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); - geom1a_.interior_rings.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); - geom1a_.interior_rings.back().emplace_back(point(-97.62451171875, 35.42598697382711)); - geom1a_.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + // exterior + geom1a_.emplace_back(); + geom1a_.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + geom1a_.back().emplace_back(point(-97.79067993164062, 35.43941441533686)); + geom1a_.back().emplace_back(point(-97.60391235351562, 35.34425514918409)); + geom1a_.back().emplace_back(point(-97.42813110351562, 35.48191987272801)); + geom1a_.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + // interior + geom1a_.emplace_back(); + geom1a_.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + geom1a_.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); + geom1a_.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); + geom1a_.back().emplace_back(point(-97.62451171875, 35.42598697382711)); + geom1a_.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); multi_polygon geom1_; geom1_.emplace_back(geom1a_); polygon geom2a_; - geom2a_.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2a_.exterior_ring.emplace_back(point(-10886008.694318, 4223757.308982)); - geom2a_.exterior_ring.emplace_back(point(-10865217.822625, 4210763.014174)); - geom2a_.exterior_ring.emplace_back(point(-10845649.943384, 4229566.523132)); - geom2a_.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2a_.interior_rings.emplace_back(); - geom2a_.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); - geom2a_.interior_rings.back().emplace_back(point(-10866440.815077, 4237668.848130)); - geom2a_.interior_rings.back().emplace_back(point(-10857879.867909, 4226509.042001)); - geom2a_.interior_rings.back().emplace_back(point(-10867510.933473, 4221922.820303)); - geom2a_.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); + // exterior + geom2a_.emplace_back(); + geom2a_.back().emplace_back(point(-10867663.807530, 4249745.898599)); + geom2a_.back().emplace_back(point(-10886008.694318, 4223757.308982)); + geom2a_.back().emplace_back(point(-10865217.822625, 4210763.014174)); + geom2a_.back().emplace_back(point(-10845649.943384, 4229566.523132)); + geom2a_.back().emplace_back(point(-10867663.807530, 4249745.898599)); + // interior + geom2a_.emplace_back(); + geom2a_.back().emplace_back(point(-10872097.155170, 4227732.034453)); + geom2a_.back().emplace_back(point(-10866440.815077, 4237668.848130)); + geom2a_.back().emplace_back(point(-10857879.867909, 4226509.042001)); + geom2a_.back().emplace_back(point(-10867510.933473, 4221922.820303)); + geom2a_.back().emplace_back(point(-10872097.155170, 4227732.034453)); multi_polygon geom2_; geom2_.emplace_back(geom2a_); multi_polygon geom0_; @@ -973,31 +998,37 @@ SECTION("test_projection_4326_3857 - Geometry Collection Object") { mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1a; - geom1a.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1a.exterior_ring.emplace_back(point(-97.79067993164062, 35.43941441533686)); - geom1a.exterior_ring.emplace_back(point(-97.60391235351562, 35.34425514918409)); - geom1a.exterior_ring.emplace_back(point(-97.42813110351562, 35.48191987272801)); - geom1a.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1a.interior_rings.emplace_back(); - geom1a.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); - geom1a.interior_rings.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); - geom1a.interior_rings.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); - geom1a.interior_rings.back().emplace_back(point(-97.62451171875, 35.42598697382711)); - geom1a.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + // exterior + geom1a.emplace_back(); + geom1a.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + geom1a.back().emplace_back(point(-97.79067993164062, 35.43941441533686)); + geom1a.back().emplace_back(point(-97.60391235351562, 35.34425514918409)); + geom1a.back().emplace_back(point(-97.42813110351562, 35.48191987272801)); + geom1a.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + // interior + geom1a.emplace_back(); + geom1a.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + geom1a.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); + geom1a.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); + geom1a.back().emplace_back(point(-97.62451171875, 35.42598697382711)); + geom1a.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); geometry_collection geom1; geom1.emplace_back(geometry(geom1a)); polygon geom2a; - geom2a.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2a.exterior_ring.emplace_back(point(-10886008.694318, 4223757.308982)); - geom2a.exterior_ring.emplace_back(point(-10865217.822625, 4210763.014174)); - geom2a.exterior_ring.emplace_back(point(-10845649.943384, 4229566.523132)); - geom2a.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2a.interior_rings.emplace_back(); - geom2a.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); - geom2a.interior_rings.back().emplace_back(point(-10866440.815077, 4237668.848130)); - geom2a.interior_rings.back().emplace_back(point(-10857879.867909, 4226509.042001)); - geom2a.interior_rings.back().emplace_back(point(-10867510.933473, 4221922.820303)); - geom2a.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); + // exerior + geom2a.emplace_back(); + geom2a.back().emplace_back(point(-10867663.807530, 4249745.898599)); + geom2a.back().emplace_back(point(-10886008.694318, 4223757.308982)); + geom2a.back().emplace_back(point(-10865217.822625, 4210763.014174)); + geom2a.back().emplace_back(point(-10845649.943384, 4229566.523132)); + geom2a.back().emplace_back(point(-10867663.807530, 4249745.898599)); + // interior + geom2a.emplace_back(); + geom2a.back().emplace_back(point(-10872097.155170, 4227732.034453)); + geom2a.back().emplace_back(point(-10866440.815077, 4237668.848130)); + geom2a.back().emplace_back(point(-10857879.867909, 4226509.042001)); + geom2a.back().emplace_back(point(-10867510.933473, 4221922.820303)); + geom2a.back().emplace_back(point(-10872097.155170, 4227732.034453)); geometry_collection geom2; geom2.emplace_back(geometry(geom2a)); unsigned int err = 0; @@ -1066,31 +1097,37 @@ SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") { mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans2(dest, source); polygon geom1a_; - geom1a_.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1a_.exterior_ring.emplace_back(point(-97.79067993164062, 35.43941441533686)); - geom1a_.exterior_ring.emplace_back(point(-97.60391235351562, 35.34425514918409)); - geom1a_.exterior_ring.emplace_back(point(-97.42813110351562, 35.48191987272801)); - geom1a_.exterior_ring.emplace_back(point(-97.62588500976562, 35.62939577711732)); - geom1a_.interior_rings.emplace_back(); - geom1a_.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); - geom1a_.interior_rings.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); - geom1a_.interior_rings.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); - geom1a_.interior_rings.back().emplace_back(point(-97.62451171875, 35.42598697382711)); - geom1a_.interior_rings.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + // exterior + geom1a_.emplace_back(); + geom1a_.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + geom1a_.back().emplace_back(point(-97.79067993164062, 35.43941441533686)); + geom1a_.back().emplace_back(point(-97.60391235351562, 35.34425514918409)); + geom1a_.back().emplace_back(point(-97.42813110351562, 35.48191987272801)); + geom1a_.back().emplace_back(point(-97.62588500976562, 35.62939577711732)); + // interior + geom1a_.emplace_back(); + geom1a_.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); + geom1a_.back().emplace_back(point(-97.61489868164062, 35.54116627999813)); + geom1a_.back().emplace_back(point(-97.53799438476562, 35.459551379037606)); + geom1a_.back().emplace_back(point(-97.62451171875, 35.42598697382711)); + geom1a_.back().emplace_back(point(-97.66571044921875, 35.46849952318069)); geometry_collection geom1_; geom1_.emplace_back(geometry(geom1a_)); polygon geom2a_; - geom2a_.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2a_.exterior_ring.emplace_back(point(-10886008.694318, 4223757.308982)); - geom2a_.exterior_ring.emplace_back(point(-10865217.822625, 4210763.014174)); - geom2a_.exterior_ring.emplace_back(point(-10845649.943384, 4229566.523132)); - geom2a_.exterior_ring.emplace_back(point(-10867663.807530, 4249745.898599)); - geom2a_.interior_rings.emplace_back(); - geom2a_.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); - geom2a_.interior_rings.back().emplace_back(point(-10866440.815077, 4237668.848130)); - geom2a_.interior_rings.back().emplace_back(point(-10857879.867909, 4226509.042001)); - geom2a_.interior_rings.back().emplace_back(point(-10867510.933473, 4221922.820303)); - geom2a_.interior_rings.back().emplace_back(point(-10872097.155170, 4227732.034453)); + // exterior + geom2a_.emplace_back(); + geom2a_.back().emplace_back(point(-10867663.807530, 4249745.898599)); + geom2a_.back().emplace_back(point(-10886008.694318, 4223757.308982)); + geom2a_.back().emplace_back(point(-10865217.822625, 4210763.014174)); + geom2a_.back().emplace_back(point(-10845649.943384, 4229566.523132)); + geom2a_.back().emplace_back(point(-10867663.807530, 4249745.898599)); + // interior + geom2a_.emplace_back(); + geom2a_.back().emplace_back(point(-10872097.155170, 4227732.034453)); + geom2a_.back().emplace_back(point(-10866440.815077, 4237668.848130)); + geom2a_.back().emplace_back(point(-10857879.867909, 4226509.042001)); + geom2a_.back().emplace_back(point(-10867510.933473, 4221922.820303)); + geom2a_.back().emplace_back(point(-10872097.155170, 4227732.034453)); geometry_collection geom2_; geom2_.emplace_back(geometry(geom2a_)); multi_polygon geom0_; diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp index c08e828cb..0c72a001c 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include "geometry_equal.hpp" @@ -12,7 +11,7 @@ #include TEST_CASE("geometry strategy tests") { - +#if 0 SECTION("proj and view strategy") { using namespace mapnik::geometry; mapnik::box2d e(-20037508.342789,-20037508.342789,20037508.342789,20037508.342789); @@ -184,5 +183,5 @@ SECTION("scaling strategies - double to int64") { assert_g_equal(r, o); } } // END SECTION - +#endif } // END TEST CASE diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp index 669081d57..38d6d4d7e 100644 --- a/test/unit/geometry/has_empty.cpp +++ b/test/unit/geometry/has_empty.cpp @@ -71,7 +71,7 @@ SECTION("polygon") { { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); REQUIRE(!mapnik::geometry::has_empty(poly)); } { @@ -82,7 +82,7 @@ SECTION("polygon") { ring.emplace_back(1, 1); ring.emplace_back(0, 1); ring.emplace_back(0, 0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); REQUIRE(!mapnik::geometry::has_empty(poly)); } } @@ -133,16 +133,16 @@ SECTION("multi-polygon") { mapnik::geometry::multi_polygon geom; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); - REQUIRE(mapnik::geometry::has_empty(geom)); + //REQUIRE(mapnik::geometry::has_empty(geom)); } { mapnik::geometry::multi_polygon geom; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; ring.emplace_back(0, 0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); REQUIRE(!mapnik::geometry::has_empty(geom)); } diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp index 2a440ecfa..8dfed1446 100644 --- a/test/unit/geometry/is_empty.cpp +++ b/test/unit/geometry/is_empty.cpp @@ -54,8 +54,8 @@ SECTION("polygon") { { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - poly.set_exterior_ring(std::move(ring)); - REQUIRE(mapnik::geometry::is_empty(poly)); + poly.push_back(std::move(ring)); + //REQUIRE(mapnik::geometry::is_empty(poly)); } { mapnik::geometry::polygon poly; @@ -65,7 +65,7 @@ SECTION("polygon") { ring.emplace_back(1, 1); ring.emplace_back(0, 1); ring.emplace_back(0, 0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); REQUIRE(!mapnik::geometry::is_empty(poly)); } } @@ -109,7 +109,7 @@ SECTION("multi-polygon") { mapnik::geometry::multi_polygon geom; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); REQUIRE(!mapnik::geometry::is_empty(geom)); } diff --git a/test/unit/geometry/remove_empty.cpp b/test/unit/geometry/remove_empty.cpp index 9f277ef95..36a6955c5 100644 --- a/test/unit/geometry/remove_empty.cpp +++ b/test/unit/geometry/remove_empty.cpp @@ -41,13 +41,13 @@ SECTION("multi-polygon") { ring.emplace_back(1, 1); ring.emplace_back(0, 1); ring.emplace_back(0, 0); - poly.set_exterior_ring(std::move(ring)); + poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); geom.emplace_back(); - + //geom.back().emplace_back(); //add an empty exterior ring REQUIRE(geom.size() == 2); geom_type geom2 = mapnik::geometry::remove_empty(geom); REQUIRE(geom2.size() == 1); - REQUIRE(geom2[0].exterior_ring.size() == 5); + REQUIRE(geom2.front().front().size() == 5); } } diff --git a/test/unit/vertex_adapter/vertex_adapter.cpp b/test/unit/vertex_adapter/vertex_adapter.cpp index 53acdd7a0..d6c1ed592 100644 --- a/test/unit/vertex_adapter/vertex_adapter.cpp +++ b/test/unit/vertex_adapter/vertex_adapter.cpp @@ -7,10 +7,11 @@ TEST_CASE("vertex_adapters") { SECTION("polygon") { mapnik::geometry::polygon g; - g.exterior_ring.emplace_back(1,1); - g.exterior_ring.emplace_back(2,2); - g.exterior_ring.emplace_back(100,100); - g.exterior_ring.emplace_back(1,1); + g.emplace_back(); + g.back().emplace_back(1,1); + g.back().emplace_back(2,2); + g.back().emplace_back(100,100); + g.back().emplace_back(1,1); mapnik::geometry::polygon_vertex_adapter va(g); double x,y; @@ -46,11 +47,12 @@ SECTION("polygon") { SECTION("polygon with hole") { mapnik::geometry::polygon g; - g.exterior_ring.emplace_back(0,0); - g.exterior_ring.emplace_back(-10,0); - g.exterior_ring.emplace_back(-10,10); - g.exterior_ring.emplace_back(0,10); - g.exterior_ring.emplace_back(0,0); + g.emplace_back(); + g.back().emplace_back(0,0); + g.back().emplace_back(-10,0); + g.back().emplace_back(-10,10); + g.back().emplace_back(0,10); + g.back().emplace_back(0,0); std::vector > interior_rings; mapnik::geometry::linear_ring hole; hole.emplace_back(-7,7); @@ -58,7 +60,7 @@ SECTION("polygon with hole") { hole.emplace_back(-3,3); hole.emplace_back(-3,7); hole.emplace_back(-7,7); - g.add_hole(std::move(hole)); + g.push_back(std::move(hole)); mapnik::geometry::linear_ring hole_in_hole; hole_in_hole.emplace_back(-6,4); @@ -66,7 +68,7 @@ SECTION("polygon with hole") { hole_in_hole.emplace_back(-4,6); hole_in_hole.emplace_back(-4,4); hole_in_hole.emplace_back(-6,4); - g.add_hole(std::move(hole_in_hole)); + g.push_back(std::move(hole_in_hole)); mapnik::geometry::polygon_vertex_adapter va(g); double x,y; @@ -99,7 +101,7 @@ SECTION("polygon with hole") { REQUIRE( y == 0 ); // exterior ring via ring_vertex_adapter - mapnik::geometry::ring_vertex_adapter va2(g.exterior_ring); + mapnik::geometry::ring_vertex_adapter va2(g.front()); cmd = va2.vertex(&x,&y); REQUIRE( cmd == mapnik::SEG_MOVETO ); REQUIRE( x == 0 ); From e44f10460d5f9d71279180341e60a7fc56db7d66 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 29 Jun 2016 15:02:19 +0100 Subject: [PATCH 18/51] disable "multi-polygon: one component empty" test --- test/unit/geometry/centroid.cpp | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/unit/geometry/centroid.cpp b/test/unit/geometry/centroid.cpp index 52a02bf72..ad9f19ec2 100644 --- a/test/unit/geometry/centroid.cpp +++ b/test/unit/geometry/centroid.cpp @@ -177,25 +177,25 @@ SECTION("multi-polygon") { REQUIRE(centroid.y == 1); } -SECTION("multi-polygon: one component empty") { - - mapnik::geometry::multi_polygon geom; - mapnik::geometry::polygon poly; - mapnik::geometry::linear_ring ring; - ring.emplace_back(0, 0); - ring.emplace_back(1, 0); - ring.emplace_back(1, 1); - ring.emplace_back(0, 1); - ring.emplace_back(0, 0); - poly.push_back(std::move(ring)); - geom.emplace_back(std::move(poly)); - geom.emplace_back(); - geom.back().emplace_back(); - mapnik::geometry::point centroid; - REQUIRE(mapnik::geometry::centroid(geom, centroid)); - REQUIRE(centroid.x == 0.5); - REQUIRE(centroid.y == 0.5); -} +//SECTION("multi-polygon: one component empty") { +// +// mapnik::geometry::multi_polygon geom; +// mapnik::geometry::polygon poly; +// mapnik::geometry::linear_ring ring; +// ring.emplace_back(0, 0); +// ring.emplace_back(1, 0); +// ring.emplace_back(1, 1); +// ring.emplace_back(0, 1); +// ring.emplace_back(0, 0); +// poly.push_back(std::move(ring)); +// geom.emplace_back(std::move(poly)); +// geom.emplace_back(); +// geom.back().emplace_back(); +// mapnik::geometry::point centroid; +// REQUIRE(mapnik::geometry::centroid(geom, centroid)); +// REQUIRE(centroid.x == 0.5); +// REQUIRE(centroid.y == 0.5); +//} SECTION("empty multi-polygon") { From 39f497ded6bd5f2d938d863f18d64b58d96d7593 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 29 Jun 2016 09:19:28 -0700 Subject: [PATCH 19/51] re-enable centroid test which appears to be passing --- test/unit/geometry/centroid.cpp | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/unit/geometry/centroid.cpp b/test/unit/geometry/centroid.cpp index ad9f19ec2..4549bec9b 100644 --- a/test/unit/geometry/centroid.cpp +++ b/test/unit/geometry/centroid.cpp @@ -177,25 +177,25 @@ SECTION("multi-polygon") { REQUIRE(centroid.y == 1); } -//SECTION("multi-polygon: one component empty") { -// -// mapnik::geometry::multi_polygon geom; -// mapnik::geometry::polygon poly; -// mapnik::geometry::linear_ring ring; -// ring.emplace_back(0, 0); -// ring.emplace_back(1, 0); -// ring.emplace_back(1, 1); -// ring.emplace_back(0, 1); -// ring.emplace_back(0, 0); -// poly.push_back(std::move(ring)); -// geom.emplace_back(std::move(poly)); -// geom.emplace_back(); -// geom.back().emplace_back(); -// mapnik::geometry::point centroid; -// REQUIRE(mapnik::geometry::centroid(geom, centroid)); -// REQUIRE(centroid.x == 0.5); -// REQUIRE(centroid.y == 0.5); -//} +SECTION("multi-polygon: one component empty") { + + mapnik::geometry::multi_polygon geom; + mapnik::geometry::polygon poly; + mapnik::geometry::linear_ring ring; + ring.emplace_back(0, 0); + ring.emplace_back(1, 0); + ring.emplace_back(1, 1); + ring.emplace_back(0, 1); + ring.emplace_back(0, 0); + poly.push_back(std::move(ring)); + geom.emplace_back(std::move(poly)); + geom.emplace_back(); + geom.back().emplace_back(); + mapnik::geometry::point centroid; + REQUIRE(mapnik::geometry::centroid(geom, centroid)); + REQUIRE(centroid.x == 0.5); + REQUIRE(centroid.y == 0.5); +} SECTION("empty multi-polygon") { From abe175c14fdc890baa79de3bf02f43eb73323c25 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 29 Jun 2016 09:20:02 -0700 Subject: [PATCH 20/51] avoid calling correct on empty geometries --- include/mapnik/geometry_adapters.hpp | 13 ++++++++++--- include/mapnik/geometry_correct.hpp | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp index c102b138f..df45f804a 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry_adapters.hpp @@ -192,13 +192,20 @@ struct exterior_ring > { static mapnik::geometry::linear_ring & get(mapnik::geometry::polygon & p) { - if (p.empty()) p.emplace_back(); - return p.at(0); + if (p.empty()) { + abort(); + throw std::runtime_error("ring must be initialized 1"); + } + return p[0]; } static mapnik::geometry::linear_ring const& get(mapnik::geometry::polygon const& p) { - return p.at(0); + if (p.empty()) { + abort(); + throw std::runtime_error("ring must be initialized 2"); + } + return p[0]; } }; diff --git a/include/mapnik/geometry_correct.hpp b/include/mapnik/geometry_correct.hpp index dc83ad3a2..673250c0c 100644 --- a/include/mapnik/geometry_correct.hpp +++ b/include/mapnik/geometry_correct.hpp @@ -60,13 +60,13 @@ struct geometry_correct template result_type operator() (polygon & poly) const { - boost::geometry::correct(poly); + if (!poly.empty()) boost::geometry::correct(poly); } template result_type operator() (multi_polygon & multi_poly) const { - boost::geometry::correct(multi_poly); + if (!multi_poly.empty()) boost::geometry::correct(multi_poly); } template From c27653066dd43d45f24282835358071956f8196c Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 29 Jun 2016 18:40:47 +0100 Subject: [PATCH 21/51] bring back failing geometry tests --- benchmark/build.py | 2 +- test/unit/geometry/geometry_strategy_test.cpp | 2 -- test/unit/geometry/has_empty.cpp | 2 +- test/unit/geometry/is_empty.cpp | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/benchmark/build.py b/benchmark/build.py index b964ea78e..37ba86707 100644 --- a/benchmark/build.py +++ b/benchmark/build.py @@ -35,7 +35,7 @@ benchmarks = [ #"test_to_double.cpp", #"test_to_int.cpp", #"test_utf_encoding.cpp" - #"test_polygon_clipping.cpp", + "test_polygon_clipping.cpp", #"test_polygon_clipping_rendering.cpp", "test_proj_transform1.cpp", "test_expression_parse.cpp", diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp index 0c72a001c..cb20cb74a 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -11,7 +11,6 @@ #include TEST_CASE("geometry strategy tests") { -#if 0 SECTION("proj and view strategy") { using namespace mapnik::geometry; mapnik::box2d e(-20037508.342789,-20037508.342789,20037508.342789,20037508.342789); @@ -183,5 +182,4 @@ SECTION("scaling strategies - double to int64") { assert_g_equal(r, o); } } // END SECTION -#endif } // END TEST CASE diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp index 38d6d4d7e..ff2e40f23 100644 --- a/test/unit/geometry/has_empty.cpp +++ b/test/unit/geometry/has_empty.cpp @@ -135,7 +135,7 @@ SECTION("multi-polygon") { mapnik::geometry::linear_ring ring; poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); - //REQUIRE(mapnik::geometry::has_empty(geom)); + REQUIRE(mapnik::geometry::has_empty(geom)); } { mapnik::geometry::multi_polygon geom; diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp index 8dfed1446..25ed8a487 100644 --- a/test/unit/geometry/is_empty.cpp +++ b/test/unit/geometry/is_empty.cpp @@ -55,7 +55,7 @@ SECTION("polygon") { mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; poly.push_back(std::move(ring)); - //REQUIRE(mapnik::geometry::is_empty(poly)); + REQUIRE(mapnik::geometry::is_empty(poly)); } { mapnik::geometry::polygon poly; From 8e31b8e2b950c536736055efd58f91dbd97e8707 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 30 Jun 2016 11:51:37 -0700 Subject: [PATCH 22/51] remove debugging aborts [skip ci] --- include/mapnik/geometry_adapters.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp index df45f804a..59efaf3d1 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry_adapters.hpp @@ -193,7 +193,6 @@ struct exterior_ring > static mapnik::geometry::linear_ring & get(mapnik::geometry::polygon & p) { if (p.empty()) { - abort(); throw std::runtime_error("ring must be initialized 1"); } return p[0]; @@ -202,7 +201,6 @@ struct exterior_ring > static mapnik::geometry::linear_ring const& get(mapnik::geometry::polygon const& p) { if (p.empty()) { - abort(); throw std::runtime_error("ring must be initialized 2"); } return p[0]; From f5ec3ba0e0f6b3688c5731329d5b72b5bd8a2be2 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 4 Jul 2016 10:28:45 +0100 Subject: [PATCH 23/51] add initial "proxy" interior rings implementation --- include/mapnik/polygon_interior.hpp | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 include/mapnik/polygon_interior.hpp diff --git a/include/mapnik/polygon_interior.hpp b/include/mapnik/polygon_interior.hpp new file mode 100644 index 000000000..bb8775d64 --- /dev/null +++ b/include/mapnik/polygon_interior.hpp @@ -0,0 +1,79 @@ +/***************************************************************************** + * + * 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_POLYGON_INTERIOR_HPP +#define MAPNIK_POLYGON_INTERIOR_HPP + +#include + + +namespace mapnik { namespace detail { + +template +struct polygon_interior +{ + using coordinate_type = T; + using iterator = typename geometry::polygon::iterator; + using const_iterator = typename geometry::polygon::const_iterator; + using value_type = typename geometry::polygon::value_type; + + polygon_interior(geometry::polygon & poly) + : poly_(poly) {} + + iterator begin() + { + auto itr = poly_.begin(); + std::advance(itr, 1); + return itr; + } + + iterator end() { return poly_.end();} + const_iterator begin() const + { + auto itr = poly_.begin(); + std::advance(itr, 1); + return itr; + } + const_iterator end() const { return poly_.end();} + + void clear() + { + poly_.resize(1); + } + void resize(std::size_t size) + { + poly_.resize(size + 1); + } + + std::size_t size() const + { + return poly_.empty() ? 0 : poly_.size() - 1; + } + + value_type& back() { return poly_.back(); } + value_type const& back() const { return poly_.back(); } + geometry::polygon & poly_; +}; + +}} + +#endif // MAPNIK_POLYGON_INTERIOR_HPP From 81419154ebcc2f06c2c45133b392f9c000caf121 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 4 Jul 2016 10:30:23 +0100 Subject: [PATCH 24/51] update geometry adapters to use polygon_interior as mutable interior rings proxy container --- include/mapnik/geometry_adapters.hpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp index 59efaf3d1..74d06b195 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry_adapters.hpp @@ -41,7 +41,7 @@ #include #include #include - +#include #include // register point @@ -183,7 +183,8 @@ struct interior_const_type > template struct interior_mutable_type > { - using type = boost::iterator_range::iterator>; + //using type = boost::iterator_range::iterator>; + using type = mapnik::detail::polygon_interior; }; // exterior @@ -192,17 +193,13 @@ struct exterior_ring > { static mapnik::geometry::linear_ring & get(mapnik::geometry::polygon & p) { - if (p.empty()) { - throw std::runtime_error("ring must be initialized 1"); - } + if (p.empty()) throw std::runtime_error("ring must be initialized 1"); return p[0]; } static mapnik::geometry::linear_ring const& get(mapnik::geometry::polygon const& p) { - if (p.empty()) { - throw std::runtime_error("ring must be initialized 2"); - } + if (p.empty()) throw std::runtime_error("ring must be initialized 2"); return p[0]; } }; @@ -210,18 +207,15 @@ struct exterior_ring > template struct interior_rings > { - using ring_iterator = typename mapbox::geometry::polygon::iterator; using const_ring_iterator = typename mapbox::geometry::polygon::const_iterator; - using holes_type = boost::iterator_range; - using const_holes_type = boost::iterator_range; - static holes_type get(mapnik::geometry::polygon & p) - // -> decltype(boost::make_iterator_range(p.begin() + 1, p.end())) + using interior_type = mapnik::detail::polygon_interior; + using const_interior_type = boost::iterator_range; + static interior_type get(mapnik::geometry::polygon & p) { - return boost::make_iterator_range(p.begin() + 1, p.end()); + return mapnik::detail::polygon_interior(p); } - static const_holes_type get(mapnik::geometry::polygon const& p) - // -> decltype(boost::make_iterator_range(p.begin() + 1, p.end())) const + static const_interior_type get(mapnik::geometry::polygon const& p) { return boost::make_iterator_range(p.begin() + 1, p.end()); } From 75b97eb64c536643e099f8fe4406b6209d55e2f1 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 4 Jul 2016 10:32:31 +0100 Subject: [PATCH 25/51] temp disable failing tests --- test/unit/geometry/geometry_strategy_test.cpp | 2 ++ test/unit/geometry/has_empty.cpp | 2 ++ test/unit/geometry/is_empty.cpp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp index cb20cb74a..d2b563a8f 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -10,6 +10,7 @@ #include #include +#if 0 //*** FIXME TEST_CASE("geometry strategy tests") { SECTION("proj and view strategy") { using namespace mapnik::geometry; @@ -183,3 +184,4 @@ SECTION("scaling strategies - double to int64") { } } // END SECTION } // END TEST CASE +#endif diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp index ff2e40f23..32585c333 100644 --- a/test/unit/geometry/has_empty.cpp +++ b/test/unit/geometry/has_empty.cpp @@ -130,12 +130,14 @@ SECTION("multi-polygon") { REQUIRE(!mapnik::geometry::has_empty(geom)); } { + /*** FIXME mapnik::geometry::multi_polygon geom; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); REQUIRE(mapnik::geometry::has_empty(geom)); + ***/ } { mapnik::geometry::multi_polygon geom; diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp index 25ed8a487..216ea1096 100644 --- a/test/unit/geometry/is_empty.cpp +++ b/test/unit/geometry/is_empty.cpp @@ -52,10 +52,12 @@ SECTION("polygon") { REQUIRE(mapnik::geometry::is_empty(poly)); } { + /*** FIXME mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; poly.push_back(std::move(ring)); REQUIRE(mapnik::geometry::is_empty(poly)); + ***/ } { mapnik::geometry::polygon poly; From 11fc2ceabd9116c641a52794a0905dd3d64d8805 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 4 Jul 2016 15:11:06 +0100 Subject: [PATCH 26/51] tidy --- include/mapnik/geometry_adapters.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp index 74d06b195..1bbb3d8a8 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry_adapters.hpp @@ -183,7 +183,6 @@ struct interior_const_type > template struct interior_mutable_type > { - //using type = boost::iterator_range::iterator>; using type = mapnik::detail::polygon_interior; }; From fb398ad465d7838b1dd761cb3b71f7e447289e00 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 4 Jul 2016 15:46:04 +0100 Subject: [PATCH 27/51] re-use typedefs --- include/mapnik/geometry_adapters.hpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp index 1bbb3d8a8..f0c5506df 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry_adapters.hpp @@ -177,7 +177,7 @@ struct ring_mutable_type > template struct interior_const_type > { - using type = boost::iterator_range::const_iterator>; + using type = boost::iterator_range::const_iterator> const; }; template @@ -190,13 +190,15 @@ struct interior_mutable_type > template struct exterior_ring > { - static mapnik::geometry::linear_ring & get(mapnik::geometry::polygon & p) + using ring_const_type = typename ring_const_type >::type; + using ring_mutable_type = typename ring_mutable_type >::type; + static ring_mutable_type get(mapnik::geometry::polygon & p) { if (p.empty()) throw std::runtime_error("ring must be initialized 1"); return p[0]; } - static mapnik::geometry::linear_ring const& get(mapnik::geometry::polygon const& p) + static ring_const_type get(mapnik::geometry::polygon const& p) { if (p.empty()) throw std::runtime_error("ring must be initialized 2"); return p[0]; @@ -206,18 +208,19 @@ struct exterior_ring > template struct interior_rings > { - using const_ring_iterator = typename mapbox::geometry::polygon::const_iterator; - using interior_type = mapnik::detail::polygon_interior; - using const_interior_type = boost::iterator_range; - static interior_type get(mapnik::geometry::polygon & p) + using interior_const_type = typename interior_const_type >::type; + using interior_mutable_type = typename interior_mutable_type >::type; + + static interior_const_type get(mapnik::geometry::polygon const& p) + { + return boost::make_iterator_range(p.begin() + 1, p.end()); + } + + static interior_mutable_type get(mapnik::geometry::polygon& p) { return mapnik::detail::polygon_interior(p); } - static const_interior_type get(mapnik::geometry::polygon const& p) - { - return boost::make_iterator_range(p.begin() + 1, p.end()); - } }; }}} From e29ca884df0331bd9614bd54b4445398e1682aa1 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 5 Jul 2016 10:23:16 +0100 Subject: [PATCH 28/51] has_empty - update logic to work with the current polygon model (FIXME: the naming is confusing to say the least) --- include/mapnik/geometry_is_empty.hpp | 33 +++++++++++++--------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/include/mapnik/geometry_is_empty.hpp b/include/mapnik/geometry_is_empty.hpp index 3315d317d..1bcbc9b3e 100644 --- a/include/mapnik/geometry_is_empty.hpp +++ b/include/mapnik/geometry_is_empty.hpp @@ -123,14 +123,25 @@ struct geometry_has_empty return false; } - bool operator() (mapnik::geometry::multi_line_string const& geom) const + bool operator() (mapnik::geometry::multi_line_string const& multi_line) const { - return test_multigeometry(geom); + for (auto const& line : multi_line) + { + if (line.empty()) return true; + } + return false; } - bool operator() (mapnik::geometry::multi_polygon const& geom) const + bool operator() (mapnik::geometry::multi_polygon const& multi_poly) const { - return test_multigeometry(geom); + for (auto const& poly : multi_poly) + { + if (poly.empty() || poly.front().empty()) // no-rings OR exterioir is empty + { + return true; + } + } + return false; } bool operator() (mapnik::geometry::geometry_collection const& geom) const @@ -150,20 +161,6 @@ struct geometry_has_empty { return true; } - -private: - template - bool test_multigeometry(U const & geom) const - { - for (auto const& item : geom) - { - if (item.empty()) - { - return true; - } - } - return false; - } }; } From 335ce8e50b822324804c98112a3d8cef3aec9915 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 5 Jul 2016 10:24:26 +0100 Subject: [PATCH 29/51] is_empty - fix implementation --- include/mapnik/geometry_is_empty.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/geometry_is_empty.hpp b/include/mapnik/geometry_is_empty.hpp index 1bcbc9b3e..ccc85a41e 100644 --- a/include/mapnik/geometry_is_empty.hpp +++ b/include/mapnik/geometry_is_empty.hpp @@ -54,7 +54,7 @@ struct geometry_is_empty bool operator() (mapnik::geometry::polygon const& geom) const { - return geom.empty(); + return geom.empty() || geom.front().empty(); } bool operator() (mapnik::geometry::multi_point const& geom) const From 68f53cfcd0a951b59cad75247d849bdbe8683be8 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 5 Jul 2016 10:24:54 +0100 Subject: [PATCH 30/51] uncomment is_empty/has_empty tests --- test/unit/geometry/has_empty.cpp | 2 -- test/unit/geometry/is_empty.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp index 32585c333..ff2e40f23 100644 --- a/test/unit/geometry/has_empty.cpp +++ b/test/unit/geometry/has_empty.cpp @@ -130,14 +130,12 @@ SECTION("multi-polygon") { REQUIRE(!mapnik::geometry::has_empty(geom)); } { - /*** FIXME mapnik::geometry::multi_polygon geom; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; poly.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); REQUIRE(mapnik::geometry::has_empty(geom)); - ***/ } { mapnik::geometry::multi_polygon geom; diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp index 216ea1096..25ed8a487 100644 --- a/test/unit/geometry/is_empty.cpp +++ b/test/unit/geometry/is_empty.cpp @@ -52,12 +52,10 @@ SECTION("polygon") { REQUIRE(mapnik::geometry::is_empty(poly)); } { - /*** FIXME mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; poly.push_back(std::move(ring)); REQUIRE(mapnik::geometry::is_empty(poly)); - ***/ } { mapnik::geometry::polygon poly; From 710a9be5b099c2f2a1865b65d3fcce806b59fdf4 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 5 Jul 2016 10:47:41 +0100 Subject: [PATCH 31/51] update to the latest geometry.hpp --- deps/mapbox/geometry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/mapbox/geometry b/deps/mapbox/geometry index d463e6c8a..d1259f75b 160000 --- a/deps/mapbox/geometry +++ b/deps/mapbox/geometry @@ -1 +1 @@ -Subproject commit d463e6c8a24178490317fa341e5cc29c3281d4f6 +Subproject commit d1259f75b01235e88e7839899e4e3cbe9ca344ce From c478849eba1a3d9f285472f59749eb23623cd1a4 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 6 Jul 2016 17:43:45 +0100 Subject: [PATCH 32/51] implement different strategy for adapting to boost::geometry using internal structure for accessing interior rings --- include/mapnik/geometry/multi_polygon.hpp | 13 +++- include/mapnik/geometry/polygon.hpp | 88 ++++++++++++++++------- include/mapnik/geometry_adapters.hpp | 10 ++- include/mapnik/polygon_interior.hpp | 79 -------------------- 4 files changed, 75 insertions(+), 115 deletions(-) delete mode 100644 include/mapnik/polygon_interior.hpp diff --git a/include/mapnik/geometry/multi_polygon.hpp b/include/mapnik/geometry/multi_polygon.hpp index fdf28437a..735df3c44 100644 --- a/include/mapnik/geometry/multi_polygon.hpp +++ b/include/mapnik/geometry/multi_polygon.hpp @@ -24,12 +24,19 @@ #define MAPNIK_GEOMETRY_MULTI_POLYGON_HPP // geometry -#include +#include namespace mapnik { namespace geometry { -template -using multi_polygon = mapbox::geometry::multi_polygon; +template class Cont = std::vector> +struct multi_polygon : Cont> +{ + using coordinate_type = T; + using polygon_type = polygon; + using container_type = Cont; + using container_type::container_type; +}; + }} diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp index 378e8ae8d..e1431d562 100644 --- a/include/mapnik/geometry/polygon.hpp +++ b/include/mapnik/geometry/polygon.hpp @@ -26,48 +26,82 @@ // geometry #include -// stl -//#include - namespace mapnik { namespace geometry { template using linear_ring = mapbox::geometry::linear_ring; template -using polygon = mapbox::geometry::polygon; - - -/* -template -using rings_container = std::vector>; - -template class InteriorRings = rings_container> -struct polygon +struct polygon : mapbox::geometry::polygon { using coordinate_type = T; - using rings_container = InteriorRings; - linear_ring exterior_ring; - rings_container interior_rings; - - inline void set_exterior_ring(linear_ring && ring) + using base_type = mapbox::geometry::polygon; + using linear_ring_type = linear_ring; + struct interior_rings { - exterior_ring = std::move(ring); + using iterator = typename base_type::iterator; + using const_iterator = typename base_type::const_iterator; + using value_type = typename base_type::value_type; + interior_rings(polygon & poly) + : poly_(poly) {} + iterator begin() + { + auto itr = poly_.begin(); + std::advance(itr, 1); + return itr; + } + + iterator end() { return poly_.end();} + const_iterator begin() const + { + auto itr = poly_.begin(); + std::advance(itr, 1); + return itr; + } + const_iterator end() const { return poly_.end();} + + void clear() + { + poly_.resize(1); + } + + void resize(std::size_t size) + { + poly_.resize(size + 1); + } + + std::size_t size() const + { + return poly_.empty() ? 0 : poly_.size() - 1; + } + + void push_back(value_type const& val) { poly_.push_back(val); } + value_type& back() { return poly_.back(); } + value_type const& back() const { return poly_.back(); } + polygon & poly_; + }; + + polygon() + : base_type(), + interior_(*this) + { + //this->resize(1); // explicit exterior ring ? } - inline void add_hole(linear_ring && ring) - { - interior_rings.emplace_back(std::move(ring)); - } + polygon(polygon const& other) + : base_type(other), + interior_(*this) {} - inline bool empty() const { return exterior_ring.empty(); } - - inline std::size_t num_rings() const + interior_rings const& interior() const { - return 1 + interior_rings.size(); + return interior_; } + interior_rings & interior() + { + return interior_; + } + interior_rings interior_; }; -*/ }} diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp index f0c5506df..770cb630c 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry_adapters.hpp @@ -41,7 +41,6 @@ #include #include #include -#include #include // register point @@ -177,13 +176,13 @@ struct ring_mutable_type > template struct interior_const_type > { - using type = boost::iterator_range::const_iterator> const; + using type = typename mapnik::geometry::polygon::interior_rings const&; }; template struct interior_mutable_type > { - using type = mapnik::detail::polygon_interior; + using type = typename mapnik::geometry::polygon::interior_rings& ; }; // exterior @@ -213,14 +212,13 @@ struct interior_rings > static interior_const_type get(mapnik::geometry::polygon const& p) { - return boost::make_iterator_range(p.begin() + 1, p.end()); + return p.interior(); } static interior_mutable_type get(mapnik::geometry::polygon& p) { - return mapnik::detail::polygon_interior(p); + return p.interior(); } - }; }}} diff --git a/include/mapnik/polygon_interior.hpp b/include/mapnik/polygon_interior.hpp deleted file mode 100644 index bb8775d64..000000000 --- a/include/mapnik/polygon_interior.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/***************************************************************************** - * - * 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_POLYGON_INTERIOR_HPP -#define MAPNIK_POLYGON_INTERIOR_HPP - -#include - - -namespace mapnik { namespace detail { - -template -struct polygon_interior -{ - using coordinate_type = T; - using iterator = typename geometry::polygon::iterator; - using const_iterator = typename geometry::polygon::const_iterator; - using value_type = typename geometry::polygon::value_type; - - polygon_interior(geometry::polygon & poly) - : poly_(poly) {} - - iterator begin() - { - auto itr = poly_.begin(); - std::advance(itr, 1); - return itr; - } - - iterator end() { return poly_.end();} - const_iterator begin() const - { - auto itr = poly_.begin(); - std::advance(itr, 1); - return itr; - } - const_iterator end() const { return poly_.end();} - - void clear() - { - poly_.resize(1); - } - void resize(std::size_t size) - { - poly_.resize(size + 1); - } - - std::size_t size() const - { - return poly_.empty() ? 0 : poly_.size() - 1; - } - - value_type& back() { return poly_.back(); } - value_type const& back() const { return poly_.back(); } - geometry::polygon & poly_; -}; - -}} - -#endif // MAPNIK_POLYGON_INTERIOR_HPP From d810ce46f2168f8ab955402b933fe3dbfd5e499d Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 6 Jul 2016 17:45:13 +0100 Subject: [PATCH 33/51] re-enable geometry_strategy_test --- test/unit/geometry/geometry_strategy_test.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp index d2b563a8f..cb20cb74a 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -10,7 +10,6 @@ #include #include -#if 0 //*** FIXME TEST_CASE("geometry strategy tests") { SECTION("proj and view strategy") { using namespace mapnik::geometry; @@ -184,4 +183,3 @@ SECTION("scaling strategies - double to int64") { } } // END SECTION } // END TEST CASE -#endif From f0a37c761b0c99d353141eed7aa4612e75c76e8f Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 7 Jul 2016 12:29:19 +0100 Subject: [PATCH 34/51] polygon - add move ctor --- include/mapnik/geometry/polygon.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp index e1431d562..0840fd000 100644 --- a/include/mapnik/geometry/polygon.hpp +++ b/include/mapnik/geometry/polygon.hpp @@ -88,6 +88,10 @@ struct polygon : mapbox::geometry::polygon //this->resize(1); // explicit exterior ring ? } + polygon(polygon && other) + : base_type(std::move(other)), + interior_(*this) {} + polygon(polygon const& other) : base_type(other), interior_(*this) {} From 359a3a845a46c1f0ee403cf11f8f25b4a63d54f4 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 11 Jul 2016 10:17:45 +0100 Subject: [PATCH 35/51] update geometry.hpp --- deps/mapbox/geometry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/mapbox/geometry b/deps/mapbox/geometry index d1259f75b..03778c6af 160000 --- a/deps/mapbox/geometry +++ b/deps/mapbox/geometry @@ -1 +1 @@ -Subproject commit d1259f75b01235e88e7839899e4e3cbe9ca344ce +Subproject commit 03778c6af7f1f116fc5722596a31334315451a53 From 033c54617c7e634a0119f262ff19bb074b63189f Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 11 Jul 2016 10:44:18 +0100 Subject: [PATCH 36/51] c++ format --- include/mapnik/geometry_remove_empty.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mapnik/geometry_remove_empty.hpp b/include/mapnik/geometry_remove_empty.hpp index 9838b5a61..de60d9869 100644 --- a/include/mapnik/geometry_remove_empty.hpp +++ b/include/mapnik/geometry_remove_empty.hpp @@ -32,25 +32,25 @@ namespace detail { struct geometry_remove_empty { - mapnik::geometry::multi_line_string operator() (mapnik::geometry::multi_line_string const & geom) const + mapnik::geometry::multi_line_string operator() (mapnik::geometry::multi_line_string const& geom) const { return remove_empty(geom); } - mapnik::geometry::multi_polygon operator() (mapnik::geometry::multi_polygon const & geom) const + mapnik::geometry::multi_polygon operator() (mapnik::geometry::multi_polygon const& geom) const { return remove_empty(geom); } template - T operator() (T const & geom) const + T operator() (T const& geom) const { return geom; } private: template - T remove_empty(T const & geom) const + T remove_empty(T const& geom) const { T new_geom; for (auto const & g : geom) From 01e962d216f5587558b4e9506bd0355f79ed82a6 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 11 Jul 2016 10:44:59 +0100 Subject: [PATCH 37/51] centroid - re-implement avoiding inefficient `remove_empty` --- include/mapnik/geometry_centroid.hpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/include/mapnik/geometry_centroid.hpp b/include/mapnik/geometry_centroid.hpp index 5dc7735b1..c88588fba 100644 --- a/include/mapnik/geometry_centroid.hpp +++ b/include/mapnik/geometry_centroid.hpp @@ -105,17 +105,29 @@ private: } template - result_type centroid_multi(Geom const & geom) const + result_type centroid_multi(Geom const & multi_geom) const { // https://github.com/mapnik/mapnik/issues/3169 #if BOOST_VERSION <= 105900 - if (mapnik::geometry::has_empty(geom)) + if (mapnik::geometry::has_empty(multi_geom)) { - Geom stripped = mapnik::geometry::remove_empty(geom); - return centroid_simple(stripped); + mapnik::geometry::multi_point multi_pt; + multi_pt.reserve(multi_geom.size()); + for (auto const& geom : multi_geom) + { + try + { + point c; + boost::geometry::centroid(geom, c); + multi_pt.push_back(std::move(c)); + + } + catch (boost::geometry::centroid_exception const & e) {} + } + return centroid_simple(multi_pt); } #endif - return centroid_simple(geom); + return centroid_simple(multi_geom); } }; From 74bf270d214a5e3bc5b308de4c7cabf7edf0859b Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 11 Jul 2016 11:55:20 +0100 Subject: [PATCH 38/51] geometry is_simple - handle empty polygons --- include/mapnik/geometry_is_simple.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/geometry_is_simple.hpp b/include/mapnik/geometry_is_simple.hpp index b73cc733f..68953ca1f 100644 --- a/include/mapnik/geometry_is_simple.hpp +++ b/include/mapnik/geometry_is_simple.hpp @@ -81,7 +81,7 @@ struct geometry_is_simple result_type operator() (polygon const& poly) const { - return boost::geometry::is_simple(poly); + return poly.empty() ? true : boost::geometry::is_simple(poly); } result_type operator() (multi_point const& multi_pt) const From fd41b682beb9340ff70bcabc714f0d13271a186d Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 12 Jul 2016 11:11:35 +0100 Subject: [PATCH 39/51] geometry_generator - fix synthesised attribute types --- include/mapnik/json/geometry_generator_grammar.hpp | 5 ++--- .../mapnik/json/geometry_generator_grammar_impl.hpp | 10 ++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/include/mapnik/json/geometry_generator_grammar.hpp b/include/mapnik/json/geometry_generator_grammar.hpp index 8e24ebaf0..931c41629 100644 --- a/include/mapnik/json/geometry_generator_grammar.hpp +++ b/include/mapnik/json/geometry_generator_grammar.hpp @@ -96,11 +96,10 @@ struct geometry_generator_grammar : karma::rule const&()> point; karma::rule const&()> point_coord; karma::rule const&()> linestring; - karma::rule::container_type const&()> linestring_coord; + karma::rule const&()> linestring_coord; karma::rule const&()> polygon; karma::rule const&()> polygon_coord; - //karma::rule const&()> exterior_ring_coord; - //karma::rule const&()> polygon_coord; + karma::rule const&()> linearring_coord; karma::rule const& ()> multi_point; karma::rule const& ()> multi_point_coord; karma::rule const& ()> multi_linestring; diff --git a/include/mapnik/json/geometry_generator_grammar_impl.hpp b/include/mapnik/json/geometry_generator_grammar_impl.hpp index dc37a76d7..e5670a88c 100644 --- a/include/mapnik/json/geometry_generator_grammar_impl.hpp +++ b/include/mapnik/json/geometry_generator_grammar_impl.hpp @@ -98,19 +98,17 @@ geometry_generator_grammar::geometry_generator_grammar ; linestring_coord = point_coord % lit(',') ; - polygon_coord = (lit('[') << linestring_coord << lit(']')) % lit(',') //<< interior_ring_coord + linearring_coord = linestring.alias(); + ; + polygon_coord = (lit('[') << linearring_coord << lit(']')) % lit(',') ; - //exterior_ring_coord = linestring_coord.alias() - // ; - //interior_ring_coord = *(lit(",[") << exterior_ring_coord << lit(']')) - // ; multi_point_coord = linestring_coord.alias() ; multi_linestring_coord = (lit('[') << linestring_coord << lit(']')) % lit(',') ; multi_polygon_coord = (lit('[') << polygon_coord << lit(']')) % lit(',') ; - geometries = geometry % lit(',') + geometries = geometry % lit(',') ; } From e08c3c1a20db52b047588948046046e2af2197bb Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 12 Jul 2016 11:13:45 +0100 Subject: [PATCH 40/51] using `alias()` doesn't work: line_string and linear_ring are different types (no-conversion) --- include/mapnik/json/geometry_generator_grammar_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/json/geometry_generator_grammar_impl.hpp b/include/mapnik/json/geometry_generator_grammar_impl.hpp index e5670a88c..952bb739f 100644 --- a/include/mapnik/json/geometry_generator_grammar_impl.hpp +++ b/include/mapnik/json/geometry_generator_grammar_impl.hpp @@ -98,7 +98,7 @@ geometry_generator_grammar::geometry_generator_grammar ; linestring_coord = point_coord % lit(',') ; - linearring_coord = linestring.alias(); + linearring_coord = point_coord % lit(',') ; polygon_coord = (lit('[') << linearring_coord << lit(']')) % lit(',') ; From abb4271bea9c2016f6229da2d3ce8bc4c7e5cb44 Mon Sep 17 00:00:00 2001 From: artemp Date: Tue, 12 Jul 2016 17:42:53 +0100 Subject: [PATCH 41/51] extract_bounding_box_grammar - make features optional / ref #3463 --- include/mapnik/json/extract_bounding_box_grammar_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp index 9e21baa08..25ddbcd92 100644 --- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp +++ b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp @@ -110,7 +110,7 @@ extract_bounding_box_grammar::extract_bounding_bo >> *((json.key_value - lit("\"features\"")) >> lit(',')) >> lit("\"features\"") >> lit(':')) - >> lit('[') >> (feature(_r1,_a) % lit(',')) >> lit(']') + >> lit('[') >> -(feature(_r1,_a) % lit(',')) >> lit(']') ; feature = raw[lit('{')[_a = 1] From 132aa6654f6cf98015d2fd6bf9c4f215e75eec0b Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 13 Jul 2016 15:07:08 +0100 Subject: [PATCH 42/51] add empty_featureset (returning feature_ptr()) implementation --- include/mapnik/featureset.hpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/mapnik/featureset.hpp b/include/mapnik/featureset.hpp index c6829d1eb..6886d8755 100644 --- a/include/mapnik/featureset.hpp +++ b/include/mapnik/featureset.hpp @@ -41,8 +41,23 @@ struct MAPNIK_DECL Featureset : private util::noncopyable virtual ~Featureset() {} }; + +struct MAPNIK_DECL empty_featureset final : Featureset +{ + feature_ptr next() + { + return feature_ptr(); + } + ~empty_featureset() {} +}; + using featureset_ptr = std::shared_ptr; +inline featureset_ptr make_empty_featureset() +{ + return std::make_shared(); +} + } #endif // MAPNIK_FEATURESET_HPP From dc74551dc0c29cbd87264caf1534c76ddad24f08 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 13 Jul 2016 15:16:33 +0100 Subject: [PATCH 43/51] always return am empty featureset instead of featureset_ptr() --- plugins/input/csv/csv_datasource.cpp | 2 +- plugins/input/geojson/geojson_datasource.cpp | 4 ++-- plugins/input/ogr/ogr_datasource.cpp | 4 ++-- plugins/input/pgraster/pgraster_datasource.cpp | 6 +++--- plugins/input/postgis/postgis_datasource.cpp | 6 +++--- plugins/input/raster/raster_datasource.cpp | 2 +- plugins/input/sqlite/sqlite_datasource.cpp | 4 ++-- plugins/input/topojson/topojson_datasource.cpp | 2 +- src/map.cpp | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 6c1ff1014..4a246b404 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -431,7 +431,7 @@ mapnik::featureset_ptr csv_datasource::features(mapnik::query const& q) const return std::make_shared(filename_, filter, locator_, separator_, quote_, headers_, ctx_); } } - return mapnik::featureset_ptr(); + return mapnik::make_empty_featureset(); } mapnik::featureset_ptr csv_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index e9456f8e1..d2ebc2d54 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -587,8 +587,8 @@ mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) cons } } - // otherwise return an empty featureset pointer - return mapnik::featureset_ptr(); + // otherwise return an empty featureset + return mapnik::make_empty_featureset(); } mapnik::featureset_ptr geojson_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const diff --git a/plugins/input/ogr/ogr_datasource.cpp b/plugins/input/ogr/ogr_datasource.cpp index dc0fc9bec..2943962fc 100644 --- a/plugins/input/ogr/ogr_datasource.cpp +++ b/plugins/input/ogr/ogr_datasource.cpp @@ -560,7 +560,7 @@ featureset_ptr ogr_datasource::features(query const& q) const } } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } featureset_ptr ogr_datasource::features_at_point(coord2d const& pt, double tol) const @@ -603,5 +603,5 @@ featureset_ptr ogr_datasource::features_at_point(coord2d const& pt, double tol) } } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } diff --git a/plugins/input/pgraster/pgraster_datasource.cpp b/plugins/input/pgraster/pgraster_datasource.cpp index 9390f3ace..ced1810b5 100644 --- a/plugins/input/pgraster/pgraster_datasource.cpp +++ b/plugins/input/pgraster/pgraster_datasource.cpp @@ -998,7 +998,7 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } @@ -1011,7 +1011,7 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double if (pool) { shared_ptr conn = pool->borrowObject(); - if (!conn) return featureset_ptr(); + if (!conn) return mapnik::make_empty_featureset(); if (conn->isOK()) { @@ -1082,7 +1082,7 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double } } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } box2d pgraster_datasource::envelope() const diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp index 909cd58ba..8aef44414 100644 --- a/plugins/input/postgis/postgis_datasource.cpp +++ b/plugins/input/postgis/postgis_datasource.cpp @@ -942,7 +942,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } @@ -955,7 +955,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t if (pool) { shared_ptr conn = pool->borrowObject(); - if (!conn) return featureset_ptr(); + if (!conn) return mapnik::make_empty_featureset(); if (conn->isOK()) { @@ -1030,7 +1030,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t } } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } box2d postgis_datasource::envelope() const diff --git a/plugins/input/raster/raster_datasource.cpp b/plugins/input/raster/raster_datasource.cpp index 4d8b5f99a..38a6aa94c 100644 --- a/plugins/input/raster/raster_datasource.cpp +++ b/plugins/input/raster/raster_datasource.cpp @@ -224,5 +224,5 @@ featureset_ptr raster_datasource::features_at_point(coord2d const&, double tol) { MAPNIK_LOG_WARN(raster) << "raster_datasource: feature_at_point not supported"; - return featureset_ptr(); + return mapnik::make_empty_featureset(); } diff --git a/plugins/input/sqlite/sqlite_datasource.cpp b/plugins/input/sqlite/sqlite_datasource.cpp index 939d9d319..37e44117b 100644 --- a/plugins/input/sqlite/sqlite_datasource.cpp +++ b/plugins/input/sqlite/sqlite_datasource.cpp @@ -551,7 +551,7 @@ featureset_ptr sqlite_datasource::features(query const& q) const using_subquery_); } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt, double tol) const @@ -631,5 +631,5 @@ featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt, double to using_subquery_); } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } diff --git a/plugins/input/topojson/topojson_datasource.cpp b/plugins/input/topojson/topojson_datasource.cpp index 502868562..e6cab26d8 100644 --- a/plugins/input/topojson/topojson_datasource.cpp +++ b/plugins/input/topojson/topojson_datasource.cpp @@ -284,7 +284,7 @@ mapnik::featureset_ptr topojson_datasource::features(mapnik::query const& q) con } } // otherwise return an empty featureset pointer - return mapnik::featureset_ptr(); + return mapnik::make_empty_featureset(); } mapnik::featureset_ptr topojson_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const diff --git a/src/map.cpp b/src/map.cpp index 3aff557c4..ca813e273 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -746,7 +746,7 @@ featureset_ptr Map::query_point(unsigned index, double x, double y) const else s << " (map has no layers)"; throw std::out_of_range(s.str()); } - return featureset_ptr(); + return mapnik::make_empty_featureset(); } featureset_ptr Map::query_map_point(unsigned index, double x, double y) const From f888fef86a8905f0ebd10a755d9509441aa10630 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 11 Nov 2016 15:05:46 +0100 Subject: [PATCH 44/51] update variant --- deps/mapbox/variant | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/mapbox/variant b/deps/mapbox/variant index 84a426a31..a5a79a594 160000 --- a/deps/mapbox/variant +++ b/deps/mapbox/variant @@ -1 +1 @@ -Subproject commit 84a426a31ad3b63c4b8f8d189841e19af48cda40 +Subproject commit a5a79a594f39d705a7ef969f54a0743516f0bc6d From 064b99168b89aedc48a6472eff79e7aca6906859 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 27 Mar 2017 16:14:51 +0100 Subject: [PATCH 45/51] geometry.hpp --- .gitmodules | 5 +- .travis.yml | 48 +- Makefile | 10 +- README.md | 2 +- SConstruct | 39 +- benchmark/bench_framework.hpp | 2 +- benchmark/run | 2 +- benchmark/test_expression_parse.cpp | 2 +- benchmark/test_polygon_clipping.cpp | 8 +- benchmark/test_proj_transform1.cpp | 2 +- bootstrap.sh | 63 +- circle.yml | 12 +- demo/c++/rundemo.cpp | 2 +- demo/python/README.txt | 20 - demo/python/rundemo.py | 379 ------ demo/viewer/about_dialog.cpp | 2 +- demo/viewer/about_dialog.hpp | 2 +- demo/viewer/info_dialog.cpp | 2 +- demo/viewer/info_dialog.hpp | 2 +- demo/viewer/layer_info_dialog.cpp | 2 +- demo/viewer/layer_info_dialog.hpp | 2 +- demo/viewer/layerdelegate.cpp | 2 +- demo/viewer/layerdelegate.hpp | 2 +- demo/viewer/layerlistmodel.cpp | 2 +- demo/viewer/layerlistmodel.hpp | 2 +- demo/viewer/layerwidget.cpp | 2 +- demo/viewer/layerwidget.hpp | 2 +- demo/viewer/main.cpp | 2 +- demo/viewer/mainwindow.cpp | 2 +- demo/viewer/mainwindow.hpp | 2 +- demo/viewer/mapwidget.cpp | 2 +- demo/viewer/mapwidget.hpp | 2 +- demo/viewer/styles_model.cpp | 2 +- demo/viewer/styles_model.hpp | 2 +- demo/viewer/viewer.pro | 1 - deps/agg/include/agg_vpgen_clip_polygon.h | 10 +- deps/agg/include/agg_vpgen_clip_polyline.h | 10 +- deps/mapbox/geometry | 2 +- deps/mapbox/variant | 2 +- include/build.py | 5 +- include/mapnik/agg_helpers.hpp | 2 +- include/mapnik/agg_pattern_source.hpp | 2 +- include/mapnik/agg_rasterizer.hpp | 2 +- include/mapnik/agg_render_marker.hpp | 9 +- include/mapnik/agg_renderer.hpp | 62 +- include/mapnik/attribute.hpp | 4 +- include/mapnik/attribute_collector.hpp | 4 +- include/mapnik/attribute_descriptor.hpp | 2 +- include/mapnik/boolean.hpp | 2 +- include/mapnik/cairo/cairo_context.hpp | 2 +- include/mapnik/cairo/cairo_image_util.hpp | 2 +- include/mapnik/cairo/cairo_render_vector.hpp | 2 +- include/mapnik/cairo/cairo_renderer.hpp | 2 +- include/mapnik/cairo_io.hpp | 2 +- include/mapnik/color.hpp | 9 +- include/mapnik/color_factory.hpp | 2 +- include/mapnik/config.hpp | 2 +- include/mapnik/config_error.hpp | 8 +- include/mapnik/coord.hpp | 3 +- include/mapnik/css_color_grammar.hpp | 67 -- .../mapnik/css_color_grammar_x3.hpp | 42 +- ..._impl.hpp => css_color_grammar_x3_def.hpp} | 399 ++++--- include/mapnik/csv/csv_grammar.hpp | 79 -- include/mapnik/csv/csv_grammar_x3.hpp | 67 ++ include/mapnik/csv/csv_grammar_x3_def.hpp | 120 ++ include/mapnik/csv/csv_types.hpp | 2 +- include/mapnik/cxx11_support.hpp | 43 + include/mapnik/datasource.hpp | 15 +- include/mapnik/datasource_cache.hpp | 2 +- include/mapnik/datasource_geometry_type.hpp | 2 +- include/mapnik/debug.hpp | 2 +- include/mapnik/ellipsoid.hpp | 2 +- include/mapnik/enumeration.hpp | 13 +- include/mapnik/evaluate_global_attributes.hpp | 42 +- include/mapnik/expression.hpp | 2 +- include/mapnik/expression_evaluator.hpp | 4 +- include/mapnik/expression_grammar.hpp | 103 -- include/mapnik/expression_grammar_impl.hpp | 280 ----- include/mapnik/expression_grammar_x3.hpp | 51 + .../mapnik/expression_grammar_x3_config.hpp | 43 + include/mapnik/expression_grammar_x3_def.hpp | 456 ++++++++ include/mapnik/expression_node.hpp | 86 +- include/mapnik/expression_node_types.hpp | 4 +- include/mapnik/expression_string.hpp | 2 +- include/mapnik/extend_converter.hpp | 232 ++++ include/mapnik/factory.hpp | 2 +- include/mapnik/feature.hpp | 15 +- include/mapnik/feature_factory.hpp | 4 +- include/mapnik/feature_kv_iterator.hpp | 2 +- include/mapnik/feature_layer_desc.hpp | 2 +- include/mapnik/feature_style_processor.hpp | 12 +- .../feature_style_processor_context.hpp | 2 +- .../mapnik/feature_style_processor_impl.hpp | 105 +- include/mapnik/feature_type_style.hpp | 2 +- include/mapnik/featureset.hpp | 2 +- include/mapnik/filter_factory.hpp | 8 - include/mapnik/filter_featureset.hpp | 2 +- include/mapnik/font_engine_freetype.hpp | 2 +- include/mapnik/font_set.hpp | 2 +- include/mapnik/function_call.hpp | 6 +- include/mapnik/geom_util.hpp | 6 +- include/mapnik/geometry.hpp | 10 +- .../boost_adapters.hpp} | 127 ++- .../geometry/boost_spirit_karma_adapter.hpp | 121 ++ include/mapnik/{ => geometry}/box2d.hpp | 5 +- include/mapnik/{ => geometry}/box2d_impl.hpp | 53 +- .../centroid.hpp} | 10 +- .../correct.hpp} | 4 +- .../envelope.hpp} | 4 +- .../envelope_impl.hpp} | 8 +- .../fusion_adapted.hpp} | 2 +- .../mapnik/{ => geometry}/geometry_type.hpp | 6 +- .../mapnik/{ => geometry}/geometry_types.hpp | 2 +- include/mapnik/geometry/is_empty.hpp | 173 +++ .../is_simple.hpp} | 27 +- .../is_valid.hpp} | 53 +- include/mapnik/geometry/polygon.hpp | 75 +- .../remove_empty.hpp} | 4 +- .../reprojection.hpp} | 2 +- .../reprojection_impl.hpp} | 18 +- .../strategy.hpp} | 32 +- .../to_path.hpp} | 4 +- .../transform.hpp} | 9 +- include/mapnik/geometry_is_empty.hpp | 184 --- include/mapnik/global.hpp | 2 +- include/mapnik/gradient.hpp | 4 +- include/mapnik/grid/grid.hpp | 4 +- include/mapnik/grid/grid_pixel.hpp | 2 +- include/mapnik/grid/grid_pixfmt.hpp | 2 +- include/mapnik/grid/grid_rasterizer.hpp | 2 +- include/mapnik/grid/grid_render_marker.hpp | 2 +- include/mapnik/grid/grid_renderer.hpp | 8 +- include/mapnik/grid/grid_renderer_base.hpp | 2 +- include/mapnik/grid/grid_rendering_buffer.hpp | 2 +- include/mapnik/grid/grid_view.hpp | 8 +- include/mapnik/group/group_layout.hpp | 2 +- include/mapnik/group/group_layout_manager.hpp | 4 +- include/mapnik/group/group_rule.hpp | 2 +- .../mapnik/group/group_symbolizer_helper.hpp | 14 +- .../group/group_symbolizer_properties.hpp | 2 +- include/mapnik/hextree.hpp | 2 +- include/mapnik/hit_test_filter.hpp | 4 +- include/mapnik/image.hpp | 2 +- include/mapnik/image_any.hpp | 2 +- include/mapnik/image_compositing.hpp | 2 +- include/mapnik/image_copy.hpp | 2 +- include/mapnik/image_filter.hpp | 12 +- include/mapnik/image_filter_grammar.hpp | 87 -- include/mapnik/image_filter_grammar_impl.hpp | 141 --- include/mapnik/image_filter_grammar_x3.hpp | 55 + .../mapnik/image_filter_grammar_x3_def.hpp | 261 +++++ include/mapnik/image_filter_types.hpp | 43 +- include/mapnik/image_impl.hpp | 2 +- include/mapnik/image_null.hpp | 2 +- include/mapnik/image_options.hpp | 6 +- include/mapnik/image_reader.hpp | 8 +- include/mapnik/image_scaling.hpp | 2 +- include/mapnik/image_scaling_traits.hpp | 2 +- include/mapnik/image_util.hpp | 6 +- include/mapnik/image_util_jpeg.hpp | 2 +- include/mapnik/image_util_png.hpp | 2 +- include/mapnik/image_util_tiff.hpp | 2 +- include/mapnik/image_util_webp.hpp | 2 +- include/mapnik/image_view.hpp | 2 +- include/mapnik/image_view_any.hpp | 2 +- include/mapnik/image_view_impl.hpp | 2 +- include/mapnik/image_view_null.hpp | 2 +- include/mapnik/jpeg_io.hpp | 2 +- .../mapnik/json/attribute_value_visitor.hpp | 1 - include/mapnik/json/create_feature.hpp | 242 ++++ ...{geometry_util.hpp => create_geometry.hpp} | 140 +-- include/mapnik/json/error_handler.hpp | 73 -- .../json/extract_bounding_box_grammar.hpp | 64 -- .../extract_bounding_box_grammar_impl.hpp | 157 --- .../mapnik/json/extract_bounding_boxes_x3.hpp | 35 + .../json/extract_bounding_boxes_x3_config.hpp | 117 ++ .../json/feature_collection_grammar.hpp | 103 -- .../json/feature_collection_grammar_impl.hpp | 122 -- .../mapnik/json/feature_generator_grammar.hpp | 23 +- .../json/feature_generator_grammar_impl.hpp | 9 +- include/mapnik/json/feature_grammar.hpp | 91 -- include/mapnik/json/feature_grammar_impl.hpp | 87 -- include/mapnik/json/feature_grammar_x3.hpp | 50 + .../mapnik/json/feature_grammar_x3_def.hpp | 318 ++++++ include/mapnik/json/feature_parser.hpp | 21 +- include/mapnik/json/generic_json.hpp | 196 ---- .../generic_json_grammar_x3.hpp} | 44 +- .../json/generic_json_grammar_x3_def.hpp | 133 +++ include/mapnik/json/geojson_grammar_x3.hpp | 83 ++ .../mapnik/json/geojson_grammar_x3_def.hpp | 183 +++ .../json/geometry_generator_grammar.hpp | 58 +- .../json/geometry_generator_grammar_impl.hpp | 85 +- include/mapnik/json/geometry_grammar.hpp | 63 - include/mapnik/json/geometry_grammar_impl.hpp | 94 -- .../geometry_grammar_x3.hpp} | 37 +- .../mapnik/json/geometry_grammar_x3_def.hpp | 161 +++ include/mapnik/json/geometry_parser.hpp | 2 +- include/mapnik/json/json_grammar_config.hpp | 118 ++ include/mapnik/json/json_value.hpp | 65 ++ .../mapnik/json/parse_feature.hpp | 26 +- include/mapnik/json/positions_grammar.hpp | 55 - .../mapnik/json/positions_grammar_impl.hpp | 97 -- include/mapnik/json/positions_grammar_x3.hpp | 50 + .../mapnik/json/positions_grammar_x3_def.hpp | 67 ++ .../json/{positions.hpp => positions_x3.hpp} | 11 +- .../json/properties_generator_grammar.hpp | 4 +- .../properties_generator_grammar_impl.hpp | 20 +- include/mapnik/json/stringifier.hpp | 2 +- include/mapnik/json/topojson_grammar.hpp | 206 ---- include/mapnik/json/topojson_grammar_impl.hpp | 206 ---- include/mapnik/json/topojson_grammar_x3.hpp | 48 + .../mapnik/json/topojson_grammar_x3_def.hpp | 445 ++++++++ include/mapnik/json/topojson_utils.hpp | 6 +- include/mapnik/json/topology.hpp | 4 +- .../mapnik/json/unicode_string_grammar_x3.hpp | 46 + .../json/unicode_string_grammar_x3_def.hpp | 159 +++ include/mapnik/json/value_converters.hpp | 2 +- include/mapnik/label_collision_detector.hpp | 4 +- include/mapnik/layer.hpp | 26 +- include/mapnik/load_map.hpp | 2 +- include/mapnik/make_unique.hpp | 6 +- include/mapnik/map.hpp | 4 +- include/mapnik/mapped_memory_cache.hpp | 2 +- include/mapnik/marker.hpp | 2 +- include/mapnik/marker_cache.hpp | 2 +- include/mapnik/marker_helpers.hpp | 10 +- include/mapnik/markers_placement.hpp | 2 +- include/mapnik/markers_placements/basic.hpp | 2 +- .../mapnik/markers_placements/interior.hpp | 4 +- include/mapnik/markers_placements/line.hpp | 4 +- include/mapnik/markers_placements/point.hpp | 4 +- .../markers_placements/vertext_first.hpp | 2 +- .../markers_placements/vertext_last.hpp | 2 +- include/mapnik/memory_datasource.hpp | 2 +- include/mapnik/memory_featureset.hpp | 6 +- include/mapnik/octree.hpp | 2 +- include/mapnik/offset_converter.hpp | 34 +- include/mapnik/palette.hpp | 2 +- include/mapnik/params.hpp | 4 +- include/mapnik/params_impl.hpp | 4 +- include/mapnik/parse_path.hpp | 2 +- include/mapnik/path.hpp | 8 +- include/mapnik/path_expression.hpp | 2 +- include/mapnik/path_expression_grammar_x3.hpp | 48 + .../mapnik/path_expression_grammar_x3_def.hpp | 63 + include/mapnik/pixel_position.hpp | 2 +- include/mapnik/pixel_types.hpp | 2 +- include/mapnik/plugin.hpp | 2 +- include/mapnik/png_io.hpp | 61 +- include/mapnik/pool.hpp | 2 +- include/mapnik/proj_strategy.hpp | 2 +- include/mapnik/proj_transform.hpp | 2 +- include/mapnik/projection.hpp | 2 +- include/mapnik/ptree_helpers.hpp | 2 +- include/mapnik/quad_tree.hpp | 32 +- include/mapnik/query.hpp | 20 +- include/mapnik/raster.hpp | 8 +- include/mapnik/raster_colorizer.hpp | 2 +- include/mapnik/renderer_common.hpp | 4 +- .../apply_vertex_converter.hpp | 2 +- .../renderer_common/clipping_extent.hpp | 4 +- .../renderer_common/pattern_alignment.hpp | 2 +- .../process_building_symbolizer.hpp | 2 +- .../process_point_symbolizer.hpp | 8 +- .../process_polygon_symbolizer.hpp | 2 +- .../process_raster_symbolizer.hpp | 2 +- .../render_group_symbolizer.hpp | 4 +- .../mapnik/renderer_common/render_pattern.hpp | 2 +- .../mapnik/renderer_common/render_thunk.hpp | 3 +- include/mapnik/request.hpp | 4 +- include/mapnik/rule.hpp | 2 +- include/mapnik/rule_cache.hpp | 2 +- include/mapnik/safe_cast.hpp | 2 +- include/mapnik/save_map.hpp | 2 +- include/mapnik/scale_denominator.hpp | 2 +- include/mapnik/segment.hpp | 2 +- include/mapnik/simplify_converter.hpp | 12 +- include/mapnik/span_image_filter.hpp | 6 +- include/mapnik/sql_utils.hpp | 136 ++- include/mapnik/sse.hpp | 2 +- include/mapnik/stringify_macro.hpp | 7 +- include/mapnik/svg/geometry_svg_generator.hpp | 2 +- .../svg/geometry_svg_generator_impl.hpp | 4 +- include/mapnik/svg/output/svg_generator.hpp | 4 +- .../svg/output/svg_output_attributes.hpp | 12 +- .../mapnik/svg/output/svg_output_grammars.hpp | 2 +- .../svg/output/svg_output_grammars_impl.hpp | 2 +- .../mapnik/svg/output/svg_path_iterator.hpp | 2 +- include/mapnik/svg/output/svg_renderer.hpp | 8 +- include/mapnik/svg/svg_converter.hpp | 2 +- .../svg_grammar_config_x3.hpp} | 53 +- include/mapnik/svg/svg_parser.hpp | 2 +- include/mapnik/svg/svg_parser_exception.hpp | 6 +- include/mapnik/svg/svg_path_adapter.hpp | 4 +- include/mapnik/svg/svg_path_attributes.hpp | 2 +- include/mapnik/svg/svg_path_commands.hpp | 2 +- include/mapnik/svg/svg_path_grammar.hpp | 61 - include/mapnik/svg/svg_path_grammar_impl.hpp | 112 -- include/mapnik/svg/svg_path_grammar_x3.hpp | 46 + .../mapnik/svg/svg_path_grammar_x3_def.hpp | 203 ++++ include/mapnik/svg/svg_path_parser.hpp | 7 +- .../mapnik/svg/svg_points_grammar_impl.hpp | 61 - include/mapnik/svg/svg_renderer_agg.hpp | 6 +- include/mapnik/svg/svg_storage.hpp | 4 +- include/mapnik/svg/svg_transform_grammar.hpp | 56 - .../mapnik/svg/svg_transform_grammar_impl.hpp | 172 --- .../mapnik/svg/svg_transform_grammar_x3.hpp | 43 + .../svg/svg_transform_grammar_x3_def.hpp | 163 +++ include/mapnik/symbolizer.hpp | 6 +- include/mapnik/symbolizer_base.hpp | 17 +- include/mapnik/symbolizer_default_values.hpp | 11 +- include/mapnik/symbolizer_dispatch.hpp | 2 +- include/mapnik/symbolizer_enumerations.hpp | 2 +- include/mapnik/symbolizer_hash.hpp | 2 +- include/mapnik/symbolizer_keys.hpp | 3 +- include/mapnik/symbolizer_utils.hpp | 6 +- .../text/evaluated_format_properties_ptr.hpp | 2 +- include/mapnik/text/face.hpp | 5 +- include/mapnik/text/font_feature_settings.hpp | 2 +- include/mapnik/text/font_library.hpp | 2 +- include/mapnik/text/formatting/base.hpp | 2 +- include/mapnik/text/formatting/format.hpp | 2 +- include/mapnik/text/formatting/layout.hpp | 2 +- include/mapnik/text/formatting/list.hpp | 2 +- include/mapnik/text/formatting/registry.hpp | 2 +- include/mapnik/text/formatting/text.hpp | 2 +- include/mapnik/text/glyph_info.hpp | 2 +- include/mapnik/text/glyph_positions.hpp | 4 +- include/mapnik/text/harfbuzz_shaper.hpp | 142 ++- include/mapnik/text/icu_shaper.hpp | 2 +- include/mapnik/text/itemizer.hpp | 4 +- include/mapnik/text/placement_finder.hpp | 6 +- include/mapnik/text/placement_finder_impl.hpp | 5 +- include/mapnik/text/placements/base.hpp | 2 +- include/mapnik/text/placements/dummy.hpp | 2 +- include/mapnik/text/placements/list.hpp | 6 +- include/mapnik/text/placements/registry.hpp | 2 +- include/mapnik/text/placements/simple.hpp | 2 +- include/mapnik/text/properties_util.hpp | 2 +- include/mapnik/text/renderer.hpp | 12 +- include/mapnik/text/symbolizer_helpers.hpp | 4 +- include/mapnik/text/text_layout.hpp | 12 +- include/mapnik/text/text_line.hpp | 2 +- include/mapnik/text/text_properties.hpp | 5 +- include/mapnik/tiff_io.hpp | 2 +- include/mapnik/timer.hpp | 2 +- include/mapnik/tolerance_iterator.hpp | 2 +- .../{ => transform}/parse_transform.hpp | 2 +- .../{ => transform}/transform_expression.hpp | 26 +- .../transform_expression_grammar_x3.hpp | 51 + .../transform_expression_grammar_x3_def.hpp | 223 ++++ .../{ => transform}/transform_processor.hpp | 4 +- .../mapnik/transform_expression_grammar.hpp | 66 -- .../transform_expression_grammar_impl.hpp | 128 --- include/mapnik/transform_path_adapter.hpp | 2 +- include/mapnik/unicode.hpp | 4 +- .../mapnik/util/const_rendering_buffer.hpp | 4 +- include/mapnik/util/container_adapter.hpp | 2 +- include/mapnik/util/conversions.hpp | 4 +- include/mapnik/util/dasharray_parser.hpp | 2 +- include/mapnik/util/feature_to_geojson.hpp | 21 +- include/mapnik/util/featureset_buffer.hpp | 2 +- include/mapnik/util/file_io.hpp | 5 +- include/mapnik/util/fs.hpp | 2 +- include/mapnik/util/geometry_to_ds_type.hpp | 4 +- include/mapnik/util/geometry_to_geojson.hpp | 2 +- include/mapnik/util/geometry_to_svg.hpp | 2 +- include/mapnik/util/geometry_to_wkb.hpp | 6 +- include/mapnik/util/geometry_to_wkt.hpp | 26 +- include/mapnik/util/hsl.hpp | 2 +- include/mapnik/util/is_clockwise.hpp | 2 +- include/mapnik/util/math.hpp | 2 +- include/mapnik/util/noncopyable.hpp | 2 +- include/mapnik/util/path_iterator.hpp | 2 +- include/mapnik/util/rounding_cast.hpp | 2 +- include/mapnik/util/singleton.hpp | 2 +- include/mapnik/util/spatial_index.hpp | 4 +- .../util/spirit_transform_attribute.hpp | 2 +- include/mapnik/util/timer.hpp | 2 +- include/mapnik/util/trim.hpp | 2 +- include/mapnik/util/utf_conv_win.hpp | 2 +- include/mapnik/util/variant.hpp | 12 +- include/mapnik/util/variant_io.hpp | 4 +- include/mapnik/value.hpp | 40 +- .../{value_error.hpp => value/error.hpp} | 10 +- .../mapnik/{value_hash.hpp => value/hash.hpp} | 23 +- .../{value_types.hpp => value/types.hpp} | 101 +- include/mapnik/version.hpp | 6 +- include/mapnik/vertex.hpp | 2 +- include/mapnik/vertex_adapters.hpp | 4 +- include/mapnik/vertex_cache.hpp | 2 +- include/mapnik/vertex_converters.hpp | 23 +- include/mapnik/vertex_processor.hpp | 6 +- include/mapnik/vertex_vector.hpp | 2 +- include/mapnik/view_strategy.hpp | 2 +- include/mapnik/view_transform.hpp | 4 +- include/mapnik/warning_ignore.hpp | 2 +- include/mapnik/warning_ignore_agg.hpp | 2 +- include/mapnik/warp.hpp | 4 +- include/mapnik/webp_io.hpp | 2 +- include/mapnik/well_known_srs.hpp | 23 +- include/mapnik/wkb.hpp | 2 +- include/mapnik/wkt/wkt_factory.hpp | 16 +- include/mapnik/wkt/wkt_generator_grammar.hpp | 55 +- .../mapnik/wkt/wkt_generator_grammar_impl.hpp | 95 +- include/mapnik/wkt/wkt_grammar.hpp | 108 -- include/mapnik/wkt/wkt_grammar_impl.hpp | 161 --- include/mapnik/wkt/wkt_grammar_x3.hpp | 49 + include/mapnik/wkt/wkt_grammar_x3_def.hpp | 138 +++ include/mapnik/xml_attribute_cast.hpp | 4 +- include/mapnik/xml_loader.hpp | 2 +- include/mapnik/xml_node.hpp | 20 +- include/mapnik/xml_tree.hpp | 8 +- mason_latest.sh | 67 -- plugins/input/csv/csv_datasource.cpp | 6 +- plugins/input/csv/csv_datasource.hpp | 6 +- plugins/input/csv/csv_featureset.cpp | 9 +- plugins/input/csv/csv_featureset.hpp | 2 +- plugins/input/csv/csv_getline.hpp | 2 +- plugins/input/csv/csv_index_featureset.cpp | 9 +- plugins/input/csv/csv_index_featureset.hpp | 2 +- plugins/input/csv/csv_inline_featureset.cpp | 4 +- plugins/input/csv/csv_inline_featureset.hpp | 2 +- plugins/input/csv/csv_utils.cpp | 27 +- plugins/input/csv/csv_utils.hpp | 6 +- plugins/input/gdal/gdal_datasource.cpp | 4 +- plugins/input/gdal/gdal_datasource.hpp | 4 +- plugins/input/gdal/gdal_featureset.cpp | 2 +- plugins/input/gdal/gdal_featureset.hpp | 2 +- plugins/input/geojson/geojson_datasource.cpp | 219 ++-- plugins/input/geojson/geojson_datasource.hpp | 4 +- plugins/input/geojson/geojson_featureset.cpp | 2 +- plugins/input/geojson/geojson_featureset.hpp | 2 +- .../geojson/geojson_index_featureset.cpp | 21 +- .../geojson/geojson_index_featureset.hpp | 2 +- .../geojson_memory_index_featureset.cpp | 23 +- .../geojson_memory_index_featureset.hpp | 2 +- plugins/input/ogr/ogr_converter.cpp | 2 +- plugins/input/ogr/ogr_converter.hpp | 2 +- plugins/input/ogr/ogr_datasource.cpp | 2 +- plugins/input/ogr/ogr_datasource.hpp | 4 +- plugins/input/ogr/ogr_featureset.cpp | 10 +- plugins/input/ogr/ogr_featureset.hpp | 2 +- plugins/input/ogr/ogr_index.hpp | 10 +- plugins/input/ogr/ogr_index_featureset.cpp | 8 +- plugins/input/ogr/ogr_index_featureset.hpp | 2 +- plugins/input/ogr/ogr_layer_ptr.hpp | 2 +- .../input/pgraster/pgraster_datasource.cpp | 1012 ++++++++--------- .../input/pgraster/pgraster_datasource.hpp | 26 +- .../input/pgraster/pgraster_featureset.cpp | 4 +- .../input/pgraster/pgraster_featureset.hpp | 4 +- .../input/pgraster/pgraster_wkb_reader.cpp | 4 +- .../input/pgraster/pgraster_wkb_reader.hpp | 4 +- plugins/input/postgis/asyncresultset.hpp | 2 +- plugins/input/postgis/build.py | 1 - plugins/input/postgis/connection.hpp | 2 +- plugins/input/postgis/connection_manager.hpp | 2 +- plugins/input/postgis/cursorresultset.hpp | 2 +- plugins/input/postgis/numeric2string.hpp | 2 +- plugins/input/postgis/postgis_datasource.cpp | 368 +++--- plugins/input/postgis/postgis_datasource.hpp | 24 +- plugins/input/postgis/postgis_featureset.cpp | 4 +- plugins/input/postgis/postgis_featureset.hpp | 4 +- plugins/input/postgis/resultset.hpp | 2 +- plugins/input/raster/raster_datasource.cpp | 2 +- plugins/input/raster/raster_datasource.hpp | 4 +- plugins/input/raster/raster_featureset.cpp | 2 +- plugins/input/raster/raster_featureset.hpp | 2 +- plugins/input/raster/raster_info.cpp | 4 +- plugins/input/raster/raster_info.hpp | 2 +- plugins/input/shape/dbf_test.cpp | 2 +- plugins/input/shape/dbfile.cpp | 20 +- plugins/input/shape/dbfile.hpp | 4 +- plugins/input/shape/shape_datasource.cpp | 4 +- plugins/input/shape/shape_datasource.hpp | 6 +- plugins/input/shape/shape_featureset.cpp | 2 +- plugins/input/shape/shape_featureset.hpp | 4 +- .../input/shape/shape_index_featureset.cpp | 2 +- .../input/shape/shape_index_featureset.hpp | 4 +- plugins/input/shape/shape_io.cpp | 4 +- plugins/input/shape/shape_io.hpp | 4 +- plugins/input/shape/shape_utils.cpp | 2 +- plugins/input/shape/shape_utils.hpp | 2 +- plugins/input/shape/shapefile.hpp | 4 +- plugins/input/sqlite/sqlite_connection.hpp | 2 +- plugins/input/sqlite/sqlite_datasource.cpp | 4 +- plugins/input/sqlite/sqlite_datasource.hpp | 6 +- plugins/input/sqlite/sqlite_featureset.cpp | 10 +- plugins/input/sqlite/sqlite_featureset.hpp | 2 +- plugins/input/sqlite/sqlite_prepared.hpp | 4 +- plugins/input/sqlite/sqlite_resultset.hpp | 2 +- plugins/input/sqlite/sqlite_utils.hpp | 6 +- .../input/topojson/topojson_datasource.cpp | 32 +- .../input/topojson/topojson_datasource.hpp | 4 +- .../input/topojson/topojson_featureset.cpp | 2 +- .../input/topojson/topojson_featureset.hpp | 2 +- scripts/travis-common.sh | 21 +- src/agg/agg_renderer.cpp | 173 +-- src/agg/process_building_symbolizer.cpp | 6 +- src/agg/process_debug_symbolizer.cpp | 8 +- src/agg/process_dot_symbolizer.cpp | 5 +- src/agg/process_group_symbolizer.cpp | 15 +- src/agg/process_line_pattern_symbolizer.cpp | 100 +- src/agg/process_line_symbolizer.cpp | 9 +- src/agg/process_markers_symbolizer.cpp | 11 +- src/agg/process_point_symbolizer.cpp | 2 +- .../process_polygon_pattern_symbolizer.cpp | 152 +-- src/agg/process_polygon_symbolizer.cpp | 7 +- src/agg/process_raster_symbolizer.cpp | 6 +- src/agg/process_shield_symbolizer.cpp | 4 +- src/agg/process_text_symbolizer.cpp | 4 +- src/build.py | 22 +- src/cairo/cairo_context.cpp | 2 +- src/cairo/cairo_render_vector.cpp | 8 +- src/cairo/cairo_renderer.cpp | 21 +- src/cairo/process_building_symbolizer.cpp | 3 +- src/cairo/process_debug_symbolizer.cpp | 2 +- src/cairo/process_group_symbolizer.cpp | 4 +- src/cairo/process_line_pattern_symbolizer.cpp | 4 +- src/cairo/process_line_symbolizer.cpp | 4 +- src/cairo/process_markers_symbolizer.cpp | 6 +- src/cairo/process_point_symbolizer.cpp | 2 +- .../process_polygon_pattern_symbolizer.cpp | 2 +- src/cairo/process_polygon_symbolizer.cpp | 2 +- src/cairo/process_raster_symbolizer.cpp | 4 +- src/cairo/process_text_symbolizer.cpp | 2 +- src/cairo_io.cpp | 2 +- src/color.cpp | 2 +- src/color_factory.cpp | 13 +- src/config_error.cpp | 2 +- src/conversions.cpp | 264 ----- src/conversions_numeric.cpp | 146 +++ src/conversions_string.cpp | 162 +++ src/css_color_grammar_x3.cpp | 33 + src/dasharray_parser.cpp | 27 +- src/datasource_cache.cpp | 2 +- src/datasource_cache_static.cpp | 2 +- src/debug.cpp | 2 +- src/expression.cpp | 25 +- ..._grammar.cpp => expression_grammar_x3.cpp} | 11 +- src/expression_node.cpp | 4 +- src/expression_string.cpp | 4 +- src/feature_kv_iterator.cpp | 2 +- src/feature_style_processor.cpp | 2 +- src/feature_type_style.cpp | 6 +- src/font_engine_freetype.cpp | 3 +- src/font_set.cpp | 2 +- src/fs.cpp | 2 +- src/function_call.cpp | 2 +- ...r_types.cpp => generate_image_filters.cpp} | 18 +- src/{ => geometry}/box2d.cpp | 4 +- .../envelope.cpp} | 7 +- .../reprojection.cpp} | 14 +- src/gradient.cpp | 4 +- src/grid/grid.cpp | 2 +- src/grid/grid_renderer.cpp | 2 +- src/grid/process_building_symbolizer.cpp | 3 +- src/grid/process_group_symbolizer.cpp | 3 +- src/grid/process_line_pattern_symbolizer.cpp | 2 +- src/grid/process_line_symbolizer.cpp | 4 +- src/grid/process_markers_symbolizer.cpp | 7 +- src/grid/process_point_symbolizer.cpp | 2 +- .../process_polygon_pattern_symbolizer.cpp | 2 +- src/grid/process_polygon_symbolizer.cpp | 2 +- src/grid/process_raster_symbolizer.cpp | 2 +- src/grid/process_shield_symbolizer.cpp | 2 +- src/grid/process_text_symbolizer.cpp | 2 +- src/group/group_layout_manager.cpp | 50 +- src/group/group_rule.cpp | 2 +- src/group/group_symbolizer_helper.cpp | 5 +- src/image.cpp | 3 +- src/image_any.cpp | 2 +- src/image_compositing.cpp | 2 +- src/image_copy.cpp | 2 +- src/image_filter_grammar_x3.cpp | 33 + src/image_options.cpp | 115 +- src/image_reader.cpp | 2 +- src/image_scaling.cpp | 2 +- src/image_util.cpp | 4 +- src/image_util_jpeg.cpp | 4 +- src/image_util_png.cpp | 22 +- src/image_util_tiff.cpp | 2 +- src/image_util_webp.cpp | 4 +- src/image_view.cpp | 4 +- src/image_view_any.cpp | 2 +- src/jpeg_reader.cpp | 2 +- src/json/extract_bounding_boxes_x3.cpp | 203 ++++ ...ry_parser.cpp => feature_from_geojson.cpp} | 26 +- src/json/feature_grammar_x3.cpp | 34 + src/json/generic_json.cpp | 63 - src/json/generic_json_grammar_x3.cpp | 37 + .../json/geojson_grammar_x3.cpp | 50 +- src/json/geometry_from_geojson.cpp | 50 + .../json/mapnik_feature_to_geojson.cpp | 13 +- src/json/mapnik_geometry_to_geojson.cpp | 2 +- src/json/mapnik_json_generator_grammar.cpp | 7 +- src/json/mapnik_topojson_grammar.cpp | 28 - src/json/parse_feature.cpp | 59 + src/json/positions_grammar_x3.cpp | 44 + ...re_grammar.cpp => topojson_grammar_x3.cpp} | 14 +- src/json/unicode_string_grammar_x3.cpp | 46 + src/layer.cpp | 87 +- src/libxml2_loader.cpp | 2 +- src/load_map.cpp | 75 +- src/map.cpp | 48 +- src/mapped_memory_cache.cpp | 2 +- src/marker_cache.cpp | 2 +- src/marker_helpers.cpp | 2 +- src/math.cpp | 2 +- src/memory_datasource.cpp | 16 +- src/palette.cpp | 2 +- src/params.cpp | 4 +- src/parse_image_filters.cpp | 53 + src/parse_path.cpp | 12 +- src/parse_transform.cpp | 33 +- src/path_expression_grammar_x3.cpp | 32 + src/plugin.cpp | 10 +- src/png_reader.cpp | 2 +- src/proj_transform.cpp | 4 +- src/projection.cpp | 2 +- src/rapidxml_loader.cpp | 2 +- src/raster_colorizer.cpp | 28 +- src/renderer_common.cpp | 2 +- .../render_group_symbolizer.cpp | 8 +- .../render_markers_symbolizer.cpp | 8 +- src/renderer_common/render_pattern.cpp | 4 +- .../render_thunk_extractor.cpp | 10 +- src/request.cpp | 2 +- src/rule.cpp | 2 +- src/save_map.cpp | 24 +- src/scale_denominator.cpp | 2 +- src/svg/output/process_line_symbolizer.cpp | 2 +- src/svg/output/process_polygon_symbolizer.cpp | 2 +- src/svg/output/process_symbolizers.cpp | 6 +- src/svg/output/svg_generator.cpp | 2 +- src/svg/output/svg_output_attributes.cpp | 2 +- src/svg/output/svg_output_grammars.cpp | 2 +- src/svg/output/svg_renderer.cpp | 2 +- src/svg/svg_parser.cpp | 149 +-- .../svg_path_grammar_x3.cpp} | 20 +- src/svg/svg_path_parser.cpp | 30 +- src/svg/svg_points_parser.cpp | 29 +- src/svg/svg_transform_parser.cpp | 33 +- src/symbolizer.cpp | 4 +- src/symbolizer_enumerations.cpp | 2 +- src/symbolizer_keys.cpp | 3 +- src/text/face.cpp | 29 +- src/text/font_feature_settings.cpp | 26 +- src/text/font_library.cpp | 2 +- src/text/formatting/base.cpp | 2 +- src/text/formatting/format.cpp | 2 +- src/text/formatting/layout.cpp | 2 +- src/text/formatting/list.cpp | 14 +- src/text/formatting/registry.cpp | 2 +- src/text/formatting/text.cpp | 2 +- src/text/glyph_positions.cpp | 2 +- src/text/itemizer.cpp | 2 +- src/text/placement_finder.cpp | 3 +- src/text/placements/base.cpp | 2 +- src/text/placements/dummy.cpp | 2 +- src/text/placements/list.cpp | 2 +- src/text/placements/registry.cpp | 2 +- src/text/placements/simple.cpp | 49 +- src/text/properties_util.cpp | 2 +- src/text/renderer.cpp | 107 +- src/text/scrptrun.cpp | 6 +- src/text/symbolizer_helpers.cpp | 52 +- src/text/text_layout.cpp | 14 +- src/text/text_line.cpp | 4 +- src/text/text_properties.cpp | 4 +- src/tiff_reader.cpp | 2 +- src/transform_expression.cpp | 4 +- src/transform_expression_grammar.cpp | 26 - ...pp => transform_expression_grammar_x3.cpp} | 13 +- src/twkb.cpp | 4 +- src/unicode.cpp | 4 +- src/util/utf_conv_win.cpp | 2 +- src/value.cpp | 2 +- src/vertex_adapters.cpp | 2 +- src/vertex_cache.cpp | 2 +- src/warp.cpp | 4 +- src/webp_reader.cpp | 3 +- src/well_known_srs.cpp | 2 +- src/wkb.cpp | 8 +- src/wkt/geometry_to_wkt.cpp | 47 + src/wkt/mapnik_wkt_generator_grammar.cpp | 7 +- src/wkt/wkt_factory.cpp | 47 + .../wkt_grammar_x3.cpp} | 16 +- src/xml_tree.cpp | 27 +- test/build.py | 1 + test/data | 2 +- test/data-visual | 2 +- test/standalone/font_registration_test.cpp | 2 +- test/unit/color/css_color.cpp | 160 ++- test/unit/core/box2d_test.cpp | 3 +- test/unit/core/comparison_test.cpp | 3 +- test/unit/core/conversions_test.cpp | 18 +- test/unit/core/expressions_test.cpp | 17 +- test/unit/core/params_test.cpp | 3 +- test/unit/core/transform_expressions_test.cpp | 60 + test/unit/core/value_test.cpp | 3 +- test/unit/datasource/csv.cpp | 4 +- test/unit/datasource/ds_test_util.hpp | 6 +- test/unit/datasource/geojson.cpp | 50 +- test/unit/datasource/postgis.cpp | 70 +- test/unit/datasource/topojson.cpp | 26 +- test/unit/font/fontset_runtime_test.cpp | 5 +- test/unit/geometry/centroid.cpp | 4 +- test/unit/geometry/geometry_envelope_test.cpp | 4 +- test/unit/geometry/geometry_equal.hpp | 2 +- test/unit/geometry/geometry_hit_test.cpp | 2 +- test/unit/geometry/geometry_is_simple.cpp | 5 +- test/unit/geometry/geometry_is_valid.cpp | 4 +- test/unit/geometry/geometry_reprojection.cpp | 26 +- test/unit/geometry/geometry_strategy_test.cpp | 6 +- test/unit/geometry/geometry_test_helper.cpp | 4 +- test/unit/geometry/has_empty.cpp | 6 +- test/unit/geometry/is_empty.cpp | 6 +- test/unit/geometry/remove_empty.cpp | 2 +- test/unit/projection/proj_transform.cpp | 3 +- test/unit/serialization/parse_hex.hpp | 12 +- test/unit/serialization/wkb_formats_test.cpp | 10 +- test/unit/serialization/wkb_test.cpp | 27 +- test/unit/text/shaping.cpp | 104 +- test/unit/vertex_adapter/extend_converter.cpp | 128 +++ test/unit/vertex_adapter/fake_path.hpp | 93 ++ test/unit/vertex_adapter/line_offset_test.cpp | 48 +- test/unit/vertex_adapter/offset_converter.cpp | 53 +- test/unit/vertex_adapter/vertex_adapter.cpp | 2 +- ..._sizes_grammar.hpp => parse_map_sizes.cpp} | 48 +- .../visual/parse_map_sizes.hpp | 19 +- test/visual/runner.cpp | 16 +- test/visual/runner.hpp | 7 +- utils/mapnik-index/build.py | 4 +- utils/mapnik-index/mapnik-index.cpp | 15 +- utils/mapnik-index/process_csv_file.cpp | 2 +- utils/mapnik-index/process_csv_file.hpp | 2 +- utils/mapnik-index/process_geojson_file.cpp | 146 --- .../mapnik-index/process_geojson_file_x3.cpp | 330 ++++++ ...n_file.hpp => process_geojson_file_x3.hpp} | 10 +- utils/ogrindex/ogrindex.cpp | 2 +- utils/pgsql2sqlite/pgsql2sqlite.hpp | 4 +- utils/shapeindex/shapeindex.cpp | 6 +- 743 files changed, 11298 insertions(+), 8765 deletions(-) delete mode 100644 demo/python/README.txt delete mode 100755 demo/python/rundemo.py delete mode 100644 include/mapnik/css_color_grammar.hpp rename src/css_color_grammar.cpp => include/mapnik/css_color_grammar_x3.hpp (61%) rename include/mapnik/{css_color_grammar_impl.hpp => css_color_grammar_x3_def.hpp} (54%) delete mode 100644 include/mapnik/csv/csv_grammar.hpp create mode 100644 include/mapnik/csv/csv_grammar_x3.hpp create mode 100644 include/mapnik/csv/csv_grammar_x3_def.hpp create mode 100644 include/mapnik/cxx11_support.hpp delete mode 100644 include/mapnik/expression_grammar.hpp delete mode 100644 include/mapnik/expression_grammar_impl.hpp create mode 100644 include/mapnik/expression_grammar_x3.hpp create mode 100644 include/mapnik/expression_grammar_x3_config.hpp create mode 100644 include/mapnik/expression_grammar_x3_def.hpp create mode 100644 include/mapnik/extend_converter.hpp delete mode 100644 include/mapnik/filter_factory.hpp rename include/mapnik/{geometry_adapters.hpp => geometry/boost_adapters.hpp} (66%) create mode 100644 include/mapnik/geometry/boost_spirit_karma_adapter.hpp rename include/mapnik/{ => geometry}/box2d.hpp (98%) rename include/mapnik/{ => geometry}/box2d_impl.hpp (89%) rename include/mapnik/{geometry_centroid.hpp => geometry/centroid.hpp} (94%) rename include/mapnik/{geometry_correct.hpp => geometry/correct.hpp} (96%) rename include/mapnik/{geometry_envelope.hpp => geometry/envelope.hpp} (94%) rename include/mapnik/{geometry_envelope_impl.hpp => geometry/envelope_impl.hpp} (94%) rename include/mapnik/{geometry_fusion_adapted.hpp => geometry/fusion_adapted.hpp} (98%) rename include/mapnik/{ => geometry}/geometry_type.hpp (94%) rename include/mapnik/{ => geometry}/geometry_types.hpp (97%) create mode 100644 include/mapnik/geometry/is_empty.hpp rename include/mapnik/{geometry_is_simple.hpp => geometry/is_simple.hpp} (88%) rename include/mapnik/{geometry_is_valid.hpp => geometry/is_valid.hpp} (82%) rename include/mapnik/{geometry_remove_empty.hpp => geometry/remove_empty.hpp} (96%) rename include/mapnik/{geometry_reprojection.hpp => geometry/reprojection.hpp} (98%) rename include/mapnik/{geometry_reprojection_impl.hpp => geometry/reprojection_impl.hpp} (95%) rename include/mapnik/{geometry_strategy.hpp => geometry/strategy.hpp} (96%) rename include/mapnik/{geometry_to_path.hpp => geometry/to_path.hpp} (97%) rename include/mapnik/{geometry_transform.hpp => geometry/transform.hpp} (97%) delete mode 100644 include/mapnik/geometry_is_empty.hpp delete mode 100644 include/mapnik/image_filter_grammar.hpp delete mode 100644 include/mapnik/image_filter_grammar_impl.hpp create mode 100644 include/mapnik/image_filter_grammar_x3.hpp create mode 100644 include/mapnik/image_filter_grammar_x3_def.hpp create mode 100644 include/mapnik/json/create_feature.hpp rename include/mapnik/json/{geometry_util.hpp => create_geometry.hpp} (61%) delete mode 100644 include/mapnik/json/error_handler.hpp delete mode 100644 include/mapnik/json/extract_bounding_box_grammar.hpp delete mode 100644 include/mapnik/json/extract_bounding_box_grammar_impl.hpp create mode 100644 include/mapnik/json/extract_bounding_boxes_x3.hpp create mode 100644 include/mapnik/json/extract_bounding_boxes_x3_config.hpp delete mode 100644 include/mapnik/json/feature_collection_grammar.hpp delete mode 100644 include/mapnik/json/feature_collection_grammar_impl.hpp delete mode 100644 include/mapnik/json/feature_grammar.hpp delete mode 100644 include/mapnik/json/feature_grammar_impl.hpp create mode 100644 include/mapnik/json/feature_grammar_x3.hpp create mode 100644 include/mapnik/json/feature_grammar_x3_def.hpp delete mode 100644 include/mapnik/json/generic_json.hpp rename include/mapnik/{path_expression_grammar.hpp => json/generic_json_grammar_x3.hpp} (56%) create mode 100644 include/mapnik/json/generic_json_grammar_x3_def.hpp create mode 100644 include/mapnik/json/geojson_grammar_x3.hpp create mode 100644 include/mapnik/json/geojson_grammar_x3_def.hpp delete mode 100644 include/mapnik/json/geometry_grammar.hpp delete mode 100644 include/mapnik/json/geometry_grammar_impl.hpp rename include/mapnik/{svg/svg_points_grammar.hpp => json/geometry_grammar_x3.hpp} (62%) create mode 100644 include/mapnik/json/geometry_grammar_x3_def.hpp create mode 100644 include/mapnik/json/json_grammar_config.hpp create mode 100644 include/mapnik/json/json_value.hpp rename src/json/mapnik_json_feature_collection_grammar.cpp => include/mapnik/json/parse_feature.hpp (66%) delete mode 100644 include/mapnik/json/positions_grammar.hpp delete mode 100644 include/mapnik/json/positions_grammar_impl.hpp create mode 100644 include/mapnik/json/positions_grammar_x3.hpp create mode 100644 include/mapnik/json/positions_grammar_x3_def.hpp rename include/mapnik/json/{positions.hpp => positions_x3.hpp} (82%) delete mode 100644 include/mapnik/json/topojson_grammar.hpp delete mode 100644 include/mapnik/json/topojson_grammar_impl.hpp create mode 100644 include/mapnik/json/topojson_grammar_x3.hpp create mode 100644 include/mapnik/json/topojson_grammar_x3_def.hpp create mode 100644 include/mapnik/json/unicode_string_grammar_x3.hpp create mode 100644 include/mapnik/json/unicode_string_grammar_x3_def.hpp create mode 100644 include/mapnik/path_expression_grammar_x3.hpp create mode 100644 include/mapnik/path_expression_grammar_x3_def.hpp rename include/mapnik/{path_expression_grammar_impl.hpp => svg/svg_grammar_config_x3.hpp} (52%) delete mode 100644 include/mapnik/svg/svg_path_grammar.hpp delete mode 100644 include/mapnik/svg/svg_path_grammar_impl.hpp create mode 100644 include/mapnik/svg/svg_path_grammar_x3.hpp create mode 100644 include/mapnik/svg/svg_path_grammar_x3_def.hpp delete mode 100644 include/mapnik/svg/svg_points_grammar_impl.hpp delete mode 100644 include/mapnik/svg/svg_transform_grammar.hpp delete mode 100644 include/mapnik/svg/svg_transform_grammar_impl.hpp create mode 100644 include/mapnik/svg/svg_transform_grammar_x3.hpp create mode 100644 include/mapnik/svg/svg_transform_grammar_x3_def.hpp rename include/mapnik/{ => transform}/parse_transform.hpp (97%) rename include/mapnik/{ => transform}/transform_expression.hpp (92%) create mode 100644 include/mapnik/transform/transform_expression_grammar_x3.hpp create mode 100644 include/mapnik/transform/transform_expression_grammar_x3_def.hpp rename include/mapnik/{ => transform}/transform_processor.hpp (98%) delete mode 100644 include/mapnik/transform_expression_grammar.hpp delete mode 100644 include/mapnik/transform_expression_grammar_impl.hpp rename include/mapnik/{value_error.hpp => value/error.hpp} (91%) rename include/mapnik/{value_hash.hpp => value/hash.hpp} (75%) rename include/mapnik/{value_types.hpp => value/types.hpp} (61%) delete mode 100644 include/mapnik/wkt/wkt_grammar.hpp delete mode 100644 include/mapnik/wkt/wkt_grammar_impl.hpp create mode 100644 include/mapnik/wkt/wkt_grammar_x3.hpp create mode 100644 include/mapnik/wkt/wkt_grammar_x3_def.hpp delete mode 100755 mason_latest.sh delete mode 100644 src/conversions.cpp create mode 100644 src/conversions_numeric.cpp create mode 100644 src/conversions_string.cpp create mode 100644 src/css_color_grammar_x3.cpp rename src/{wkt/mapnik_wkt_grammar.cpp => expression_grammar_x3.cpp} (79%) rename src/{image_filter_types.cpp => generate_image_filters.cpp} (66%) rename src/{ => geometry}/box2d.cpp (93%) rename src/{geometry_envelope.cpp => geometry/envelope.cpp} (91%) rename src/{geometry_reprojection.cpp => geometry/reprojection.cpp} (89%) create mode 100644 src/image_filter_grammar_x3.cpp create mode 100644 src/json/extract_bounding_boxes_x3.cpp rename src/json/{mapnik_json_geometry_parser.cpp => feature_from_geojson.cpp} (69%) create mode 100644 src/json/feature_grammar_x3.cpp delete mode 100644 src/json/generic_json.cpp create mode 100644 src/json/generic_json_grammar_x3.cpp rename include/mapnik/csv/csv_grammar_impl.hpp => src/json/geojson_grammar_x3.cpp (50%) create mode 100644 src/json/geometry_from_geojson.cpp rename include/mapnik/json/feature_generator.hpp => src/json/mapnik_feature_to_geojson.cpp (81%) delete mode 100644 src/json/mapnik_topojson_grammar.cpp create mode 100644 src/json/parse_feature.cpp create mode 100644 src/json/positions_grammar_x3.cpp rename src/json/{mapnik_json_feature_grammar.cpp => topojson_grammar_x3.cpp} (76%) create mode 100644 src/json/unicode_string_grammar_x3.cpp create mode 100644 src/parse_image_filters.cpp create mode 100644 src/path_expression_grammar_x3.cpp rename src/{json/mapnik_json_positions_grammar.cpp => svg/svg_path_grammar_x3.cpp} (58%) delete mode 100644 src/transform_expression_grammar.cpp rename src/{json/mapnik_json_geometry_grammar.cpp => transform_expression_grammar_x3.cpp} (76%) create mode 100644 src/wkt/geometry_to_wkt.cpp create mode 100644 src/wkt/wkt_factory.cpp rename src/{expression_grammar.cpp => wkt/wkt_grammar_x3.cpp} (72%) create mode 100644 test/unit/core/transform_expressions_test.cpp create mode 100644 test/unit/vertex_adapter/extend_converter.cpp create mode 100644 test/unit/vertex_adapter/fake_path.hpp rename test/visual/{map_sizes_grammar.hpp => parse_map_sizes.cpp} (55%) rename src/image_filter_grammar.cpp => test/visual/parse_map_sizes.hpp (80%) delete mode 100644 utils/mapnik-index/process_geojson_file.cpp create mode 100644 utils/mapnik-index/process_geojson_file_x3.cpp rename utils/mapnik-index/{process_geojson_file.hpp => process_geojson_file_x3.hpp} (81%) diff --git a/.gitmodules b/.gitmodules index 7846a4f6c..345b8a2aa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,10 +5,13 @@ [submodule "test/data-visual"] path = test/data-visual url = https://github.com/mapnik/test-data-visual.git - branch = master + branch = harfbuzz-shaper [submodule "deps/mapbox/variant"] path = deps/mapbox/variant url = https://github.com/mapbox/variant.git + branch = master [submodule "deps/mapbox/geometry"] path = deps/mapbox/geometry url = https://github.com/mapbox/geometry.hpp.git + branch = master + diff --git a/.travis.yml b/.travis.yml index bc4d5462f..174406b30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,8 +10,6 @@ env: - CCACHE_COMPRESS=1 - HEAVY_JOBS="2" - PREFIX=/tmp/mapnik - - secure: "N3a5nzzsgpuu45k8qWdYsHNxrSnqeAGLTOYpfYoAH7B94vuf7pa7XV1tQjXbxrnx2D6ryTdtUtyRKwy7zXbwXxGt4DpczWEo8f6DUd6+obAp3kdnXABg2Sj4oA7KMs0F0CmoADy0jdUZD5YyOJHu64LCIIgzEQ9q49PFMNbU3IE=" - - secure: "iQYPNpMtejcgYeUkWZGIWz1msIco5qydJrhZTSCQOYahAQerdT7q5WZEpEo3G6IWOGgO1eo7GFuY8DvqQjw1+jC9b9mhkRNdo3LhGTKS9Gsbl5Q27k0rjlaFZmmQHrfPlQJwhfAIp+KLugHtQw5bCoLh+95E3j0F0DayF1tuJ3s=" - secure: "F6ivqDNMBQQnrDGA9+7IX+GDswuIqQQd7YPJdQqa2Ked9jddAQDeJClb05ig3JlwfOlYLGZOd43ZX0pKuMtI2Gbkwz211agGP9S3YunwlRg8iWtJlO5kYFUdKCmJNhjg4icfkGELCgwXn+zuEWFSLpkPcjqAFKFlQrIJeAJJgKM=" addons: postgresql: "9.4" @@ -25,24 +23,32 @@ matrix: - os: linux sudo: false compiler: ": clang" - env: JOBS=8 MASON_PUBLISH=true CXX="ccache clang++-3.8 -Qunused-arguments" CC="clang-3.8" TRIGGER=true + env: JOBS=4 CXX="ccache g++-6" CC="gcc-6" addons: apt: sources: [ 'ubuntu-toolchain-r-test'] - packages: [ 'libstdc++-5-dev', 'xutils-dev'] + packages: [ 'libstdc++-6-dev', 'g++-6', 'xutils-dev'] + - os: linux + sudo: false + compiler: ": clang" + env: JOBS=8 CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9" TRIGGER=true + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test'] + packages: [ 'libstdc++-4.9-dev', 'xutils-dev'] - os: linux sudo: false compiler: ": clang-coverage" - env: JOBS=8 COVERAGE=true CXX="ccache clang++-3.8 -Qunused-arguments" CC="clang-3.8" + env: JOBS=8 COVERAGE=true CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9" addons: apt: sources: [ 'ubuntu-toolchain-r-test'] - packages: ['libstdc++-5-dev', 'xutils-dev' ] + packages: ['libstdc++-4.9-dev', 'xutils-dev' ] - os: osx compiler: ": clang-osx" # https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions osx_image: xcode7.3 # upgrades clang from 6 -> 7 - env: JOBS=4 MASON_PUBLISH=true CXX="ccache clang++ -Qunused-arguments" + env: JOBS=4 CXX="ccache clang++ -Qunused-arguments" before_install: # workaround travis rvm bug @@ -52,8 +58,7 @@ before_install: rvm get head || true fi - source scripts/travis-common.sh - - export PYTHONUSERBASE=$(pwd)/mason_packages/.link - - export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PYTHONUSERBASE}/bin:${PATH} + - export PATH=${PREFIX}/bin:$(pwd)/mason_packages/.link/bin:${PATH} - export COVERAGE=${COVERAGE:-false} - export MASON_PUBLISH=${MASON_PUBLISH:-false} - export BENCH=${BENCH:-false} @@ -62,8 +67,6 @@ before_install: - git_submodule_update --init --depth=10 install: - - on 'linux' export PYTHONPATH=${PYTHONUSERBASE}/lib/python2.7/site-packages - - on 'osx' export PYTHONPATH=${PYTHONUSERBASE}/lib/python/site-packages - on 'osx' export DATA_PATH=$(brew --prefix)/var/postgres - on 'osx' rm -rf ${DATA_PATH} - on 'osx' initdb ${DATA_PATH} -E utf8 @@ -72,16 +75,19 @@ install: - on 'osx' createuser -s postgres - psql -c 'create database template_postgis;' -U postgres - psql -c 'create extension postgis;' -d template_postgis -U postgres - - enabled ${COVERAGE} pip install --user cpp-coveralls + - enabled ${COVERAGE} curl -S -f https://codecov.io/bash -o codecov + - enabled ${COVERAGE} chmod +x codecov before_script: - source bootstrap.sh - | if [[ $(uname -s) == 'Linux' ]]; then - mason install clang 3.8.0 - export PATH=$(mason prefix clang 3.8.0)/bin:${PATH} - which clang++ - export LLVM_COV="$(mason prefix clang 3.8.0)/bin/llvm-cov" + mason install clang++ 3.9.1 + export PATH=$(mason prefix clang++ 3.9.1)/bin:${PATH} + mason install llvm-cov 3.9.1 + export PATH=$(mason prefix llvm-cov 3.9.1)/bin:${PATH} + which llvm-cov + export LLVM_COV="$(mason prefix llvm-cov 3.9.1)/bin/llvm-cov" fi - ccache --version - ccache -p || true @@ -98,14 +104,12 @@ script: # (and might work) for the next build - DURATION=2400 - scripts/travis-command-wrapper.py -s "date" -i 120 --deadline=$(( $(date +%s) + ${DURATION} )) make - - make test + - RESULT=0 + - make test || RESULT=$? + # we allow visual failures with g++ for now: https://github.com/mapnik/mapnik/issues/3567 + - if [[ ${RESULT} != 0 ]] && [[ ${CXX} =~ 'clang++' ]]; then false; fi; - enabled ${COVERAGE} coverage - enabled ${BENCH} make bench after_success: - enabled ${TRIGGER} trigger_downstream - - if enabled ${MASON_PUBLISH}; then - source ./.mason/mason.sh && - ./mason_latest.sh build && - ./mason_latest.sh publish; - fi diff --git a/Makefile b/Makefile index 752791b1e..090be8d5d 100755 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ - OS := $(shell uname -s) PYTHON = python @@ -36,15 +35,14 @@ 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 \ plugins/input/geojson/geojson_datasource.os \ - utils/mapnik-index/process_geojson_file.o \ src/svg/svg_path_parser.os \ src/svg/svg_parser.os \ src/svg/svg_points_parser.os \ diff --git a/README.md b/README.md index b58be712a..300aac3e9 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ _/ _/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/ [![Build Status Linux](https://api.travis-ci.org/mapnik/mapnik.svg?branch=master)](http://travis-ci.org/mapnik/mapnik) [![Build Status Windows](https://ci.appveyor.com/api/projects/status/hc9l7okdjtucfqqn?branch=master&svg=true)](https://ci.appveyor.com/project/Mapbox/mapnik) -[![Coverage Status](https://coveralls.io/repos/mapnik/mapnik/badge.svg?branch=master&service=github)](https://coveralls.io/github/mapnik/mapnik?branch=master) +[![codecov](https://codecov.io/gh/mapnik/mapnik/branch/master/graph/badge.svg)](https://codecov.io/gh/mapnik/mapnik) Mapnik is an open source toolkit for developing mapping applications. At the core is a C++ shared library providing algorithms and patterns for spatial data access and visualization. diff --git a/SConstruct b/SConstruct index 85713c694..d640afe15 100644 --- a/SConstruct +++ b/SConstruct @@ -41,8 +41,8 @@ ICU_LIBS_DEFAULT='/usr/' DEFAULT_CC = "cc" DEFAULT_CXX = "c++" -DEFAULT_CXX11_CXXFLAGS = " -std=c++11" -DEFAULT_CXX11_LINKFLAGS = "" +DEFAULT_CXX14_CXXFLAGS = " -std=c++14" +DEFAULT_CXX14_LINKFLAGS = "" if sys.platform == 'darwin': # homebrew default ICU_INCLUDES_DEFAULT='/usr/local/opt/icu4c/include/' @@ -61,7 +61,7 @@ SCONS_CONFIGURE_CACHE = 'config.cache' SCONF_TEMP_DIR = '.sconf_temp' # auto-search directories for boost libs/headers BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',] -BOOST_MIN_VERSION = '1.47' +BOOST_MIN_VERSION = '1.61' #CAIRO_MIN_VERSION = '1.8.0' HARFBUZZ_MIN_VERSION = (0, 9, 34) @@ -1037,12 +1037,12 @@ int main() return True return False -def supports_cxx11(context,silent=False): +def supports_cxx14(context,silent=False): ret = context.TryRun(""" int main() { -#if __cplusplus >= 201103 +#if __cplusplus >= 201402L return 0; #else return -1; @@ -1051,7 +1051,7 @@ int main() """, '.cpp') if not silent: - context.Message('Checking if compiler (%s) supports -std=c++11 flag... ' % context.env.get('CXX','CXX')) + context.Message('Checking if compiler (%s) supports -std=c++14 flag... ' % context.env.get('CXX','CXX')) if silent: context.did_show_result=1 context.Result(ret[0]) @@ -1080,7 +1080,7 @@ conf_tests = { 'prioritize_paths' : prioritize_paths, 'harfbuzz_with_freetype_support': harfbuzz_with_freetype_support, 'boost_regex_has_icu' : boost_regex_has_icu, 'sqlite_has_rtree' : sqlite_has_rtree, - 'supports_cxx11' : supports_cxx11, + 'supports_cxx14' : supports_cxx14, 'CheckBoostScopedEnum' : CheckBoostScopedEnum, } @@ -1129,6 +1129,7 @@ if not preconfigured: else: color_print(4,'SCons USE_CONFIG specified as false, will not inherit variables python config file...') + conf = Configure(env, custom_tests = conf_tests) if env['DEBUG']: @@ -1142,6 +1143,9 @@ if not preconfigured: env['PLATFORM'] = platform.uname()[0] color_print(4,"Configuring on %s in *%s*..." % (env['PLATFORM'],mode)) + cxx_version = call("%s --version" % env["CXX"] ,silent=True) + color_print(5, "CXX %s" % cxx_version) + env['MISSING_DEPS'] = [] env['SKIPPED_DEPS'] = [] env['HAS_CAIRO'] = False @@ -1213,13 +1217,13 @@ if not preconfigured: # set any custom cxxflags and ldflags to come first if sys.platform == 'darwin' and not env['HOST']: - DEFAULT_CXX11_CXXFLAGS += ' -stdlib=libc++' - DEFAULT_CXX11_LINKFLAGS = ' -stdlib=libc++' + DEFAULT_CXX14_CXXFLAGS += ' -stdlib=libc++' + DEFAULT_CXX14_LINKFLAGS = ' -stdlib=libc++' env.Append(CPPDEFINES = env['CUSTOM_DEFINES']) - env.Append(CXXFLAGS = DEFAULT_CXX11_CXXFLAGS) + env.Append(CXXFLAGS = DEFAULT_CXX14_CXXFLAGS) env.Append(CXXFLAGS = env['CUSTOM_CXXFLAGS']) env.Append(CFLAGS = env['CUSTOM_CFLAGS']) - env.Append(LINKFLAGS = DEFAULT_CXX11_LINKFLAGS) + env.Append(LINKFLAGS = DEFAULT_CXX14_LINKFLAGS) env.Append(LINKFLAGS = env['CUSTOM_LDFLAGS']) ### platform specific bits @@ -1353,9 +1357,9 @@ if not preconfigured: if env['PRIORITIZE_LINKING']: conf.prioritize_paths(silent=True) - # test for C++11 support, which is required - if not env['HOST'] and not conf.supports_cxx11(): - color_print(1,"C++ compiler does not support C++11 standard (-std=c++11), which is required. Please upgrade your compiler") + # test for C++14 support, which is required + if not env['HOST'] and not conf.supports_cxx14(): + color_print(1,"C++ compiler does not support C++14 standard (-std=c++14), which is required. Please upgrade your compiler") Exit(1) if not env['HOST']: @@ -1784,11 +1788,10 @@ if not preconfigured: # Common flags for g++/clang++ CXX compiler. # TODO: clean up code more to make -Wextra -Wsign-compare -Wsign-conversion -Wconversion viable # -Wfloat-equal -Wold-style-cast -Wexit-time-destructors -Wglobal-constructors -Wreserved-id-macro -Wheader-hygiene -Wmissing-noreturn - common_cxx_flags = '-fvisibility=hidden -fvisibility-inlines-hidden -Wall %s %s -ftemplate-depth-300 -Wsign-compare -Wshadow ' % (env['WARNING_CXXFLAGS'], pthread) + common_cxx_flags = '-fvisibility=hidden -fvisibility-inlines-hidden -Wall %s %s -ftemplate-depth-300 -Wsign-compare ' % (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: @@ -1797,7 +1800,7 @@ if not preconfigured: env.Append(CXXFLAGS = '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -ftrapv -fwrapv') if env['DEBUG_SANITIZE']: - env.Append(CXXFLAGS = ['-fsanitize=address']) + env.Append(CXXFLAGS = ['-fsanitize=address','-fno-omit-frame-pointer']) env.Append(LINKFLAGS = ['-fsanitize=address']) diff --git a/benchmark/bench_framework.hpp b/benchmark/bench_framework.hpp index a3de4fdd9..4cc9390e8 100644 --- a/benchmark/bench_framework.hpp +++ b/benchmark/bench_framework.hpp @@ -4,7 +4,7 @@ // mapnik #include #include -#include +#include #include #include "../test/cleanup.hpp" diff --git a/benchmark/run b/benchmark/run index 6a8fdd938..36cda4e92 100755 --- a/benchmark/run +++ b/benchmark/run @@ -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 diff --git a/benchmark/test_expression_parse.cpp b/benchmark/test_expression_parse.cpp index 7e399223c..f39fb8e84 100644 --- a/benchmark/test_expression_parse.cpp +++ b/benchmark/test_expression_parse.cpp @@ -1,8 +1,8 @@ #include "bench_framework.hpp" #include +#include #include #include -#include class test : public benchmark::test_case { diff --git a/benchmark/test_polygon_clipping.cpp b/benchmark/test_polygon_clipping.cpp index d10911a42..aed74fe33 100644 --- a/benchmark/test_polygon_clipping.cpp +++ b/benchmark/test_polygon_clipping.cpp @@ -10,10 +10,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include // boost geometry diff --git a/benchmark/test_proj_transform1.cpp b/benchmark/test_proj_transform1.cpp index 37f4b0c4c..fa050da12 100644 --- a/benchmark/test_proj_transform1.cpp +++ b/benchmark/test_proj_transform1.cpp @@ -1,5 +1,5 @@ #include "bench_framework.hpp" -#include +#include #include #include diff --git a/bootstrap.sh b/bootstrap.sh index e926c26bc..b2b171f49 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -11,7 +11,7 @@ todo - shrink icu data ' -MASON_VERSION="new-pkgs" +MASON_VERSION="3c6df04" function setup_mason() { if [[ ! -d ./.mason ]]; then @@ -19,7 +19,7 @@ function setup_mason() { (cd ./.mason && git checkout ${MASON_VERSION}) else echo "Updating to latest mason" - (cd ./.mason && git fetch && git checkout ${MASON_VERSION} && git pull) + (cd ./.mason && git fetch && git checkout ${MASON_VERSION} && git pull origin ${MASON_VERSION}) fi export PATH=$(pwd)/.mason:$PATH export CXX=${CXX:-clang++} @@ -44,45 +44,37 @@ function install() { mason link $1 $2 } -ICU_VERSION="55.1" +ICU_VERSION="57.1" function install_mason_deps() { - FAIL=0 - install ccache 3.3.0 & - install zlib system & - install jpeg_turbo 1.5.0 libjpeg & - install libpng 1.6.24 libpng & - install libtiff 4.0.6 libtiff & - install libpq 9.5.2 & - install sqlite 3.14.1 libsqlite3 & - install expat 2.2.0 libexpat & - install icu ${ICU_VERSION} & - install proj 4.9.2 libproj & - install pixman 0.34.0 libpixman-1 & - install cairo 1.14.6 libcairo & - install protobuf 2.6.1 & + install ccache 3.3.1 + install zlib 1.2.8 + install jpeg_turbo 1.5.1 libjpeg + install libpng 1.6.28 libpng + install libtiff 4.0.7 libtiff + install libpq 9.6.2 + install sqlite 3.17.0 libsqlite3 + install expat 2.2.0 libexpat + install icu ${ICU_VERSION} + install proj 4.9.3 libproj + install pixman 0.34.0 libpixman-1 + install cairo 1.14.8 libcairo + install protobuf 3.2.0 # technically protobuf is not a mapnik core dep, but installing # here by default helps make mapnik-vector-tile builds easier - install webp 0.5.1 libwebp & - install gdal 2.1.1 libgdal & - install boost 1.61.0 & - install boost_libsystem 1.61.0 & - install boost_libfilesystem 1.61.0 & - install boost_libprogram_options 1.61.0 & - install boost_libregex_icu 1.61.0 & + install webp 0.6.0 libwebp + install libgdal 2.1.3 libgdal + install boost 1.63.0 + install boost_libsystem 1.63.0 + install boost_libfilesystem 1.63.0 + install boost_libprogram_options 1.63.0 + install boost_libregex_icu57 1.63.0 # technically boost thread and python are not a core dep, but installing # here by default helps make python-mapnik builds easier - install boost_libthread 1.61.0 & - install boost_libpython 1.61.0 & - install freetype 2.6.5 libfreetype & - install harfbuzz 1.3.0 libharfbuzz & - for job in $(jobs -p) - do - wait $job || let "FAIL+=1" - done - if [[ "$FAIL" != "0" ]]; then - exit ${FAIL} - fi + install boost_libthread 1.63.0 + install boost_libpython 1.63.0 + install freetype 2.7.1 libfreetype + install harfbuzz 1.4.4-ft libharfbuzz } MASON_LINKED_ABS=$(pwd)/mason_packages/.link @@ -95,6 +87,7 @@ function make_config() { echo " CXX = '$CXX' CC = '$CC' +CUSTOM_CXXFLAGS = '-D_GLIBCXX_USE_CXX11_ABI=0' RUNTIME_LINK = 'static' INPUT_PLUGINS = 'all' PATH = '${MASON_LINKED_REL}/bin' diff --git a/circle.yml b/circle.yml index d9d4bad81..5624c66ae 100644 --- a/circle.yml +++ b/circle.yml @@ -7,11 +7,7 @@ machine: JOBS: 8 CCACHE_TEMPDIR: /tmp/.ccache-temp CCACHE_COMPRESS: 1 - LLVM_VERSION: 3.8 - pre: - - echo "here" - post: - - echo "there" + LLVM_VERSION: 3.9.1 checkout: post: @@ -32,9 +28,9 @@ dependencies: database: pre: - ./bootstrap.sh - - ./.mason/mason install clang ${LLVM_VERSION}.0 - - ./.mason/mason link clang ${LLVM_VERSION}.0 - - ./configure CC="$(pwd)/mason_packages/.link/bin/clang-${LLVM_VERSION}" CXX="$(pwd)/mason_packages/.link/bin/ccache $(pwd)/mason_packages/.link/bin/clang++-${LLVM_VERSION} -Qunused-arguments" + - ./.mason/mason install clang++ ${LLVM_VERSION} + - ./.mason/mason link clang++ ${LLVM_VERSION} + - ./configure CC="$(pwd)/mason_packages/.link/bin/clang" CXX="$(pwd)/mason_packages/.link/bin/ccache $(pwd)/mason_packages/.link/bin/clang++ -Qunused-arguments" - make override: - psql -c 'create database template_postgis;' diff --git a/demo/c++/rundemo.cpp b/demo/c++/rundemo.cpp index ff7907d2e..46e2cb2c0 100644 --- a/demo/c++/rundemo.cpp +++ b/demo/c++/rundemo.cpp @@ -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 diff --git a/demo/python/README.txt b/demo/python/README.txt deleted file mode 100644 index 4a13579cb..000000000 --- a/demo/python/README.txt +++ /dev/null @@ -1,20 +0,0 @@ -This directory contains a sample python script implementing the Mapnik API. - -The script is thoroughly commented and also acts as a mini tutorial. Reading -it should get you on your way, and you can use it as a base for your work. - -You must compile and install mapnik and the python bindings FIRST. - -Once this is done, run it: - -/path/to/python rundemo.py - -If all goes well, it should render 2 map images: - -demo.jpg -demo.png - -Have a look! - -Cheers, -J.F. diff --git a/demo/python/rundemo.py b/demo/python/rundemo.py deleted file mode 100755 index 910d846a5..000000000 --- a/demo/python/rundemo.py +++ /dev/null @@ -1,379 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# -# -# This file is part of Mapnik (c++ mapping toolkit) -# Copyright (C) 2005 Jean-Francois Doyon -# -# Mapnik is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or any later version. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -from __future__ import print_function -import sys -from os import path -import mapnik - -# Instanciate a map, giving it a width and height. Remember: the word "map" is -# reserved in Python! :) - -root = path.dirname(__file__) -m = mapnik.Map(800,600,"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs") - -# Set its background colour. More on colours later ... - -m.background = mapnik.Color('white') - -# Now we can start adding layers, in stacking order (i.e. bottom layer first) - -# Canadian Provinces (Polygons) - -# Instanciate a layer. The parameters depend on the type of data: -# shape: -# type='shape' -# file='/path/to/shape' -# raster: -# type='raster' -# file='/path/to/raster' -# postgis: -# type='postgis' -# host='127.0.0.1' -# dbname='mydatabase' -# user='myusername' -# password='mypassword' -# table= TODO - -provpoly_lyr = mapnik.Layer('Provinces') -provpoly_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -provpoly_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/boundaries'), encoding='latin1') - -# We then define a style for the layer. A layer can have one or many styles. -# Styles are named, so they can be shared across different layers. -# Multiple styles per layer behaves functionally like multiple layers. The -# data is completely re-scanned for each style within one layer, and a style -# will be drawn entirely "above" the previous one. Performance wise using -# multiple styles in one layer is the same has having multiple layers. -# The paradigm is useful mostly as a convenience. - -provpoly_style = mapnik.Style() - -# A Style needs one or more rules. A rule will normally consist of a filter -# for feature selection, and one or more symbolizers. - -provpoly_rule_on = mapnik.Rule() - -# A Expression() allows the selection of features to which the symbology will -# be applied. More on Mapnik expressions can be found in Tutorial #2. -# A given feature can only match one filter per rule per style. - -provpoly_rule_on.filter = mapnik.Expression("[NAME_EN] = 'Ontario'") - -# Here a symbolizer is defined. Available are: -# - LineSymbolizer(Color(),) -# - LineSymbolizer(Stroke()) -# - PolygonSymbolizer(Color()) -# - PointSymbolizer(,,,) - -# Some of them can accept a Color() instance, which can be created with: -# - Color(, , ) -# - Color(, , , ) -# - Color() where will be something like '#00FF00' -# or '#0f0' or 'green' - -sym = mapnik.PolygonSymbolizer() -sym.fill = mapnik.Color(250, 190, 183); -provpoly_rule_on.symbols.append(sym) -provpoly_style.rules.append(provpoly_rule_on) - -provpoly_rule_qc = mapnik.Rule() -provpoly_rule_qc.filter = mapnik.Expression("[NOM_FR] = 'Québec'") -sym = mapnik.PolygonSymbolizer() -sym.fill = mapnik.Color(217, 235, 203) -provpoly_rule_qc.symbols.append(sym) -provpoly_style.rules.append(provpoly_rule_qc) - -# Add the style to the map, giving it a name. This is the name that will be -# used to refer to it from here on. Having named styles allows them to be -# re-used throughout the map. - -m.append_style('provinces', provpoly_style) - -# Then associate the style to the layer itself. - -provpoly_lyr.styles.append('provinces') - -# Then add the layer to the map. In reality, it's the order in which you -# append them to the map that will determine the drawing order, though by -# convention it is recommended to define them in drawing order as well. - -m.layers.append(provpoly_lyr) - -# Drainage - -# A simple example ... - -qcdrain_lyr = mapnik.Layer('Quebec Hydrography') -qcdrain_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -qcdrain_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/qcdrainage')) - -qcdrain_style = mapnik.Style() -qcdrain_rule = mapnik.Rule() -qcdrain_rule.filter = mapnik.Expression('[HYC] = 8') -sym = mapnik.PolygonSymbolizer() -sym.fill = mapnik.Color(153, 204, 255) -sym.smooth = 1.0 # very smooth -qcdrain_rule.symbols.append(sym) -qcdrain_style.rules.append(qcdrain_rule) - -m.append_style('drainage', qcdrain_style) -qcdrain_lyr.styles.append('drainage') -m.layers.append(qcdrain_lyr) - -# In this case, we have 2 data sets with similar schemas (same filtering -# attributes, and same desired style), so we're going to -# re-use the style defined in the above layer for the next one. - -ondrain_lyr = mapnik.Layer('Ontario Hydrography') -ondrain_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -ondrain_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/ontdrainage')) - -ondrain_lyr.styles.append('drainage') -m.layers.append(ondrain_lyr) - -# Provincial boundaries - -provlines_lyr = mapnik.Layer('Provincial borders') -provlines_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -provlines_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/boundaries_l')) - -# Here we define a "dash dot dot dash" pattern for the provincial boundaries. - -provlines_style = mapnik.Style() -provlines_rule = mapnik.Rule() -sym = mapnik.LineSymbolizer() -# FIXME - currently adding dash arrays is broken -# https://github.com/mapnik/mapnik/issues/2324 -sym.stroke = mapnik.Color('black') -sym.stroke_width = 1.0 -provlines_rule.symbols.append(sym) -provlines_style.rules.append(provlines_rule) - -m.append_style('provlines', provlines_style) -provlines_lyr.styles.append('provlines') -m.layers.append(provlines_lyr) - -# Roads 3 and 4 (The "grey" roads) - -roads34_lyr = mapnik.Layer('Roads') -roads34_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -# create roads datasource (we're going to re-use it later) - -roads34_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/roads')) - -roads34_style = mapnik.Style() -roads34_rule = mapnik.Rule() -roads34_rule.filter = mapnik.Expression('([CLASS] = 3) or ([CLASS] = 4)') - -# With lines of a certain width, you can control how the ends -# are closed off using line_cap as below. - -# Available options are: -# line_cap: BUTT_CAP, SQUARE_CAP, ROUND_CAP -# line_join: MITER_JOIN, MITER_REVERT_JOIN, ROUND_JOIN, BEVEL_JOIN - -# And one last Stroke() attribute not used here is "opacity", which -# can be set to a numerical value. - -sym = mapnik.LineSymbolizer() -sym.stroke = mapnik.Color(171,158,137) -sym.stroke_width = 2.0 -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP - -roads34_rule.symbols.append(sym) -roads34_style.rules.append(roads34_rule) - -m.append_style('smallroads', roads34_style) -roads34_lyr.styles.append('smallroads') -m.layers.append(roads34_lyr) - -# Roads 2 (The thin yellow ones) - -roads2_lyr = mapnik.Layer('Roads') -roads2_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -# Just get a copy from roads34_lyr -roads2_lyr.datasource = roads34_lyr.datasource - -roads2_style_1 = mapnik.Style() -roads2_rule_1 = mapnik.Rule() -roads2_rule_1.filter = mapnik.Expression('[CLASS] = 2') - -sym = mapnik.LineSymbolizer() -sym.stroke = mapnik.Color(171,158,137) -sym.stroke_width = 4.0 -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP -roads2_rule_1.symbols.append(sym) -roads2_style_1.rules.append(roads2_rule_1) - -m.append_style('road-border', roads2_style_1) - -roads2_style_2 = mapnik.Style() -roads2_rule_2 = mapnik.Rule() -roads2_rule_2.filter = mapnik.Expression('[CLASS] = 2') -sym = mapnik.LineSymbolizer() -sym.stroke = mapnik.Color(255,250,115) -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP -sym.stroke_width = 2.0 -roads2_rule_2.symbols.append(sym) -roads2_style_2.rules.append(roads2_rule_2) - -m.append_style('road-fill', roads2_style_2) - -roads2_lyr.styles.append('road-border') -roads2_lyr.styles.append('road-fill') - -m.layers.append(roads2_lyr) - -# Roads 1 (The big orange ones, the highways) - -roads1_lyr = mapnik.Layer('Roads') -roads1_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -roads1_lyr.datasource = roads34_lyr.datasource - -roads1_style_1 = mapnik.Style() -roads1_rule_1 = mapnik.Rule() -roads1_rule_1.filter = mapnik.Expression('[CLASS] = 1') -sym = mapnik.LineSymbolizer() -sym.stroke = mapnik.Color(188,149,28) -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP -sym.stroke_width = 7.0 -roads1_rule_1.symbols.append(sym) -roads1_style_1.rules.append(roads1_rule_1) -m.append_style('highway-border', roads1_style_1) - -roads1_style_2 = mapnik.Style() -roads1_rule_2 = mapnik.Rule() -roads1_rule_2.filter = mapnik.Expression('[CLASS] = 1') -sym.stroke = mapnik.Color(242,191,36) -sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP -sym.stroke_width = 5.0 -roads1_rule_2.symbols.append(sym) -roads1_style_2.rules.append(roads1_rule_2) - -m.append_style('highway-fill', roads1_style_2) - -roads1_lyr.styles.append('highway-border') -roads1_lyr.styles.append('highway-fill') - -m.layers.append(roads1_lyr) - -# Populated Places - -popplaces_lyr = mapnik.Layer('Populated Places') -popplaces_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs" -popplaces_lyr.datasource = mapnik.Shapefile(file=path.join(root,'../data/popplaces'),encoding='latin1') - -popplaces_style = mapnik.Style() -popplaces_rule = mapnik.Rule() - -# And here we have a TextSymbolizer, used for labeling. -# The first parameter is the name of the attribute to use as the source of the -# text to label with. Then there is font size in points (I think?), and colour. - -# TODO - currently broken: https://github.com/mapnik/mapnik/issues/2324 -#popplaces_text_symbolizer = mapnik.TextSymbolizer(mapnik.Expression("[GEONAME]"), -# 'DejaVu Sans Book', -# 10, mapnik.Color('black')) - -# We set a "halo" around the text, which looks like an outline if thin enough, -# or an outright background if large enough. -#popplaces_text_symbolizer.label_placement= mapnik.label_placement.POINT_PLACEMENT -#popplaces_text_symbolizer.halo_fill = mapnik.Color(255,255,200) -#popplaces_text_symbolizer.halo_radius = 1 -#popplaces_text_symbolizer.avoid_edges = True -#popplaces_text_symbolizer.minimum_padding = 30 -#popplaces_rule.symbols.append(popplaces_text_symbolizer) - -popplaces_style.rules.append(popplaces_rule) - -m.append_style('popplaces', popplaces_style) -popplaces_lyr.styles.append('popplaces') -m.layers.append(popplaces_lyr) - -# Draw map - -# Set the initial extent of the map in 'master' spherical Mercator projection -m.zoom_to_box(mapnik.Box2d(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855)) - -# Render map -im = mapnik.Image(m.width,m.height) -mapnik.render(m, im) - -# Save image to files -images_ = [] -if mapnik.has_png(): - im.save('demo.png', 'png') # true-colour RGBA - images_.append('demo.png') - - # old behavior, now can do 'png8:c=256' - im.save('demo256.png', 'png256') # save to palette based (max 256 colours) png - images_.append('demo256.png') - - im.save('demo64_binary_transparency.png', 'png8:c=64:t=1') - images_.append('demo64_binary_transparency.png') - - im.save('demo128_colors_hextree_no_alpha.png', 'png8:c=100:m=h:t=0') - images_.append('demo128_colors_hextree_no_alpha.png') - -if mapnik.has_jpeg(): - im.save('demo_high.jpg', 'jpeg100') - images_.append('demo_high.jpg') - - im.save('demo_low.jpg', 'jpeg50') - images_.append('demo_low.jpg') - -if mapnik.has_tiff(): - im.save('demo.tif', 'tiff') - images_.append('demo.tif') - -if mapnik.has_webp(): - im.save('demo.webp', 'webp') # default quality is 90 - images_.append('demo.webp') - - im.save('demo_highest.webp', 'webp:quality=100') - images_.append('demo_med.webp') - - im.save('demo_low.webp', 'webp:quality=50') - images_.append('demo_low.webp') - - -# Render cairo examples -if mapnik.has_cairo(): - mapnik.render_to_file(m,'demo.pdf') - images_.append('demo.pdf') - mapnik.render_to_file(m,'demo.ps') - images_.append('demo.ps') - mapnik.render_to_file(m,'demo.svg') - images_.append('demo.svg') - mapnik.render_to_file(m,'demo_cairo_rgb24.png','RGB24') - images_.append('demo_cairo_rgb.png') - mapnik.render_to_file(m,'demo_cairo_argb32.png','ARGB32') - images_.append('demo_cairo_argb.png') - -print ("\n\n", len(images_), "maps have been rendered in the current directory:") - -for im_ in images_: - print ("-", im_) - -print ("\n\nHave a look!\n\n") - -mapnik.save_map(m,"map.xml") diff --git a/demo/viewer/about_dialog.cpp b/demo/viewer/about_dialog.cpp index 2a37349ee..b6aa9fa33 100644 --- a/demo/viewer/about_dialog.cpp +++ b/demo/viewer/about_dialog.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/about_dialog.hpp b/demo/viewer/about_dialog.hpp index 160dcc857..0edc78dfa 100644 --- a/demo/viewer/about_dialog.hpp +++ b/demo/viewer/about_dialog.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/info_dialog.cpp b/demo/viewer/info_dialog.cpp index b25002025..a65951082 100644 --- a/demo/viewer/info_dialog.cpp +++ b/demo/viewer/info_dialog.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/info_dialog.hpp b/demo/viewer/info_dialog.hpp index c4b887f18..4dfded270 100644 --- a/demo/viewer/info_dialog.hpp +++ b/demo/viewer/info_dialog.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layer_info_dialog.cpp b/demo/viewer/layer_info_dialog.cpp index f7e983d35..65dddd392 100644 --- a/demo/viewer/layer_info_dialog.cpp +++ b/demo/viewer/layer_info_dialog.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layer_info_dialog.hpp b/demo/viewer/layer_info_dialog.hpp index 370551e01..3ac825dbc 100644 --- a/demo/viewer/layer_info_dialog.hpp +++ b/demo/viewer/layer_info_dialog.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerdelegate.cpp b/demo/viewer/layerdelegate.cpp index 5e4331793..a43214a9b 100644 --- a/demo/viewer/layerdelegate.cpp +++ b/demo/viewer/layerdelegate.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerdelegate.hpp b/demo/viewer/layerdelegate.hpp index 92a57a75e..479e0838d 100644 --- a/demo/viewer/layerdelegate.hpp +++ b/demo/viewer/layerdelegate.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerlistmodel.cpp b/demo/viewer/layerlistmodel.cpp index f2ad085ef..e1e46e075 100644 --- a/demo/viewer/layerlistmodel.cpp +++ b/demo/viewer/layerlistmodel.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerlistmodel.hpp b/demo/viewer/layerlistmodel.hpp index d69133315..4fec7a712 100644 --- a/demo/viewer/layerlistmodel.hpp +++ b/demo/viewer/layerlistmodel.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerwidget.cpp b/demo/viewer/layerwidget.cpp index d392150fb..f066a3d1b 100644 --- a/demo/viewer/layerwidget.cpp +++ b/demo/viewer/layerwidget.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/layerwidget.hpp b/demo/viewer/layerwidget.hpp index e75ee7db2..09763fc45 100644 --- a/demo/viewer/layerwidget.hpp +++ b/demo/viewer/layerwidget.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/main.cpp b/demo/viewer/main.cpp index d8f06d25a..f7ab2e432 100644 --- a/demo/viewer/main.cpp +++ b/demo/viewer/main.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/mainwindow.cpp b/demo/viewer/mainwindow.cpp index 939028ab5..27f71d4c0 100644 --- a/demo/viewer/mainwindow.cpp +++ b/demo/viewer/mainwindow.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/mainwindow.hpp b/demo/viewer/mainwindow.hpp index ebfc2c59a..b816617ad 100644 --- a/demo/viewer/mainwindow.hpp +++ b/demo/viewer/mainwindow.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/mapwidget.cpp b/demo/viewer/mapwidget.cpp index 9b2c5278d..fd3c3d1f7 100644 --- a/demo/viewer/mapwidget.cpp +++ b/demo/viewer/mapwidget.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/mapwidget.hpp b/demo/viewer/mapwidget.hpp index e65908fcf..d0f538e6e 100644 --- a/demo/viewer/mapwidget.hpp +++ b/demo/viewer/mapwidget.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/styles_model.cpp b/demo/viewer/styles_model.cpp index d7b68ba0e..332200b21 100644 --- a/demo/viewer/styles_model.cpp +++ b/demo/viewer/styles_model.cpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/styles_model.hpp b/demo/viewer/styles_model.hpp index a21885915..ce7879469 100644 --- a/demo/viewer/styles_model.hpp +++ b/demo/viewer/styles_model.hpp @@ -1,6 +1,6 @@ /* This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/demo/viewer/viewer.pro b/demo/viewer/viewer.pro index 8a9747752..aad00b424 100644 --- a/demo/viewer/viewer.pro +++ b/demo/viewer/viewer.pro @@ -1,7 +1,6 @@ ###################################################################### # Mapnik viewer - Copyright (C) 2007 Artem Pavlenko ###################################################################### -QMAKE_MAC_SDK = macosx10.11 TEMPLATE = app QT += core gui widgets QMAKE_CXX = $$system(mapnik-config --cxx) diff --git a/deps/agg/include/agg_vpgen_clip_polygon.h b/deps/agg/include/agg_vpgen_clip_polygon.h index 4972a390b..7f98538e3 100644 --- a/deps/agg/include/agg_vpgen_clip_polygon.h +++ b/deps/agg/include/agg_vpgen_clip_polygon.h @@ -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(); } diff --git a/deps/agg/include/agg_vpgen_clip_polyline.h b/deps/agg/include/agg_vpgen_clip_polyline.h index a2e60fa7b..c7b18c98a 100644 --- a/deps/agg/include/agg_vpgen_clip_polyline.h +++ b/deps/agg/include/agg_vpgen_clip_polyline.h @@ -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(); } diff --git a/deps/mapbox/geometry b/deps/mapbox/geometry index 03778c6af..b0d64e6e8 160000 --- a/deps/mapbox/geometry +++ b/deps/mapbox/geometry @@ -1 +1 @@ -Subproject commit 03778c6af7f1f116fc5722596a31334315451a53 +Subproject commit b0d64e6e8d55026781325df1068e8043ff880aff diff --git a/deps/mapbox/variant b/deps/mapbox/variant index a5a79a594..916139a2e 160000 --- a/deps/mapbox/variant +++ b/deps/mapbox/variant @@ -1 +1 @@ -Subproject commit a5a79a594f39d705a7ef969f54a0743516f0bc6d +Subproject commit 916139a2e51e125816efce6e19d428385601273f diff --git a/include/build.py b/include/build.py index ec705419a..aa122d9a5 100644 --- a/include/build.py +++ b/include/build.py @@ -39,7 +39,10 @@ subdirs = [ 'text', 'text/placements', 'text/formatting', - 'markers_placements' + 'transform', + 'markers_placements', + 'geometry', + 'value' ] if env['SVG_RENDERER']: diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp index ff87ce0ef..51319d52b 100644 --- a/include/mapnik/agg_helpers.hpp +++ b/include/mapnik/agg_helpers.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 diff --git a/include/mapnik/agg_pattern_source.hpp b/include/mapnik/agg_pattern_source.hpp index 42dd7f36f..7ca93e1df 100644 --- a/include/mapnik/agg_pattern_source.hpp +++ b/include/mapnik/agg_pattern_source.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 diff --git a/include/mapnik/agg_rasterizer.hpp b/include/mapnik/agg_rasterizer.hpp index 66da59fd6..b25160b04 100644 --- a/include/mapnik/agg_rasterizer.hpp +++ b/include/mapnik/agg_rasterizer.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 diff --git a/include/mapnik/agg_render_marker.hpp b/include/mapnik/agg_render_marker.hpp index 283807a93..d11789df4 100644 --- a/include/mapnik/agg_render_marker.hpp +++ b/include/mapnik/agg_render_marker.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,13 +20,16 @@ * *****************************************************************************/ +#ifndef MAPNIK_AGG_RENDER_MARKER_HPP +#define MAPNIK_AGG_RENDER_MARKER_HPP + #include #include #include #include #include #include -#include +#include #include #include @@ -148,3 +151,5 @@ void render_raster_marker(RendererType renb, RasterizerType & ras, image_rgba8 c } } + +#endif // MAPNIK_AGG_RENDER_MARKER_HPP diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index 776632d68..27a22b74a 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.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 @@ -28,15 +28,17 @@ #include #include // for noncopyable #include // for rule, symbolizers -#include // for box2d +#include // for box2d #include // for view_transform #include // for composite_mode_e #include #include #include #include +#include // stl #include +#include // fwd declaration to avoid dependence on agg headers namespace agg { struct trans_affine; } @@ -58,6 +60,53 @@ namespace mapnik { namespace mapnik { +template +class buffer_stack +{ +public: + buffer_stack(std::size_t width, std::size_t height) + : width_(width), + height_(height), + buffers_(), + position_(buffers_.begin()) + { + } + + T & push() + { + if (position_ == buffers_.begin()) + { + buffers_.emplace_front(width_, height_); + position_ = buffers_.begin(); + } + else + { + position_--; + mapnik::fill(*position_, 0); // fill with transparent colour + } + return *position_; + } + + void pop() + { + if (position_ != buffers_.end()) + { + position_++; + } + } + + T & top() const + { + return *position_; + } + +private: + const std::size_t width_; + const std::size_t height_; + std::deque buffers_; + typename std::deque::iterator position_; +}; + template class MAPNIK_DECL agg_renderer : public feature_style_processor >, private util::noncopyable @@ -160,15 +209,14 @@ protected: void draw_geo_extent(box2d const& extent,mapnik::color const& color); private: - buffer_type & pixmap_; - std::shared_ptr internal_buffer_; - mutable buffer_type * current_buffer_; - mutable bool style_level_compositing_; + std::stack> buffers_; + buffer_stack internal_buffers_; + std::unique_ptr inflated_buffer_; const std::unique_ptr ras_ptr; gamma_method_enum gamma_method_; double gamma_; renderer_common common_; - void setup(Map const& m); + void setup(Map const & m, buffer_type & pixmap); }; extern template class MAPNIK_DECL agg_renderer>; diff --git a/include/mapnik/attribute.hpp b/include/mapnik/attribute.hpp index edfaebefc..3e82f8f2f 100644 --- a/include/mapnik/attribute.hpp +++ b/include/mapnik/attribute.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 @@ -24,7 +24,7 @@ #define MAPNIK_ATTRIBUTE_HPP // mapnik -#include +#include #include #include // stl diff --git a/include/mapnik/attribute_collector.hpp b/include/mapnik/attribute_collector.hpp index cfd29cc6b..83fec1171 100644 --- a/include/mapnik/attribute_collector.hpp +++ b/include/mapnik/attribute_collector.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 @@ -24,7 +24,7 @@ #define MAPNIK_ATTRIBUTE_COLLECTOR_HPP // mapnik -#include +#include #include #include #include diff --git a/include/mapnik/attribute_descriptor.hpp b/include/mapnik/attribute_descriptor.hpp index a5245ea55..a80d7e0d5 100644 --- a/include/mapnik/attribute_descriptor.hpp +++ b/include/mapnik/attribute_descriptor.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 diff --git a/include/mapnik/boolean.hpp b/include/mapnik/boolean.hpp index 92751b7fe..9d2b97bf6 100644 --- a/include/mapnik/boolean.hpp +++ b/include/mapnik/boolean.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 diff --git a/include/mapnik/cairo/cairo_context.hpp b/include/mapnik/cairo/cairo_context.hpp index c15f87cd7..1e775d6a0 100644 --- a/include/mapnik/cairo/cairo_context.hpp +++ b/include/mapnik/cairo/cairo_context.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 diff --git a/include/mapnik/cairo/cairo_image_util.hpp b/include/mapnik/cairo/cairo_image_util.hpp index 9f039d605..2c7c269a4 100644 --- a/include/mapnik/cairo/cairo_image_util.hpp +++ b/include/mapnik/cairo/cairo_image_util.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 diff --git a/include/mapnik/cairo/cairo_render_vector.hpp b/include/mapnik/cairo/cairo_render_vector.hpp index 37bd44925..ead3798e9 100644 --- a/include/mapnik/cairo/cairo_render_vector.hpp +++ b/include/mapnik/cairo/cairo_render_vector.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 diff --git a/include/mapnik/cairo/cairo_renderer.hpp b/include/mapnik/cairo/cairo_renderer.hpp index 0563149a6..9e7a91477 100644 --- a/include/mapnik/cairo/cairo_renderer.hpp +++ b/include/mapnik/cairo/cairo_renderer.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 diff --git a/include/mapnik/cairo_io.hpp b/include/mapnik/cairo_io.hpp index 55b107286..45c4353d2 100644 --- a/include/mapnik/cairo_io.hpp +++ b/include/mapnik/cairo_io.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 diff --git a/include/mapnik/color.hpp b/include/mapnik/color.hpp index 434a9cf21..7f8ee7c03 100644 --- a/include/mapnik/color.hpp +++ b/include/mapnik/color.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 @@ -38,16 +38,15 @@ namespace mapnik { -class MAPNIK_DECL color - : boost::equality_comparable +class MAPNIK_DECL color : boost::equality_comparable { -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), diff --git a/include/mapnik/color_factory.hpp b/include/mapnik/color_factory.hpp index 6fdb5663c..594cb40b0 100644 --- a/include/mapnik/color_factory.hpp +++ b/include/mapnik/color_factory.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 diff --git a/include/mapnik/config.hpp b/include/mapnik/config.hpp index a9168e59f..25df5371f 100644 --- a/include/mapnik/config.hpp +++ b/include/mapnik/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 diff --git a/include/mapnik/config_error.hpp b/include/mapnik/config_error.hpp index b8bd31f67..0d1d4c1dc 100644 --- a/include/mapnik/config_error.hpp +++ b/include/mapnik/config_error.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 @@ -41,10 +41,8 @@ public: config_error(std::string const& what, unsigned line_number, std::string const& filename); - virtual ~config_error() throw() {} - - virtual const char * what() const throw(); - + virtual ~config_error() {} + virtual const char * what() const noexcept; void append_context(std::string const& ctx) const; void append_context(std::string const& ctx, xml_node const& node) const; void append_context(xml_node const& node) const; diff --git a/include/mapnik/coord.hpp b/include/mapnik/coord.hpp index f8ea3f161..c20c755bc 100644 --- a/include/mapnik/coord.hpp +++ b/include/mapnik/coord.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 @@ -181,6 +181,7 @@ private: }; using coord2d = coord; +using coord2f = coord; using coord2i = coord; } diff --git a/include/mapnik/css_color_grammar.hpp b/include/mapnik/css_color_grammar.hpp deleted file mode 100644 index 8fbdeaa6f..000000000 --- a/include/mapnik/css_color_grammar.hpp +++ /dev/null @@ -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 -#include -#include - -// boost -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -// stl -#include - -namespace mapnik -{ - -namespace qi = boost::spirit::qi; -namespace ascii = boost::spirit::ascii; - -using ascii_space_type = boost::spirit::ascii::space_type; - -template -struct css_color_grammar : qi::grammar -{ - // 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 rgba_color; - qi::rule rgba_percent_color; - qi::rule,color(), ascii_space_type> hsl_percent_color; - qi::rule hex_color; - qi::rule hex_color_small; - qi::rule css_color; -}; - -} - -#endif // MAPNIK_CSS_COLOR_GRAMMAR_HPP diff --git a/src/css_color_grammar.cpp b/include/mapnik/css_color_grammar_x3.hpp similarity index 61% rename from src/css_color_grammar.cpp rename to include/mapnik/css_color_grammar_x3.hpp index 2e9f60c92..54e022528 100644 --- a/src/css_color_grammar.cpp +++ b/include/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,12 +20,36 @@ * *****************************************************************************/ -// NOTE: we define this here in a cpp because def is needed twice: -// once by src/color_factory.cpp and once by include/mapnik/image_filter_grammar.hpp -// otherwise it would make sense to simply do `#include ` -// in a single file -#include -#include -#include +#ifndef MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP +#define MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP -template struct mapnik::css_color_grammar; +#include + +#pragma GCC diagnostic push +#include +#include +#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; + +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 diff --git a/include/mapnik/css_color_grammar_impl.hpp b/include/mapnik/css_color_grammar_x3_def.hpp similarity index 54% rename from include/mapnik/css_color_grammar_impl.hpp rename to include/mapnik/css_color_grammar_x3_def.hpp index 22fa74472..457f0d999 100644 --- a/include/mapnik/css_color_grammar_impl.hpp +++ b/include/mapnik/css_color_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 @@ -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 -// 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 +#include +#include + #pragma GCC diagnostic push -#include -#include -#include -#include +#include +#include +#include +#include #pragma GCC diagnostic pop - -BOOST_FUSION_ADAPT_ADT( +BOOST_FUSION_ADAPT_STRUCT ( mapnik::color, - (unsigned, unsigned, obj.red(), obj.set_red(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.green(), obj.set_green(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.blue(), obj.set_blue(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.alpha(), obj.set_alpha(mapnik::safe_cast(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 { -namespace phoenix = boost::phoenix; - -struct percent_conv_impl -{ - using result_type = unsigned; - unsigned operator() (double val) const - { - return safe_cast(std::lround((255.0 * val)/100.0)); - } -}; - -struct alpha_conv_impl -{ - using result_type = unsigned; - unsigned operator() (double val) const - { - return safe_cast(std::lround((255.0 * val))); - } -}; - -struct hsl_conv_impl -{ - using result_type = void; - template - 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(std::lround(255.0 * r))); - c.set_green(safe_cast(std::lround(255.0 * g))); - c.set_blue(safe_cast(std::lround(255.0 * b))); - } -}; - -struct named_colors : qi::symbols -{ - named_colors() + named_colors_() { add ("aliceblue", color(240, 248, 255)) @@ -249,77 +214,241 @@ struct named_colors : qi::symbols ("transparent", color(0, 0, 0, 0)) ; } +} named_colors; + +x3::uint_parser hex2; +x3::uint_parser hex1; +x3::uint_parser dec3; + +// starting rule +css_color_grammar_type const css_color("css_color"); +// rules +x3::rule const hex2_color("hex2_color"); +x3::rule const hex1_color("hex1_color"); +x3::rule const rgb_color("rgb_color"); +x3::rule const rgba_color("rgba_color"); +x3::rule const rgb_color_percent("rgb_color_percent"); +x3::rule 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 -css_color_grammar::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_converter; - phoenix::function alpha_converter; - phoenix::function hsl_converter; + static std::uint8_t call(double val) + { + return safe_cast(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(std::lround(255.0 * r)), + safe_cast(std::lround(255.0 * g)), + safe_cast(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> {} = + lit("hsl") + >> lit('(') >> dec3 + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> dec3 >> lit('%') + >> attr(1.0) >> lit(')') + ; + +auto const hsla_values = x3::rule> {} = + lit("hsla") + >> lit('(') >> dec3 + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> double_ >> lit(')') + ; + +auto const hsl_color = x3::rule {} = hsl_values[hsl_to_rgba]; +auto const hsla_color = x3::rule {} = 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 +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 diff --git a/include/mapnik/csv/csv_grammar.hpp b/include/mapnik/csv/csv_grammar.hpp deleted file mode 100644 index 240f11ce1..000000000 --- a/include/mapnik/csv/csv_grammar.hpp +++ /dev/null @@ -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 -#include - -namespace mapnik { - -namespace qi = boost::spirit::qi; - -struct csv_white_space_skipper : qi::primitive_parser -{ - template - struct attribute - { - typedef qi::unused_type type; - }; - - template - 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 - qi::info what(Context& /*context*/) const - { - return qi::info("csv_white_space_skipper"); - } -}; - - -template -struct csv_line_grammar : qi::grammar -{ - csv_line_grammar(); -private: - qi::rule line; - qi::rule column; // no-skip - qi::rule text; // no-skip - qi::rule quoted; // no-skip - qi::symbols unesc_char; -}; - -} - -#endif // MAPNIK_CSV_GRAMMAR_HPP diff --git a/include/mapnik/csv/csv_grammar_x3.hpp b/include/mapnik/csv/csv_grammar_x3.hpp new file mode 100644 index 000000000..26abba97f --- /dev/null +++ b/include/mapnik/csv/csv_grammar_x3.hpp @@ -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_CSV_GRAMMAR_X3_HPP +#define MAPNIK_CSV_GRAMMAR_X3_HPP + +#include +#include +#include +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +struct csv_white_space_skipper : x3::parser +{ + using attribute_type = x3::unused_type; + static bool const has_attribute = false; + + template + 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; + +BOOST_SPIRIT_DECLARE(csv_line_grammar_type); + +}} + +#endif // MAPNIK_CSV_GRAMMAR_X3_HPP diff --git a/include/mapnik/csv/csv_grammar_x3_def.hpp b/include/mapnik/csv/csv_grammar_x3_def.hpp new file mode 100644 index 000000000..d284cbbce --- /dev/null +++ b/include/mapnik/csv/csv_grammar_x3_def.hpp @@ -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_CSV_GRAMMAR_X3_DEF_HPP +#define MAPNIK_CSV_GRAMMAR_X3_DEF_HPP + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + + +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 +{ + unesc_char_() + { + add("\\a", '\a') + ("\\b", '\b') + ("\\f", '\f') + ("\\n", '\n') + ("\\r", '\r') + ("\\t", '\t') + ("\\v", '\v') + ("\\\\",'\\') + ("\\\'", '\'') + ("\\\"", '\"') + ("\"\"", '\"') // double quote + ; + } +} unesc_char; + +template +struct literal : x3::parser> +{ + using attribute_type = x3::unused_type; + using context_tag = T; + static bool const has_attribute = false; + + template + 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)) + { + ++first; + return true; + } + return false; + } +}; + +auto static const separator = literal{}; +auto static const quote = literal{}; + +// starting rule +csv_line_grammar_type const line("csv-line"); +// rules +x3::rule column("csv-column"); +x3::rule text("csv-text"); +x3::rule 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 + + +#endif // MAPNIK_CSV_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/csv/csv_types.hpp b/include/mapnik/csv/csv_types.hpp index 5359c3dd6..042f68968 100644 --- a/include/mapnik/csv/csv_types.hpp +++ b/include/mapnik/csv/csv_types.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 diff --git a/include/mapnik/cxx11_support.hpp b/include/mapnik/cxx11_support.hpp new file mode 100644 index 000000000..dafd721dd --- /dev/null +++ b/include/mapnik/cxx11_support.hpp @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * 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_CXX11_SUPPORT_HPP +#define MAPNIK_CXX11_SUPPORT_HPP + +#include + +namespace mapnik { +namespace detail { + +template +using conditional_t = typename std::conditional::type; + +template +using decay_t = typename std::decay::type; + +template +using enable_if_t = typename std::enable_if::type; + +} // namespace detail +} // namespace mapnik + +#endif // MAPNIK_CXX11_SUPPORT_HPP diff --git a/include/mapnik/datasource.hpp b/include/mapnik/datasource.hpp index ec14a621c..2917ab976 100644 --- a/include/mapnik/datasource.hpp +++ b/include/mapnik/datasource.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 @@ -46,14 +46,11 @@ class MAPNIK_DECL datasource_exception : public std::exception public: datasource_exception(std::string const& message) : message_(message) - { - } + {} - ~datasource_exception() throw() - { - } + ~datasource_exception() {} - virtual const char* what() const throw() + virtual const char* what() const noexcept { return message_.c_str(); } @@ -69,8 +66,8 @@ public: Raster }; - datasource (parameters const& params) - : params_(params) {} + datasource (parameters const& _params) + : params_(_params) {} /*! * @brief Get the configuration parameters of the data source. diff --git a/include/mapnik/datasource_cache.hpp b/include/mapnik/datasource_cache.hpp index 4f90f8907..bd5b3310d 100644 --- a/include/mapnik/datasource_cache.hpp +++ b/include/mapnik/datasource_cache.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 diff --git a/include/mapnik/datasource_geometry_type.hpp b/include/mapnik/datasource_geometry_type.hpp index 00e4b2af7..4d824b841 100644 --- a/include/mapnik/datasource_geometry_type.hpp +++ b/include/mapnik/datasource_geometry_type.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 diff --git a/include/mapnik/debug.hpp b/include/mapnik/debug.hpp index 84290958b..b841d81d5 100644 --- a/include/mapnik/debug.hpp +++ b/include/mapnik/debug.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 diff --git a/include/mapnik/ellipsoid.hpp b/include/mapnik/ellipsoid.hpp index 6f872d4d4..b43a6dad9 100644 --- a/include/mapnik/ellipsoid.hpp +++ b/include/mapnik/ellipsoid.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 diff --git a/include/mapnik/enumeration.hpp b/include/mapnik/enumeration.hpp index d57955b9f..c4b736025 100644 --- a/include/mapnik/enumeration.hpp +++ b/include/mapnik/enumeration.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 @@ -28,7 +28,6 @@ #include // stl -#include #include #include #include @@ -45,9 +44,9 @@ public: what_( _what ) { } - virtual ~illegal_enum_value() throw() {} + virtual ~illegal_enum_value() {} - virtual const char * what() const throw() + virtual const char * what() const noexcept { return what_.c_str(); } @@ -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 diff --git a/include/mapnik/evaluate_global_attributes.hpp b/include/mapnik/evaluate_global_attributes.hpp index 3e3d63cbd..a73ac1262 100644 --- a/include/mapnik/evaluate_global_attributes.hpp +++ b/include/mapnik/evaluate_global_attributes.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 @@ -43,8 +43,8 @@ struct evaluate_expression { using value_type = T; - explicit evaluate_expression(Attributes const& attributes) - : attributes_(attributes) {} + explicit evaluate_expression(Attributes const& attrs) + : attrs_(attrs) {} value_type operator() (attribute const&) const { @@ -53,8 +53,8 @@ struct evaluate_expression value_type operator() (global_attribute const& attr) const { - auto itr = attributes_.find(attr.name); - if (itr != attributes_.end()) + auto itr = attrs_.find(attr.name); + if (itr != attrs_.end()) { return itr->second; } @@ -129,7 +129,7 @@ struct evaluate_expression return value_type(val); } - Attributes const& attributes_; + Attributes const& attrs_; }; template @@ -221,7 +221,7 @@ struct evaluate_expression struct assign_value { template - static void apply(symbolizer_base::value_type & val, expression_ptr const& expr, Attributes const& attributes, property_types target ) + static void apply(symbolizer_base::value_type & val, expression_ptr const& expr, Attributes const& attrs, property_types target ) { switch (target) @@ -230,24 +230,24 @@ struct assign_value { // evaluate expression as a string then parse as css color std::string str = util::apply_visitor(mapnik::evaluate_expression(attributes),*expr).to_string(); + Attributes>(attrs),*expr).to_string(); try { val = parse_color(str); } catch (...) { val = color(0,0,0);} break; } case property_types::target_double: { - val = util::apply_visitor(mapnik::evaluate_expression(attributes),*expr).to_double(); + val = util::apply_visitor(mapnik::evaluate_expression(attrs),*expr).to_double(); break; } case property_types::target_integer: { - val = util::apply_visitor(mapnik::evaluate_expression(attributes),*expr).to_int(); + val = util::apply_visitor(mapnik::evaluate_expression(attrs),*expr).to_int(); break; } case property_types::target_bool: { - val = util::apply_visitor(mapnik::evaluate_expression(attributes),*expr).to_bool(); + val = util::apply_visitor(mapnik::evaluate_expression(attrs),*expr).to_bool(); break; } default: // no-op @@ -276,14 +276,14 @@ struct evaluate_global_attributes : util::noncopyable template struct evaluator { - evaluator(symbolizer_base::cont_type::value_type & prop, Attributes const& attributes) + evaluator(symbolizer_base::cont_type::value_type & prop, Attributes const& attrs) : prop_(prop), - attributes_(attributes) {} + attrs_(attrs) {} void operator() (expression_ptr const& expr) const { auto const& meta = get_meta(prop_.first); - assign_value::apply(prop_.second, expr, attributes_, std::get<2>(meta)); + assign_value::apply(prop_.second, expr, attrs_, std::get<2>(meta)); } template @@ -292,28 +292,28 @@ struct evaluate_global_attributes : util::noncopyable // no-op } symbolizer_base::cont_type::value_type & prop_; - Attributes const& attributes_; + Attributes const& attrs_; }; template struct extract_symbolizer { - extract_symbolizer(Attributes const& attributes) - : attributes_(attributes) {} + extract_symbolizer(Attributes const& attrs) + : attrs_(attrs) {} template void operator() (Symbolizer & sym) const { for (auto & prop : sym.properties) { - util::apply_visitor(evaluator(prop, attributes_), prop.second); + util::apply_visitor(evaluator(prop, attrs_), prop.second); } } - Attributes const& attributes_; + Attributes const& attrs_; }; template - static void apply(Map & m, Attributes const& attributes) + static void apply(Map & m, Attributes const& attrs) { for ( auto & val : m.styles() ) { @@ -321,7 +321,7 @@ struct evaluate_global_attributes : util::noncopyable { for (auto & sym : rule) { - util::apply_visitor(extract_symbolizer(attributes), sym); + util::apply_visitor(extract_symbolizer(attrs), sym); } } } diff --git a/include/mapnik/expression.hpp b/include/mapnik/expression.hpp index 7b9ca59e7..7b8f0c4f8 100644 --- a/include/mapnik/expression.hpp +++ b/include/mapnik/expression.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 diff --git a/include/mapnik/expression_evaluator.hpp b/include/mapnik/expression_evaluator.hpp index 58b34486e..8b87a64e1 100644 --- a/include/mapnik/expression_evaluator.hpp +++ b/include/mapnik/expression_evaluator.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #include #include diff --git a/include/mapnik/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp deleted file mode 100644 index ad35589bb..000000000 --- a/include/mapnik/expression_grammar.hpp +++ /dev/null @@ -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 -#include -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik -{ -namespace qi = boost::spirit::qi; -namespace standard_wide = boost::spirit::standard_wide; -using standard_wide::space_type; - -template -struct integer_parser -{ - using type = qi::int_parser; -}; - -struct unary_function_types : qi::symbols -{ - unary_function_types(); -}; - -struct binary_function_types : qi::symbols -{ - binary_function_types(); -}; - - -#ifdef __GNUC__ -template -struct MAPNIK_DECL expression_grammar : qi::grammar -#else -template -struct expression_grammar : qi::grammar -#endif -{ - using rule_type = qi::rule; - - explicit expression_grammar(std::string const& encoding = "utf-8"); - - qi::real_parser > strict_double; - typename integer_parser::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 unary_function_expr; - qi::rule binary_function_expr; - qi::rule regex_match_expr; - qi::rule, space_type> regex_replace_expr; - qi::rule attr; - qi::rule global_attr; - qi::rule > quoted_ustring; - qi::rule unquoted_ustring; - qi::rule ustring; - - qi::symbols unesc_char; - qi::rule quote_char; - qi::symbols constant; - unary_function_types unary_func_type; - binary_function_types binary_func_type; - -}; - -} // namespace - -#endif // MAPNIK_EXPRESSIONS_GRAMMAR_HPP diff --git a/include/mapnik/expression_grammar_impl.hpp b/include/mapnik/expression_grammar_impl.hpp deleted file mode 100644 index ad28f0135..000000000 --- a/include/mapnik/expression_grammar_impl.hpp +++ /dev/null @@ -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 -#include -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#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 - 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 - 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 -expr_node regex_match_impl::operator() (T0 & node, T1 const& pattern) const -{ - return regex_match_node(tr_,node,pattern); -} - -template -expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const& format) const -{ - return regex_replace_node(tr_,node,pattern,format); -} - -template -expression_grammar::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 = unicode_impl(tr_); - boost::phoenix::function regex_match = regex_match_impl(tr_); - boost::phoenix::function 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(_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(), - _val = construct(_1))] - | global_attr [_val = construct( _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_('-'))]; - -} - -} diff --git a/include/mapnik/expression_grammar_x3.hpp b/include/mapnik/expression_grammar_x3.hpp new file mode 100644 index 000000000..ae3660c4f --- /dev/null +++ b/include/mapnik/expression_grammar_x3.hpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP +#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#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; + +BOOST_SPIRIT_DECLARE(expression_grammar_type); + +}} + + +namespace mapnik +{ +grammar::expression_grammar_type const& expression_grammar(); +} + + +#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP diff --git a/include/mapnik/expression_grammar_x3_config.hpp b/include/mapnik/expression_grammar_x3_config.hpp new file mode 100644 index 000000000..6d79b3b82 --- /dev/null +++ b/include/mapnik/expression_grammar_x3_config.hpp @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * 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_CONFIG_HPP +#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP + +#include +#include +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using phrase_context_type = x3::phrase_parse_context::type; + +// define combined context +using context_type = x3::with_context const, + phrase_context_type>::type; + +}} + +#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP diff --git a/include/mapnik/expression_grammar_x3_def.hpp b/include/mapnik/expression_grammar_x3_def.hpp new file mode 100644 index 000000000..a7efe6173 --- /dev/null +++ b/include/mapnik/expression_grammar_x3_def.hpp @@ -0,0 +1,456 @@ +/***************************************************************************** + * + * 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 +#include +#include +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#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; + x3::uint_parser const hex2 {}; + + namespace { + auto const& escaped_unicode = json::grammar::escaped_unicode; + } + + auto append = [](auto const& ctx) + { + _val(ctx) += _attr(ctx); + }; + + auto do_assign = [] (auto const& ctx) + { + _val(ctx) = std::move(_attr(ctx)); + }; + + auto do_negate = [] (auto const& ctx) + { + _val(ctx) = std::move(unary_node(_attr(ctx))); + }; + + auto do_attribute = [] (auto const& ctx) + { + auto & attr = _attr(ctx); + if (attr == "mapnik::geometry_type") + { + _val(ctx) = std::move(geometry_type_attribute()); + } + else + { + _val(ctx) = std::move(attribute(attr)); + } + }; + + auto do_global_attribute = [] (auto const& ctx) + { + _val(ctx) = std::move(global_attribute(_attr(ctx))); + }; + + auto do_add = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_subt = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_mult = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_div = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_mod = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_unicode = [] (auto const& ctx) + { + auto & tr = x3::get(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 node(_attr(ctx)); + _val(ctx) = std::move(node); + }; + + auto do_and = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_or = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_equal = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_not_equal = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_less = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_less_equal = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_greater = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_greater_equal = [] (auto const& ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + +// regex + auto do_regex_match = [] (auto const& ctx) + { + auto const& tr = x3::get(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(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(); +// mapnik::value_double + auto const mapnik_double = x3::real_parser>(); +// mapnik::value_bool + struct boolean_ : x3::symbols + { + boolean_() + { + add + ("true", true) + ("false", false) + ; + } + } boolean; + + struct floating_point_constants : x3::symbols + { + 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_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_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 + { + geometry_types_() + { + add + ("point", 1) + ("linestring", 2) + ("polygon",3) + ("collection",4) + ; + } + } geometry_type; + + struct unesc_chars_ : x3::symbols + { + 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 const logical_expression("logical expression"); + x3::rule const not_expression("not expression"); + x3::rule const conditional_expression("conditional expression"); + x3::rule const equality_expression("equality expression"); + x3::rule const relational_expression("relational expression"); + x3::rule const additive_expression("additive expression"); + x3::rule const multiplicative_expression("multiplicative expression"); + x3::rule const unary_func_expression("unary function expression"); + x3::rule const binary_func_expression("binary function expression"); + x3::rule const unary_expression("unary expression"); + x3::rule const primary_expression("primary expression"); + x3::rule const regex_match_expression("regex match expression"); + x3::rule > const regex_replace_expression("regex replace expression"); + + // strings + auto const single_quoted_string = x3::rule {} = lit('\'') + >> no_skip[*(unesc_char[append] + | + //(lit('\\') > escaped_unicode[append]) // FIXME (!) + //| + (~char_('\''))[append])] > lit('\''); + + auto const double_quoted_string = x3::rule {} = lit('"') + >> no_skip[*(unesc_char[append] + | + (lit('\\') > escaped_unicode[append]) + | + (~char_('"'))[append])] > lit('"'); + + auto const quoted_string = x3::rule {} = single_quoted_string | double_quoted_string; + + auto const unquoted_ustring = x3::rule {} = 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 {} = lexeme[lit('@') > char_("a-zA-Z_") > *char_("a-zA-Z0-9_")]; + + 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] + | + 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 diff --git a/include/mapnik/expression_node.hpp b/include/mapnik/expression_node.hpp index 6fdad8f5f..9823fd05e 100644 --- a/include/mapnik/expression_node.hpp +++ b/include/mapnik/expression_node.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 @@ -24,7 +24,7 @@ #define MAPNIK_EXPRESSION_NODE_HPP // mapnik -#include +#include #include #include #include @@ -59,6 +59,9 @@ template <> struct make_op { using type = std::logica template 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 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(expr); -} - -inline expr_node & operator += ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator -= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator *= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator /= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator %= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator < ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator <= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator > ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator >= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator == ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator != ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator ! (expr_node & expr) -{ - return expr = unary_node(expr); -} - -inline expr_node & operator && ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator || ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - } diff --git a/include/mapnik/expression_node_types.hpp b/include/mapnik/expression_node_types.hpp index 371274a4e..2db430486 100644 --- a/include/mapnik/expression_node_types.hpp +++ b/include/mapnik/expression_node_types.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include namespace mapnik diff --git a/include/mapnik/expression_string.hpp b/include/mapnik/expression_string.hpp index 6efc07e81..0a8a171da 100644 --- a/include/mapnik/expression_string.hpp +++ b/include/mapnik/expression_string.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 diff --git a/include/mapnik/extend_converter.hpp b/include/mapnik/extend_converter.hpp new file mode 100644 index 000000000..a7ac187eb --- /dev/null +++ b/include/mapnik/extend_converter.hpp @@ -0,0 +1,232 @@ +/***************************************************************************** + * + * 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_EXTEND_CONVERTER_HPP +#define MAPNIK_EXTEND_CONVERTER_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#pragma GCC diagnostic pop + +// stl +#include + +namespace mapnik +{ + +namespace detail +{ + +namespace msm = boost::msm; +namespace mpl = boost::mpl; +using namespace msm::front; + +template +T extend(T const & v1, T const & v2, double length) +{ + double dx = v2.x - v1.x; + double dy = v2.y - v1.y; + double l12 = std::sqrt(dx * dx + dy * dy); + double coef = 1.0 + length / l12; + return vertex2d(v1.x + dx * coef, + v1.y + dy * coef, v2.cmd); +} + +namespace events +{ + struct vertex_event + { + vertex_event(vertex2d const & vertex) : vertex(vertex) { } + vertex2d const & vertex; + }; + + struct move_to : vertex_event { using vertex_event::vertex_event; }; + struct line_to : vertex_event { using vertex_event::vertex_event; }; + struct close : vertex_event { using vertex_event::vertex_event; }; + struct end : vertex_event { using vertex_event::vertex_event; }; +} + +namespace actions +{ + struct store + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.v2 = m.v1; + m.v1 = e.vertex; + m.output = boost::none; + } + }; + + struct output + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.output = e.vertex; + } + }; + + struct store_and_output + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.v2 = m.v1; + m.v1 = e.vertex; + m.output = m.v2; + } + }; + + struct output_begin + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.v2 = m.v1; + m.v1 = e.vertex; + m.output = extend(m.v1, m.v2, m.extend_length); + } + }; + + struct output_end + { + template + void operator()(EVT const & e, FSM & m, SourceState&, TargetState&) + { + m.output = extend(m.v2, m.v1, m.extend_length); + m.v1 = e.vertex; + } + }; +} + +struct extender_def : public msm::front::state_machine_def +{ + using no_exception_thrown = int; + using no_message_queue = int; + + struct initial : public msm::front::state<> { }; + struct vertex_one : public msm::front::state<> { }; + struct vertex_two : public msm::front::state<> { }; + struct end : public msm::front::state<> { }; + + using initial_state = initial; + + struct transition_table : mpl::vector< + // Start Event Next Action Guard + // +------------+-----------------+------------+--------------------+------+ + Row < initial , events::move_to , vertex_one , actions::store >, + Row < initial , events::line_to , vertex_one , actions::store >, + Row < initial , events::close , initial >, + Row < initial , events::end , end , actions::output >, + Row < vertex_one , events::move_to , vertex_one , actions::store_and_output >, + Row < vertex_one , events::line_to , vertex_two , actions::output_begin >, + Row < vertex_one , events::close , initial , actions::store_and_output >, + Row < vertex_one , events::end , end , actions::store_and_output >, + Row < vertex_two , events::move_to , vertex_one , actions::output_end >, + Row < vertex_two , events::line_to , vertex_two , actions::store_and_output >, + Row < vertex_two , events::close , initial , actions::output_end >, + Row < vertex_two , events::end , end , actions::output_end >, + Row < end , events::end , end , actions::output > + > {}; + + extender_def(double extend_length) + : extend_length(extend_length) + { + } + + boost::optional output; + vertex2d v1, v2; + double extend_length; +}; + +using extender = msm::back::state_machine; + +} + +template +struct extend_converter +{ + extend_converter(Geometry & geom) + : extend_converter(geom, 0) + {} + + extend_converter(Geometry & geom, double extend) + : geom_(geom), extender_(extend) + {} + + void set_extend(double extend) + { + extender_.extend_length = extend; + } + + unsigned vertex(double * x, double * y) + { + using namespace detail; + vertex2d v; + do + { + v.cmd = geom_.vertex(&v.x, &v.y); + switch (v.cmd) + { + case SEG_MOVETO: + extender_.process_event(events::move_to(v)); + break; + case SEG_LINETO: + extender_.process_event(events::line_to(v)); + break; + case SEG_CLOSE: + extender_.process_event(events::close(v)); + break; + case SEG_END: + extender_.process_event(events::end(v)); + break; + } + } while(!extender_.output); + + vertex2d const & output = *extender_.output; + *x = output.x; + *y = output.y; + return output.cmd; + } + + void rewind(unsigned) + { + geom_.rewind(0); + extender_.start(); + } + +private: + Geometry & geom_; + detail::extender extender_; +}; + +} + +#endif // MAPNIK_EXTEND_CONVERTER_HPP diff --git a/include/mapnik/factory.hpp b/include/mapnik/factory.hpp index 81f261320..69f62b8bf 100644 --- a/include/mapnik/factory.hpp +++ b/include/mapnik/factory.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 diff --git a/include/mapnik/feature.hpp b/include/mapnik/feature.hpp index 2812d0b3d..657cc906f 100644 --- a/include/mapnik/feature.hpp +++ b/include/mapnik/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 @@ -25,11 +25,11 @@ // mapnik #include -#include +#include #include -#include +#include #include -#include +#include // #include #include @@ -105,7 +105,7 @@ public: : id_(_id), ctx_(ctx), data_(ctx_->mapping_.size()), - geom_(geometry::geometry_empty()), + geom_(geometry::geometry_empty()), raster_() {} inline mapnik::value_integer id() const { return id_;} @@ -208,6 +208,11 @@ public: return geom_; } + inline geometry::geometry & get_geometry() + { + return geom_; + } + inline box2d envelope() const { return mapnik::geometry::envelope(geom_); diff --git a/include/mapnik/feature_factory.hpp b/include/mapnik/feature_factory.hpp index c4a4d560e..4388ac1e7 100644 --- a/include/mapnik/feature_factory.hpp +++ b/include/mapnik/feature_factory.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include // boost //#include diff --git a/include/mapnik/feature_kv_iterator.hpp b/include/mapnik/feature_kv_iterator.hpp index 1def2e7c2..eb3402b37 100644 --- a/include/mapnik/feature_kv_iterator.hpp +++ b/include/mapnik/feature_kv_iterator.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 diff --git a/include/mapnik/feature_layer_desc.hpp b/include/mapnik/feature_layer_desc.hpp index cd69d831f..d8fcc4990 100644 --- a/include/mapnik/feature_layer_desc.hpp +++ b/include/mapnik/feature_layer_desc.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 diff --git a/include/mapnik/feature_style_processor.hpp b/include/mapnik/feature_style_processor.hpp index c0ba4f383..4ae4fa9c0 100644 --- a/include/mapnik/feature_style_processor.hpp +++ b/include/mapnik/feature_style_processor.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 @@ -24,12 +24,13 @@ #define MAPNIK_FEATURE_STYLE_PROCESSOR_HPP // mapnik -#include +#include #include #include #include // stl +#include #include #include @@ -93,6 +94,12 @@ private: featureset_ptr features, proj_transform const& prj_trans); + void prepare_layers(layer_rendering_material & parent_mat, + std::vector const & layers, + feature_style_context_map & ctx_map, + Processor & p, + double scale_denom); + /*! * \brief prepare features for rendering asynchronously. */ @@ -111,6 +118,7 @@ private: * \brief render features list queued when they are available. */ void render_material(layer_rendering_material const & mat, Processor & p ); + void render_submaterials(layer_rendering_material const & mat, Processor & p); Map const& m_; }; diff --git a/include/mapnik/feature_style_processor_context.hpp b/include/mapnik/feature_style_processor_context.hpp index aca0c8f72..c1f1d7112 100644 --- a/include/mapnik/feature_style_processor_context.hpp +++ b/include/mapnik/feature_style_processor_context.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 diff --git a/include/mapnik/feature_style_processor_impl.hpp b/include/mapnik/feature_style_processor_impl.hpp index 2fea9d8b3..981595147 100644 --- a/include/mapnik/feature_style_processor_impl.hpp +++ b/include/mapnik/feature_style_processor_impl.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 @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -63,6 +63,7 @@ struct layer_rendering_material std::vector active_styles_; std::vector featureset_ptr_list_; std::vector rule_caches_; + std::vector materials_; layer_rendering_material(layer const& lay, projection const& dest) : @@ -84,6 +85,41 @@ feature_style_processor::feature_style_processor(Map const& m, double } } +template +void feature_style_processor::prepare_layers(layer_rendering_material & parent_mat, + std::vector const & layers, + feature_style_context_map & ctx_map, + Processor & p, + double scale_denom) +{ + for (layer const& lyr : layers) + { + if (lyr.visible(scale_denom)) + { + std::set names; + layer_rendering_material mat(lyr, parent_mat.proj0_); + + prepare_layer(mat, + ctx_map, + p, + m_.scale(), + scale_denom, + m_.width(), + m_.height(), + m_.get_current_extent(), + m_.buffer_size(), + names); + + // Store active material + if (!mat.active_styles_.empty()) + { + prepare_layers(mat, lyr.layers(), ctx_map, p, scale_denom); + parent_mat.materials_.emplace_back(std::move(mat)); + } + } + } +} + template void feature_style_processor::apply(double scale_denom) { @@ -101,44 +137,16 @@ void feature_style_processor::apply(double scale_denom) // in a second time, we fetch the results and // do the actual rendering - std::vector mat_list; - // Define processing context map used by datasources // implementing asynchronous queries feature_style_context_map ctx_map; - for ( layer const& lyr : m_.layers() ) + if (!m_.layers().empty()) { - if (lyr.visible(scale_denom)) - { - std::set names; - layer_rendering_material mat(lyr, proj); + layer_rendering_material root_mat(m_.layers().front(), proj); + prepare_layers(root_mat, m_.layers(), ctx_map, p, scale_denom); - prepare_layer(mat, - ctx_map, - p, - m_.scale(), - scale_denom, - m_.width(), - m_.height(), - m_.get_current_extent(), - m_.buffer_size(), - names); - - // Store active material - if (!mat.active_styles_.empty()) - { - mat_list.emplace_back(std::move(mat)); - } - } - } - - for ( layer_rendering_material const & mat : mat_list ) - { - if (!mat.active_styles_.empty()) - { - render_material(mat, p); - } + render_submaterials(root_mat, p); } p.end_map_processing(m_); @@ -201,9 +209,12 @@ void feature_style_processor::apply_to_layer(layer const& lay, buffer_size, names); + prepare_layers(mat, lay.layers(), ctx_map, p, scale_denom); + if (!mat.active_styles_.empty()) { render_material(mat,p); + render_submaterials(mat, p); } } @@ -368,10 +379,10 @@ void feature_style_processor::prepare_layer(layer_rendering_material continue; } - std::vector const& rules = style->get_rules(); + std::vector 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)) { @@ -441,10 +452,27 @@ void feature_style_processor::prepare_layer(layer_rendering_material } } +template +void feature_style_processor::render_submaterials(layer_rendering_material const & parent_mat, + Processor & p) +{ + for (layer_rendering_material const & mat : parent_mat.materials_) + { + if (!mat.active_styles_.empty()) + { + p.start_layer_processing(mat.lay_, mat.layer_ext2_); + + render_material(mat, p); + render_submaterials(mat, p); + + p.end_layer_processing(mat.lay_); + } + } +} template void feature_style_processor::render_material(layer_rendering_material const & mat, - Processor & p ) + Processor & p) { std::vector const & active_styles = mat.active_styles_; std::vector const & featureset_ptr_list = mat.featureset_ptr_list_; @@ -460,8 +488,6 @@ void feature_style_processor::render_material(layer_rendering_materia return; } - p.start_layer_processing(mat.lay_, mat.layer_ext2_); - layer const& lay = mat.lay_; std::vector const & rule_caches = mat.rule_caches_; @@ -555,7 +581,6 @@ void feature_style_processor::render_material(layer_rendering_materia ++i; } } - p.end_layer_processing(mat.lay_); } template diff --git a/include/mapnik/feature_type_style.hpp b/include/mapnik/feature_type_style.hpp index 9f9f1aec9..5341b2fdb 100644 --- a/include/mapnik/feature_type_style.hpp +++ b/include/mapnik/feature_type_style.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 diff --git a/include/mapnik/featureset.hpp b/include/mapnik/featureset.hpp index a6ad4e85d..579bf6ffe 100644 --- a/include/mapnik/featureset.hpp +++ b/include/mapnik/featureset.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 diff --git a/include/mapnik/filter_factory.hpp b/include/mapnik/filter_factory.hpp deleted file mode 100644 index 68d729a6c..000000000 --- a/include/mapnik/filter_factory.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// TODO - remove this file at mapnik 3.x -#ifdef _MSC_VER -#pragma NOTE("filter_factory.hpp" is now called "expression.hpp") -#else -#warning "filter_factory.hpp" is now called "expression.hpp" -#endif - -#include diff --git a/include/mapnik/filter_featureset.hpp b/include/mapnik/filter_featureset.hpp index ee3fa4087..a4bf5d299 100644 --- a/include/mapnik/filter_featureset.hpp +++ b/include/mapnik/filter_featureset.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 diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index 73227cdbf..a4ca09642 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.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 diff --git a/include/mapnik/font_set.hpp b/include/mapnik/font_set.hpp index 5df8e35df..6e1366559 100644 --- a/include/mapnik/font_set.hpp +++ b/include/mapnik/font_set.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 diff --git a/include/mapnik/function_call.hpp b/include/mapnik/function_call.hpp index f50829bd6..68f102129 100644 --- a/include/mapnik/function_call.hpp +++ b/include/mapnik/function_call.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 @@ -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()); } }; diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index 7dbe51ff4..da2b0f4e1 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.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 @@ -24,10 +24,10 @@ #define MAPNIK_GEOM_UTIL_HPP // mapnik -#include +#include #include #include -#include +#include // stl #include #include diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 3f5d2aabd..eb0505a82 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.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 @@ -43,14 +43,10 @@ namespace mapnik { namespace geometry { template class Cont = std::vector> struct geometry_collection; -template -struct geometry_empty -{ - using coordinate_type = T; -}; +struct geometry_empty {}; template -using geometry_base = mapnik::util::variant, +using geometry_base = mapnik::util::variant, line_string, polygon, diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry/boost_adapters.hpp similarity index 66% rename from include/mapnik/geometry_adapters.hpp rename to include/mapnik/geometry/boost_adapters.hpp index 770cb630c..63f135aea 100644 --- a/include/mapnik/geometry_adapters.hpp +++ b/include/mapnik/geometry/boost_adapters.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2017 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,8 +20,9 @@ * *****************************************************************************/ -#ifndef MAPNIK_GEOMETRY_ADAPTERS_HPP -#define MAPNIK_GEOMETRY_ADAPTERS_HPP + +#ifndef MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP +#define MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP #include @@ -29,63 +30,77 @@ #pragma GCC diagnostic push #include #undef B0 -#include +#include #include #include -// NOTE: ideally we would not include all of boost/geometry here to save on compile time -// however we need to pull in for things to work -// and once we do that the compile time is == to just including boost/geometry.hpp -#include +#include #pragma GCC diagnostic pop -#include +// mapnik #include #include -#include -#include +#include -// register point -BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point, double, boost::geometry::cs::cartesian, x, y) -BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point, std::int64_t, boost::geometry::cs::cartesian, x, y) -// ring +BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::geometry::point, double, boost::geometry::cs::cartesian, x, y) +BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(mapnik::geometry::line_string) BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(mapnik::geometry::linear_ring) -// needed by box2d +// needed by box2d BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y) -namespace boost { +namespace mapnik { template -struct range_iterator > +struct interior_rings { - using type = typename mapnik::geometry::line_string::iterator; + using polygon_type = mapnik::geometry::polygon; + using iterator = typename polygon_type::iterator; + using const_iterator = typename polygon_type::const_iterator; + using value_type = typename polygon_type::value_type; + + interior_rings(polygon_type & poly) + : poly_(poly) {} + + iterator begin() + { + auto itr = poly_.begin(); + std::advance(itr, 1); + return itr; + } + + iterator end() { return poly_.end();} + const_iterator begin() const + { + auto itr = poly_.begin(); + std::advance(itr, 1); + return itr; + } + + const_iterator end() const { return poly_.end();} + + void clear() + { + poly_.resize(1); + } + + void resize(std::size_t size) + { + poly_.resize(size + 1); + } + + std::size_t size() const + { + return poly_.empty() ? 0 : poly_.size() - 1; + } + + void push_back(value_type const& val) { poly_.push_back(val); } + value_type& back() { return poly_.back(); } + value_type const& back() const { return poly_.back(); } + polygon_type & poly_; }; -template -struct range_const_iterator > -{ - using type = typename mapnik::geometry::line_string::const_iterator; -}; +} // ns mapnik -template -inline typename mapnik::geometry::line_string::iterator -range_begin(mapnik::geometry::line_string & line) {return line.begin();} +namespace boost { namespace geometry { namespace traits { -template -inline typename mapnik::geometry::line_string::iterator -range_end(mapnik::geometry::line_string & line) {return line.end();} - -template -inline typename mapnik::geometry::line_string::const_iterator -range_begin(mapnik::geometry::line_string const& line) {return line.begin();} - -template -inline typename mapnik::geometry::line_string::const_iterator -range_end(mapnik::geometry::line_string const& line) {return line.end();} - -namespace geometry { - -namespace traits { - -// register mapnik::box2d template<> struct tag > { using type = box_tag; }; template<> struct point_type > { using type = mapnik::coord2d; }; @@ -121,14 +136,6 @@ struct indexed_access, max_corner, 1> static inline void set(mapnik::box2d &b , ct const& value) { b.set_maxy(value); } }; -// mapnik::geometry::line_string -template -struct tag > -{ - using type = linestring_tag; -}; - -// mapnik::geometry::polygon template struct tag > { @@ -176,16 +183,15 @@ struct ring_mutable_type > template struct interior_const_type > { - using type = typename mapnik::geometry::polygon::interior_rings const&; + using type = typename mapnik::interior_rings const; }; template struct interior_mutable_type > { - using type = typename mapnik::geometry::polygon::interior_rings& ; + using type = typename mapnik::interior_rings ; }; -// exterior template struct exterior_ring > { @@ -193,13 +199,13 @@ struct exterior_ring > using ring_mutable_type = typename ring_mutable_type >::type; static ring_mutable_type get(mapnik::geometry::polygon & p) { - if (p.empty()) throw std::runtime_error("ring must be initialized 1"); + if (p.empty()) p.resize(1); return p[0]; } static ring_const_type get(mapnik::geometry::polygon const& p) { - if (p.empty()) throw std::runtime_error("ring must be initialized 2"); + if (p.empty()) throw std::runtime_error("Exterior ring must be initialized!"); return p[0]; } }; @@ -212,16 +218,15 @@ struct interior_rings > static interior_const_type get(mapnik::geometry::polygon const& p) { - return p.interior(); + return mapnik::interior_rings(const_cast&>(p)); } static interior_mutable_type get(mapnik::geometry::polygon& p) { - return p.interior(); + return mapnik::interior_rings(p); } }; }}} - -#endif //MAPNIK_GEOMETRY_ADAPTERS_HPP +#endif //MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP diff --git a/include/mapnik/geometry/boost_spirit_karma_adapter.hpp b/include/mapnik/geometry/boost_spirit_karma_adapter.hpp new file mode 100644 index 000000000..8182e6e57 --- /dev/null +++ b/include/mapnik/geometry/boost_spirit_karma_adapter.hpp @@ -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 + +namespace boost { using mapbox::util::get; } + +#include +#include + +namespace boost { namespace spirit { namespace traits +{ +template <> +struct not_is_variant, karma::domain> + : mpl::false_ +{}; + +template <> +struct not_is_variant, karma::domain> + : mpl::false_ +{}; + +template <> +struct variant_which< mapnik::geometry::geometry > +{ + static int call(mapnik::geometry::geometry const& v) + { + return v.which(); + } +}; + +template <> +struct variant_which< mapnik::geometry::geometry > +{ + static int call(mapnik::geometry::geometry const& v) + { + return v.which(); + } +}; + +namespace detail { + +template +struct has_type; + +template +struct has_type> : std::false_type {}; + +template +struct has_type> : has_type> {}; + +template +struct has_type> : std::true_type {}; + +template +struct index; + +template +struct index> +{ + static const std::size_t value = 0; +}; + +template +struct index> +{ + static const std::size_t value = 1 + index>::value; +}; + +} + +template +struct compute_compatible_component_variant, Expected> + : detail::has_type::types> +{ + using compatible_type = Expected; + static bool is_compatible(int index) + { + return (index == detail::index::types>::value); + } +}; + +template +struct compute_compatible_component_variant, Expected> + : detail::has_type::types> +{ + using compatible_type = Expected; + static bool is_compatible(int index) + { + return (index == detail::index::types>::value); + } +}; + +}}} + + + +#endif //MAPNIK_BOOST_SPIRIT_KARMA_ADAPTER_HPP diff --git a/include/mapnik/box2d.hpp b/include/mapnik/geometry/box2d.hpp similarity index 98% rename from include/mapnik/box2d.hpp rename to include/mapnik/geometry/box2d.hpp index 267120111..f9f59ba28 100644 --- a/include/mapnik/box2d.hpp +++ b/include/mapnik/geometry/box2d.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 @@ -51,11 +51,11 @@ template class MAPNIK_DECL box2d public: using value_type = T; using box2d_type = box2d; -private: T minx_; T miny_; T maxx_; T maxy_; +private: friend inline void swap(box2d_type & lhs, box2d_type & rhs) { using std::swap; @@ -116,6 +116,7 @@ public: bool valid() const; void move(T x, T y); std::string to_string() const; + T area() const; // define some operators box2d_type& operator+=(box2d_type const& other); diff --git a/include/mapnik/box2d_impl.hpp b/include/mapnik/geometry/box2d_impl.hpp similarity index 89% rename from include/mapnik/box2d_impl.hpp rename to include/mapnik/geometry/box2d_impl.hpp index 7f3e9d1e7..dccc8d270 100644 --- a/include/mapnik/box2d_impl.hpp +++ b/include/mapnik/geometry/box2d_impl.hpp @@ -21,7 +21,7 @@ *****************************************************************************/ // mapnik -#include +#include #include // stl @@ -33,24 +33,35 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include +#include #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(val))) - (T, T, obj.miny(), obj.set_miny(mapnik::safe_cast(val))) - (T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast(val))) - (T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast(val)))) + (T, minx_), + (T, miny_), + (T, maxx_), + (T, maxy_)) -namespace mapnik +namespace mapnik { namespace detail { namespace { + +template +struct assign { + template + void operator() (Context & ctx) const + { + _val(ctx) = safe_cast(_attr(ctx)); + } +}; +} // anonymous +} // detail + template box2d::box2d() :minx_( std::numeric_limits::max()), @@ -61,13 +72,13 @@ box2d::box2d() template box2d::box2d(T minx,T miny,T maxx,T maxy) { - init(minx,miny,maxx,maxy); + init(minx, miny, maxx, maxy); } template box2d::box2d(coord const& c0, coord const& c1) { - init(c0.x,c0.y,c1.x,c1.y); + init(c0.x, c0.y, c1.x, c1.y); } template @@ -350,12 +361,15 @@ void box2d::pad(T padding) template bool box2d::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()] >> -lit(',') >> + double_[detail::assign()] >> -lit(',') >> + double_[detail::assign()] >> -lit(',') >> + double_[detail::assign()], space, *this); return r; @@ -393,6 +407,11 @@ std::string box2d::to_string() const return s.str(); } +template +T box2d::area() const +{ + return width() * height(); +} template box2d& box2d::operator+=(box2d const& other) diff --git a/include/mapnik/geometry_centroid.hpp b/include/mapnik/geometry/centroid.hpp similarity index 94% rename from include/mapnik/geometry_centroid.hpp rename to include/mapnik/geometry/centroid.hpp index c88588fba..3608d95ce 100644 --- a/include/mapnik/geometry_centroid.hpp +++ b/include/mapnik/geometry/centroid.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 @@ -24,10 +24,10 @@ #define MAPNIK_GEOMETRY_CENTROID_HPP #include -#include +#include #include -#include -#include +#include +#include namespace mapnik { namespace geometry { @@ -47,7 +47,7 @@ struct geometry_centroid return util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const&) const + result_type operator() (geometry_empty const&) const { return false; } diff --git a/include/mapnik/geometry_correct.hpp b/include/mapnik/geometry/correct.hpp similarity index 96% rename from include/mapnik/geometry_correct.hpp rename to include/mapnik/geometry/correct.hpp index 673250c0c..42bdf1826 100644 --- a/include/mapnik/geometry_correct.hpp +++ b/include/mapnik/geometry/correct.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 @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_CORRECT_HPP #include -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/geometry_envelope.hpp b/include/mapnik/geometry/envelope.hpp similarity index 94% rename from include/mapnik/geometry_envelope.hpp rename to include/mapnik/geometry/envelope.hpp index 1621fd22f..d42d517a7 100644 --- a/include/mapnik/geometry_envelope.hpp +++ b/include/mapnik/geometry/envelope.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 @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_ENVELOPE_HPP #include -#include +#include namespace mapnik { namespace geometry { diff --git a/include/mapnik/geometry_envelope_impl.hpp b/include/mapnik/geometry/envelope_impl.hpp similarity index 94% rename from include/mapnik/geometry_envelope_impl.hpp rename to include/mapnik/geometry/envelope_impl.hpp index 692481131..b6cf47403 100644 --- a/include/mapnik/geometry_envelope_impl.hpp +++ b/include/mapnik/geometry/envelope_impl.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,9 +20,9 @@ * *****************************************************************************/ -#include +#include #include -#include +#include namespace mapnik { namespace geometry { @@ -44,7 +44,7 @@ struct geometry_envelope return mapnik::util::apply_visitor(*this, geom); } - void operator() (mapnik::geometry::geometry_empty const&) const {} + void operator() (mapnik::geometry::geometry_empty const&) const {} void operator() (mapnik::geometry::point const& pt) const { diff --git a/include/mapnik/geometry_fusion_adapted.hpp b/include/mapnik/geometry/fusion_adapted.hpp similarity index 98% rename from include/mapnik/geometry_fusion_adapted.hpp rename to include/mapnik/geometry/fusion_adapted.hpp index 8430d4f48..3abdb478c 100644 --- a/include/mapnik/geometry_fusion_adapted.hpp +++ b/include/mapnik/geometry/fusion_adapted.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 diff --git a/include/mapnik/geometry_type.hpp b/include/mapnik/geometry/geometry_type.hpp similarity index 94% rename from include/mapnik/geometry_type.hpp rename to include/mapnik/geometry/geometry_type.hpp index c0055c5b4..a5a4658a5 100644 --- a/include/mapnik/geometry_type.hpp +++ b/include/mapnik/geometry/geometry_type.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include namespace mapnik { namespace geometry { namespace detail { @@ -37,7 +37,7 @@ struct geometry_type return mapnik::util::apply_visitor(*this, geom); } - mapnik::geometry::geometry_types operator() (geometry_empty const& ) const + mapnik::geometry::geometry_types operator() (geometry_empty const& ) const { return mapnik::geometry::geometry_types::Unknown; } diff --git a/include/mapnik/geometry_types.hpp b/include/mapnik/geometry/geometry_types.hpp similarity index 97% rename from include/mapnik/geometry_types.hpp rename to include/mapnik/geometry/geometry_types.hpp index 8c4d67722..a4f00c287 100644 --- a/include/mapnik/geometry_types.hpp +++ b/include/mapnik/geometry/geometry_types.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 diff --git a/include/mapnik/geometry/is_empty.hpp b/include/mapnik/geometry/is_empty.hpp new file mode 100644 index 000000000..206fb185c --- /dev/null +++ b/include/mapnik/geometry/is_empty.hpp @@ -0,0 +1,173 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_GEOMETRY_IS_EMPTY_HPP +#define MAPNIK_GEOMETRY_IS_EMPTY_HPP + +#include + +namespace mapnik { namespace geometry { + +namespace detail { + +struct geometry_is_empty +{ + bool operator() (mapnik::geometry::geometry const& geom) const + { + return mapnik::util::apply_visitor(*this, geom); + } + + bool operator() (mapnik::geometry::point const&) const + { + return false; + } + + bool operator() (mapnik::geometry::line_string const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::polygon const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::multi_point const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::multi_line_string const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::multi_polygon const& geom) const + { + return geom.empty(); + } + + bool operator() (mapnik::geometry::geometry_collection const& geom) const + { + return geom.empty(); + } + + template + bool operator() (T const&) const + { + return true; + } + +}; + +struct geometry_has_empty +{ + bool operator() (mapnik::geometry::geometry const& geom) const + { + return mapnik::util::apply_visitor(*this, geom); + } + + bool operator() (mapnik::geometry::geometry_empty const&) const + { + return false; + } + + bool operator() (mapnik::geometry::point const&) const + { + return false; + } + + bool operator() (mapnik::geometry::line_string const&) const + { + return false; + } + + bool operator() (mapnik::geometry::polygon const&) const + { + return false; + } + + bool operator() (mapnik::geometry::multi_point const&) const + { + return false; + } + + bool operator() (mapnik::geometry::multi_line_string const& geom) const + { + return test_multigeometry(geom); + } + + bool operator() (mapnik::geometry::multi_polygon const& geom) const + { + return test_multigeometry(geom); + } + + bool operator() (mapnik::geometry::geometry_collection const& geom) const + { + for (auto const & item : geom) + { + if (geometry_is_empty()(item) || (*this)(item)) + { + return true; + } + } + return false; + } + + template + bool operator() (T const&) const + { + return true; + } + +private: + template + bool test_multigeometry(T const & geom) const + { + for (auto const & item : geom) + { + if (item.empty()) + { + return true; + } + } + return false; + } +}; + +} + +template +inline bool is_empty(GeomType const& geom) +{ + return detail::geometry_is_empty()(geom); +} + +template +inline bool has_empty(GeomType const& geom) +{ + return detail::geometry_has_empty()(geom); +} + +}} + +#endif // MAPNIK_GEOMETRY_IS_EMPTY_HPP diff --git a/include/mapnik/geometry_is_simple.hpp b/include/mapnik/geometry/is_simple.hpp similarity index 88% rename from include/mapnik/geometry_is_simple.hpp rename to include/mapnik/geometry/is_simple.hpp index 68953ca1f..c8df58e2d 100644 --- a/include/mapnik/geometry_is_simple.hpp +++ b/include/mapnik/geometry/is_simple.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 @@ -29,30 +29,31 @@ #if BOOST_VERSION >= 105600 #include -#include +#include #include namespace mapnik { namespace geometry { namespace detail { -template struct geometry_is_simple { using result_type = bool; + template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { // An empty geometry has no anomalous geometric points, such as self intersection or self tangency. // Therefore, we will return true return true; } + template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -62,11 +63,12 @@ struct geometry_is_simple return true; } + template result_type operator() (point const& pt) const { return boost::geometry::is_simple(pt); } - + template result_type operator() (line_string const& line) const { if (line.empty()) @@ -78,12 +80,12 @@ struct geometry_is_simple } return boost::geometry::is_simple(line); } - + template result_type operator() (polygon const& poly) const { - return poly.empty() ? true : boost::geometry::is_simple(poly); + return boost::geometry::is_simple(poly); } - + template result_type operator() (multi_point const& multi_pt) const { if (multi_pt.empty()) @@ -94,7 +96,7 @@ struct geometry_is_simple } return boost::geometry::is_simple(multi_pt); } - + template result_type operator() (multi_line_string const& multi_line) const { if (multi_line.empty()) @@ -109,7 +111,7 @@ struct geometry_is_simple } return true; } - + template result_type operator() (multi_polygon const& multi_poly) const { if (multi_poly.empty()) @@ -132,14 +134,13 @@ struct geometry_is_simple template inline bool is_simple(T const& geom) { - using coordinate_type = typename T::coordinate_type; - return detail::geometry_is_simple() (geom); + return detail::geometry_is_simple() (geom); } template inline bool is_simple(mapnik::geometry::geometry const& geom) { - return util::apply_visitor(detail::geometry_is_simple(), geom); + return util::apply_visitor(detail::geometry_is_simple(), geom); } }} diff --git a/include/mapnik/geometry_is_valid.hpp b/include/mapnik/geometry/is_valid.hpp similarity index 82% rename from include/mapnik/geometry_is_valid.hpp rename to include/mapnik/geometry/is_valid.hpp index fbaef63c4..9fb17b192 100644 --- a/include/mapnik/geometry_is_valid.hpp +++ b/include/mapnik/geometry/is_valid.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 @@ -29,7 +29,7 @@ #if BOOST_VERSION >= 105800 #include -#include +#include #include #include @@ -37,21 +37,22 @@ namespace mapnik { namespace geometry { namespace detail { -template struct geometry_is_valid { using result_type = bool; + template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { return true; } + template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -61,38 +62,43 @@ struct geometry_is_valid return true; } + template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt); } + template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line); } + template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly); } + template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt); } + template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line); } + template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly); } }; -template struct geometry_is_valid_reason { using result_type = bool; @@ -102,17 +108,19 @@ struct geometry_is_valid_reason geometry_is_valid_reason(boost::geometry::validity_failure_type & failure): failure_(failure) {} + template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { failure_ = boost::geometry::no_failure; return true; } + template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -122,38 +130,43 @@ struct geometry_is_valid_reason return true; } + template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt, failure_); } + template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line, failure_); } + template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly, failure_); } + template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt, failure_); } + template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line, failure_); } + template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly, failure_); } }; -template struct geometry_is_valid_string { using result_type = bool; @@ -163,17 +176,19 @@ struct geometry_is_valid_string geometry_is_valid_string(std::string & message): message_(message) {} + template result_type operator() (geometry const& geom) const { return mapnik::util::apply_visitor(*this, geom); } - result_type operator() (geometry_empty const& ) const + result_type operator() (geometry_empty const& ) const { message_ = "Geometry is valid"; return true; } + template result_type operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -183,78 +198,82 @@ struct geometry_is_valid_string return true; } + template result_type operator() (point const& pt) const { return boost::geometry::is_valid(pt, message_); } + template result_type operator() (line_string const& line) const { return boost::geometry::is_valid(line, message_); } + template result_type operator() (polygon const& poly) const { return boost::geometry::is_valid(poly, message_); } + template result_type operator() (multi_point const& multi_pt) const { return boost::geometry::is_valid(multi_pt, message_); } + template result_type operator() (multi_line_string const& multi_line) const { return boost::geometry::is_valid(multi_line, message_); } + template result_type operator() (multi_polygon const& multi_poly) const { return boost::geometry::is_valid(multi_poly, message_); } }; + } template inline bool is_valid(T const& geom) { - using coordinate_type = typename T::coordinate_type; - return detail::geometry_is_valid() (geom); + return detail::geometry_is_valid() (geom); } template inline bool is_valid(mapnik::geometry::geometry const& geom) { - return util::apply_visitor(detail::geometry_is_valid(), geom); + return util::apply_visitor(detail::geometry_is_valid(), geom); } template inline bool is_valid(T const& geom, boost::geometry::validity_failure_type & failure) { - using coordinate_type = typename T::coordinate_type; - return detail::geometry_is_valid_reason(failure) (geom); + return detail::geometry_is_valid_reason(failure) (geom); } template inline bool is_valid(mapnik::geometry::geometry const& geom, boost::geometry::validity_failure_type & failure) { - return util::apply_visitor(detail::geometry_is_valid_reason(failure), geom); + return util::apply_visitor(detail::geometry_is_valid_reason(failure), geom); } template inline bool is_valid(T const& geom, std::string & message) { - using coordinate_type = typename T::coordinate_type; - return detail::geometry_is_valid_string(message) (geom); + return detail::geometry_is_valid_string(message) (geom); } template inline bool is_valid(mapnik::geometry::geometry const& geom, std::string & message) { - return util::apply_visitor(detail::geometry_is_valid_string(message), geom); + return util::apply_visitor(detail::geometry_is_valid_string(message), geom); } }} diff --git a/include/mapnik/geometry/polygon.hpp b/include/mapnik/geometry/polygon.hpp index 0840fd000..efb65e60f 100644 --- a/include/mapnik/geometry/polygon.hpp +++ b/include/mapnik/geometry/polygon.hpp @@ -32,80 +32,7 @@ template using linear_ring = mapbox::geometry::linear_ring; template -struct polygon : mapbox::geometry::polygon -{ - using coordinate_type = T; - using base_type = mapbox::geometry::polygon; - using linear_ring_type = linear_ring; - struct interior_rings - { - using iterator = typename base_type::iterator; - using const_iterator = typename base_type::const_iterator; - using value_type = typename base_type::value_type; - interior_rings(polygon & poly) - : poly_(poly) {} - iterator begin() - { - auto itr = poly_.begin(); - std::advance(itr, 1); - return itr; - } - - iterator end() { return poly_.end();} - const_iterator begin() const - { - auto itr = poly_.begin(); - std::advance(itr, 1); - return itr; - } - const_iterator end() const { return poly_.end();} - - void clear() - { - poly_.resize(1); - } - - void resize(std::size_t size) - { - poly_.resize(size + 1); - } - - std::size_t size() const - { - return poly_.empty() ? 0 : poly_.size() - 1; - } - - void push_back(value_type const& val) { poly_.push_back(val); } - value_type& back() { return poly_.back(); } - value_type const& back() const { return poly_.back(); } - polygon & poly_; - }; - - polygon() - : base_type(), - interior_(*this) - { - //this->resize(1); // explicit exterior ring ? - } - - polygon(polygon && other) - : base_type(std::move(other)), - interior_(*this) {} - - polygon(polygon const& other) - : base_type(other), - interior_(*this) {} - - interior_rings const& interior() const - { - return interior_; - } - interior_rings & interior() - { - return interior_; - } - interior_rings interior_; -}; +using polygon = mapbox::geometry::polygon; }} diff --git a/include/mapnik/geometry_remove_empty.hpp b/include/mapnik/geometry/remove_empty.hpp similarity index 96% rename from include/mapnik/geometry_remove_empty.hpp rename to include/mapnik/geometry/remove_empty.hpp index de60d9869..7ae365235 100644 --- a/include/mapnik/geometry_remove_empty.hpp +++ b/include/mapnik/geometry/remove_empty.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 @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_REMOVE_EMPTY_HPP #include -#include +#include namespace mapnik { namespace geometry { diff --git a/include/mapnik/geometry_reprojection.hpp b/include/mapnik/geometry/reprojection.hpp similarity index 98% rename from include/mapnik/geometry_reprojection.hpp rename to include/mapnik/geometry/reprojection.hpp index 22a334e61..a8b82860b 100644 --- a/include/mapnik/geometry_reprojection.hpp +++ b/include/mapnik/geometry/reprojection.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 diff --git a/include/mapnik/geometry_reprojection_impl.hpp b/include/mapnik/geometry/reprojection_impl.hpp similarity index 95% rename from include/mapnik/geometry_reprojection_impl.hpp rename to include/mapnik/geometry/reprojection_impl.hpp index d76e84081..f4903613e 100644 --- a/include/mapnik/geometry_reprojection_impl.hpp +++ b/include/mapnik/geometry/reprojection_impl.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2017 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,10 +29,10 @@ namespace geometry { namespace detail { -template -geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &) +//template +geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &) { - return geometry_empty(); + return geometry_empty(); } template @@ -153,7 +153,7 @@ geometry_collection reproject_internal(geometry_collection const & c, proj { geometry new_g = reproject_copy(g, proj_trans, n_err); - if (!new_g.template is>()) + if (!new_g.template is()) { new_c.emplace_back(std::move(new_g)); } @@ -169,9 +169,9 @@ struct geom_reproj_copy_visitor : proj_trans_(proj_trans), n_err_(n_err) {} - geometry operator() (geometry_empty) const + geometry operator() (geometry_empty) const { - return geometry_empty(); + return geometry_empty(); } geometry operator() (point const& p) const @@ -280,8 +280,8 @@ struct geom_reproj_visitor { return mapnik::util::apply_visitor((*this), geom); } - template - bool operator() (geometry_empty &) const { return true; } + //template + bool operator() (geometry_empty &) const { return true; } template bool operator() (point & p) const diff --git a/include/mapnik/geometry_strategy.hpp b/include/mapnik/geometry/strategy.hpp similarity index 96% rename from include/mapnik/geometry_strategy.hpp rename to include/mapnik/geometry/strategy.hpp index cc4121e60..d71479072 100644 --- a/include/mapnik/geometry_strategy.hpp +++ b/include/mapnik/geometry/strategy.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 @@ -23,20 +23,20 @@ #ifndef MAPNIK_GEOMETRY_STRATEGY_HPP #define MAPNIK_GEOMETRY_STRATEGY_HPP -#include +#include #include -namespace mapnik { +namespace mapnik { namespace geometry { namespace helper { template struct index {}; - + template struct gen_seq : gen_seq {}; - + template struct gen_seq<0, Ts...> : index {}; } @@ -70,7 +70,7 @@ struct strategy_group template inline P2 execute(P1 const& p, bool & status, T const& strat, Args const& ... args) const - { + { return execute(strat.template execute(p, status), status, args...); } @@ -79,7 +79,7 @@ struct strategy_group { return strat.template execute(p, status); } - + private: std::tuple 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 struct strategy_group_first { @@ -116,13 +116,13 @@ struct strategy_group_first template inline P2 execute_first(P1 const& p, bool & status, T const& strat, Args const& ... args) const - { + { return execute(strat.template execute(p, status), status, args...); } template inline P2 execute(P2 const& p, bool & status, T const& strat, Args const& ... args) const - { + { return execute(strat.template execute(p, status), status, args...); } @@ -131,13 +131,13 @@ struct strategy_group_first { return strat.template execute(p, status); } - + template inline P2 execute(P2 const& p, bool & status) const { return p; } - + private: std::tuple ops_; @@ -151,7 +151,7 @@ struct scale_strategy template inline bool apply(P1 const & p1, P2 & p2) const { - + using p2_type = typename boost::geometry::coordinate_type::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(y)); return true; } - + template inline P2 execute(P1 const& p1, bool & status) const { @@ -181,7 +181,7 @@ struct scale_rounding_strategy template inline bool apply(P1 const & p1, P2 & p2) const { - + using p2_type = typename boost::geometry::coordinate_type::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(std::round(y))); return true; } - + template inline P2 execute(P1 const& p1, bool & status) const { diff --git a/include/mapnik/geometry_to_path.hpp b/include/mapnik/geometry/to_path.hpp similarity index 97% rename from include/mapnik/geometry_to_path.hpp rename to include/mapnik/geometry/to_path.hpp index 2aadbc200..afa432246 100644 --- a/include/mapnik/geometry_to_path.hpp +++ b/include/mapnik/geometry/to_path.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 @@ -39,7 +39,7 @@ struct geometry_to_path mapnik::util::apply_visitor(*this, geom); } - void operator() (geometry_empty const&) const + void operator() (geometry_empty const&) const { // no-op } diff --git a/include/mapnik/geometry_transform.hpp b/include/mapnik/geometry/transform.hpp similarity index 97% rename from include/mapnik/geometry_transform.hpp rename to include/mapnik/geometry/transform.hpp index 4004d6083..11848e019 100644 --- a/include/mapnik/geometry_transform.hpp +++ b/include/mapnik/geometry/transform.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 @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_TRANSFORM_HPP #include -#include +#include #include namespace mapnik { namespace geometry { namespace detail { @@ -103,10 +103,9 @@ struct geometry_transform using result_type = geometry; - template - geometry operator() (geometry_empty const& empty) const + geometry operator() (geometry_empty const& empty) const { - return geometry_empty(); + return geometry_empty(); } template diff --git a/include/mapnik/geometry_is_empty.hpp b/include/mapnik/geometry_is_empty.hpp deleted file mode 100644 index ccc85a41e..000000000 --- a/include/mapnik/geometry_is_empty.hpp +++ /dev/null @@ -1,184 +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_IS_EMPTY_HPP -#define MAPNIK_GEOMETRY_IS_EMPTY_HPP - -#include - -namespace mapnik { namespace geometry { - -namespace detail { - -template -struct geometry_is_empty -{ - bool operator() (mapnik::geometry::geometry const& geom) const - { - return mapnik::util::apply_visitor(*this, geom); - } - - bool operator() (mapnik::geometry::point const&) const - { - return false; - } - - bool operator() (mapnik::geometry::line_string const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::linear_ring const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::polygon const& geom) const - { - return geom.empty() || geom.front().empty(); - } - - bool operator() (mapnik::geometry::multi_point const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::multi_line_string const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::multi_polygon const& geom) const - { - return geom.empty(); - } - - bool operator() (mapnik::geometry::geometry_collection const& geom) const - { - return geom.empty(); - } - - template - bool operator() (U const&) const - { - return true; - } - -}; - -template -struct geometry_has_empty -{ - bool operator() (mapnik::geometry::geometry const& geom) const - { - return mapnik::util::apply_visitor(*this, geom); - } - - bool operator() (mapnik::geometry::geometry_empty const&) const - { - return false; - } - - bool operator() (mapnik::geometry::point const&) const - { - return false; - } - - bool operator() (mapnik::geometry::line_string const&) const - { - return false; - } - - bool operator() (mapnik::geometry::linear_ring const&) const - { - return false; - } - - bool operator() (mapnik::geometry::polygon const&) const - { - return false; - } - - bool operator() (mapnik::geometry::multi_point const&) const - { - return false; - } - - bool operator() (mapnik::geometry::multi_line_string const& multi_line) const - { - for (auto const& line : multi_line) - { - if (line.empty()) return true; - } - return false; - } - - bool operator() (mapnik::geometry::multi_polygon const& multi_poly) const - { - for (auto const& poly : multi_poly) - { - if (poly.empty() || poly.front().empty()) // no-rings OR exterioir is empty - { - return true; - } - } - return false; - } - - bool operator() (mapnik::geometry::geometry_collection const& geom) const - { - for (auto const & item : geom) - { - if (geometry_is_empty()(item) || (*this)(item)) - { - return true; - } - } - return false; - } - - template - bool operator() (U const&) const - { - return true; - } -}; - -} - -template -inline bool is_empty(G const& geom) -{ - using coordinate_type = typename G::coordinate_type; - return detail::geometry_is_empty()(geom); -} - -template -inline bool has_empty(G const& geom) -{ - using coordinate_type = typename G::coordinate_type; - return detail::geometry_has_empty()(geom); -} - -}} - -#endif // MAPNIK_GEOMETRY_IS_EMPTY_HPP diff --git a/include/mapnik/global.hpp b/include/mapnik/global.hpp index 39a8c5ff7..0ef336d6b 100644 --- a/include/mapnik/global.hpp +++ b/include/mapnik/global.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 diff --git a/include/mapnik/gradient.hpp b/include/mapnik/gradient.hpp index ae9acb5a3..cad7dd3ea 100644 --- a/include/mapnik/gradient.hpp +++ b/include/mapnik/gradient.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 @@ -96,7 +96,7 @@ public: void get_control_points(double &x1, double &y1, double &x2, double &y2) const; private: - void swap(gradient& other) throw(); + void swap(gradient& other) noexcept; }; } diff --git a/include/mapnik/grid/grid.hpp b/include/mapnik/grid/grid.hpp index ab79cdd2a..39a32bcef 100644 --- a/include/mapnik/grid/grid.hpp +++ b/include/mapnik/grid/grid.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 @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #include #include #include diff --git a/include/mapnik/grid/grid_pixel.hpp b/include/mapnik/grid/grid_pixel.hpp index fda65779a..16a917a2b 100644 --- a/include/mapnik/grid/grid_pixel.hpp +++ b/include/mapnik/grid/grid_pixel.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 diff --git a/include/mapnik/grid/grid_pixfmt.hpp b/include/mapnik/grid/grid_pixfmt.hpp index dda24121f..7d5623850 100644 --- a/include/mapnik/grid/grid_pixfmt.hpp +++ b/include/mapnik/grid/grid_pixfmt.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 diff --git a/include/mapnik/grid/grid_rasterizer.hpp b/include/mapnik/grid/grid_rasterizer.hpp index 612944799..c79dec555 100644 --- a/include/mapnik/grid/grid_rasterizer.hpp +++ b/include/mapnik/grid/grid_rasterizer.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 diff --git a/include/mapnik/grid/grid_render_marker.hpp b/include/mapnik/grid/grid_render_marker.hpp index 5ad5fea13..68b09c3a3 100644 --- a/include/mapnik/grid/grid_render_marker.hpp +++ b/include/mapnik/grid/grid_render_marker.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 diff --git a/include/mapnik/grid/grid_renderer.hpp b/include/mapnik/grid/grid_renderer.hpp index cc689e308..9c2e4dbf8 100644 --- a/include/mapnik/grid/grid_renderer.hpp +++ b/include/mapnik/grid/grid_renderer.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 @@ -29,7 +29,7 @@ #include #include #include // for rule, symbolizers -#include // for box2d +#include // for box2d #include // for color #include // for view_transform #include // for composite_mode_e @@ -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 diff --git a/include/mapnik/grid/grid_renderer_base.hpp b/include/mapnik/grid/grid_renderer_base.hpp index bcc2e18c1..439b585a5 100644 --- a/include/mapnik/grid/grid_renderer_base.hpp +++ b/include/mapnik/grid/grid_renderer_base.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 diff --git a/include/mapnik/grid/grid_rendering_buffer.hpp b/include/mapnik/grid/grid_rendering_buffer.hpp index 8ab12cfc0..dc38d3d83 100644 --- a/include/mapnik/grid/grid_rendering_buffer.hpp +++ b/include/mapnik/grid/grid_rendering_buffer.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 diff --git a/include/mapnik/grid/grid_view.hpp b/include/mapnik/grid/grid_view.hpp index 80c539f53..bd5575d56 100644 --- a/include/mapnik/grid/grid_view.hpp +++ b/include/mapnik/grid/grid_view.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 @@ -24,7 +24,7 @@ #define MAPNIK_GRID_VIEW_HPP #include -#include +#include #include #include #include @@ -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 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), diff --git a/include/mapnik/group/group_layout.hpp b/include/mapnik/group/group_layout.hpp index 23811e800..4b4e6d4a3 100644 --- a/include/mapnik/group/group_layout.hpp +++ b/include/mapnik/group/group_layout.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 diff --git a/include/mapnik/group/group_layout_manager.hpp b/include/mapnik/group/group_layout_manager.hpp index 548e37bb6..6037718a3 100644 --- a/include/mapnik/group/group_layout_manager.hpp +++ b/include/mapnik/group/group_layout_manager.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 @@ -24,7 +24,7 @@ #define MAPNIK_GROUP_LAYOUT_MANAGER_HPP // mapnik -#include +#include #include #include diff --git a/include/mapnik/group/group_rule.hpp b/include/mapnik/group/group_rule.hpp index 58f8505b4..486e85bca 100644 --- a/include/mapnik/group/group_rule.hpp +++ b/include/mapnik/group/group_rule.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 diff --git a/include/mapnik/group/group_symbolizer_helper.hpp b/include/mapnik/group/group_symbolizer_helper.hpp index 93c7d4f3f..b3ff666bf 100644 --- a/include/mapnik/group/group_symbolizer_helper.hpp +++ b/include/mapnik/group/group_symbolizer_helper.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 @@ -25,7 +25,7 @@ //mapnik #include #include -#include +#include #include namespace mapnik { @@ -68,16 +68,6 @@ public: box_elements_.push_back(box_element(box, repeat_key)); } - inline void clear_box_elements() - { - box_elements_.clear(); - } - - inline text_symbolizer_properties const& get_properties() const - { - return info_ptr_->properties; - } - pixel_position_list const& get(); // Iterate over the given path, placing line-following labels or point labels with respect to label_spacing. diff --git a/include/mapnik/group/group_symbolizer_properties.hpp b/include/mapnik/group/group_symbolizer_properties.hpp index f5967b8be..6837b5ef2 100644 --- a/include/mapnik/group/group_symbolizer_properties.hpp +++ b/include/mapnik/group/group_symbolizer_properties.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 diff --git a/include/mapnik/hextree.hpp b/include/mapnik/hextree.hpp index 5d8adc1da..33654703f 100644 --- a/include/mapnik/hextree.hpp +++ b/include/mapnik/hextree.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 diff --git a/include/mapnik/hit_test_filter.hpp b/include/mapnik/hit_test_filter.hpp index fd9fb443c..11fcb1504 100644 --- a/include/mapnik/hit_test_filter.hpp +++ b/include/mapnik/hit_test_filter.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 @@ -49,7 +49,7 @@ struct hit_test_visitor y_(y), tol_(tol) {} - bool operator() (geometry::geometry_empty const& ) const + bool operator() (geometry::geometry_empty const& ) const { return false; } diff --git a/include/mapnik/image.hpp b/include/mapnik/image.hpp index da2f7738e..96b65e00e 100644 --- a/include/mapnik/image.hpp +++ b/include/mapnik/image.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 diff --git a/include/mapnik/image_any.hpp b/include/mapnik/image_any.hpp index 8aedf302a..9ee056c81 100644 --- a/include/mapnik/image_any.hpp +++ b/include/mapnik/image_any.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 diff --git a/include/mapnik/image_compositing.hpp b/include/mapnik/image_compositing.hpp index 82b89a398..0cb6b1339 100644 --- a/include/mapnik/image_compositing.hpp +++ b/include/mapnik/image_compositing.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 diff --git a/include/mapnik/image_copy.hpp b/include/mapnik/image_copy.hpp index 8f40ef40a..84481c692 100644 --- a/include/mapnik/image_copy.hpp +++ b/include/mapnik/image_copy.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 diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp index 0532b6a5b..8c29fe19b 100644 --- a/include/mapnik/image_filter.hpp +++ b/include/mapnik/image_filter.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 @@ -681,7 +681,7 @@ void apply_filter(Src & src, scale_hsla const& transform, double /*scale_factor* } template -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 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 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 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 @@ -916,7 +916,7 @@ void apply_filter(Src & src, invert const& /*op*/, double /*scale_factor*/) template struct filter_visitor { - filter_visitor(Src & src, double scale_factor) + filter_visitor(Src & src, double scale_factor=1.0) : src_(src), scale_factor_(scale_factor) {} diff --git a/include/mapnik/image_filter_grammar.hpp b/include/mapnik/image_filter_grammar.hpp deleted file mode 100644 index ca96116eb..000000000 --- a/include/mapnik/image_filter_grammar.hpp +++ /dev/null @@ -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 -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -// stl -#include - -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 -struct image_filter_grammar : - qi::grammar -{ - using alternative_type = qi::rule; - - image_filter_grammar(); - - qi::rule start; - qi::rule> filter; - qi::rule no_args; - qi::symbols alternatives; - qi::uint_parser< unsigned, 10, 1, 3 > radius_; - css_color_grammar css_color_; - qi::rule color_stop_; - qi::rule 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 diff --git a/include/mapnik/image_filter_grammar_impl.hpp b/include/mapnik/image_filter_grammar_impl.hpp deleted file mode 100644 index bf1770083..000000000 --- a/include/mapnik/image_filter_grammar_impl.hpp +++ /dev/null @@ -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 -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace { // internal - - BOOST_PHOENIX_ADAPT_FUNCTION( - typename std::remove_reference::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 -image_filter_grammar::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; - - start = -(filter % *lit(',')) - ; - - filter = omit[alternatives[_a = _1]] >> qi::lazy(*_a) - ; - - add("emboss") = no_args >> attr(construct()); - add("blur") = no_args >> attr(construct()); - add("gray") = no_args >> attr(construct()); - add("edge-detect") = no_args >> attr(construct()); - add("sobel") = no_args >> attr(construct()); - add("sharpen") = no_args >> attr(construct()); - add("x-gradient") = no_args >> attr(construct()); - add("y-gradient") = no_args >> attr(construct()); - add("invert") = no_args >> attr(construct()); - add("color-blind-protanope") = no_args >> attr(construct()); - add("color-blind-deuteranope") = no_args >> attr(construct()); - add("color-blind-tritanope") = no_args >> attr(construct()); - - add("agg-stack-blur") = - (lit('(') >> radius_ >> -( lit(',') >> radius_ ) >> lit(')')) - [push_back(_val, construct(_1, ovo(_2, _1)))] - | - no_args - [push_back(_val, construct(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(_1,_2,_3,_4,_5,_6,_7,_8))] - ; - - add("colorize-alpha") = qi::as() - [lit('(') >> color_stop_ % lit(',') >> lit(')')] - [push_back(_val, _1)] - ; - - color_stop_ = (css_color_ >> -color_stop_offset) - [_val = construct(_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(_1))] - ; - - no_args = -(lit('(') >> lit(')')); -} - -template -auto image_filter_grammar::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 diff --git a/include/mapnik/image_filter_grammar_x3.hpp b/include/mapnik/image_filter_grammar_x3.hpp new file mode 100644 index 000000000..cddc2d0dd --- /dev/null +++ b/include/mapnik/image_filter_grammar_x3.hpp @@ -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_IMAGE_FILTER_GRAMMAR_X3_HPP +#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#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 >; + +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 diff --git a/include/mapnik/image_filter_grammar_x3_def.hpp b/include/mapnik/image_filter_grammar_x3_def.hpp new file mode 100644 index 000000000..b40bfc8f9 --- /dev/null +++ b/include/mapnik/image_filter_grammar_x3_def.hpp @@ -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 +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include // 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 radius; + +// Import the expression rule +namespace { auto const& css_color = color_grammar(); } + +// starting rule +image_filter_grammar_type const start("start"); +// rules +x3::rule const filter("filter"); + +x3::rule const emboss_filter("emboss"); +x3::rule const blur_filter("blur"); +x3::rule const gray_filter("gray"); +x3::rule const edge_detect_filter("edge-detect"); +x3::rule const sobel_filter("sobel"); +x3::rule const sharpen_filter("sharpen"); +x3::rule const x_gradient_filter("x-gradient"); +x3::rule const y_gradient_filter("y-gradient"); +x3::rule const invert_filter("invert"); +x3::rule const color_blind_protanope_filter("color-blind-protanope"); +x3::rule const color_blind_deuteranope_filter("color-blind-deuteranope"); +x3::rule const color_blind_tritanope_filter("color-blind-tritanope"); + +x3::rule const agg_blur_filter("agg blur filter"); +x3::rule const scale_hsla_filter("scale-hsla"); +x3::rule const colorize_alpha_filter("colorize-alpha"); +x3::rule const color_stop("color-stop"); +x3::rule const offset("color-stop-offset"); +x3::rule 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 + +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 diff --git a/include/mapnik/image_filter_types.hpp b/include/mapnik/image_filter_types.hpp index 7e04df87a..1b7fd0498 100644 --- a/include/mapnik/image_filter_types.hpp +++ b/include/mapnik/image_filter_types.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 @@ -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, diff --git a/include/mapnik/image_impl.hpp b/include/mapnik/image_impl.hpp index f340d9a4b..5e9a50948 100644 --- a/include/mapnik/image_impl.hpp +++ b/include/mapnik/image_impl.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 diff --git a/include/mapnik/image_null.hpp b/include/mapnik/image_null.hpp index 5a698bbc9..7fb2a5da8 100644 --- a/include/mapnik/image_null.hpp +++ b/include/mapnik/image_null.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 diff --git a/include/mapnik/image_options.hpp b/include/mapnik/image_options.hpp index d44b2bf35..17b279ce1 100644 --- a/include/mapnik/image_options.hpp +++ b/include/mapnik/image_options.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 @@ -38,6 +38,10 @@ using image_options_map = std::map >; inline std::string to_string(boost::optional const& val) { return val ? *val : "";} image_options_map parse_image_options(std::string const& options); +#if defined(HAVE_PNG) +int parse_png_filters(std::string const& str); +#endif + } #endif // MAPNIK_IMAGE_OPTIONS_HPP diff --git a/include/mapnik/image_reader.hpp b/include/mapnik/image_reader.hpp index 6c1c2329c..77cc1073b 100644 --- a/include/mapnik/image_reader.hpp +++ b/include/mapnik/image_reader.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #pragma GCC diagnostic push #include @@ -50,9 +50,9 @@ public: image_reader_exception(std::string const& message) : message_(message) {} - ~image_reader_exception() throw() {} + ~image_reader_exception() {} - virtual const char* what() const throw() + virtual const char* what() const noexcept { return message_.c_str(); } diff --git a/include/mapnik/image_scaling.hpp b/include/mapnik/image_scaling.hpp index 461e99f27..f2ac1c10c 100644 --- a/include/mapnik/image_scaling.hpp +++ b/include/mapnik/image_scaling.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 diff --git a/include/mapnik/image_scaling_traits.hpp b/include/mapnik/image_scaling_traits.hpp index b8daff152..a1c329e31 100644 --- a/include/mapnik/image_scaling_traits.hpp +++ b/include/mapnik/image_scaling_traits.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 diff --git a/include/mapnik/image_util.hpp b/include/mapnik/image_util.hpp index 0db5a3752..b36ba75d6 100644 --- a/include/mapnik/image_util.hpp +++ b/include/mapnik/image_util.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 @@ -56,9 +56,9 @@ public: image_writer_exception(std::string const& message) : message_(message) {} - ~image_writer_exception() throw() {} + ~image_writer_exception(){} - virtual const char* what() const throw() + virtual const char* what() const noexcept { return message_.c_str(); } diff --git a/include/mapnik/image_util_jpeg.hpp b/include/mapnik/image_util_jpeg.hpp index feb810533..d684b9a22 100644 --- a/include/mapnik/image_util_jpeg.hpp +++ b/include/mapnik/image_util_jpeg.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 diff --git a/include/mapnik/image_util_png.hpp b/include/mapnik/image_util_png.hpp index 8592c4fd4..c6ef08a24 100644 --- a/include/mapnik/image_util_png.hpp +++ b/include/mapnik/image_util_png.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 diff --git a/include/mapnik/image_util_tiff.hpp b/include/mapnik/image_util_tiff.hpp index 39b524d88..87791e4e2 100644 --- a/include/mapnik/image_util_tiff.hpp +++ b/include/mapnik/image_util_tiff.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 diff --git a/include/mapnik/image_util_webp.hpp b/include/mapnik/image_util_webp.hpp index 6d28138de..3c654dec8 100644 --- a/include/mapnik/image_util_webp.hpp +++ b/include/mapnik/image_util_webp.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 diff --git a/include/mapnik/image_view.hpp b/include/mapnik/image_view.hpp index 846da6691..3b2270b27 100644 --- a/include/mapnik/image_view.hpp +++ b/include/mapnik/image_view.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 diff --git a/include/mapnik/image_view_any.hpp b/include/mapnik/image_view_any.hpp index a5452df0b..fde9b723e 100644 --- a/include/mapnik/image_view_any.hpp +++ b/include/mapnik/image_view_any.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 diff --git a/include/mapnik/image_view_impl.hpp b/include/mapnik/image_view_impl.hpp index 14032042a..9609913d6 100644 --- a/include/mapnik/image_view_impl.hpp +++ b/include/mapnik/image_view_impl.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 diff --git a/include/mapnik/image_view_null.hpp b/include/mapnik/image_view_null.hpp index 76ebc5f49..214e8f0a3 100644 --- a/include/mapnik/image_view_null.hpp +++ b/include/mapnik/image_view_null.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 diff --git a/include/mapnik/jpeg_io.hpp b/include/mapnik/jpeg_io.hpp index cc64dac75..02b8b94a2 100644 --- a/include/mapnik/jpeg_io.hpp +++ b/include/mapnik/jpeg_io.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 diff --git a/include/mapnik/json/attribute_value_visitor.hpp b/include/mapnik/json/attribute_value_visitor.hpp index 206530cae..3e5e74219 100644 --- a/include/mapnik/json/attribute_value_visitor.hpp +++ b/include/mapnik/json/attribute_value_visitor.hpp @@ -27,7 +27,6 @@ #include #include #include -#include namespace mapnik { namespace json { diff --git a/include/mapnik/json/create_feature.hpp b/include/mapnik/json/create_feature.hpp new file mode 100644 index 000000000..bada4ab69 --- /dev/null +++ b/include/mapnik/json/create_feature.hpp @@ -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 +#include +#include +#include + +#include +#include +#include + +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 + 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 + 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()) + { + throw std::runtime_error("Expecting an GeoJSON object"); + } + mapnik::json::geojson_object const& feature_value = mapnik::util::get(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()) + { + throw std::runtime_error("\"geometry\": xxx <-- expecting an JSON object here"); + } + auto const& geometry = mapnik::util::get(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()) + { + throw std::runtime_error("\"type\": xxx <-- expecting an GeoJSON geometry type here"); + } + geom_type = mapnik::util::get(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()) + { + throw std::runtime_error("\"coordinates\": xxx <-- expecting an GeoJSON positions here"); + } + coordinates = &mapnik::util::get(coordinates_value); + } + } + + mapnik::geometry::geometry 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()) + { + throw std::runtime_error("\"properties\": xxx <-- expecting an JSON object here"); + } + auto const& properties = mapnik::util::get(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 diff --git a/include/mapnik/json/geometry_util.hpp b/include/mapnik/json/create_geometry.hpp similarity index 61% rename from include/mapnik/json/geometry_util.hpp rename to include/mapnik/json/create_geometry.hpp index 82c4158b0..5f241efc1 100644 --- a/include/mapnik/json/geometry_util.hpp +++ b/include/mapnik/json/create_geometry.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 -#include -#include +#include +#include namespace mapnik { namespace json { +namespace { // geometries template struct create_point @@ -36,14 +37,17 @@ 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 point(pos.x, pos.y); geom_ = std::move(point); } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -53,23 +57,23 @@ 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(); - if (size > 1) + mapnik::geometry::line_string line; + std::size_t size = points.size(); + line.reserve(size); + for (auto && pt : points) { - mapnik::geometry::line_string line; - line.reserve(size); - for (auto && pt : ring) - { - line.emplace_back(std::move(pt)); - } - geom_ = std::move(line); + line.emplace_back(std::move(pt)); } + geom_ = std::move(line); } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -80,18 +84,17 @@ struct create_polygon explicit create_polygon(Geometry & geom) : geom_(geom) {} - void operator() (std::vector const& rings) const + void operator() (rings const& rngs) const { mapnik::geometry::polygon poly; - std::size_t num_rings = rings.size(); + std::size_t num_rings = rngs.size(); poly.reserve(num_rings); - 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 ring; ring.reserve(size); - for ( auto && pt : rings[i]) + for ( auto && pt : rngs[i]) { ring.emplace_back(std::move(pt)); } @@ -102,7 +105,10 @@ struct create_polygon } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -114,7 +120,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 multi_point; multi_point.reserve(points.size()); @@ -126,7 +132,10 @@ struct create_multipoint } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -137,12 +146,12 @@ struct create_multilinestring explicit create_multilinestring(Geometry & geom) : geom_(geom) {} - void operator() (std::vector const& rings) const + void operator() (rings const& rngs) const { mapnik::geometry::multi_line_string 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 line; line.reserve(ring.size()); @@ -156,7 +165,10 @@ struct create_multilinestring } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; @@ -167,11 +179,11 @@ struct create_multipolygon explicit create_multipolygon(Geometry & geom) : geom_(geom) {} - void operator()(std::vector > const& rings_array) const + void operator()(rings_array const& rngs_arr) const { mapnik::geometry::multi_polygon 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 poly; std::size_t num_rings = rings.size(); @@ -195,44 +207,44 @@ struct create_multipolygon } template - void operator()(T const&) const {} // no-op - shouldn't get here + void operator()(T const&) const + { + throw std::runtime_error("Failed to parse geojson geometry"); + } Geometry & geom_; }; +} // anonymous ns -struct create_geometry_impl +template +void create_geometry (Geometry & geom, int type, mapnik::json::positions const& coords) { - using result_type = void; - template - void operator() (Geometry & geom, int type, mapnik::json::coordinates const& coords) const + switch (type) { - switch (type) - { - case 1 ://Point - util::apply_visitor(create_point(geom), coords); - break; - case 2 ://LineString - util::apply_visitor(create_linestring(geom), coords); - break; - case 3 ://Polygon - util::apply_visitor(create_polygon(geom), coords); - break; - case 4 ://MultiPoint - util::apply_visitor(create_multipoint(geom), coords); - break; - case 5 ://MultiLineString - util::apply_visitor(create_multilinestring(geom), coords); - break; - case 6 ://MultiPolygon - util::apply_visitor(create_multipolygon(geom), coords); - break; - default: - break; - } - + case 1 ://Point + util::apply_visitor(create_point(geom), coords); + break; + case 2 ://LineString + util::apply_visitor(create_linestring(geom), coords); + break; + case 3 ://Polygon + util::apply_visitor(create_polygon(geom), coords); + break; + case 4 ://MultiPoint + util::apply_visitor(create_multipoint(geom), coords); + break; + case 5 ://MultiLineString + util::apply_visitor(create_multilinestring(geom), coords); + break; + case 6 ://MultiPolygon + util::apply_visitor(create_multipolygon(geom), coords); + break; + default: + throw std::runtime_error("Failed to parse geojson geometry"); + break; } -}; +} }} -#endif // MAPNIK_JSON_GEOMETRY_UTIL_HPP +#endif // MAPNIK_JSON_CREATE_GEOMETRY_HPP diff --git a/include/mapnik/json/error_handler.hpp b/include/mapnik/json/error_handler.hpp deleted file mode 100644 index 1e66427ad..000000000 --- a/include/mapnik/json/error_handler.hpp +++ /dev/null @@ -1,73 +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_ERROR_HANDLER_HPP -#define MAPNIK_JSON_ERROR_HANDLER_HPP - -#include - -#pragma GCC diagnostic push -#include -#include -namespace boost { namespace spirit { struct info; } } -#pragma GCC diagnostic pop - -// mapnik -#ifdef MAPNIK_LOG -#include -#endif - -// stl -#include -#include -#include - - -namespace mapnik { namespace json { - -template -struct error_handler -{ - using result_type = boost::spirit::qi::error_handler_result; - result_type operator() ( - Iterator, - Iterator end, - Iterator err_pos, - boost::spirit::info const& what) const - { -#ifdef MAPNIK_LOG - std::stringstream s; - using difference_type = typename std::iterator_traits::difference_type; - auto start_err = err_pos; - std::advance(err_pos, std::min(std::distance(err_pos, end), difference_type(16))); - auto end_err = err_pos; - assert(end_err <= end); - s << "Mapnik GeoJSON parsing error:" << what << " expected but got: " << std::string(start_err, end_err); - MAPNIK_LOG_ERROR(error_handler) << s.str(); -#endif - return boost::spirit::qi::fail; - } -}; - -}} - -#endif // MAPNIK_JSON_ERROR_HANDLER_HPP diff --git a/include/mapnik/json/extract_bounding_box_grammar.hpp b/include/mapnik/json/extract_bounding_box_grammar.hpp deleted file mode 100644 index 906e7126d..000000000 --- a/include/mapnik/json/extract_bounding_box_grammar.hpp +++ /dev/null @@ -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 -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; - -template > -struct extract_bounding_box_grammar : - qi::grammar -{ - using position_type = mapnik::geometry::point; - using boxes_type = Boxes; - using box_type = typename Boxes::value_type::first_type; - extract_bounding_box_grammar(); - // rules - qi::rule start; - qi::rule, void(boxes_type&), space_type> features; - qi::rule, void(boxes_type&, Iterator const&), space_type> feature; - qi::rule, box_type(), space_type> coords; - qi::rule(), space_type> pos; - qi::rule ring; - qi::rule rings; - qi::rule rings_array; - // generic JSON support - json::generic_json json; -}; - -}} - -#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOX_GRAMMAR_HPP diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp deleted file mode 100644 index bdc1b98b2..000000000 --- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp +++ /dev/null @@ -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 -#include -// boost -#include -#include -#include -#include -#include -#include -// stl -#include -#include - -namespace mapnik { namespace json { - -struct calculate_bounding_box_impl -{ - using result_type = void; - template - 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 - 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 -extract_bounding_box_grammar::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; - boost::phoenix::function calculate_bounding_box; - // error handler - boost::phoenix::function 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(coords, error_handler(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/json/extract_bounding_boxes_x3.hpp b/include/mapnik/json/extract_bounding_boxes_x3.hpp new file mode 100644 index 000000000..39ede302c --- /dev/null +++ b/include/mapnik/json/extract_bounding_boxes_x3.hpp @@ -0,0 +1,35 @@ +/***************************************************************************** + * + * 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_X3_HPP +#define MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_X3_HPP + +namespace mapnik { namespace json { + +template +void extract_bounding_boxes(Iterator & start, Iterator const& end, Boxes & boxes); + +}} + + +#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_X3_HPP diff --git a/include/mapnik/json/extract_bounding_boxes_x3_config.hpp b/include/mapnik/json/extract_bounding_boxes_x3_config.hpp new file mode 100644 index 000000000..885c066c1 --- /dev/null +++ b/include/mapnik/json/extract_bounding_boxes_x3_config.hpp @@ -0,0 +1,117 @@ +/***************************************************************************** + * + * 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 +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +//auto feature_collection_impl = x3::with(std::ref(bracket_counter)) +// [x3::with(std::ref(keys)) +// [x3::with(std::ref(callback)) +// [mapnik::json::grammar::feature_collection] +// ]]; + +namespace mapnik { namespace json { + +template +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 + void operator() (T const& val) const + { + auto const& r = std::get<0>(val); + auto const& b = std::get<1>(val); + if (b.valid()) + { + 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; +using boxes_type = std::vector>>; +using callback_type = extract_positions; + +using box_type_f = mapnik::box2d; +using boxes_type_f = std::vector>>; +using callback_type_f = extract_positions; + + +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::type; + +using context_type = x3::with_context const, + phrase_parse_context_type>::type; + +using extract_bounding_boxes_context_type = + x3::with_context const, + x3::with_context const, + context_type>::type>::type; + +using extract_bounding_boxes_reverse_context_type = + x3::with_context const, + x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::type>::type>::type; + + +using extract_bounding_boxes_context_type_f = + x3::with_context const, + x3::with_context const, + context_type>::type>::type; + +using extract_bounding_boxes_reverse_context_type_f = + x3::with_context const, + x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::type>::type>::type; + +}}} + +#endif // MAPNIK_JSON_EXTRACT_BOUNDING_BOXES_CONFIG_HPP diff --git a/include/mapnik/json/feature_collection_grammar.hpp b/include/mapnik/json/feature_collection_grammar.hpp deleted file mode 100644 index c71801c3f..000000000 --- a/include/mapnik/json/feature_collection_grammar.hpp +++ /dev/null @@ -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 -#include -#include -#include - -// spirit::qi -#include -#include - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; - -struct default_feature_callback -{ - default_feature_callback(std::vector & features) - : features_(features) {} - void operator() (feature_ptr const& feature) - { - features_.push_back(feature); - } - std::vector & features_; -}; - -struct apply_feature_callback -{ - using result_type = void; - template - void operator() (Callback & callback, Feature const& feature) const - { - callback(feature); - } -}; - -template > -struct feature_collection_grammar : - qi::grammar -{ - feature_collection_grammar(mapnik::transcoder const& tr); - // grammars - feature_grammar feature_g; - // rules - qi::rule start; // START - qi::rule feature_collection; - qi::rule type; - qi::rule features; - qi::rule, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature; - // phoenix functions - phoenix::function on_feature; - // error handler - boost::phoenix::function const error_handler; -}; - -template > -struct feature_grammar_callback : - qi::grammar -{ - feature_grammar_callback(mapnik::transcoder const& tr); - // grammars - feature_grammar feature_g; - geometry_grammar geometry_g; - // rules - qi::rule start; // START - qi::rule, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature; - qi::rule, void(context_ptr const& ctx, std::size_t, FeatureCallback&), space_type> feature_from_geometry; - // phoenix functions - phoenix::function set_geometry; - phoenix::function on_feature; - // error handler - boost::phoenix::function const error_handler; -}; - - -}} - -#endif // MAPNIK_FEATURE_COLLECTION_GRAMMAR_HPP diff --git a/include/mapnik/json/feature_collection_grammar_impl.hpp b/include/mapnik/json/feature_collection_grammar_impl.hpp deleted file mode 100644 index b2836af37..000000000 --- a/include/mapnik/json/feature_collection_grammar_impl.hpp +++ /dev/null @@ -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 -#include - -// spirit::qi -#include -#include - -namespace mapnik { namespace json { - -template -feature_collection_grammar::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(new_(_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(feature_collection, error_handler(_1, _2, _3, _4)); -} - - -template -feature_grammar_callback::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(new_(_r1, _r2))] - >> feature_g(*_a)[on_feature(_r3,_a)] - ; - - feature_from_geometry = - eps[_a = phoenix::construct(new_(_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(feature, error_handler(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/json/feature_generator_grammar.hpp b/include/mapnik/json/feature_generator_grammar.hpp index 9eaa3bb99..6da343feb 100644 --- a/include/mapnik/json/feature_generator_grammar.hpp +++ b/include/mapnik/json/feature_generator_grammar.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 @@ -63,17 +63,6 @@ struct end_container } }; -template <> -struct transform_attribute, - mapnik::geometry::geometry const& , karma::domain> -{ - using type = mapnik::geometry::geometry const&; - static type pre(const boost::fusion::cons& f) - { - return boost::fusion::at >(f).get_geometry(); - } -}; - }}} namespace mapnik { namespace json { @@ -91,6 +80,15 @@ struct get_id } }; +struct extract_geometry +{ + using result_type = mapnik::geometry::geometry const&; + template + result_type operator() (T const& f) const + { + return f.get_geometry(); + } +}; template struct feature_generator_grammar : @@ -101,6 +99,7 @@ struct feature_generator_grammar : geometry_generator_grammar > geometry; properties_generator_grammar properties; boost::phoenix::function > id_; + boost::phoenix::function geom_; }; }} diff --git a/include/mapnik/json/feature_generator_grammar_impl.hpp b/include/mapnik/json/feature_generator_grammar_impl.hpp index f819baa80..3bb56dff9 100644 --- a/include/mapnik/json/feature_generator_grammar_impl.hpp +++ b/include/mapnik/json/feature_generator_grammar_impl.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 @@ -22,11 +22,6 @@ #include -#include -#include -#include -#include - namespace mapnik { namespace json { template @@ -40,7 +35,7 @@ feature_generator_grammar::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('}') ; diff --git a/include/mapnik/json/feature_grammar.hpp b/include/mapnik/json/feature_grammar.hpp deleted file mode 100644 index fae8ed58a..000000000 --- a/include/mapnik/json/feature_grammar.hpp +++ /dev/null @@ -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 -#include -#include -#include -#pragma GCC diagnostic push -#include -#include -#include -#include -#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 - 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 - result_type operator() (T0 & feature, T1 && geom) const - { - return feature.set_geometry(std::move(geom)); - } -}; - -template > -struct feature_grammar : qi::grammar -{ - explicit feature_grammar(mapnik::transcoder const& tr); - // generic JSON - generic_json json_; - // geoJSON - qi::rule start; - qi::rule, void(FeatureType&), space_type> feature; - qi::rule feature_part; - qi::rule feature_type; - qi::rule properties; - qi::rule, void(FeatureType &),space_type> attributes; - // functions - phoenix::function put_property_; - phoenix::function set_geometry; - // error handler - boost::phoenix::function const error_handler; - // geometry - geometry_grammar geometry_grammar_; -}; - -}} - -#endif // MAPNIK_FEATURE_GRAMMAR_HPP diff --git a/include/mapnik/json/feature_grammar_impl.hpp b/include/mapnik/json/feature_grammar_impl.hpp deleted file mode 100644 index bdda650cc..000000000 --- a/include/mapnik/json/feature_grammar_impl.hpp +++ /dev/null @@ -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 -#include - -namespace mapnik { namespace json { - -template -feature_grammar::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(feature, error_handler(_1, _2, _3, _4)); - -} - -}} diff --git a/include/mapnik/json/feature_grammar_x3.hpp b/include/mapnik/json/feature_grammar_x3.hpp new file mode 100644 index 000000000..b3425e88f --- /dev/null +++ b/include/mapnik/json/feature_grammar_x3.hpp @@ -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_FEATURE_GRAMMAR_X3_HPP +#define MAPNIK_JSON_FEATURE_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; +using feature_grammar_type = x3::rule; +using geometry_grammar_type = x3::rule >; + +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 diff --git a/include/mapnik/json/feature_grammar_x3_def.hpp b/include/mapnik/json/feature_grammar_x3_def.hpp new file mode 100644 index 000000000..1e18faeec --- /dev/null +++ b/include/mapnik/json/feature_grammar_x3_def.hpp @@ -0,0 +1,318 @@ +/***************************************************************************** + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +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 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> 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 const& array) const + { + std::string str = stringifier()(array); + return mapnik::value(tr_.transcode(str.c_str())); + } + + mapnik::value operator()(std::vector > const& object) const + { + std::string str = stringifier()(object); + return mapnik::value(tr_.transcode(str.c_str())); + } + + template + 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 +{ + 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_geometry = [] (auto const& ctx) +{ + mapnik::geometry::geometry geom; + auto const type = std::get<0>(_attr(ctx)); + if (type == mapnik::geometry::geometry_types::GeometryCollection) + { + _val(ctx) = std::move(std::get<2>(_attr(ctx))); + } + else + { + auto const& coordinates = std::get<1>(_attr(ctx)); + mapnik::json::create_geometry(geom, type, coordinates); + _val(ctx) = std::move(geom); + } +}; + +auto const assign_geometry = [] (auto const& ctx) +{ + mapnik::feature_impl & feature = x3::get(ctx); + feature.set_geometry(std::move(_attr(ctx))); +}; + +auto const push_geometry = [] (auto const& ctx) +{ + mapnik::geometry::geometry geom; + auto const type = std::get<0>(_attr(ctx)); + auto const& coordinates = std::get<1>(_attr(ctx)); + mapnik::json::create_geometry(geom, type, coordinates); + _val(ctx).push_back(std::move(geom)); +}; + +auto const assign_positions = [] (auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto const assign_collection = [] (auto const& ctx) +{ + std::get<2>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_property = [](auto const& ctx) +{ + mapnik::feature_impl & feature = x3::get(ctx); + mapnik::transcoder const& tr = x3::get(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 Rule"; +geometry_grammar_type const geometry_rule = "Feature Rule"; + +// rules +x3::rule const feature_type = "Feature Type"; +x3::rule const geometry_type = "Geometry Type"; +x3::rule const coordinates = "Coordinates"; +x3::rule>> const geometry_tuple = "Geometry"; +x3::rule> const property = "Property"; +x3::rule const properties = "Properties"; +x3::rule const feature_part = "Feature part"; +x3::rule> 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\"") > 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[assign_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(':') > geometry_rule[assign_geometry]) + | + (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[create_geometry] > lit('}')) | lit("null"); + +#pragma GCC diagnostic push +#include + +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 diff --git a/include/mapnik/json/feature_parser.hpp b/include/mapnik/json/feature_parser.hpp index 433d19e30..7c0cf3198 100644 --- a/include/mapnik/json/feature_parser.hpp +++ b/include/mapnik/json/feature_parser.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 @@ -25,25 +25,12 @@ // mapnik #include -#include - -// boost -#include -#include +// stl +#include 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 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); }} diff --git a/include/mapnik/json/generic_json.hpp b/include/mapnik/json/generic_json.hpp deleted file mode 100644 index 65c04c47d..000000000 --- a/include/mapnik/json/generic_json.hpp +++ /dev/null @@ -1,196 +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_GENERIC_JSON_HPP -#define MAPNIK_GENERIC_JSON_HPP - -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - -#include - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; -namespace standard = boost::spirit::standard; -namespace phoenix = boost::phoenix; -using space_type = standard::space_type; - -struct json_value; - -using json_array = std::vector; -using json_object_element = std::pair; -using json_object = std::vector; -using json_value_base = mapnik::util::variant, - mapnik::util::recursive_wrapper >; -struct json_value : json_value_base -{ -#if __cpp_inheriting_constructors >= 200802 - - using json_value_base::json_value_base; - -#else - - json_value() = default; - - template - json_value(T && val) - : json_value_base(std::forward(val)) {} - -#endif -}; - -using uchar = std::uint32_t; // a unicode code point - -// unicode string grammar via boost/libs/spirit/example/qi/json/json/parser/grammar.hpp - -template -struct unicode_string : qi::grammar -{ - unicode_string(); - qi::rule escape; - qi::rule char_esc; - qi::rule double_quoted; -}; - - -struct push_utf8 -{ - using result_type = void; - - void operator()(std::string& utf8, uchar code_point) const - { - typedef std::back_insert_iterator insert_iter; - insert_iter out_iter(utf8); - boost::utf8_output_iterator utf8_iter(out_iter); - *utf8_iter++ = code_point; - } -}; - -struct push_esc -{ - using result_type = void; - - void operator()(std::string& utf8, uchar c) const - { - switch (c) - { - case ' ': utf8 += ' '; break; - case '\t': utf8 += '\t'; break; - case '0': utf8 += char(0); break; - case 'a': utf8 += 0x7; break; - case 'b': utf8 += 0x8; break; - case 't': utf8 += 0x9; break; - case 'n': utf8 += 0xA; break; - case 'v': utf8 += 0xB; break; - case 'f': utf8 += 0xC; break; - case 'r': utf8 += 0xD; break; - case 'e': utf8 += 0x1B; break; - case '"': utf8 += '"'; break; - case '/': utf8 += '/'; break; - case '\\': utf8 += '\\'; break; - case '_': push_utf8()(utf8, 0xA0); break; - case 'N': push_utf8()(utf8, 0x85); break; - case 'L': push_utf8()(utf8, 0x2028); break; - case 'P': push_utf8()(utf8, 0x2029); break; - } - } -}; - -template< typename Iterator> -unicode_string::unicode_string() - : unicode_string::base_type(double_quoted) -{ - qi::char_type char_; - qi::_val_type _val; - qi::_r1_type _r1; - qi::_1_type _1; - qi::lit_type lit; - qi::eol_type eol; - qi::repeat_type repeat; - qi::hex_type hex; - - using boost::spirit::qi::uint_parser; - using boost::phoenix::function; - using boost::phoenix::ref; - - uint_parser hex4; - uint_parser hex8; - function push_utf8; - function push_esc; - - escape = - ('x' > hex) [push_utf8(_r1, _1)] - | - ('u' > hex4) [push_utf8(_r1, _1)] - | - ('U' > hex8) [push_utf8(_r1, _1)] - | - char_("0abtnvfre\"/\\N_LP \t") [push_esc(_r1, _1)] - | - eol // continue to next line - ; - - char_esc = - '\\' > escape(_r1) - ; - - double_quoted = - '"' - > *(char_esc(_val) | (~char_('"')) [_val += _1]) - > '"' - ; -} - -template -struct generic_json : qi::grammar -{ - generic_json(); - qi::rule value; - qi::int_parser int__; - unicode_string string_; - qi::rule key_value; - qi::rule number; - qi::rule object; - qi::rule array; - qi::real_parser> strict_double; - // conversions - boost::phoenix::function> integer_converter; - boost::phoenix::function> double_converter; -}; - -}} - -#endif // MAPNIK_GENERIC_JSON_HPP diff --git a/include/mapnik/path_expression_grammar.hpp b/include/mapnik/json/generic_json_grammar_x3.hpp similarity index 56% rename from include/mapnik/path_expression_grammar.hpp rename to include/mapnik/json/generic_json_grammar_x3.hpp index 61a3db7ed..1dce6b161 100644 --- a/include/mapnik/path_expression_grammar.hpp +++ b/include/mapnik/json/generic_json_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,40 +20,32 @@ * *****************************************************************************/ -#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP -#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP - -// mapnik -#include +#ifndef MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP +#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP +#include #pragma GCC diagnostic push #include -#include +#include #pragma GCC diagnostic pop -// stl -#include #include -namespace mapnik -{ +namespace mapnik { namespace json { -using namespace boost; -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -namespace standard_wide = boost::spirit::standard_wide; +namespace x3 = boost::spirit::x3; -using standard_wide::space_type; - -template -struct path_expression_grammar : qi::grammar(), space_type> -{ - path_expression_grammar(); - qi::rule() , space_type> expr; - qi::rule attr; - qi::rule str; -}; +namespace grammar { +using generic_json_grammar_type = x3::rule; +using generic_json_key_value_type = x3::rule; +BOOST_SPIRIT_DECLARE(generic_json_grammar_type); +BOOST_SPIRIT_DECLARE(generic_json_key_value_type); } -#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP +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 diff --git a/include/mapnik/json/generic_json_grammar_x3_def.hpp b/include/mapnik/json/generic_json_grammar_x3_def.hpp new file mode 100644 index 000000000..64570eeb1 --- /dev/null +++ b/include/mapnik/json/generic_json_grammar_x3_def.hpp @@ -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 +#include +#include + +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 const object("JSON Object"); +x3::rule const array("JSON Array"); +x3::rule const number("JSON Number"); + +auto const json_double = x3::real_parser>(); +auto const json_integer = x3::int_parser(); + +// 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 + +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 diff --git a/include/mapnik/json/geojson_grammar_x3.hpp b/include/mapnik/json/geojson_grammar_x3.hpp new file mode 100644 index 000000000..b5dda0b35 --- /dev/null +++ b/include/mapnik/json/geojson_grammar_x3.hpp @@ -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 +#include +#include +#include +#include +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +#include + +namespace mapnik { namespace json { + +namespace x3 = boost::spirit::x3; +struct geojson_value; +using geojson_array = std::vector; +using geojson_object_element = std::pair; +using geojson_object = std::vector; +using geojson_value_base = mapnik::util::variant; +struct geojson_value : geojson_value_base +{ +#if __cpp_inheriting_constructors >= 200802 + + using geojson_value_base::geojson_value_base; + +#else + + geojson_value() = default; + + template + geojson_value(T && val) + : geojson_value_base(std::forward(val)) {} + +#endif +}; + +namespace grammar { + +using geojson_grammar_type = x3::rule; +using key_value_type = x3::rule; +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 diff --git a/include/mapnik/json/geojson_grammar_x3_def.hpp b/include/mapnik/json/geojson_grammar_x3_def.hpp new file mode 100644 index 000000000..10dd81aab --- /dev/null +++ b/include/mapnik/json/geojson_grammar_x3_def.hpp @@ -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 +#include +#include +#include + +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(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 +{ + 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 const object("JSON Object"); +x3::rule const array("JSON Array"); +x3::rule const number("JSON Number"); +//x3::rule key_value("JSON key/value"); +// GeoJSON +x3::rule const coordinates("GeoJSON Coordinates"); +x3::rule const geometry_type("GeoJSON Geometry Type"); +x3::rule const geojson_key_value("GeoJSON Key/Value Type"); +auto const geojson_double = x3::real_parser>(); +auto const geojson_integer = x3::int_parser(); + +// 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 + +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 diff --git a/include/mapnik/json/geometry_generator_grammar.hpp b/include/mapnik/json/geometry_generator_grammar.hpp index 931c41629..7d4e9df28 100644 --- a/include/mapnik/json/geometry_generator_grammar.hpp +++ b/include/mapnik/json/geometry_generator_grammar.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 @@ -26,13 +26,10 @@ // mapnik #include #include -#include // boost #pragma GCC diagnostic push #include #include -#include -#include #include // for vc++ and android whose c++11 libs lack std::trunc #include #pragma GCC diagnostic pop @@ -43,18 +40,6 @@ namespace karma = boost::spirit::karma; namespace detail { -template -struct get_type -{ - using result_type = mapnik::geometry::geometry_types; - template - result_type operator() (T const& geom) const - { - auto type = mapnik::geometry::geometry_type(geom); - return type; - } -}; - template struct json_coordinate_policy : karma::real_policies { @@ -88,29 +73,28 @@ struct json_coordinate_policy : karma::real_policies template struct geometry_generator_grammar : - karma::grammar + karma::grammar { + using coord_type = typename Geometry::coordinate_type; geometry_generator_grammar(); - karma::rule geometry; - karma::rule, Geometry const&() > geometry_dispatch; - karma::rule const&()> point; - karma::rule const&()> point_coord; - karma::rule const&()> linestring; - karma::rule const&()> linestring_coord; - karma::rule const&()> polygon; - karma::rule const&()> polygon_coord; - karma::rule const&()> linearring_coord; - karma::rule const& ()> multi_point; - karma::rule const& ()> multi_point_coord; - karma::rule const& ()> multi_linestring; - karma::rule const& ()> multi_linestring_coord; - karma::rule const& ()> multi_polygon; - karma::rule const& ()> multi_polygon_coord; - karma::rule const& ()> geometry_collection; - karma::rule const& ()> geometries; - boost::phoenix::function > geometry_type; - karma::real_generator > coordinate; - + karma::rule geometry; + karma::rule()> point; + karma::rule()> point_coord; + karma::rule()> linestring; + karma::rule()> linestring_coord; + karma::rule()> polygon; + karma::rule()> polygon_coord; + karma::rule()> linear_ring_coord; + karma::rule()> multi_point; + karma::rule()> multi_point_coord; + karma::rule()> multi_linestring; + karma::rule ()> multi_linestring_coord; + karma::rule()> multi_polygon; + karma::rule()> multi_polygon_coord; + karma::rule()> geometry_collection; + karma::rule()> geometries; + // + karma::real_generator > coordinate; }; }} diff --git a/include/mapnik/json/geometry_generator_grammar_impl.hpp b/include/mapnik/json/geometry_generator_grammar_impl.hpp index 952bb739f..1298803bb 100644 --- a/include/mapnik/json/geometry_generator_grammar_impl.hpp +++ b/include/mapnik/json/geometry_generator_grammar_impl.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 @@ -22,92 +22,79 @@ // mapnik #include -#include -#include -#include +#include -// boost -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop namespace mapnik { namespace json { namespace karma = boost::spirit::karma; -namespace phoenix = boost::phoenix; template geometry_generator_grammar::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") + lit("null") // geometry_empty ; point = lit("{\"type\":\"Point\",\"coordinates\":") << point_coord << lit("}") ; - linestring = lit("{\"type\":\"LineString\",\"coordinates\":[") << linestring_coord << lit("]}") + + linestring = lit("{\"type\":\"LineString\",\"coordinates\":") << linestring_coord << lit("}") ; - polygon = lit("{\"type\":\"Polygon\",\"coordinates\":[") << polygon_coord << lit("]}") + + polygon = lit("{\"type\":\"Polygon\",\"coordinates\":") << polygon_coord << lit("}") ; - multi_point = lit("{\"type\":\"MultiPoint\",\"coordinates\":[") << multi_point_coord << lit("]}") + + multi_point = lit("{\"type\":\"MultiPoint\",\"coordinates\":") << multi_point_coord << lit("}") ; - multi_linestring = lit("{\"type\":\"MultiLineString\",\"coordinates\":[") << multi_linestring_coord << lit("]}") + + multi_linestring = lit("{\"type\":\"MultiLineString\",\"coordinates\":") << multi_linestring_coord << lit("}") ; - multi_polygon = lit("{\"type\":\"MultiPolygon\",\"coordinates\":[") << multi_polygon_coord << lit("]}") + + multi_polygon = lit("{\"type\":\"MultiPolygon\",\"coordinates\":") << multi_polygon_coord << lit("}") ; + geometry_collection = lit("{\"type\":\"GeometryCollection\",\"geometries\":[") << geometries << lit("]}") ; + point_coord = lit('[') << coordinate << lit(',') << coordinate << lit(']') ; - linestring_coord = point_coord % lit(',') + + linestring_coord = lit('[') << -(point_coord % lit(',')) << lit(']') ; - linearring_coord = point_coord % lit(',') + + linear_ring_coord = lit('[') << -(point_coord % lit(',')) << lit(']')//linestring_coord.alias() ; - polygon_coord = (lit('[') << linearring_coord << lit(']')) % lit(',') + + polygon_coord = lit('[') << linear_ring_coord % lit(',') << lit(']') ; - multi_point_coord = linestring_coord.alias() + + multi_point_coord = lit('[') << -(point_coord % lit(',')) << lit(']');//linestring_coord.alias() ; - multi_linestring_coord = (lit('[') << linestring_coord << lit(']')) % lit(',') + + multi_linestring_coord = lit('[') << linestring_coord % lit(',') << lit(']') ; - multi_polygon_coord = (lit('[') << polygon_coord << lit(']')) % lit(',') + + multi_polygon_coord = lit('[') << polygon_coord % lit(',') << lit("]") ; + geometries = geometry % lit(',') ; } diff --git a/include/mapnik/json/geometry_grammar.hpp b/include/mapnik/json/geometry_grammar.hpp deleted file mode 100644 index fc0d3a43d..000000000 --- a/include/mapnik/json/geometry_grammar.hpp +++ /dev/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 // for geometry_type -#include -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace json { - -namespace qi = boost::spirit::qi; - -template > -struct geometry_grammar : - qi::grammar() ,space_type> -{ - geometry_grammar(); - qi::rule(), space_type> start; - qi::rule, mapnik::geometry::geometry(), space_type> geometry; - qi::rule&), space_type> geometry_part; - qi::rule(), space_type> geometry_collection; - qi::symbols geometry_type_dispatch; - positions_grammar coordinates; - boost::phoenix::function create_geometry; - // generic JSON - generic_json json_; - // error handler - ErrorHandler error_handler; -}; - -}} - -#endif // MAPNIK_GEOMETRY_GRAMMAR_HPP diff --git a/include/mapnik/json/geometry_grammar_impl.hpp b/include/mapnik/json/geometry_grammar_impl.hpp deleted file mode 100644 index 171894c78..000000000 --- a/include/mapnik/json/geometry_grammar_impl.hpp +++ /dev/null @@ -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 -#include -#include -#include -// boost -#include -#include - -namespace mapnik { namespace json { - -template -geometry_grammar::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(error_handler); - on_error(start, error_handler_function(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/svg/svg_points_grammar.hpp b/include/mapnik/json/geometry_grammar_x3.hpp similarity index 62% rename from include/mapnik/svg/svg_points_grammar.hpp rename to include/mapnik/json/geometry_grammar_x3.hpp index afbe7ee09..a630f6b05 100644 --- a/include/mapnik/svg/svg_points_grammar.hpp +++ b/include/mapnik/json/geometry_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,31 +20,32 @@ * *****************************************************************************/ -#ifndef SVG_POINTS_GRAMMAR_HPP -#define SVG_POINTS_GRAMMAR_HPP +#ifndef MAPNIK_GEOMETRY_GRAMMAR_X3_HPP +#define MAPNIK_GEOMETRY_GRAMMAR_X3_HPP // mapnik -#include +#include // for geometry_type #pragma GCC diagnostic push #include -#include +#include #pragma GCC diagnostic pop -namespace mapnik { namespace svg { +// mapnik +#include -using namespace boost::spirit; -using namespace boost::phoenix; +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using geometry_grammar_type = x3::rule>; + +BOOST_SPIRIT_DECLARE(geometry_grammar_type); + +} + +grammar::geometry_grammar_type const& geometry_grammar(); -template -struct svg_points_grammar : qi::grammar -{ - // ctor - svg_points_grammar(); - // rules - qi::rule start; - qi::rule(), SkipType> coord; -}; }} -#endif // SVG_POINTS_GRAMMAR_HPP +#endif // MAPNIK_GEOMETRY_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/geometry_grammar_x3_def.hpp b/include/mapnik/json/geometry_grammar_x3_def.hpp new file mode 100644 index 000000000..69d5a2e90 --- /dev/null +++ b/include/mapnik/json/geometry_grammar_x3_def.hpp @@ -0,0 +1,161 @@ +/***************************************************************************** + * + * 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_GEOMETRY_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_GEOMETRY_GRAMMAR_X3_DEF_HPP + +// mapnik +#include +#include +#include +#include +#include +#include +#include +#include +// boost +#include + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; +using x3::lit; +using x3::_pass; +using x3::omit; + +auto create_geometry = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + mapnik::json::create_geometry_impl()(_val(ctx), std::get<0>(attr), std::get<1>(attr)); +}; + +auto assign_element = [] (auto const& ctx) +{ + _val(ctx) = std::move(_attr(ctx)); +}; + +namespace { +template +struct assign_geometry_element_visitor : util::noncopyable +{ + assign_geometry_element_visitor(T & t) + : t_(t) {} + + void operator() (int const& type) + { + std::get<0>(t_) = type; + } + void operator () (::mapnik::json::positions const& p) + { + std::get<1>(t_) = p; + } + + T & t_; +}; + +} + +auto assign_geometry_element = [] (auto const& ctx) +{ + assign_geometry_element_visitor v(_val(ctx)); + mapnik::util::apply_visitor(v, _attr(ctx)); +}; + +auto assign_collection = [] (auto const& ctx) +{ + auto & val = _val(ctx); + std::get<0>(val) = 7; //GeometryCollection + std::get<1>(val) = std::move(_attr(ctx)); +}; + +auto push_geometry = [] (auto const& ctx) +{ + _val(ctx).emplace_back(std::move(_attr(ctx))); +}; + +// start rule +geometry_grammar_type const geometry("Geometry"); +// rules +x3::rule> const geometry_element("Geometry Element"); +x3::rule> const geometry_tuple("Geometry Tuple"); +x3::rule> const geometry_collection("Geometry Collection"); +// import positions rule +namespace { auto const& pos = positions_grammar(); } +// import generic JSON key:value rule +namespace { auto const& json_key_value = generic_json_key_value(); } + +struct geometry_type_ : x3::symbols +{ + geometry_type_() + { + add + ("\"Point\"",1) + ("\"LineString\"",2) + ("\"Polygon\"",3) + ("\"MultiPoint\"",4) + ("\"MultiLineString\"",5) + ("\"MultiPolygon\"",6) + ("\"GeometryCollection\"",7) + ; + } +} geometry_type; + +auto const geometry_def = (lit('{') > (geometry_tuple)[create_geometry] > lit('}')) | lit("null") + ; + +auto const geometry_tuple_def = geometry_element[assign_geometry_element] % lit(',') + ; + +auto const geometry_element_def = + (lit("\"type\"") > lit(":") > geometry_type[assign_element]) + | + (lit("\"coordinates\"") > lit(':') > pos[assign_element]) + | + (lit("\"geometries\"") > lit(':') > lit('[') > geometry_collection[assign_collection] > lit(']')) + | + omit[json_key_value] + ; + +auto const geometry_collection_def = geometry[push_geometry] % lit(',') + ; + +BOOST_SPIRIT_DEFINE( + geometry, + geometry_element, + geometry_tuple, + geometry_collection + ); + +}}} + +namespace mapnik { namespace json { +grammar::geometry_grammar_type const& geometry_grammar() +{ + return grammar::geometry; +} +}} + + +#endif // MAPNIK_JSON_GEOMETRY_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/geometry_parser.hpp b/include/mapnik/json/geometry_parser.hpp index 761c193f8..a4fded3f0 100644 --- a/include/mapnik/json/geometry_parser.hpp +++ b/include/mapnik/json/geometry_parser.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 diff --git a/include/mapnik/json/json_grammar_config.hpp b/include/mapnik/json/json_grammar_config.hpp new file mode 100644 index 000000000..26c117201 --- /dev/null +++ b/include/mapnik/json/json_grammar_config.hpp @@ -0,0 +1,118 @@ +/***************************************************************************** + * + * 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 +#include +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#include +#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::set_of>; + +inline keys_map get_keys() +{ + keys_map keys = boost::assign::list_of + ("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::type; +using context_type = x3::with_context const, + phrase_parse_context_type>::type; + +using feature_context_type = x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::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 const, + x3::with_context const, + phrase_parse_context_type>::type>::type; + +// helper macro +#define BOOST_SPIRIT_INSTANTIATE_UNUSED(rule_type, Iterator, Context) \ + template bool parse_rule( \ + rule_type rule_ \ + , Iterator& first, Iterator const& last \ + , Context const& context, boost::spirit::x3::unused_type const& ); \ + /***/ + +}}} + +#endif // MAPNIK_JSON_GRAMMAR_CONFIG_HPP diff --git a/include/mapnik/json/json_value.hpp b/include/mapnik/json/json_value.hpp new file mode 100644 index 000000000..8d6c1b09a --- /dev/null +++ b/include/mapnik/json/json_value.hpp @@ -0,0 +1,65 @@ +/***************************************************************************** + * + * 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_JSON_VALUE_HPP +#define MAPNIK_JSON_JSON_VALUE_HPP + +// mapnik +#include +#include +// stl +#include +#include + +namespace mapnik { namespace json { + +struct json_value; + +using json_array = std::vector; +using json_object_element = std::pair; +using json_object = std::vector; +using json_value_base = mapnik::util::variant; +struct json_value : json_value_base +{ +#if __cpp_inheriting_constructors >= 200802 + + using json_value_base::json_value_base; + +#else + + json_value() = default; + + template + json_value(T && val) + : json_value_base(std::forward(val)) {} + +#endif +}; +}} + +#endif // MAPNIK_JSON_JSON_VALUE_HPP diff --git a/src/json/mapnik_json_feature_collection_grammar.cpp b/include/mapnik/json/parse_feature.hpp similarity index 66% rename from src/json/mapnik_json_feature_collection_grammar.cpp rename to include/mapnik/json/parse_feature.hpp index e262d7cfc..b0d775e78 100644 --- a/src/json/mapnik_json_feature_collection_grammar.cpp +++ b/include/mapnik/json/parse_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,10 +20,22 @@ * *****************************************************************************/ -#include -#include -#include -using iterator_type = char const*; -template struct mapnik::json::feature_collection_grammar ; -template struct mapnik::json::feature_grammar_callback ; +#ifndef MAPNIK_JSON_PARSE_FEATURE_HPP +#define MAPNIK_JSON_PARSE_FEATURE_HPP + +#include +#include + +namespace mapnik { namespace json { + +template +void parse_feature(Iterator start, Iterator end, feature_impl& feature, mapnik::transcoder const& tr = mapnik::transcoder("utf8")); + +template +void parse_geometry(Iterator start, Iterator end, feature_impl& feature); + +}} + + +#endif // MAPNIK_JSON_PARSE_FEATURE_HPP diff --git a/include/mapnik/json/positions_grammar.hpp b/include/mapnik/json/positions_grammar.hpp deleted file mode 100644 index 6984300f9..000000000 --- a/include/mapnik/json/positions_grammar.hpp +++ /dev/null @@ -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 -#include -#pragma GCC diagnostic push -#include -#include -#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 > -struct positions_grammar : - qi::grammar -{ - positions_grammar(ErrorHandler & error_handler); - qi::rule coords; - qi::rule(), space_type> pos; - qi::rule ring; - qi::rule(), space_type> rings; - qi::rule >(), space_type> rings_array; -}; - -}} - -#endif // MAPNIK_JSON_POSITIONS_GRAMMAR_HPP diff --git a/include/mapnik/json/positions_grammar_impl.hpp b/include/mapnik/json/positions_grammar_impl.hpp deleted file mode 100644 index 65f2a93c0..000000000 --- a/include/mapnik/json/positions_grammar_impl.hpp +++ /dev/null @@ -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 -#include -// boost -#include -#include -#include -#include -#include -// stl -#include -#include - -namespace mapnik { namespace json { - -struct set_position_impl -{ - using result_type = void; - template - result_type operator() (T0 & coords, T1 const& pos) const - { - if (pos) coords = *pos; - } -}; - -struct push_position_impl -{ - using result_type = void; - template - result_type operator() (T0 & coords, T1 const& pos) const - { - if (pos) coords.emplace_back(*pos); - } -}; - -template -positions_grammar::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; - boost::phoenix::function 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(error_handler); - on_error(coords, error_handler_function(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/json/positions_grammar_x3.hpp b/include/mapnik/json/positions_grammar_x3.hpp new file mode 100644 index 000000000..55827907e --- /dev/null +++ b/include/mapnik/json/positions_grammar_x3.hpp @@ -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 +#include +#pragma GCC diagnostic pop + +// mapnik +#include +#include + +namespace mapnik { namespace json { + +namespace grammar { + +namespace x3 = boost::spirit::x3; +using positions_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(positions_grammar_type); + +} + +grammar::positions_grammar_type const& positions_grammar(); + +}} + +#endif // MAPNIK_JSON_POSITIONS_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/positions_grammar_x3_def.hpp b/include/mapnik/json/positions_grammar_x3_def.hpp new file mode 100644 index 000000000..7312ee79d --- /dev/null +++ b/include/mapnik/json/positions_grammar_x3_def.hpp @@ -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 +#include + +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 const point("Position"); +x3::rule const ring("Ring"); +x3::rule const rings("Rings"); +x3::rule 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 diff --git a/include/mapnik/json/positions.hpp b/include/mapnik/json/positions_x3.hpp similarity index 82% rename from include/mapnik/json/positions.hpp rename to include/mapnik/json/positions_x3.hpp index 9ad10f99a..38a56a647 100644 --- a/include/mapnik/json/positions.hpp +++ b/include/mapnik/json/positions_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 @@ -30,10 +30,11 @@ namespace mapnik { namespace json { struct empty {}; - -using position = mapnik::geometry::point; -using positions = std::vector; -using coordinates = util::variant, std::vector > > ; +using point = mapnik::geometry::point; +using ring = std::vector; +using rings = std::vector; +using rings_array = std::vector; +using positions = util::variant; }} diff --git a/include/mapnik/json/properties_generator_grammar.hpp b/include/mapnik/json/properties_generator_grammar.hpp index 69145b8ab..fd925b825 100644 --- a/include/mapnik/json/properties_generator_grammar.hpp +++ b/include/mapnik/json/properties_generator_grammar.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 @@ -23,7 +23,7 @@ #ifndef MAPNIK_JSON_PROPERTIES_GENERATOR_GRAMMAR_HPP #define MAPNIK_JSON_PROPERTIES_GENERATOR_GRAMMAR_HPP -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/json/properties_generator_grammar_impl.hpp b/include/mapnik/json/properties_generator_grammar_impl.hpp index eff4565b5..d3d81026f 100644 --- a/include/mapnik/json/properties_generator_grammar_impl.hpp +++ b/include/mapnik/json/properties_generator_grammar_impl.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 @@ -23,6 +23,12 @@ #include +#pragma GCC diagnostic push +#include +#include +#include +#pragma GCC diagnostic pop + namespace mapnik { namespace json { namespace karma = boost::spirit::karma; @@ -52,7 +58,7 @@ escaped_string::escaped_string() } template -properties_generator_grammar::properties_generator_grammar() +properties_generator_grammar::properties_generator_grammar() : properties_generator_grammar::base_type(properties), quote_("\"") { @@ -63,14 +69,13 @@ properties_generator_grammar::properties_generator boost::spirit::karma::string_type kstring; boost::spirit::karma::eps_type eps; using boost::phoenix::at_c; - properties = lit('{') << -(pair % lit(',')) << lit('}') ; pair = lit('"') - << kstring[_1 = boost::phoenix::at_c<0>(_val)] << lit('"') + << kstring[_1 = at_c<0>(_val)] << lit('"') << lit(':') << value[_1 = extract_string_(at_c<1>(_val))] ; @@ -80,13 +85,6 @@ properties_generator_grammar::properties_generator kstring[_1 = at_c<0>(_val)] ; - // FIXME http://boost-spirit.com/home/articles/karma-examples/creating-your-own-generator-component-for-spirit-karma/ - //value = (value_null_| bool_ | int__ | double_ | ustring)//[_1 = value_base_(_r1)] - // ; - //value_null_ = kstring[_1 = "null"] - // ; - //ustring = escaped_string_(quote_.c_str())[_1 = utf8_(_val)] - // ; } }} diff --git a/include/mapnik/json/stringifier.hpp b/include/mapnik/json/stringifier.hpp index 44b9425d8..af5a39778 100644 --- a/include/mapnik/json/stringifier.hpp +++ b/include/mapnik/json/stringifier.hpp @@ -24,7 +24,7 @@ #define MAPNIK_JSON_STRINGIFIER_HPP // mapnik -#include +#include #include #include // stl diff --git a/include/mapnik/json/topojson_grammar.hpp b/include/mapnik/json/topojson_grammar.hpp deleted file mode 100644 index c21be95fe..000000000 --- a/include/mapnik/json/topojson_grammar.hpp +++ /dev/null @@ -1,206 +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_TOPOJSON_GRAMMAR_HPP -#define MAPNIK_TOPOJSON_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -// stl -#include - -namespace mapnik { namespace topojson { - -namespace qi = boost::spirit::qi; -namespace fusion = boost::fusion; -using space_type = mapnik::json::space_type; - -struct create_point -{ - using result_type = mapnik::topojson::point; - template - result_type operator()(T0 & coord, T1 & props) const - { - mapnik::topojson::point pt; - if (coord.template is()) - { - auto const& coord_ = coord.template get(); - pt.coord = coord_; - pt.props = props; - } - return pt; - } -}; - -struct create_multi_point -{ - using result_type = mapnik::topojson::multi_point; - template - result_type operator()(T0 & coords, T1 & props) const - { - mapnik::topojson::multi_point mpt; - if (coords.template is>()) - { - auto const& points = coords.template get>(); - mpt. points = points; - mpt.props = props; - } - return mpt; - } -}; - -struct create_line_string -{ - using result_type = mapnik::topojson::linestring; - template - result_type operator()(T0 & arcs, T1 & props) const - { - mapnik::topojson::linestring line; - if (arcs.template is>()) - { - auto const& arcs_ = arcs.template get>(); - line.rings = arcs_; - line.props = props; - } - return line; - } -}; - -struct create_multi_line_string -{ - using result_type = mapnik::topojson::multi_linestring; - template - result_type operator()(T0 & arcs, T1 & props) const - { - mapnik::topojson::multi_linestring mline; - if (arcs.template is>>()) - { - auto const& arcs_ = arcs.template get>>(); - mline.lines = arcs_; - mline.props = props; - } - return mline; - } -}; - -struct create_polygon -{ - using result_type = mapnik::topojson::polygon; - template - result_type operator()(T0 & arcs, T1 & props) const - { - mapnik::topojson::polygon poly; - if (arcs.template is>>()) - { - auto const& arcs_ = arcs.template get>>(); - poly.rings = arcs_; - poly.props = props; - } - return poly; - } -}; - -struct create_multi_polygon -{ - using result_type = mapnik::topojson::multi_polygon; - template - result_type operator()(T0 & arcs, T1 & props) const - { - mapnik::topojson::multi_polygon mpoly; - if (arcs.template is>>>()) - { - auto const& arcs_ = arcs.template get>>>(); - mpoly.polygons = arcs_; - mpoly.props = props; - } - return mpoly; - } -}; - - -struct create_geometry_impl -{ - using result_type = mapnik::topojson::geometry; - template - result_type operator()(T0 geom_type, T1 & coord, T2 & arcs, T3 & props) const - { - switch (geom_type) - { - case 1: //Point - return create_point()(coord, props); - case 2: //LineString - return create_line_string()(arcs, props); - case 3: //Polygon - return create_polygon()(arcs, props); - case 4: //MultiPoint - return create_multi_point()(coord, props); - case 5: //MultiLineString - return create_multi_line_string()(arcs, props); - case 6: //MultiPolygon - return create_multi_polygon()(arcs, props); - default: - break; - } - return mapnik::topojson::geometry(); //empty - } -}; - -using coordinates_type = util::variant>; -using arcs_type = util::variant, std::vector>, std::vector>>>; -template > -struct topojson_grammar : qi::grammar - -{ - topojson_grammar(); -private: - // generic JSON support - json::generic_json json; - // topoJSON - qi::rule topology; - qi::rule()> objects; - qi::rule()> arcs; - qi::rule arc; - qi::rule coordinate_; - qi::rule coordinates; - qi::rule transform; - qi::rule bbox; - qi::rule, mapnik::topojson::geometry(), space_type> geometry; - qi::rule&)> geometry_collection; - qi::rule()> ring; - qi::rule>()> rings; - qi::rule rings_array; - // properties - qi::rule properties_; - qi::symbols geometry_type_dispatch; -}; - -}} - -#endif //MAPNIK_TOPOJSON_GRAMMAR_HPP diff --git a/include/mapnik/json/topojson_grammar_impl.hpp b/include/mapnik/json/topojson_grammar_impl.hpp deleted file mode 100644 index 07b3a9756..000000000 --- a/include/mapnik/json/topojson_grammar_impl.hpp +++ /dev/null @@ -1,206 +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 - * - *****************************************************************************/ - -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::coordinate, - (double, x) - (double, y) - ) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::arc, - (std::list, coordinates) - ) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::transform, - (double, scale_x) - (double, scale_y) - (double, translate_x) - (double, translate_y) - ) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::bounding_box, - (double, minx) - (double, miny) - (double, maxx) - (double, maxy) - ) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::topojson::topology, - (std::vector, geometries) - (std::vector, arcs) - (boost::optional, tr) - (boost::optional, bbox) - ) - - - -namespace mapnik { namespace topojson { - -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -namespace fusion = boost::fusion; - -template -topojson_grammar::topojson_grammar() - : topojson_grammar::base_type(topology, "topojson") -{ - qi::lit_type lit; - qi::double_type double_; - qi::int_type int_; - qi::omit_type omit; - qi::_val_type _val; - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_r1_type _r1; - qi::_a_type _a; - qi::_b_type _b; - qi::_c_type _c; - qi::_d_type _d; - using qi::fail; - using qi::on_error; - using phoenix::push_back; - - geometry_type_dispatch.add - ("\"Point\"",1) - ("\"LineString\"",2) - ("\"Polygon\"",3) - ("\"MultiPoint\"",4) - ("\"MultiLineString\"",5) - ("\"MultiPolygon\"",6) - ("\"GeometryCollection\"",7) - ; - - // error handler - boost::phoenix::function const error_handler; - boost::phoenix::function const create_geometry; - - // topo json - topology = lit('{') >> lit("\"type\"") >> lit(':') >> lit("\"Topology\"") - >> ( (lit(',') >> objects ) ^ ( lit(',') >> arcs) ^ (lit(',') >> transform) ^ (lit(',') >> bbox)) - >> lit('}') - ; - - transform = lit("\"transform\"") >> lit(':') >> lit('{') - >> lit("\"scale\"") >> lit(':') - >> lit('[') - >> double_ >> lit(',') - >> double_ >> lit(']') >> lit(',') - >> lit("\"translate\"") >> lit(':') - >> lit('[') >> double_ >> lit(',') >> double_ >> lit(']') - >> lit('}') - ; - - bbox = lit("\"bbox\"") >> lit(':') - >> lit('[') >> double_ >> lit(',') >> double_ - >> lit(',') >> double_ >> lit(',') >> double_ - >> lit(']') - ; - - objects = lit("\"objects\"") - >> lit(':') - >> lit('{') - >> -((omit[json.string_] - >> lit(':') - >> (geometry_collection(_val) | geometry[push_back(_val, _1)]) % lit(','))) - >> lit('}') - ; - - geometry = lit('{')[_a = 0] - > ((lit("\"type\"") > lit(':') > geometry_type_dispatch[_a = _1]) - | - (lit("\"coordinates\"") > lit(':') > coordinates[_b = _1]) - | - (lit("\"arcs\"") > lit(':') > rings_array[_c = _1]) - | - properties_[_d = _1] - | - json.key_value) % lit(',') - > lit('}')[_val = create_geometry(_a, _b, _c, _d)] - ; - - - geometry_collection = lit('{') - >> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"") - >> lit(',') >> lit("\"geometries\"") >> lit(':') - >> lit('[') - >> -(geometry[push_back(_r1, _1)] % lit(',')) - >> lit(']') - >> lit('}') - ; - - ring = lit('[') >> -(int_ % lit(',')) >> lit(']') - ; - rings = lit('[') >> -(ring % lit(',')) >> lit(']') - ; - rings_array = lit('[') >> -(rings % lit(',')) >> lit(']') - | - rings - | - ring - ; - - properties_ = lit("\"properties\"") - >> lit(':') - >> lit('{') >> (json.string_ >> lit(':') >> json.value) % lit(',') >> lit('}') - ; - - arcs = lit("\"arcs\"") >> lit(':') - >> lit('[') >> -( arc % lit(',')) >> lit(']') ; - - arc = lit('[') >> -(coordinate_ % lit(',')) >> lit(']') ; - - coordinate_ = lit('[') > double_ > lit(',') > double_ > lit(']'); - - coordinates = (lit('[') >> coordinate_ % lit(',') > lit(']')) - | coordinate_; - - topology.name("topology"); - transform.name("transform"); - objects.name("objects"); - arc.name("arc"); - arcs.name("arcs"); - json.value.name("value"); - coordinate_.name("coordinate"); - geometry.name("geometry"); - properties_.name("properties"); - geometry_collection.name("geometry_collection"); - // error handler - on_error(topology, error_handler(_1, _2, _3, _4)); -} - -}} diff --git a/include/mapnik/json/topojson_grammar_x3.hpp b/include/mapnik/json/topojson_grammar_x3.hpp new file mode 100644 index 000000000..6f5d58eb0 --- /dev/null +++ b/include/mapnik/json/topojson_grammar_x3.hpp @@ -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_TOPOJSON_GRAMMAR_X3_HPP +#define MAPNIK_TOPOJSON_GRAMMAR_X3_HPP + +// mapnik +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using topojson_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(topojson_grammar_type); + +} + +grammar::topojson_grammar_type const& topojson_grammar(); + +}} + +#endif //MAPNIK_TOPOJSON_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/topojson_grammar_x3_def.hpp b/include/mapnik/json/topojson_grammar_x3_def.hpp new file mode 100644 index 000000000..bddbed3eb --- /dev/null +++ b/include/mapnik/json/topojson_grammar_x3_def.hpp @@ -0,0 +1,445 @@ +/***************************************************************************** + * + * 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_TOPOJSON_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_TOPOJSON_GRAMMAR_X3_DEF_HPP + +#include +#include +#include +#pragma GCC diagnostic push +#include +#include +#include +#pragma GCC diagnostic pop + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::topojson::coordinate, + (double, x) + (double, y) + ) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::topojson::arc, + (std::list, coordinates) + ) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::topojson::transform, + (double, scale_x) + (double, scale_y) + (double, translate_x) + (double, translate_y) + ) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::topojson::bounding_box, + (double, minx) + (double, miny) + (double, maxx) + (double, maxy) + ) + +namespace mapnik { namespace json { namespace grammar { + +using index_type = topojson::index_type; +struct create_point +{ + using result_type = mapnik::topojson::point; + template + result_type operator()(T0 & coord, T1 & props) const + { + mapnik::topojson::point pt; + if (coord.template is()) + { + auto const& coord_ = coord.template get(); + pt.coord = coord_; + pt.props = props; + } + return pt; + } +}; + +struct create_multi_point +{ + using result_type = mapnik::topojson::multi_point; + template + result_type operator()(T0 & coords, T1 & props) const + { + mapnik::topojson::multi_point mpt; + if (coords.template is>()) + { + auto const& points = coords.template get>(); + mpt. points = points; + mpt.props = props; + } + return mpt; + } +}; + +struct create_line_string +{ + using result_type = mapnik::topojson::linestring; + template + result_type operator()(T0 & arcs, T1 & props) const + { + mapnik::topojson::linestring line; + if (arcs.template is>()) + { + auto const& arcs_ = arcs.template get>(); + line.rings = arcs_; + line.props = props; + } + return line; + } +}; + +struct create_multi_line_string +{ + using result_type = mapnik::topojson::multi_linestring; + template + result_type operator()(T0 & arcs, T1 & props) const + { + mapnik::topojson::multi_linestring mline; + if (arcs.template is>>()) + { + auto const& arcs_ = arcs.template get>>(); + mline.lines = arcs_; + mline.props = props; + } + return mline; + } +}; + +struct create_polygon +{ + using result_type = mapnik::topojson::polygon; + template + result_type operator()(T0 & arcs, T1 & props) const + { + mapnik::topojson::polygon poly; + if (arcs.template is>>()) + { + auto const& arcs_ = arcs.template get>>(); + poly.rings = arcs_; + poly.props = props; + } + return poly; + } +}; + +struct create_multi_polygon +{ + using result_type = mapnik::topojson::multi_polygon; + template + result_type operator()(T0 & arcs, T1 & props) const + { + mapnik::topojson::multi_polygon mpoly; + if (arcs.template is>>>()) + { + auto const& arcs_ = arcs.template get>>>(); + mpoly.polygons = arcs_; + mpoly.props = props; + } + return mpoly; + } +}; + + +auto create_geometry = [] (auto const& ctx) +{ + auto const geom_type = std::get<0>(_attr(ctx)); + auto const& coord = std::get<1>(_attr(ctx)); + auto const& arcs = std::get<2>(_attr(ctx)); + auto const& props = std::get<3>(_attr(ctx)); + mapnik::topojson::geometry geom; //empty + switch (geom_type) + { + case 1: //Point + geom = create_point()(coord, props); + break; + case 2: //LineString + geom = create_line_string()(arcs, props); + break; + case 3: //Polygon + geom = create_polygon()(arcs, props); + break; + case 4: //MultiPoint + geom = create_multi_point()(coord, props); + break; + case 5: //MultiLineString + geom = create_multi_line_string()(arcs, props); + break; + case 6: //MultiPolygon + geom = create_multi_polygon()(arcs, props); + break; + } + _val(ctx) = std::move(geom); +}; + + +auto assign_bbox = [] (auto const& ctx) +{ + _val(ctx).bbox = std::move(_attr(ctx)); +}; + +auto assign_transform = [] (auto const& ctx) +{ + _val(ctx).tr = std::move(_attr(ctx)); +}; + +auto assign_arcs = [] (auto const& ctx) +{ + _val(ctx).arcs = std::move(_attr(ctx)); +}; + +auto assign_objects = [] (auto const& ctx) +{ + _val(ctx).geometries = std::move(_attr(ctx)); +}; + + +auto push_geometry = [] (auto const& ctx) +{ + _val(ctx).push_back(std::move(_attr(ctx))); +}; + +auto push_collection = [] (auto const& ctx) +{ + auto & dest = _val(ctx); + auto & src = _attr(ctx); + if (dest.empty()) dest = std::move(src); + else + { + dest.reserve(dest.size() + src.size()); + dest.insert(std::end(dest), + std::make_move_iterator(std::begin(src)), + std::make_move_iterator(std::end(src))); + } +}; + + +auto assign_geometry_type = [] (auto const& ctx) +{ + std::get<0>(_val(ctx)) = _attr(ctx); +}; + +auto assign_coordinates = [] (auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_rings = [] (auto const& ctx) +{ + std::get<2>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_properties = [] (auto const& ctx) +{ + std::get<3>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_prop_name = [] (auto const& ctx) +{ + std::get<0>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_prop_value = [] (auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +namespace x3 = boost::spirit::x3; + +using x3::lit; +using x3::double_; +using x3::int_; +using x3::omit; +using x3::char_; +namespace +{ +// import unicode string rule +auto const& json_string = json::unicode_string_grammar(); +// json value +auto const& json_value = json::generic_json_grammar(); +} + +using coordinates_type = util::variant>; +using arcs_type = util::variant, + std::vector>, + std::vector>>>; + +struct geometry_type_ : x3::symbols +{ + geometry_type_() + { + add + ("\"Point\"",1) + ("\"LineString\"",2) + ("\"Polygon\"",3) + ("\"MultiPoint\"",4) + ("\"MultiLineString\"",5) + ("\"MultiPolygon\"",6) + ; + } +} geometry_type; + +// start rule +topojson_grammar_type const topology = "Topology"; +// rules +x3::rule const transform = "Transform"; +x3::rule const bbox = "Bounding Box"; +x3::rule> const objects= "Objects"; +x3::rule const property = "Property"; +x3::rule const properties = "Properties"; +x3::rule const geometry = "Geometry"; +x3::rule> const geometry_collection = "Geometry Collection"; +x3::rule> const geometry_tuple = "Geometry Tuple"; +x3::rule const coordinate = "Coordinate"; +x3::rule const coordinates = "Coordinates"; +x3::rule const arc = "Arc"; +x3::rule> const arcs = "Arcs"; +x3::rule> const ring = "Ring"; +x3::rule>> const rings = "Rings"; +x3::rule const rings_array = "Rings Array"; + +// defs +auto const topology_def = lit('{') > + -(((lit("\"type\"") > lit(':') > lit("\"Topology\"")) + | + bbox[assign_bbox] + | + transform[assign_transform] + | + objects[assign_objects] + | + arcs[assign_arcs]) % lit(',')) + > lit('}') + ; + + +auto const transform_def = lit("\"transform\"") > lit(':') > lit('{') + > lit("\"scale\"") > lit(':') + > lit('[') + > double_ > lit(',') + > double_ > lit(']') > lit(',') + > lit("\"translate\"") > lit(':') + > lit('[') > double_ > lit(',') > double_ > lit(']') + > lit('}') + ; + +auto const bbox_def = lit("\"bbox\"") > lit(':') + > lit('[') > double_ > lit(',') > double_ + > lit(',') > double_ > lit(',') > double_ + > lit(']') + ; + + +auto const objects_def = lit("\"objects\"") > lit(':') + > lit('{') + > ((omit[*~char_(':')] > lit(':') > ((geometry_collection[push_collection] | geometry[push_geometry]))) % lit(',')) + > lit('}') + ; + +auto const geometry_tuple_def = + ((lit("\"type\"") > lit(':') > geometry_type[assign_geometry_type]) + | + (lit("\"coordinates\"") > lit(':') > coordinates[assign_coordinates]) + | + (lit("\"arcs\"") > lit(':') > rings_array[assign_rings]) + | + properties[assign_properties] + | + (omit[json_string] > lit(':') > omit[json_value])) % lit(',') + ; + +auto const geometry_def = lit("{") > geometry_tuple[create_geometry] > lit("}"); + +auto const geometry_collection_def = (lit('{') >> lit("\"type\"") >> lit(':') >> lit("\"GeometryCollection\"") >> -omit[lit(',') >> bbox]) + > lit(',') > lit("\"geometries\"") > lit(':') + > lit('[') + > -(geometry[push_geometry] % lit(',')) + > lit(']') + > lit('}') + ; + + +auto const ring_def = lit('[') >> (int_ % lit(',')) >> lit(']') + ; +auto const rings_def = lit('[') >> (ring % lit(',')) >> lit(']') + ; +auto const rings_array_def = (lit('[') >> (rings % lit(',')) >> lit(']')) + | + rings + | + ring + ; + +auto const property_def = json_string[assign_prop_name] > lit(':') > json_value[assign_prop_value] + ; + +auto const properties_def = lit("\"properties\"") + > lit(':') + > lit('{') > (property % lit(',')) > lit('}') + ; + +auto const arcs_def = lit("\"arcs\"") >> lit(':') >> lit('[') >> -( arc % lit(',')) >> lit(']') ; + +auto const arc_def = lit('[') >> -(coordinate % lit(',')) >> lit(']') ; + +auto const coordinate_def = lit('[') >> double_ >> lit(',') >> double_ >> omit[*(lit(',') >> double_)] >> lit(']'); + +auto const coordinates_def = (lit('[') >> coordinate % lit(',') >> lit(']')) | coordinate; + +BOOST_SPIRIT_DEFINE( + topology, + transform, + bbox, + objects, + geometry_tuple, + geometry, + geometry_collection, + ring, + rings, + rings_array, + property, + properties, + arcs, + arc, + coordinate, + coordinates + ); + +}}} + +namespace mapnik { namespace json { +grammar::topojson_grammar_type const& topojson_grammar() +{ + return grammar::topology; +} +}} + +#endif //MAPNIK_TOPOJSON_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp index dc4166475..0ac888602 100644 --- a/include/mapnik/json/topojson_utils.hpp +++ b/include/mapnik/json/topojson_utils.hpp @@ -24,13 +24,13 @@ #define MAPNIK_TOPOJSON_UTILS_HPP // mapnik -#include +#include #include #include #include #include -#include -#include +#include +#include namespace mapnik { namespace topojson { diff --git a/include/mapnik/json/topology.hpp b/include/mapnik/json/topology.hpp index 048c85528..97d44f7b6 100644 --- a/include/mapnik/json/topology.hpp +++ b/include/mapnik/json/topology.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 @@ -23,7 +23,7 @@ #ifndef MAPNIK_TOPOLOGY_HPP #define MAPNIK_TOPOLOGY_HPP -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/json/unicode_string_grammar_x3.hpp b/include/mapnik/json/unicode_string_grammar_x3.hpp new file mode 100644 index 000000000..4415a0046 --- /dev/null +++ b/include/mapnik/json/unicode_string_grammar_x3.hpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_HPP +#define MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_HPP + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + + +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; +class unicode_string_tag; +using unicode_string_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(unicode_string_grammar_type); + +} + +grammar::unicode_string_grammar_type const& unicode_string_grammar(); + +}} + +#endif // MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_HPP diff --git a/include/mapnik/json/unicode_string_grammar_x3_def.hpp b/include/mapnik/json/unicode_string_grammar_x3_def.hpp new file mode 100644 index 000000000..fd0bcebe1 --- /dev/null +++ b/include/mapnik/json/unicode_string_grammar_x3_def.hpp @@ -0,0 +1,159 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_DEF_HPP +#define MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_DEF_HPP + +#include +// boost +#include +// +namespace mapnik { namespace json { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using uchar = std::uint32_t; // a unicode code point + +auto append = [](auto const& ctx) +{ + _val(ctx) += _attr(ctx); +}; + +namespace detail { + +void push_utf8_impl(std::string & str, uchar code_point) +{ + using insert_iterator = std::back_insert_iterator; + insert_iterator iter(str); + boost::utf8_output_iterator utf8_iter(iter); + *utf8_iter++ = code_point; +} +} + +auto push_char = [](auto const& ctx) { _val(ctx).push_back(_attr(ctx));}; + +auto push_utf8 = [](auto const& ctx) { detail::push_utf8_impl(_val(ctx), _attr(ctx));}; + +auto push_utf16 = [](auto const& ctx) +{ + using iterator_type = std::vector::const_iterator; + auto const& utf16 = _attr(ctx); + try + { + boost::u16_to_u32_iterator itr(utf16.begin()); + boost::u16_to_u32_iterator end(utf16.end()); + for (; itr != end; ++itr) + { + detail::push_utf8_impl(_val(ctx), *itr); + } + } + catch( ... ) + { + // caught + } +}; + +auto push_esc = [] (auto const& ctx) +{ + std::string & utf8 = _val(ctx); + char c = _attr(ctx); + switch (c) + { + case ' ': utf8 += ' '; break; + case '\t': utf8 += '\t'; break; + case '0': utf8 += char(0); break; + case 'a': utf8 += 0x7; break; + case 'b': utf8 += 0x8; break; + case 't': utf8 += 0x9; break; + case 'n': utf8 += 0xA; break; + case 'v': utf8 += 0xB; break; + case 'f': utf8 += 0xC; break; + case 'r': utf8 += 0xD; break; + case 'e': utf8 += 0x1B; break; + case '"': utf8 += '"'; break; + case '/': utf8 += '/'; break; + case '\\': utf8 += '\\'; break; + case '_': detail::push_utf8_impl(utf8, 0xA0); break; + case 'N': detail::push_utf8_impl(utf8, 0x85); break; + case 'L': detail::push_utf8_impl(utf8, 0x2028); break; + case 'P': detail::push_utf8_impl(utf8, 0x2029); break; + } +}; + +using x3::lit; +using x3::char_; +using x3::eol; +using x3::no_skip; + +x3::uint_parser const hex2 {}; +x3::uint_parser const hex4 {}; +x3::uint_parser const hex8 {}; + +// start rule +unicode_string_grammar_type const unicode_string("Unicode String"); +// rules +x3::rule const double_quoted("Double-quoted string"); +x3::rule const escaped("Escaped Character"); +x3::rule const escaped_unicode("Escaped Unicode code point(s)"); +x3::rule> const utf16_string("UTF16 encoded string"); + +auto unicode_string_def = double_quoted + ; +auto utf16_string_def = lit('u') > hex4 > *(lit("\\u") > hex4) + ; +auto escaped_unicode_def = + (lit('x') > hex2[push_char]) + | + utf16_string[push_utf16] + | + (lit('U') > hex8[push_utf8]) + ; +auto const escaped_def = lit('\\') > + (escaped_unicode[append] + | + char_("0abtnvfre\"/\\N_LP \t")[push_esc] + | + eol) // continue to next line + ; +auto const double_quoted_def = lit('"') > no_skip[*(escaped[append] | (~char_('"'))[append])] > lit('"'); + +#pragma GCC diagnostic push +#include + +BOOST_SPIRIT_DEFINE( + unicode_string, + double_quoted, + escaped, + escaped_unicode, + utf16_string + ); + +#pragma GCC diagnostic pop + +} +grammar::unicode_string_grammar_type const& unicode_string_grammar() +{ + return grammar::unicode_string; +} +}} + +#endif // MAPNIK_JSON_UNICODE_STRING_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/json/value_converters.hpp b/include/mapnik/json/value_converters.hpp index 384ecb88c..1f92aa97b 100644 --- a/include/mapnik/json/value_converters.hpp +++ b/include/mapnik/json/value_converters.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 diff --git a/include/mapnik/label_collision_detector.hpp b/include/mapnik/label_collision_detector.hpp index f751f31c3..135a6daa8 100644 --- a/include/mapnik/label_collision_detector.hpp +++ b/include/mapnik/label_collision_detector.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 @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #pragma GCC diagnostic push #include diff --git a/include/mapnik/layer.hpp b/include/mapnik/layer.hpp index a00b4885f..43e8760c2 100644 --- a/include/mapnik/layer.hpp +++ b/include/mapnik/layer.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 @@ -25,7 +25,8 @@ // mapnik #include -#include +#include +#include // stl #include @@ -96,6 +97,18 @@ public: */ std::vector& styles(); + /*! \brief Add a child layer by copying it. + * @param l The layer to add. + */ + void add_layer(layer const& l); + + /*! \brief Add a child layer by moving it. + * @param l The layer to add. + */ + void add_layer(layer && l); + + std::vector const& layers() const; + /*! * @param minimum_scale_denom The minimum scale denominator */ @@ -197,6 +210,12 @@ public: */ box2d envelope() const; + // compositing + void set_comp_op(composite_mode_e comp_op); + boost::optional comp_op() const; + void set_opacity(double opacity); + double get_opacity() const; + void set_maximum_extent(box2d const& box); boost::optional > const& maximum_extent() const; void reset_maximum_extent(); @@ -215,9 +234,12 @@ private: bool cache_features_; std::string group_by_; std::vector styles_; + std::vector layers_; datasource_ptr ds_; boost::optional buffer_size_; boost::optional > maximum_extent_; + boost::optional comp_op_; + double opacity_; }; } diff --git a/include/mapnik/load_map.hpp b/include/mapnik/load_map.hpp index 30a04eb07..4ec42d55d 100644 --- a/include/mapnik/load_map.hpp +++ b/include/mapnik/load_map.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 diff --git a/include/mapnik/make_unique.hpp b/include/mapnik/make_unique.hpp index f6fd4a230..b967a5241 100644 --- a/include/mapnik/make_unique.hpp +++ b/include/mapnik/make_unique.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 @@ -23,11 +23,11 @@ #ifndef MAPNIK_MAKE_UNIQUE_HPP #define MAPNIK_MAKE_UNIQUE_HPP -#include - // http://stackoverflow.com/questions/14131454/visual-studio-2012-cplusplus-and-c-11 #if defined(_MSC_VER) && _MSC_VER < 1800 || !defined(_MSC_VER) && __cplusplus <= 201103L +#include + namespace std { // C++14 backfill from http://herbsutter.com/gotw/_102/ diff --git a/include/mapnik/map.hpp b/include/mapnik/map.hpp index 9f582791b..309be53de 100644 --- a/include/mapnik/map.hpp +++ b/include/mapnik/map.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/mapnik/mapped_memory_cache.hpp b/include/mapnik/mapped_memory_cache.hpp index 1ac8d877e..d00f4396b 100644 --- a/include/mapnik/mapped_memory_cache.hpp +++ b/include/mapnik/mapped_memory_cache.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 diff --git a/include/mapnik/marker.hpp b/include/mapnik/marker.hpp index 1feb0fecf..e4222e10f 100644 --- a/include/mapnik/marker.hpp +++ b/include/mapnik/marker.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 diff --git a/include/mapnik/marker_cache.hpp b/include/mapnik/marker_cache.hpp index 47aa5558e..5a59eaca3 100644 --- a/include/mapnik/marker_cache.hpp +++ b/include/mapnik/marker_cache.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 diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp index 8ba3c6f4b..fc688c16c 100644 --- a/include/mapnik/marker_helpers.hpp +++ b/include/mapnik/marker_helpers.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 @@ -25,14 +25,14 @@ #include #include -#include -#include +#include +#include #include #include #include // for svg_storage_type #include #include -#include +#include #include #include #include @@ -50,8 +50,6 @@ namespace mapnik { struct clip_poly_tag; -using svg_attribute_type = agg::pod_bvector; - template struct vector_markers_dispatch : util::noncopyable { diff --git a/include/mapnik/markers_placement.hpp b/include/mapnik/markers_placement.hpp index 0d4319115..c164f307a 100644 --- a/include/mapnik/markers_placement.hpp +++ b/include/mapnik/markers_placement.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 diff --git a/include/mapnik/markers_placements/basic.hpp b/include/mapnik/markers_placements/basic.hpp index abcef5ea6..15233bafa 100644 --- a/include/mapnik/markers_placements/basic.hpp +++ b/include/mapnik/markers_placements/basic.hpp @@ -24,7 +24,7 @@ #define MAPNIK_MARKERS_PLACEMENTS_BASIC_HPP // mapnik -#include +#include #include #include #include diff --git a/include/mapnik/markers_placements/interior.hpp b/include/mapnik/markers_placements/interior.hpp index 6a2705e15..987c28991 100644 --- a/include/mapnik/markers_placements/interior.hpp +++ b/include/mapnik/markers_placements/interior.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 @@ -25,7 +25,7 @@ #include #include -#include +#include namespace mapnik { diff --git a/include/mapnik/markers_placements/line.hpp b/include/mapnik/markers_placements/line.hpp index bc99cc937..c1ab435c6 100644 --- a/include/mapnik/markers_placements/line.hpp +++ b/include/mapnik/markers_placements/line.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 @@ -27,7 +27,7 @@ #include #include #include -#include +#include namespace mapnik { diff --git a/include/mapnik/markers_placements/point.hpp b/include/mapnik/markers_placements/point.hpp index 6e2f1dafb..7ae070a70 100644 --- a/include/mapnik/markers_placements/point.hpp +++ b/include/mapnik/markers_placements/point.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 @@ -24,7 +24,7 @@ #define MAPNIK_MARKERS_PLACEMENTS_POINT_HPP #include -#include +#include #include namespace mapnik { diff --git a/include/mapnik/markers_placements/vertext_first.hpp b/include/mapnik/markers_placements/vertext_first.hpp index ce1b415b3..59943c709 100644 --- a/include/mapnik/markers_placements/vertext_first.hpp +++ b/include/mapnik/markers_placements/vertext_first.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 diff --git a/include/mapnik/markers_placements/vertext_last.hpp b/include/mapnik/markers_placements/vertext_last.hpp index 62c94a66a..077fd8eca 100644 --- a/include/mapnik/markers_placements/vertext_last.hpp +++ b/include/mapnik/markers_placements/vertext_last.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 diff --git a/include/mapnik/memory_datasource.hpp b/include/mapnik/memory_datasource.hpp index 9b589741f..11a64069d 100644 --- a/include/mapnik/memory_datasource.hpp +++ b/include/mapnik/memory_datasource.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 diff --git a/include/mapnik/memory_featureset.hpp b/include/mapnik/memory_featureset.hpp index cc5005b42..2f3cb6f07 100644 --- a/include/mapnik/memory_featureset.hpp +++ b/include/mapnik/memory_featureset.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 @@ -24,9 +24,9 @@ #define MAPNIK_MEMORY_FEATURESET_HPP // mapnik -#include +#include #include -#include +#include #include #include #include diff --git a/include/mapnik/octree.hpp b/include/mapnik/octree.hpp index 007e6960e..f085f219b 100644 --- a/include/mapnik/octree.hpp +++ b/include/mapnik/octree.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 diff --git a/include/mapnik/offset_converter.hpp b/include/mapnik/offset_converter.hpp index 310ed808a..c54f3b5f9 100644 --- a/include/mapnik/offset_converter.hpp +++ b/include/mapnik/offset_converter.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 @@ -77,18 +77,18 @@ struct offset_converter return threshold_; } - void set_offset(double value) + void set_offset(double val) { - if (offset_ != value) + if (offset_ != val) { - offset_ = value; + offset_ = val; reset(); } } - void set_threshold(double value) + void set_threshold(double val) { - threshold_ = value; + threshold_ = val; // no need to reset(), since threshold doesn't affect // offset vertices' computation, it only controls how // far will we be looking for self-intersections @@ -269,7 +269,7 @@ private: if (position < -1e-6) return -1; return 0; } - + void displace2(vertex2d & v1, vertex2d const& v0, vertex2d const& v2, double a, double b) const { double sa = offset_ * std::sin(a); @@ -284,14 +284,14 @@ private: double abs_hcasa = std::abs(hcasa); double abs_hsa = std::abs(hsa); double abs_hca = std::abs(hca); - - vertex2d v_tmp(vertex2d::no_init); + + vertex2d v_tmp(vertex2d::no_init); v_tmp.x = v1.x - sa - hca; v_tmp.y = v1.y + ca - hsa; v_tmp.cmd = v1.cmd; - + int same = point_line_position(v0, v2, v_tmp)*point_line_position(v0, v2, v1); - + if (same >= 0 && std::abs(h) < 10) { v1.x = v_tmp.x; @@ -314,14 +314,14 @@ private: v1.y = v1.y + ca - hsa; } else - { + { if (abs_hsaca*abs_hsaca + abs_hcasa*abs_hcasa > abs_offset*abs_offset) { double d = (abs_hsaca*abs_hsaca + abs_hcasa*abs_hcasa); d = d < 1e-6 ? 1. : d; double scale = (abs_offset*abs_offset)/d; v1.x = v1.x + hcasa*scale; - v1.y = v1.y + hsaca*scale; + v1.y = v1.y + hsaca*scale; } else { @@ -330,8 +330,7 @@ private: } } } - - + status init_vertices() { if (status_ != initial) // already initialized @@ -482,8 +481,9 @@ private: } start_v2.x = v2.x; start_v2.y = v2.y; + vertex2d tmp_prev(vertex2d::no_init); - + while (i < points.size()) { v1 = v2; @@ -576,7 +576,7 @@ private: tmp_prev.cmd = v1.cmd; tmp_prev.x = v1.x; tmp_prev.y = v1.y; - + if (v1.cmd == SEG_MOVETO) { if (bulge_steps == 0) diff --git a/include/mapnik/palette.hpp b/include/mapnik/palette.hpp index 1276d1302..2f5dc3091 100644 --- a/include/mapnik/palette.hpp +++ b/include/mapnik/palette.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 diff --git a/include/mapnik/params.hpp b/include/mapnik/params.hpp index 535cacb38..f53a4e651 100644 --- a/include/mapnik/params.hpp +++ b/include/mapnik/params.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/params_impl.hpp b/include/mapnik/params_impl.hpp index f127c4cf2..f7534d666 100644 --- a/include/mapnik/params_impl.hpp +++ b/include/mapnik/params_impl.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #include diff --git a/include/mapnik/parse_path.hpp b/include/mapnik/parse_path.hpp index e5b5882ab..3b1eb2524 100644 --- a/include/mapnik/parse_path.hpp +++ b/include/mapnik/parse_path.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 diff --git a/include/mapnik/path.hpp b/include/mapnik/path.hpp index fc1cdab1a..3f713a553 100644 --- a/include/mapnik/path.hpp +++ b/include/mapnik/path.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include namespace mapnik { namespace detail { @@ -70,9 +70,9 @@ public: return static_cast(type_ >> geometry_bits); } - void set_type(types type) + void set_type(types _type) { - type_ = type; + type_ = _type; } container_type const& data() const diff --git a/include/mapnik/path_expression.hpp b/include/mapnik/path_expression.hpp index b3dde7dab..1cc4a949d 100644 --- a/include/mapnik/path_expression.hpp +++ b/include/mapnik/path_expression.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 diff --git a/include/mapnik/path_expression_grammar_x3.hpp b/include/mapnik/path_expression_grammar_x3.hpp new file mode 100644 index 000000000..60bfd2bb4 --- /dev/null +++ b/include/mapnik/path_expression_grammar_x3.hpp @@ -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_PATH_EXPRESSIONS_GRAMMAR_X3_HPP +#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP + +// mapnik +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +struct path_expression_class; // top-most ID +using path_expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(path_expression_grammar_type); + +} + +grammar::path_expression_grammar_type const& path_expression_grammar(); + +} + +#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP diff --git a/include/mapnik/path_expression_grammar_x3_def.hpp b/include/mapnik/path_expression_grammar_x3_def.hpp new file mode 100644 index 000000000..73e940a5c --- /dev/null +++ b/include/mapnik/path_expression_grammar_x3_def.hpp @@ -0,0 +1,63 @@ +/***************************************************************************** + * + * 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_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP +#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP +// mapnik +#include +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using x3::standard_wide::char_; +using x3::lexeme; +auto create_string = [](auto & ctx) { _val(ctx).push_back(_attr(ctx)); }; +auto create_attribute = [](auto & ctx) { _val(ctx).push_back(mapnik::attribute(_attr(ctx))); }; +// top-most rule +path_expression_grammar_type const path_expression("path_expression"); +// rules +x3::rule const attr_expression("attribute"); +x3::rule const str_expression("string"); + +auto const attr_expression_def = +(char_ - ']'); +auto const str_expression_def = lexeme[+(char_ -'[')]; +auto const path_expression_def = *(str_expression[create_string] | ('[' > attr_expression[create_attribute] > ']')); + +BOOST_SPIRIT_DEFINE( + path_expression, + attr_expression, + str_expression +); + +}} + +namespace mapnik { + +grammar::path_expression_grammar_type const& path_expression_grammar() +{ + return grammar::path_expression; +} + +} + +#endif //MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/pixel_position.hpp b/include/mapnik/pixel_position.hpp index 93cdb4f7f..09381345c 100644 --- a/include/mapnik/pixel_position.hpp +++ b/include/mapnik/pixel_position.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 diff --git a/include/mapnik/pixel_types.hpp b/include/mapnik/pixel_types.hpp index b0d6304b3..f341155c8 100644 --- a/include/mapnik/pixel_types.hpp +++ b/include/mapnik/pixel_types.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 diff --git a/include/mapnik/plugin.hpp b/include/mapnik/plugin.hpp index 68e7de620..99c1e8d1e 100644 --- a/include/mapnik/plugin.hpp +++ b/include/mapnik/plugin.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 diff --git a/include/mapnik/png_io.hpp b/include/mapnik/png_io.hpp index 9f8b38d8f..827df4cdb 100644 --- a/include/mapnik/png_io.hpp +++ b/include/mapnik/png_io.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 @@ -48,14 +48,17 @@ namespace mapnik { struct png_options { int colors; + int filters; int compression; int strategy; int trans_mode; double gamma; bool paletted; bool use_hextree; + png_options() : colors(256), + filters(PNG_FILTER_NONE), compression(Z_DEFAULT_COMPRESSION), strategy(Z_DEFAULT_STRATEGY), trans_mode(-1), @@ -97,7 +100,7 @@ void save_as_png(T1 & file, mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags | mask); #endif - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE); + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, opts.filters); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { @@ -120,7 +123,7 @@ void save_as_png(T1 & file, (opts.trans_mode == 0) ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA,PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT); const std::unique_ptr row_pointers(new png_bytep[image.height()]); - for (unsigned int i = 0; i < image.height(); i++) + for (unsigned int i = 0; i < image.height(); ++i) { row_pointers[i] = const_cast(reinterpret_cast(image.get_row(i))); } @@ -141,7 +144,7 @@ void reduce_8(T const& in, unsigned height = in.height(); std::vector alphaCount(alpha.size()); - for(unsigned i=0; i0; j--) + for(int j=levels-1; j>0; --j) { if (U2ALPHA(val)>=limits[j] && trees[j].colors()>0) { @@ -166,12 +169,12 @@ void reduce_8(T const& in, if (idx>=0 && idx < static_cast(alpha.size())) { alpha[idx]+=U2ALPHA(val); - alphaCount[idx]++; + ++alphaCount[idx]; } row_out[x] = index; } } - for(unsigned i=0; i alphaCount(alpha.size()); - for(unsigned i=0; i0; j--) + for(int j=levels-1; j>0; --j) { if (U2ALPHA(val)>=limits[j] && trees[j].colors()>0) { @@ -217,7 +220,7 @@ void reduce_4(T const& in, if (idx>=0 && idx < static_cast(alpha.size())) { alpha[idx]+=U2ALPHA(val); - alphaCount[idx]++; + ++alphaCount[idx]; } if (x%2 == 0) { @@ -226,7 +229,7 @@ void reduce_4(T const& in, row_out[x>>1] |= index; } } - for(unsigned i=0; i const& palette, unsigned width, unsigned height, unsigned color_depth, - std::vector const&alpha, + std::vector const& alpha, png_options const& opts) { png_voidp error_ptr=0; @@ -271,7 +274,7 @@ void save_as_png(T & file, std::vector const& palette, mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags | mask); #endif - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE); + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, opts.filters); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { @@ -302,7 +305,7 @@ void save_as_png(T & file, std::vector const& palette, { std::vector trans(alpha.size()); unsigned alphaSize=0;//truncate to nonopaque values - for(unsigned i=0; i < alpha.size(); i++) + for(unsigned i=0; i < alpha.size(); ++i) { trans[i]=alpha[i]; if (alpha[i]<255) @@ -317,7 +320,7 @@ void save_as_png(T & file, std::vector const& palette, } png_write_info(png_ptr, info_ptr); - for (unsigned i=0;i(image.get_row(i))); } @@ -346,7 +349,7 @@ void save_as_png8_oct(T1 & file, } else { - for(int i=0; i<256; i++) + for(int i=0; i<256; ++i) { alphaHist[i] = 0; } @@ -355,11 +358,11 @@ void save_as_png8_oct(T1 & file, for (unsigned x = 0; x < width; ++x) { unsigned val = U2ALPHA(static_cast(image.get_row(y)[x])); - alphaHist[val]++; + ++alphaHist[val]; meanAlpha += val; if (val>0 && val<255) { - semiCount++; + ++semiCount; } } } @@ -371,17 +374,17 @@ void save_as_png8_oct(T1 & file, limits[0] = 0; limits[1] = (opts.trans_mode!=0 && alphaHist[0]>0)?1:0; limits[TRANSPARENCY_LEVELS] = 256; - for(unsigned j=2; j12 && cols[j] trees[MAX_OCTREE_LEVELS]; - for(unsigned j=1; j0; j--) + for(unsigned j=TRANSPARENCY_LEVELS-1; j>0; --j) { if (cols[j]>0 && U2ALPHA(val)>=limits[j]) { @@ -495,7 +498,7 @@ void save_as_png8_oct(T1 & file, palette.push_back(rgb(0,0,0)); } - for(unsigned j=1; j0) { diff --git a/include/mapnik/pool.hpp b/include/mapnik/pool.hpp index c37aab4e3..96a305fce 100644 --- a/include/mapnik/pool.hpp +++ b/include/mapnik/pool.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 diff --git a/include/mapnik/proj_strategy.hpp b/include/mapnik/proj_strategy.hpp index a8366fc5a..6330e233d 100644 --- a/include/mapnik/proj_strategy.hpp +++ b/include/mapnik/proj_strategy.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 diff --git a/include/mapnik/proj_transform.hpp b/include/mapnik/proj_transform.hpp index 71d678ef4..28791dd3d 100644 --- a/include/mapnik/proj_transform.hpp +++ b/include/mapnik/proj_transform.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 diff --git a/include/mapnik/projection.hpp b/include/mapnik/projection.hpp index 0869bb2d6..ddc4ff843 100644 --- a/include/mapnik/projection.hpp +++ b/include/mapnik/projection.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 diff --git a/include/mapnik/ptree_helpers.hpp b/include/mapnik/ptree_helpers.hpp index 6a9c91e56..3bdb26aea 100644 --- a/include/mapnik/ptree_helpers.hpp +++ b/include/mapnik/ptree_helpers.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 diff --git a/include/mapnik/quad_tree.hpp b/include/mapnik/quad_tree.hpp index c15f09f26..1d72b3f46 100644 --- a/include/mapnik/quad_tree.hpp +++ b/include/mapnik/quad_tree.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 @@ -24,11 +24,13 @@ #define MAPNIK_QUAD_TREE_HPP // mapnik -#include +#include #include #include + // stl -#include +#include +#include #include #include @@ -83,12 +85,12 @@ class quad_tree : util::noncopyable int num_subnodes() const { - int count = 0; + int _count = 0; for (int i = 0; i < 4; ++i) { - if (children_[i]) ++count; + if (children_[i]) ++_count; } - return count; + return _count; } ~node () {} }; @@ -164,9 +166,9 @@ public: int count_items() const { - int count = 0; - count_items(root_, count); - return count; + int _count = 0; + count_items(root_, _count); + return _count; } void trim() { @@ -276,23 +278,23 @@ private: if (!n) return 0; else { - int count = 1; + int _count = 1; for (int i = 0; i < 4; ++i) { - count += count_nodes(n->children_[i]); + _count += count_nodes(n->children_[i]); } - return count; + return _count; } } - void count_items(node const* n,int& count) const + void count_items(node const* n, int& _count) const { if (n) { - count += n->cont_.size(); + _count += n->cont_.size(); for (int i = 0; i < 4; ++i) { - count_items(n->children_[i],count); + count_items(n->children_[i],_count); } } } diff --git a/include/mapnik/query.hpp b/include/mapnik/query.hpp index 5d5a6e7c8..07da0caac 100644 --- a/include/mapnik/query.hpp +++ b/include/mapnik/query.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 @@ -24,7 +24,7 @@ #define MAPNIK_QUERY_HPP //mapnik -#include +#include #include // stl @@ -40,12 +40,12 @@ public: using resolution_type = std::tuple; query(box2d const& bbox, - resolution_type const& resolution, - double scale_denominator, + resolution_type const& _resolution, + double _scale_denominator, box2d const& unbuffered_bbox) : bbox_(bbox), - resolution_(resolution), - scale_denominator_(scale_denominator), + resolution_(_resolution), + scale_denominator_(_scale_denominator), filter_factor_(1.0), unbuffered_bbox_(unbuffered_bbox), names_(), @@ -53,11 +53,11 @@ public: {} query(box2d const& bbox, - resolution_type const& resolution, - double scale_denominator = 1.0) + resolution_type const& _resolution, + double _scale_denominator = 1.0) : bbox_(bbox), - resolution_(resolution), - scale_denominator_(scale_denominator), + resolution_(_resolution), + scale_denominator_(_scale_denominator), filter_factor_(1.0), unbuffered_bbox_(bbox), names_(), diff --git a/include/mapnik/raster.hpp b/include/mapnik/raster.hpp index 02022d359..35a067f03 100644 --- a/include/mapnik/raster.hpp +++ b/include/mapnik/raster.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 @@ -24,7 +24,7 @@ #define MAPNIK_RASTER_HPP // mapnik -#include +#include #include #include #include @@ -52,9 +52,9 @@ public: data_(std::move(data)), filter_factor_(filter_factor) {} - void set_nodata(double nodata) + void set_nodata(double _nodata) { - nodata_ = nodata; + nodata_ = _nodata; } boost::optional const& nodata() const diff --git a/include/mapnik/raster_colorizer.hpp b/include/mapnik/raster_colorizer.hpp index 690549746..448dc9e9d 100644 --- a/include/mapnik/raster_colorizer.hpp +++ b/include/mapnik/raster_colorizer.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 diff --git a/include/mapnik/renderer_common.hpp b/include/mapnik/renderer_common.hpp index c9d181b42..1c48ad3f5 100644 --- a/include/mapnik/renderer_common.hpp +++ b/include/mapnik/renderer_common.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 @@ -25,7 +25,7 @@ #include // for MAPNIK_DECL #include // for face_manager, etc -#include // for box2d +#include // for box2d #include // for view_transform #include #include diff --git a/include/mapnik/renderer_common/apply_vertex_converter.hpp b/include/mapnik/renderer_common/apply_vertex_converter.hpp index 503dc4176..b79912d57 100644 --- a/include/mapnik/renderer_common/apply_vertex_converter.hpp +++ b/include/mapnik/renderer_common/apply_vertex_converter.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 diff --git a/include/mapnik/renderer_common/clipping_extent.hpp b/include/mapnik/renderer_common/clipping_extent.hpp index aabacf36f..dcd678103 100644 --- a/include/mapnik/renderer_common/clipping_extent.hpp +++ b/include/mapnik/renderer_common/clipping_extent.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 @@ -24,7 +24,7 @@ #define MAPNIK_CLIPPING_EXTENT_HPP -#include +#include namespace mapnik { diff --git a/include/mapnik/renderer_common/pattern_alignment.hpp b/include/mapnik/renderer_common/pattern_alignment.hpp index 12f746d32..053901188 100644 --- a/include/mapnik/renderer_common/pattern_alignment.hpp +++ b/include/mapnik/renderer_common/pattern_alignment.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 diff --git a/include/mapnik/renderer_common/process_building_symbolizer.hpp b/include/mapnik/renderer_common/process_building_symbolizer.hpp index d65df2544..9c157c7c3 100644 --- a/include/mapnik/renderer_common/process_building_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_building_symbolizer.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 diff --git a/include/mapnik/renderer_common/process_point_symbolizer.hpp b/include/mapnik/renderer_common/process_point_symbolizer.hpp index ef0863fd6..4365240eb 100644 --- a/include/mapnik/renderer_common/process_point_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_point_symbolizer.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 @@ -29,9 +29,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/include/mapnik/renderer_common/process_polygon_symbolizer.hpp b/include/mapnik/renderer_common/process_polygon_symbolizer.hpp index 6fd2524fc..4322793f0 100644 --- a/include/mapnik/renderer_common/process_polygon_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_polygon_symbolizer.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 diff --git a/include/mapnik/renderer_common/process_raster_symbolizer.hpp b/include/mapnik/renderer_common/process_raster_symbolizer.hpp index 7ca90a0af..c700327c4 100644 --- a/include/mapnik/renderer_common/process_raster_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_raster_symbolizer.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 diff --git a/include/mapnik/renderer_common/render_group_symbolizer.hpp b/include/mapnik/renderer_common/render_group_symbolizer.hpp index e7b1b2248..65cc0f94f 100644 --- a/include/mapnik/renderer_common/render_group_symbolizer.hpp +++ b/include/mapnik/renderer_common/render_group_symbolizer.hpp @@ -42,9 +42,9 @@ struct render_thunk_list_dispatch { offset_ = offset; - for (render_thunk_ptr const& thunk : thunks) + for (render_thunk const& thunk : thunks) { - util::apply_visitor(std::ref(*this), *thunk); + util::apply_visitor(std::ref(*this), thunk); } } diff --git a/include/mapnik/renderer_common/render_pattern.hpp b/include/mapnik/renderer_common/render_pattern.hpp index acb989731..e9953e215 100644 --- a/include/mapnik/renderer_common/render_pattern.hpp +++ b/include/mapnik/renderer_common/render_pattern.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 diff --git a/include/mapnik/renderer_common/render_thunk.hpp b/include/mapnik/renderer_common/render_thunk.hpp index 2a957d260..66b108bb9 100644 --- a/include/mapnik/renderer_common/render_thunk.hpp +++ b/include/mapnik/renderer_common/render_thunk.hpp @@ -107,8 +107,7 @@ struct text_render_thunk : util::movable using render_thunk = util::variant; -using render_thunk_ptr = std::unique_ptr; -using render_thunk_list = std::list; +using render_thunk_list = std::list; } // namespace mapnik diff --git a/include/mapnik/request.hpp b/include/mapnik/request.hpp index 74c085197..c1b70c268 100644 --- a/include/mapnik/request.hpp +++ b/include/mapnik/request.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include namespace mapnik { diff --git a/include/mapnik/rule.hpp b/include/mapnik/rule.hpp index 1c98eaf59..018297ae9 100644 --- a/include/mapnik/rule.hpp +++ b/include/mapnik/rule.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 diff --git a/include/mapnik/rule_cache.hpp b/include/mapnik/rule_cache.hpp index 3d6f7d025..857873734 100644 --- a/include/mapnik/rule_cache.hpp +++ b/include/mapnik/rule_cache.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 diff --git a/include/mapnik/safe_cast.hpp b/include/mapnik/safe_cast.hpp index d8973032e..7e638e8a6 100644 --- a/include/mapnik/safe_cast.hpp +++ b/include/mapnik/safe_cast.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 diff --git a/include/mapnik/save_map.hpp b/include/mapnik/save_map.hpp index 80317b356..99d3beacb 100644 --- a/include/mapnik/save_map.hpp +++ b/include/mapnik/save_map.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 diff --git a/include/mapnik/scale_denominator.hpp b/include/mapnik/scale_denominator.hpp index fb09cefd9..68cad70d2 100644 --- a/include/mapnik/scale_denominator.hpp +++ b/include/mapnik/scale_denominator.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 diff --git a/include/mapnik/segment.hpp b/include/mapnik/segment.hpp index 4463382b8..6aace570c 100644 --- a/include/mapnik/segment.hpp +++ b/include/mapnik/segment.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 diff --git a/include/mapnik/simplify_converter.hpp b/include/mapnik/simplify_converter.hpp index 248842504..a8a6c377b 100644 --- a/include/mapnik/simplify_converter.hpp +++ b/include/mapnik/simplify_converter.hpp @@ -120,11 +120,11 @@ public: return algorithm_; } - void set_simplify_algorithm(simplify_algorithm_e value) + void set_simplify_algorithm(simplify_algorithm_e val) { - if (algorithm_ != value) + if (algorithm_ != val) { - algorithm_ = value; + algorithm_ = val; reset(); } } @@ -134,11 +134,11 @@ public: return tolerance_; } - void set_simplify_tolerance(double value) + void set_simplify_tolerance(double val) { - if (tolerance_ != value) + if (tolerance_ != val) { - tolerance_ = value; + tolerance_ = val; reset(); } } diff --git a/include/mapnik/span_image_filter.hpp b/include/mapnik/span_image_filter.hpp index c0a9adbb9..b3fd21367 100644 --- a/include/mapnik/span_image_filter.hpp +++ b/include/mapnik/span_image_filter.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 @@ -176,9 +176,9 @@ public: span_image_resample_rgba_affine(source_type & src, interpolator_type & inter, - agg::image_filter_lut const & filter, + agg::image_filter_lut const & _filter, boost::optional const & nodata_value) : - agg::span_image_resample_rgba_affine(src, inter, filter) + agg::span_image_resample_rgba_affine(src, inter, _filter) { } }; diff --git a/include/mapnik/sql_utils.hpp b/include/mapnik/sql_utils.hpp index 2720e8424..96ec79342 100644 --- a/include/mapnik/sql_utils.hpp +++ b/include/mapnik/sql_utils.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 @@ -33,12 +33,77 @@ #pragma GCC diagnostic pop // stl -#include -#include +#include +#include #include namespace mapnik { namespace sql_utils { + struct quoted_string + { + std::string const* operator-> () const { return &str; } + std::string const& str; + char const quot; + }; + + inline quoted_string identifier(std::string const& str) + { + return { str, '"' }; + } + + inline quoted_string literal(std::string const& str) + { + return { str, '\'' }; + } + + inline std::ostream& operator << (std::ostream& os, quoted_string qs) + { + std::size_t pos = 0, next; + + os.put(qs.quot); + while ((next = qs->find(qs.quot, pos)) != std::string::npos) + { + os.write(qs->data() + pos, next - pos + 1); + os.put(qs.quot); + pos = next + 1; + } + if ((next = qs->size()) > pos) + { + os.write(qs->data() + pos, next - pos); + } + return os.put(qs.quot); + } + + // Does nothing if `str` doesn't start with `quot`. + // Otherwise erases the opening quote, collapses inner quote pairs, + // and erases everything from the closing quote to the end of the + // string. The closing quote is the first non-paired quote after the + // opening one. For a well-formed quoted string, it is also the last + // character, so nothing gets lost. + inline void unquote(char quot, std::string & str) + { + if (!str.empty() && str.front() == quot) + { + std::size_t di = 0; + for (std::size_t si = 1; si < str.size(); ++si) + { + char c = str[si]; + if (c == quot && (++si >= str.size() || str[si] != quot)) + break; + str[di++] = c; + } + str.erase(di); + } + } + + inline std::string unquote_copy(char quot, std::string const& str) + { + std::string tmp(str); + sql_utils::unquote(quot, tmp); + return tmp; + } + + [[deprecated("flawed")]] inline std::string unquote_double(std::string const& sql) { std::string table_name = sql; @@ -46,6 +111,7 @@ namespace mapnik { namespace sql_utils { return table_name; } + [[deprecated("flawed")]] inline std::string unquote(std::string const& sql) { std::string table_name = sql; @@ -53,11 +119,75 @@ namespace mapnik { namespace sql_utils { return table_name; } + [[deprecated("flawed")]] inline void quote_attr(std::ostringstream & s, std::string const& field) { s << ",\"" << field << "\""; } + const std::regex re_from{ + "\\bFROM\\b" + , std::regex::icase + }; + + const std::regex re_table_name{ + "\\s*(\\w+|(\"[^\"]*\")+)" // $1 = schema + "(\\.(\\w+|(\"[^\"]*\")+))?" // $4 = table + "\\s*" + }; + + inline bool table_from_sql(std::string const& sql, + std::string & schema, + std::string & table) + { + std::smatch m; + auto start = sql.begin(); + auto end = sql.end(); + auto flags = std::regex_constants::match_default; + auto found = std::regex_match(start, end, m, re_table_name); + auto extract_matched_parts = [&]() + { + if (m[4].matched) + { + table.assign(m[4].first, m[4].second); + schema.assign(m[1].first, m[1].second); + } + else + { + table.assign(m[1].first, m[1].second); + schema.clear(); + } + }; + + if (found) + { + // input is not subquery, just "[schema.]table" + extract_matched_parts(); + } + else + { + // search "FROM [schema.]table" in subquery + while (std::regex_search(start, end, m, re_from, flags)) + { + start = m[0].second; + if (std::regex_search(start, end, m, re_table_name, + std::regex_constants::match_continuous)) + { + extract_matched_parts(); + found = true; + start = m[0].second; + } + flags = std::regex_constants::match_prev_avail; + } + } + if (found) + { + sql_utils::unquote('"', schema); + sql_utils::unquote('"', table); + } + return found; + } + inline std::string table_from_sql(std::string const& sql) { std::string table_name = sql; diff --git a/include/mapnik/sse.hpp b/include/mapnik/sse.hpp index 603af7cd2..4e9d96445 100644 --- a/include/mapnik/sse.hpp +++ b/include/mapnik/sse.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 diff --git a/include/mapnik/stringify_macro.hpp b/include/mapnik/stringify_macro.hpp index 41f947467..a450b98c8 100644 --- a/include/mapnik/stringify_macro.hpp +++ b/include/mapnik/stringify_macro.hpp @@ -20,7 +20,12 @@ * *****************************************************************************/ +#ifndef MAPNIK_STRINGIFY_MACRO_HPP +#define MAPNIK_STRINGIFY_MACRO_HPP + #ifndef MAPNIK_STRINGIFY #define MAPNIK_STRINGIFY(n) MAPNIK_STRINGIFY_HELPER(n) #define MAPNIK_STRINGIFY_HELPER(n) #n -#endif \ No newline at end of file +#endif + +#endif // MAPNIK_STRINGIFY_MACRO_HPP diff --git a/include/mapnik/svg/geometry_svg_generator.hpp b/include/mapnik/svg/geometry_svg_generator.hpp index 24135e5a6..e06db6f39 100644 --- a/include/mapnik/svg/geometry_svg_generator.hpp +++ b/include/mapnik/svg/geometry_svg_generator.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 diff --git a/include/mapnik/svg/geometry_svg_generator_impl.hpp b/include/mapnik/svg/geometry_svg_generator_impl.hpp index 57df89f96..98df1cb44 100644 --- a/include/mapnik/svg/geometry_svg_generator_impl.hpp +++ b/include/mapnik/svg/geometry_svg_generator_impl.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 @@ -21,7 +21,7 @@ *****************************************************************************/ // mapnik -#include +#include #include namespace mapnik { namespace svg { diff --git a/include/mapnik/svg/output/svg_generator.hpp b/include/mapnik/svg/output/svg_generator.hpp index 1b3f18dea..f3f2414f3 100644 --- a/include/mapnik/svg/output/svg_generator.hpp +++ b/include/mapnik/svg/output/svg_generator.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,7 +30,7 @@ #include #include #include -#include +#include namespace mapnik { namespace svg { diff --git a/include/mapnik/svg/output/svg_output_attributes.hpp b/include/mapnik/svg/output/svg_output_attributes.hpp index 00deeea26..21644a8bd 100644 --- a/include/mapnik/svg/output/svg_output_attributes.hpp +++ b/include/mapnik/svg/output/svg_output_attributes.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,8 +20,8 @@ * *****************************************************************************/ -#ifndef MAPNIK_SVG_OUTPUT_ATTRIBUTES -#define MAPNIK_SVG_OUTPUT_ATTRIBUTES +#ifndef MAPNIK_SVG_OUTPUT_ATTRIBUTES_HPP +#define MAPNIK_SVG_OUTPUT_ATTRIBUTES_HPP // mapnik #include @@ -121,12 +121,12 @@ namespace mapnik { namespace svg { fill_color_("#000000") {} - rect_output_attributes(const int x, const int y, const unsigned width, const unsigned height, color const& fill_color) + rect_output_attributes(const int x, const int y, const unsigned width, const unsigned height, color const& _fill_color) : x_(x), y_(y), width_(width), height_(height), - fill_color_(fill_color.to_hex_string()) + fill_color_(_fill_color.to_hex_string()) {} void set_x(const int x); @@ -199,4 +199,4 @@ namespace mapnik { namespace svg { }; }} -#endif // MAPNIK_SVG_OUTPUT_ATTRIBUTES +#endif // MAPNIK_SVG_OUTPUT_ATTRIBUTES_HPP diff --git a/include/mapnik/svg/output/svg_output_grammars.hpp b/include/mapnik/svg/output/svg_output_grammars.hpp index 5657e2606..d4f1bb6d1 100644 --- a/include/mapnik/svg/output/svg_output_grammars.hpp +++ b/include/mapnik/svg/output/svg_output_grammars.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 diff --git a/include/mapnik/svg/output/svg_output_grammars_impl.hpp b/include/mapnik/svg/output/svg_output_grammars_impl.hpp index ef856a05e..6ada195fd 100644 --- a/include/mapnik/svg/output/svg_output_grammars_impl.hpp +++ b/include/mapnik/svg/output/svg_output_grammars_impl.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 diff --git a/include/mapnik/svg/output/svg_path_iterator.hpp b/include/mapnik/svg/output/svg_path_iterator.hpp index 639788ae4..779abd771 100644 --- a/include/mapnik/svg/output/svg_path_iterator.hpp +++ b/include/mapnik/svg/output/svg_path_iterator.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 diff --git a/include/mapnik/svg/output/svg_renderer.hpp b/include/mapnik/svg/output/svg_renderer.hpp index 037ec0ddb..dbfa3477b 100644 --- a/include/mapnik/svg/output/svg_renderer.hpp +++ b/include/mapnik/svg/output/svg_renderer.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,7 +30,7 @@ #include #include #include // for rule, symbolizers -#include // for box2d +#include // for box2d #include // for color #include // for view_transform #include // for composite_mode_e @@ -131,9 +131,9 @@ public: return painted_; } - void painted(bool painted) + void painted(bool _painted) { - painted_ = painted; + painted_ = _painted; } inline eAttributeCollectionPolicy attribute_collection_policy() const diff --git a/include/mapnik/svg/svg_converter.hpp b/include/mapnik/svg/svg_converter.hpp index 9cf3c9c16..66edc5d0b 100644 --- a/include/mapnik/svg/svg_converter.hpp +++ b/include/mapnik/svg/svg_converter.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 diff --git a/include/mapnik/path_expression_grammar_impl.hpp b/include/mapnik/svg/svg_grammar_config_x3.hpp similarity index 52% rename from include/mapnik/path_expression_grammar_impl.hpp rename to include/mapnik/svg/svg_grammar_config_x3.hpp index 22002bf33..3666cebb9 100644 --- a/include/mapnik/path_expression_grammar_impl.hpp +++ b/include/mapnik/svg/svg_grammar_config_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,43 +20,32 @@ * *****************************************************************************/ -// mapnik -#include -#include - +#ifndef MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP +#define MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP +#include #pragma GCC diagnostic push #include -#include -#include -#include +#include #pragma GCC diagnostic pop -namespace mapnik -{ +namespace mapnik { namespace svg { namespace grammar { -template -path_expression_grammar::path_expression_grammar() - : path_expression_grammar::base_type(expr) -{ - standard_wide::char_type char_; - qi::_1_type _1; - qi::_val_type _val; - qi::lit_type lit; - qi::lexeme_type lexeme; - using phoenix::push_back; - using boost::phoenix::construct; +class relative_tag; +class svg_path_tag; +class svg_transform_tag; - expr = - * ( - str [ push_back(_val, _1)] - | - ( '[' >> attr [ push_back(_val, construct( _1 )) ] >> ']') - ) - ; +namespace x3 = boost::spirit::x3; +using space_type = x3::standard::space_type; +using iterator_type = char const*; - attr %= +(char_ - ']'); - str %= lexeme[+(char_ -'[')]; -} +using phrase_parse_context_type = x3::phrase_parse_context::type; +using svg_parse_context_type = x3::with_context const, + x3::with_context const, + phrase_parse_context_type>::type>::type; -} +inline double deg2rad(double deg) {return (M_PI * deg) / 180.0;} + +}}} + +#endif // MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP diff --git a/include/mapnik/svg/svg_parser.hpp b/include/mapnik/svg/svg_parser.hpp index 63caacd8b..8246bac91 100644 --- a/include/mapnik/svg/svg_parser.hpp +++ b/include/mapnik/svg/svg_parser.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 diff --git a/include/mapnik/svg/svg_parser_exception.hpp b/include/mapnik/svg/svg_parser_exception.hpp index 89139da88..8732e0259 100644 --- a/include/mapnik/svg/svg_parser_exception.hpp +++ b/include/mapnik/svg/svg_parser_exception.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 @@ -38,9 +38,9 @@ public: svg_parser_exception(std::string const& message) : message_(message) {} - ~svg_parser_exception() throw() {} + ~svg_parser_exception() {} - virtual const char* what() const throw() + virtual const char* what() const noexcept { return message_.c_str(); } diff --git a/include/mapnik/svg/svg_path_adapter.hpp b/include/mapnik/svg/svg_path_adapter.hpp index 8b4fb6bf2..288491030 100644 --- a/include/mapnik/svg/svg_path_adapter.hpp +++ b/include/mapnik/svg/svg_path_adapter.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/svg/svg_path_attributes.hpp b/include/mapnik/svg/svg_path_attributes.hpp index 80bf46349..e4acbba49 100644 --- a/include/mapnik/svg/svg_path_attributes.hpp +++ b/include/mapnik/svg/svg_path_attributes.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 diff --git a/include/mapnik/svg/svg_path_commands.hpp b/include/mapnik/svg/svg_path_commands.hpp index 7e7ab5fef..26a5bba6b 100644 --- a/include/mapnik/svg/svg_path_commands.hpp +++ b/include/mapnik/svg/svg_path_commands.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 diff --git a/include/mapnik/svg/svg_path_grammar.hpp b/include/mapnik/svg/svg_path_grammar.hpp deleted file mode 100644 index a65b27266..000000000 --- a/include/mapnik/svg/svg_path_grammar.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************** - * - * 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_SVG_PATH_GRAMMAR_HPP -#define MAPNIK_SVG_PATH_GRAMMAR_HPP - -// spirit -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; - -template -struct svg_path_grammar : qi::grammar -{ - // ctor - svg_path_grammar(); - // rules - qi::rule start; - qi::rule cmd; - qi::rule drawto_cmd; - qi::rule, void(PathType&), SkipType> M; // M,m - qi::rule, void(PathType&), SkipType> L; // L,l - qi::rule, void(PathType&), SkipType> H; // H,h - qi::rule, void(PathType&), SkipType> V; // V,v - qi::rule, void(PathType&), SkipType> C; // C,c - qi::rule, void(PathType&), SkipType> S; // S,s - qi::rule, void(PathType&), SkipType> Q; // Q,q - qi::rule, void(PathType&), SkipType> T; // T,t - qi::rule, void(PathType&), SkipType> A; // A,a - qi::rule Z; // Z,z - qi::rule(), SkipType> coord; -}; - -}} - - -#endif // MAPNIK_SVG_PATH_GRAMMAR_HPP diff --git a/include/mapnik/svg/svg_path_grammar_impl.hpp b/include/mapnik/svg/svg_path_grammar_impl.hpp deleted file mode 100644 index 5d5fd1a7a..000000000 --- a/include/mapnik/svg/svg_path_grammar_impl.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************** - * - * 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 - * - *****************************************************************************/ - -// 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 -#include - -// spirit -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; -using namespace boost::phoenix; - - -template -svg_path_grammar::svg_path_grammar() - : svg_path_grammar::base_type(start) -{ - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_5_type _5; - qi::_a_type _a; - qi::lit_type lit; - qi::_r1_type _r1; - qi::double_type double_; - qi::int_type int_; - qi::no_case_type no_case; - - // commands - function move_to_; - function hline_to_; - function vline_to_; - function line_to_; - function curve4_; - function curve4_smooth_; - function curve3_; - function curve3_smooth_; - function arc_to_; - function close_; - // - start = +cmd(_r1); - - cmd = M(_r1) >> *drawto_cmd(_r1); - - drawto_cmd = L(_r1) | H(_r1) | V(_r1) | C(_r1) | S(_r1) | Q(_r1) | T(_r1) | A(_r1) | Z(_r1); - - M = (lit('M')[_a = false] | lit('m')[_a = true]) >> coord[move_to_(_r1, _1, _a)] // move_to - >> *(-lit(',') >> coord[line_to_(_r1, _1, _a)]); // *line_to - - H = (lit('H')[_a = false] | lit('h')[_a = true]) - >> (double_[ hline_to_(_r1, _1,_a) ] % -lit(',')) ; // +hline_to - - V = (lit('V')[_a = false] | lit('v')[_a = true]) - >> (double_ [ vline_to_(_r1, _1,_a) ] % -lit(',')); // +vline_to - - L = (lit('L')[_a = false] | lit('l')[_a = true]) - >> (coord [ line_to_(_r1, _1, _a) ] % -lit(',')); // +line_to - - C = (lit('C')[_a = false] | lit('c')[_a = true]) - >> ((coord >> -lit(',') >> coord >> -lit(',') >> coord)[curve4_(_r1, _1, _2, _3, _a)] % -lit(',')); // +curve4 - - S = (lit('S')[_a = false] | lit('s')[_a = true]) - >> ((coord >> -lit(',') >> coord) [ curve4_smooth_(_r1, _1,_2,_a) ] % -lit(',')); // +curve4_smooth (smooth curveto) - - Q = (lit('Q')[_a = false] | lit('q')[_a = true]) - >> ((coord >> -lit(',') >> coord) [ curve3_(_r1, _1,_2,_a) ] % -lit(',')); // +curve3 (quadratic-bezier-curveto) - - T = (lit('T')[_a = false] | lit('t')[_a = true]) - >> ((coord ) [ curve3_smooth_(_r1, _1,_a) ] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto) - - A = (lit('A')[_a = false] | lit('a')[_a = true]) - >> ((coord >> -lit(',') >> double_ >> -lit(',') >> int_ >> -lit(',') >> int_ >> -lit(',') >> coord) - [arc_to_(_r1, _1, _2, _3, _4, _5, _a)] % -lit(',')); // arc_to; - - Z = no_case[lit('z')] [close_(_r1)]; // close path - - coord = double_ >> -lit(',') >> double_; -} - -} // namespace svg -} // namespace mapnik diff --git a/include/mapnik/svg/svg_path_grammar_x3.hpp b/include/mapnik/svg/svg_path_grammar_x3.hpp new file mode 100644 index 000000000..80882fce1 --- /dev/null +++ b/include/mapnik/svg/svg_path_grammar_x3.hpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * + * 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_SVG_PATH_GRAMMAR_X3_HPP +#define MAPNIK_SVG_PATH_GRAMMAR_X3_HPP + +#include + +namespace mapnik { namespace svg { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using svg_path_grammar_type = x3::rule; +using svg_points_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(svg_path_grammar_type, + svg_points_grammar_type); + +} + +grammar::svg_path_grammar_type const& svg_path_grammar(); + +grammar::svg_points_grammar_type const& svg_points_grammar(); + +}} + +#endif // MAPNIK_SVG_PATH_GRAMMAR_X3_HPP diff --git a/include/mapnik/svg/svg_path_grammar_x3_def.hpp b/include/mapnik/svg/svg_path_grammar_x3_def.hpp new file mode 100644 index 000000000..b1bed97aa --- /dev/null +++ b/include/mapnik/svg/svg_path_grammar_x3_def.hpp @@ -0,0 +1,203 @@ +/***************************************************************************** + * + * 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_SVG_PATH_GRAMMAR_X3_DEF_HPP +#define MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP + +// mapnik +#include +#include +#include +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace svg { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using x3::lit; +using x3::double_; +using x3::int_; +using x3::no_case; + +using coord_type = std::tuple; + +auto const move_to = [] (auto const& ctx) +{ + x3::get(ctx).get().move_to(std::get<0>(_attr(ctx)), std::get<1>(_attr(ctx)), x3::get(ctx)); +}; + +auto const line_to = [] (auto const & ctx) +{ + x3::get(ctx).get().line_to(std::get<0>(_attr(ctx)), std::get<1>(_attr(ctx)), x3::get(ctx)); +}; + +auto const hline_to = [] (auto const& ctx) +{ + x3::get(ctx).get().hline_to(_attr(ctx), x3::get(ctx)); +}; + +auto const vline_to = [] (auto const& ctx) +{ + x3::get(ctx).get().vline_to(_attr(ctx), x3::get(ctx)); +}; + +auto const curve4 = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& p0 = boost::fusion::at_c<0>(attr); + auto const& p1 = boost::fusion::at_c<1>(attr); + auto const& p2 = boost::fusion::at_c<2>(attr); + x3::get(ctx).get().curve4(std::get<0>(p0),std::get<1>(p0), + std::get<0>(p1),std::get<1>(p1), + std::get<0>(p2),std::get<1>(p2), + x3::get(ctx)); +}; + +auto const curve4_smooth = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& p0 = boost::fusion::at_c<0>(attr); + auto const& p1 = boost::fusion::at_c<1>(attr); + x3::get(ctx).get().curve4(std::get<0>(p0),std::get<1>(p0), + std::get<0>(p1),std::get<1>(p1), + x3::get(ctx)); +}; + +auto const curve3 = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& p0 = boost::fusion::at_c<0>(attr); + auto const& p1 = boost::fusion::at_c<1>(attr); + x3::get(ctx).get().curve3(std::get<0>(p0),std::get<1>(p0), + std::get<0>(p1),std::get<1>(p1), + x3::get(ctx)); +}; + +auto const curve3_smooth = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + x3::get(ctx).get().curve3(std::get<0>(attr),std::get<1>(attr), + x3::get(ctx)); +}; + + +auto const arc_to = [] (auto & ctx) +{ + auto const& attr = _attr(ctx); + auto const& p = boost::fusion::at_c<0>(attr); + double angle = boost::fusion::at_c<1>(attr); + int large_arc_flag = boost::fusion::at_c<2>(attr); + int sweep_flag = boost::fusion::at_c<3>(attr); + auto const& v = boost::fusion::at_c<4>(attr); + x3::get(ctx).get().arc_to(std::get<0>(p),std::get<1>(p), + deg2rad(angle), large_arc_flag, sweep_flag, + std::get<0>(v),std::get<1>(v), + x3::get(ctx)); +}; + +auto const close_path = [] (auto const& ctx) +{ + x3::get(ctx).get().close_subpath(); +}; + +auto const relative = [] (auto const& ctx) +{ + x3::get(ctx).get() = true; +}; + +auto const absolute = [] (auto const& ctx) +{ + x3::get(ctx).get() = false; +}; + +// exported rules +svg_path_grammar_type const svg_path = "SVG Path"; +svg_points_grammar_type const svg_points = "SVG_Points"; + +// rules +auto const coord = x3::rule{} = double_ > -lit(',') > double_; + +auto const svg_points_def = coord[move_to] // move_to + > *(-lit(',') >> coord[line_to]); // *line_to + +auto const M = x3::rule {} = (lit('M')[absolute] | lit('m')[relative]) + > svg_points ; + +auto const H = x3::rule {} = (lit('H')[absolute] | lit('h')[relative]) + > (double_[ hline_to] % -lit(',')) ; // +hline_to + +auto const V = x3::rule {} = (lit('V')[absolute] | lit('v')[relative]) + > (double_[ vline_to] % -lit(',')) ; // +vline_to + +auto const L = x3::rule {} = (lit('L')[absolute] | lit('l')[relative]) + > (coord [line_to] % -lit(',')); // +line_to + +auto const C = x3::rule {} = (lit('C')[absolute] | lit('c')[relative]) + > ((coord > -lit(',') > coord > -lit(',') > coord)[curve4] % -lit(',')); // +curve4 + +auto const S = x3::rule {} = (lit('S')[absolute] | lit('s')[relative]) + > ((coord > -lit(',') > coord) [curve4_smooth] % -lit(',')); // +curve4_smooth (smooth curveto) + +auto const Q = x3::rule {} = (lit('Q')[absolute] | lit('q')[relative]) + > ((coord > -lit(',') > coord) [curve3] % -lit(',')); // +curve3 (quadratic-bezier-curveto) + +auto const T = x3::rule {} = (lit('T')[absolute] | lit('t')[relative]) + > ((coord ) [curve3_smooth] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto) + +auto const A = x3::rule {} = (lit('A')[absolute] | lit('a')[relative]) + > ((coord > -lit(',') > double_ > -lit(',') > int_ > -lit(',') > int_ > -lit(',') > coord) + [arc_to] % -lit(',')); // arc_to; + +auto const Z = x3::rule{} = no_case[lit('z')] [close_path]; // close path + +auto const drawto_cmd = x3::rule {} = L | H | V | C | S | Q | T | A | Z; + +auto const cmd = x3::rule {} = M > *drawto_cmd ; + +auto const svg_path_def = +cmd; + +#pragma GCC diagnostic push +#include +BOOST_SPIRIT_DEFINE( + svg_path, + svg_points + ); +#pragma GCC diagnostic pop + +} + +grammar::svg_path_grammar_type const& svg_path_grammar() +{ + return grammar::svg_path; +} + +grammar::svg_points_grammar_type const& svg_points_grammar() +{ + return grammar::svg_points; +} + +}} + +#endif // MAPNIK_SVG_PATH_GRAMMAR_X3_HPP diff --git a/include/mapnik/svg/svg_path_parser.hpp b/include/mapnik/svg/svg_path_parser.hpp index 5633b2ea9..444badbf5 100644 --- a/include/mapnik/svg/svg_path_parser.hpp +++ b/include/mapnik/svg/svg_path_parser.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 @@ -26,7 +26,6 @@ // mapnik #include #include -#include // stl #include @@ -40,12 +39,12 @@ template bool parse_points(const char* wkt, PathType& p); template -bool MAPNIK_DECL parse_svg_transform(const char* wkt, TransformType& tr); +bool parse_svg_transform(const char* wkt, TransformType& tr); // extern template bool MAPNIK_DECL parse_path(const char*, svg_converter_type&); extern template bool MAPNIK_DECL parse_points(const char*, svg_converter_type&); -extern template bool MAPNIK_DECL parse_svg_transform(const char*, svg_converter_type&); +extern template bool MAPNIK_DECL parse_svg_transform(const char*, agg::trans_affine&); } } diff --git a/include/mapnik/svg/svg_points_grammar_impl.hpp b/include/mapnik/svg/svg_points_grammar_impl.hpp deleted file mode 100644 index 5d56f7e25..000000000 --- a/include/mapnik/svg/svg_points_grammar_impl.hpp +++ /dev/null @@ -1,61 +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 -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; -using namespace boost::phoenix; - -template -svg_points_grammar::svg_points_grammar() - : svg_points_grammar::base_type(start) -{ - qi::_1_type _1; - qi::_r1_type _r1; - qi::lit_type lit; - qi::double_type double_; - // commands - function move_to_; - function line_to_; - function close_; - - start = coord[move_to_(_r1, _1, false)] // move_to - >> *(-lit(',') >> coord [ line_to_(_r1, _1,false) ] ); // *line_to - - coord = double_ >> -lit(',') >> double_; -} - -}} diff --git a/include/mapnik/svg/svg_renderer_agg.hpp b/include/mapnik/svg/svg_renderer_agg.hpp index d99575b4d..9183dd7e6 100644 --- a/include/mapnik/svg/svg_renderer_agg.hpp +++ b/include/mapnik/svg/svg_renderer_agg.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 @@ -26,8 +26,8 @@ // mapnik #include #include -#include -#include +#include +#include #include #if defined(GRID_RENDERER) diff --git a/include/mapnik/svg/svg_storage.hpp b/include/mapnik/svg/svg_storage.hpp index c360ecf52..120c27b1c 100644 --- a/include/mapnik/svg/svg_storage.hpp +++ b/include/mapnik/svg/svg_storage.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 @@ -24,7 +24,7 @@ #define MAPNIK_SVG_STORAGE_HPP // mapnik -#include +#include #include namespace mapnik { diff --git a/include/mapnik/svg/svg_transform_grammar.hpp b/include/mapnik/svg/svg_transform_grammar.hpp deleted file mode 100644 index 895112d4a..000000000 --- a/include/mapnik/svg/svg_transform_grammar.hpp +++ /dev/null @@ -1,56 +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_SVG_TRANSFORM_GRAMMAR_HPP -#define MAPNIK_SVG_TRANSFORM_GRAMMAR_HPP - -// mapnik -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; - -template -struct svg_transform_grammar : qi::grammar -{ - // ctor - svg_transform_grammar(); - // rules - qi::rule start; - qi::rule transform_; - qi::rule matrix; - qi::rule translate; - qi::rule scale; - qi::rule, void(TransformType&), SkipType> rotate; - qi::rule skewX; - qi::rule skewY; -}; - -}} - -#endif // MAPNIK_SVG_TRANSFORM_GRAMMAR_HPP diff --git a/include/mapnik/svg/svg_transform_grammar_impl.hpp b/include/mapnik/svg/svg_transform_grammar_impl.hpp deleted file mode 100644 index 65c05ab2c..000000000 --- a/include/mapnik/svg/svg_transform_grammar_impl.hpp +++ /dev/null @@ -1,172 +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 - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace svg { - -using namespace boost::spirit; -using namespace boost::fusion; -using namespace boost::phoenix; - -inline double deg2rad(double d) -{ - return M_PI * d / 180.0; -} - -struct process_matrix -{ - using result_type = void; - template - void operator () (TransformType & tr, double a, double b, double c, double d, double e, double f) const - { - tr = agg::trans_affine(a,b,c,d,e,f) * tr; - } -}; - -struct process_rotate -{ - using result_type = void; - - template - void operator () (TransformType & tr, T0 a, T1 cx, T2 cy) const - { - if (cx == 0.0 && cy == 0.0) - { - tr = agg::trans_affine_rotation(deg2rad(a)) * tr; - } - else - { - agg::trans_affine t = agg::trans_affine_translation(-cx,-cy); - t *= agg::trans_affine_rotation(deg2rad(a)); - t *= agg::trans_affine_translation(cx, cy); - tr = t * tr; - } - } -}; - -struct process_translate -{ - using result_type = void; - template - void operator () (TransformType & tr, T0 tx, T1 ty) const - { - if (ty) tr = agg::trans_affine_translation(tx,*ty) * tr; - else tr = agg::trans_affine_translation(tx,0.0) * tr; - } -}; - -struct process_scale -{ - using result_type = void; - template - void operator () (TransformType & tr, T0 sx, T1 sy) const - { - if (sy) tr = agg::trans_affine_scaling(sx,*sy) * tr; - else tr = agg::trans_affine_scaling(sx,sx) * tr; - } -}; - - -struct process_skew -{ - using result_type = void; - - template - void operator () (TransformType & tr, T0 skew_x, T1 skew_y) const - { - tr = agg::trans_affine_skewing(deg2rad(skew_x),deg2rad(skew_y)) * tr; - } -}; - -template -svg_transform_grammar::svg_transform_grammar() - : svg_transform_grammar::base_type(start) -{ - 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::_a_type _a; - qi::_b_type _b; - qi::_c_type _c; - qi::_r1_type _r1; - qi::lit_type lit; - qi::double_type double_; - qi::no_case_type no_case; - - // actions - function matrix_action; - function rotate_action; - function translate_action; - function scale_action; - function skew_action; - - start = +transform_(_r1) ; - - transform_ = matrix(_r1) | rotate(_r1) | translate(_r1) | scale(_r1) | rotate(_r1) | skewX(_r1) | skewY (_r1) ; - - matrix = no_case[lit("matrix")] >> lit('(') - >> (double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_)[matrix_action(_r1, _1, _2, _3, _4, _5, _6)] >> lit(')'); - - translate = no_case[lit("translate")] - >> lit('(') >> (double_ >> -lit(',') >> -double_)[translate_action(_r1, _1, _2)] >> lit(')'); - - scale = no_case[lit("scale")] - >> lit('(') >> (double_ >> -lit(',') >> -double_)[scale_action(_r1, _1, _2)] >> lit(')'); - - rotate = no_case[lit("rotate")] - >> lit('(') - >> double_[_a = _1] >> -lit(',') - >> -(double_ [_b = _1] >> -lit(',') >> double_[_c = _1]) - >> lit(')') [ rotate_action(_r1, _a,_b,_c)]; - - skewX = no_case[lit("skewX")] >> lit('(') >> double_ [ skew_action(_r1, _1, 0.0)] >> lit(')'); - - skewY = no_case[lit("skewY")] >> lit('(') >> double_ [ skew_action(_r1, 0.0, _1)] >> lit(')'); - -} - -}} diff --git a/include/mapnik/svg/svg_transform_grammar_x3.hpp b/include/mapnik/svg/svg_transform_grammar_x3.hpp new file mode 100644 index 000000000..c0fb12915 --- /dev/null +++ b/include/mapnik/svg/svg_transform_grammar_x3.hpp @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * 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_SVG_TRANSFORM_GRAMMAR_X3_HPP +#define MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_HPP + +// mapnik +#include + +namespace mapnik { namespace svg { namespace grammar { + +using namespace boost::spirit::x3; + +using svg_transform_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(svg_transform_grammar_type); + +} + +grammar::svg_transform_grammar_type const& svg_transform_grammar(); + +}} + +#endif // MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_HPP diff --git a/include/mapnik/svg/svg_transform_grammar_x3_def.hpp b/include/mapnik/svg/svg_transform_grammar_x3_def.hpp new file mode 100644 index 000000000..47b6030ce --- /dev/null +++ b/include/mapnik/svg/svg_transform_grammar_x3_def.hpp @@ -0,0 +1,163 @@ +/***************************************************************************** + * + * 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_SVG_TRANSFORM_GRAMMAR_X3_DEF_HPP +#define MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_DEF_HPP + +// mapnik +#include +// boost::fusion +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop +// agg +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace svg { namespace grammar { + +namespace x3 = boost::spirit::x3; + +using x3::lit; +using x3::double_; +using x3::no_case; + +auto const matrix_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto const& attr = _attr(ctx); + auto a = boost::fusion::at_c<0>(attr); + auto b = boost::fusion::at_c<1>(attr); + auto c = boost::fusion::at_c<2>(attr); + auto d = boost::fusion::at_c<3>(attr); + auto e = boost::fusion::at_c<4>(attr); + auto f = boost::fusion::at_c<5>(attr); + tr = agg::trans_affine(a, b, c, d, e, f) * tr; +}; + +auto const rotate_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto const& attr = _attr(ctx); + auto a = boost::fusion::at_c<0>(attr); + auto cx = boost::fusion::at_c<1>(attr) ? *boost::fusion::at_c<1>(attr) : 0.0; + auto cy = boost::fusion::at_c<2>(attr) ? *boost::fusion::at_c<2>(attr) : 0.0; + if (cx == 0.0 && cy == 0.0) + { + tr = agg::trans_affine_rotation(deg2rad(a)) * tr; + } + else + { + agg::trans_affine t = agg::trans_affine_translation(-cx,-cy); + t *= agg::trans_affine_rotation(deg2rad(a)); + t *= agg::trans_affine_translation(cx, cy); + tr = t * tr; + } +}; + +auto const translate_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto const& attr = _attr(ctx); + auto tx = boost::fusion::at_c<0>(attr); + auto ty = boost::fusion::at_c<1>(attr); + if (ty) tr = agg::trans_affine_translation(tx, *ty) * tr; + else tr = agg::trans_affine_translation(tx,0.0) * tr; +}; + +auto const scale_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto const& attr = _attr(ctx); + auto sx = boost::fusion::at_c<0>(attr); + auto sy = boost::fusion::at_c<1>(attr); + if (sy) tr = agg::trans_affine_scaling(sx, *sy) * tr; + else tr = agg::trans_affine_scaling(sx, sx) * tr; +}; + +auto const skewX_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto skew_x = _attr(ctx); + tr = agg::trans_affine_skewing(deg2rad(skew_x), 0.0) * tr; +}; + +auto const skewY_action = [] (auto const& ctx) +{ + auto & tr = x3::get(ctx).get(); + auto skew_y= _attr(ctx); + tr = agg::trans_affine_skewing(0.0, deg2rad(skew_y)) * tr; +}; + +//exported rule +svg_transform_grammar_type const svg_transform = "SVG Transform"; +// rules +auto const matrix = x3::rule {} = no_case[lit("matrix")] + > lit('(') > (double_ > -lit(',') + > double_ > -lit(',') + > double_ > -lit(',') + > double_ > -lit(',') + > double_ > -lit(',') + > double_)[matrix_action] + > lit(')'); + +auto const translate = x3::rule {} = no_case[lit("translate")] + > lit('(') > (double_ > -lit(',') >> -double_)[translate_action] > lit(')'); + +auto const scale = x3::rule {} = no_case[lit("scale")] + > lit('(') > (double_ > -lit(',') > -double_)[scale_action] > lit(')'); + +auto const rotate = x3::rule {} = no_case[lit("rotate")] + > lit('(') + > (double_ > -(lit(',') > double_) > -(lit(',') > double_))[rotate_action] + > lit(')') ; + +auto const skewX = x3::rule {} = no_case[lit("skewX")] + > lit('(') > double_ [ skewX_action] > lit(')'); +auto const skewY = x3::rule {} = no_case[lit("skewY")] + > lit('(') > double_ [ skewY_action] > lit(')'); + +auto const transform = x3::rule {} = matrix | rotate | translate | scale /*| rotate*/ | skewX | skewY ; + +auto const svg_transform_def = +transform ; + +#pragma GCC diagnostic push +#include +BOOST_SPIRIT_DEFINE( + svg_transform + ); +#pragma GCC diagnostic pop + +} + +grammar::svg_transform_grammar_type const& svg_transform_grammar() +{ + return grammar::svg_transform; +} + +}} + + +#endif // MAPNIK_SVG_TRANSFORM_GRAMMAR_X3_HPP diff --git a/include/mapnik/symbolizer.hpp b/include/mapnik/symbolizer.hpp index 9308ecd7b..9cdb96f70 100644 --- a/include/mapnik/symbolizer.hpp +++ b/include/mapnik/symbolizer.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 @@ -462,7 +462,7 @@ T get(symbolizer_base const& sym, keys key) { return util::apply_visitor(extract_raw_value(), itr->second); } - return T(); + return T{}; } @@ -487,7 +487,7 @@ boost::optional get_optional(symbolizer_base const& sym, keys key) { return util::apply_visitor(extract_raw_value(), itr->second); } - return boost::optional(); + return boost::optional{}; } } diff --git a/include/mapnik/symbolizer_base.hpp b/include/mapnik/symbolizer_base.hpp index f07cf3d2a..be1529216 100644 --- a/include/mapnik/symbolizer_base.hpp +++ b/include/mapnik/symbolizer_base.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include #include #include @@ -100,18 +100,13 @@ struct strict_value : value_base_type { strict_value() = default; - strict_value(const char* val) + strict_value(const char* val) noexcept(false) : value_base_type(std::string(val)) {} - template - strict_value(T const& obj) - : value_base_type(typename detail::mapnik_value_type::type(obj)) - {} - - template + template > strict_value(T && obj) - noexcept(std::is_nothrow_constructible::value) - : value_base_type(std::forward(obj)) + noexcept(std::is_nothrow_constructible::value) + : value_base_type(U(std::forward(obj))) {} }; diff --git a/include/mapnik/symbolizer_default_values.hpp b/include/mapnik/symbolizer_default_values.hpp index ea5e5c02e..3f918fb2f 100644 --- a/include/mapnik/symbolizer_default_values.hpp +++ b/include/mapnik/symbolizer_default_values.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 @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include @@ -369,6 +369,13 @@ struct symbolizer_default // font-feature-settings +// extend +template <> +struct symbolizer_default +{ + static value_double value() { return 0.0; } +}; + } // namespace mapnik #endif // MAPNIK_SYMBOLIZER_DEFAULT_VALUES_HPP diff --git a/include/mapnik/symbolizer_dispatch.hpp b/include/mapnik/symbolizer_dispatch.hpp index 52f65bcfc..cb43b7b65 100644 --- a/include/mapnik/symbolizer_dispatch.hpp +++ b/include/mapnik/symbolizer_dispatch.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 diff --git a/include/mapnik/symbolizer_enumerations.hpp b/include/mapnik/symbolizer_enumerations.hpp index 7a3e72fd8..e24f079a9 100644 --- a/include/mapnik/symbolizer_enumerations.hpp +++ b/include/mapnik/symbolizer_enumerations.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 diff --git a/include/mapnik/symbolizer_hash.hpp b/include/mapnik/symbolizer_hash.hpp index 9c2baa4e4..afd5cd3de 100644 --- a/include/mapnik/symbolizer_hash.hpp +++ b/include/mapnik/symbolizer_hash.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 diff --git a/include/mapnik/symbolizer_keys.hpp b/include/mapnik/symbolizer_keys.hpp index 15919dc1b..1d395c015 100644 --- a/include/mapnik/symbolizer_keys.hpp +++ b/include/mapnik/symbolizer_keys.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 @@ -92,6 +92,7 @@ enum class keys : std::uint8_t direction, avoid_edges, ff_settings, + extend, MAX_SYMBOLIZER_KEY }; diff --git a/include/mapnik/symbolizer_utils.hpp b/include/mapnik/symbolizer_utils.hpp index cea99000c..e18cf2a8c 100644 --- a/include/mapnik/symbolizer_utils.hpp +++ b/include/mapnik/symbolizer_utils.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,13 +30,13 @@ #include #include #include -#include #include #include #include #include #include -#include +#include +#include #include #include diff --git a/include/mapnik/text/evaluated_format_properties_ptr.hpp b/include/mapnik/text/evaluated_format_properties_ptr.hpp index 472865181..351261339 100644 --- a/include/mapnik/text/evaluated_format_properties_ptr.hpp +++ b/include/mapnik/text/evaluated_format_properties_ptr.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 diff --git a/include/mapnik/text/face.hpp b/include/mapnik/text/face.hpp index 3d797a1f2..9158e258b 100644 --- a/include/mapnik/text/face.hpp +++ b/include/mapnik/text/face.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 @@ -72,10 +72,13 @@ public: bool glyph_dimensions(glyph_info &glyph) const; + inline bool is_color() const { return color_font_;} + ~font_face(); private: FT_Face face_; + bool color_font_ = false; }; using face_ptr = std::shared_ptr; diff --git a/include/mapnik/text/font_feature_settings.hpp b/include/mapnik/text/font_feature_settings.hpp index 8bc3e33c6..e6b8d7b6c 100644 --- a/include/mapnik/text/font_feature_settings.hpp +++ b/include/mapnik/text/font_feature_settings.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 diff --git a/include/mapnik/text/font_library.hpp b/include/mapnik/text/font_library.hpp index 163aad3d6..31ef063ab 100644 --- a/include/mapnik/text/font_library.hpp +++ b/include/mapnik/text/font_library.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 diff --git a/include/mapnik/text/formatting/base.hpp b/include/mapnik/text/formatting/base.hpp index da47d5d54..68aa33392 100644 --- a/include/mapnik/text/formatting/base.hpp +++ b/include/mapnik/text/formatting/base.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 diff --git a/include/mapnik/text/formatting/format.hpp b/include/mapnik/text/formatting/format.hpp index c540abd13..76deed1a5 100644 --- a/include/mapnik/text/formatting/format.hpp +++ b/include/mapnik/text/formatting/format.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 diff --git a/include/mapnik/text/formatting/layout.hpp b/include/mapnik/text/formatting/layout.hpp index 6892ce72b..de6d35e5a 100644 --- a/include/mapnik/text/formatting/layout.hpp +++ b/include/mapnik/text/formatting/layout.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 diff --git a/include/mapnik/text/formatting/list.hpp b/include/mapnik/text/formatting/list.hpp index 45c4217db..3f9914dcc 100644 --- a/include/mapnik/text/formatting/list.hpp +++ b/include/mapnik/text/formatting/list.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 diff --git a/include/mapnik/text/formatting/registry.hpp b/include/mapnik/text/formatting/registry.hpp index 7328d2b9c..ed974fc10 100644 --- a/include/mapnik/text/formatting/registry.hpp +++ b/include/mapnik/text/formatting/registry.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 diff --git a/include/mapnik/text/formatting/text.hpp b/include/mapnik/text/formatting/text.hpp index 012288507..46766422e 100644 --- a/include/mapnik/text/formatting/text.hpp +++ b/include/mapnik/text/formatting/text.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 diff --git a/include/mapnik/text/glyph_info.hpp b/include/mapnik/text/glyph_info.hpp index 3950f9dd2..fc177440d 100644 --- a/include/mapnik/text/glyph_info.hpp +++ b/include/mapnik/text/glyph_info.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 diff --git a/include/mapnik/text/glyph_positions.hpp b/include/mapnik/text/glyph_positions.hpp index aa08e3376..e8d732cf3 100644 --- a/include/mapnik/text/glyph_positions.hpp +++ b/include/mapnik/text/glyph_positions.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 @@ -24,7 +24,7 @@ #define MAPNIK_TEXT_GLYPH_POSITIONS_HPP //mapnik -#include +#include #include #include #include diff --git a/include/mapnik/text/harfbuzz_shaper.hpp b/include/mapnik/text/harfbuzz_shaper.hpp index 8b574b095..bee119557 100644 --- a/include/mapnik/text/harfbuzz_shaper.hpp +++ b/include/mapnik/text/harfbuzz_shaper.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 @@ -80,17 +80,16 @@ static void shape_text(text_line & line, line.reserve(length); auto hb_buffer_deleter = [](hb_buffer_t * buffer) { hb_buffer_destroy(buffer);}; - const std::unique_ptr buffer(hb_buffer_create(),hb_buffer_deleter); + const std::unique_ptr buffer(hb_buffer_create(), hb_buffer_deleter); hb_buffer_pre_allocate(buffer.get(), safe_cast(length)); mapnik::value_unicode_string const& text = itemizer.text(); - for (auto const& text_item : list) { face_set_ptr face_set = font_manager.get_face_set(text_item.format_->face_name, text_item.format_->fontset); double size = text_item.format_->text_size * scale_factor; face_set->set_unscaled_character_sizes(); std::size_t num_faces = face_set->size(); - std::size_t pos = 0; + font_feature_settings const& ff_settings = text_item.format_->ff_settings; int ff_count = safe_cast(ff_settings.count()); @@ -101,83 +100,116 @@ static void shape_text(text_line & line, hb_glyph_info_t glyph; hb_glyph_position_t position; }; - // this table is filled with information for rendering each glyph, so that - // several font faces can be used in a single text_item - std::vector glyphinfos; - unsigned valid_glyphs = 0; + // this table is filled with information for rendering each glyph, so that + // several font faces can be used in a single text_item + std::size_t pos = 0; + std::vector> glyphinfos; + + glyphinfos.resize(text.length()); for (auto const& face : *face_set) { ++pos; hb_buffer_clear_contents(buffer.get()); hb_buffer_add_utf16(buffer.get(), uchar_to_utf16(text.getBuffer()), text.length(), text_item.start, static_cast(text_item.end - text_item.start)); - hb_buffer_set_direction(buffer.get(), (text_item.dir == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR); + hb_buffer_set_direction(buffer.get(), (text_item.dir == UBIDI_RTL) ? HB_DIRECTION_RTL : HB_DIRECTION_LTR); hb_buffer_set_script(buffer.get(), _icu_script_to_script(text_item.script)); hb_font_t *font(hb_ft_font_create(face->get_face(), nullptr)); // https://github.com/mapnik/test-data-visual/pull/25 - #if HB_VERSION_MAJOR > 0 - #if HB_VERSION_ATLEAST(1, 0 , 5) +#if HB_VERSION_MAJOR > 0 +#if HB_VERSION_ATLEAST(1, 0 , 5) hb_ft_font_set_load_flags(font,FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); - #endif - #endif +#endif +#endif hb_shape(font, buffer.get(), ff_settings.get_features(), ff_count); hb_font_destroy(font); unsigned num_glyphs = hb_buffer_get_length(buffer.get()); + hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer.get(), &num_glyphs); + hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer.get(), &num_glyphs); - // if the number of rendered glyphs has increased, we need to resize the table - if (num_glyphs > glyphinfos.size()) + unsigned cluster = 0; + bool in_cluster = false; + std::vector clusters; + + for (unsigned i = 0; i < num_glyphs; ++i) { - glyphinfos.resize(num_glyphs); - } - - hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer.get(), nullptr); - hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer.get(), nullptr); - - // Check if all glyphs are valid. - for (unsigned i=0; iglyph_dimensions(g)) - { - g.face = theface; - g.scale_multiplier = size / theface->get_face()->units_per_EM; - //Overwrite default advance with better value provided by HarfBuzz - g.unscaled_advance = gpos.x_advance; - g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier); - double tmp_height = g.height(); - if (tmp_height > max_glyph_height) max_glyph_height = tmp_height; - width_map[char_index] += g.advance(); - line.add_glyph(std::move(g), scale_factor); + auto const& gpos = info.position; + auto const& glyph = info.glyph; + unsigned char_index = glyph.cluster; + glyph_info g(glyph.codepoint,char_index,text_item.format_); + if (info.glyph.codepoint != 0) g.face = info.face; + else g.face = face; + if (g.face->glyph_dimensions(g)) + { + g.scale_multiplier = g.face->get_face()->units_per_EM > 0 ? + (size / g.face->get_face()->units_per_EM) : (size / 2048.0) ; + //Overwrite default advance with better value provided by HarfBuzz + g.unscaled_advance = gpos.x_advance; + g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier); + double tmp_height = g.height(); + if (g.face->is_color()) + { + tmp_height = size; + } + if (tmp_height > max_glyph_height) max_glyph_height = tmp_height; + width_map[char_index] += g.advance(); + line.add_glyph(std::move(g), scale_factor); + } } } line.update_max_char_height(max_glyph_height); diff --git a/include/mapnik/text/icu_shaper.hpp b/include/mapnik/text/icu_shaper.hpp index 39bc590bb..2f3373e9c 100644 --- a/include/mapnik/text/icu_shaper.hpp +++ b/include/mapnik/text/icu_shaper.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 diff --git a/include/mapnik/text/itemizer.hpp b/include/mapnik/text/itemizer.hpp index 5087ce06f..70e99322e 100644 --- a/include/mapnik/text/itemizer.hpp +++ b/include/mapnik/text/itemizer.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 @@ -25,7 +25,7 @@ //mapnik #include -#include +#include #include #include diff --git a/include/mapnik/text/placement_finder.hpp b/include/mapnik/text/placement_finder.hpp index 3b02d8924..195dba80d 100644 --- a/include/mapnik/text/placement_finder.hpp +++ b/include/mapnik/text/placement_finder.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 @@ -23,7 +23,7 @@ #define MAPNIK_PLACEMENT_FINDER_HPP //mapnik -#include +#include #include #include #include @@ -67,8 +67,6 @@ private: bool single_line_placement(vertex_cache &pp, text_upright_e orientation); // Moves dx pixels but makes sure not to fall of the end. void path_move_dx(vertex_cache & pp, double dx); - // Normalize angle in range [-pi, +pi]. - static double normalize_angle(double angle); // Adjusts user defined spacing to place an integer number of labels. double get_spacing(double path_length, double layout_width) const; // Checks for collision. diff --git a/include/mapnik/text/placement_finder_impl.hpp b/include/mapnik/text/placement_finder_impl.hpp index 1b8f84147..efebf3d76 100644 --- a/include/mapnik/text/placement_finder_impl.hpp +++ b/include/mapnik/text/placement_finder_impl.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 @@ -21,12 +21,9 @@ *****************************************************************************/ // mapnik -//#include -//#include #include #include #include -//#include #include #include #include diff --git a/include/mapnik/text/placements/base.hpp b/include/mapnik/text/placements/base.hpp index 0b93fb8e8..8e075f575 100644 --- a/include/mapnik/text/placements/base.hpp +++ b/include/mapnik/text/placements/base.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 diff --git a/include/mapnik/text/placements/dummy.hpp b/include/mapnik/text/placements/dummy.hpp index e83808f45..3e39dd678 100644 --- a/include/mapnik/text/placements/dummy.hpp +++ b/include/mapnik/text/placements/dummy.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 diff --git a/include/mapnik/text/placements/list.hpp b/include/mapnik/text/placements/list.hpp index c21a4d87c..5da67e85b 100644 --- a/include/mapnik/text/placements/list.hpp +++ b/include/mapnik/text/placements/list.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 @@ -50,8 +50,8 @@ private: class text_placement_info_list : public text_placement_info { public: - text_placement_info_list(text_placements_list const* parent, double scale_factor) : - text_placement_info(parent, scale_factor), + text_placement_info_list(text_placements_list const* parent, double _scale_factor) : + text_placement_info(parent, _scale_factor), state(0), parent_(parent) {} bool next() const; private: diff --git a/include/mapnik/text/placements/registry.hpp b/include/mapnik/text/placements/registry.hpp index f8d8aefb1..76ec5e285 100644 --- a/include/mapnik/text/placements/registry.hpp +++ b/include/mapnik/text/placements/registry.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 diff --git a/include/mapnik/text/placements/simple.hpp b/include/mapnik/text/placements/simple.hpp index ea0d73c5e..9f7bf91bc 100644 --- a/include/mapnik/text/placements/simple.hpp +++ b/include/mapnik/text/placements/simple.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 diff --git a/include/mapnik/text/properties_util.hpp b/include/mapnik/text/properties_util.hpp index 5b92ed306..d280f5657 100644 --- a/include/mapnik/text/properties_util.hpp +++ b/include/mapnik/text/properties_util.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 diff --git a/include/mapnik/text/renderer.hpp b/include/mapnik/text/renderer.hpp index 692ada3cd..267a1bae5 100644 --- a/include/mapnik/text/renderer.hpp +++ b/include/mapnik/text/renderer.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 @@ -28,6 +28,7 @@ #include #include #include +#include #pragma GCC diagnostic push #include @@ -51,8 +52,13 @@ struct glyph_t { FT_Glyph image; detail::evaluated_format_properties const& properties; - glyph_t(FT_Glyph image_, detail::evaluated_format_properties const& properties_) - : image(image_), properties(properties_) {} + pixel_position pos; + double size; + glyph_t(FT_Glyph image_, detail::evaluated_format_properties const& properties_, pixel_position const& pos_, double size_) + : image(image_), + properties(properties_), + pos(pos_), + size(size_) {} }; class text_renderer : private util::noncopyable diff --git a/include/mapnik/text/symbolizer_helpers.hpp b/include/mapnik/text/symbolizer_helpers.hpp index 83a3c1939..222c6f89e 100644 --- a/include/mapnik/text/symbolizer_helpers.hpp +++ b/include/mapnik/text/symbolizer_helpers.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 @@ -59,7 +59,7 @@ struct placement_finder_adapter }; -using vertex_converter_type = vertex_converter; +using vertex_converter_type = vertex_converter; class base_symbolizer_helper { diff --git a/include/mapnik/text/text_layout.hpp b/include/mapnik/text/text_layout.hpp index 2e59cdc8b..a79a0caf8 100644 --- a/include/mapnik/text/text_layout.hpp +++ b/include/mapnik/text/text_layout.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 @@ -23,9 +23,9 @@ #define MAPNIK_TEXT_LAYOUT_HPP //mapnik -#include +#include #include -#include +#include #include #include #include @@ -143,8 +143,8 @@ private: // note: this probably isn't the best solution. it would be better to have an object for each cluster, but // it needs to be implemented with no overhead. std::map width_map_; - double width_; - double height_; + double width_ = 0.0; + double height_ = 0.0; unsigned glyphs_count_; // output @@ -173,7 +173,7 @@ private: bool rotate_displacement_ = false; double text_ratio_ = 0.0; pixel_position displacement_ = {0,0}; - box2d bounds_; + box2d bounds_ = {0, 0, 0, 0}; // children text_layout_vector child_layout_list_; diff --git a/include/mapnik/text/text_line.hpp b/include/mapnik/text/text_line.hpp index cf47026df..81e7d7e72 100644 --- a/include/mapnik/text/text_line.hpp +++ b/include/mapnik/text/text_line.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 diff --git a/include/mapnik/text/text_properties.hpp b/include/mapnik/text/text_properties.hpp index 511ba3a28..677cd3230 100644 --- a/include/mapnik/text/text_properties.hpp +++ b/include/mapnik/text/text_properties.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 @@ -96,7 +96,8 @@ enum directions_e : std::uint8_t SOUTHEAST, NORTHWEST, SOUTHWEST, - EXACT_POSITION + EXACT_POSITION, + CENTER }; using fontset_map = std::map; diff --git a/include/mapnik/tiff_io.hpp b/include/mapnik/tiff_io.hpp index b80142906..1b31cb94c 100644 --- a/include/mapnik/tiff_io.hpp +++ b/include/mapnik/tiff_io.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 diff --git a/include/mapnik/timer.hpp b/include/mapnik/timer.hpp index 8111ff645..347fda4d2 100644 --- a/include/mapnik/timer.hpp +++ b/include/mapnik/timer.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 diff --git a/include/mapnik/tolerance_iterator.hpp b/include/mapnik/tolerance_iterator.hpp index 2b9512c8b..448a0af3b 100644 --- a/include/mapnik/tolerance_iterator.hpp +++ b/include/mapnik/tolerance_iterator.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 diff --git a/include/mapnik/parse_transform.hpp b/include/mapnik/transform/parse_transform.hpp similarity index 97% rename from include/mapnik/parse_transform.hpp rename to include/mapnik/transform/parse_transform.hpp index 68e605c40..8d4c4899b 100644 --- a/include/mapnik/parse_transform.hpp +++ b/include/mapnik/transform/parse_transform.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 diff --git a/include/mapnik/transform_expression.hpp b/include/mapnik/transform/transform_expression.hpp similarity index 92% rename from include/mapnik/transform_expression.hpp rename to include/mapnik/transform/transform_expression.hpp index b43f69170..18256efee 100644 --- a/include/mapnik/transform_expression.hpp +++ b/include/mapnik/transform/transform_expression.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 @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #include #include #include @@ -55,6 +55,8 @@ struct matrix_node expr_node e_; expr_node f_; + matrix_node() = default; + template explicit matrix_node(T const& m) : a_(m.sx), b_(m.shy), c_(m.shx), d_(m.sy), e_(m.tx), f_(m.ty) {} @@ -69,6 +71,8 @@ struct translate_node expr_node tx_; expr_node ty_; + translate_node() = default; + translate_node(expr_node const& tx, boost::optional const& ty) : tx_(tx) @@ -80,6 +84,8 @@ struct scale_node expr_node sx_; expr_node sy_; + scale_node() = default; + scale_node(expr_node const& sx, boost::optional const& sy) : sx_(sx) @@ -94,6 +100,8 @@ struct rotate_node expr_node cx_; expr_node cy_; + rotate_node() = default; + explicit rotate_node(expr_node const& angle) : angle_(angle) {} @@ -123,16 +131,16 @@ struct rotate_node struct skewX_node { expr_node angle_; - - explicit skewX_node(expr_node const& angle) + skewX_node() = default; + skewX_node(expr_node const& angle) : angle_(angle) {} }; struct skewY_node { expr_node angle_; - - explicit skewY_node(expr_node const& angle) + skewY_node() = default; + skewY_node(expr_node const& angle) : angle_(angle) {} }; @@ -225,9 +233,9 @@ bool is_null_node (T const& node) } // namespace detail -using transform_node = detail::transform_node ; -using transform_list = std::vector ; -using transform_list_ptr = std::shared_ptr ; +using transform_node = detail::transform_node; +using transform_list = std::vector; +using transform_list_ptr = std::shared_ptr; MAPNIK_DECL std::string to_expression_string(transform_node const& node); MAPNIK_DECL std::string to_expression_string(transform_list const& list); diff --git a/include/mapnik/transform/transform_expression_grammar_x3.hpp b/include/mapnik/transform/transform_expression_grammar_x3.hpp new file mode 100644 index 000000000..4cc5237f2 --- /dev/null +++ b/include/mapnik/transform/transform_expression_grammar_x3.hpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_TRANSFORM_GRAMMAR_X3_HPP +#define MAPNIK_TRANSFORM_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +namespace grammar { + +struct transform_expression_class; // top-most ID +using transform_expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(transform_expression_grammar_type); + +}} // ns + +namespace mapnik +{ +grammar::transform_expression_grammar_type const& transform_expression_grammar(); +} + +#endif diff --git a/include/mapnik/transform/transform_expression_grammar_x3_def.hpp b/include/mapnik/transform/transform_expression_grammar_x3_def.hpp new file mode 100644 index 000000000..76c439391 --- /dev/null +++ b/include/mapnik/transform/transform_expression_grammar_x3_def.hpp @@ -0,0 +1,223 @@ +/***************************************************************************** + * + * 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_TRANSFORM_GRAMMAR_X3_DEF_HPP +#define MAPNIK_TRANSFORM_GRAMMAR_X3_DEF_HPP + +#include +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#pragma GCC diagnostic pop + +// skewX +BOOST_FUSION_ADAPT_STRUCT(mapnik::skewX_node, + (mapnik::expr_node, angle_)) + +// skewY +BOOST_FUSION_ADAPT_STRUCT(mapnik::skewY_node, + (mapnik::expr_node, angle_)) + + +// Following specializations are required to avoid trasferring mapnik::skewX/Y nodes as underlying expressions +// +// template +// inline void +// move_to_plain(Source&& src, Dest& dest, mpl::true_) // src is a single-element tuple +// { +// dest = std::move(fusion::front(src)); +// } +// which will fail to compile with latest (more strict) `mapbox::variant` (boost_1_61) + +namespace boost { namespace spirit { namespace x3 { namespace traits { +template <> +inline void move_to(mapnik::skewX_node && src, mapnik::detail::transform_node& dst) +{ + dst = std::move(src); +} + +template <> +inline void move_to(mapnik::skewY_node && src, mapnik::detail::transform_node& dst) +{ + dst = std::move(src); +} + +}}}} + + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +namespace ascii = boost::spirit::x3::ascii; + +// [http://www.w3.org/TR/SVG/coords.html#TransformAttribute] + +// The value of the ‘transform’ attribute is a , which +// is defined as a list of transform definitions, which are applied in +// the order provided. The individual transform definitions are +// separated by whitespace and/or a comma. + +using x3::double_; +using x3::no_skip; +using x3::no_case; +using x3::lit; + +auto const create_expr_node = [](auto const& ctx) +{ + _val(ctx) = _attr(ctx); +}; + +auto const construct_matrix = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& a = boost::fusion::at>(attr); + auto const& b = boost::fusion::at>(attr); + auto const& c = boost::fusion::at>(attr); + auto const& d = boost::fusion::at>(attr); + auto const& e = boost::fusion::at>(attr); + auto const& f = boost::fusion::at>(attr); + _val(ctx) = mapnik::matrix_node(a, b, c, d, e, f); +}; + +auto const construct_translate = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& dx = boost::fusion::at>(attr); + auto const& dy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::translate_node(dx, dy); +}; + +auto const construct_scale = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& sx = boost::fusion::at>(attr); + auto const& sy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::scale_node(sx, sy); +}; + +auto const construct_rotate = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& a = boost::fusion::at>(attr); + auto const& sx = boost::fusion::at>(attr); //optional + auto const& sy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::rotate_node(a, sx, sy); +}; + +// starting rule +transform_expression_grammar_type const transform("transform"); +// rules +x3::rule transform_list_rule("transform list"); +x3::rule transform_node_rule("transform node"); +x3::rule matrix("matrix node"); +x3::rule translate("translate node"); +x3::rule scale("scale node"); +x3::rule rotate("rotate node"); +x3::rule skewX("skew X node"); +x3::rule skewY("skew Y node"); +x3::rule expr("Expression"); +x3::rule sep_expr("Separated Expression"); + +// start +auto const transform_def = transform_list_rule; + +auto const transform_list_rule_def = transform_node_rule % *lit(','); + +auto const transform_node_rule_def = matrix | translate | scale | rotate | skewX | skewY ; + +// number or attribute +auto const atom = x3::rule {} = double_[create_expr_node] + ; + +auto const sep_atom = x3::rule {} = -lit(',') >> double_[create_expr_node] + ; + +auto const expr_def = expression_grammar(); +// Individual arguments in lists containing one or more compound +// expressions are separated by a comma. +auto const sep_expr_def = lit(',') > expr + ; + +// matrix( ) +auto const matrix_def = no_case[lit("matrix")] > '(' + > ((atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom >> lit(')'))[construct_matrix] + | + (expr > sep_expr > sep_expr > sep_expr > sep_expr > sep_expr > lit(')'))[construct_matrix]) + ; + +// translate( []) +auto const translate_def = no_case[lit("translate")] > lit('(') + > (( atom >> -sep_atom >> lit(')'))[construct_translate] + | + ( expr > -sep_expr > lit(')'))[construct_translate] + ); + +// scale( []) +auto const scale_def = no_case[lit("scale")] > lit('(') + > (( atom >> -sep_atom >> lit(')'))[construct_scale] + | + ( expr > -sep_expr > lit(')'))[construct_scale] + ); + +// rotate( [ ]) +auto const rotate_def = no_case[lit("rotate")] > lit('(') + > ((atom >> -sep_atom >> -sep_atom >> lit(')'))[construct_rotate] + | + (expr > -sep_expr > -sep_expr > lit(')'))[construct_rotate] + ); + +// skewX() +auto const skewX_def = no_case[lit("skewX")] + > '(' > expr > ')'; + +// skewY() +auto const skewY_def = no_case[lit("skewY")] + > '(' > expr > ')'; + +BOOST_SPIRIT_DEFINE ( + expr, + sep_expr, + transform, + transform_list_rule, + transform_node_rule, + matrix, + translate, + scale, + rotate, + skewX, + skewY); + +}} // ns + +namespace mapnik +{ +grammar::transform_expression_grammar_type const& transform_expression_grammar() +{ + return grammar::transform; +} +} + +#endif diff --git a/include/mapnik/transform_processor.hpp b/include/mapnik/transform/transform_processor.hpp similarity index 98% rename from include/mapnik/transform_processor.hpp rename to include/mapnik/transform/transform_processor.hpp index b1d8eab73..1e780b320 100644 --- a/include/mapnik/transform_processor.hpp +++ b/include/mapnik/transform/transform_processor.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 @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #include #include diff --git a/include/mapnik/transform_expression_grammar.hpp b/include/mapnik/transform_expression_grammar.hpp deleted file mode 100644 index f3945f39b..000000000 --- a/include/mapnik/transform_expression_grammar.hpp +++ /dev/null @@ -1,66 +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_TRANSFORM_EXPRESSION_GRAMMAR_HPP -#define MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -// spirit -#include - -namespace mapnik { - - namespace qi = boost::spirit::qi; - - template - struct transform_expression_grammar - : qi::grammar - { - explicit transform_expression_grammar(); - - using node_rule = qi::rule; - using list_rule = qi::rule; - - // rules - qi::rule attr; - qi::rule atom; - qi::rule expr; - qi::rule sep_atom; - qi::rule sep_expr; - qi::rule start; - qi::rule transform_; - qi::rule matrix; - qi::rule translate; - qi::rule scale; - qi::rule rotate; - qi::rule skewX; - qi::rule skewY; - mapnik::expression_grammar g_; - }; - -} // namespace mapnik - -#endif // MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP diff --git a/include/mapnik/transform_expression_grammar_impl.hpp b/include/mapnik/transform_expression_grammar_impl.hpp deleted file mode 100644 index 4b8c2b92a..000000000 --- a/include/mapnik/transform_expression_grammar_impl.hpp +++ /dev/null @@ -1,128 +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 - -// boost -#include -#include -#include - - -namespace mapnik { - -namespace qi = boost::spirit::qi; - -template -transform_expression_grammar::transform_expression_grammar() - : transform_expression_grammar::base_type(start) -{ - using boost::phoenix::construct; - qi::_1_type _1; - qi::_4_type _4; - qi::_2_type _2; - qi::_5_type _5; - qi::_3_type _3; - qi::_6_type _6; - qi::_val_type _val; - qi::double_type double_; - qi::lit_type lit; - qi::no_case_type no_case; - - // [http://www.w3.org/TR/SVG/coords.html#TransformAttribute] - - // The value of the ‘transform’ attribute is a , which - // is defined as a list of transform definitions, which are applied in - // the order provided. The individual transform definitions are - // separated by whitespace and/or a comma. - - start = transform_ % *lit(',') ; - - transform_ = matrix | translate | scale | rotate | skewX | skewY ; - - // matrix( ) - matrix = no_case[lit("matrix")] - >> (lit('(') - >> ( atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom - >> sep_atom >> lit(')') - | expr >> sep_expr >> sep_expr >> sep_expr >> sep_expr - >> sep_expr >> lit(')') - )) - [ _val = construct(_1,_2,_3,_4,_5,_6) ]; - - // translate( []) - translate = no_case[lit("translate")] - >> lit('(') - >> ( ( atom >> -sep_atom >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -sep_expr >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // scale( []) - scale = no_case[lit("scale")] - >> lit('(') - >> ( ( atom >> -sep_atom >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -sep_expr >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // rotate( [ ]) - rotate = no_case[lit("rotate")] - >> lit('(') - >> ( ( atom >> -( sep_atom >> sep_atom ) >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -( sep_expr >> sep_expr ) >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // skewX() - skewX = no_case[lit("skewX")] - >> lit('(') - >> expr [ _val = construct(_1) ] - >> lit(')'); - - // skewY() - skewY = no_case[lit("skewY")] - >> lit('(') - >> expr [ _val = construct(_1) ] - >> lit(')'); - - // number or attribute - atom = double_ [ _val = _1 ] - | attr [ _val = construct(_1) ]; - - // Individual arguments in lists consiting solely of numbers and/or - // attributes are separated by whitespace and/or a comma. - sep_atom = -lit(',') >> atom [ _val = _1 ]; - - // Individual arguments in lists containing one or more compound - // expressions are separated by a comma. - sep_expr = lit(',') >> expr [ _val = _1 ]; - - attr = g_.attr.alias(); - expr = g_.expr.alias(); -} - -} diff --git a/include/mapnik/transform_path_adapter.hpp b/include/mapnik/transform_path_adapter.hpp index 08212703f..fbb7a75ee 100644 --- a/include/mapnik/transform_path_adapter.hpp +++ b/include/mapnik/transform_path_adapter.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 diff --git a/include/mapnik/unicode.hpp b/include/mapnik/unicode.hpp index f3b270cb9..48b433f68 100644 --- a/include/mapnik/unicode.hpp +++ b/include/mapnik/unicode.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 @@ -26,7 +26,7 @@ //mapnik #include #include -#include +#include // std #include diff --git a/include/mapnik/util/const_rendering_buffer.hpp b/include/mapnik/util/const_rendering_buffer.hpp index 97b98ca65..5ee9de7f1 100644 --- a/include/mapnik/util/const_rendering_buffer.hpp +++ b/include/mapnik/util/const_rendering_buffer.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 @@ -58,4 +58,4 @@ struct rendering_buffer }} -#endif // MAPNIK_CONST_RENDERING_BUFFER_HPP \ No newline at end of file +#endif // MAPNIK_CONST_RENDERING_BUFFER_HPP diff --git a/include/mapnik/util/container_adapter.hpp b/include/mapnik/util/container_adapter.hpp index 8c70c4c2a..63d25163c 100644 --- a/include/mapnik/util/container_adapter.hpp +++ b/include/mapnik/util/container_adapter.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 diff --git a/include/mapnik/util/conversions.hpp b/include/mapnik/util/conversions.hpp index 284d20e03..009e9315c 100644 --- a/include/mapnik/util/conversions.hpp +++ b/include/mapnik/util/conversions.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include // stl #include diff --git a/include/mapnik/util/dasharray_parser.hpp b/include/mapnik/util/dasharray_parser.hpp index 7c5d26711..191da098f 100644 --- a/include/mapnik/util/dasharray_parser.hpp +++ b/include/mapnik/util/dasharray_parser.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 diff --git a/include/mapnik/util/feature_to_geojson.hpp b/include/mapnik/util/feature_to_geojson.hpp index ad3c0a7d4..b6e5797c4 100644 --- a/include/mapnik/util/feature_to_geojson.hpp +++ b/include/mapnik/util/feature_to_geojson.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,23 +20,18 @@ * *****************************************************************************/ -#ifndef MAPNIK_FEATURE_TO_GEOJSON_HPP -#define MAPNIK_FEATURE_TO_GEOJSON_HPP +#ifndef MAPNIK_UTIL_FEATURE_TO_GEOJSON_HPP +#define MAPNIK_UTIL_FEATURE_TO_GEOJSON_HPP // mapnik - -#include +#include +// stl +#include namespace mapnik { namespace util { -inline bool to_geojson(std::string & json, mapnik::feature_impl const& feat) -{ - using sink_type = std::back_insert_iterator; - static const mapnik::json::feature_generator_grammar grammar; - sink_type sink(json); - return boost::spirit::karma::generate(sink, grammar, feat); -} +bool to_geojson(std::string & json, mapnik::feature_impl const& feat); }} -#endif // MAPNIK_FEATURE_TO_GEOJSON_HPP +#endif // MAPNIK_UTIL_FEATURE_TO_GEOJSON_HPP diff --git a/include/mapnik/util/featureset_buffer.hpp b/include/mapnik/util/featureset_buffer.hpp index 8689a41e9..ff2a8b39e 100644 --- a/include/mapnik/util/featureset_buffer.hpp +++ b/include/mapnik/util/featureset_buffer.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 diff --git a/include/mapnik/util/file_io.hpp b/include/mapnik/util/file_io.hpp index b8bc22f01..00c925006 100644 --- a/include/mapnik/util/file_io.hpp +++ b/include/mapnik/util/file_io.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 @@ -83,7 +83,8 @@ public: if (!size_) return nullptr; std::fseek(file_.get(), 0, SEEK_SET); data_type buffer(new char[size_]); - std::fread(buffer.get(), size_, 1, file_.get()); + auto count = std::fread(buffer.get(), size_, 1, file_.get()); + if (count != 1) return nullptr; return buffer; } private: diff --git a/include/mapnik/util/fs.hpp b/include/mapnik/util/fs.hpp index 03905cb45..57abef0a4 100644 --- a/include/mapnik/util/fs.hpp +++ b/include/mapnik/util/fs.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 diff --git a/include/mapnik/util/geometry_to_ds_type.hpp b/include/mapnik/util/geometry_to_ds_type.hpp index 7791285ac..cbd0841a9 100644 --- a/include/mapnik/util/geometry_to_ds_type.hpp +++ b/include/mapnik/util/geometry_to_ds_type.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 @@ -42,7 +42,7 @@ namespace detail { struct datasource_geometry_type { - mapnik::datasource_geometry_t operator () (mapnik::geometry::geometry_empty const&) const + mapnik::datasource_geometry_t operator () (mapnik::geometry::geometry_empty const&) const { return mapnik::datasource_geometry_t::Unknown; } diff --git a/include/mapnik/util/geometry_to_geojson.hpp b/include/mapnik/util/geometry_to_geojson.hpp index 71c867eb7..02d3bd34f 100644 --- a/include/mapnik/util/geometry_to_geojson.hpp +++ b/include/mapnik/util/geometry_to_geojson.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 diff --git a/include/mapnik/util/geometry_to_svg.hpp b/include/mapnik/util/geometry_to_svg.hpp index 9efb55134..f95567ab3 100644 --- a/include/mapnik/util/geometry_to_svg.hpp +++ b/include/mapnik/util/geometry_to_svg.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 diff --git a/include/mapnik/util/geometry_to_wkb.hpp b/include/mapnik/util/geometry_to_wkb.hpp index f16ad240a..bf3a3dd10 100644 --- a/include/mapnik/util/geometry_to_wkb.hpp +++ b/include/mapnik/util/geometry_to_wkb.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include // stl #include @@ -229,7 +229,7 @@ struct geometry_to_wkb return util::apply_visitor(*this, geom); } - result_type operator() (geometry::geometry_empty const&) const + result_type operator() (geometry::geometry_empty const&) const { return result_type(); } diff --git a/include/mapnik/util/geometry_to_wkt.hpp b/include/mapnik/util/geometry_to_wkt.hpp index 3c81ef440..73637d04e 100644 --- a/include/mapnik/util/geometry_to_wkt.hpp +++ b/include/mapnik/util/geometry_to_wkt.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 @@ -24,29 +24,15 @@ #define MAPNIK_GEOMETRY_TO_WKT_HPP // mapnik -#include -#include - -// boost -#include +#include +// stl +#include namespace mapnik { namespace util { -inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) -{ - using sink_type = std::back_insert_iterator; - static const mapnik::wkt::wkt_generator_grammar> generator; - sink_type sink(wkt); - return boost::spirit::karma::generate(sink, generator, geom); -} +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom); -inline bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) -{ - using sink_type = std::back_insert_iterator; - static const mapnik::wkt::wkt_generator_grammar> generator; - sink_type sink(wkt); - return boost::spirit::karma::generate(sink, generator, geom); -} +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom); }} diff --git a/include/mapnik/util/hsl.hpp b/include/mapnik/util/hsl.hpp index d060da92f..5776570cf 100644 --- a/include/mapnik/util/hsl.hpp +++ b/include/mapnik/util/hsl.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 diff --git a/include/mapnik/util/is_clockwise.hpp b/include/mapnik/util/is_clockwise.hpp index 93951df38..6ec532769 100644 --- a/include/mapnik/util/is_clockwise.hpp +++ b/include/mapnik/util/is_clockwise.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 diff --git a/include/mapnik/util/math.hpp b/include/mapnik/util/math.hpp index 4b24893b1..fed1c7bbf 100644 --- a/include/mapnik/util/math.hpp +++ b/include/mapnik/util/math.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 diff --git a/include/mapnik/util/noncopyable.hpp b/include/mapnik/util/noncopyable.hpp index 7a6a9f8f7..44bb3654e 100644 --- a/include/mapnik/util/noncopyable.hpp +++ b/include/mapnik/util/noncopyable.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 diff --git a/include/mapnik/util/path_iterator.hpp b/include/mapnik/util/path_iterator.hpp index 19b69ce26..e7c6b92b5 100644 --- a/include/mapnik/util/path_iterator.hpp +++ b/include/mapnik/util/path_iterator.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 diff --git a/include/mapnik/util/rounding_cast.hpp b/include/mapnik/util/rounding_cast.hpp index d67c066cc..512363b23 100644 --- a/include/mapnik/util/rounding_cast.hpp +++ b/include/mapnik/util/rounding_cast.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 diff --git a/include/mapnik/util/singleton.hpp b/include/mapnik/util/singleton.hpp index fcb0275ef..61c5b6962 100644 --- a/include/mapnik/util/singleton.hpp +++ b/include/mapnik/util/singleton.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 diff --git a/include/mapnik/util/spatial_index.hpp b/include/mapnik/util/spatial_index.hpp index 720667768..0f271526e 100644 --- a/include/mapnik/util/spatial_index.hpp +++ b/include/mapnik/util/spatial_index.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 @@ -25,7 +25,7 @@ //mapnik #include -#include +#include #include #include // stl diff --git a/include/mapnik/util/spirit_transform_attribute.hpp b/include/mapnik/util/spirit_transform_attribute.hpp index e53d335a1..31b80e38c 100644 --- a/include/mapnik/util/spirit_transform_attribute.hpp +++ b/include/mapnik/util/spirit_transform_attribute.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 diff --git a/include/mapnik/util/timer.hpp b/include/mapnik/util/timer.hpp index e29a8eae1..7c8ff67d3 100644 --- a/include/mapnik/util/timer.hpp +++ b/include/mapnik/util/timer.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 diff --git a/include/mapnik/util/trim.hpp b/include/mapnik/util/trim.hpp index 60320331b..9b0e5c7c5 100644 --- a/include/mapnik/util/trim.hpp +++ b/include/mapnik/util/trim.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 diff --git a/include/mapnik/util/utf_conv_win.hpp b/include/mapnik/util/utf_conv_win.hpp index 68e28ec15..f6c0ea19a 100644 --- a/include/mapnik/util/utf_conv_win.hpp +++ b/include/mapnik/util/utf_conv_win.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 diff --git a/include/mapnik/util/variant.hpp b/include/mapnik/util/variant.hpp index 27993ce3f..2451cea0c 100644 --- a/include/mapnik/util/variant.hpp +++ b/include/mapnik/util/variant.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 @@ -32,15 +32,7 @@ template using recursive_wrapper = typename mapbox::util::recursive_wrapper; template -class variant : public mapbox::util::variant -{ -public: - // tell spirit that this is an adapted variant - struct adapted_variant_tag; - using types = std::tuple; - // inherit ctor's - using mapbox::util::variant::variant; -}; +using variant = typename mapbox::util::variant; // unary visitor interface // const diff --git a/include/mapnik/util/variant_io.hpp b/include/mapnik/util/variant_io.hpp index 02f0be5ca..bdbfcdbbc 100644 --- a/include/mapnik/util/variant_io.hpp +++ b/include/mapnik/util/variant_io.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 @@ -24,7 +24,7 @@ #define MAPNIK_UTIL_VARIANT_IO_HPP -namespace mapnik { namespace util { +namespace mapbox { namespace util { namespace detail { diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp index 9ee732385..0618e8abe 100644 --- a/include/mapnik/value.hpp +++ b/include/mapnik/value.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 @@ -25,8 +25,8 @@ // mapnik #include -#include -#include +#include +#include #include @@ -47,30 +47,20 @@ class MAPNIK_DECL value : public value_base public: value() = default; - // conversion from type T is done via a temporary of type U, which - // is determined by mapnik_value_type; - // enable_if< decay != value > is necessary to avoid ill-formed - // recursion in noexcept specifier; and it also prevents using this - // constructor where implicitly-declared copy/move should be used - // (e.g. value(value&)) - template ::value, - detail::mapnik_value_type_decay - >::type::type> + // Conversion from type T is done via a temporary value or reference + // of type U, which is determined by mapnik_value_type_t. + // + // CAVEAT: We don't check `noexcept(conversion from T to U)`. + // But since the type U is either value_bool, value_integer, + // value_double or T &&, this conversion SHOULD NEVER throw. + template > value(T && val) - noexcept(noexcept(U(std::forward(val))) && - std::is_nothrow_constructible::value) + noexcept(std::is_nothrow_constructible::value) : value_base(U(std::forward(val))) {} - template ::value, - detail::mapnik_value_type_decay - >::type::type> + template > value& operator=(T && val) - noexcept(noexcept(U(std::forward(val))) && - std::is_nothrow_assignable::value) + noexcept(std::is_nothrow_assignable::value) { value_base::operator=(U(std::forward(val))); return *this; @@ -115,7 +105,7 @@ operator << (std::basic_ostream& out, // hash function inline std::size_t hash_value(value const& val) { - return mapnik_hash_value(val); + return mapnik::value_hash(val); } } // namespace value_adl_barrier @@ -157,7 +147,7 @@ struct hash { size_t operator()(mapnik::value const& val) const { - return mapnik::mapnik_hash_value(val); + return mapnik::value_hash(val); } }; diff --git a/include/mapnik/value_error.hpp b/include/mapnik/value/error.hpp similarity index 91% rename from include/mapnik/value_error.hpp rename to include/mapnik/value/error.hpp index 68df62255..f371f7bae 100644 --- a/include/mapnik/value_error.hpp +++ b/include/mapnik/value/error.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 @@ -38,12 +38,11 @@ public: value_error( std::string const& what ) : what_( what ) - { - } + {} - virtual ~value_error() throw() {} + virtual ~value_error() {} - virtual const char * what() const throw() + virtual const char * what() const noexcept { return what_.c_str(); } @@ -56,6 +55,7 @@ public: protected: mutable std::string what_; }; + } #endif // MAPNIK_VALUE_ERROR_HPP diff --git a/include/mapnik/value_hash.hpp b/include/mapnik/value/hash.hpp similarity index 75% rename from include/mapnik/value_hash.hpp rename to include/mapnik/value/hash.hpp index 80e10d855..86bb190ad 100644 --- a/include/mapnik/value_hash.hpp +++ b/include/mapnik/value/hash.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include // stl #include @@ -35,12 +35,9 @@ #pragma GCC diagnostic pop -namespace mapnik { namespace detail { +namespace mapnik { -inline void hash_combine(std::size_t & seed, std::size_t val) -{ - seed ^= val + 0x9e3779b9 + (seed << 6) + (seed >> 2); -} +namespace detail { struct value_hasher { @@ -54,11 +51,6 @@ struct value_hasher return static_cast(val.hashCode()); } - std::size_t operator()(value_integer val) const - { - return static_cast(val); - } - template std::size_t operator()(T const& val) const { @@ -70,12 +62,9 @@ struct value_hasher } // namespace detail template -std::size_t mapnik_hash_value(T const& val) +std::size_t value_hash(T const& val) { - std::size_t seed = 0; - detail::hash_combine(seed, util::apply_visitor(detail::value_hasher(), val)); - detail::hash_combine(seed, val.which()); - return seed; + return util::apply_visitor(detail::value_hasher(), val); } } // namespace mapnik diff --git a/include/mapnik/value_types.hpp b/include/mapnik/value/types.hpp similarity index 61% rename from include/mapnik/value_types.hpp rename to include/mapnik/value/types.hpp index 235133a34..93ee0859a 100644 --- a/include/mapnik/value_types.hpp +++ b/include/mapnik/value/types.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 @@ -25,6 +25,7 @@ // mapnik #include +#include #include @@ -34,7 +35,6 @@ #pragma GCC diagnostic pop // stl -#include #include #include @@ -152,90 +152,23 @@ inline std::istream& operator>> ( std::istream & s, value_null & ) namespace detail { -// to mapnik::value_type conversions traits -template -struct is_value_bool -{ - constexpr static bool value = std::is_same::value; -}; -template -struct is_value_integer -{ - constexpr static bool value = std::is_integral::value && !std::is_same::value; -}; +// Helper metafunction for mapnik::value construction and assignment. +// Returns: +// value_bool if T is bool +// value_integer if T is an integral type (except bool) +// value_double if T is a floating-point type +// T && otherwise -template -struct is_value_double -{ - constexpr static bool value = std::is_floating_point::value; -}; - -template -struct is_value_unicode_string -{ - constexpr static bool value = std::is_same::value; -}; - -template -struct is_value_string -{ - constexpr static bool value = std::is_same::value; -}; - -template -struct is_value_null -{ - constexpr static bool value = std::is_same::value; -}; - -template -struct mapnik_value_type -{ - using type = T; -}; - -// value_null -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_null; -}; - -// value_bool -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_bool; -}; - -// value_integer -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_integer; -}; - -// value_double -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_double; -}; - -// value_unicode_string -template -struct mapnik_value_type::value>::type> -{ - using type = mapnik::value_unicode_string const&; -}; - -template -using mapnik_value_type_decay = mapnik_value_type::type>; - -template -using is_same_decay = std::is_same::type, - typename std::decay::type>; +template > +using mapnik_value_type_t = + conditional_t< + std::is_same::value, value_bool, + conditional_t< + std::is_integral
::value, value_integer, + conditional_t< + std::is_floating_point
::value, value_double, + T && >>>; } // namespace detail diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp index deba4287c..c6eecef02 100644 --- a/include/mapnik/version.hpp +++ b/include/mapnik/version.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 @@ -26,8 +26,8 @@ #include #define MAPNIK_MAJOR_VERSION 3 -#define MAPNIK_MINOR_VERSION 0 -#define MAPNIK_PATCH_VERSION 12 +#define MAPNIK_MINOR_VERSION 1 +#define MAPNIK_PATCH_VERSION 0 #define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION) diff --git a/include/mapnik/vertex.hpp b/include/mapnik/vertex.hpp index 92b6a0b4f..25c5213e4 100644 --- a/include/mapnik/vertex.hpp +++ b/include/mapnik/vertex.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 diff --git a/include/mapnik/vertex_adapters.hpp b/include/mapnik/vertex_adapters.hpp index 4dbdcd2e5..eeee90785 100644 --- a/include/mapnik/vertex_adapters.hpp +++ b/include/mapnik/vertex_adapters.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 @@ -24,7 +24,7 @@ #define MAPNIK_VERTEX_ADAPTERS_HPP #include -#include +#include #include namespace mapnik { namespace geometry { diff --git a/include/mapnik/vertex_cache.hpp b/include/mapnik/vertex_cache.hpp index 9df786e62..abacb14de 100644 --- a/include/mapnik/vertex_cache.hpp +++ b/include/mapnik/vertex_cache.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 diff --git a/include/mapnik/vertex_converters.hpp b/include/mapnik/vertex_converters.hpp index ba1829472..05c0d74fc 100644 --- a/include/mapnik/vertex_converters.hpp +++ b/include/mapnik/vertex_converters.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 @@ -32,10 +32,11 @@ #include #include #include -#include +#include #include #include #include +#include #pragma GCC diagnostic push #include @@ -65,6 +66,7 @@ struct stroke_tag {}; struct dash_tag {}; struct affine_transform_tag {}; struct offset_transform_tag {}; +struct extend_tag {}; namespace detail { @@ -254,6 +256,23 @@ struct converter_traits } }; +template +struct converter_traits +{ + using geometry_type = T; + using conv_type = extend_converter; + + template + static void setup(geometry_type & geom, Args const& args) + { + auto const& sym = args.sym; + auto const& feat = args.feature; + auto const& vars = args.vars; + double extend = get(sym, feat, vars); + geom.set_extend(extend * args.scale_factor); + } +}; + template struct is_switchable diff --git a/include/mapnik/vertex_processor.hpp b/include/mapnik/vertex_processor.hpp index 57f6b4112..5d30b77da 100644 --- a/include/mapnik/vertex_processor.hpp +++ b/include/mapnik/vertex_processor.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 @@ -39,8 +39,8 @@ struct vertex_processor { util::apply_visitor(*this, geom); } - template - void operator() (geometry_empty const&) const + + void operator() (geometry_empty const&) const { // no-op } diff --git a/include/mapnik/vertex_vector.hpp b/include/mapnik/vertex_vector.hpp index a55f5ec20..6b397f41f 100644 --- a/include/mapnik/vertex_vector.hpp +++ b/include/mapnik/vertex_vector.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 diff --git a/include/mapnik/view_strategy.hpp b/include/mapnik/view_strategy.hpp index 0d1125b97..951012d97 100644 --- a/include/mapnik/view_strategy.hpp +++ b/include/mapnik/view_strategy.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 diff --git a/include/mapnik/view_transform.hpp b/include/mapnik/view_transform.hpp index 74fa89cf7..96cde0a4c 100644 --- a/include/mapnik/view_transform.hpp +++ b/include/mapnik/view_transform.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 @@ -25,7 +25,7 @@ // mapnik #include -#include +#include #include namespace mapnik diff --git a/include/mapnik/warning_ignore.hpp b/include/mapnik/warning_ignore.hpp index ccbf16925..fe0f4f83d 100644 --- a/include/mapnik/warning_ignore.hpp +++ b/include/mapnik/warning_ignore.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 diff --git a/include/mapnik/warning_ignore_agg.hpp b/include/mapnik/warning_ignore_agg.hpp index 2f44c5c78..f741e7a07 100644 --- a/include/mapnik/warning_ignore_agg.hpp +++ b/include/mapnik/warning_ignore_agg.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 diff --git a/include/mapnik/warp.hpp b/include/mapnik/warp.hpp index abf010851..46c11e8b3 100644 --- a/include/mapnik/warp.hpp +++ b/include/mapnik/warp.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 @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include namespace mapnik { diff --git a/include/mapnik/webp_io.hpp b/include/mapnik/webp_io.hpp index 225ff2f50..81862e08a 100644 --- a/include/mapnik/webp_io.hpp +++ b/include/mapnik/webp_io.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 diff --git a/include/mapnik/well_known_srs.hpp b/include/mapnik/well_known_srs.hpp index d175ef528..09ed22275 100644 --- a/include/mapnik/well_known_srs.hpp +++ b/include/mapnik/well_known_srs.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 @@ -52,11 +52,11 @@ static const double EARTH_DIAMETER = EARTH_RADIUS * 2.0; static const double EARTH_CIRCUMFERENCE = EARTH_DIAMETER * M_PI; static const double MAXEXTENT = EARTH_CIRCUMFERENCE / 2.0; static const double M_PI_by2 = M_PI / 2; -static const double D2R = M_PI / 180; -static const double R2D = 180 / M_PI; -static const double M_PIby360 = M_PI / 360; -static const double MAXEXTENTby180 = MAXEXTENT / 180; -static const double MAX_LATITUDE = R2D * (2 * std::atan(std::exp(180 * D2R)) - M_PI_by2); +static const double D2R = M_PI / 180.0; +static const double R2D = 180.0 / M_PI; +static const double M_PIby360 = M_PI / 360.0; +static const double MAXEXTENTby180 = MAXEXTENT / 180.0; +static const double MAX_LATITUDE = R2D * (2 * std::atan(std::exp(180.0 * D2R)) - M_PI_by2); static const std::string MAPNIK_LONGLAT_PROJ = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"; static const std::string MAPNIK_GMERC_PROJ = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"; @@ -64,24 +64,23 @@ boost::optional is_well_known_srs(std::string const& srs); boost::optional is_known_geographic(std::string const& srs); -static inline bool lonlat2merc(double * x, double * y , int point_count) +static inline bool lonlat2merc(double * x, double * y, std::size_t point_count) { - for(int i=0; i 180) x[i] = 180; else if (x[i] < -180) x[i] = -180; if (y[i] > MAX_LATITUDE) y[i] = MAX_LATITUDE; else if (y[i] < -MAX_LATITUDE) y[i] = -MAX_LATITUDE; x[i] = x[i] * MAXEXTENTby180; - y[i] = std::log(std::tan((90 + y[i]) * M_PIby360)) * R2D; - y[i] = y[i] * MAXEXTENTby180; + y[i] = std::log(std::tan((90.0 + y[i]) * M_PIby360)) * R2D * MAXEXTENTby180; } return true; } -static inline bool merc2lonlat(double * x, double * y , int point_count) +static inline bool merc2lonlat(double * x, double * y, std::size_t point_count) { - for(int i=0; i MAXEXTENT) x[i] = MAXEXTENT; else if (x[i] < -MAXEXTENT) x[i] = -MAXEXTENT; diff --git a/include/mapnik/wkb.hpp b/include/mapnik/wkb.hpp index 98b3d30c9..dcbe45d8b 100644 --- a/include/mapnik/wkb.hpp +++ b/include/mapnik/wkb.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 diff --git a/include/mapnik/wkt/wkt_factory.hpp b/include/mapnik/wkt/wkt_factory.hpp index 14f509dda..722fc18d6 100644 --- a/include/mapnik/wkt/wkt_factory.hpp +++ b/include/mapnik/wkt/wkt_factory.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 @@ -25,24 +25,12 @@ // mapnik #include - -#include -#include - // stl #include namespace mapnik { -inline bool from_wkt(std::string const& wkt, mapnik::geometry::geometry & geom) -{ - using namespace boost::spirit; - static const mapnik::wkt::wkt_grammar g; - ascii::space_type space; - std::string::const_iterator first = wkt.begin(); - std::string::const_iterator last = wkt.end(); - return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(geom)), space); -} +bool from_wkt(std::string const& wkt, mapnik::geometry::geometry & geom); } diff --git a/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp index 2df1bd7cc..c8ea23da6 100644 --- a/include/mapnik/wkt/wkt_generator_grammar.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar.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 @@ -26,12 +26,10 @@ // mapnik #include #include -#include #pragma GCC diagnostic push #include #include -#include #include // for vc++ and android whose c++11 libs lack std::trunc #include #pragma GCC diagnostic pop @@ -39,22 +37,9 @@ namespace mapnik { namespace wkt { namespace karma = boost::spirit::karma; -namespace phoenix = boost::phoenix; namespace detail { -template -struct get_type -{ - using result_type = mapnik::geometry::geometry_types; - template - result_type operator() (T const& geom) const - { - auto type = mapnik::geometry::geometry_type(geom); - return type; - } -}; - template struct wkt_coordinate_policy : karma::real_policies { @@ -102,31 +87,27 @@ struct coordinate_generator template struct wkt_generator_grammar : - karma::grammar + karma::grammar { using coordinate_type = typename Geometry::coordinate_type; wkt_generator_grammar(); // rules - karma::rule geometry; - karma::rule, Geometry const&() > geometry_dispatch; - karma::rule const&()> point; - karma::rule const&()> point_coord; - karma::rule const&()> linestring; - karma::rule const&()> linestring_coord; - karma::rule const&()> polygon; - karma::rule const&()> polygon_coord; - karma::rule const&()> ring; - //karma::rule > const&()> interior_ring_coord; - karma::rule const& ()> multi_point; - karma::rule const& ()> multi_point_coord; - karma::rule const& ()> multi_linestring; - karma::rule const& ()> multi_linestring_coord; - karma::rule const& ()> multi_polygon; - karma::rule const& ()> multi_polygon_coord; - karma::rule const& ()> geometry_collection; - karma::rule const& ()> geometries; - boost::phoenix::function > geometry_type; - karma::symbols empty; + karma::rule geometry; + karma::rule()> point; + karma::rule()> point_coord; + karma::rule()> linestring; + karma::rule()> linestring_coord; + karma::rule()> polygon; + karma::rule()> polygon_coord; + karma::rule()> linear_ring_coord; + karma::rule()> multi_point; + karma::rule()> multi_point_coord; + karma::rule()> multi_linestring; + karma::rule()> multi_linestring_coord; + karma::rule()> multi_polygon; + karma::rule()> multi_polygon_coord; + karma::rule()> geometry_collection; + karma::rule()> geometries; // typename detail::coordinate_generator::generator coordinate; }; diff --git a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp index ea000ca92..cdbb4546b 100644 --- a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar_impl.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 @@ -22,13 +22,7 @@ // mapnik #include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop +#include namespace mapnik { namespace wkt { @@ -36,81 +30,68 @@ template wkt_generator_grammar::wkt_generator_grammar() : wkt_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; - - empty.add - (geometry::geometry_types::Point, "POINT EMPTY") - (geometry::geometry_types::LineString, "LINESTRING EMPTY") - (geometry::geometry_types::Polygon, "POLYGON EMPTY") - (geometry::geometry_types::MultiPoint, "MULTIPOINT EMPTY") - (geometry::geometry_types::MultiLineString, "MULTILINESTRING EMPTY") - (geometry::geometry_types::MultiPolygon, "MULTIPOLYGON EMPTY") - (geometry::geometry_types::GeometryCollection, "GEOMETRYCOLLECTION EMPTY") - ; - - geometry = geometry_dispatch.alias() - ; - - geometry_dispatch = eps[_a = geometry_type(_val)] << - (&uint_(geometry::geometry_types::Point)[_1 = _a] - << point) + geometry = + point | - (&uint_(geometry::geometry_types::LineString)[_1 = _a] - << (linestring | empty[_1 = _a])) + linestring | - (&uint_(geometry::geometry_types::Polygon)[_1 = _a] - << (polygon | empty[_1 = _a])) + polygon | - (&uint_(geometry::geometry_types::MultiPoint)[_1 = _a] - << ( multi_point | empty[_1 = _a])) + multi_point | - (&uint_(geometry::geometry_types::MultiLineString)[_1 = _a] - << (multi_linestring | empty[_1 = _a])) + multi_linestring | - (&uint_(geometry::geometry_types::MultiPolygon)[_1 = _a] - << (multi_polygon | empty[_1 = _a])) + multi_polygon | - (&uint_(geometry::geometry_types::GeometryCollection)[_1 = _a] - << (geometry_collection | empty[_1 = _a])) + geometry_collection | - (&uint_(geometry::geometry_types::Unknown)[_1 = _a] - << lit("POINT EMPTY")) // special case for geometry_empty as mapnik::geometry::point can't be empty + lit("POINT EMPTY") // special case for geometry_empty ; point = lit("POINT(") << point_coord << lit(")") ; - linestring = lit("LINESTRING(") << linestring_coord << lit(")") + + linestring = lit("LINESTRING") << (linestring_coord | lit(" EMPTY")) ; - polygon = lit("POLYGON(") << polygon_coord << lit(")") + + polygon = lit("POLYGON") << (polygon_coord | lit(" EMPTY")) ; - multi_point = lit("MULTIPOINT(") << multi_point_coord << lit(")") + + multi_point = lit("MULTIPOINT") << (multi_point_coord | lit(" EMPTY")) ; - multi_linestring = lit("MULTILINESTRING(") << multi_linestring_coord << lit(")") + + multi_linestring = lit("MULTILINESTRING") << (multi_linestring_coord | lit(" EMPTY")) ; - multi_polygon = lit("MULTIPOLYGON(") << multi_polygon_coord << lit(")") + + multi_polygon = lit("MULTIPOLYGON") << (multi_polygon_coord | lit(" EMPTY")) ; - geometry_collection = lit("GEOMETRYCOLLECTION(") << geometries << lit(")") + + geometry_collection = lit("GEOMETRYCOLLECTION") << (lit("(") << geometries << lit(")") | lit(" EMPTY")) ; + point_coord = coordinate << lit(' ') << coordinate ; - linestring_coord = point_coord % lit(',') + + linestring_coord = lit('(') << point_coord % lit(',') << lit(')') ; - polygon_coord = ring % lit(',')//<< interior_ring_coord + + linear_ring_coord = lit('(') << point_coord % lit(',') << lit(')');//linestring_coord.alias() ; - ring = lit('(') << linestring_coord << lit(')') + + polygon_coord = linear_ring_coord % lit(',') ; - multi_point_coord = linestring_coord.alias() + + multi_point_coord = lit('(') << point_coord % lit(',') << lit(')');//linestring_coord.alias() ; - multi_linestring_coord = (lit('(') << linestring_coord << lit(')')) % lit(',') + + multi_linestring_coord = lit("(") << linestring_coord % lit(',') << lit(")") ; - multi_polygon_coord = (lit('(') << polygon_coord << lit(')')) % lit(',') + + multi_polygon_coord = lit("(") << polygon_coord % lit(',') << lit(")") ; - geometries = geometry % lit(',') + + geometries = geometry % lit(',') ; } diff --git a/include/mapnik/wkt/wkt_grammar.hpp b/include/mapnik/wkt/wkt_grammar.hpp deleted file mode 100644 index 55750b838..000000000 --- a/include/mapnik/wkt/wkt_grammar.hpp +++ /dev/null @@ -1,108 +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_WKT_GRAMMAR_HPP -#define MAPNIK_WKT_GRAMMAR_HPP - -// mapnik -#include -#include -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - - -namespace mapnik { namespace wkt { - -using namespace boost::spirit; - -namespace detail { - -struct assign -{ - using result_type = void; - template - void operator() (T0 & geom, T1 && obj) const - { - geom = std::move(obj); - } -}; - -struct move_part -{ - using result_type = void; - template - void operator() (Geometry & geom, Part && part) const - { - geom.push_back(std::move(part)); - } -}; - - -struct set_ring -{ - using result_type = void; - template - void operator() (Polygon & poly, Ring && ring) const - { - poly.push_back(std::move(ring)); - } -}; - -} - -template -struct wkt_grammar : qi::grammar &) , ascii::space_type> -{ - wkt_grammar(); - qi::rule &), ascii::space_type> geometry_tagged_text; - qi::rule &), ascii::space_type> point_tagged_text; - qi::rule &), ascii::space_type> linestring_tagged_text; - qi::rule &), ascii::space_type> polygon_tagged_text; - qi::rule &), ascii::space_type> multipoint_tagged_text; - qi::rule &), ascii::space_type> multilinestring_tagged_text; - qi::rule &), ascii::space_type> multipolygon_tagged_text; - qi::rule &), ascii::space_type> geometrycollection_tagged_text; - qi::rule(), ascii::space_type> point_text; - qi::rule(), ascii::space_type> linestring_text; - qi::rule(), ascii::space_type> linearring_text; - qi::rule(), ascii::space_type> polygon_text; - qi::rule(), ascii::space_type> multipoint_text; - qi::rule(), ascii::space_type> multilinestring_text; - qi::rule(), ascii::space_type> multipolygon_text; - qi::rule >, - mapnik::geometry::geometry_collection(), ascii::space_type> geometrycollection_text; - qi::rule(), ascii::space_type> point; - qi::rule(), ascii::space_type> points; - qi::rule(), ascii::space_type> ring_points; - qi::rule empty_set; - boost::phoenix::function assign; - boost::phoenix::function move_part; - boost::phoenix::function set_ring; -}; - -}} - -#endif // MAPNIK_WKT_GRAMMAR_HPP diff --git a/include/mapnik/wkt/wkt_grammar_impl.hpp b/include/mapnik/wkt/wkt_grammar_impl.hpp deleted file mode 100644 index 33caab6bc..000000000 --- a/include/mapnik/wkt/wkt_grammar_impl.hpp +++ /dev/null @@ -1,161 +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 - * - *****************************************************************************/ - -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik { namespace wkt { - -using namespace boost::spirit; - -template -wkt_grammar::wkt_grammar() - : wkt_grammar::base_type(geometry_tagged_text) -{ - qi::eps_type eps; - qi::_r1_type _r1; - qi::_val_type _val; - qi::lit_type lit; - qi::no_case_type no_case; - qi::double_type double_; - qi::_1_type _1; - qi::_a_type _a; - using boost::phoenix::construct; - using boost::phoenix::at_c; - geometry_tagged_text = point_tagged_text(_r1) - | linestring_tagged_text(_r1) - | polygon_tagged_text(_r1) - | multipoint_tagged_text(_r1) - | multilinestring_tagged_text(_r1) - | multipolygon_tagged_text(_r1) - | geometrycollection_tagged_text(_r1) - ; - - // ::= point - point_tagged_text = no_case[lit("POINT")] - >> (point_text[assign(_r1,_1)] | empty_set[assign(_r1,construct>())]) - ; - // ::= | - point_text = (lit("(") >> point >> lit(')')) - //| empty_set - we're catching 'POINT EMPTY' case in point_tagged_text rule ^^ by creating geometry_empty - // because our geometry::point can't be empty - ; - - // ::= linestring - linestring_tagged_text = no_case[lit("LINESTRING")] - >> linestring_text[assign(_r1,_1)] - ; - - // ::= | { }* - linestring_text = points | empty_set - ; - - // ::= polygon - polygon_tagged_text = no_case[lit("POLYGON")] - >> polygon_text[assign(_r1,_1)] - ; - - // ::= | { }* - polygon_text = - lit('(') >> linearring_text[set_ring(_val,_1)] % lit(',') >> lit(')') - | - empty_set - ; - - linearring_text = ring_points - | - empty_set - ; - // ::= multipoint - multipoint_tagged_text = no_case[lit("MULTIPOINT")] - >> multipoint_text[assign(_r1,_1)] - ; - - // ::= | { }* - multipoint_text = (lit('(') - >> point_text % lit(',') - >> lit(')')) - | - (lit('(') - >> point % lit(',') - >> lit(')')) - | - empty_set - ; - - // ::= multilinestring - multilinestring_tagged_text = no_case[lit("MULTILINESTRING")] - >> multilinestring_text[assign(_r1,_1)] ; - - // ::= | { }* - multilinestring_text = (lit('(') - >> points[move_part(_val,_1)] % lit(',') - >> lit(')')) | empty_set; - - // ::= multipolygon - multipolygon_tagged_text = no_case[lit("MULTIPOLYGON")] - >> multipolygon_text[assign(_r1,_1)] ; - - // ::= | { }* - multipolygon_text = (lit('(') - >> polygon_text[move_part(_val,_1)] % lit(',') - >> lit(')')) - | - empty_set; - - // geometry collection tagged text - geometrycollection_tagged_text = no_case[lit("GEOMETRYCOLLECTION")] - >> geometrycollection_text[assign(_r1,_1)] - ; - - // geometry collection text - geometrycollection_text = (lit('(') - >> ( eps[_a = construct >()] - >> geometry_tagged_text(_a)[move_part(_val,_a)] % lit(',')) - >> lit(')')) - | - empty_set; - // points - points = lit('(') >> point % lit(',') >> lit(')') - ; - // ring points - ring_points = lit('(') >> point % lit(',') >> lit(')') - ; - // point - point = double_ >> double_ - ; - - // - empty_set = no_case[lit("EMPTY")]; -} - -}} diff --git a/include/mapnik/wkt/wkt_grammar_x3.hpp b/include/mapnik/wkt/wkt_grammar_x3.hpp new file mode 100644 index 000000000..a0b6be0f0 --- /dev/null +++ b/include/mapnik/wkt/wkt_grammar_x3.hpp @@ -0,0 +1,49 @@ +/***************************************************************************** + * + * 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_WKT_GRAMMAR_X3_HPP +#define MAPNIK_WKT_GRAMMAR_X3_HPP + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +struct wkt_class; // top-most ID +using wkt_grammar_type = x3::rule>; + +BOOST_SPIRIT_DECLARE(wkt_grammar_type); + +}} + +namespace mapnik +{ +grammar::wkt_grammar_type const& wkt_grammar(); +} + + +#endif // MAPNIK_WKT_GRAMMAR_X3_HPP diff --git a/include/mapnik/wkt/wkt_grammar_x3_def.hpp b/include/mapnik/wkt/wkt_grammar_x3_def.hpp new file mode 100644 index 000000000..b8d5065d1 --- /dev/null +++ b/include/mapnik/wkt/wkt_grammar_x3_def.hpp @@ -0,0 +1,138 @@ +/***************************************************************************** + * + * 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_WKT_GRAMMAR_X3_DEF_HPP +#define MAPNIK_WKT_GRAMMAR_X3_DEF_HPP + +#include +#include + +#if defined(__GNUC__) +// instantiate `is_substitute` for reference T and reference Attribute +// fixes gcc6 compilation issue +namespace boost { namespace spirit { namespace x3 { namespace traits { + +template +struct is_substitute + : is_substitute {}; +}}}} +#endif + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +namespace ascii = boost::spirit::x3::ascii; +using x3::lit; +using x3::double_; +using x3::no_case; + +// functors +auto make_empty = [](auto const& ctx) +{ + _val(ctx) = geometry::geometry_empty(); +}; + +auto add_ring = [](auto const& ctx) +{ + auto & ring = reinterpret_cast &>(_attr(ctx)); + _val(ctx).push_back(std::move(ring)); +}; + +// start rule +wkt_grammar_type const wkt("wkt"); +// rules +x3::rule const empty("EMPTY"); +x3::rule > const point("POINT"); +x3::rule > const line_string("LINESTRING"); +x3::rule > const polygon("POLYGON"); +x3::rule > const multi_point("MULTIPOINT"); +x3::rule > const multi_line_string("MULTILINESTRING"); +x3::rule > const multi_polygon("MULTIPOLYGON"); +x3::rule > const geometry_collection("GEOMETRYCOLLECTION"); + +x3::rule > const point_text("point-text"); +x3::rule > const positions("positions"); +x3::rule > const polygon_rings("polygon-rings"); +x3::rule > const points("points"); +x3::rule > const lines("lines"); +x3::rule > const polygons("polygons"); +x3::rule > const geometries("geometries"); + + +auto const point_text_def = '(' > double_ > double_ > ')'; +auto const positions_def = lit('(') > (double_ > double_) % lit(',') > lit(')'); +//auto const polygon_rings_def = '(' > positions[set_exterior] > *(lit(',') > positions[add_hole]) > ')'; +auto const polygon_rings_def = '(' > positions[add_ring] % lit(',') > ')'; +auto const points_def = (lit('(') >> ((point_text_def % ',') > lit(')'))) | positions_def ; +auto const lines_def = lit('(') > (positions_def % lit(',')) > lit(')'); +auto const polygons_def = lit('(') > (polygon_rings % lit(',')) > lit(')'); +auto const geometries_def = lit('(') > -(wkt % ',') > lit(')'); + +// +auto const wkt_def = point | line_string | polygon | multi_point | multi_line_string | multi_polygon | geometry_collection; + +// EMPTY +auto const empty_def = no_case["EMPTY"][make_empty]; +// POINT +auto const point_def = no_case["POINT"] > (point_text | empty); +// LINESTRING +auto const line_string_def = no_case["LINESTRING"] > (positions | no_case["EMPTY"]); +// POLYGON +auto const polygon_def = no_case["POLYGON"] > (polygon_rings | no_case["EMPTY"]); +// MULTIPOINT +auto const multi_point_def = no_case["MULTIPOINT"] > (points | no_case["EMPTY"]); +// MULTILINESTRING +auto const multi_line_string_def = no_case["MULTILINESTRING"] > (lines | no_case["EMPTY"]); +// MULTIPOLYGON +auto const multi_polygon_def = no_case["MULTIPOLYGON"] > (polygons | no_case["EMPTY"]); +// GEOMETRYCOLLECTION +auto const geometry_collection_def = no_case["GEOMETRYCOLLECTION"] > (geometries | no_case["EMPTY"]); + +BOOST_SPIRIT_DEFINE( + wkt, + point_text, + positions, + points, + lines, + polygons, + geometries, + empty, + point, + line_string, + polygon_rings, + polygon, + multi_point, + multi_line_string, + multi_polygon, + geometry_collection + ); +}} + +namespace mapnik +{ +grammar::wkt_grammar_type const& wkt_grammar() +{ + return grammar::wkt; +} +} + +#endif // MAPNIK_WKT_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/xml_attribute_cast.hpp b/include/mapnik/xml_attribute_cast.hpp index cafa7e79a..1beafe5be 100644 --- a/include/mapnik/xml_attribute_cast.hpp +++ b/include/mapnik/xml_attribute_cast.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 @@ -25,7 +25,7 @@ //mapnik #include -#include +#include #include #include #include diff --git a/include/mapnik/xml_loader.hpp b/include/mapnik/xml_loader.hpp index 5fe98af0c..2cb73a3c4 100644 --- a/include/mapnik/xml_loader.hpp +++ b/include/mapnik/xml_loader.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 diff --git a/include/mapnik/xml_node.hpp b/include/mapnik/xml_node.hpp index bf7130c20..8aa2048b6 100644 --- a/include/mapnik/xml_node.hpp +++ b/include/mapnik/xml_node.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,8 +20,8 @@ * *****************************************************************************/ -#ifndef MAPNIK_XML_NODE_H -#define MAPNIK_XML_NODE_H +#ifndef MAPNIK_XML_NODE_HPP +#define MAPNIK_XML_NODE_HPP //mapnik #include // for MAPNIK_DECL @@ -53,8 +53,8 @@ class MAPNIK_DECL node_not_found: public std::exception { public: node_not_found(std::string const& node_name); - virtual const char* what() const throw(); - ~node_not_found() throw (); + virtual const char* what() const noexcept; + ~node_not_found(); private: std::string node_name_; protected: @@ -65,8 +65,8 @@ class MAPNIK_DECL attribute_not_found: public std::exception { public: attribute_not_found(std::string const& node_name, std::string const& attribute_name); - virtual const char* what() const throw(); - ~attribute_not_found() throw (); + virtual const char* what() const noexcept; + ~attribute_not_found(); private: std::string node_name_; std::string attribute_name_; @@ -78,8 +78,8 @@ class MAPNIK_DECL more_than_one_child: public std::exception { public: more_than_one_child(std::string const& node_name); - virtual const char* what() const throw(); - ~more_than_one_child() throw (); + virtual const char* what() const noexcept; + ~more_than_one_child(); private: std::string node_name_; protected: @@ -150,4 +150,4 @@ private: } //ns mapnik -#endif // MAPNIK_XML_NODE_H +#endif // MAPNIK_XML_NODE_HPP diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index 535d96763..e0e00a914 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.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,8 +20,8 @@ * *****************************************************************************/ -#ifndef MAPNIK_XML_TREE_H -#define MAPNIK_XML_TREE_H +#ifndef MAPNIK_XML_TREE_HPP +#define MAPNIK_XML_TREE_HPP // mapnik #include @@ -50,4 +50,4 @@ public: } //ns mapnik -#endif // MAPNIK_XML_TREE_H +#endif // MAPNIK_XML_TREE_HPP diff --git a/mason_latest.sh b/mason_latest.sh deleted file mode 100755 index cf064953b..000000000 --- a/mason_latest.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash - -MASON_NAME=mapnik -MASON_VERSION=latest -MASON_LIB_FILE=lib/libmapnik-wkt.a - -# warning: may break when https://github.com/mapbox/mason/issues/141 lands -# hence we are pinned for now to older mason in bootstrap.sh -. ./.mason/mason.sh - -set -eu - -function mason_load_source { - export MASON_BUILD_PATH=$(pwd) -} - -function mason_compile { - HERE=$(pwd) - make install - # this is to adapt to when mapnik is not installed in MASON_PREFIX - # originally (to make it easier to publish locally as a stopgap) - MAPNIK_PREFIX=$(mapnik-config --prefix) - if [[ ${MAPNIK_PREFIX} != ${MASON_PREFIX} ]]; then - mkdir -p ${MASON_PREFIX}/lib - mkdir -p ${MASON_PREFIX}/include - mkdir -p ${MASON_PREFIX}/bin - cp -r ${MAPNIK_PREFIX}/lib/*mapnik* ${MASON_PREFIX}/lib/ - cp -r ${MAPNIK_PREFIX}/include/mapnik ${MASON_PREFIX}/include/ - cp -r ${MAPNIK_PREFIX}/bin/mapnik* ${MASON_PREFIX}/bin/ - cp -r ${MAPNIK_PREFIX}/bin/shapeindex ${MASON_PREFIX}/bin/ - fi - if [[ $(uname -s) == 'Darwin' ]]; then - install_name_tool -id @loader_path/lib/libmapnik.dylib ${MASON_PREFIX}"/lib/libmapnik.dylib"; - PLUGINDIR=${MASON_PREFIX}"/lib/mapnik/input/*.input"; - for f in $PLUGINDIR; do - echo $f; - echo $(basename $f); - install_name_tool -id plugins/input/$(basename $f) $f; - install_name_tool -change "${MAPNIK_PREFIX}/lib/libmapnik.dylib" @loader_path/../../lib/libmapnik.dylib $f; - done; - BINDIR=${MASON_PREFIX}"/bin/*"; - for f in $BINDIR; do - echo $f; - echo $(basename $f); - if [[ $(file $f) =~ 'Mach-O' ]]; then - install_name_tool -id bin/$(basename $f) $f; - install_name_tool -change "${MAPNIK_PREFIX}/lib/libmapnik.dylib" @loader_path/../lib/libmapnik.dylib $f; - fi - done; - fi; - python -c "data=open('$MASON_PREFIX/bin/mapnik-config','r').read();open('$MASON_PREFIX/bin/mapnik-config','w').write(data.replace('$HERE','.'))" - find ${MASON_PREFIX} -name "*.pyc" -exec rm {} \; -} - -function mason_cflags { - : -} - -function mason_ldflags { - : -} - -function mason_clean { - echo "Done" -} - -mason_run "$@" diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 322940528..49c6c660d 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -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 @@ -38,9 +38,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/plugins/input/csv/csv_datasource.hpp b/plugins/input/csv/csv_datasource.hpp index 71cf2ea71..b21570d05 100644 --- a/plugins/input/csv/csv_datasource.hpp +++ b/plugins/input/csv/csv_datasource.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 @@ -28,10 +28,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include "csv_utils.hpp" #pragma GCC diagnostic push diff --git a/plugins/input/csv/csv_featureset.cpp b/plugins/input/csv/csv_featureset.cpp index f73b52a54..b73f2e4b3 100644 --- a/plugins/input/csv/csv_featureset.cpp +++ b/plugins/input/csv/csv_featureset.cpp @@ -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 @@ -73,7 +73,7 @@ mapnik::feature_ptr csv_featureset::parse_feature(char const* beg, char const* e { auto values = csv_utils::parse_line(beg, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is>()) + if (!geom.is()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); @@ -97,7 +97,10 @@ mapnik::feature_ptr csv_featureset::next() std::fseek(file_.get(), file_offset, SEEK_SET); std::vector record; record.resize(size); - std::fread(record.data(), size, 1, file_.get()); + if (std::fread(record.data(), size, 1, file_.get()) != 1) + { + return mapnik::feature_ptr(); + } auto const* start = record.data(); auto const* end = start + record.size(); #endif diff --git a/plugins/input/csv/csv_featureset.hpp b/plugins/input/csv/csv_featureset.hpp index 8828fa4a5..f9850a2bc 100644 --- a/plugins/input/csv/csv_featureset.hpp +++ b/plugins/input/csv/csv_featureset.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 diff --git a/plugins/input/csv/csv_getline.hpp b/plugins/input/csv/csv_getline.hpp index 9dfe5de49..8259cb305 100644 --- a/plugins/input/csv/csv_getline.hpp +++ b/plugins/input/csv/csv_getline.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 diff --git a/plugins/input/csv/csv_index_featureset.cpp b/plugins/input/csv/csv_index_featureset.cpp index 493d65daf..3498dc37f 100644 --- a/plugins/input/csv/csv_index_featureset.cpp +++ b/plugins/input/csv/csv_index_featureset.cpp @@ -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 @@ -90,7 +90,7 @@ mapnik::feature_ptr csv_index_featureset::parse_feature(char const* beg, char co { auto values = csv_utils::parse_line(beg, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is>()) + if (!geom.is()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); @@ -119,7 +119,10 @@ mapnik::feature_ptr csv_index_featureset::next() std::fseek(file_.get(), pos.first, SEEK_SET); std::vector record; record.resize(pos.second); - std::fread(record.data(), pos.second, 1, file_.get()); + if (std::fread(record.data(), pos.second, 1, file_.get()) != 1) + { + return mapnik::feature_ptr(); + } auto const* start = record.data(); auto const* end = start + record.size(); #endif diff --git a/plugins/input/csv/csv_index_featureset.hpp b/plugins/input/csv/csv_index_featureset.hpp index e57a356c9..ac1a1ed91 100644 --- a/plugins/input/csv/csv_index_featureset.hpp +++ b/plugins/input/csv/csv_index_featureset.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 diff --git a/plugins/input/csv/csv_inline_featureset.cpp b/plugins/input/csv/csv_inline_featureset.cpp index 54c8f14f9..893410fb9 100644 --- a/plugins/input/csv/csv_inline_featureset.cpp +++ b/plugins/input/csv/csv_inline_featureset.cpp @@ -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 @@ -58,7 +58,7 @@ mapnik::feature_ptr csv_inline_featureset::parse_feature(std::string const& str) auto const* end = start + str.size(); auto values = csv_utils::parse_line(start, end, separator_, quote_, headers_.size()); auto geom = csv_utils::extract_geometry(values, locator_); - if (!geom.is>()) + if (!geom.is()) { mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, ++feature_id_)); feature->set_geometry(std::move(geom)); diff --git a/plugins/input/csv/csv_inline_featureset.hpp b/plugins/input/csv/csv_inline_featureset.hpp index 4873cecaa..342a5b2bb 100644 --- a/plugins/input/csv/csv_inline_featureset.hpp +++ b/plugins/input/csv/csv_inline_featureset.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 diff --git a/plugins/input/csv/csv_utils.cpp b/plugins/input/csv/csv_utils.cpp index b35942d4c..f85cee4ec 100644 --- a/plugins/input/csv/csv_utils.cpp +++ b/plugins/input/csv/csv_utils.cpp @@ -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 @@ -23,14 +23,14 @@ // mapnik #include #include -#include +#include #include #include #include #include #include // csv grammar -#include +#include // #include "csv_getline.hpp" #include "csv_utils.hpp" @@ -192,14 +192,17 @@ bool valid(geometry_column_locator const& locator, std::size_t max_size) } // namespace detail -static const mapnik::csv_line_grammar line_g; -static const mapnik::csv_white_space_skipper skipper{}; - mapnik::csv_line parse_line(char const* start, char const* end, char separator, char quote, std::size_t num_columns) { + namespace x3 = boost::spirit::x3; + auto parser = x3::with(quote) + [ x3::with(separator) + [ mapnik::csv_line_grammar()] + ]; + mapnik::csv_line values; if (num_columns > 0) values.reserve(num_columns); - if (!boost::spirit::qi::phrase_parse(start, end, (line_g)(separator, quote), skipper, values)) + if (!x3::phrase_parse(start, end, parser, mapnik::csv_white_space, values)) { throw mapnik::datasource_exception("Failed to parse CSV line:\n" + std::string(start, end)); } @@ -285,7 +288,10 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) { auto headers = csv_utils::parse_line(csv_line, separator_, quote_); // skip blank lines - if (headers.size() > 0 && headers[0].empty()) ++line_number; + if (headers.size() == 1 && headers[0].empty()) + { + ++line_number; + } else { std::size_t index = 0; @@ -300,7 +306,7 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) std::ostringstream s; s << "CSV Plugin: expected a column header at line "; s << line_number << ", column " << index; - s << " - ensure this row contains valid header fields: '"; + s << " - expected fields: '"; s << csv_line; throw mapnik::datasource_exception(s.str()); } @@ -338,7 +344,6 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) std::string str("CSV Plugin: could not detect column(s) with the name(s) of wkt, geojson, x/y, or "); str += "latitude/longitude in:\n"; str += csv_line; - str += "\n - this is required for reading geometry data"; throw mapnik::datasource_exception(str); } @@ -406,7 +411,7 @@ void csv_file_parser::parse_csv_and_boxes(std::istream & csv_file, T & boxes) } auto geom = extract_geometry(values, locator_); - if (!geom.is>()) + if (!geom.is()) { auto box = mapnik::geometry::envelope(geom); if (!extent_initialized_) diff --git a/plugins/input/csv/csv_utils.hpp b/plugins/input/csv/csv_utils.hpp index df976e3a7..0200cca1e 100644 --- a/plugins/input/csv/csv_utils.hpp +++ b/plugins/input/csv/csv_utils.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 @@ -24,9 +24,9 @@ #define MAPNIK_CSV_UTILS_DATASOURCE_HPP // mapnik -#include +#include #include -#include +#include #include #include #include diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp index 2454ed65b..b98ed1e93 100644 --- a/plugins/input/gdal/gdal_datasource.cpp +++ b/plugins/input/gdal/gdal_datasource.cpp @@ -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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include diff --git a/plugins/input/gdal/gdal_datasource.hpp b/plugins/input/gdal/gdal_datasource.hpp index 3fc3036c8..53cdece2c 100644 --- a/plugins/input/gdal/gdal_datasource.hpp +++ b/plugins/input/gdal/gdal_datasource.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp index 1377322e3..70d8ef73b 100644 --- a/plugins/input/gdal/gdal_featureset.cpp +++ b/plugins/input/gdal/gdal_featureset.cpp @@ -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 diff --git a/plugins/input/gdal/gdal_featureset.hpp b/plugins/input/gdal/gdal_featureset.hpp index f2f66f796..3d0ebeafc 100644 --- a/plugins/input/gdal/gdal_featureset.hpp +++ b/plugins/input/gdal/gdal_featureset.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 diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 60fd7b715..906b204b9 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -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,7 +30,6 @@ #pragma GCC diagnostic push #include #include -#include #pragma GCC diagnostic pop // mapnik @@ -40,8 +39,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -49,12 +48,12 @@ #include #include #include -#include -#include -#include +#include #include #include #include +#include +#include #if defined(MAPNIK_MEMORY_MAPPED_FILE) #pragma GCC diagnostic push @@ -156,9 +155,9 @@ geojson_datasource::geojson_datasource(parameters const& params) std::string file_buffer; file_buffer.resize(file.size()); - std::fread(&file_buffer[0], file.size(), 1, file.get()); + auto count = std::fread(&file_buffer[0], file.size(), 1, file.get()); char const* start = file_buffer.c_str(); - char const* end = start + file_buffer.length(); + char const* end = (count == 1) ? start + file_buffer.length() : start; #else boost::optional mapped_region = mapnik::mapped_memory_cache::instance().find(filename_, false); @@ -182,14 +181,12 @@ geojson_datasource::geojson_datasource(parameters const& params) } namespace { + using box_type = box2d; using boxes_type = std::vector>>; using base_iterator_type = char const*; const mapnik::transcoder geojson_datasource_static_tr("utf8"); -const mapnik::json::feature_collection_grammar geojson_datasource_static_fc_grammar(geojson_datasource_static_tr); -const mapnik::json::feature_grammar_callback geojson_datasource_static_feature_callback_grammar(geojson_datasource_static_tr); -const mapnik::json::feature_grammar geojson_datasource_static_feature_grammar(geojson_datasource_static_tr); -const mapnik::json::extract_bounding_box_grammar geojson_datasource_static_bbox_grammar; + } void geojson_datasource::initialise_descriptor(mapnik::feature_ptr const& feature) @@ -229,15 +226,15 @@ void geojson_datasource::initialise_disk_index(std::string const& filename) std::fseek(file.get(), pos.first, SEEK_SET); std::vector record; record.resize(pos.second); - std::fread(record.data(), pos.second, 1, file.get()); + auto count = std::fread(record.data(), pos.second, 1, file.get()); auto const* start = record.data(); - auto const* end = start + record.size(); + auto const* end = (count == 1) ? start + record.size() : start; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, -1)); - using namespace boost::spirit; - standard::space_type space; - if (!boost::spirit::qi::phrase_parse(start, end, - (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space) - || start != end) + try + { + mapnik::json::parse_feature(start, end, *feature, geojson_datasource_static_tr); + } + catch (...) { throw std::runtime_error("Failed to parse geojson feature"); } @@ -246,29 +243,84 @@ void geojson_datasource::initialise_disk_index(std::string const& filename) desc_.order_by_name(); } +namespace mapnik { namespace json { + +template +void parse_geometry_or_feature(Iterator& itr, Iterator const& end, feature_impl& feature, transcoder const& tr ) +{ + Iterator start = itr; + try + { + parse_feature(start, end, feature, tr); + } + catch (...) + { + start = itr; + parse_geometry(start, end, feature); + } +} + +}} + + template void geojson_datasource::initialise_index(Iterator start, Iterator end) { boxes_type boxes; - boost::spirit::standard::space_type space; + mapnik::context_ptr ctx = std::make_shared(); Iterator itr = start; - if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space)) + try { + mapnik::json::extract_bounding_boxes(itr, end, boxes); + // bulk insert initialise r-tree + tree_ = std::make_unique(boxes); + // calculate total extent + std::size_t feature_count = 0; + + for (auto const& item : boxes) + { + auto const& box = std::get<0>(item); + auto const& geometry_index = std::get<1>(item); + if (!extent_.valid()) extent_ = box; + else extent_.expand_to_include(box); + if (feature_count++ < num_features_to_query_) + { + // parse first N features to extract attributes schema. + // NOTE: this doesn't yield correct answer for geoJSON in general, just an indication + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,-1)); // temp feature + Iterator itr2 = start + geometry_index.first; + Iterator end2 = itr2 + geometry_index.second; + try + { + mapnik::json::parse_feature(itr2, end2, *feature, geojson_datasource_static_tr); + } + catch (...) + { + throw std::runtime_error("Failed to parse geojson feature"); + } + initialise_descriptor(feature); + } + } + } + catch (...) + { + cache_features_ = true; // force caching single feature itr = start; // reset iteraror - // try parsing as single Feature or single Geometry JSON - mapnik::context_ptr ctx = std::make_shared(); std::size_t start_id = 1; - mapnik::json::default_feature_callback callback(features_); - bool result = boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_feature_callback_grammar) - (boost::phoenix::ref(ctx), boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || itr != end) + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, start_id)); // single feature + try + { + mapnik::json::parse_geometry_or_feature(itr, end, *feature, geojson_datasource_static_tr); + } + catch (...) { if (from_inline_string_) throw mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file from in-memory string"); else throw mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file '" + filename_ + "'"); } + features_.push_back(std::move(feature)); + using values_container = std::vector< std::pair>>; values_container values; values.reserve(features_.size()); @@ -298,82 +350,48 @@ void geojson_datasource::initialise_index(Iterator start, Iterator end) // packing algorithm tree_ = std::make_unique(values); } - else - { - // bulk insert initialise r-tree - tree_ = std::make_unique(boxes); - // calculate total extent - std::size_t feature_count = 0; - mapnik::context_ptr ctx = std::make_shared(); - for (auto const& item : boxes) - { - auto const& box = std::get<0>(item); - auto const& geometry_index = std::get<1>(item); - if (!extent_.valid()) extent_ = box; - else extent_.expand_to_include(box); - if (feature_count++ < num_features_to_query_) - { - // parse first N features to extract attributes schema. - // NOTE: this doesn't yield correct answer for geoJSON in general, just an indication - Iterator itr2 = start + geometry_index.first; - Iterator end2 = itr2 + geometry_index.second; - mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,-1)); // temp feature - if (!boost::spirit::qi::phrase_parse(itr2, end2, - (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space) - || itr2 != end2) - { - throw std::runtime_error("Failed to parse geojson feature"); - } - - initialise_descriptor(feature); - } - } - } desc_.order_by_name(); } template void geojson_datasource::parse_geojson(Iterator start, Iterator end) { - using boost::spirit::qi::expectation_failure; - boost::spirit::standard::space_type space; mapnik::context_ptr ctx = std::make_shared(); std::size_t start_id = 1; - - mapnik::json::default_feature_callback callback(features_); Iterator itr = start; - try { - bool result = boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_fc_grammar) - (boost::phoenix::ref(ctx), boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || itr != end) + boxes_type boxes; + mapnik::json::extract_bounding_boxes(itr, end, boxes); + + if (itr != end) throw std::runtime_error("Malformed GeoJSON"); //ensure we've consumed all input + + for (auto const& item : boxes) { - itr = start; - // try parsing as single Feature or single Geometry JSON - result = boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_feature_callback_grammar) - (boost::phoenix::ref(ctx),boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || itr != end) - { - if (from_inline_string_) throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file from in-memory string"); - else throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + filename_ + "'"); - } + auto const& geometry_index = std::get<1>(item); + Iterator itr2 = start + geometry_index.first; + Iterator end2 = itr2 + geometry_index.second; + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, start_id++)); + mapnik::json::parse_feature(itr2, end2, *feature, geojson_datasource_static_tr); + features_.push_back(std::move(feature)); } } - catch (expectation_failure const& ex) + catch (...) { itr = start; // try parsing as single Feature or single Geometry JSON - bool result = boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_feature_callback_grammar) - (boost::phoenix::ref(ctx),boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || itr != end) + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, start_id)); // single feature + try { - if (from_inline_string_) throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file from in-memory string"); - else throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + filename_ + "'"); + mapnik::json::parse_geometry_or_feature(itr, end, *feature, geojson_datasource_static_tr); } + catch (...) + { + if (from_inline_string_) throw mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file from in-memory string"); + else throw mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file '" + filename_ + "'"); + } + + features_.push_back(std::move(feature)); } using values_container = std::vector< std::pair>>; @@ -389,7 +407,6 @@ void geojson_datasource::parse_geojson(Iterator start, Iterator end) if (geometry_index == 0) { extent_ = box; - } else { @@ -454,15 +471,15 @@ boost::optional geojson_datasource::get_geometry_ std::fseek(file.get(), pos.first, SEEK_SET); std::vector record; record.resize(pos.second); - std::fread(record.data(), pos.second, 1, file.get()); + auto count = std::fread(record.data(), pos.second, 1, file.get()); auto const* start = record.data(); - auto const* end = start + record.size(); + auto const* end = (count == 1) ? start + record.size() : start; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, -1)); // temp feature - using namespace boost::spirit; - standard::space_type space; - if (!boost::spirit::qi::phrase_parse(start, end, - (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space) - || start != end) + try + { + mapnik::json::parse_feature(start, end, *feature, geojson_datasource_static_tr); + } + catch (...) { throw std::runtime_error("Failed to parse geojson feature"); } @@ -516,19 +533,21 @@ boost::optional geojson_datasource::get_geometry_ std::fseek(file.get(), file_offset, SEEK_SET); std::vector json; json.resize(size); - std::fread(json.data(), size, 1, file.get()); - + auto count_objects = std::fread(json.data(), size, 1, file.get()); using chr_iterator_type = char const*; chr_iterator_type start2 = json.data(); - chr_iterator_type end2 = start2 + json.size(); + chr_iterator_type end2 = (count_objects == 1) ? start2 + json.size() : start2; - using namespace boost::spirit; - standard::space_type space; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, -1)); // temp feature - if (!qi::phrase_parse(start2, end2, (geojson_datasource_static_feature_grammar)(boost::phoenix::ref(*feature)), space)) + try + { + mapnik::json::parse_feature(start2, end2, *feature, geojson_datasource_static_tr); + } + catch (...) { throw std::runtime_error("Failed to parse geojson feature"); } + result = mapnik::util::to_ds_type(feature->get_geometry()); if (result) { diff --git a/plugins/input/geojson/geojson_datasource.hpp b/plugins/input/geojson/geojson_datasource.hpp index e295cb1d6..cbe7b9b12 100644 --- a/plugins/input/geojson/geojson_datasource.hpp +++ b/plugins/input/geojson/geojson_datasource.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/geojson/geojson_featureset.cpp b/plugins/input/geojson/geojson_featureset.cpp index 1976f03ba..1d718527b 100644 --- a/plugins/input/geojson/geojson_featureset.cpp +++ b/plugins/input/geojson/geojson_featureset.cpp @@ -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 diff --git a/plugins/input/geojson/geojson_featureset.hpp b/plugins/input/geojson/geojson_featureset.hpp index e055b9777..995df35ce 100644 --- a/plugins/input/geojson/geojson_featureset.hpp +++ b/plugins/input/geojson/geojson_featureset.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 diff --git a/plugins/input/geojson/geojson_index_featureset.cpp b/plugins/input/geojson/geojson_index_featureset.cpp index 4cd139899..b5e0fc66a 100644 --- a/plugins/input/geojson/geojson_index_featureset.cpp +++ b/plugins/input/geojson/geojson_index_featureset.cpp @@ -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 @@ -24,10 +24,12 @@ #include "geojson_index_featureset.hpp" #include #include -#include #include #include -#include +#include +#include +#include +#include // stl #include #include @@ -85,19 +87,14 @@ mapnik::feature_ptr geojson_index_featureset::next() std::fseek(file_.get(), pos.first, SEEK_SET); std::vector record; record.resize(pos.second); - std::fread(record.data(), pos.second, 1, file_.get()); + auto count = std::fread(record.data(), pos.second, 1, file_.get()); auto const* start = record.data(); - auto const* end = start + record.size(); + auto const* end = (count == 1) ? start + record.size() : start; #endif static const mapnik::transcoder tr("utf8"); - static const mapnik::json::feature_grammar grammar(tr); - using namespace boost::spirit; - standard::space_type space; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, feature_id_++)); - if (!qi::phrase_parse(start, end, (grammar)(boost::phoenix::ref(*feature)), space) || start != end) - { - throw std::runtime_error("Failed to parse GeoJSON feature"); - } + using mapnik::json::grammar::iterator_type; + mapnik::json::parse_feature(start, end, *feature, tr); // throw on failure // skip empty geometries if (mapnik::geometry::is_empty(feature->get_geometry())) continue; diff --git a/plugins/input/geojson/geojson_index_featureset.hpp b/plugins/input/geojson/geojson_index_featureset.hpp index 41e8e84ba..9b9b03428 100644 --- a/plugins/input/geojson/geojson_index_featureset.hpp +++ b/plugins/input/geojson/geojson_index_featureset.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 diff --git a/plugins/input/geojson/geojson_memory_index_featureset.cpp b/plugins/input/geojson/geojson_memory_index_featureset.cpp index 32b851373..f26e098e2 100644 --- a/plugins/input/geojson/geojson_memory_index_featureset.cpp +++ b/plugins/input/geojson/geojson_memory_index_featureset.cpp @@ -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 @@ -21,17 +21,18 @@ *****************************************************************************/ // mapnik +#include "geojson_memory_index_featureset.hpp" + #include #include -#include #include -#include +#include +#include + // stl #include #include -#include "geojson_memory_index_featureset.hpp" - geojson_memory_index_featureset::geojson_memory_index_featureset(std::string const& filename, array_type && index_array) : @@ -60,19 +61,13 @@ mapnik::feature_ptr geojson_memory_index_featureset::next() std::fseek(file_.get(), file_offset, SEEK_SET); std::vector json; json.resize(size); - std::fread(json.data(), size, 1, file_.get()); + auto count = std::fread(json.data(), size, 1, file_.get()); using chr_iterator_type = char const*; chr_iterator_type start = json.data(); - chr_iterator_type end = start + json.size(); + chr_iterator_type end = (count == 1) ? start + json.size() : start; static const mapnik::transcoder tr("utf8"); - static const mapnik::json::feature_grammar grammar(tr); - using namespace boost::spirit; - standard::space_type space; mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, feature_id_++)); - if (!qi::phrase_parse(start, end, (grammar)(boost::phoenix::ref(*feature)), space) || start != end) - { - throw std::runtime_error("Failed to parse geojson feature"); - } + mapnik::json::parse_feature(start, end, *feature, tr); // throw on failure // skip empty geometries if (mapnik::geometry::is_empty(feature->get_geometry())) continue; diff --git a/plugins/input/geojson/geojson_memory_index_featureset.hpp b/plugins/input/geojson/geojson_memory_index_featureset.hpp index a29751d67..888ccd52d 100644 --- a/plugins/input/geojson/geojson_memory_index_featureset.hpp +++ b/plugins/input/geojson/geojson_memory_index_featureset.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 diff --git a/plugins/input/ogr/ogr_converter.cpp b/plugins/input/ogr/ogr_converter.cpp index e409e81a0..91ba612ad 100644 --- a/plugins/input/ogr/ogr_converter.cpp +++ b/plugins/input/ogr/ogr_converter.cpp @@ -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 diff --git a/plugins/input/ogr/ogr_converter.hpp b/plugins/input/ogr/ogr_converter.hpp index 8b7f909af..452ee250e 100644 --- a/plugins/input/ogr/ogr_converter.hpp +++ b/plugins/input/ogr/ogr_converter.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 diff --git a/plugins/input/ogr/ogr_datasource.cpp b/plugins/input/ogr/ogr_datasource.cpp index 706a376e3..b23304968 100644 --- a/plugins/input/ogr/ogr_datasource.cpp +++ b/plugins/input/ogr/ogr_datasource.cpp @@ -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 diff --git a/plugins/input/ogr/ogr_datasource.hpp b/plugins/input/ogr/ogr_datasource.hpp index 0edeae9dc..35f48f644 100644 --- a/plugins/input/ogr/ogr_datasource.hpp +++ b/plugins/input/ogr/ogr_datasource.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/plugins/input/ogr/ogr_featureset.cpp b/plugins/input/ogr/ogr_featureset.cpp index 267ebc017..f3182b1f2 100644 --- a/plugins/input/ogr/ogr_featureset.cpp +++ b/plugins/input/ogr/ogr_featureset.cpp @@ -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 @@ -22,16 +22,16 @@ // mapnik #include -#include +#include #include -#include +#include #include #include #include #include -#include +#include #include -#include +#include // ogr #include "ogr_featureset.hpp" diff --git a/plugins/input/ogr/ogr_featureset.hpp b/plugins/input/ogr/ogr_featureset.hpp index 6a594ec52..8f73cc6df 100644 --- a/plugins/input/ogr/ogr_featureset.hpp +++ b/plugins/input/ogr/ogr_featureset.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 diff --git a/plugins/input/ogr/ogr_index.hpp b/plugins/input/ogr/ogr_index.hpp index e661d21b0..7a6f0047c 100644 --- a/plugins/input/ogr/ogr_index.hpp +++ b/plugins/input/ogr/ogr_index.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,15 @@ * *****************************************************************************/ -#ifndef OGR_INDEX_HH -#define OGR_INDEX_HH +#ifndef OGR_INDEX_HPP +#define OGR_INDEX_HPP // stl #include #include // mapnik -#include +#include #include using mapnik::box2d; @@ -102,4 +102,4 @@ void ogr_index::read_envelope(IStream& file, box2d& en file.read(reinterpret_cast(&envelope), sizeof(envelope)); } -#endif // OGR_INDEX_HH +#endif // OGR_INDEX_HPP diff --git a/plugins/input/ogr/ogr_index_featureset.cpp b/plugins/input/ogr/ogr_index_featureset.cpp index 54b91f470..6f087fd25 100644 --- a/plugins/input/ogr/ogr_index_featureset.cpp +++ b/plugins/input/ogr/ogr_index_featureset.cpp @@ -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 @@ -21,16 +21,16 @@ *****************************************************************************/ // mapnik -#include +#include #include #include -#include +#include #include #include #include #include #include -#include +#include // boost #if defined(MAPNIK_MEMORY_MAPPED_FILE) diff --git a/plugins/input/ogr/ogr_index_featureset.hpp b/plugins/input/ogr/ogr_index_featureset.hpp index 93d3a327f..961e1c259 100644 --- a/plugins/input/ogr/ogr_index_featureset.hpp +++ b/plugins/input/ogr/ogr_index_featureset.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 diff --git a/plugins/input/ogr/ogr_layer_ptr.hpp b/plugins/input/ogr/ogr_layer_ptr.hpp index 28df28b21..2c50816d9 100644 --- a/plugins/input/ogr/ogr_layer_ptr.hpp +++ b/plugins/input/ogr/ogr_layer_ptr.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 diff --git a/plugins/input/pgraster/pgraster_datasource.cpp b/plugins/input/pgraster/pgraster_datasource.cpp index e6eddf758..11ade8da2 100644 --- a/plugins/input/pgraster/pgraster_datasource.cpp +++ b/plugins/input/pgraster/pgraster_datasource.cpp @@ -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 @@ -36,15 +36,15 @@ #include #include #include -#include +#include #pragma GCC diagnostic push #include #include -#include #pragma GCC diagnostic pop // stl +#include // FLT_MAX #include #include #include @@ -53,28 +53,19 @@ DATASOURCE_PLUGIN(pgraster_datasource) -const double pgraster_datasource::FMAX = std::numeric_limits::max(); const std::string pgraster_datasource::RASTER_COLUMNS = "raster_columns"; const std::string pgraster_datasource::RASTER_OVERVIEWS = "raster_overviews"; const std::string pgraster_datasource::SPATIAL_REF_SYS = "spatial_ref_system"; using std::shared_ptr; using mapnik::attribute_descriptor; +using mapnik::sql_utils::identifier; +using mapnik::sql_utils::literal; using mapnik::value_integer; -namespace { - - // TODO: move to sql_utils - std::string quote_ident(std::string& s) { - return "\"" + s + "\""; // TODO: escape internal quotes - } - -}; - pgraster_datasource::pgraster_datasource(parameters const& params) : datasource(params), table_(*params.get("table", "")), - schema_(""), raster_table_(*params.get("raster_table", "")), raster_field_(*params.get("raster_field", "")), key_field_(*params.get("key_field", "")), @@ -94,10 +85,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params) params.get("user"), params.get("password"), params.get("connect_timeout", "4")), - bbox_token_("!bbox!"), - scale_denom_token_("!scale_denominator!"), - pixel_width_token_("!pixel_width!"), - pixel_height_token_("!pixel_height!"), + re_tokens_("!(@?\\w+)!"), // matches !mapnik_var! or !@user_var! pool_max_size_(*params_.get("max_size", 10)), persist_connection_(*params.get("persist_connection", true)), extent_from_subquery_(*params.get("extent_from_subquery", false)), @@ -141,160 +129,112 @@ pgraster_datasource::pgraster_datasource(parameters const& params) ConnectionManager::instance().registerPool(creator_, *initial_size, pool_max_size_); CnxPool_ptr pool = ConnectionManager::instance().getPool(creator_.id()); - if (pool) + if (!pool) return; + + shared_ptr conn = pool->borrowObject(); + if (!conn) return; + + if (conn->isOK()) { - shared_ptr conn = pool->borrowObject(); - if (!conn) return; + desc_.set_encoding(conn->client_encoding()); - if (conn->isOK()) + if (raster_table_.empty()) { + mapnik::sql_utils::table_from_sql + (table_, parsed_schema_, parsed_table_); - desc_.set_encoding(conn->client_encoding()); - - if (raster_table_.empty()) + // non-trivial subqueries (having no FROM) make it + // impossible to use overviews + // TODO: improve "table_from_sql" ? + auto nsp = table_.find_first_not_of(" \t\r\n"); + if (nsp != std::string::npos && table_[nsp] == '(') { - raster_table_ = mapnik::sql_utils::table_from_sql(table_); - // non-trivial subqueries (having no FROM) make it - // impossible to use overviews - // TODO: improve "table_from_sql" ? - if ( raster_table_[raster_table_.find_first_not_of(" \t\r\n")] == '(' ) - { - raster_table_.clear(); if ( use_overviews_ ) { - std::ostringstream err; - err << "Pgraster Plugin: overviews cannot be used " - "with non-trivial subqueries"; - MAPNIK_LOG_WARN(pgraster) << err.str(); - use_overviews_ = false; + std::ostringstream err; + err << "Pgraster Plugin: overviews cannot be used " + "with non-trivial subqueries"; + MAPNIK_LOG_WARN(pgraster) << err.str(); + use_overviews_ = false; } if ( ! extent_from_subquery_ ) { - std::ostringstream err; - err << "Pgraster Plugin: extent can only be computed " - "from subquery as we could not found table source"; - MAPNIK_LOG_WARN(pgraster) << err.str(); - extent_from_subquery_ = true; + std::ostringstream err; + err << "Pgraster Plugin: extent can only be computed " + "from subquery as we could not found table source"; + MAPNIK_LOG_WARN(pgraster) << err.str(); + extent_from_subquery_ = true; } - - } } + } + else + { + mapnik::sql_utils::table_from_sql + (raster_table_, parsed_schema_, parsed_table_); + } - std::string::size_type idx = raster_table_.find_last_of('.'); - if (idx != std::string::npos) - { - schema_ = raster_table_.substr(0, idx); - raster_table_ = raster_table_.substr(idx + 1); - } - - // If we do not know either the geometry_field or the srid or we - // want to use overviews but do not know about schema, or - // no extent was specified, then attempt to fetch the missing - // information from a raster_columns entry. - // - // This will return no records if we are querying a bogus table returned - // from the simplistic table parsing in table_from_sql() or if - // the table parameter references a table, view, or subselect not - // registered in the geometry columns. - // - geometryColumn_ = mapnik::sql_utils::unquote_double(raster_field_); - if (!raster_table_.empty() && ( - geometryColumn_.empty() || srid_ == 0 || - (schema_.empty() && use_overviews_) || - ! extent_initialized_ - )) - { + // If we do not know either the geometry_field or the srid or we + // want to use overviews but do not know about schema, or + // no extent was specified, then attempt to fetch the missing + // information from a raster_columns entry. + // + // This will return no records if we are querying a bogus table returned + // from the simplistic table parsing in table_from_sql() or if + // the table parameter references a table, view, or subselect not + // registered in the geometry columns. + // + geometryColumn_ = mapnik::sql_utils::unquote_copy('"', raster_field_); + if (!parsed_table_.empty() && ( + geometryColumn_.empty() || srid_ == 0 || + (parsed_schema_.empty() && use_overviews_) || + ! extent_initialized_ + )) + { #ifdef MAPNIK_STATS - mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::init(get_srid_and_geometry_column)"); + mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::init(get_srid_and_geometry_column)"); #endif - std::ostringstream s; + std::ostringstream s; - try + try + { + s << "SELECT r_raster_column col, srid, r_table_schema"; + if ( ! extent_initialized_ ) { + s << ", st_xmin(extent) xmin, st_ymin(extent) ymin" + << ", st_xmax(extent) xmax, st_ymax(extent) ymax"; + } + s << " FROM " << RASTER_COLUMNS + << " WHERE r_table_name=" << literal(parsed_table_); + if (!parsed_schema_.empty()) { - s << "SELECT r_raster_column col, srid, r_table_schema"; - if ( ! extent_initialized_ ) { - s << ", st_xmin(extent) xmin, st_ymin(extent) ymin" - << ", st_xmax(extent) xmax, st_ymax(extent) ymax"; - } - s << " FROM " - << RASTER_COLUMNS << " WHERE r_table_name='" - << mapnik::sql_utils::unquote_double(raster_table_) - << "'"; - if (! schema_.empty()) + s << " AND r_table_schema=" << literal(parsed_schema_); + } + if (!geometryColumn_.empty()) + { + s << " AND r_raster_column=" << literal(geometryColumn_); + } + MAPNIK_LOG_DEBUG(pgraster) << + "pgraster_datasource: running query " << s.str(); + shared_ptr rs = conn->executeQuery(s.str()); + if (rs->next()) + { + geometryColumn_ = rs->getValue("col"); + if ( ! extent_initialized_ ) { - s << " AND r_table_schema='" - << mapnik::sql_utils::unquote_double(schema_) - << "'"; - } - if (! raster_field_.empty()) - { - s << " AND r_raster_column='" - << mapnik::sql_utils::unquote_double(raster_field_) - << "'"; - } - MAPNIK_LOG_DEBUG(pgraster) << - "pgraster_datasource: running query " << s.str(); - shared_ptr rs = conn->executeQuery(s.str()); - if (rs->next()) - { - geometryColumn_ = rs->getValue("col"); - if ( ! extent_initialized_ ) + double lox, loy, hix, hiy; + if (mapnik::util::string2double(rs->getValue("xmin"), lox) && + mapnik::util::string2double(rs->getValue("ymin"), loy) && + mapnik::util::string2double(rs->getValue("xmax"), hix) && + mapnik::util::string2double(rs->getValue("ymax"), hiy)) { - double lox, loy, hix, hiy; - if (mapnik::util::string2double(rs->getValue("xmin"), lox) && - mapnik::util::string2double(rs->getValue("ymin"), loy) && - mapnik::util::string2double(rs->getValue("xmax"), hix) && - mapnik::util::string2double(rs->getValue("ymax"), hiy)) - { extent_.init(lox, loy, hix, hiy); extent_initialized_ = true; MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Layer extent=" << extent_; - } - else - { + } + else + { MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Could not determine extent from query: " << s.str(); - } - } - if (srid_ == 0) - { - const char* srid_c = rs->getValue("srid"); - if (srid_c != nullptr) - { - int result = 0; - const char * end = srid_c + std::strlen(srid_c); - if (mapnik::util::string2int(srid_c, end, result)) - { - srid_ = result; - } - } - } - if ( schema_.empty() ) - { - schema_ = rs->getValue("r_table_schema"); } } - else - { - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no response from metadata query " << s.str(); - } - rs->close(); - } - catch (mapnik::datasource_exception const& ex) { - // let this pass on query error and use the fallback below - MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: metadata query failed: " << ex.what(); - } - - // If we still do not know the srid then we can try to fetch - // it from the 'table_' parameter, which should work even if it is - // a subselect as long as we know the geometry_field to query - if (! geometryColumn_.empty() && srid_ <= 0) - { - s.str(""); - - s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM " - << populate_tokens(table_) << " WHERE \"" << geometryColumn_ << "\" IS NOT NULL LIMIT 1;"; - - shared_ptr rs = conn->executeQuery(s.str()); - if (rs->next()) + if (srid_ == 0) { const char* srid_c = rs->getValue("srid"); if (srid_c != nullptr) @@ -307,275 +247,312 @@ pgraster_datasource::pgraster_datasource(parameters const& params) } } } - rs->close(); - } - } - - // If overviews were requested, take note of the max scale - // of each available overview, sorted by scale descending - if ( use_overviews_ ) - { - std::ostringstream err; - if ( schema_.empty() ) - { - err << "Pgraster Plugin: unable to lookup available table" - << " overviews due to unknown schema"; - throw mapnik::datasource_exception(err.str()); - } - if ( geometryColumn_.empty() ) - { - err << "Pgraster Plugin: unable to lookup available table" - << " overviews due to unknown column name"; - throw mapnik::datasource_exception(err.str()); - } - - std::ostringstream s; - s << "select " - "r.r_table_schema sch, " - "r.r_table_name tab, " - "r.r_raster_column col, " - "greatest(abs(r.scale_x), abs(r.scale_y)) scl " - "from" - " raster_overviews o," - " raster_columns r " - "where" - " o.r_table_schema = '" - << mapnik::sql_utils::unquote_double(schema_) - << "' and o.r_table_name = '" - << mapnik::sql_utils::unquote_double(raster_table_) - << "' and o.r_raster_column = '" - << mapnik::sql_utils::unquote_double(geometryColumn_) - << "' and r.r_table_schema = o.o_table_schema" - " and r.r_table_name = o.o_table_name" - " and r.r_raster_column = o.o_raster_column" - " ORDER BY scl ASC"; - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: running query " << s.str(); - shared_ptr rs = conn->executeQuery(s.str()); - while (rs->next()) - { - pgraster_overview ov = pgraster_overview(); - - ov.schema = rs->getValue("sch"); - ov.table = rs->getValue("tab"); - ov.column = rs->getValue("col"); - ov.scale = atof(rs->getValue("scl")); - - if(ov.scale == 0.0f) - { - MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: found invalid overview " - << ov.schema << "." << ov.table << "." << ov.column << " with scale " << ov.scale; - continue; - } - - overviews_.push_back(ov); - - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: found overview " << ov.schema << "." << ov.table << "." << ov.column << " with scale " << ov.scale; - } - rs->close(); - if ( overviews_.empty() ) { - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no overview found for " << schema_ << "." << raster_table_ << "." << geometryColumn_; - } - } - - // detect primary key - if (*autodetect_key_field && key_field_.empty()) - { -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::bind(get_primary_key)"); -#endif - - std::ostringstream s; - s << "SELECT a.attname, a.attnum, t.typname, t.typname in ('int2','int4','int8') " - "AS is_int FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n, pg_index i " - "WHERE a.attnum > 0 AND a.attrelid = c.oid " - "AND a.atttypid = t.oid AND c.relnamespace = n.oid " - "AND c.oid = i.indrelid AND i.indisprimary = 't' " - "AND t.typname !~ '^geom' AND c.relname =" - << " '" << mapnik::sql_utils::unquote_double(raster_table_) << "' " - //"AND a.attnum = ANY (i.indkey) " // postgres >= 8.1 - << "AND (i.indkey[0]=a.attnum OR i.indkey[1]=a.attnum OR i.indkey[2]=a.attnum " - "OR i.indkey[3]=a.attnum OR i.indkey[4]=a.attnum OR i.indkey[5]=a.attnum " - "OR i.indkey[6]=a.attnum OR i.indkey[7]=a.attnum OR i.indkey[8]=a.attnum " - "OR i.indkey[9]=a.attnum) "; - if (! schema_.empty()) - { - s << "AND n.nspname='" - << mapnik::sql_utils::unquote_double(schema_) - << "' "; - } - s << "ORDER BY a.attnum"; - - shared_ptr rs_key = conn->executeQuery(s.str()); - if (rs_key->next()) - { - unsigned int result_rows = rs_key->size(); - if (result_rows == 1) + if (parsed_schema_.empty()) { - bool is_int = (std::string(rs_key->getValue(3)) == "t"); - if (is_int) - { - const char* key_field_string = rs_key->getValue(0); - if (key_field_string) - { - key_field_ = std::string(key_field_string); - - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: auto-detected key field of '" - << key_field_ << "' on table '" << raster_table_ << "'"; - } - } - else - { - // throw for cases like a numeric primary key, which is invalid - // as it should be floating point (int numerics are useless) - std::ostringstream err; - err << "PostGIS Plugin: Error: '" - << rs_key->getValue(0) - << "' on table '" - << raster_table_ - << "' is not a valid integer primary key field\n"; - throw mapnik::datasource_exception(err.str()); - } - } - else if (result_rows > 1) - { - std::ostringstream err; - err << "PostGIS Plugin: Error: '" - << "multi column primary key detected but is not supported"; - throw mapnik::datasource_exception(err.str()); - } - } - rs_key->close(); - } - - // if a globally unique key field/primary key is required - // but still not known at this point, then throw - if (*autodetect_key_field && key_field_.empty()) - { - throw mapnik::datasource_exception(std::string("PostGIS Plugin: Error: primary key required") - + " but could not be detected for table '" + - raster_table_ + "', please supply 'key_field' option to specify field to use for primary key"); - } - - if (srid_ == 0) - { - srid_ = -1; - - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Table " << table_ << " is using SRID=" << srid_; - } - - // At this point the geometry_field may still not be known - // but we'll catch that where more useful... - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Using SRID=" << srid_; - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Using geometry_column=" << geometryColumn_; - - // collect attribute desc -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::bind(get_column_description)"); -#endif - - std::ostringstream s; - s << "SELECT * FROM " << populate_tokens(table_) << " LIMIT 0"; - - shared_ptr rs = conn->executeQuery(s.str()); - int count = rs->getNumFields(); - bool found_key_field = false; - for (int i = 0; i < count; ++i) - { - std::string fld_name = rs->getFieldName(i); - int type_oid = rs->getTypeOID(i); - - // validate type of key_field - if (! found_key_field && ! key_field_.empty() && fld_name == key_field_) - { - if (type_oid == 20 || type_oid == 21 || type_oid == 23) - { - found_key_field = true; - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer)); - } - else - { - std::ostringstream error_s; - error_s << "invalid type '"; - - std::ostringstream type_s; - type_s << "SELECT oid, typname FROM pg_type WHERE oid = " << type_oid; - - shared_ptr rs_oid = conn->executeQuery(type_s.str()); - if (rs_oid->next()) - { - error_s << rs_oid->getValue("typname") - << "' (oid:" << rs_oid->getValue("oid") << ")"; - } - else - { - error_s << "oid:" << type_oid << "'"; - } - - rs_oid->close(); - error_s << " for key_field '" << fld_name << "' - " - << "must be an integer primary key"; - - rs->close(); - throw mapnik::datasource_exception(error_s.str()); + parsed_schema_ = rs->getValue("r_table_schema"); } } else { - switch (type_oid) - { - case 16: // bool - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Boolean)); - break; - case 20: // int8 - case 21: // int2 - case 23: // int4 - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer)); - break; - case 700: // float4 - case 701: // float8 - case 1700: // numeric - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Double)); - break; - case 1042: // bpchar - case 1043: // varchar - case 25: // text - case 705: // literal - desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::String)); - break; - default: // should not get here -#ifdef MAPNIK_LOG - s.str(""); - s << "SELECT oid, typname FROM pg_type WHERE oid = " << type_oid; - - shared_ptr rs_oid = conn->executeQuery(s.str()); - if (rs_oid->next()) - { - std::string typname(rs_oid->getValue("typname")); - if (typname != "geometry" && typname != "raster") - { - MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: Unknown type=" << typname - << " (oid:" << rs_oid->getValue("oid") << ")"; - } - } - else - { - MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: Unknown type_oid=" << type_oid; - } - rs_oid->close(); -#endif - break; - } + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no response from metadata query " << s.str(); } + rs->close(); + } + catch (mapnik::datasource_exception const& ex) { + // let this pass on query error and use the fallback below + MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: metadata query failed: " << ex.what(); } - rs->close(); + // If we still do not know the srid then we can try to fetch + // it from the 'table_' parameter, which should work even if it is + // a subselect as long as we know the geometry_field to query + if (! geometryColumn_.empty() && srid_ <= 0) + { + s.str(""); + s << "SELECT ST_SRID(" << identifier(geometryColumn_) + << ") AS srid FROM " << populate_tokens(table_) + << " WHERE " << identifier(geometryColumn_) + << " IS NOT NULL LIMIT 1"; + + shared_ptr rs = conn->executeQuery(s.str()); + if (rs->next()) + { + const char* srid_c = rs->getValue("srid"); + if (srid_c != nullptr) + { + int result = 0; + const char * end = srid_c + std::strlen(srid_c); + if (mapnik::util::string2int(srid_c, end, result)) + { + srid_ = result; + } + } + } + rs->close(); + } } - // Close explicitly the connection so we can 'fork()' without sharing open connections - conn->close(); + // If overviews were requested, take note of the max scale + // of each available overview, sorted by scale descending + if ( use_overviews_ ) + { + std::ostringstream err; + if (parsed_schema_.empty()) + { + err << "Pgraster Plugin: unable to lookup available table" + << " overviews due to unknown schema"; + throw mapnik::datasource_exception(err.str()); + } + if (geometryColumn_.empty()) + { + err << "Pgraster Plugin: unable to lookup available table" + << " overviews due to unknown column name"; + throw mapnik::datasource_exception(err.str()); + } + std::ostringstream s; + s << "select " + "r.r_table_schema sch, " + "r.r_table_name tab, " + "r.r_raster_column col, " + "greatest(abs(r.scale_x), abs(r.scale_y)) scl " + "from" + " raster_overviews o," + " raster_columns r " + "where" + " o.r_table_schema = " << literal(parsed_schema_) + << " and o.r_table_name = " << literal(parsed_table_) + << " and o.r_raster_column = " << literal(geometryColumn_) + << " and r.r_table_schema = o.o_table_schema" + " and r.r_table_name = o.o_table_name" + " and r.r_raster_column = o.o_raster_column" + " ORDER BY scl ASC"; + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: running query " << s.str(); + shared_ptr rs = conn->executeQuery(s.str()); + while (rs->next()) + { + pgraster_overview ov = pgraster_overview(); + + ov.schema = rs->getValue("sch"); + ov.table = rs->getValue("tab"); + ov.column = rs->getValue("col"); + ov.scale = atof(rs->getValue("scl")); + + if(ov.scale == 0.0f) + { + MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: found invalid overview " + << ov.schema << "." << ov.table << "." << ov.column << " with scale " << ov.scale; + continue; + } + + overviews_.push_back(ov); + + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: found overview " + << ov.schema << "." << ov.table << "." << ov.column << " with scale " << ov.scale; + } + rs->close(); + if ( overviews_.empty() ) { + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no overview found for " + << parsed_schema_ << "." << parsed_table_ << "." << geometryColumn_; + } + } + + // detect primary key + if (*autodetect_key_field && key_field_.empty()) + { +#ifdef MAPNIK_STATS + mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::bind(get_primary_key)"); +#endif + + std::ostringstream s; + s << "SELECT a.attname, a.attnum, t.typname, t.typname in ('int2','int4','int8') " + "AS is_int FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n, pg_index i " + "WHERE a.attnum > 0 AND a.attrelid = c.oid " + "AND a.atttypid = t.oid AND c.relnamespace = n.oid " + "AND c.oid = i.indrelid AND i.indisprimary = 't' " + "AND t.typname !~ '^geom' AND c.relname = " << literal(parsed_table_) << " " + //"AND a.attnum = ANY (i.indkey) " // postgres >= 8.1 + << "AND (i.indkey[0]=a.attnum OR i.indkey[1]=a.attnum OR i.indkey[2]=a.attnum " + "OR i.indkey[3]=a.attnum OR i.indkey[4]=a.attnum OR i.indkey[5]=a.attnum " + "OR i.indkey[6]=a.attnum OR i.indkey[7]=a.attnum OR i.indkey[8]=a.attnum " + "OR i.indkey[9]=a.attnum) "; + if (!parsed_schema_.empty()) + { + s << "AND n.nspname=" << literal(parsed_schema_) << ' '; + } + s << "ORDER BY a.attnum"; + + shared_ptr rs_key = conn->executeQuery(s.str()); + if (rs_key->next()) + { + unsigned int result_rows = rs_key->size(); + if (result_rows == 1) + { + bool is_int = (std::string(rs_key->getValue(3)) == "t"); + if (is_int) + { + const char* key_field_string = rs_key->getValue(0); + if (key_field_string) + { + key_field_ = std::string(key_field_string); + + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: auto-detected key field of '" + << key_field_ << "' on table '" << parsed_table_ << "'"; + } + } + else + { + // throw for cases like a numeric primary key, which is invalid + // as it should be floating point (int numerics are useless) + std::ostringstream err; + err << "PostGIS Plugin: Error: '" + << rs_key->getValue(0) + << "' on table '" + << parsed_table_ + << "' is not a valid integer primary key field\n"; + throw mapnik::datasource_exception(err.str()); + } + } + else if (result_rows > 1) + { + std::ostringstream err; + err << "PostGIS Plugin: Error: '" + << "multi column primary key detected but is not supported"; + throw mapnik::datasource_exception(err.str()); + } + } + rs_key->close(); + } + + // if a globally unique key field/primary key is required + // but still not known at this point, then throw + if (*autodetect_key_field && key_field_.empty()) + { + throw mapnik::datasource_exception( + "PostGIS Plugin: Error: primary key required" + " but could not be detected for table '" + + parsed_table_ + "', please supply 'key_field'" + " option to specify field to use for primary key"); + } + + if (srid_ == 0) + { + srid_ = -1; + + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Table " << table_ << " is using SRID=" << srid_; + } + + // At this point the geometry_field may still not be known + // but we'll catch that where more useful... + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Using SRID=" << srid_; + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: Using geometry_column=" << geometryColumn_; + + // collect attribute desc +#ifdef MAPNIK_STATS + mapnik::progress_timer __stats2__(std::clog, "pgraster_datasource::bind(get_column_description)"); +#endif + + std::ostringstream s; + s << "SELECT * FROM " << populate_tokens(table_) << " LIMIT 0"; + + shared_ptr rs = conn->executeQuery(s.str()); + int count = rs->getNumFields(); + bool found_key_field = false; + for (int i = 0; i < count; ++i) + { + std::string fld_name = rs->getFieldName(i); + int type_oid = rs->getTypeOID(i); + + // validate type of key_field + if (! found_key_field && ! key_field_.empty() && fld_name == key_field_) + { + if (type_oid == 20 || type_oid == 21 || type_oid == 23) + { + found_key_field = true; + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer)); + } + else + { + std::ostringstream error_s; + error_s << "invalid type '"; + + std::ostringstream type_s; + type_s << "SELECT oid, typname FROM pg_type WHERE oid = " << type_oid; + + shared_ptr rs_oid = conn->executeQuery(type_s.str()); + if (rs_oid->next()) + { + error_s << rs_oid->getValue("typname") + << "' (oid:" << rs_oid->getValue("oid") << ")"; + } + else + { + error_s << "oid:" << type_oid << "'"; + } + + rs_oid->close(); + error_s << " for key_field '" << fld_name << "' - " + << "must be an integer primary key"; + + rs->close(); + throw mapnik::datasource_exception(error_s.str()); + } + } + else + { + switch (type_oid) + { + case 16: // bool + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Boolean)); + break; + case 20: // int8 + case 21: // int2 + case 23: // int4 + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Integer)); + break; + case 700: // float4 + case 701: // float8 + case 1700: // numeric + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::Double)); + break; + case 1042: // bpchar + case 1043: // varchar + case 25: // text + case 705: // literal + desc_.add_descriptor(attribute_descriptor(fld_name, mapnik::String)); + break; + default: // should not get here +#ifdef MAPNIK_LOG + s.str(""); + s << "SELECT oid, typname FROM pg_type WHERE oid = " << type_oid; + + shared_ptr rs_oid = conn->executeQuery(s.str()); + if (rs_oid->next()) + { + std::string typname(rs_oid->getValue("typname")); + if (typname != "geometry" && typname != "raster") + { + MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: Unknown type=" << typname + << " (oid:" << rs_oid->getValue("oid") << ")"; + } + } + else + { + MAPNIK_LOG_WARN(pgraster) << "pgraster_datasource: Unknown type_oid=" << type_oid; + } + rs_oid->close(); +#endif + break; + } + } + } + + rs->close(); } + + // Close explicitly the connection so we can 'fork()' without sharing open connections + conn->close(); } pgraster_datasource::~pgraster_datasource() @@ -627,10 +604,10 @@ std::string pgraster_datasource::sql_bbox(box2d const& env) const b << "ST_SetSRID("; } - b << "'BOX3D("; + b << "'BOX("; b << std::setprecision(16); b << env.minx() << " " << env.miny() << ","; - b << env.maxx() << " " << env.maxy() << ")'::box3d"; + b << env.maxx() << " " << env.maxy() << ")'::box2d"; if (srid_ > 0) { @@ -642,77 +619,76 @@ std::string pgraster_datasource::sql_bbox(box2d const& env) const std::string pgraster_datasource::populate_tokens(std::string const& sql) const { - std::string populated_sql = sql; - - if (boost::algorithm::icontains(sql, bbox_token_)) - { - box2d max_env(-1.0 * FMAX, -1.0 * FMAX, FMAX, FMAX); - const std::string max_box = sql_bbox(max_env); - boost::algorithm::replace_all(populated_sql, bbox_token_, max_box); - } - - if (boost::algorithm::icontains(sql, scale_denom_token_)) - { - std::ostringstream ss; - ss << FMAX; - boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str()); - } - - if (boost::algorithm::icontains(sql, pixel_width_token_)) - { - std::ostringstream ss; - ss << 0; - boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str()); - } - - if (boost::algorithm::icontains(sql, pixel_height_token_)) - { - std::ostringstream ss; - ss << 0; - boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str()); - } - - return populated_sql; + return populate_tokens(sql, FLT_MAX, + box2d(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX), + 0, 0, mapnik::attributes{}, false); } -std::string pgraster_datasource::populate_tokens(std::string const& sql, double scale_denom, box2d const& env, double pixel_width, double pixel_height) const +std::string pgraster_datasource::populate_tokens(std::string const& sql, + double scale_denom, + box2d const& env, + double pixel_width, + double pixel_height, + mapnik::attributes const& vars, + bool intersect) const { - std::string populated_sql = sql; - std::string box = sql_bbox(env); + std::ostringstream populated_sql; + std::cmatch m; + char const* start = sql.data(); + char const* end = start + sql.size(); - if (boost::algorithm::icontains(populated_sql, scale_denom_token_)) + while (std::regex_search(start, end, m, re_tokens_)) { - std::ostringstream ss; - ss << scale_denom; - boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str()); + populated_sql.write(start, m[0].first - start); + start = m[0].second; + + auto m1 = boost::make_iterator_range(m[1].first, m[1].second); + if (m1.front() == '@') + { + std::string var_name(m1.begin() + 1, m1.end()); + auto itr = vars.find(var_name); + if (itr != vars.end()) + { + auto var_value = itr->second.to_string(); + populated_sql << literal(var_value); + } + else + { + populated_sql << "NULL"; // undefined @variable + } + } + else if (boost::algorithm::equals(m1, "bbox")) + { + populated_sql << sql_bbox(env); + intersect = false; + } + else if (boost::algorithm::equals(m1, "pixel_height")) + { + populated_sql << pixel_height; + } + else if (boost::algorithm::equals(m1, "pixel_width")) + { + populated_sql << pixel_width; + } + else if (boost::algorithm::equals(m1, "scale_denominator")) + { + populated_sql << scale_denom; + } + else + { + populated_sql << "NULL"; // unrecognized !token! + } } - if (boost::algorithm::icontains(sql, pixel_width_token_)) - { - std::ostringstream ss; - ss << pixel_width; - boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str()); - } + populated_sql.write(start, end - start); - if (boost::algorithm::icontains(sql, pixel_height_token_)) + if (intersect) { - std::ostringstream ss; - ss << pixel_height; - boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str()); - } - - if (boost::algorithm::icontains(populated_sql, bbox_token_)) - { - boost::algorithm::replace_all(populated_sql, bbox_token_, box); - return populated_sql; - } - else - { - std::ostringstream s; - if (intersect_min_scale_ > 0 && (scale_denom <= intersect_min_scale_)) { - s << " WHERE ST_Intersects(\"" << geometryColumn_ << "\"," << box << ")"; + populated_sql << " WHERE ST_Intersects(" + << identifier(geometryColumn_) << ", " + << sql_bbox(env) << ")"; } else if (intersect_max_scale_ > 0 && (scale_denom >= intersect_max_scale_)) { @@ -720,11 +696,13 @@ std::string pgraster_datasource::populate_tokens(std::string const& sql, double } else { - s << " WHERE \"" << geometryColumn_ << "\" && " << box; + populated_sql << " WHERE " + << identifier(geometryColumn_) << " && " + << sql_bbox(env); } - - return populated_sql + s.str(); } + + return populated_sql.str(); } @@ -852,19 +830,19 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process std::ostringstream s_error; s_error << "PostGIS: geometry name lookup failed for table '"; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s_error << schema_ << "."; + s_error << parsed_schema_ << "."; } - s_error << raster_table_ + s_error << parsed_table_ << "'. Please manually provide the 'geometry_field' parameter or add an entry " << "in the geometry_columns for '"; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s_error << schema_ << "."; + s_error << parsed_schema_ << "."; } - s_error << raster_table_ << "'."; + s_error << parsed_table_ << "'."; throw mapnik::datasource_exception(s_error.str()); } @@ -877,6 +855,7 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process std::string table_with_bbox; std::string col = geometryColumn_; + table_with_bbox = table_; // possibly a subquery if ( use_overviews_ && !overviews_.empty()) { std::string sch = overviews_[0].schema; @@ -904,18 +883,12 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process << " not good for min out scale " << scale; } } - table_with_bbox = table_; // possibly a subquery - boost::algorithm::replace_all(table_with_bbox, - mapnik::sql_utils::unquote_double(raster_table_), tab); - boost::algorithm::replace_all(table_with_bbox, - mapnik::sql_utils::unquote_double(schema_), sch); - boost::algorithm::replace_all(table_with_bbox, - mapnik::sql_utils::unquote_double(geometryColumn_), col); - table_with_bbox = populate_tokens(table_with_bbox, - scale_denom, box, px_gw, px_gh); - } else { - table_with_bbox = populate_tokens(table_, scale_denom, box, px_gw, px_gh); + boost::algorithm::replace_all(table_with_bbox, parsed_table_, tab); + boost::algorithm::replace_all(table_with_bbox, parsed_schema_, sch); + boost::algorithm::replace_all(table_with_bbox, geometryColumn_, col); } + table_with_bbox = populate_tokens(table_with_bbox, scale_denom, box, + px_gw, px_gh, q.variables()); std::ostringstream s; @@ -927,21 +900,21 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process if (clip_rasters_) s << "ST_Clip("; - s << "\"" << col << "\""; + s << identifier(col); if (clip_rasters_) { s << ", ST_Expand(" << sql_bbox(box) - << ", greatest(abs(ST_ScaleX(\"" - << col << "\")), abs(ST_ScaleY(\"" - << col << "\")))))"; + << ", greatest(abs(ST_ScaleX(" + << identifier(col) << ")), abs(ST_ScaleY(" + << identifier(col) << ")))))"; } if (prescale_rasters_) { const double scale = std::min(px_gw, px_gh); - s << ", least(abs(ST_ScaleX(\"" << col - << "\"))::float8/" << scale - << ", 1.0), least(abs(ST_ScaleY(\"" << col - << "\"))::float8/" << scale << ", 1.0))"; + s << ", least(1.0, abs(ST_ScaleX(" << identifier(col) + << "))::float8/" << scale + << "), least(1.0, abs(ST_ScaleY(" << identifier(col) + << "))::float8/" << scale << "))"; // TODO: if band_ is given, we'll interpret as indexed so // the rescaling must NOT ruin it (use algorithm mode!) } @@ -957,14 +930,14 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process if (! key_field_.empty()) { - mapnik::sql_utils::quote_attr(s, key_field_); + s << ',' << identifier(key_field_); ctx->push(key_field_); for (; pos != end; ++pos) { if (*pos != key_field_) { - mapnik::sql_utils::quote_attr(s, *pos); + s << ',' << identifier(*pos); ctx->push(*pos); } } @@ -973,7 +946,7 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process { for (; pos != end; ++pos) { - mapnik::sql_utils::quote_attr(s, *pos); + s << ',' << identifier(*pos); ctx->push(*pos); } } @@ -1020,39 +993,39 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double std::ostringstream s_error; s_error << "PostGIS: geometry name lookup failed for table '"; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s_error << schema_ << "."; + s_error << parsed_schema_ << "."; } - s_error << raster_table_ + s_error << parsed_table_ << "'. Please manually provide the 'geometry_field' parameter or add an entry " << "in the geometry_columns for '"; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s_error << schema_ << "."; + s_error << parsed_schema_ << "."; } - s_error << raster_table_ << "'."; + s_error << parsed_table_ << "'."; throw mapnik::datasource_exception(s_error.str()); } std::ostringstream s; - s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom"; + s << "SELECT ST_AsBinary(" << identifier(geometryColumn_) << ") AS geom"; mapnik::context_ptr ctx = std::make_shared(); auto const& desc = desc_.get_descriptors(); if (!key_field_.empty()) { - mapnik::sql_utils::quote_attr(s, key_field_); + s << ',' << identifier(key_field_); ctx->push(key_field_); for (auto const& attr_info : desc) { std::string const& name = attr_info.get_name(); if (name != key_field_) { - mapnik::sql_utils::quote_attr(s, name); + s << ',' << identifier(name); ctx->push(name); } } @@ -1062,13 +1035,14 @@ featureset_ptr pgraster_datasource::features_at_point(coord2d const& pt, double for (auto const& attr_info : desc) { std::string const& name = attr_info.get_name(); - mapnik::sql_utils::quote_attr(s, name); + s << ',' << identifier(name); ctx->push(name); } } box2d box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol); - std::string table_with_bbox = populate_tokens(table_, FMAX, box, 0, 0); + std::string table_with_bbox = populate_tokens(table_, FLT_MAX, box, 0, 0, + mapnik::attributes{}); s << " FROM " << table_with_bbox; @@ -1101,9 +1075,9 @@ box2d pgraster_datasource::envelope() const { std::ostringstream s; - std::string col = mapnik::sql_utils::unquote_double(geometryColumn_); - std::string sch = mapnik::sql_utils::unquote_double(schema_); - std::string tab = mapnik::sql_utils::unquote_double(raster_table_); + std::string col = geometryColumn_; + std::string sch = parsed_schema_; + std::string tab = parsed_table_; if ( ! overviews_.empty() ) { @@ -1123,7 +1097,7 @@ box2d pgraster_datasource::envelope() const { s_error << sch << "."; } - s_error << raster_table_ << "' because we cannot determine the raster field name." + s_error << parsed_table_ << "' because we cannot determine the raster field name." << "\nPlease provide either an 'extent' parameter to skip this query, " << "a 'raster_field' and/or 'raster_table' parameter, or add " << "standard constraints to your raster table."; @@ -1143,20 +1117,20 @@ box2d pgraster_datasource::envelope() const throw mapnik::datasource_exception("Pgraster Plugin: " + s_error.str()); } s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)" - << " FROM (SELECT ST_Estimated_Extent('"; + << " FROM (SELECT ST_EstimatedExtent('"; if (! sch.empty()) { - s << mapnik::sql_utils::unquote_double(sch) << "','"; + s << literal(sch) << ','; } - s << mapnik::sql_utils::unquote_double(tab) << "','" - << mapnik::sql_utils::unquote_double(col) << "') as ext) as tmp"; + s << literal(tab) << ',' + << literal(col) << ") as ext) as tmp"; } else { s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)" - << " FROM (SELECT ST_Extent(" << quote_ident(col) << "::geometry) as ext from "; + << " FROM (SELECT ST_Extent(" << identifier(col) << "::geometry) as ext from "; if (extent_from_subquery_) { @@ -1168,12 +1142,12 @@ box2d pgraster_datasource::envelope() const { if (! sch.empty()) { - s << quote_ident(sch) << "."; + s << identifier(sch) << "."; } // but if the subquery does not limit records then querying the // actual table will be faster as indexes can be used - s << quote_ident(tab) << ") as tmp"; + s << identifier(tab) << ") as tmp"; } } diff --git a/plugins/input/pgraster/pgraster_datasource.hpp b/plugins/input/pgraster/pgraster_datasource.hpp index 221f196e4..0ffe762b5 100644 --- a/plugins/input/pgraster/pgraster_datasource.hpp +++ b/plugins/input/pgraster/pgraster_datasource.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 @@ -32,16 +32,17 @@ #include #include #include -#include +#include #include #include #include -#include +#include // boost #include // stl +#include #include #include #include @@ -90,24 +91,26 @@ public: private: std::string sql_bbox(box2d const& env) const; - std::string populate_tokens(std::string const& sql, double scale_denom, box2d const& env, double pixel_width, double pixel_height) const; + std::string populate_tokens(std::string const& sql, double scale_denom, + box2d const& env, + double pixel_width, double pixel_height, + mapnik::attributes const& vars, + bool intersect = true) const; std::string populate_tokens(std::string const& sql) const; std::shared_ptr get_resultset(std::shared_ptr &conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx= processor_context_ptr()) const; static const std::string RASTER_COLUMNS; static const std::string RASTER_OVERVIEWS; static const std::string SPATIAL_REF_SYS; - static const double FMAX; const std::string uri_; const std::string username_; const std::string password_; // table name (schema qualified or not) or subquery const std::string table_; - // schema name (possibly extracted from table_) - std::string schema_; - // table name (possibly extracted from table_) - std::string raster_table_; + const std::string raster_table_; // possibly schema-qualified const std::string raster_field_; + std::string parsed_schema_; // extracted from raster_table_ or table_ + std::string parsed_table_; // extracted from raster_table_ or table_ std::string key_field_; mapnik::value_integer cursor_fetch_size_; mapnik::value_integer row_limit_; @@ -129,10 +132,7 @@ private: bool clip_rasters_; layer_descriptor desc_; ConnectionCreator creator_; - const std::string bbox_token_; - const std::string scale_denom_token_; - const std::string pixel_width_token_; - const std::string pixel_height_token_; + std::regex re_tokens_; int pool_max_size_; bool persist_connection_; bool extent_from_subquery_; diff --git a/plugins/input/pgraster/pgraster_featureset.cpp b/plugins/input/pgraster/pgraster_featureset.cpp index e2d4ccb50..8cf596ead 100644 --- a/plugins/input/pgraster/pgraster_featureset.cpp +++ b/plugins/input/pgraster/pgraster_featureset.cpp @@ -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 @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/pgraster/pgraster_featureset.hpp b/plugins/input/pgraster/pgraster_featureset.hpp index 25319b31a..d218b667d 100644 --- a/plugins/input/pgraster/pgraster_featureset.hpp +++ b/plugins/input/pgraster/pgraster_featureset.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 @@ -28,7 +28,7 @@ #define PGRASTER_FEATURESET_HPP // mapnik -#include +#include #include #include #include diff --git a/plugins/input/pgraster/pgraster_wkb_reader.cpp b/plugins/input/pgraster/pgraster_wkb_reader.cpp index 4a9fd1c8f..aa2891c0e 100644 --- a/plugins/input/pgraster/pgraster_wkb_reader.cpp +++ b/plugins/input/pgraster/pgraster_wkb_reader.cpp @@ -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 @@ -35,7 +35,7 @@ #include #include #include -#include // for box2d +#include // for box2d #include #include diff --git a/plugins/input/pgraster/pgraster_wkb_reader.hpp b/plugins/input/pgraster/pgraster_wkb_reader.hpp index 02a22bc4a..d4cff13ad 100644 --- a/plugins/input/pgraster/pgraster_wkb_reader.hpp +++ b/plugins/input/pgraster/pgraster_wkb_reader.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 @@ -29,7 +29,7 @@ // mapnik #include // for raster_ptr -#include +#include enum pgraster_color_interp { // Automatic color interpretation: diff --git a/plugins/input/postgis/asyncresultset.hpp b/plugins/input/postgis/asyncresultset.hpp index 9c30d57f3..68a5058e0 100644 --- a/plugins/input/postgis/asyncresultset.hpp +++ b/plugins/input/postgis/asyncresultset.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 diff --git a/plugins/input/postgis/build.py b/plugins/input/postgis/build.py index 157952f45..635efb848 100644 --- a/plugins/input/postgis/build.py +++ b/plugins/input/postgis/build.py @@ -52,7 +52,6 @@ libraries = copy(plugin_env['LIBS']) if env['PLUGIN_LINKING'] == 'shared': libraries.append('boost_system%s' % env['BOOST_APPEND']) - libraries.append('boost_regex%s' % env['BOOST_APPEND']) libraries.insert(0,env['MAPNIK_NAME']) libraries.append(env['ICU_LIB_NAME']) diff --git a/plugins/input/postgis/connection.hpp b/plugins/input/postgis/connection.hpp index 3d33a2d67..d241eced2 100644 --- a/plugins/input/postgis/connection.hpp +++ b/plugins/input/postgis/connection.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 diff --git a/plugins/input/postgis/connection_manager.hpp b/plugins/input/postgis/connection_manager.hpp index 73656cbbc..e3de59191 100644 --- a/plugins/input/postgis/connection_manager.hpp +++ b/plugins/input/postgis/connection_manager.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 diff --git a/plugins/input/postgis/cursorresultset.hpp b/plugins/input/postgis/cursorresultset.hpp index 63bb9429c..b4bd1d5da 100644 --- a/plugins/input/postgis/cursorresultset.hpp +++ b/plugins/input/postgis/cursorresultset.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 diff --git a/plugins/input/postgis/numeric2string.hpp b/plugins/input/postgis/numeric2string.hpp index 76c204f0c..35381f07e 100644 --- a/plugins/input/postgis/numeric2string.hpp +++ b/plugins/input/postgis/numeric2string.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 diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp index 10ce521d0..0e90ac5fb 100644 --- a/plugins/input/postgis/postgis_datasource.cpp +++ b/plugins/input/postgis/postgis_datasource.cpp @@ -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 @@ -33,16 +33,15 @@ #include #include #include -#include +#include #pragma GCC diagnostic push #include #include -#include -#include #pragma GCC diagnostic pop // stl +#include // FLT_MAX #include #include #include @@ -52,17 +51,17 @@ DATASOURCE_PLUGIN(postgis_datasource) -const double postgis_datasource::FMAX = std::numeric_limits::max(); const std::string postgis_datasource::GEOMETRY_COLUMNS = "geometry_columns"; const std::string postgis_datasource::SPATIAL_REF_SYS = "spatial_ref_system"; using std::shared_ptr; using mapnik::attribute_descriptor; +using mapnik::sql_utils::identifier; +using mapnik::sql_utils::literal; postgis_datasource::postgis_datasource(parameters const& params) : datasource(params), table_(*params.get("table", "")), - schema_(""), geometry_table_(*params.get("geometry_table", "")), geometry_field_(*params.get("geometry_field", "")), key_field_(*params.get("key_field", "")), @@ -79,10 +78,6 @@ postgis_datasource::postgis_datasource(parameters const& params) params.get("user"), params.get("password"), params.get("connect_timeout", "4")), - bbox_token_("!bbox!"), - scale_denom_token_("!scale_denominator!"), - pixel_width_token_("!pixel_width!"), - pixel_height_token_("!pixel_height!"), pool_max_size_(*params_.get("max_size", 10)), persist_connection_(*params.get("persist_connection", true)), extent_from_subquery_(*params.get("extent_from_subquery", false)), @@ -99,8 +94,7 @@ postgis_datasource::postgis_datasource(parameters const& params) simplify_prefilter_(*params_.get("simplify_prefilter", 0.0)), simplify_dp_preserve_(false), simplify_clip_resolution_(*params_.get("simplify_clip_resolution", 0.0)), - // TODO - use for known tokens too: "(@\\w+|!\\w+!)" - pattern_(boost::regex("(@\\w+)",boost::regex::normal | boost::regbase::icase)), + re_tokens_("!(@?\\w+)!"), // matches !mapnik_var! or !@user_var! // params below are for testing purposes only and may be removed at any time intersect_min_scale_(*params.get("intersect_min_scale", 0)), intersect_max_scale_(*params.get("intersect_max_scale", 0)), @@ -159,21 +153,13 @@ postgis_datasource::postgis_datasource(parameters const& params) desc_.set_encoding(conn->client_encoding()); - if (geometry_table_.empty()) - { - geometry_table_ = mapnik::sql_utils::table_from_sql(table_); - } + mapnik::sql_utils::table_from_sql( + geometry_table_.empty() ? table_ : geometry_table_, + parsed_schema_, parsed_table_); - std::string::size_type idx = geometry_table_.find_last_of('.'); - if (idx != std::string::npos) - { - schema_ = geometry_table_.substr(0, idx); - geometry_table_ = geometry_table_.substr(idx + 1); - } - - // NOTE: geometry_table_ how should ideally be a table name, but + // NOTE: parsed_table_ now should ideally be a table name, but // there are known edge cases where this will break down and - // geometry_table_ may even be empty: https://github.com/mapnik/mapnik/issues/2718 + // it may even be empty: https://github.com/mapnik/mapnik/issues/2718 // If we do not know both the geometry_field and the srid // then first attempt to fetch the geometry name from a geometry_columns entry. @@ -181,8 +167,8 @@ postgis_datasource::postgis_datasource(parameters const& params) // from the simplistic table parsing in table_from_sql() or if // the table parameter references a table, view, or subselect not // registered in the geometry columns. - geometryColumn_ = geometry_field_; - if (!geometry_table_.empty() && (geometryColumn_.empty() || srid_ == 0)) + geometryColumn_ = mapnik::sql_utils::unquote_copy('"', geometry_field_); + if (!parsed_table_.empty() && (geometryColumn_.empty() || srid_ == 0)) { #ifdef MAPNIK_STATS mapnik::progress_timer __stats2__(std::clog, "postgis_datasource::init(get_srid_and_geometry_column)"); @@ -191,21 +177,15 @@ postgis_datasource::postgis_datasource(parameters const& params) try { - s << "SELECT f_geometry_column, srid FROM " - << GEOMETRY_COLUMNS <<" WHERE f_table_name='" - << mapnik::sql_utils::unquote_double(geometry_table_) - << "'"; - if (! schema_.empty()) + s << "SELECT f_geometry_column, srid FROM " << GEOMETRY_COLUMNS + << " WHERE f_table_name=" << literal(parsed_table_); + if (!parsed_schema_.empty()) { - s << " AND f_table_schema='" - << mapnik::sql_utils::unquote_double(schema_) - << "'"; + s << " AND f_table_schema=" << literal(parsed_schema_); } - if (! geometry_field_.empty()) + if (!geometryColumn_.empty()) { - s << " AND f_geometry_column='" - << mapnik::sql_utils::unquote_double(geometry_field_) - << "'"; + s << " AND f_geometry_column=" << literal(geometryColumn_); } shared_ptr rs = conn->executeQuery(s.str()); if (rs->next()) @@ -237,26 +217,24 @@ postgis_datasource::postgis_datasource(parameters const& params) } // If we still do not know the srid then we can try to fetch - // it from the 'geometry_table_' parameter, which should work even if it is + // it from the 'parsed_table_' parameter, which should work even if it is // a subselect as long as we know the geometry_field to query if (!geometryColumn_.empty() && srid_ <= 0) { std::ostringstream s; - s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM "; - if (!geometry_table_.empty()) + s << "SELECT ST_SRID(" << identifier(geometryColumn_) + << ") AS srid FROM "; + if (!parsed_table_.empty()) { - if (!schema_.empty()) - { - s << schema_ << '.'; - } - s << geometry_table_; + append_geometry_table(s); } else { s << populate_tokens(table_); } - s << " WHERE \"" << geometryColumn_ << "\" IS NOT NULL LIMIT 1;"; + s << " WHERE " << identifier(geometryColumn_) + << " IS NOT NULL LIMIT 1"; shared_ptr rs = conn->executeQuery(s.str()); if (rs->next()) @@ -288,18 +266,16 @@ postgis_datasource::postgis_datasource(parameters const& params) "WHERE a.attnum > 0 AND a.attrelid = c.oid " "AND a.atttypid = t.oid AND c.relnamespace = n.oid " "AND c.oid = i.indrelid AND i.indisprimary = 't' " - "AND t.typname !~ '^geom' AND c.relname =" - << " '" << mapnik::sql_utils::unquote_double(geometry_table_) << "' " + "AND t.typname !~ '^geom' AND c.relname = " + << literal(parsed_table_) << " " //"AND a.attnum = ANY (i.indkey) " // postgres >= 8.1 << "AND (i.indkey[0]=a.attnum OR i.indkey[1]=a.attnum OR i.indkey[2]=a.attnum " "OR i.indkey[3]=a.attnum OR i.indkey[4]=a.attnum OR i.indkey[5]=a.attnum " "OR i.indkey[6]=a.attnum OR i.indkey[7]=a.attnum OR i.indkey[8]=a.attnum " "OR i.indkey[9]=a.attnum) "; - if (! schema_.empty()) + if (!parsed_schema_.empty()) { - s << "AND n.nspname='" - << mapnik::sql_utils::unquote_double(schema_) - << "' "; + s << "AND n.nspname=" << literal(parsed_schema_) << ' '; } s << "ORDER BY a.attnum"; @@ -318,7 +294,7 @@ postgis_datasource::postgis_datasource(parameters const& params) key_field_ = std::string(key_field_string); MAPNIK_LOG_DEBUG(postgis) << "postgis_datasource: auto-detected key field of '" - << key_field_ << "' on table '" << geometry_table_ << "'"; + << key_field_ << "' on table '" << parsed_table_ << "'"; } } else @@ -329,7 +305,7 @@ postgis_datasource::postgis_datasource(parameters const& params) err << "PostGIS Plugin: Error: '" << rs_key->getValue(0) << "' on table '" - << geometry_table_ + << parsed_table_ << "' is not a valid integer primary key field\n"; throw mapnik::datasource_exception(err.str()); } @@ -349,9 +325,11 @@ postgis_datasource::postgis_datasource(parameters const& params) // but still not known at this point, then throw if (*autodetect_key_field && key_field_.empty()) { - throw mapnik::datasource_exception(std::string("PostGIS Plugin: Error: primary key required") - + " but could not be detected for table '" + - geometry_table_ + "', please supply 'key_field' option to specify field to use for primary key"); + throw mapnik::datasource_exception( + "PostGIS Plugin: Error: primary key required" + " but could not be detected for table '" + + parsed_table_ + "', please supply 'key_field'" + " option to specify field to use for primary key"); } if (srid_ == 0) @@ -551,43 +529,9 @@ std::string postgis_datasource::sql_bbox(box2d const& env) const std::string postgis_datasource::populate_tokens(std::string const& sql) const { - std::string populated_sql = sql; - - if (boost::algorithm::icontains(sql, bbox_token_)) - { - box2d max_env(-1.0 * FMAX, -1.0 * FMAX, FMAX, FMAX); - const std::string max_box = sql_bbox(max_env); - boost::algorithm::replace_all(populated_sql, bbox_token_, max_box); - } - - if (boost::algorithm::icontains(sql, scale_denom_token_)) - { - std::ostringstream ss; - ss << FMAX; - boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str()); - } - - if (boost::algorithm::icontains(sql, pixel_width_token_)) - { - boost::algorithm::replace_all(populated_sql, pixel_width_token_, "0"); - } - - if (boost::algorithm::icontains(sql, pixel_height_token_)) - { - boost::algorithm::replace_all(populated_sql, pixel_height_token_, "0"); - } - - std::string copy2 = populated_sql; - std::list l; - boost::regex_split(std::back_inserter(l), copy2, pattern_); - if (!l.empty()) - { - for (auto const & token: l) - { - boost::algorithm::replace_all(populated_sql, token, "null"); - } - } - return populated_sql; + return populate_tokens(sql, FLT_MAX, + box2d(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX), + 0, 0, mapnik::attributes{}, false); } std::string postgis_datasource::populate_tokens( @@ -596,43 +540,66 @@ std::string postgis_datasource::populate_tokens( box2d const& env, double pixel_width, double pixel_height, - mapnik::attributes const& vars) const + mapnik::attributes const& vars, + bool intersect) const { - std::string populated_sql = sql; - std::string box = sql_bbox(env); + std::ostringstream populated_sql; + std::cmatch m; + char const* start = sql.data(); + char const* end = start + sql.size(); - if (boost::algorithm::icontains(populated_sql, scale_denom_token_)) + while (std::regex_search(start, end, m, re_tokens_)) { - std::ostringstream ss; - ss << scale_denom; - boost::algorithm::replace_all(populated_sql, scale_denom_token_, ss.str()); + populated_sql.write(start, m[0].first - start); + start = m[0].second; + + auto m1 = boost::make_iterator_range(m[1].first, m[1].second); + if (m1.front() == '@') + { + std::string var_name(m1.begin() + 1, m1.end()); + auto itr = vars.find(var_name); + if (itr != vars.end()) + { + auto var_value = itr->second.to_string(); + populated_sql << literal(var_value); + } + else + { + populated_sql << "NULL"; // undefined @variable + } + } + else if (boost::algorithm::equals(m1, "bbox")) + { + populated_sql << sql_bbox(env); + intersect = false; + } + else if (boost::algorithm::equals(m1, "pixel_height")) + { + populated_sql << pixel_height; + } + else if (boost::algorithm::equals(m1, "pixel_width")) + { + populated_sql << pixel_width; + } + else if (boost::algorithm::equals(m1, "scale_denominator")) + { + populated_sql << scale_denom; + } + else + { + populated_sql << "NULL"; // unrecognized !token! + } } - if (boost::algorithm::icontains(sql, pixel_width_token_)) - { - std::ostringstream ss; - ss << pixel_width; - boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str()); - } + populated_sql.write(start, end - start); - if (boost::algorithm::icontains(sql, pixel_height_token_)) + if (intersect) { - std::ostringstream ss; - ss << pixel_height; - boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str()); - } - - if (boost::algorithm::icontains(populated_sql, bbox_token_)) - { - boost::algorithm::replace_all(populated_sql, bbox_token_, box); - } - else - { - std::ostringstream s; - if (intersect_min_scale_ > 0 && (scale_denom <= intersect_min_scale_)) { - s << " WHERE ST_Intersects(\"" << geometryColumn_ << "\"," << box << ")"; + populated_sql << " WHERE ST_Intersects(" + << identifier(geometryColumn_) << ", " + << sql_bbox(env) << ")"; } else if (intersect_max_scale_ > 0 && (scale_denom >= intersect_max_scale_)) { @@ -640,31 +607,34 @@ std::string postgis_datasource::populate_tokens( } else { - s << " WHERE \"" << geometryColumn_ << "\" && " << box; - } - populated_sql += s.str(); - } - std::string copy2 = populated_sql; - std::list l; - boost::regex_split(std::back_inserter(l), copy2, pattern_); - if (!l.empty()) - { - for (auto const & token: l) - { - auto itr = vars.find(token.substr(1,std::string::npos)); - if (itr != vars.end()) - { - boost::algorithm::replace_all(populated_sql, token, itr->second.to_string()); - } - else - { - boost::algorithm::replace_all(populated_sql, token, "null"); - } + populated_sql << " WHERE " + << identifier(geometryColumn_) << " && " + << sql_bbox(env); } } - return populated_sql; + + return populated_sql.str(); } +void postgis_datasource::append_geometry_table(std::ostream & os) const +{ + if (!geometry_table_.empty()) + { + os << geometry_table_; // assume datasource parameter is valid SQL + } + else if (!parsed_schema_.empty()) + { + os << identifier(parsed_schema_) << '.' << identifier(parsed_table_); + } + else if (!parsed_table_.empty()) + { + os << identifier(parsed_table_); + } + else + { + os << table_; // assume datasource parameter is valid SQL + } +} std::shared_ptr postgis_datasource::get_resultset(std::shared_ptr &conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx) const { @@ -789,20 +759,11 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo { std::ostringstream s_error; s_error << "PostGIS: geometry name lookup failed for table '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ - << "'. Please manually provide the 'geometry_field' parameter or add an entry " + append_geometry_table(s_error); + s_error << "'. Please manually provide the 'geometry_field' parameter or add an entry " << "in the geometry_columns for '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ << "'."; + append_geometry_table(s_error); + s_error << "'."; throw mapnik::datasource_exception(s_error.str()); } @@ -833,7 +794,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo { s << "ST_ClipByBox2D("; } - s << "\"" << geometryColumn_ << "\""; + s << identifier(geometryColumn_); // ! ST_ClipByBox2D() if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz) @@ -865,7 +826,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo } // Geometry column! - s << "\"" << geometryColumn_ << "\""; + s << identifier(geometryColumn_); // ! ST_SnapToGrid() if (simplify_geometries_ && simplify_snap_ratio_ > 0.0) @@ -903,7 +864,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo if (! key_field_.empty()) { - mapnik::sql_utils::quote_attr(s, key_field_); + s << ',' << identifier(key_field_); if (key_field_as_attribute_) { ctx->push(key_field_); @@ -913,7 +874,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo { if (*pos != key_field_) { - mapnik::sql_utils::quote_attr(s, *pos); + s << ',' << identifier(*pos); ctx->push(*pos); } } @@ -922,7 +883,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo { for (; pos != end; ++pos) { - mapnik::sql_utils::quote_attr(s, *pos); + s << ',' << identifier(*pos); ctx->push(*pos); } } @@ -963,33 +924,25 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t { std::ostringstream s_error; s_error << "PostGIS: geometry name lookup failed for table '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ - << "'. Please manually provide the 'geometry_field' parameter or add an entry " + append_geometry_table(s_error); + s_error << "'. Please manually provide the 'geometry_field' parameter or add an entry " << "in the geometry_columns for '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ << "'."; + append_geometry_table(s_error); + s_error << "'."; throw mapnik::datasource_exception(s_error.str()); } std::ostringstream s; - s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom"; + s << "SELECT ST_AsBinary(" << identifier(geometryColumn_) + << ") AS geom"; mapnik::context_ptr ctx = std::make_shared(); auto const& desc = desc_.get_descriptors(); if (!key_field_.empty()) { - mapnik::sql_utils::quote_attr(s, key_field_); + s << ',' << identifier(key_field_); if (key_field_as_attribute_) { ctx->push(key_field_); @@ -999,7 +952,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t std::string const& name = attr_info.get_name(); if (name != key_field_) { - mapnik::sql_utils::quote_attr(s, name); + s << ',' << identifier(name); ctx->push(name); } } @@ -1009,13 +962,14 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t for (auto const& attr_info : desc) { std::string const& name = attr_info.get_name(); - mapnik::sql_utils::quote_attr(s, name); + s << ',' << identifier(name); ctx->push(name); } } box2d box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol); - std::string table_with_bbox = populate_tokens(table_, FMAX, box, 0, 0, mapnik::attributes()); + std::string table_with_bbox = populate_tokens(table_, FLT_MAX, box, 0, 0, + mapnik::attributes{}); s << " FROM " << table_with_bbox; @@ -1053,12 +1007,8 @@ box2d postgis_datasource::envelope() const { std::ostringstream s_error; s_error << "PostGIS: unable to query the layer extent of table '"; - - if (! schema_.empty()) - { - s_error << schema_ << "."; - } - s_error << geometry_table_ << "' because we cannot determine the geometry field name." + append_geometry_table(s_error); + s_error << "' because we cannot determine the geometry field name." << "\nPlease provide either an 'extent' parameter to skip this query, " << "a 'geometry_field' and/or 'geometry_table' parameter, or add a " << "record to the 'geometry_columns' for your table."; @@ -1069,20 +1019,20 @@ box2d postgis_datasource::envelope() const if (estimate_extent_) { s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)" - << " FROM (SELECT ST_Estimated_Extent('"; - - if (! schema_.empty()) + << " FROM (SELECT ST_EstimatedExtent('"; + if (!parsed_schema_.empty()) { - s << mapnik::sql_utils::unquote_double(schema_) << "','"; + s << literal(parsed_schema_) << ','; } - s << mapnik::sql_utils::unquote_double(geometry_table_) << "','" - << mapnik::sql_utils::unquote_double(geometryColumn_) << "') as ext) as tmp"; + s << literal(parsed_table_) << ',' + << literal(geometryColumn_) << ") as ext) as tmp"; } else { s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)" - << " FROM (SELECT ST_Extent(" < postgis_datasource::envelope() const } else { - if (! schema_.empty()) - { - s << schema_ << "."; - } - // but if the subquery does not limit records then querying the // actual table will be faster as indexes can be used - s << geometry_table_ << ") as tmp"; + append_geometry_table(s); + s << ") as tmp"; } } @@ -1142,21 +1088,15 @@ boost::optional postgis_datasource::get_geometry_ std::string g_type; try { - s << "SELECT lower(type) as type FROM " - << GEOMETRY_COLUMNS <<" WHERE f_table_name='" - << mapnik::sql_utils::unquote_double(geometry_table_) - << "'"; - if (! schema_.empty()) + s << "SELECT lower(type) as type FROM " << GEOMETRY_COLUMNS + << " WHERE f_table_name=" << literal(parsed_table_); + if (!parsed_schema_.empty()) { - s << " AND f_table_schema='" - << mapnik::sql_utils::unquote_double(schema_) - << "'"; + s << " AND f_table_schema=" << literal(parsed_schema_); } - if (! geometry_field_.empty()) + if (!geometryColumn_.empty()) { - s << " AND f_geometry_column='" - << mapnik::sql_utils::unquote_double(geometry_field_) - << "'"; + s << " AND f_geometry_column=" << literal(geometryColumn_); } shared_ptr rs = conn->executeQuery(s.str()); if (rs->next()) @@ -1195,8 +1135,8 @@ boost::optional postgis_datasource::get_geometry_ std::string prev_type(""); - s << "SELECT ST_GeometryType(\"" - << geometryColumn_ << "\") AS geom" + s << "SELECT ST_GeometryType(" + << identifier(geometryColumn_) << ") AS geom" << " FROM " << populate_tokens(table_); if (row_limit_ > 0 && row_limit_ < 5) diff --git a/plugins/input/postgis/postgis_datasource.hpp b/plugins/input/postgis/postgis_datasource.hpp index 80ba89495..636ccd4e8 100644 --- a/plugins/input/postgis/postgis_datasource.hpp +++ b/plugins/input/postgis/postgis_datasource.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 @@ -28,19 +28,19 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include // boost #include -#include // stl #include +#include #include #include @@ -84,20 +84,22 @@ private: box2d const& env, double pixel_width, double pixel_height, - mapnik::attributes const& vars) const; + mapnik::attributes const& vars, + bool intersect = true) const; std::string populate_tokens(std::string const& sql) const; + void append_geometry_table(std::ostream & os) const; std::shared_ptr get_resultset(std::shared_ptr &conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx= processor_context_ptr()) const; static const std::string GEOMETRY_COLUMNS; static const std::string SPATIAL_REF_SYS; - static const double FMAX; const std::string uri_; const std::string username_; const std::string password_; const std::string table_; - std::string schema_; - std::string geometry_table_; + const std::string geometry_table_; const std::string geometry_field_; + std::string parsed_schema_; + std::string parsed_table_; std::string key_field_; mapnik::value_integer cursor_fetch_size_; mapnik::value_integer row_limit_; @@ -109,10 +111,6 @@ private: bool simplify_geometries_; layer_descriptor desc_; ConnectionCreator creator_; - const std::string bbox_token_; - const std::string scale_denom_token_; - const std::string pixel_width_token_; - const std::string pixel_height_token_; int pool_max_size_; bool persist_connection_; bool extent_from_subquery_; @@ -126,7 +124,7 @@ private: mapnik::value_double simplify_prefilter_; bool simplify_dp_preserve_; mapnik::value_double simplify_clip_resolution_; - boost::regex pattern_; + std::regex re_tokens_; int intersect_min_scale_; int intersect_max_scale_; bool key_field_as_attribute_; diff --git a/plugins/input/postgis/postgis_featureset.cpp b/plugins/input/postgis/postgis_featureset.cpp index 25e2b6b4b..d0eed531a 100644 --- a/plugins/input/postgis/postgis_featureset.cpp +++ b/plugins/input/postgis/postgis_featureset.cpp @@ -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,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/postgis/postgis_featureset.hpp b/plugins/input/postgis/postgis_featureset.hpp index 9ef8cb392..53b961c8a 100644 --- a/plugins/input/postgis/postgis_featureset.hpp +++ b/plugins/input/postgis/postgis_featureset.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 @@ -24,7 +24,7 @@ #define POSTGIS_FEATURESET_HPP // mapnik -#include +#include #include #include #include diff --git a/plugins/input/postgis/resultset.hpp b/plugins/input/postgis/resultset.hpp index 915a5962d..dbbc8771b 100644 --- a/plugins/input/postgis/resultset.hpp +++ b/plugins/input/postgis/resultset.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 diff --git a/plugins/input/raster/raster_datasource.cpp b/plugins/input/raster/raster_datasource.cpp index e059247cd..cfdfccda7 100644 --- a/plugins/input/raster/raster_datasource.cpp +++ b/plugins/input/raster/raster_datasource.cpp @@ -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 diff --git a/plugins/input/raster/raster_datasource.hpp b/plugins/input/raster/raster_datasource.hpp index 7ff099086..cd2149c88 100644 --- a/plugins/input/raster/raster_datasource.hpp +++ b/plugins/input/raster/raster_datasource.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/plugins/input/raster/raster_featureset.cpp b/plugins/input/raster/raster_featureset.cpp index 26cac964f..4a4cf441e 100644 --- a/plugins/input/raster/raster_featureset.cpp +++ b/plugins/input/raster/raster_featureset.cpp @@ -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 diff --git a/plugins/input/raster/raster_featureset.hpp b/plugins/input/raster/raster_featureset.hpp index 007689275..1b0b0222a 100644 --- a/plugins/input/raster/raster_featureset.hpp +++ b/plugins/input/raster/raster_featureset.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 diff --git a/plugins/input/raster/raster_info.cpp b/plugins/input/raster/raster_info.cpp index 54b17c412..984eb59b6 100644 --- a/plugins/input/raster/raster_info.cpp +++ b/plugins/input/raster/raster_info.cpp @@ -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 @@ -44,7 +44,7 @@ raster_info::raster_info(const raster_info& rhs) { } -void raster_info::swap(raster_info& other) //throw() +void raster_info::swap(raster_info& other) { std::swap(file_,other.file_); std::swap(format_,other.format_); diff --git a/plugins/input/raster/raster_info.hpp b/plugins/input/raster/raster_info.hpp index f0208425a..356d4193d 100644 --- a/plugins/input/raster/raster_info.hpp +++ b/plugins/input/raster/raster_info.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 diff --git a/plugins/input/shape/dbf_test.cpp b/plugins/input/shape/dbf_test.cpp index c5e22f576..5c37bf293 100644 --- a/plugins/input/shape/dbf_test.cpp +++ b/plugins/input/shape/dbf_test.cpp @@ -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 diff --git a/plugins/input/shape/dbfile.cpp b/plugins/input/shape/dbfile.cpp index d64d37384..3da607417 100644 --- a/plugins/input/shape/dbfile.cpp +++ b/plugins/input/shape/dbfile.cpp @@ -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,7 +20,7 @@ * *****************************************************************************/ // mapnik -#include +#include #include #include #include @@ -30,7 +30,7 @@ #pragma GCC diagnostic push #include -#include +#include #if defined(MAPNIK_MEMORY_MAPPED_FILE) #include #include @@ -137,7 +137,7 @@ const field_descriptor& dbf_file::descriptor(int col) const } -void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const throw() +void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const { using namespace boost::spirit; @@ -187,9 +187,9 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feat double val = 0.0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; - ascii::space_type space; - static qi::double_type double_; - if (qi::phrase_parse(itr,end,double_,space,val)) + x3::ascii::space_type space; + static x3::double_type double_; + if (x3::phrase_parse(itr,end,double_,space,val)) { f.put(name,val); } @@ -199,9 +199,9 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feat mapnik::value_integer val = 0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; - ascii::space_type space; - static qi::int_parser numeric_parser; - if (qi::phrase_parse(itr, end, numeric_parser, space, val)) + x3::ascii::space_type space; + static x3::int_parser numeric_parser; + if (x3::phrase_parse(itr, end, numeric_parser, space, val)) { f.put(name,val); } diff --git a/plugins/input/shape/dbfile.hpp b/plugins/input/shape/dbfile.hpp index 9ff022400..fec46cc96 100644 --- a/plugins/input/shape/dbfile.hpp +++ b/plugins/input/shape/dbfile.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 @@ -77,7 +77,7 @@ public: field_descriptor const& descriptor(int col) const; void move_to(int index); std::string string_value(int col) const; - void add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const throw(); + void add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const; private: void read_header(); int read_short(); diff --git a/plugins/input/shape/shape_datasource.cpp b/plugins/input/shape/shape_datasource.cpp index 56d7a6aae..bc52acf50 100644 --- a/plugins/input/shape/shape_datasource.cpp +++ b/plugins/input/shape/shape_datasource.cpp @@ -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 @@ -40,7 +40,7 @@ #include #include #include -#include +#include // stl #include diff --git a/plugins/input/shape/shape_datasource.hpp b/plugins/input/shape/shape_datasource.hpp index f702036eb..ea3fb5c39 100644 --- a/plugins/input/shape/shape_datasource.hpp +++ b/plugins/input/shape/shape_datasource.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 @@ -28,10 +28,10 @@ #include #include #include -#include +#include #include #include -#include +#include // boost #include diff --git a/plugins/input/shape/shape_featureset.cpp b/plugins/input/shape/shape_featureset.cpp index 490fa3d5e..46e482d3d 100644 --- a/plugins/input/shape/shape_featureset.cpp +++ b/plugins/input/shape/shape_featureset.cpp @@ -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 diff --git a/plugins/input/shape/shape_featureset.hpp b/plugins/input/shape/shape_featureset.hpp index caa962554..b1f0b9f6f 100644 --- a/plugins/input/shape/shape_featureset.hpp +++ b/plugins/input/shape/shape_featureset.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "shape_io.hpp" diff --git a/plugins/input/shape/shape_index_featureset.cpp b/plugins/input/shape/shape_index_featureset.cpp index c4b1918d8..d32bcba78 100644 --- a/plugins/input/shape/shape_index_featureset.cpp +++ b/plugins/input/shape/shape_index_featureset.cpp @@ -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 diff --git a/plugins/input/shape/shape_index_featureset.hpp b/plugins/input/shape/shape_index_featureset.hpp index d104e0f20..660204a82 100644 --- a/plugins/input/shape/shape_index_featureset.hpp +++ b/plugins/input/shape/shape_index_featureset.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 @@ -31,7 +31,7 @@ #include #include #include -#include +#include // boost diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index b5d3776e4..cafa04a7d 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -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 @@ -27,7 +27,7 @@ #include #include #include -#include +#include using mapnik::datasource_exception; const std::string shape_io::SHP = ".shp"; diff --git a/plugins/input/shape/shape_io.hpp b/plugins/input/shape/shape_io.hpp index 1828ebd54..f85d7eed9 100644 --- a/plugins/input/shape/shape_io.hpp +++ b/plugins/input/shape/shape_io.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 @@ -27,7 +27,7 @@ #include #include // mapnik -#include +#include #include #include // boost diff --git a/plugins/input/shape/shape_utils.cpp b/plugins/input/shape/shape_utils.cpp index 40d8fc6c3..4a6c8acd1 100644 --- a/plugins/input/shape/shape_utils.cpp +++ b/plugins/input/shape/shape_utils.cpp @@ -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 diff --git a/plugins/input/shape/shape_utils.hpp b/plugins/input/shape/shape_utils.hpp index edb22225b..c77625e14 100644 --- a/plugins/input/shape/shape_utils.hpp +++ b/plugins/input/shape/shape_utils.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 diff --git a/plugins/input/shape/shapefile.hpp b/plugins/input/shape/shapefile.hpp index 15e5c7757..c00ffc3e4 100644 --- a/plugins/input/shape/shapefile.hpp +++ b/plugins/input/shape/shapefile.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 @@ -32,7 +32,7 @@ // mapnik #include #include -#include +#include #if defined(MAPNIK_MEMORY_MAPPED_FILE) #pragma GCC diagnostic push diff --git a/plugins/input/sqlite/sqlite_connection.hpp b/plugins/input/sqlite/sqlite_connection.hpp index c87086d78..bc3c0d89b 100644 --- a/plugins/input/sqlite/sqlite_connection.hpp +++ b/plugins/input/sqlite/sqlite_connection.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 diff --git a/plugins/input/sqlite/sqlite_datasource.cpp b/plugins/input/sqlite/sqlite_datasource.cpp index 28add6453..e76ef41bb 100644 --- a/plugins/input/sqlite/sqlite_datasource.cpp +++ b/plugins/input/sqlite/sqlite_datasource.cpp @@ -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 @@ -34,7 +34,7 @@ #include #include #include -#include +#include // boost #include diff --git a/plugins/input/sqlite/sqlite_datasource.hpp b/plugins/input/sqlite/sqlite_datasource.hpp index eab71e9e3..e73e0c3e8 100644 --- a/plugins/input/sqlite/sqlite_datasource.hpp +++ b/plugins/input/sqlite/sqlite_datasource.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 @@ -28,11 +28,11 @@ #include #include #include -#include +#include #include #include #include -#include +#include // boost #include diff --git a/plugins/input/sqlite/sqlite_featureset.cpp b/plugins/input/sqlite/sqlite_featureset.cpp index 99a44db54..9226f40d0 100644 --- a/plugins/input/sqlite/sqlite_featureset.cpp +++ b/plugins/input/sqlite/sqlite_featureset.cpp @@ -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 @@ -23,15 +23,15 @@ // mapnik #include #include -#include +#include #include #include #include #include -#include +#include #include -#include -#include +#include +#include // ogr #include "sqlite_featureset.hpp" diff --git a/plugins/input/sqlite/sqlite_featureset.hpp b/plugins/input/sqlite/sqlite_featureset.hpp index dc168676e..9e2f1c20a 100644 --- a/plugins/input/sqlite/sqlite_featureset.hpp +++ b/plugins/input/sqlite/sqlite_featureset.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 diff --git a/plugins/input/sqlite/sqlite_prepared.hpp b/plugins/input/sqlite/sqlite_prepared.hpp index db1355d67..9ddecbffd 100644 --- a/plugins/input/sqlite/sqlite_prepared.hpp +++ b/plugins/input/sqlite/sqlite_prepared.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 @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include // boost diff --git a/plugins/input/sqlite/sqlite_resultset.hpp b/plugins/input/sqlite/sqlite_resultset.hpp index 6046387f9..042e02d07 100644 --- a/plugins/input/sqlite/sqlite_resultset.hpp +++ b/plugins/input/sqlite/sqlite_resultset.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 diff --git a/plugins/input/sqlite/sqlite_utils.hpp b/plugins/input/sqlite/sqlite_utils.hpp index 959e3f7c6..235b9c035 100644 --- a/plugins/input/sqlite/sqlite_utils.hpp +++ b/plugins/input/sqlite/sqlite_utils.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 @@ -35,8 +35,8 @@ #include #include #include -#include -#include +#include +#include #pragma GCC diagnostic push #include diff --git a/plugins/input/topojson/topojson_datasource.cpp b/plugins/input/topojson/topojson_datasource.cpp index 67bae443b..8a16dd3e2 100644 --- a/plugins/input/topojson/topojson_datasource.cpp +++ b/plugins/input/topojson/topojson_datasource.cpp @@ -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 @@ -31,10 +31,10 @@ // mapnik #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -171,25 +171,27 @@ topojson_datasource::topojson_datasource(parameters const& params) } std::string file_buffer; file_buffer.resize(file.size()); - std::fread(&file_buffer[0], file.size(), 1, file.get()); - parse_topojson(file_buffer.c_str()); + auto count = std::fread(&file_buffer[0], file.size(), 1, file.get()); + if (count == 1) parse_topojson(file_buffer.c_str()); } } -namespace { -using iterator_type = const char*; -const mapnik::topojson::topojson_grammar g; -} - template void topojson_datasource::parse_topojson(T const& buffer) { - boost::spirit::standard::space_type space; auto itr = buffer; auto end = buffer + std::strlen(buffer); - bool result = boost::spirit::qi::phrase_parse(itr, end, g, space, topo_); - if (!result) + using space_type = boost::spirit::x3::standard::space_type; + try { + boost::spirit::x3::phrase_parse(itr, end, mapnik::json::topojson_grammar(), space_type(), topo_); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + std::clog << "failed to parse TopoJSON..." << std::endl; + std::clog << ex.what() << std::endl; + std::clog << "Expected: " << ex.which(); + std::clog << " Got: \"" << std::string(ex.where(), ex.where() + 200) << "...\"" << std::endl; throw mapnik::datasource_exception("topojson_datasource: Failed parse TopoJSON file '" + filename_ + "'"); } diff --git a/plugins/input/topojson/topojson_datasource.hpp b/plugins/input/topojson/topojson_datasource.hpp index ebc92aea2..c9b9165ae 100644 --- a/plugins/input/topojson/topojson_datasource.hpp +++ b/plugins/input/topojson/topojson_datasource.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 @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/topojson/topojson_featureset.cpp b/plugins/input/topojson/topojson_featureset.cpp index 36dbdf9db..2cad74123 100644 --- a/plugins/input/topojson/topojson_featureset.cpp +++ b/plugins/input/topojson/topojson_featureset.cpp @@ -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 diff --git a/plugins/input/topojson/topojson_featureset.hpp b/plugins/input/topojson/topojson_featureset.hpp index 44f833512..f767f0881 100644 --- a/plugins/input/topojson/topojson_featureset.hpp +++ b/plugins/input/topojson/topojson_featureset.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 diff --git a/scripts/travis-common.sh b/scripts/travis-common.sh index 56909b79d..d3ce79f10 100644 --- a/scripts/travis-common.sh +++ b/scripts/travis-common.sh @@ -46,15 +46,6 @@ git_submodule_update () { git submodule update "$@" } -# install and call pip -pip () { - if ! which pip >/dev/null; then - easy_install --user pip && \ - export PATH="$HOME/Library/Python/2.7/bin:$PATH" - fi - command pip "$@" -} - # commit_message_contains TEXT # - returns 0 (true) if TEXT is found in commit message # - case-insensitive, plain-text search, not regex @@ -83,22 +74,16 @@ config_override () { configure () { if enabled ${COVERAGE}; then ./configure "$@" PREFIX=${PREFIX} PGSQL2SQLITE=False SVG2PNG=False SVG_RENDERER=False \ - COVERAGE=True DEBUG=True WARNING_CXXFLAGS="-Wno-unknown-warning-option" + COVERAGE=True DEBUG=True else - ./configure "$@" PREFIX=${PREFIX} WARNING_CXXFLAGS="-Wno-unknown-warning-option" + ./configure "$@" PREFIX=${PREFIX} fi # print final config values, sorted and indented sort -sk1,1 ./config.py | sed -e 's/^/ /' } coverage () { - ./mason_packages/.link/bin/cpp-coveralls \ - --gcov ${LLVM_COV} \ - --exclude mason_packages \ - --exclude .sconf_temp --exclude benchmark --exclude deps \ - --exclude scons --exclude test --exclude demo --exclude docs \ - --exclude fonts \ - > /dev/null + ./codecov -x "llvm-cov gcov" -Z } trigger_downstream() { diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index dc2c21514..ed28335ef 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -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 @@ -41,8 +41,8 @@ #include #include #include -#include #include +#include #pragma GCC diagnostic push #include @@ -71,47 +71,44 @@ namespace mapnik template agg_renderer::agg_renderer(Map const& m, T0 & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y) : feature_style_processor(m, scale_factor), - pixmap_(pixmap), - internal_buffer_(), - current_buffer_(&pixmap), - style_level_compositing_(false), + buffers_(), + internal_buffers_(m.width(), m.height()), + inflated_buffer_(), ras_ptr(new rasterizer), gamma_method_(GAMMA_POWER), gamma_(1.0), common_(m, attributes(), offset_x, offset_y, m.width(), m.height(), scale_factor) { - setup(m); + setup(m, pixmap); } template agg_renderer::agg_renderer(Map const& m, request const& req, attributes const& vars, T0 & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y) : feature_style_processor(m, scale_factor), - pixmap_(pixmap), - internal_buffer_(), - current_buffer_(&pixmap), - style_level_compositing_(false), + buffers_(), + internal_buffers_(req.width(), req.height()), + inflated_buffer_(), ras_ptr(new rasterizer), gamma_method_(GAMMA_POWER), gamma_(1.0), common_(m, req, vars, offset_x, offset_y, req.width(), req.height(), scale_factor) { - setup(m); + setup(m, pixmap); } template agg_renderer::agg_renderer(Map const& m, T0 & pixmap, std::shared_ptr detector, double scale_factor, unsigned offset_x, unsigned offset_y) : feature_style_processor(m, scale_factor), - pixmap_(pixmap), - internal_buffer_(), - current_buffer_(&pixmap), - style_level_compositing_(false), + buffers_(), + internal_buffers_(m.width(), m.height()), + inflated_buffer_(), ras_ptr(new rasterizer), gamma_method_(GAMMA_POWER), gamma_(1.0), common_(m, attributes(), offset_x, offset_y, m.width(), m.height(), scale_factor, detector) { - setup(m); + setup(m, pixmap); } template @@ -157,9 +154,11 @@ struct setup_agg_bg_visitor }; template -void agg_renderer::setup(Map const &m) +void agg_renderer::setup(Map const &m, buffer_type & pixmap) { - mapnik::set_premultiplied_alpha(pixmap_, true); + buffers_.emplace(pixmap); + + mapnik::set_premultiplied_alpha(pixmap, true); boost::optional const& bg = m.background(); if (bg) { @@ -167,13 +166,13 @@ void agg_renderer::setup(Map const &m) { mapnik::color bg_color = *bg; bg_color.premultiply(); - mapnik::fill(pixmap_, bg_color); + mapnik::fill(pixmap, bg_color); } else { mapnik::color bg_color = *bg; bg_color.set_premultiplied(true); - mapnik::fill(pixmap_,bg_color); + mapnik::fill(pixmap, bg_color); } } @@ -182,7 +181,7 @@ void agg_renderer::setup(Map const &m) { // NOTE: marker_cache returns premultiplied image, if needed std::shared_ptr bg_marker = mapnik::marker_cache::instance().find(*image_filename,true); - setup_agg_bg_visitor visitor(pixmap_, + setup_agg_bg_visitor visitor(pixmap, common_, m.background_image_comp_op(), m.background_image_opacity()); @@ -204,7 +203,7 @@ void agg_renderer::start_map_processing(Map const& map) template void agg_renderer::end_map_processing(Map const& map) { - mapnik::demultiply_alpha(pixmap_); + mapnik::demultiply_alpha(buffers_.top().get()); MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End map processing"; } @@ -226,28 +225,44 @@ void agg_renderer::start_layer_processing(layer const& lay, box2d { common_.query_extent_.clip(*maximum_extent); } + + if (lay.comp_op() || lay.get_opacity() < 1.0) + { + buffers_.emplace(internal_buffers_.push()); + set_premultiplied_alpha(buffers_.top().get(), true); + } + else + { + buffers_.emplace(buffers_.top().get()); + } } template -void agg_renderer::end_layer_processing(layer const&) +void agg_renderer::end_layer_processing(layer const& lyr) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End layer processing"; + + buffer_type & current_buffer = buffers_.top().get(); + buffers_.pop(); + buffer_type & previous_buffer = buffers_.top().get(); + + if (¤t_buffer != &previous_buffer) + { + composite_mode_e comp_op = lyr.comp_op() ? *lyr.comp_op() : src_over; + composite(previous_buffer, current_buffer, + comp_op, lyr.get_opacity(), + -common_.t_.offset(), + -common_.t_.offset()); + internal_buffers_.pop(); + } } template void agg_renderer::start_style_processing(feature_type_style const& st) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Start processing style"; - if (st.comp_op() || st.image_filters().size() > 0 || st.get_opacity() < 1) - { - style_level_compositing_ = true; - } - else - { - style_level_compositing_ = false; - } - if (style_level_compositing_) + if (st.comp_op() || st.image_filters().size() > 0 || st.get_opacity() < 1) { if (st.image_filters_inflate()) { @@ -266,81 +281,81 @@ void agg_renderer::start_style_processing(feature_type_style const& st) unsigned target_width = common_.width_ + (offset * 2); unsigned target_height = common_.height_ + (offset * 2); ras_ptr->clip_box(-int(offset*2),-int(offset*2),target_width,target_height); - if (!internal_buffer_ || - (internal_buffer_->width() < target_width || - internal_buffer_->height() < target_height)) + if (!inflated_buffer_ || + (inflated_buffer_->width() < target_width || + inflated_buffer_->height() < target_height)) { - internal_buffer_ = std::make_shared(target_width,target_height); + inflated_buffer_ = std::make_unique(target_width, target_height); } else { - mapnik::fill(*internal_buffer_, 0); // fill with transparent colour + mapnik::fill(*inflated_buffer_, 0); // fill with transparent colour } + buffers_.emplace(*inflated_buffer_); } else { - if (!internal_buffer_) - { - internal_buffer_ = std::make_shared(common_.width_,common_.height_); - } - else - { - mapnik::fill(*internal_buffer_, 0); // fill with transparent colour - } + buffers_.emplace(internal_buffers_.push()); common_.t_.set_offset(0); ras_ptr->clip_box(0,0,common_.width_,common_.height_); } - current_buffer_ = internal_buffer_.get(); - set_premultiplied_alpha(*current_buffer_,true); + set_premultiplied_alpha(buffers_.top().get(), true); } else { common_.t_.set_offset(0); ras_ptr->clip_box(0,0,common_.width_,common_.height_); - current_buffer_ = &pixmap_; + buffers_.emplace(buffers_.top().get()); } } template void agg_renderer::end_style_processing(feature_type_style const& st) { - if (style_level_compositing_) + buffer_type & current_buffer = buffers_.top().get(); + buffers_.pop(); + buffer_type & previous_buffer = buffers_.top().get(); + if (¤t_buffer != &previous_buffer) { bool blend_from = false; if (st.image_filters().size() > 0) { blend_from = true; - mapnik::filter::filter_visitor visitor(*current_buffer_, common_.scale_factor_); + mapnik::filter::filter_visitor visitor(current_buffer, common_.scale_factor_); for (mapnik::filter::filter_type const& filter_tag : st.image_filters()) { util::apply_visitor(visitor, filter_tag); } - mapnik::premultiply_alpha(*current_buffer_); + mapnik::premultiply_alpha(current_buffer); } if (st.comp_op()) { - composite(pixmap_, *current_buffer_, + composite(previous_buffer, current_buffer, *st.comp_op(), st.get_opacity(), -common_.t_.offset(), -common_.t_.offset()); } else if (blend_from || st.get_opacity() < 1.0) { - composite(pixmap_, *current_buffer_, + composite(previous_buffer, current_buffer, src_over, st.get_opacity(), -common_.t_.offset(), -common_.t_.offset()); } + if (¤t_buffer == &internal_buffers_.top()) + { + internal_buffers_.pop(); + } } if (st.direct_image_filters().size() > 0) { // apply any 'direct' image filters - mapnik::filter::filter_visitor visitor(pixmap_, common_.scale_factor_); + mapnik::filter::filter_visitor visitor(previous_buffer, common_.scale_factor_); for (mapnik::filter::filter_type const& filter_tag : st.direct_image_filters()) { util::apply_visitor(visitor, filter_tag); } - mapnik::premultiply_alpha(pixmap_); + mapnik::premultiply_alpha(previous_buffer); } MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End processing style"; } @@ -349,7 +364,7 @@ template struct agg_render_marker_visitor { agg_render_marker_visitor(renderer_common & common, - buffer_type * current_buffer, + buffer_type & current_buffer, std::unique_ptr const& ras_ptr, gamma_method_enum & gamma_method, double & gamma, @@ -377,7 +392,6 @@ struct agg_render_marker_visitor using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; using renderer_base = agg::renderer_base; using renderer_type = agg::renderer_scanline_aa_solid; - using svg_attribute_type = agg::pod_bvector; ras_ptr_->reset(); if (gamma_method_ != GAMMA_POWER || gamma_ != 1.0) @@ -387,10 +401,10 @@ struct agg_render_marker_visitor gamma_ = 1.0; } agg::scanline_u8 sl; - agg::rendering_buffer buf(current_buffer_->bytes(), - current_buffer_->width(), - current_buffer_->height(), - current_buffer_->row_size()); + agg::rendering_buffer buf(current_buffer_.bytes(), + current_buffer_.width(), + current_buffer_.height(), + current_buffer_.row_size()); pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast(comp_op_)); renderer_base renb(pixf); @@ -436,10 +450,10 @@ struct agg_render_marker_visitor gamma_ = 1.0; } agg::scanline_u8 sl; - agg::rendering_buffer buf(current_buffer_->bytes(), - current_buffer_->width(), - current_buffer_->height(), - current_buffer_->row_size()); + agg::rendering_buffer buf(current_buffer_.bytes(), + current_buffer_.width(), + current_buffer_.height(), + current_buffer_.row_size()); pixfmt_comp_type pixf(buf); pixf.comp_op(static_cast(comp_op_)); renderer_base renb(pixf); @@ -454,7 +468,7 @@ struct agg_render_marker_visitor { double cx = 0.5 * width; double cy = 0.5 * height; - composite(*current_buffer_, marker.get_data(), + composite(current_buffer_, marker.get_data(), comp_op_, opacity_, std::floor(pos_.x - cx + .5), std::floor(pos_.y - cy + .5)); @@ -518,7 +532,7 @@ struct agg_render_marker_visitor private: renderer_common & common_; - buffer_type * current_buffer_; + buffer_type & current_buffer_; std::unique_ptr const& ras_ptr_; gamma_method_enum & gamma_method_; double & gamma_; @@ -537,7 +551,7 @@ void agg_renderer::render_marker(pixel_position const& pos, composite_mode_e comp_op) { agg_render_marker_visitor visitor(common_, - current_buffer_, + buffers_.top().get(), ras_ptr, gamma_method_, gamma_, @@ -551,23 +565,24 @@ void agg_renderer::render_marker(pixel_position const& pos, template bool agg_renderer::painted() { - return pixmap_.painted(); + return buffers_.top().get().painted(); } template void agg_renderer::painted(bool painted) { - pixmap_.painted(painted); + buffers_.top().get().painted(painted); } template void agg_renderer::debug_draw_box(box2d const& box, double x, double y, double angle) { - agg::rendering_buffer buf(current_buffer_->bytes(), - current_buffer_->width(), - current_buffer_->height(), - current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), + current_buffer.width(), + current_buffer.height(), + current_buffer.row_size()); debug_draw_box(buf, box, x, y, angle); } @@ -620,13 +635,13 @@ void agg_renderer::draw_geo_extent(box2d const& extent, mapnik::c unsigned rgba = color.rgba(); for (double x=x0; x +#include #pragma GCC diagnostic push #include @@ -61,7 +62,8 @@ void agg_renderer::process(building_symbolizer const& sym, using ren_base = agg::renderer_base; using renderer = agg::renderer_scanline_aa_solid; - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); agg::pixfmt_rgba32_pre pixf(buf); ren_base renb(pixf); diff --git a/src/agg/process_debug_symbolizer.cpp b/src/agg/process_debug_symbolizer.cpp index 137c2457d..7d0feed40 100644 --- a/src/agg/process_debug_symbolizer.cpp +++ b/src/agg/process_debug_symbolizer.cpp @@ -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 @@ -234,7 +234,7 @@ void agg_renderer::process(debug_symbolizer const& sym, if (mode == DEBUG_SYM_MODE_RINGS) { - RingRenderer renderer(*ras_ptr,*current_buffer_,common_.t_,prj_trans); + RingRenderer renderer(*ras_ptr, buffers_.top().get(), common_.t_, prj_trans); render_ring_visitor apply(renderer); mapnik::util::apply_visitor(apply,feature.get_geometry()); } @@ -242,13 +242,13 @@ void agg_renderer::process(debug_symbolizer const& sym, { for (auto const& n : *common_.detector_) { - draw_rect(pixmap_, n.get().box); + draw_rect(buffers_.top().get(), n.get().box); } } else if (mode == DEBUG_SYM_MODE_VERTEX) { using apply_vertex_mode = apply_vertex_mode; - apply_vertex_mode apply(pixmap_, common_.t_, prj_trans); + apply_vertex_mode apply(buffers_.top().get(), common_.t_, prj_trans); util::apply_visitor(geometry::vertex_processor(apply), feature.get_geometry()); } } diff --git a/src/agg/process_dot_symbolizer.cpp b/src/agg/process_dot_symbolizer.cpp index cfb58c6e9..7f5291806 100644 --- a/src/agg/process_dot_symbolizer.cpp +++ b/src/agg/process_dot_symbolizer.cpp @@ -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 @@ -119,7 +119,8 @@ void agg_renderer::process(dot_symbolizer const& sym, gamma_method_ = GAMMA_POWER; gamma_ = 1.0; } - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(),current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); using blender_type = agg::comp_op_adaptor_rgba_pre; using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; using renderer_base = agg::renderer_base; diff --git a/src/agg/process_group_symbolizer.cpp b/src/agg/process_group_symbolizer.cpp index 6ba5605dc..486d714f2 100644 --- a/src/agg/process_group_symbolizer.cpp +++ b/src/agg/process_group_symbolizer.cpp @@ -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 @@ -61,10 +61,10 @@ struct thunk_renderer : render_thunk_list_dispatch thunk_renderer(renderer_type &ren, std::unique_ptr const& ras_ptr, - buffer_type *buf, + buffer_type & buf, renderer_common &common) : ren_(ren), ras_ptr_(ras_ptr), buf_(buf), common_(common), - tex_(*buf, HALO_RASTERIZER_FULL, src_over, src_over, + tex_(buf, HALO_RASTERIZER_FULL, src_over, src_over, common.scale_factor_, common.font_manager_.get_stroker()) {} @@ -75,13 +75,12 @@ struct thunk_renderer : render_thunk_list_dispatch using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; using renderer_base = agg::renderer_base; using renderer_type = agg::renderer_scanline_aa_solid; - using svg_attribute_type = agg::pod_bvector; using svg_renderer_type = svg::svg_renderer_agg; ras_ptr_->reset(); - buf_type render_buffer(buf_->bytes(), buf_->width(), buf_->height(), buf_->row_size()); + buf_type render_buffer(buf_.bytes(), buf_.width(), buf_.height(), buf_.row_size()); pixfmt_comp_type pixf(render_buffer); pixf.comp_op(static_cast(thunk.comp_op_)); renderer_base renb(pixf); @@ -102,7 +101,7 @@ struct thunk_renderer : render_thunk_list_dispatch using renderer_base = agg::renderer_base; ras_ptr_->reset(); - buf_type render_buffer(buf_->bytes(), buf_->width(), buf_->height(), buf_->row_size()); + buf_type render_buffer(buf_.bytes(), buf_.width(), buf_.height(), buf_.row_size()); pixfmt_comp_type pixf(render_buffer); pixf.comp_op(static_cast(thunk.comp_op_)); renderer_base renb(pixf); @@ -136,7 +135,7 @@ struct thunk_renderer : render_thunk_list_dispatch private: renderer_type &ren_; std::unique_ptr const& ras_ptr_; - buffer_type *buf_; + buffer_type & buf_; renderer_common &common_; text_renderer_type tex_; }; @@ -146,7 +145,7 @@ void agg_renderer::process(group_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { - thunk_renderer ren(*this, ras_ptr, current_buffer_, common_); + thunk_renderer ren(*this, ras_ptr, buffers_.top().get(), common_); render_group_symbolizer( sym, feature, common_.vars_, prj_trans, clipping_extent(common_), common_, diff --git a/src/agg/process_line_pattern_symbolizer.cpp b/src/agg/process_line_pattern_symbolizer.cpp index dbbb7f26d..5e304cb8f 100644 --- a/src/agg/process_line_pattern_symbolizer.cpp +++ b/src/agg/process_line_pattern_symbolizer.cpp @@ -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 @@ -61,14 +61,12 @@ template struct agg_renderer_process_visitor_l { agg_renderer_process_visitor_l(renderer_common & common, - buffer_type & pixmap, - buffer_type * current_buffer, + buffer_type & current_buffer, std::unique_ptr const& ras_ptr, line_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) : common_(common), - pixmap_(pixmap), current_buffer_(current_buffer), ras_ptr_(ras_ptr), sym_(sym), @@ -79,83 +77,26 @@ struct agg_renderer_process_visitor_l void operator() (marker_svg const& marker) const { - using color = agg::rgba8; - using order = agg::order_rgba; - using blender_type = agg::comp_op_adaptor_rgba_pre; - using pattern_filter_type = agg::pattern_filter_bilinear_rgba8; - using pattern_type = agg::line_image_pattern; - using pixfmt_type = agg::pixfmt_custom_blend_rgba; - using renderer_base = agg::renderer_base; - using renderer_type = agg::renderer_outline_image; - using rasterizer_type = agg::rasterizer_outline_aa; - - value_double opacity = get(sym_, feature_, common_.vars_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); auto image_transform = get_optional(sym_, keys::image_transform); if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_); mapnik::box2d const& bbox_image = marker.get_data()->bounding_box() * image_tr; image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern(*ras_ptr_, marker, image_tr, 1.0, image); - - value_bool clip = get(sym_, feature_, common_.vars_); - value_double offset = get(sym_, feature_, common_.vars_); - value_double simplify_tolerance = get(sym_, feature_, common_.vars_); - value_double smooth = get(sym_, feature_, common_.vars_); - - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size()); - pixfmt_type pixf(buf); - pixf.comp_op(static_cast(get(sym_, feature_, common_.vars_))); - renderer_base ren_base(pixf); - agg::pattern_filter_bilinear_rgba8 filter; - - pattern_source source(image, opacity); - pattern_type pattern (filter,source); - renderer_type ren(ren_base, pattern); - double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0); - int rast_clip_padding = static_cast(std::round(half_stroke)); - ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding); - rasterizer_type ras(ren); - - agg::trans_affine tr; - auto transform = get_optional(sym_, keys::geometry_transform); - if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_); - - box2d clip_box = clipping_extent(common_); - if (clip) - { - double padding = (double)(common_.query_extent_.width()/pixmap_.width()); - if (half_stroke > 1) - padding *= half_stroke; - if (std::fabs(offset) > 0) - padding *= std::fabs(offset) * 1.2; - padding *= common_.scale_factor_; - clip_box.pad(padding); - } - using vertex_converter_type = vertex_converter; - - vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_); - - if (clip) converter.set(); - converter.set(); //always transform - if (simplify_tolerance > 0.0) converter.set(); // optional simplify converter - if (std::fabs(offset) > 0.0) converter.set(); // parallel offset - converter.set(); // optional affine transform - if (smooth > 0.0) converter.set(); // optional smooth converter - - using apply_vertex_converter_type = detail::apply_vertex_converter; - using vertex_processor_type = geometry::vertex_processor; - apply_vertex_converter_type apply(converter, ras); - mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry()); + render(image, marker.width(), marker.height()); } void operator() (marker_rgba8 const& marker) const { - using color = agg::rgba8; + render(marker.get_data(), marker.width(), marker.height()); + } + +private: + void render(mapnik::image_rgba8 const& marker, double width, double height) const + { + using col = agg::rgba8; using order = agg::order_rgba; - using blender_type = agg::comp_op_adaptor_rgba_pre; + using blender_type = agg::comp_op_adaptor_rgba_pre; using pattern_filter_type = agg::pattern_filter_bilinear_rgba8; using pattern_type = agg::line_image_pattern; using pixfmt_type = agg::pixfmt_custom_blend_rgba; @@ -164,24 +105,22 @@ struct agg_renderer_process_visitor_l using rasterizer_type = agg::rasterizer_outline_aa; value_double opacity = get(sym_, feature_, common_.vars_); - mapnik::image_rgba8 const& image = marker.get_data(); - value_bool clip = get(sym_, feature_, common_.vars_); value_double offset = get(sym_, feature_, common_.vars_); value_double simplify_tolerance = get(sym_, feature_, common_.vars_); value_double smooth = get(sym_, feature_, common_.vars_); - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(), - current_buffer_->height(), current_buffer_->row_size()); + agg::rendering_buffer buf(current_buffer_.bytes(), current_buffer_.width(), + current_buffer_.height(), current_buffer_.row_size()); pixfmt_type pixf(buf); pixf.comp_op(static_cast(get(sym_, feature_, common_.vars_))); renderer_base ren_base(pixf); agg::pattern_filter_bilinear_rgba8 filter; - pattern_source source(image, opacity); + pattern_source source(marker, opacity); pattern_type pattern (filter,source); renderer_type ren(ren_base, pattern); - double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0); + double half_stroke = std::max(width / 2.0, height / 2.0); int rast_clip_padding = static_cast(std::round(half_stroke)); ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding); rasterizer_type ras(ren); @@ -193,7 +132,7 @@ struct agg_renderer_process_visitor_l box2d clip_box = clipping_extent(common_); if (clip) { - double padding = (double)(common_.query_extent_.width()/pixmap_.width()); + double padding = (double)(common_.query_extent_.width() / common_.width_); if (half_stroke > 1) padding *= half_stroke; if (std::fabs(offset) > 0) @@ -221,10 +160,8 @@ struct agg_renderer_process_visitor_l mapnik::util::apply_visitor(vertex_processor_type(apply), feature_.get_geometry()); } - private: renderer_common & common_; - buffer_type & pixmap_; - buffer_type * current_buffer_; + buffer_type & current_buffer_; std::unique_ptr const& ras_ptr_; line_pattern_symbolizer const& sym_; mapnik::feature_impl & feature_; @@ -249,8 +186,7 @@ void agg_renderer::process(line_pattern_symbolizer const& sym, } std::shared_ptr marker = marker_cache::instance().find(filename, true); agg_renderer_process_visitor_l visitor(common_, - pixmap_, - current_buffer_, + buffers_.top().get(), ras_ptr, sym, feature, diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index 9bace2539..5d8ebf073 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -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 @@ -31,7 +31,7 @@ #include #include #include -#include +#include #pragma GCC diagnostic push #include @@ -112,7 +112,8 @@ void agg_renderer::process(line_symbolizer const& sym, gamma_ = gamma; } - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); using color_type = agg::rgba8; using order_type = agg::order_rgba; @@ -139,7 +140,7 @@ void agg_renderer::process(line_symbolizer const& sym, line_rasterizer_enum rasterizer_e = get(sym, feature, common_.vars_); if (clip) { - double padding = static_cast(common_.query_extent_.width()/pixmap_.width()); + double padding = static_cast(common_.query_extent_.width() / common_.width_); double half_stroke = 0.5 * width; if (half_stroke > 1) { diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 3fc122dcb..8546f042b 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -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 @@ -56,7 +56,6 @@ struct agg_markers_renderer_context : markers_renderer_context { using renderer_base = typename SvgRenderer::renderer_base; using vertex_source_type = typename SvgRenderer::vertex_source_type; - using attribute_source_type = typename SvgRenderer::attribute_source_type; using pixfmt_type = typename renderer_base::pixfmt_type; agg_markers_renderer_context(symbolizer_base const& sym, @@ -117,7 +116,6 @@ void agg_renderer::process(markers_symbolizer const& sym, using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; using renderer_base = agg::renderer_base; using renderer_type = agg::renderer_scanline_aa_solid; - using svg_attribute_type = agg::pod_bvector; using svg_renderer_type = svg_renderer_agg::process(markers_symbolizer const& sym, gamma_ = gamma; } - buf_type render_buffer(current_buffer_->bytes(), current_buffer_->width(), current_buffer_->height(), current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + buf_type render_buffer(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); box2d clip_box = clipping_extent(common_); - using context_type = detail::agg_markers_renderer_context; - context_type renderer_context(sym, feature, common_.vars_, render_buffer, *ras_ptr); + renderer_context_type renderer_context(sym, feature, common_.vars_, render_buffer, *ras_ptr); render_markers_symbolizer( sym, feature, prj_trans, common_, clip_box, renderer_context); diff --git a/src/agg/process_point_symbolizer.cpp b/src/agg/process_point_symbolizer.cpp index bb54db51c..2ed9675ab 100644 --- a/src/agg/process_point_symbolizer.cpp +++ b/src/agg/process_point_symbolizer.cpp @@ -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 diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp index f2a0159d1..935e5294a 100644 --- a/src/agg/process_polygon_pattern_symbolizer.cpp +++ b/src/agg/process_polygon_pattern_symbolizer.cpp @@ -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 @@ -62,7 +62,7 @@ template struct agg_renderer_process_visitor_p { agg_renderer_process_visitor_p(renderer_common & common, - buffer_type * current_buffer, + buffer_type & current_buffer, std::unique_ptr const& ras_ptr, gamma_method_enum & gamma_method, double & gamma, @@ -88,125 +88,19 @@ struct agg_renderer_process_visitor_p mapnik::box2d const& bbox_image = marker.get_data()->bounding_box() * image_tr; mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern(*ras_ptr_, marker, image_tr, 1.0, image); - - agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(), - current_buffer_->height(), current_buffer_->row_size()); - ras_ptr_->reset(); - value_double gamma = get(sym_, feature_, common_.vars_); - gamma_method_enum gamma_method = get(sym_, feature_, common_.vars_); - if (gamma != gamma_ || gamma_method != gamma_method_) - { - set_gamma_method(ras_ptr_, gamma, gamma_method); - gamma_method_ = gamma_method; - gamma_ = gamma; - } - - value_bool clip = get(sym_, feature_, common_.vars_); - value_double opacity = get(sym_, feature_, common_.vars_); - value_double simplify_tolerance = get(sym_, feature_, common_.vars_); - value_double smooth = get(sym_, feature_, common_.vars_); - - box2d clip_box = clipping_extent(common_); - - using color = agg::rgba8; - using order = agg::order_rgba; - using blender_type = agg::comp_op_adaptor_rgba_pre; - using pixfmt_type = agg::pixfmt_custom_blend_rgba; - - using wrap_x_type = agg::wrap_mode_repeat; - using wrap_y_type = agg::wrap_mode_repeat; - using img_source_type = agg::image_accessor_wrap; - - using span_gen_type = agg::span_pattern_rgba; - using ren_base = agg::renderer_base; - - using renderer_type = agg::renderer_scanline_aa_alpha, - span_gen_type>; - - pixfmt_type pixf(buf); - pixf.comp_op(static_cast(get(sym_, feature_, common_.vars_))); - ren_base renb(pixf); - - unsigned w = image.width(); - unsigned h = image.height(); - agg::rendering_buffer pattern_rbuf((agg::int8u*)image.bytes(),w,h,w*4); - agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf); - img_source_type img_src(pixf_pattern); - - pattern_alignment_enum alignment = get(sym_, feature_, common_.vars_); - unsigned offset_x=0; - unsigned offset_y=0; - - if (alignment == LOCAL_ALIGNMENT) - { - double x0 = 0; - double y0 = 0; - using apply_local_alignment = detail::apply_local_alignment; - apply_local_alignment apply(common_.t_,prj_trans_, clip_box, x0, y0); - util::apply_visitor(geometry::vertex_processor(apply), feature_.get_geometry()); - offset_x = unsigned(current_buffer_->width() - x0); - offset_y = unsigned(current_buffer_->height() - y0); - } - - span_gen_type sg(img_src, offset_x, offset_y); - - agg::span_allocator sa; - renderer_type rp(renb,sa, sg, unsigned(opacity * 255)); - - agg::trans_affine tr; - auto transform = get_optional(sym_, keys::geometry_transform); - if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_); - using vertex_converter_type = vertex_converter; - - vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_); - - - if (prj_trans_.equal() && clip) converter.set(); - converter.set(); //always transform - converter.set(); // optional affine transform - if (simplify_tolerance > 0.0) converter.set(); // optional simplify converter - if (smooth > 0.0) converter.set(); // optional smooth converter - - using apply_vertex_converter_type = detail::apply_vertex_converter; - using vertex_processor_type = geometry::vertex_processor; - apply_vertex_converter_type apply(converter, *ras_ptr_); - mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry()); - agg::scanline_u8 sl; - ras_ptr_->filling_rule(agg::fill_even_odd); - agg::render_scanlines(*ras_ptr_, sl, rp); + render(image); } void operator() (marker_rgba8 const& marker) const { - using color = agg::rgba8; - using order = agg::order_rgba; - using blender_type = agg::comp_op_adaptor_rgba_pre; - using pixfmt_type = agg::pixfmt_custom_blend_rgba; + render(marker.get_data()); + } - using wrap_x_type = agg::wrap_mode_repeat; - using wrap_y_type = agg::wrap_mode_repeat; - using img_source_type = agg::image_accessor_wrap; - - using span_gen_type = agg::span_pattern_rgba; - using ren_base = agg::renderer_base; - - using renderer_type = agg::renderer_scanline_aa_alpha, - span_gen_type>; - mapnik::image_rgba8 const& image = marker.get_data(); - - - agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(), - current_buffer_->height(), current_buffer_->row_size()); +private: + void render(mapnik::image_rgba8 const& image) const + { + agg::rendering_buffer buf(current_buffer_.bytes(), current_buffer_.width(), + current_buffer_.height(), current_buffer_.row_size()); ras_ptr_->reset(); value_double gamma = get(sym_, feature_, common_.vars_); gamma_method_enum gamma_method = get(sym_, feature_, common_.vars_); @@ -224,6 +118,23 @@ struct agg_renderer_process_visitor_p box2d clip_box = clipping_extent(common_); + using col = agg::rgba8; + using order = agg::order_rgba; + using blender_type = agg::comp_op_adaptor_rgba_pre; + using pixfmt_type = agg::pixfmt_custom_blend_rgba; + + using wrap_x_type = agg::wrap_mode_repeat; + using wrap_y_type = agg::wrap_mode_repeat; + using img_source_type = agg::image_accessor_wrap; + + using span_gen_type = agg::span_pattern_rgba; + using ren_base = agg::renderer_base; + + using renderer_type = agg::renderer_scanline_aa_alpha, + span_gen_type>; pixfmt_type pixf(buf); pixf.comp_op(static_cast(get(sym_, feature_, common_.vars_))); @@ -247,8 +158,8 @@ struct agg_renderer_process_visitor_p apply_local_alignment apply(common_.t_,prj_trans_, clip_box, x0, y0); util::apply_visitor(geometry::vertex_processor(apply), feature_.get_geometry()); - offset_x = unsigned(current_buffer_->width() - x0); - offset_y = unsigned(current_buffer_->height() - y0); + offset_x = unsigned(current_buffer_.width() - x0); + offset_y = unsigned(current_buffer_.height() - y0); } span_gen_type sg(img_src, offset_x, offset_y); @@ -282,9 +193,8 @@ struct agg_renderer_process_visitor_p agg::render_scanlines(*ras_ptr_, sl, rp); } -private: renderer_common & common_; - buffer_type * current_buffer_; + buffer_type & current_buffer_; std::unique_ptr const& ras_ptr_; gamma_method_enum & gamma_method_; double & gamma_; @@ -302,7 +212,7 @@ void agg_renderer::process(polygon_pattern_symbolizer const& sym, if (filename.empty()) return; std::shared_ptr marker = marker_cache::instance().find(filename, true); agg_renderer_process_visitor_p visitor(common_, - current_buffer_, + buffers_.top().get(), ras_ptr, gamma_method_, gamma_, diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp index bd2d2bc15..a3cf32fe0 100644 --- a/src/agg/process_polygon_symbolizer.cpp +++ b/src/agg/process_polygon_symbolizer.cpp @@ -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 @@ -63,9 +63,10 @@ void agg_renderer::process(polygon_symbolizer const& sym, gamma_ = gamma; } - box2d clip_box = clipping_extent(common_); - agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size()); + buffer_type & current_buffer = buffers_.top().get(); + agg::rendering_buffer buf(current_buffer.bytes(), current_buffer.width(), current_buffer.height(), current_buffer.row_size()); + box2d clip_box = clipping_extent(common_); render_polygon_symbolizer( sym, feature, prj_trans, common_, clip_box, *ras_ptr, [&](color const &fill, double opacity) { diff --git a/src/agg/process_raster_symbolizer.cpp b/src/agg/process_raster_symbolizer.cpp index 746a5cc2b..ad3581065 100644 --- a/src/agg/process_raster_symbolizer.cpp +++ b/src/agg/process_raster_symbolizer.cpp @@ -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 @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include @@ -55,7 +55,7 @@ void agg_renderer::process(raster_symbolizer const& sym, sym, feature, prj_trans, common_, [&](image_rgba8 const & target, composite_mode_e comp_op, double opacity, int start_x, int start_y) { - composite(*current_buffer_, target, + composite(buffers_.top().get(), target, comp_op, opacity, start_x, start_y); } ); diff --git a/src/agg/process_shield_symbolizer.cpp b/src/agg/process_shield_symbolizer.cpp index 3d28eff60..e331121e9 100644 --- a/src/agg/process_shield_symbolizer.cpp +++ b/src/agg/process_shield_symbolizer.cpp @@ -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 @@ -51,7 +51,7 @@ void agg_renderer::process(shield_symbolizer const& sym, halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer, feature, common_.vars_, HALO_RASTERIZER_FULL); composite_mode_e comp_op = get(sym, keys::comp_op, feature, common_.vars_, src_over); composite_mode_e halo_comp_op = get(sym, keys::halo_comp_op, feature, common_.vars_, src_over); - agg_text_renderer ren(*current_buffer_, + agg_text_renderer ren(buffers_.top().get(), halo_rasterizer, comp_op, halo_comp_op, diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp index 685b66c95..afb6c85a3 100644 --- a/src/agg/process_text_symbolizer.cpp +++ b/src/agg/process_text_symbolizer.cpp @@ -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 @@ -52,7 +52,7 @@ void agg_renderer::process(text_symbolizer const& sym, halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer,feature, common_.vars_, HALO_RASTERIZER_FULL); composite_mode_e comp_op = get(sym, keys::comp_op, feature, common_.vars_, src_over); composite_mode_e halo_comp_op = get(sym, keys::halo_comp_op, feature, common_.vars_, src_over); - agg_text_renderer ren(*current_buffer_, + agg_text_renderer ren(buffers_.top().get(), halo_rasterizer, comp_op, halo_comp_op, diff --git a/src/build.py b/src/build.py index 6dd0f24a9..00c9134a4 100644 --- a/src/build.py +++ b/src/build.py @@ -152,27 +152,31 @@ else: # unix, non-macos source = Split( """ - expression_grammar.cpp + expression_grammar_x3.cpp fs.cpp request.cpp well_known_srs.cpp params.cpp - image_filter_types.cpp - image_filter_grammar.cpp + parse_image_filters.cpp + generate_image_filters.cpp + image_filter_grammar_x3.cpp color.cpp - conversions.cpp + conversions_numeric.cpp + conversions_string.cpp image_copy.cpp image_compositing.cpp image_scaling.cpp - box2d.cpp datasource_cache.cpp datasource_cache_static.cpp debug.cpp - geometry_reprojection.cpp + geometry/box2d.cpp + geometry/reprojection.cpp + geometry/envelope.cpp expression_node.cpp expression_string.cpp expression.cpp transform_expression.cpp + transform_expression_grammar_x3.cpp feature_kv_iterator.cpp feature_style_processor.cpp feature_type_style.cpp @@ -181,6 +185,7 @@ source = Split( font_set.cpp function_call.cpp gradient.cpp + path_expression_grammar_x3.cpp parse_path.cpp image_reader.cpp cairo_io.cpp @@ -199,8 +204,6 @@ source = Split( load_map.cpp palette.cpp marker_helpers.cpp - transform_expression_grammar.cpp - geometry_envelope.cpp plugin.cpp rule.cpp save_map.cpp @@ -223,8 +226,9 @@ source = Split( svg/svg_path_parser.cpp svg/svg_points_parser.cpp svg/svg_transform_parser.cpp + svg/svg_path_grammar_x3.cpp warp.cpp - css_color_grammar.cpp + css_color_grammar_x3.cpp vertex_cache.cpp vertex_adapters.cpp text/font_library.cpp diff --git a/src/cairo/cairo_context.cpp b/src/cairo/cairo_context.cpp index cb9216df4..3dae97105 100644 --- a/src/cairo/cairo_context.cpp +++ b/src/cairo/cairo_context.cpp @@ -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 diff --git a/src/cairo/cairo_render_vector.cpp b/src/cairo/cairo_render_vector.cpp index 160002dd2..f1779d96e 100644 --- a/src/cairo/cairo_render_vector.cpp +++ b/src/cairo/cairo_render_vector.cpp @@ -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 @@ -33,16 +33,16 @@ namespace mapnik { void render_vector_marker(cairo_context & context, svg::svg_path_adapter & svg_path, - agg::pod_bvector const & attributes, + agg::pod_bvector const & attrs, box2d const& bbox, agg::trans_affine const& tr, double opacity) { using namespace mapnik::svg; agg::trans_affine transform; - for(unsigned i = 0; i < attributes.size(); ++i) + for(unsigned i = 0; i < attrs.size(); ++i) { - mapnik::svg::path_attributes const& attr = attributes[i]; + mapnik::svg::path_attributes const& attr = attrs[i]; if (!attr.visibility_flag) continue; cairo_save_restore guard(context); diff --git a/src/cairo/cairo_renderer.cpp b/src/cairo/cairo_renderer.cpp index 2f845a53a..43c3ffef4 100644 --- a/src/cairo/cairo_renderer.cpp +++ b/src/cairo/cairo_renderer.cpp @@ -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 @@ -188,12 +188,25 @@ void cairo_renderer::start_layer_processing(layer const& lay, box2d c common_.detector_->clear(); } common_.query_extent_ = query_extent; + + if (lay.comp_op() || lay.get_opacity() < 1.0) + { + context_.push_group(); + } } template -void cairo_renderer::end_layer_processing(layer const&) +void cairo_renderer::end_layer_processing(layer const& lay) { MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer: End layer processing"; + + if (lay.comp_op() || lay.get_opacity() < 1.0) + { + context_.pop_group(); + composite_mode_e comp_op = lay.comp_op() ? *lay.comp_op() : src_over; + context_.set_operator(comp_op); + context_.paint(lay.get_opacity()); + } } template @@ -254,11 +267,11 @@ struct cairo_render_marker_visitor marker_tr *= tr_; } marker_tr *= agg::trans_affine_scaling(common_.scale_factor_); - agg::pod_bvector const & attributes = vmarker->attributes(); + agg::pod_bvector const & attrs = vmarker->attributes(); svg::vertex_stl_adapter stl_storage(vmarker->source()); svg::svg_path_adapter svg_path(stl_storage); marker_tr.translate(pos_.x, pos_.y); - render_vector_marker(context_, svg_path, attributes, bbox, marker_tr, opacity_); + render_vector_marker(context_, svg_path, attrs, bbox, marker_tr, opacity_); } } diff --git a/src/cairo/process_building_symbolizer.cpp b/src/cairo/process_building_symbolizer.cpp index 544414374..af305a2e6 100644 --- a/src/cairo/process_building_symbolizer.cpp +++ b/src/cairo/process_building_symbolizer.cpp @@ -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 @@ -34,6 +34,7 @@ // stl #include +#include namespace mapnik { diff --git a/src/cairo/process_debug_symbolizer.cpp b/src/cairo/process_debug_symbolizer.cpp index 8c78a82b5..627c4586f 100644 --- a/src/cairo/process_debug_symbolizer.cpp +++ b/src/cairo/process_debug_symbolizer.cpp @@ -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 diff --git a/src/cairo/process_group_symbolizer.cpp b/src/cairo/process_group_symbolizer.cpp index 0c35ba0ec..fa7b1e628 100644 --- a/src/cairo/process_group_symbolizer.cpp +++ b/src/cairo/process_group_symbolizer.cpp @@ -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 @@ -32,6 +32,8 @@ // mapnik symbolizer generics #include +#include + namespace mapnik { diff --git a/src/cairo/process_line_pattern_symbolizer.cpp b/src/cairo/process_line_pattern_symbolizer.cpp index f53d850a6..65ec43500 100644 --- a/src/cairo/process_line_pattern_symbolizer.cpp +++ b/src/cairo/process_line_pattern_symbolizer.cpp @@ -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 @@ -35,6 +35,8 @@ #include #include +#include + namespace mapnik { diff --git a/src/cairo/process_line_symbolizer.cpp b/src/cairo/process_line_symbolizer.cpp index ed64d5c01..6a798582e 100644 --- a/src/cairo/process_line_symbolizer.cpp +++ b/src/cairo/process_line_symbolizer.cpp @@ -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 @@ -29,7 +29,7 @@ #include #include #include -#include +#include namespace mapnik { diff --git a/src/cairo/process_markers_symbolizer.cpp b/src/cairo/process_markers_symbolizer.cpp index 73b84ecb7..e598b0cbd 100644 --- a/src/cairo/process_markers_symbolizer.cpp +++ b/src/cairo/process_markers_symbolizer.cpp @@ -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 @@ -76,8 +76,8 @@ void cairo_renderer::process(markers_symbolizer const& sym, context_.set_operator(comp_op); box2d clip_box = common_.query_extent_; - using context_type = detail::cairo_markers_renderer_context; - context_type renderer_context(context_); + using renderer_context_type = detail::cairo_markers_renderer_context; + renderer_context_type renderer_context(context_); render_markers_symbolizer( sym, feature, prj_trans, common_, clip_box, diff --git a/src/cairo/process_point_symbolizer.cpp b/src/cairo/process_point_symbolizer.cpp index b0ffefb80..a9ee159d1 100644 --- a/src/cairo/process_point_symbolizer.cpp +++ b/src/cairo/process_point_symbolizer.cpp @@ -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 diff --git a/src/cairo/process_polygon_pattern_symbolizer.cpp b/src/cairo/process_polygon_pattern_symbolizer.cpp index 4e21234b8..4578cac5a 100644 --- a/src/cairo/process_polygon_pattern_symbolizer.cpp +++ b/src/cairo/process_polygon_pattern_symbolizer.cpp @@ -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 diff --git a/src/cairo/process_polygon_symbolizer.cpp b/src/cairo/process_polygon_symbolizer.cpp index b2558a46a..360b28d3f 100644 --- a/src/cairo/process_polygon_symbolizer.cpp +++ b/src/cairo/process_polygon_symbolizer.cpp @@ -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 diff --git a/src/cairo/process_raster_symbolizer.cpp b/src/cairo/process_raster_symbolizer.cpp index 2b6fdc5c2..bd297ec6d 100644 --- a/src/cairo/process_raster_symbolizer.cpp +++ b/src/cairo/process_raster_symbolizer.cpp @@ -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 @@ -32,6 +32,8 @@ // mapnik symbolizer generics #include +#include + namespace mapnik { diff --git a/src/cairo/process_text_symbolizer.cpp b/src/cairo/process_text_symbolizer.cpp index 2d34e213c..548c2bf94 100644 --- a/src/cairo/process_text_symbolizer.cpp +++ b/src/cairo/process_text_symbolizer.cpp @@ -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 diff --git a/src/cairo_io.cpp b/src/cairo_io.cpp index 96152cc92..30f54d8f0 100644 --- a/src/cairo_io.cpp +++ b/src/cairo_io.cpp @@ -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 diff --git a/src/color.cpp b/src/color.cpp index 1804d5107..325f690f5 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -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 diff --git a/src/color_factory.cpp b/src/color_factory.cpp index dc54e89e5..e3607fa26 100644 --- a/src/color_factory.cpp +++ b/src/color_factory.cpp @@ -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 @@ -24,21 +24,20 @@ #include #include #include -#include +#include namespace mapnik { color parse_color(std::string const& str) { // TODO - early return for @color? - static const css_color_grammar g; + auto const& grammar = mapnik::color_grammar(); color c; std::string::const_iterator first = str.begin(); std::string::const_iterator last = str.end(); - boost::spirit::ascii::space_type space; - bool result = boost::spirit::qi::phrase_parse(first, last, g, - space, - c); + using namespace boost::spirit::x3::ascii; + + bool result = boost::spirit::x3::phrase_parse(first, last, grammar, space, c); if (result && (first == last)) { return c; diff --git a/src/config_error.cpp b/src/config_error.cpp index 8de797072..b5b069ffa 100644 --- a/src/config_error.cpp +++ b/src/config_error.cpp @@ -37,7 +37,7 @@ config_error::config_error(std::string const& what, { } -char const* config_error::what() const throw() +char const* config_error::what() const noexcept { msg_ = what_; if (!node_name_.empty()) diff --git a/src/conversions.cpp b/src/conversions.cpp deleted file mode 100644 index 04bfc5789..000000000 --- a/src/conversions.cpp +++ /dev/null @@ -1,264 +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 -#include - -#include -#include - -// karma is used by default -#define MAPNIK_KARMA_TO_STRING - -#pragma GCC diagnostic push -#include -#include -#ifdef MAPNIK_KARMA_TO_STRING - #include -#endif -#pragma GCC diagnostic pop - -#if _MSC_VER -#define snprintf _snprintf -#endif - -namespace mapnik { - -namespace util { - -using namespace boost::spirit; - -auto INTEGER = qi::int_type(); -#ifdef BIGINT -auto LONGLONG = qi::long_long_type(); -#endif -auto FLOAT = qi::float_type(); -auto DOUBLE = qi::double_type(); - -bool string2bool(std::string const& value, bool & result) -{ - if (value.empty() || value.size() > 5) { - return false; - } else if (value == "true") { - return result = true; - } else if (value == "false") { - result = false; - return true; - } - std::string val(value); - std::transform(val.begin(), val.end(), val.begin(), ::tolower); - if (val == "true" || val == "yes" || val == "1" || val == "on") { - return result = true; - } else if (val == "false" || val == "no" || val == "0" || val == "off") { - result = false; - return true; - } - return false; -} - -bool string2bool(const char * iter, const char * end, bool & result) -{ - std::string val(iter,end); - return string2bool(val,result); -} - -bool string2int(const char * iter, const char * end, int & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,INTEGER,space,result); - return r && (iter == end); -} - -bool string2int(std::string const& value, int & result) -{ - ascii::space_type space; - std::string::const_iterator str_beg = value.begin(); - std::string::const_iterator str_end = value.end(); - bool r = qi::phrase_parse(str_beg,str_end,INTEGER,space,result); - return r && (str_beg == str_end); -} - -#ifdef BIGINT -bool string2int(const char * iter, const char * end, mapnik::value_integer & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,LONGLONG,space,result); - return r && (iter == end); -} - -bool string2int(std::string const& value, mapnik::value_integer & result) -{ - ascii::space_type space; - std::string::const_iterator str_beg = value.begin(); - std::string::const_iterator str_end = value.end(); - bool r = qi::phrase_parse(str_beg,str_end,LONGLONG,space,result); - return r && (str_beg == str_end); -} -#endif - -bool string2double(std::string const& value, double & result) -{ - ascii::space_type space; - std::string::const_iterator str_beg = value.begin(); - std::string::const_iterator str_end = value.end(); - bool r = qi::phrase_parse(str_beg,str_end,DOUBLE,space,result); - return r && (str_beg == str_end); -} - -bool string2double(const char * iter, const char * end, double & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,DOUBLE,space,result); - return r && (iter == end); -} - -bool string2float(std::string const& value, float & result) -{ - ascii::space_type space; - std::string::const_iterator str_beg = value.begin(); - std::string::const_iterator str_end = value.end(); - bool r = qi::phrase_parse(str_beg,str_end,FLOAT,space,result); - return r && (str_beg == str_end); -} - -bool string2float(const char * iter, const char * end, float & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,FLOAT,space,result); - return r && (iter == end); -} - -// double conversion - here we use sprintf over karma to work -// around https://github.com/mapnik/mapnik/issues/1741 -bool to_string(std::string & s, double val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%g", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -#ifdef MAPNIK_KARMA_TO_STRING - -bool to_string(std::string & str, int value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -#ifdef BIGINT -bool to_string(std::string & str, mapnik::value_integer value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} -#endif - -bool to_string(std::string & str, unsigned value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -bool to_string(std::string & str, bool value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -#else - -bool to_string(std::string & s, int val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%d", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -#ifdef BIGINT -bool to_string(std::string & s, mapnik::value_integer val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%lld", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} -#endif - -bool to_string(std::string & s, unsigned val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%u", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -bool to_string(std::string & s, bool val) -{ - if (val) s = "true"; - else s = "false"; - return true; -} - -#endif - -} // end namespace util - -} diff --git a/src/conversions_numeric.cpp b/src/conversions_numeric.cpp new file mode 100644 index 000000000..d209ea6b6 --- /dev/null +++ b/src/conversions_numeric.cpp @@ -0,0 +1,146 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace util { + +using namespace boost::spirit; + +auto INTEGER = x3::int_type(); +#ifdef BIGINT +//auto LONGLONG = x3::long_long_type(); +#endif +auto FLOAT = x3::float_type(); +auto DOUBLE = x3::double_type(); + +bool string2bool(std::string const& value, bool& result) +{ + if (value.empty() || value.size() > 5) + { + return false; + } + else if (value == "true") + { + return result = true; + } + else if (value == "false") + { + result = false; + return true; + } + std::string val(value); + std::transform(val.begin(), val.end(), val.begin(), ::tolower); + if (val == "true" || val == "yes" || val == "1" || val == "on") + { + return result = true; + } + else if (val == "false" || val == "no" || val == "0" || val == "off") + { + result = false; + return true; + } + return false; +} + +bool string2bool(const char* iter, const char* end, bool& result) +{ + std::string val(iter, end); + return string2bool(val, result); +} + +bool string2int(const char* iter, const char* end, int& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, INTEGER, space, result); + return r && (iter == end); +} + +bool string2int(std::string const& value, int& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, INTEGER, space, result); + return r && (str_beg == str_end); +} + +#ifdef BIGINT +bool string2int(const char* iter, const char* end, mapnik::value_integer& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, x3::long_long, space, result); + return r && (iter == end); +} + +bool string2int(std::string const& value, mapnik::value_integer& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, x3::long_long, space, result); + return r && (str_beg == str_end); +} +#endif + +bool string2double(std::string const& value, double& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, DOUBLE, space, result); + return r && (str_beg == str_end); +} + +bool string2double(const char* iter, const char* end, double& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, DOUBLE, space, result); + return r && (iter == end); +} + +bool string2float(std::string const& value, float& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, FLOAT, space, result); + return r && (str_beg == str_end); +} + +bool string2float(const char* iter, const char* end, float& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, FLOAT, space, result); + return r && (iter == end); +} +} // util +} // mapnik diff --git a/src/conversions_string.cpp b/src/conversions_string.cpp new file mode 100644 index 000000000..bd9e46df1 --- /dev/null +++ b/src/conversions_string.cpp @@ -0,0 +1,162 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include + +#include +#include + +// karma is used by default +#define MAPNIK_KARMA_TO_STRING + +#pragma GCC diagnostic push +#include +#ifdef MAPNIK_KARMA_TO_STRING +#include +#endif +#pragma GCC diagnostic pop + +#if _MSC_VER +#define snprintf _snprintf +#endif + +namespace mapnik { namespace util { + +using namespace boost::spirit; + +// double conversion - here we use sprintf over karma to work +// around https://github.com/mapnik/mapnik/issues/1741 +bool to_string(std::string& s, double val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%g", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +#ifdef MAPNIK_KARMA_TO_STRING + +bool to_string(std::string& str, int value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +#ifdef BIGINT +bool to_string(std::string& str, mapnik::value_integer value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} +#endif + +bool to_string(std::string& str, unsigned value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +bool to_string(std::string& str, bool value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +#else + +bool to_string(std::string& s, int val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%d", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +#ifdef BIGINT +bool to_string(std::string& s, mapnik::value_integer val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%lld", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} +#endif + +bool to_string(std::string& s, unsigned val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%u", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +bool to_string(std::string& s, bool val) +{ + if (val) + s = "true"; + else + s = "false"; + return true; +} + +#endif + +} // end namespace util +} diff --git a/src/css_color_grammar_x3.cpp b/src/css_color_grammar_x3.cpp new file mode 100644 index 000000000..a89505496 --- /dev/null +++ b/src/css_color_grammar_x3.cpp @@ -0,0 +1,33 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include + +namespace mapnik { namespace css_color_grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; + +BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_type, context_type); + +}} diff --git a/src/dasharray_parser.cpp b/src/dasharray_parser.cpp index 963a2905a..e42182c0c 100644 --- a/src/dasharray_parser.cpp +++ b/src/dasharray_parser.cpp @@ -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 @@ -25,11 +25,7 @@ #pragma GCC diagnostic push #include -#include -#include -#include -#include -#include +#include #pragma GCC diagnostic pop namespace mapnik { @@ -58,15 +54,14 @@ inline bool setup_dashes(std::vector & buf, dash_array & dash) } } + bool parse_dasharray(std::string const& value, dash_array & dash) { using namespace boost::spirit; - qi::double_type double_; - qi::_1_type _1; - qi::lit_type lit; - qi::char_type char_; - qi::ascii::space_type space; - qi::no_skip_type no_skip; + using x3::no_skip; + using x3::double_; + using x3::char_; + boost::spirit::x3::ascii::space_type space; // SVG // dasharray ::= (length | percentage) (comma-wsp dasharray)? // no support for 'percentage' as viewport is unknown at load_map @@ -74,11 +69,9 @@ bool parse_dasharray(std::string const& value, dash_array & dash) std::vector buf; auto first = value.begin(); auto last = value.end(); - bool r = qi::phrase_parse(first, last, - (double_[boost::phoenix::push_back(boost::phoenix::ref(buf), _1)] % - no_skip[char_(", ")] - | lit("none")), - space); + bool r = x3::phrase_parse(first, last, + (double_ % no_skip[char_(", ")] | "none"), + space, buf); if (r && first == last) { return setup_dashes(buf, dash); diff --git a/src/datasource_cache.cpp b/src/datasource_cache.cpp index 3759a6ceb..ccb6a19c2 100644 --- a/src/datasource_cache.cpp +++ b/src/datasource_cache.cpp @@ -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 diff --git a/src/datasource_cache_static.cpp b/src/datasource_cache_static.cpp index ba79d1d01..38d87f273 100644 --- a/src/datasource_cache_static.cpp +++ b/src/datasource_cache_static.cpp @@ -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 diff --git a/src/debug.cpp b/src/debug.cpp index d1ae15fa4..affb39491 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -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 diff --git a/src/expression.cpp b/src/expression.cpp index f4bdeeb84..7c3726682 100644 --- a/src/expression.cpp +++ b/src/expression.cpp @@ -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 @@ -25,27 +25,30 @@ #include #include #include -#include - -// boost -#include +#include namespace mapnik { expression_ptr parse_expression(std::string const& str) { - static const expression_grammar g; - boost::spirit::standard_wide::space_type space; auto node = std::make_shared(); - std::string::const_iterator itr = str.begin(); - std::string::const_iterator end = str.end(); + using boost::spirit::x3::ascii::space; + mapnik::transcoder const tr("utf8"); + auto parser = boost::spirit::x3::with(std::ref(tr)) + [ + mapnik::expression_grammar() + ]; + bool r = false; + std::string::const_iterator itr = str.begin(); + std::string::const_iterator const end = str.end(); + try { - r = boost::spirit::qi::phrase_parse(itr, end, g, space, *node); + r = boost::spirit::x3::phrase_parse(itr, end, parser, space, *node); } - catch (boost::spirit::qi::expectation_failure const& ex) + catch (boost::spirit::x3::expectation_failure const& ex) { // no need to show "boost::spirit::qi::expectation_failure" which is a std::runtime_error throw config_error("Failed to parse expression: \"" + str + "\""); diff --git a/src/wkt/mapnik_wkt_grammar.cpp b/src/expression_grammar_x3.cpp similarity index 79% rename from src/wkt/mapnik_wkt_grammar.cpp rename to src/expression_grammar_x3.cpp index aea52a917..07d4a8ece 100644 --- a/src/wkt/mapnik_wkt_grammar.cpp +++ b/src/expression_grammar_x3.cpp @@ -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,12 +20,11 @@ * *****************************************************************************/ -#include -#include +#include +#include -namespace mapnik { namespace wkt { +namespace mapnik { namespace grammar { -using iterator_type = std::string::const_iterator; -template struct wkt_grammar; +BOOST_SPIRIT_INSTANTIATE(expression_grammar_type, iterator_type, context_type); }} diff --git a/src/expression_node.cpp b/src/expression_node.cpp index 549f4c891..62d19fd4f 100644 --- a/src/expression_node.cpp +++ b/src/expression_node.cpp @@ -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 @@ -21,7 +21,7 @@ *****************************************************************************/ #include -#include +#include #include #include diff --git a/src/expression_string.cpp b/src/expression_string.cpp index 0f904ee68..471acc50e 100644 --- a/src/expression_string.cpp +++ b/src/expression_string.cpp @@ -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 @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include namespace mapnik diff --git a/src/feature_kv_iterator.cpp b/src/feature_kv_iterator.cpp index 4ae384254..6853bc503 100644 --- a/src/feature_kv_iterator.cpp +++ b/src/feature_kv_iterator.cpp @@ -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 diff --git a/src/feature_style_processor.cpp b/src/feature_style_processor.cpp index c041016d6..f923128da 100644 --- a/src/feature_style_processor.cpp +++ b/src/feature_style_processor.cpp @@ -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 diff --git a/src/feature_type_style.cpp b/src/feature_type_style.cpp index a2ddb33ba..0fdf67536 100644 --- a/src/feature_type_style.cpp +++ b/src/feature_type_style.cpp @@ -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 @@ -148,9 +148,9 @@ std::vector const& feature_type_style::direct_image_filter return direct_filters_; } -void feature_type_style::set_comp_op(composite_mode_e comp_op) +void feature_type_style::set_comp_op(composite_mode_e _comp_op) { - comp_op_ = comp_op; + comp_op_ = _comp_op; } boost::optional feature_type_style::comp_op() const diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp index 9721d70bf..a325ada42 100644 --- a/src/font_engine_freetype.cpp +++ b/src/font_engine_freetype.cpp @@ -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 @@ -48,7 +48,6 @@ extern "C" #include #include - namespace mapnik { diff --git a/src/font_set.cpp b/src/font_set.cpp index 9236cac32..cb06be77f 100644 --- a/src/font_set.cpp +++ b/src/font_set.cpp @@ -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 diff --git a/src/fs.cpp b/src/fs.cpp index 640345396..3ed841e1e 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -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 diff --git a/src/function_call.cpp b/src/function_call.cpp index e813deef7..6326becfa 100644 --- a/src/function_call.cpp +++ b/src/function_call.cpp @@ -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 diff --git a/src/image_filter_types.cpp b/src/generate_image_filters.cpp similarity index 66% rename from src/image_filter_types.cpp rename to src/generate_image_filters.cpp index d30804378..03c55ab43 100644 --- a/src/image_filter_types.cpp +++ b/src/generate_image_filters.cpp @@ -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 @@ -19,9 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ + // mapnik #include -#include #pragma GCC diagnostic push #include @@ -43,18 +43,4 @@ bool generate_image_filters(std::back_insert_iterator & sink, std:: return r; } -bool parse_image_filters(std::string const& filters, std::vector& image_filters) -{ - std::string::const_iterator itr = filters.begin(); - std::string::const_iterator end = filters.end(); - static const mapnik::image_filter_grammar > filter_grammar; - boost::spirit::qi::ascii::space_type space; - bool r = boost::spirit::qi::phrase_parse(itr,end, - filter_grammar, - space, - image_filters); - return r && itr==end; -} - }} diff --git a/src/box2d.cpp b/src/geometry/box2d.cpp similarity index 93% rename from src/box2d.cpp rename to src/geometry/box2d.cpp index 2a87553ce..07ceda0eb 100644 --- a/src/box2d.cpp +++ b/src/geometry/box2d.cpp @@ -21,12 +21,12 @@ *****************************************************************************/ // mapnik -#include +#include namespace mapnik { template class box2d; -template class box2d; +//template class box2d; template class box2d; template class box2d; diff --git a/src/geometry_envelope.cpp b/src/geometry/envelope.cpp similarity index 91% rename from src/geometry_envelope.cpp rename to src/geometry/envelope.cpp index bb79f59ad..cb4b61371 100644 --- a/src/geometry_envelope.cpp +++ b/src/geometry/envelope.cpp @@ -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,8 @@ * *****************************************************************************/ -#include -#include -#include +#include +#include namespace mapnik { namespace geometry { diff --git a/src/geometry_reprojection.cpp b/src/geometry/reprojection.cpp similarity index 89% rename from src/geometry_reprojection.cpp rename to src/geometry/reprojection.cpp index fad2c5b6f..8f4ae742c 100644 --- a/src/geometry_reprojection.cpp +++ b/src/geometry/reprojection.cpp @@ -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 @@ -21,15 +21,15 @@ *****************************************************************************/ // mapnik -#include -#include +#include +#include namespace mapnik { namespace geometry { template MAPNIK_DECL geometry reproject_copy(geometry const& geom, proj_transform const& proj_trans, unsigned int & n_err); -template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, proj_transform const& proj_trans, unsigned int & n_err); +template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL point reproject_copy(point const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL line_string reproject_copy(line_string const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL polygon reproject_copy(polygon const& geom, proj_transform const& proj_trans, unsigned int & n_err); @@ -39,7 +39,7 @@ template MAPNIK_DECL multi_polygon reproject_copy(multi_polygon template MAPNIK_DECL geometry_collection reproject_copy(geometry_collection const& geom, proj_transform const& proj_trans, unsigned int & n_err); template MAPNIK_DECL geometry reproject_copy(geometry const& geom, projection const& source, projection const& dest, unsigned int & n_err); -template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, projection const& source, projection const& dest, unsigned int & n_err); +template MAPNIK_DECL geometry_empty reproject_copy(geometry_empty const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL point reproject_copy(point const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL line_string reproject_copy(line_string const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL polygon reproject_copy(polygon const& geom, projection const& source, projection const& dest, unsigned int & n_err); @@ -49,7 +49,7 @@ template MAPNIK_DECL multi_polygon reproject_copy(multi_polygon template MAPNIK_DECL geometry_collection reproject_copy(geometry_collection const& geom, projection const& source, projection const& dest, unsigned int & n_err); template MAPNIK_DECL bool reproject(geometry & geom, proj_transform const& proj_trans); -template MAPNIK_DECL bool reproject(geometry_empty & geom, proj_transform const& proj_trans); +template MAPNIK_DECL bool reproject(geometry_empty & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(point & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(line_string & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(polygon & geom, proj_transform const& proj_trans); @@ -59,7 +59,7 @@ template MAPNIK_DECL bool reproject(multi_polygon & geom, proj_transform template MAPNIK_DECL bool reproject(geometry_collection & geom, proj_transform const& proj_trans); template MAPNIK_DECL bool reproject(geometry & geom, projection const& source, projection const& dest); -template MAPNIK_DECL bool reproject(geometry_empty & geom, projection const& source, projection const& dest); +template MAPNIK_DECL bool reproject(geometry_empty & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(point & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(line_string & geom, projection const& source, projection const& dest); template MAPNIK_DECL bool reproject(polygon & geom, projection const& source, projection const& dest); diff --git a/src/gradient.cpp b/src/gradient.cpp index 0c9c6b8fa..6e3ca355a 100644 --- a/src/gradient.cpp +++ b/src/gradient.cpp @@ -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 @@ -121,7 +121,7 @@ stop_array const& gradient::get_stop_array() const return stops_; } -void gradient::swap(gradient& other) throw() +void gradient::swap(gradient& other) noexcept { std::swap(gradient_type_, other.gradient_type_); std::swap(stops_, other.stops_); diff --git a/src/grid/grid.cpp b/src/grid/grid.cpp index b0d3d598d..678584412 100644 --- a/src/grid/grid.cpp +++ b/src/grid/grid.cpp @@ -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 diff --git a/src/grid/grid_renderer.cpp b/src/grid/grid_renderer.cpp index fd970f580..593a7ee21 100644 --- a/src/grid/grid_renderer.cpp +++ b/src/grid/grid_renderer.cpp @@ -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 diff --git a/src/grid/process_building_symbolizer.cpp b/src/grid/process_building_symbolizer.cpp index 13ee8d442..14893ce0f 100644 --- a/src/grid/process_building_symbolizer.cpp +++ b/src/grid/process_building_symbolizer.cpp @@ -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 @@ -38,6 +38,7 @@ // stl #include +#include #pragma GCC diagnostic push #include diff --git a/src/grid/process_group_symbolizer.cpp b/src/grid/process_group_symbolizer.cpp index ba7f48ece..46f90bbc7 100644 --- a/src/grid/process_group_symbolizer.cpp +++ b/src/grid/process_group_symbolizer.cpp @@ -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 @@ -74,7 +74,6 @@ struct thunk_renderer : render_thunk_list_dispatch using renderer_type = agg::renderer_scanline_bin_solid; using namespace mapnik::svg; - using svg_attribute_type = agg::pod_bvector; using svg_renderer_type = svg_renderer_agg #include #include -#include +#include #pragma GCC diagnostic push #include diff --git a/src/grid/process_markers_symbolizer.cpp b/src/grid/process_markers_symbolizer.cpp index 380923211..7b8d7ed8a 100644 --- a/src/grid/process_markers_symbolizer.cpp +++ b/src/grid/process_markers_symbolizer.cpp @@ -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 @@ -143,7 +143,6 @@ void grid_renderer::process(markers_symbolizer const& sym, using renderer_type = agg::renderer_scanline_bin_solid; using namespace mapnik::svg; - using svg_attribute_type = agg::pod_bvector; using svg_renderer_type = svg_renderer_agg::process(markers_symbolizer const& sym, ras_ptr->reset(); box2d clip_box = common_.query_extent_; - using context_type = detail::grid_markers_renderer_context; - context_type renderer_context(feature, render_buf, *ras_ptr, pixmap_); + renderer_context_type renderer_context(feature, render_buf, *ras_ptr, pixmap_); render_markers_symbolizer( sym, feature, prj_trans, common_, clip_box, renderer_context); diff --git a/src/grid/process_point_symbolizer.cpp b/src/grid/process_point_symbolizer.cpp index 60328009d..e8c364965 100644 --- a/src/grid/process_point_symbolizer.cpp +++ b/src/grid/process_point_symbolizer.cpp @@ -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 diff --git a/src/grid/process_polygon_pattern_symbolizer.cpp b/src/grid/process_polygon_pattern_symbolizer.cpp index 03e27c65d..d0ff02107 100644 --- a/src/grid/process_polygon_pattern_symbolizer.cpp +++ b/src/grid/process_polygon_pattern_symbolizer.cpp @@ -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 diff --git a/src/grid/process_polygon_symbolizer.cpp b/src/grid/process_polygon_symbolizer.cpp index ab8526252..c951d1a81 100644 --- a/src/grid/process_polygon_symbolizer.cpp +++ b/src/grid/process_polygon_symbolizer.cpp @@ -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 diff --git a/src/grid/process_raster_symbolizer.cpp b/src/grid/process_raster_symbolizer.cpp index 9e392a720..413f6e1ff 100644 --- a/src/grid/process_raster_symbolizer.cpp +++ b/src/grid/process_raster_symbolizer.cpp @@ -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 diff --git a/src/grid/process_shield_symbolizer.cpp b/src/grid/process_shield_symbolizer.cpp index 0463bee8e..54c2dea12 100644 --- a/src/grid/process_shield_symbolizer.cpp +++ b/src/grid/process_shield_symbolizer.cpp @@ -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 diff --git a/src/grid/process_text_symbolizer.cpp b/src/grid/process_text_symbolizer.cpp index d1b6a17b4..a28165f92 100644 --- a/src/grid/process_text_symbolizer.cpp +++ b/src/grid/process_text_symbolizer.cpp @@ -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 diff --git a/src/group/group_layout_manager.cpp b/src/group/group_layout_manager.cpp index ad9aaad7c..dd5f2099a 100644 --- a/src/group/group_layout_manager.cpp +++ b/src/group/group_layout_manager.cpp @@ -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 @@ -90,30 +90,26 @@ struct process_layout return; } - bound_box layout_box; - int middle_ifirst = safe_cast((member_boxes_.size() - 1) >> 1); - int top_i = 0; - int bottom_i = 0; - if (middle_ifirst % 2 == 0) + auto max_diff = layout.get_max_difference(); + auto layout_box = make_horiz_pair(0, 0.0, 0, x_margin, max_diff); + auto y_shift = 0.5 * layout_box.height(); + + for (size_t i = 2; i < member_boxes_.size(); i += 2) { - layout_box = make_horiz_pair(0, 0.0, 0, x_margin, layout.get_max_difference()); - top_i = middle_ifirst - 2; - bottom_i = middle_ifirst + 2; - } - else - { - top_i = middle_ifirst - 1; - bottom_i = middle_ifirst + 1; + auto y = layout_box.maxy() + y_margin; + auto pair_box = make_horiz_pair(i, y, 1, x_margin, max_diff); + layout_box.expand_to_include(pair_box); } - while (bottom_i >= 0 && top_i >= 0 && top_i < static_cast(member_offsets_.size())) - { - layout_box.expand_to_include(make_horiz_pair(static_cast(top_i), layout_box.miny() - y_margin, -1, x_margin, layout.get_max_difference())); - layout_box.expand_to_include(make_horiz_pair(static_cast(bottom_i), layout_box.maxy() + y_margin, 1, x_margin, layout.get_max_difference())); - top_i -= 2; - bottom_i += 2; - } + // layout_box.center corresponds to the center of the first row; + // shift offsets so that the whole group is centered vertically + y_shift -= 0.5 * layout_box.height(); + + for (auto & offset : member_offsets_) + { + offset.y += y_shift; + } } private: @@ -146,12 +142,12 @@ private: // stores corresponding offset, and returns modified bounding box bound_box box_offset_align(size_t i, double x, double y, int x_dir, int y_dir) const { - bound_box const& box = member_boxes_[i]; - pixel_position offset((x_dir == 0 ? x - input_origin_.x : x - (x_dir < 0 ? box.maxx() : box.minx())), - (y_dir == 0 ? y - input_origin_.y : y - (y_dir < 0 ? box.maxy() : box.miny()))); - - member_offsets_[i] = offset; - return bound_box(box.minx() + offset.x, box.miny() + offset.y, box.maxx() + offset.x, box.maxy() + offset.y); + auto box = member_boxes_[i]; + auto & offset = member_offsets_[i]; + offset.x = x - (x_dir == 0 ? input_origin_.x : (x_dir < 0 ? box.maxx() : box.minx())); + offset.y = y - (y_dir == 0 ? input_origin_.y : (y_dir < 0 ? box.maxy() : box.miny())); + box.move(offset.x, offset.y); + return box; } }; diff --git a/src/group/group_rule.cpp b/src/group/group_rule.cpp index a1a6bf940..56beb819b 100644 --- a/src/group/group_rule.cpp +++ b/src/group/group_rule.cpp @@ -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 diff --git a/src/group/group_symbolizer_helper.cpp b/src/group/group_symbolizer_helper.cpp index 2ba70ff9b..4643595a4 100644 --- a/src/group/group_symbolizer_helper.cpp +++ b/src/group/group_symbolizer_helper.cpp @@ -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 @@ -23,12 +23,11 @@ // mapnik #include #include -//#include #include #include #include #include -#include +#include #include #include #include diff --git a/src/image.cpp b/src/image.cpp index 5141860b7..086749cd0 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -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 @@ -88,7 +88,6 @@ template struct MAPNIK_DECL image_dimensions<65535>; } // end ns detail -template class MAPNIK_DECL image; template class MAPNIK_DECL image; template class MAPNIK_DECL image; template class MAPNIK_DECL image; diff --git a/src/image_any.cpp b/src/image_any.cpp index 5ba0c3947..4dfb39fa1 100644 --- a/src/image_any.cpp +++ b/src/image_any.cpp @@ -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 diff --git a/src/image_compositing.cpp b/src/image_compositing.cpp index d6c8a3333..6fe319b52 100644 --- a/src/image_compositing.cpp +++ b/src/image_compositing.cpp @@ -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 diff --git a/src/image_copy.cpp b/src/image_copy.cpp index 04fa75c32..8611e83e8 100644 --- a/src/image_copy.cpp +++ b/src/image_copy.cpp @@ -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 diff --git a/src/image_filter_grammar_x3.cpp b/src/image_filter_grammar_x3.cpp new file mode 100644 index 000000000..8b1e84f8a --- /dev/null +++ b/src/image_filter_grammar_x3.cpp @@ -0,0 +1,33 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include + +namespace mapnik { namespace image_filter { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; + +BOOST_SPIRIT_INSTANTIATE(image_filter_grammar_type, iterator_type, context_type); + +}} // image_filter //mapnik diff --git a/src/image_options.cpp b/src/image_options.cpp index bbcb6c909..fedf1f976 100644 --- a/src/image_options.cpp +++ b/src/image_options.cpp @@ -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 @@ -24,54 +24,99 @@ #pragma GCC diagnostic push #include -#include +#include #include #pragma GCC diagnostic pop -namespace mapnik { namespace detail { - -namespace qi = boost::spirit::qi; - -template -struct image_options_grammar - : qi::grammar +#if defined(HAVE_PNG) +extern "C" { - using pair_type = std::pair>; - image_options_grammar() - : image_options_grammar::base_type(start) - { - qi::lit_type lit; - qi::char_type char_; - start = pair >> *(lit(':') >> pair) - ; - pair = key >> -('=' >> value) - ; - key = char_("a-zA-Z_") >> *char_("a-zA-Z_0-9\\.\\-") - ; - value = +char_("a-zA-Z_0-9\\.\\-") - ; - } +#include +} +#endif // HAVE_PNG - qi::rule start; - qi::rule pair; - qi::rule key, value; -}; +namespace mapnik { namespace grammar { -} // ns detail +namespace x3 = boost::spirit::x3; + +using x3::lit; +using x3::ascii::char_; +using pair_type = std::pair>; + +x3::rule const image_options("image options"); +x3::rule const key_value("key_value"); +x3::rule const key("key"); +x3::rule const value("value"); + +auto const key_def = char_("a-zA-Z_") > *char_("a-zA-Z_0-9\\.\\-"); +auto const value_def = +char_("a-zA-Z_0-9\\.\\-|"); +auto const key_value_def = key > -('=' > value); +auto const image_options_def = key_value % lit(':'); + +BOOST_SPIRIT_DEFINE(key); +BOOST_SPIRIT_DEFINE(value); +BOOST_SPIRIT_DEFINE(key_value); +BOOST_SPIRIT_DEFINE(image_options); + +} // grammar image_options_map parse_image_options(std::string const& str) { - auto const begin = str.begin(); + auto begin = str.begin(); auto const end = str.end(); - boost::spirit::ascii::space_type space; - mapnik::detail::image_options_grammar g; + using boost::spirit::x3::space; + using mapnik::grammar::image_options; image_options_map options; - bool success = boost::spirit::qi::phrase_parse(begin, end, g, space, options); - if (!success) + try { - throw std::runtime_error("Can't parse image options: " + str); + bool success = boost::spirit::x3::phrase_parse(begin, end, image_options, space, options); + if (!success || begin != end) + { + throw std::runtime_error("Can't parse image options: " + str); + } + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + throw std::runtime_error("Can't parse image options: " + str + " " + ex.what()); } return options; // RVO } +#if defined(HAVE_PNG) + +int parse_png_filters(std::string const& str) +{ + auto begin = str.begin(); + auto const end = str.end(); + using boost::spirit::x3::space; + using boost::spirit::x3::symbols; + symbols filter; + filter.add + ("none", PNG_FILTER_NONE) + ("sub", PNG_FILTER_SUB) + ("up", PNG_FILTER_UP) + ("avg", PNG_FILTER_AVG) + ("paeth", PNG_FILTER_PAETH) + ; + + std::vector opts; + try + { + bool success = boost::spirit::x3::phrase_parse(begin, end, filter % "|" , space , opts); + if (!success || begin != end) + { + throw std::runtime_error("Can't parse PNG filters: " + str); + } + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + throw std::runtime_error("Can't parse PNG filters: " + str + " " + ex.what()); + } + int filters = 0; + std::for_each(opts.begin(), opts.end(), [&filters] (int f) { filters |= f;}); + return filters; +} + +#endif // HAVE_PNG + } // ns mapnik diff --git a/src/image_reader.cpp b/src/image_reader.cpp index d0ec815b9..b37ad06e1 100644 --- a/src/image_reader.cpp +++ b/src/image_reader.cpp @@ -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 diff --git a/src/image_scaling.cpp b/src/image_scaling.cpp index 413948c64..a2ed8ea53 100644 --- a/src/image_scaling.cpp +++ b/src/image_scaling.cpp @@ -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 diff --git a/src/image_util.cpp b/src/image_util.cpp index 1fec8b130..954d5321c 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -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 @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/image_util_jpeg.cpp b/src/image_util_jpeg.cpp index 13860fd4e..5abf8a21d 100644 --- a/src/image_util_jpeg.cpp +++ b/src/image_util_jpeg.cpp @@ -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 @@ -119,7 +119,6 @@ void jpeg_saver::operator() (T const& image) const throw image_writer_exception("Mapnik does not support jpeg grayscale images"); } -template void jpeg_saver::operator() (image_rgba8 const& image) const; template void jpeg_saver::operator() (image_gray8 const& image) const; template void jpeg_saver::operator() (image_gray8s const& image) const; template void jpeg_saver::operator() (image_gray16 const& image) const; @@ -130,7 +129,6 @@ template void jpeg_saver::operator() (image_gray32f const& image) template void jpeg_saver::operator() (image_gray64 const& image) const; template void jpeg_saver::operator() (image_gray64s const& image) const; template void jpeg_saver::operator() (image_gray64f const& image) const; -template void jpeg_saver::operator() (image_view_rgba8 const& image) const; template void jpeg_saver::operator() (image_view_gray8 const& image) const; template void jpeg_saver::operator() (image_view_gray8s const& image) const; template void jpeg_saver::operator() (image_view_gray16 const& image) const; diff --git a/src/image_util_png.cpp b/src/image_util_png.cpp index f09d58019..0586ded06 100644 --- a/src/image_util_png.cpp +++ b/src/image_util_png.cpp @@ -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 @@ -25,7 +25,10 @@ extern "C" { #include } +#ifndef PNG_FAST_FILTERS // libpng < 1.6 +#define PNG_FAST_FILTERS ( PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP ) #endif +#endif // HAVE_PNG // mapnik #if defined(HAVE_PNG) @@ -154,6 +157,19 @@ void handle_png_options(std::string const& type, throw image_writer_exception("invalid compression strategy parameter: " + *val); } } + else if (key == "f") + { + // filters = PNG_NO_FILTERS; + // filters = PNG_ALL_FILTERS; + // filters = PNG_FAST_FILTERS; + // filters = PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | PNG_FILTER_PAETH; + + if (!val) throw image_writer_exception("invalid filters parameter: "); + if (*val == "no") opts.filters = PNG_NO_FILTERS; + else if (*val == "all") opts.filters = PNG_ALL_FILTERS; + else if (*val == "fast") opts.filters = PNG_FAST_FILTERS; + else opts.filters = parse_png_filters(*val); // none | sub | up | avg | paeth + } else { throw image_writer_exception("unhandled png option: " + key); @@ -316,7 +332,6 @@ void png_saver_pal::operator() (T const& image) const #endif } -template void png_saver::operator() (image_rgba8 const& image) const; template void png_saver::operator() (image_gray8 const& image) const; template void png_saver::operator() (image_gray8s const& image) const; template void png_saver::operator() (image_gray16 const& image) const; @@ -327,7 +342,6 @@ template void png_saver::operator() (image_gray32f const& image) template void png_saver::operator() (image_gray64 const& image) const; template void png_saver::operator() (image_gray64s const& image) const; template void png_saver::operator() (image_gray64f const& image) const; -template void png_saver::operator() (image_view_rgba8 const& image) const; template void png_saver::operator() (image_view_gray8 const& image) const; template void png_saver::operator() (image_view_gray8s const& image) const; template void png_saver::operator() (image_view_gray16 const& image) const; @@ -338,7 +352,6 @@ template void png_saver::operator() (image_view_gray32f cons template void png_saver::operator() (image_view_gray64 const& image) const; template void png_saver::operator() (image_view_gray64s const& image) const; template void png_saver::operator() (image_view_gray64f const& image) const; -template void png_saver_pal::operator() (image_rgba8 const& image) const; template void png_saver_pal::operator() (image_gray8 const& image) const; template void png_saver_pal::operator() (image_gray8s const& image) const; template void png_saver_pal::operator() (image_gray16 const& image) const; @@ -349,7 +362,6 @@ template void png_saver_pal::operator() (image_gray32f const& ima template void png_saver_pal::operator() (image_gray64 const& image) const; template void png_saver_pal::operator() (image_gray64s const& image) const; template void png_saver_pal::operator() (image_gray64f const& image) const; -template void png_saver_pal::operator() (image_view_rgba8 const& image) const; template void png_saver_pal::operator() (image_view_gray8 const& image) const; template void png_saver_pal::operator() (image_view_gray8s const& image) const; template void png_saver_pal::operator() (image_view_gray16 const& image) const; diff --git a/src/image_util_tiff.cpp b/src/image_util_tiff.cpp index 68ef9d9f8..1a0573cb8 100644 --- a/src/image_util_tiff.cpp +++ b/src/image_util_tiff.cpp @@ -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 diff --git a/src/image_util_webp.cpp b/src/image_util_webp.cpp index c7b96aca5..86713ed85 100644 --- a/src/image_util_webp.cpp +++ b/src/image_util_webp.cpp @@ -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 @@ -360,7 +360,6 @@ void webp_saver::operator() (T const& image) const throw image_writer_exception("Mapnik does not support webp grayscale images"); } -template void webp_saver::operator() (image_rgba8 const& image) const; template void webp_saver::operator() (image_gray8 const& image) const; template void webp_saver::operator() (image_gray8s const& image) const; template void webp_saver::operator() (image_gray16 const& image) const; @@ -371,7 +370,6 @@ template void webp_saver::operator() (image_gray32f const& image) template void webp_saver::operator() (image_gray64 const& image) const; template void webp_saver::operator() (image_gray64s const& image) const; template void webp_saver::operator() (image_gray64f const& image) const; -template void webp_saver::operator() (image_view_rgba8 const& image) const; template void webp_saver::operator() (image_view_gray8 const& image) const; template void webp_saver::operator() (image_view_gray8s const& image) const; template void webp_saver::operator() (image_view_gray16 const& image) const; diff --git a/src/image_view.cpp b/src/image_view.cpp index 44e4d7716..5e51327c7 100644 --- a/src/image_view.cpp +++ b/src/image_view.cpp @@ -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 @@ -28,8 +28,6 @@ namespace mapnik { - -template class MAPNIK_DECL image_view; template class MAPNIK_DECL image_view; template class MAPNIK_DECL image_view; template class MAPNIK_DECL image_view; diff --git a/src/image_view_any.cpp b/src/image_view_any.cpp index 6fbbd7be4..80391e164 100644 --- a/src/image_view_any.cpp +++ b/src/image_view_any.cpp @@ -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 diff --git a/src/jpeg_reader.cpp b/src/jpeg_reader.cpp index 6b6e1b127..57c358fb9 100644 --- a/src/jpeg_reader.cpp +++ b/src/jpeg_reader.cpp @@ -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 diff --git a/src/json/extract_bounding_boxes_x3.cpp b/src/json/extract_bounding_boxes_x3.cpp new file mode 100644 index 000000000..500bb8f68 --- /dev/null +++ b/src/json/extract_bounding_boxes_x3.cpp @@ -0,0 +1,203 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +namespace mapnik { namespace json { + +template +struct calculate_bounding_box +{ + calculate_bounding_box(Box & box) + : box_(box) {} + + void operator()(mapnik::json::point const& pt) const + { + box_.init(pt.x, pt.y); + } + + void operator()(mapnik::json::ring const& r) const + { + for (auto const& pt : r) + { + if (!box_.valid()) box_.init(pt.x, pt.y); + else box_.expand_to_include(pt.x, pt.y); + } + } + + void operator()(mapnik::json::rings const& rs) const + { + for (auto const& r : rs) + { + operator()(r); + break; // consider first ring only + } + } + + void operator()(mapnik::json::rings_array const& rings_ar) const + { + for (auto const& rs : rings_ar) + { + operator()(rs); + } + } + + template + void operator() (T const& ) const {} + + Box & box_; +}; + +namespace grammar { + +namespace x3 = boost::spirit::x3; + +using base_iterator_type = char const*; +using x3::lit; +using x3::omit; +using x3::raw; +using x3::char_; +using x3::eps; + +struct feature_callback_tag; + +auto on_feature_callback = [] (auto const& ctx) +{ + // call our callback + x3::get(ctx)(_attr(ctx)); +}; + +namespace { auto const& geojson_value = geojson_grammar();} +// import unicode string rule +namespace { auto const& geojson_string = unicode_string_grammar(); } +// import positions rule +namespace { auto const& positions_rule = positions_grammar(); } + +// extract bounding box from GeoJSON Feature + +struct bracket_tag ; + +auto check_brackets = [](auto const& ctx) +{ + _pass(ctx) = (x3::get(ctx) > 0); +}; + +auto open_bracket = [](auto const& ctx) +{ + ++x3::get(ctx); +}; + +auto close_bracket = [](auto const& ctx) +{ + --x3::get(ctx); +}; + +auto assign_range = [](auto const& ctx) +{ + std::get<0>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto assign_bbox = [](auto const& ctx) +{ + std::get<1>(_val(ctx)) = std::move(_attr(ctx)); +}; + +auto extract_bounding_box = [](auto const& ctx) +{ + using box_type = typename std::decay::type; + box_type bbox; + calculate_bounding_box visitor(bbox); + mapnik::util::apply_visitor(visitor, _attr(ctx)); + _val(ctx) = std::move(bbox); +}; + +x3::rule > const coordinates_rule = "Coordinates"; +x3::rule, mapnik::box2d>> const bounding_box = "Bounding Box"; +x3::rule const feature_collection = "Feature Collection"; + +auto const coordinates_rule_def = lit("\"coordinates\"") >> lit(':') >> positions_rule[extract_bounding_box]; + +auto const bounding_box_def = raw[lit('{')[open_bracket] + >> *(eps[check_brackets] >> + ((lit("\"FeatureCollection\"") > eps(false)) + | + lit('{')[open_bracket] + | + lit('}')[close_bracket] + | + coordinates_rule[assign_bbox] + | + omit[geojson_string] + | + omit[char_]))][assign_range]; + + +auto const feature = bounding_box[on_feature_callback]; + +auto const key_value_ = omit[geojson_string] > lit(':') > omit[geojson_value] ; + +auto const features = lit("\"features\"") + > lit(':') > lit('[') > -(omit[feature] % lit(',')) > lit(']'); + +auto const type = lit("\"type\"") > lit(':') > lit("\"FeatureCollection\""); + +auto const feature_collection_def = lit('{') > (( type | features | key_value_) % lit(',')) > lit('}'); + +BOOST_SPIRIT_DEFINE ( + coordinates_rule, + bounding_box, + feature_collection + ); +} + +template +void extract_bounding_boxes(Iterator& start, Iterator const& end, Boxes & boxes) +{ + using namespace boost::spirit; + using space_type = mapnik::json::grammar::space_type; + using iterator_type = Iterator; + + extract_positions callback(start, boxes); + auto keys = mapnik::json::get_keys(); + std::size_t bracket_counter = 0; + auto feature_collection_impl = x3::with(std::ref(bracket_counter)) + [x3::with(std::ref(callback)) + [x3::with(std::ref(keys)) + [mapnik::json::grammar::feature_collection] + ]]; + + if (!x3::phrase_parse(start, end, feature_collection_impl, space_type())) + { + throw std::runtime_error("Can't extract bounding boxes"); + } + +} +using base_iterator_type = char const*; +template void extract_bounding_boxes(base_iterator_type&, base_iterator_type const&, boxes_type&); +template void extract_bounding_boxes(base_iterator_type&, base_iterator_type const& , boxes_type_f&); +}} diff --git a/src/json/mapnik_json_geometry_parser.cpp b/src/json/feature_from_geojson.cpp similarity index 69% rename from src/json/mapnik_json_geometry_parser.cpp rename to src/json/feature_from_geojson.cpp index 278d2c4be..b4d0188c8 100644 --- a/src/json/mapnik_json_geometry_parser.cpp +++ b/src/json/feature_from_geojson.cpp @@ -21,23 +21,25 @@ *****************************************************************************/ +// mapnik #include -#include - -// boost -#include -#include +#include namespace mapnik { namespace json { -bool from_geojson(std::string const& json, mapnik::geometry::geometry & geom) +bool from_geojson(std::string const& json, feature_impl & feature) { - using namespace boost::spirit; - static const geometry_grammar g; - standard::space_type space; - char const* start = json.c_str(); - char const* end = start + json.length(); - return qi::phrase_parse(start, end, g, space, geom); + try + { + const char* start = json.c_str(); + const char* end = start + json.length(); + mapnik::json::parse_feature(start, end, feature); + } + catch (...) + { + return false; + } + return true; } }} diff --git a/src/json/feature_grammar_x3.cpp b/src/json/feature_grammar_x3.cpp new file mode 100644 index 000000000..a34474d49 --- /dev/null +++ b/src/json/feature_grammar_x3.cpp @@ -0,0 +1,34 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(feature_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE(geometry_grammar_type, iterator_type, phrase_parse_context_type); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(feature_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(feature_grammar_type, iterator_type, feature_context_const_type); + +}}} diff --git a/src/json/generic_json.cpp b/src/json/generic_json.cpp deleted file mode 100644 index 7fb2e9fd3..000000000 --- a/src/json/generic_json.cpp +++ /dev/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 - * - *****************************************************************************/ - -#include - -namespace mapnik { namespace json { - -template -generic_json::generic_json() - : generic_json::base_type(value) -{ - qi::lit_type lit; - qi::_val_type _val; - qi::_1_type _1; - using phoenix::construct; - // generic json types - value = object | array | string_ | number - ; - - key_value = string_ > lit(':') > value - ; - - object = lit('{') - > -(key_value % lit(',')) - > lit('}') - ; - - array = lit('[') - > -(value % lit(',')) - > lit(']') - ; - - number = strict_double[_val = double_converter(_1)] - | int__[_val = integer_converter(_1)] - | lit("true") [_val = true] - | lit ("false") [_val = false] - | lit("null")[_val = construct()] - ; -} - -}} - -using iterator_type = char const*; -template struct mapnik::json::generic_json; diff --git a/src/json/generic_json_grammar_x3.cpp b/src/json/generic_json_grammar_x3.cpp new file mode 100644 index 000000000..7c768e6cf --- /dev/null +++ b/src/json/generic_json_grammar_x3.cpp @@ -0,0 +1,37 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(generic_json_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE(generic_json_grammar_type, iterator_type, context_type); +BOOST_SPIRIT_INSTANTIATE(generic_json_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE(generic_json_grammar_type, iterator_type, feature_context_const_type); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(generic_json_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(generic_json_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(generic_json_grammar_type, iterator_type, feature_context_const_type); + +}}} diff --git a/include/mapnik/csv/csv_grammar_impl.hpp b/src/json/geojson_grammar_x3.cpp similarity index 50% rename from include/mapnik/csv/csv_grammar_impl.hpp rename to src/json/geojson_grammar_x3.cpp index 560835443..2d9b30bb9 100644 --- a/include/mapnik/csv/csv_grammar_impl.hpp +++ b/src/json/geojson_grammar_x3.cpp @@ -20,42 +20,22 @@ * *****************************************************************************/ -#include -namespace mapnik { +#include +#include +#include -namespace qi = boost::spirit::qi; +namespace mapnik { namespace json { namespace grammar { -template -csv_line_grammar::csv_line_grammar() - : csv_line_grammar::base_type(line) -{ - qi::_r1_type _r1; - qi::_r2_type _r2; - qi::lit_type lit; - qi::char_type char_; - unesc_char.add - ("\\a", '\a') - ("\\b", '\b') - ("\\f", '\f') - ("\\n", '\n') - ("\\r", '\r') - ("\\t", '\t') - ("\\v", '\v') - ("\\\\",'\\') - ("\\\'", '\'') - ("\\\"", '\"') - ("\"\"", '\"') // double quote - ; - line = -lit("\r") > -lit("\n") > column(_r1, _r2) % lit(_r1) - ; - column = quoted(_r2) | *(char_ - lit(_r1)) - ; - quoted = lit(_r1) > text(_r1) > lit(_r1) // support unmatched quotes or not (??) - ; - text = *(unesc_char | (char_ - lit(_r1))) - ; - BOOST_SPIRIT_DEBUG_NODES((line)(column)(quoted)); -} +BOOST_SPIRIT_INSTANTIATE(geojson_grammar_type, iterator_type, context_type); +BOOST_SPIRIT_INSTANTIATE(key_value_type, iterator_type, context_type); -} // namespace mapnik +BOOST_SPIRIT_INSTANTIATE(geojson_grammar_type, iterator_type, extract_bounding_boxes_context_type); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(geojson_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(geojson_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(geojson_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE_UNUSED(geojson_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +}}} diff --git a/src/json/geometry_from_geojson.cpp b/src/json/geometry_from_geojson.cpp new file mode 100644 index 000000000..c9a0659f4 --- /dev/null +++ b/src/json/geometry_from_geojson.cpp @@ -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 + * + *****************************************************************************/ + + +// mapnik +#include +#include +#include + +namespace mapnik { namespace json { + +bool from_geojson(std::string const& json, mapnik::geometry::geometry & geom) +{ + namespace x3 = boost::spirit::x3; + using space_type = mapnik::json::grammar::space_type; + auto grammar = mapnik::json::geometry_grammar(); + try + { + const char* start = json.c_str(); + const char* end = start + json.length(); + if (!x3::phrase_parse(start, end, grammar, space_type(), geom)) + { + throw std::runtime_error("Can't parser GeoJSON Geometry"); + } + } + catch(...) { return false; } + + return true; +} + +}} diff --git a/include/mapnik/json/feature_generator.hpp b/src/json/mapnik_feature_to_geojson.cpp similarity index 81% rename from include/mapnik/json/feature_generator.hpp rename to src/json/mapnik_feature_to_geojson.cpp index f24df4ed8..3532fea97 100644 --- a/include/mapnik/json/feature_generator.hpp +++ b/src/json/mapnik_feature_to_geojson.cpp @@ -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,19 +20,16 @@ * *****************************************************************************/ -#ifndef MAPNIK_JSON_FEATURE_GENERATOR_HPP -#define MAPNIK_JSON_FEATURE_GENERATOR_HPP - // mapnik -#include +#include #include // boost #include -namespace mapnik { namespace json { +namespace mapnik { namespace util { -inline bool to_geojson(std::string & json, mapnik::feature_impl const& feature) +bool to_geojson(std::string & json, mapnik::feature_impl const& feature) { using sink_type = std::back_insert_iterator; static const mapnik::json::feature_generator_grammar grammar; @@ -41,5 +38,3 @@ inline bool to_geojson(std::string & json, mapnik::feature_impl const& feature) } }} - -#endif // MAPNIK_JSON_FEATURE_GENERATOR_HPP diff --git a/src/json/mapnik_geometry_to_geojson.cpp b/src/json/mapnik_geometry_to_geojson.cpp index ab2618093..9b76b0648 100644 --- a/src/json/mapnik_geometry_to_geojson.cpp +++ b/src/json/mapnik_geometry_to_geojson.cpp @@ -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 diff --git a/src/json/mapnik_json_generator_grammar.cpp b/src/json/mapnik_json_generator_grammar.cpp index 2b0171f98..5e5241fc5 100644 --- a/src/json/mapnik_json_generator_grammar.cpp +++ b/src/json/mapnik_json_generator_grammar.cpp @@ -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,8 +20,7 @@ * *****************************************************************************/ -#include - +#include #include #include #include @@ -31,5 +30,5 @@ using sink_type = std::back_insert_iterator; template struct mapnik::json::properties_generator_grammar; -template struct mapnik::json::feature_generator_grammar; template struct mapnik::json::geometry_generator_grammar >; +template struct mapnik::json::feature_generator_grammar; diff --git a/src/json/mapnik_topojson_grammar.cpp b/src/json/mapnik_topojson_grammar.cpp deleted file mode 100644 index e4b9dca32..000000000 --- a/src/json/mapnik_topojson_grammar.cpp +++ /dev/null @@ -1,28 +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 - * - *****************************************************************************/ - -#include -#include -#include - -using iterator_type = char const*; -template struct mapnik::topojson::topojson_grammar ; diff --git a/src/json/parse_feature.cpp b/src/json/parse_feature.cpp new file mode 100644 index 000000000..d95343ccb --- /dev/null +++ b/src/json/parse_feature.cpp @@ -0,0 +1,59 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include +#include + +namespace mapnik { namespace json { + +template +void parse_feature(Iterator start, Iterator end, feature_impl& feature, mapnik::transcoder const& tr) +{ + namespace x3 = boost::spirit::x3; + using space_type = mapnik::json::grammar::space_type; + auto grammar = x3::with(std::ref(tr)) + [x3::with(std::ref(feature)) + [ mapnik::json::feature_grammar() ]]; + if (!x3::phrase_parse(start, end, grammar, space_type())) + { + throw std::runtime_error("Can't parser GeoJSON Feature"); + } +} + +template +void parse_geometry(Iterator start, Iterator end, feature_impl& feature) +{ + namespace x3 = boost::spirit::x3; + using space_type = mapnik::json::grammar::space_type; + auto grammar = mapnik::json::geometry_grammar(); + if (!x3::phrase_parse(start, end, grammar, space_type(), feature.get_geometry())) + { + throw std::runtime_error("Can't parser GeoJSON Geometry"); + } +} + +using iterator_type = mapnik::json::grammar::iterator_type; +template void parse_feature(iterator_type,iterator_type, feature_impl& feature, mapnik::transcoder const& tr); +template void parse_geometry(iterator_type,iterator_type, feature_impl& feature); + +}} diff --git a/src/json/positions_grammar_x3.cpp b/src/json/positions_grammar_x3.cpp new file mode 100644 index 000000000..339137ae2 --- /dev/null +++ b/src/json/positions_grammar_x3.cpp @@ -0,0 +1,44 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, feature_context_const_type); + +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE(positions_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(positions_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(positions_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(positions_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE_UNUSED(positions_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +}}} diff --git a/src/json/mapnik_json_feature_grammar.cpp b/src/json/topojson_grammar_x3.cpp similarity index 76% rename from src/json/mapnik_json_feature_grammar.cpp rename to src/json/topojson_grammar_x3.cpp index 1aa6c7e9e..895b5e8cd 100644 --- a/src/json/mapnik_json_feature_grammar.cpp +++ b/src/json/topojson_grammar_x3.cpp @@ -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,11 @@ * *****************************************************************************/ -#include -#include -#include +#include +#include -using iterator_type = char const*; -template struct mapnik::json::feature_grammar; +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(topojson_grammar_type, iterator_type, phrase_parse_context_type); + +}}} diff --git a/src/json/unicode_string_grammar_x3.cpp b/src/json/unicode_string_grammar_x3.cpp new file mode 100644 index 000000000..76c0e731e --- /dev/null +++ b/src/json/unicode_string_grammar_x3.cpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include +#include +#include + +namespace mapnik { namespace json { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, feature_context_const_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, phrase_parse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, feature_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, feature_context_const_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_context_type_f); +BOOST_SPIRIT_INSTANTIATE_UNUSED(unicode_string_grammar_type, iterator_type, extract_bounding_boxes_reverse_context_type_f); + +}}} diff --git a/src/layer.cpp b/src/layer.cpp index 442026b4d..aa781860d 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -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 @@ -31,9 +31,9 @@ namespace mapnik { -layer::layer(std::string const& name, std::string const& srs) - : name_(name), - srs_(srs), +layer::layer(std::string const& _name, std::string const& _srs) + : name_(_name), + srs_(_srs), minimum_scale_denom_(0), maximum_scale_denom_(std::numeric_limits::max()), active_(true), @@ -42,9 +42,13 @@ layer::layer(std::string const& name, std::string const& srs) cache_features_(false), group_by_(), styles_(), + layers_(), ds_(), buffer_size_(), - maximum_extent_() {} + maximum_extent_(), + comp_op_(), + opacity_(1.0f) +{} layer::layer(layer const& rhs) : name_(rhs.name_), @@ -57,9 +61,13 @@ layer::layer(layer const& rhs) cache_features_(rhs.cache_features_), group_by_(rhs.group_by_), styles_(rhs.styles_), + layers_(rhs.layers_), ds_(rhs.ds_), buffer_size_(rhs.buffer_size_), - maximum_extent_(rhs.maximum_extent_) {} + maximum_extent_(rhs.maximum_extent_), + comp_op_(rhs.comp_op_), + opacity_(rhs.opacity_) +{} layer::layer(layer && rhs) : name_(std::move(rhs.name_)), @@ -72,9 +80,13 @@ layer::layer(layer && rhs) cache_features_(std::move(rhs.cache_features_)), group_by_(std::move(rhs.group_by_)), styles_(std::move(rhs.styles_)), + layers_(std::move(rhs.layers_)), ds_(std::move(rhs.ds_)), buffer_size_(std::move(rhs.buffer_size_)), - maximum_extent_(std::move(rhs.maximum_extent_)) {} + maximum_extent_(std::move(rhs.maximum_extent_)), + comp_op_(std::move(rhs.comp_op_)), + opacity_(std::move(rhs.opacity_)) +{} layer& layer::operator=(layer rhs) { @@ -92,6 +104,8 @@ layer& layer::operator=(layer rhs) std::swap(this->ds_, rhs.ds_); std::swap(this->buffer_size_, rhs.buffer_size_); std::swap(this->maximum_extent_, rhs.maximum_extent_); + std::swap(this->comp_op_, rhs.comp_op_); + std::swap(this->opacity_, rhs.opacity_); return *this; } @@ -109,14 +123,16 @@ bool layer::operator==(layer const& rhs) const (styles_ == rhs.styles_) && ((ds_ && rhs.ds_) ? *ds_ == *rhs.ds_ : ds_ == rhs.ds_) && (buffer_size_ == rhs.buffer_size_) && - (maximum_extent_ == rhs.maximum_extent_); + (maximum_extent_ == rhs.maximum_extent_) && + (comp_op_ == rhs.comp_op_) && + (opacity_ == rhs.opacity_); } layer::~layer() {} -void layer::set_name( std::string const& name) +void layer::set_name( std::string const& _name) { - name_ = name; + name_ = _name; } std::string const& layer::name() const @@ -124,9 +140,9 @@ std::string const& layer::name() const return name_; } -void layer::set_srs(std::string const& srs) +void layer::set_srs(std::string const& _srs) { - srs_ = srs; + srs_ = _srs; } std::string const& layer::srs() const @@ -149,6 +165,21 @@ std::vector & layer::styles() return styles_; } +void layer::add_layer(layer const& l) +{ + layers_.emplace_back(l); +} + +void layer::add_layer(layer && l) +{ + layers_.push_back(std::move(l)); +} + +std::vector const& layer::layers() const +{ + return layers_; +} + void layer::set_minimum_scale_denominator(double minimum_scale_denom) { minimum_scale_denom_=minimum_scale_denom; @@ -169,9 +200,9 @@ double layer::maximum_scale_denominator() const return maximum_scale_denom_; } -void layer::set_active(bool active) +void layer::set_active(bool _active) { - active_=active; + active_ = _active; } bool layer::active() const @@ -184,9 +215,9 @@ bool layer::visible(double scale_denom) const return active() && scale_denom >= minimum_scale_denom_ - 1e-6 && scale_denom < maximum_scale_denom_ + 1e-6; } -void layer::set_queryable(bool queryable) +void layer::set_queryable(bool _queryable) { - queryable_=queryable; + queryable_ = _queryable; } bool layer::queryable() const @@ -250,9 +281,9 @@ bool layer::clear_label_cache() const return clear_label_cache_; } -void layer::set_cache_features(bool cache_features) +void layer::set_cache_features(bool _cache_features) { - cache_features_ = cache_features; + cache_features_ = _cache_features; } bool layer::cache_features() const @@ -270,4 +301,24 @@ std::string const& layer::group_by() const return group_by_; } +void layer::set_comp_op(composite_mode_e comp_op) +{ + comp_op_ = comp_op; +} + +boost::optional layer::comp_op() const +{ + return comp_op_; +} + +void layer::set_opacity(double opacity) +{ + opacity_ = opacity; +} + +double layer::get_opacity() const +{ + return opacity_; +} + } diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index 3c904074c..b1216e6d4 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -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 diff --git a/src/load_map.cpp b/src/load_map.cpp index bf6324d20..767d32366 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -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 @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include @@ -104,7 +104,10 @@ public: private: void parse_map_include(Map & map, xml_node const& node); void parse_style(Map & map, xml_node const& node); - void parse_layer(Map & map, xml_node const& node); + + template + void parse_layer(Parent & parent, xml_node const& node); + void parse_symbolizer_base(symbolizer_base &sym, xml_node const& node); void parse_fontset(Map & map, xml_node const & node); bool parse_font(font_set & fset, xml_node const& f); @@ -133,7 +136,7 @@ private: void find_unused_nodes_recursive(xml_node const& node, std::string & error_text); std::string ensure_relative_to_xml(boost::optional const& opt_path); void ensure_exists(std::string const& file_path); - void check_styles(Map const & map) const throw (config_error); + void check_styles(Map const & map); boost::optional get_opt_color_attr(boost::property_tree::ptree const& node, std::string const& name); @@ -559,7 +562,8 @@ bool map_parser::parse_font(font_set & fset, xml_node const& f) return false; } -void map_parser::parse_layer(Map & map, xml_node const& node) +template +void map_parser::parse_layer(Parent & parent, xml_node const& node) { std::string name; try @@ -575,7 +579,7 @@ void map_parser::parse_layer(Map & map, xml_node const& node) name = node.get_attr("name", std::string("Unnamed")); // If no projection is given inherit from map - std::string srs = node.get_attr("srs", map.srs()); + std::string srs = node.get_attr("srs", parent.srs()); try { // create throwaway projection object here to ensure it is valid @@ -679,6 +683,24 @@ void map_parser::parse_layer(Map & map, xml_node const& node) } } + // compositing + optional comp_op_name = node.get_opt_attr("comp-op"); + if (comp_op_name) + { + optional comp_op = comp_op_from_string(*comp_op_name); + if (comp_op) + { + lyr.set_comp_op(*comp_op); + } + else + { + throw config_error("failed to parse comp-op: '" + *comp_op_name + "'"); + } + } + + optional opacity = node.get_opt_attr("opacity"); + if (opacity) lyr.set_opacity(*opacity); + for (auto const& child: node) { @@ -758,8 +780,12 @@ void map_parser::parse_layer(Map & map, xml_node const& node) throw config_error("Unknown exception occurred attempting to create datasoure for layer '" + lyr.name() + "'"); } } + else if (child.is("Layer")) + { + parse_layer(lyr, child); + } } - map.add_layer(std::move(lyr)); + parent.add_layer(std::move(lyr)); } catch (config_error const& ex) { @@ -895,6 +921,7 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const& nod set_symbolizer_property(sym, keys::comp_op, node); set_symbolizer_property(sym, keys::geometry_transform, node); set_symbolizer_property(sym, keys::simplify_algorithm, node); + set_symbolizer_property(sym, keys::extend, node); } void map_parser::parse_point_symbolizer(rule & rule, xml_node const & node) @@ -1155,10 +1182,14 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& node) if (placement_type) { placements = placements::registry::instance().from_xml(*placement_type, node, fontsets_, true); - } else { - placements = std::make_shared(); + if (!placements) + return; + } + else + { + placements = std::make_shared(); + placements->defaults.from_xml(node, fontsets_, true); } - placements->defaults.from_xml(node, fontsets_, true); if (strict_ && !placements->defaults.format_defaults.fontset) { @@ -1483,32 +1514,32 @@ bool map_parser::parse_raster_colorizer(raster_colorizer_ptr const& rc, colorizer_mode mode = n.get_attr("mode", COLORIZER_INHERIT); // value is required, and it must be bigger than the previous - optional value = n.get_opt_attr("value"); + optional val = n.get_opt_attr("value"); - if(!value) + if (!val) { throw config_error("stop tag missing value"); } - if(value < maximumValue) + if (val < maximumValue) { throw config_error("stop tag values must be in ascending order"); } - maximumValue = *value; + maximumValue = *val; optional label = n.get_opt_attr("label"); //append the stop - colorizer_stop tmpStop; - tmpStop.set_color(*stopcolor); - tmpStop.set_mode(mode); - tmpStop.set_value(*value); + colorizer_stop stop; + stop.set_color(*stopcolor); + stop.set_mode(mode); + stop.set_value(*val); if (label) { - tmpStop.set_label(*label); + stop.set_label(*label); } - rc->add_stop(tmpStop); + rc->add_stop(stop); } } } @@ -1691,7 +1722,7 @@ void map_parser::find_unused_nodes_recursive(xml_node const& node, std::string & } } -void map_parser::check_styles(Map const & map) const throw (config_error) +void map_parser::check_styles(Map const & map) { for (auto const & layer : map.layers()) { diff --git a/src/map.cpp b/src/map.cpp index ec0d9f83e..23d6d92f1 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -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 @@ -375,39 +375,39 @@ unsigned Map::height() const return height_; } -void Map::set_width(unsigned width) +void Map::set_width(unsigned _width) { - if (width != width_ && - width >= MIN_MAPSIZE && - width <= MAX_MAPSIZE) + if (_width != width_ && + _width >= MIN_MAPSIZE && + _width <= MAX_MAPSIZE) { - width_=width; + width_=_width; fixAspectRatio(); } } -void Map::set_height(unsigned height) +void Map::set_height(unsigned _height) { - if (height != height_ && - height >= MIN_MAPSIZE && - height <= MAX_MAPSIZE) + if (_height != height_ && + _height >= MIN_MAPSIZE && + _height <= MAX_MAPSIZE) { - height_=height; + height_ = _height; fixAspectRatio(); } } -void Map::resize(unsigned width,unsigned height) +void Map::resize(unsigned _width, unsigned _height) { - if ((width != width_ || - height != height_) && - width >= MIN_MAPSIZE && - width <= MAX_MAPSIZE && - height >= MIN_MAPSIZE && - height <= MAX_MAPSIZE) + if ((_width != width_ || + _height != height_) && + _width >= MIN_MAPSIZE && + _width <= MAX_MAPSIZE && + _height >= MIN_MAPSIZE && + _height <= MAX_MAPSIZE) { - width_=width; - height_=height; + width_ = _width; + height_ = _height; fixAspectRatio(); } } @@ -417,14 +417,14 @@ std::string const& Map::srs() const return srs_; } -void Map::set_srs(std::string const& srs) +void Map::set_srs(std::string const& _srs) { - srs_ = srs; + srs_ = _srs; } -void Map::set_buffer_size( int buffer_size) +void Map::set_buffer_size(int _buffer_size) { - buffer_size_ = buffer_size; + buffer_size_ = _buffer_size; } int Map::buffer_size() const diff --git a/src/mapped_memory_cache.cpp b/src/mapped_memory_cache.cpp index f35a379af..03654a6d7 100644 --- a/src/mapped_memory_cache.cpp +++ b/src/mapped_memory_cache.cpp @@ -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 diff --git a/src/marker_cache.cpp b/src/marker_cache.cpp index 059280c6b..74ccf642d 100644 --- a/src/marker_cache.cpp +++ b/src/marker_cache.cpp @@ -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 diff --git a/src/marker_helpers.cpp b/src/marker_helpers.cpp index eb0202169..86dcc8795 100644 --- a/src/marker_helpers.cpp +++ b/src/marker_helpers.cpp @@ -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 diff --git a/src/math.cpp b/src/math.cpp index 1fd2a4fff..b8d1950cb 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -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 diff --git a/src/memory_datasource.cpp b/src/memory_datasource.cpp index 1127f4b83..21acfd7f6 100644 --- a/src/memory_datasource.cpp +++ b/src/memory_datasource.cpp @@ -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 @@ -23,11 +23,11 @@ // mapnik #include #include -#include +#include #include #include #include -#include +#include // stl #include @@ -68,12 +68,12 @@ const char * memory_datasource::name() return "memory"; } -memory_datasource::memory_datasource(parameters const& params) - : datasource(params), +memory_datasource::memory_datasource(parameters const& _params) + : datasource(_params), desc_(memory_datasource::name(), - *params.get("encoding","utf-8")), + *params_.get("encoding","utf-8")), type_(datasource::Vector), - bbox_check_(*params.get("bbox_check", true)), + bbox_check_(*params_.get("bbox_check", true)), type_set_(false) {} memory_datasource::~memory_datasource() {} @@ -95,7 +95,7 @@ void memory_datasource::push(feature_ptr feature) throw std::runtime_error("Can not add a raster feature to a memory datasource that contains vectors"); } } - else + else { if (!type_set_) { diff --git a/src/palette.cpp b/src/palette.cpp index 1fc5b8b21..e1b8cad9e 100644 --- a/src/palette.cpp +++ b/src/palette.cpp @@ -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 diff --git a/src/params.cpp b/src/params.cpp index 8d3a2c859..61a2dc61a 100644 --- a/src/params.cpp +++ b/src/params.cpp @@ -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 @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace mapnik { diff --git a/src/parse_image_filters.cpp b/src/parse_image_filters.cpp new file mode 100644 index 000000000..74c29261c --- /dev/null +++ b/src/parse_image_filters.cpp @@ -0,0 +1,53 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include +// stl +#include + +namespace mapnik { + +namespace filter { + +bool parse_image_filters(std::string const& str, std::vector & image_filters) +{ + auto const& grammar = mapnik::image_filter_grammar(); + auto itr = str.begin(); + auto end = str.end(); + + boost::spirit::x3::ascii::space_type space; + bool r = false; + try + { + r = boost::spirit::x3::phrase_parse(itr, end, grammar, space, image_filters); + } + catch (...) + { + image_filters.clear(); + r = false; + } + return r && itr==end; +} + +}} diff --git a/src/parse_path.cpp b/src/parse_path.cpp index a3d67c2cb..4a9751d13 100644 --- a/src/parse_path.cpp +++ b/src/parse_path.cpp @@ -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 @@ -21,13 +21,13 @@ *****************************************************************************/ #include -#include -#include #include #include #include #include +#include + // stl #include @@ -35,12 +35,12 @@ namespace mapnik { path_expression_ptr parse_path(std::string const& str) { - static const path_expression_grammar g; + namespace x3 = boost::spirit::x3; auto path = std::make_shared(); - boost::spirit::standard_wide::space_type space; + using boost::spirit::x3::standard_wide::space; std::string::const_iterator itr = str.begin(); std::string::const_iterator end = str.end(); - bool r = qi::phrase_parse(itr, end, g, space, *path); + bool r = x3::phrase_parse(itr, end, path_expression_grammar(), space, *path); if (r && itr == end) { return path; diff --git a/src/parse_transform.cpp b/src/parse_transform.cpp index e2daaf480..ae56560f2 100644 --- a/src/parse_transform.cpp +++ b/src/parse_transform.cpp @@ -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,10 @@ * *****************************************************************************/ -#include -#include - +#include +#include +#include // transcoder_tag +#include // stl #include #include @@ -31,14 +32,28 @@ namespace mapnik { transform_list_ptr parse_transform(std::string const& str, std::string const& encoding) { - static const transform_expression_grammar g; - transform_list_ptr tl = std::make_shared(); + using boost::spirit::x3::ascii::space; + transform_list_ptr trans_list = std::make_shared(); std::string::const_iterator itr = str.begin(); std::string::const_iterator end = str.end(); - bool r = qi::phrase_parse(itr, end, g, space_type(), *tl); - if (r && itr == end) + mapnik::transcoder const tr(encoding); + auto const parser = boost::spirit::x3::with(std::ref(tr)) + [ + mapnik::transform_expression_grammar() + ]; + bool status = false; + try { - return tl; + status = boost::spirit::x3::phrase_parse(itr, end, parser, space, *trans_list); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + throw config_error("Failed to parse transform expression: \"" + str + "\""); + } + + if (status && itr == end) + { + return trans_list; } else { diff --git a/src/path_expression_grammar_x3.cpp b/src/path_expression_grammar_x3.cpp new file mode 100644 index 000000000..fe3bf276d --- /dev/null +++ b/src/path_expression_grammar_x3.cpp @@ -0,0 +1,32 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; +BOOST_SPIRIT_INSTANTIATE(path_expression_grammar_type, iterator_type, context_type); + +}} diff --git a/src/plugin.cpp b/src/plugin.cpp index b2186304d..ee39a7727 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -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 @@ -58,8 +58,8 @@ PluginInfo::PluginInfo(std::string const& filename, if (module_) module_->dl = LoadLibraryA(filename.c_str()); if (module_ && module_->dl) { - callable_returning_string name = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); - if (name) name_ = name(); + callable_returning_string name_call = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); + if (name_call) name_ = name_call(); callable_returning_void init_once = reinterpret_cast(dlsym(module_->dl, "on_plugin_load")); if (init_once) { init_once(); @@ -70,8 +70,8 @@ PluginInfo::PluginInfo(std::string const& filename, if (module_) module_->dl = dlopen(filename.c_str(),RTLD_LAZY); if (module_ && module_->dl) { - callable_returning_string name = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); - if (name) name_ = name(); + callable_returning_string name_call = reinterpret_cast(dlsym(module_->dl, library_name.c_str())); + if (name_call) name_ = name_call(); callable_returning_void init_once = reinterpret_cast(dlsym(module_->dl, "on_plugin_load")); if (init_once) { init_once(); diff --git a/src/png_reader.cpp b/src/png_reader.cpp index 8c58b2238..4f70dd928 100644 --- a/src/png_reader.cpp +++ b/src/png_reader.cpp @@ -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 diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp index 4761724de..c3b5aa098 100644 --- a/src/proj_transform.cpp +++ b/src/proj_transform.cpp @@ -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 @@ -22,7 +22,7 @@ // mapnik #include -#include +#include #include #include #include diff --git a/src/projection.cpp b/src/projection.cpp index 07f78ba11..10e7fd12b 100644 --- a/src/projection.cpp +++ b/src/projection.cpp @@ -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 diff --git a/src/rapidxml_loader.cpp b/src/rapidxml_loader.cpp index 94e829405..976e14f96 100644 --- a/src/rapidxml_loader.cpp +++ b/src/rapidxml_loader.cpp @@ -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 diff --git a/src/raster_colorizer.cpp b/src/raster_colorizer.cpp index 2c43df6b6..879da7fdb 100644 --- a/src/raster_colorizer.cpp +++ b/src/raster_colorizer.cpp @@ -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 @@ -22,7 +22,7 @@ // mapnik #include -#include +#include #include // for to_double #include #include @@ -48,10 +48,10 @@ static const char *colorizer_mode_strings[] = { IMPLEMENT_ENUM( colorizer_mode, colorizer_mode_strings ) -colorizer_stop::colorizer_stop(float value, colorizer_mode mode, +colorizer_stop::colorizer_stop(float val, colorizer_mode mode, color const& _color, std::string const& label) -: value_(value) +: value_(val) , mode_(mode) , color_(_color) , label_(label) @@ -135,14 +135,14 @@ void raster_colorizer::colorize(image_rgba8 & out, T const& in, int len = out.width() * out.height(); for (int i=0; i(fraction * (static_cast(end) - static_cast(start)) + static_cast(start)); } -unsigned raster_colorizer::get_color(float value) const +unsigned raster_colorizer::get_color(float val) const { int stopCount = stops_.size(); @@ -162,13 +162,13 @@ unsigned raster_colorizer::get_color(float value) const return default_color_.rgba(); } - //1 - Find the stop that the value is in + //1 - Find the stop that the val is in int stopIdx = -1; bool foundStopIdx = false; for(int i=0; i layout_thunks; + std::list layout_thunks; // layout manager to store and arrange bboxes of matched features group_layout_manager layout_manager(props->get_layout()); @@ -182,11 +182,13 @@ void render_group_symbolizer(group_symbolizer const& sym, pixel_position_list const& positions = helper.get(); for (pixel_position const& pos : positions) { - for (size_t layout_i = 0; layout_i < layout_thunks.size(); ++layout_i) + size_t layout_i = 0; + for (auto const& thunks : layout_thunks) { pixel_position const& offset = layout_manager.offset_at(layout_i); pixel_position render_offset = pos + offset; - render_thunks.render_list(layout_thunks[layout_i], render_offset); + render_thunks.render_list(thunks, render_offset); + ++layout_i; } } } diff --git a/src/renderer_common/render_markers_symbolizer.cpp b/src/renderer_common/render_markers_symbolizer.cpp index 6706cb1cd..c0c148b0a 100644 --- a/src/renderer_common/render_markers_symbolizer.cpp +++ b/src/renderer_common/render_markers_symbolizer.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -128,12 +128,12 @@ struct render_marker_symbolizer_visitor agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); - boost::optional const& stock_vector_marker = mark.get_data(); - svg_path_ptr marker_ptr = *stock_vector_marker; + svg_path_ptr stock_vector_marker = mark.get_data(); + svg_path_ptr marker_ptr = stock_vector_marker; bool is_ellipse = false; svg_attribute_type s_attributes; - auto const& r_attributes = get_marker_attributes(*stock_vector_marker, s_attributes); + auto const& r_attributes = get_marker_attributes(stock_vector_marker, s_attributes); // special case for simple ellipse markers // to allow for full control over rx/ry dimensions diff --git a/src/renderer_common/render_pattern.cpp b/src/renderer_common/render_pattern.cpp index 5e6f95820..f33645996 100644 --- a/src/renderer_common/render_pattern.cpp +++ b/src/renderer_common/render_pattern.cpp @@ -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 @@ -21,7 +21,7 @@ *****************************************************************************/ // mapnik #include -#include +#include #include #include #include diff --git a/src/renderer_common/render_thunk_extractor.cpp b/src/renderer_common/render_thunk_extractor.cpp index c437262da..9307064eb 100644 --- a/src/renderer_common/render_thunk_extractor.cpp +++ b/src/renderer_common/render_thunk_extractor.cpp @@ -55,7 +55,7 @@ struct thunk_markers_renderer_context : markers_renderer_context { vector_marker_render_thunk thunk(src, attrs, marker_tr, params.opacity, comp_op_, params.snap_to_pixels); - thunks_.push_back(std::make_unique(std::move(thunk))); + thunks_.emplace_back(std::move(thunk)); } virtual void render_marker(image_rgba8 const& src, @@ -64,7 +64,7 @@ struct thunk_markers_renderer_context : markers_renderer_context { raster_marker_render_thunk thunk(src, marker_tr, params.opacity, comp_op_, params.snap_to_pixels); - thunks_.push_back(std::make_unique(std::move(thunk))); + thunks_.emplace_back(std::move(thunk)); } private: @@ -87,8 +87,8 @@ render_thunk_extractor::render_thunk_extractor(box2d & box, void render_thunk_extractor::operator()(markers_symbolizer const& sym) const { - using context_type = detail::thunk_markers_renderer_context; - context_type renderer_context(sym, feature_, vars_, thunks_); + using renderer_context_type = detail::thunk_markers_renderer_context; + renderer_context_type renderer_context(sym, feature_, vars_, thunks_); render_markers_symbolizer( sym, feature_, prj_trans_, common_, clipping_extent_, renderer_context); @@ -128,7 +128,7 @@ void render_thunk_extractor::extract_text_thunk(text_render_thunk::helper_ptr && halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer, feature_, common_.vars_, HALO_RASTERIZER_FULL); text_render_thunk thunk(std::move(helper), opacity, comp_op, halo_rasterizer); - thunks_.push_back(std::make_unique(std::move(thunk))); + thunks_.emplace_back(std::move(thunk)); update_box(); } diff --git a/src/request.cpp b/src/request.cpp index f74f62c38..2f5e2eddc 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -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 diff --git a/src/rule.cpp b/src/rule.cpp index 2fec472a0..e6b2c0244 100644 --- a/src/rule.cpp +++ b/src/rule.cpp @@ -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 diff --git a/src/save_map.cpp b/src/save_map.cpp index f3d89153c..f5825ce73 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -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 @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include @@ -488,7 +488,8 @@ void serialize_datasource( ptree & layer_node, datasource_ptr datasource) void serialize_parameters( ptree & map_node, mapnik::parameters const& params) { - if (params.size()) { + if (params.size()) + { ptree & params_node = map_node.push_back( ptree::value_type("Parameters", ptree()))->second; @@ -513,6 +514,17 @@ void serialize_layer( ptree & map_node, layer const& lyr, bool explicit_defaults set_attr( layer_node, "name", lyr.name() ); } + auto const comp_op = lyr.comp_op(); + + if (comp_op) + { + set_attr(layer_node, "comp-op", *comp_op_to_string(*comp_op)); + } + else if (explicit_defaults) + { + set_attr(layer_node, "comp-op", "src-over"); + } + if ( lyr.srs() != "" ) { set_attr( layer_node, "srs", lyr.srs() ); @@ -582,6 +594,12 @@ void serialize_layer( ptree & map_node, layer const& lyr, bool explicit_defaults { serialize_datasource( layer_node, datasource ); } + + // serialize nested layers + for (auto const& child : lyr.layers()) + { + serialize_layer(layer_node, child, explicit_defaults ); + } } void serialize_map(ptree & pt, Map const& map, bool explicit_defaults) diff --git a/src/scale_denominator.cpp b/src/scale_denominator.cpp index 7e7b2f14d..fdd7fba7a 100644 --- a/src/scale_denominator.cpp +++ b/src/scale_denominator.cpp @@ -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 diff --git a/src/svg/output/process_line_symbolizer.cpp b/src/svg/output/process_line_symbolizer.cpp index 5db205eff..e2063a6ce 100644 --- a/src/svg/output/process_line_symbolizer.cpp +++ b/src/svg/output/process_line_symbolizer.cpp @@ -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 diff --git a/src/svg/output/process_polygon_symbolizer.cpp b/src/svg/output/process_polygon_symbolizer.cpp index c5a1f8709..be994ec1e 100644 --- a/src/svg/output/process_polygon_symbolizer.cpp +++ b/src/svg/output/process_polygon_symbolizer.cpp @@ -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 diff --git a/src/svg/output/process_symbolizers.cpp b/src/svg/output/process_symbolizers.cpp index 6ff486f7f..c7f7ec9a7 100644 --- a/src/svg/output/process_symbolizers.cpp +++ b/src/svg/output/process_symbolizers.cpp @@ -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 @@ -32,8 +32,8 @@ #include #include #include -#include -#include +#include +#include #include #include // boost diff --git a/src/svg/output/svg_generator.cpp b/src/svg/output/svg_generator.cpp index cb8eb79ec..9a353c087 100644 --- a/src/svg/output/svg_generator.cpp +++ b/src/svg/output/svg_generator.cpp @@ -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 diff --git a/src/svg/output/svg_output_attributes.cpp b/src/svg/output/svg_output_attributes.cpp index bf05d874b..2612a71a3 100644 --- a/src/svg/output/svg_output_attributes.cpp +++ b/src/svg/output/svg_output_attributes.cpp @@ -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 diff --git a/src/svg/output/svg_output_grammars.cpp b/src/svg/output/svg_output_grammars.cpp index 398c41a7e..b048968a1 100644 --- a/src/svg/output/svg_output_grammars.cpp +++ b/src/svg/output/svg_output_grammars.cpp @@ -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 diff --git a/src/svg/output/svg_renderer.cpp b/src/svg/output/svg_renderer.cpp index 569164645..2519d54fa 100644 --- a/src/svg/output/svg_renderer.cpp +++ b/src/svg/output/svg_renderer.cpp @@ -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 diff --git a/src/svg/svg_parser.cpp b/src/svg/svg_parser.cpp index 827f557fc..b4d90cda7 100644 --- a/src/svg/svg_parser.cpp +++ b/src/svg/svg_parser.cpp @@ -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 @@ -41,9 +41,8 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include +#include #include #include #include @@ -55,6 +54,24 @@ #include #include +namespace mapnik { namespace svg { +struct viewbox +{ + double x0; + double y0; + double x1; + double y1; +}; +}} + +BOOST_FUSION_ADAPT_STRUCT ( + mapnik::svg::viewbox, + (double, x0) + (double, y0) + (double, x1) + (double, y1) + ) + namespace mapnik { namespace svg { namespace rapidxml = boost::property_tree::detail::rapidxml; @@ -77,29 +94,26 @@ void parse_attr(svg_parser & parser,rapidxml::xml_node const* node); void parse_attr(svg_parser & parser,char const * name, char const* value); +namespace { namespace grammar { + +namespace x3 = boost::spirit::x3; + using color_lookup_type = std::vector >; -namespace qi = boost::spirit::qi; using pairs_type = std::vector >; -template -struct key_value_sequence_ordered - : qi::grammar -{ - key_value_sequence_ordered() - : key_value_sequence_ordered::base_type(query) - { - qi::lit_type lit; - qi::char_type char_; - query = pair >> *( lit(';') >> pair); - pair = key >> -(':' >> value); - key = char_("a-zA-Z_") >> *char_("a-zA-Z_0-9-"); - value = +(char_ - lit(';')); - } +x3::rule const key_value_sequence_ordered("key_value_sequence_ordered"); +x3::rule > key_value("key_value"); +x3::rule key("key"); +x3::rule value("value"); - qi::rule query; - qi::rule(), SkipType> pair; - qi::rule key, value; -}; +auto const key_def = x3::char_("a-zA-Z_") > *x3::char_("a-zA-Z_0-9-"); +auto const value_def = +(x3::char_ - ';'); +auto const key_value_def = key > -(':' > value); +auto const key_value_sequence_ordered_def = key_value % ';'; + +BOOST_SPIRIT_DEFINE(key, value, key_value, key_value_sequence_ordered); + +}} template mapnik::color parse_color(T & error_messages, const char* str) @@ -126,10 +140,9 @@ agg::rgba8 parse_color_agg(T & error_messages, const char* str) template double parse_double(T & error_messages, const char* str) { - using namespace boost::spirit::qi; - double_type double_; + using namespace boost::spirit::x3; double val = 0.0; - if (!parse(str, str + std::strlen(str),double_,val)) + if (!parse(str, str + std::strlen(str), double_, val)) { error_messages.emplace_back("Failed to parse double: \"" + std::string(str) + "\""); } @@ -138,15 +151,11 @@ double parse_double(T & error_messages, const char* str) // https://www.w3.org/TR/SVG/coords.html#Units template -double parse_svg_value(T & error_messages, const char* str, bool & percent) +double parse_svg_value(T & error_messages, const char* str, bool & is_percent) { - using skip_type = boost::spirit::ascii::space_type; - using boost::phoenix::ref; - qi::double_type double_; - qi::lit_type lit; - qi::_1_type _1; + namespace x3 = boost::spirit::x3; double val = 0.0; - qi::symbols units; + x3::symbols units; units.add ("px", 1.0) ("pt", DPI/72.0) @@ -157,12 +166,17 @@ double parse_svg_value(T & error_messages, const char* str, bool & percent) ; const char* cur = str; // phrase_parse modifies the first iterator const char* end = str + std::strlen(str); - if (!qi::phrase_parse(cur, end, - double_[ref(val) = _1][ref(percent) = false] - > - (units[ ref(val) *= _1] - | - lit('%')[ref(val) *= 0.01][ref(percent) = true]), - skip_type())) + + auto apply_value = [&](auto const& ctx) { val = _attr(ctx); is_percent = false; }; + auto apply_units = [&](auto const& ctx) { val *= _attr(ctx); }; + auto apply_percent = [&](auto const& ctx) { val *= 0.01; is_percent = true; }; + + if (!x3::phrase_parse(cur, end, + x3::double_[apply_value] + > - (units[apply_units] + | + x3::lit('%')[apply_percent]), + x3::space)) { error_messages.emplace_back("Failed to parse SVG value: '" + std::string(str) + "'"); } @@ -174,46 +188,35 @@ double parse_svg_value(T & error_messages, const char* str, bool & percent) return val; } -template -bool parse_double_list(T & error_messages, const char* str, double* list) +template +bool parse_viewbox(T & error_messages, const char* str, V & viewbox) { - using namespace boost::spirit::qi; - using boost::phoenix::ref; - _1_type _1; - double_type double_; - lit_type lit; - using skip_type = boost::spirit::ascii::space_type; - - if (!phrase_parse(str, str + std::strlen(str), - double_[ref(list[0])=_1] >> -lit(',') >> - double_[ref(list[1])=_1] >> -lit(',') >> - double_[ref(list[2])=_1] >> -lit(',') >> - double_[ref(list[3])=_1], skip_type())) + namespace x3 = boost::spirit::x3; + if ( !x3::phrase_parse(str, str + std::strlen(str), + x3::double_ > -x3::lit(',') > + x3::double_ > -x3::lit(',') > + x3::double_ > -x3::lit(',') > + x3::double_, x3::space, viewbox)) { - error_messages.emplace_back("failed to parse list of doubles from " + std::string(str)); + error_messages.emplace_back("failed to parse SVG viewbox from " + std::string(str)); return false; } return true; } -bool parse_style (char const* str, pairs_type & v) +bool parse_style (char const* str, grammar::pairs_type & v) { - using namespace boost::spirit::qi; - using skip_type = boost::spirit::ascii::space_type; - key_value_sequence_ordered kv_parser; - return phrase_parse(str, str + std::strlen(str), kv_parser, skip_type(), v); + namespace x3 = boost::spirit::x3; + return x3::phrase_parse(str, str + std::strlen(str), grammar::key_value_sequence_ordered , x3::space, v); } bool parse_id_from_url (char const* str, std::string & id) { - using namespace boost::spirit::qi; - using skip_type = boost::spirit::ascii::space_type; - qi::_1_type _1; - qi::char_type char_; - qi::lit_type lit; - return phrase_parse(str, str + std::strlen(str), - lit("url") > "(" > "#" > *(char_ - lit(')'))[boost::phoenix::ref(id) += _1] > ")", - skip_type()); + namespace x3 = boost::spirit::x3; + auto extract_id = [&](auto const& ctx) { id += _attr(ctx); }; + return x3::phrase_parse(str, str + std::strlen(str), + x3::lit("url") > '(' > '#' > *(x3::char_ - ')')[extract_id] > ')', + x3::space); } bool traverse_tree(svg_parser & parser, rapidxml::xml_node const* node) @@ -517,7 +520,7 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node const* node) double width = 0; double height = 0; double aspect_ratio = 1; - double viewbox[4] = {0,0,0,0}; + viewbox vbox = {0,0,0,0}; bool has_viewbox = false; bool has_percent_height = true; bool has_percent_width = true; @@ -535,23 +538,23 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node const* node) auto const* viewbox_attr = node->first_attribute("viewBox"); if (viewbox_attr) { - has_viewbox = parse_double_list(parser.error_messages_, viewbox_attr->value(), viewbox); + has_viewbox = parse_viewbox(parser.error_messages_, viewbox_attr->value(), vbox); } if (has_percent_width && !has_percent_height && has_viewbox) { - aspect_ratio = viewbox[2] / viewbox[3]; + aspect_ratio = vbox.x1 / vbox.y1; width = aspect_ratio * height; } else if (!has_percent_width && has_percent_height && has_viewbox) { - aspect_ratio = viewbox[2] / viewbox[3]; + aspect_ratio = vbox.x1 / vbox.y1; height = height / aspect_ratio; } else if (has_percent_width && has_percent_height && has_viewbox) { - width = viewbox[2]; - height = viewbox[3]; + width = vbox.x1; + height = vbox.y1; } parser.path_.set_dimensions(width, height); diff --git a/src/json/mapnik_json_positions_grammar.cpp b/src/svg/svg_path_grammar_x3.cpp similarity index 58% rename from src/json/mapnik_json_positions_grammar.cpp rename to src/svg/svg_path_grammar_x3.cpp index a13f0e313..b1b04434d 100644 --- a/src/json/mapnik_json_positions_grammar.cpp +++ b/src/svg/svg_path_grammar_x3.cpp @@ -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,8 +20,18 @@ * *****************************************************************************/ -#include -#include +#include -using iterator_type = char const*; -template struct mapnik::json::positions_grammar; +namespace mapnik { namespace svg { namespace grammar { + +#define BOOST_SPIRIT_INSTANTIATE_UNUSED(rule_type, Iterator, Context) \ + template bool parse_rule( \ + rule_type rule_ \ + , Iterator& first, Iterator const& last \ + , Context const& context, boost::spirit::x3::unused_type const& ); \ + /***/ + +BOOST_SPIRIT_INSTANTIATE_UNUSED(svg_path_grammar_type, iterator_type, svg_parse_context_type); +BOOST_SPIRIT_INSTANTIATE_UNUSED(svg_points_grammar_type, iterator_type, svg_parse_context_type); + +}}} diff --git a/src/svg/svg_path_parser.cpp b/src/svg/svg_path_parser.cpp index 52f95ef6e..53c3a94ee 100644 --- a/src/svg/svg_path_parser.cpp +++ b/src/svg/svg_path_parser.cpp @@ -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 @@ -23,7 +23,7 @@ // mapnik #include -#include +#include // stl #include #include @@ -35,14 +35,30 @@ template bool parse_path(const char* wkt, PathType& p) { using namespace boost::spirit; - using iterator_type = const char*; - using skip_type = ascii::space_type; - static const svg_path_grammar g; + using iterator_type = char const*; iterator_type first = wkt; iterator_type last = wkt + std::strlen(wkt); - bool status = qi::phrase_parse(first, last, (g)(boost::phoenix::ref(p)), skip_type()); - return (status && (first == last)); + bool relative = false; + using space_type = mapnik::svg::grammar::space_type; + auto const grammar = x3::with(std::ref(p)) + [ x3::with(std::ref(relative)) + [mapnik::svg::svg_path_grammar()]]; + + try + { + if (!x3::phrase_parse(first, last, grammar, space_type()) + || first != last) + { + throw std::runtime_error("Failed to parse svg-path"); + } + } + catch (...) + { + return false; + } + return true; } + template bool MAPNIK_DECL parse_path(const char*, svg_converter_type&); } // namespace svg diff --git a/src/svg/svg_points_parser.cpp b/src/svg/svg_points_parser.cpp index 3e292ba70..9ede3b7de 100644 --- a/src/svg/svg_points_parser.cpp +++ b/src/svg/svg_points_parser.cpp @@ -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 @@ -22,7 +22,7 @@ // mapnik #include -#include +#include // stl #include #include @@ -34,12 +34,29 @@ template bool parse_points(const char* wkt, PathType& p) { using namespace boost::spirit; - using iterator_type = const char*; - using skip_type = ascii::space_type; - static const svg_points_grammar g; + using iterator_type = char const*; + using space_type = mapnik::svg::grammar::space_type; iterator_type first = wkt; iterator_type last = wkt + std::strlen(wkt); - return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(p)), skip_type()); + bool relative = false; + + auto const grammar = x3::with(std::ref(p)) + [ x3::with(std::ref(relative)) + [mapnik::svg::svg_points_grammar()]]; + + try + { + if (!x3::phrase_parse(first, last, grammar, space_type()) + || first != last) + { + throw std::runtime_error("Failed to parse svg-path"); + } + } + catch (...) + { + return false; + } + return true; } template bool parse_points(const char*, svg_converter_type&); diff --git a/src/svg/svg_transform_parser.cpp b/src/svg/svg_transform_parser.cpp index 7b90ca4cb..46aca7fd6 100644 --- a/src/svg/svg_transform_parser.cpp +++ b/src/svg/svg_transform_parser.cpp @@ -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 @@ -22,24 +22,37 @@ // mapnik #include -#include +#include // stl #include #include -namespace mapnik { -namespace svg { +namespace mapnik { namespace svg { -template -bool parse_svg_transform(const char* wkt, TransformType& tr) +template +bool parse_svg_transform(const char* wkt, Transform& tr) { using namespace boost::spirit; - using iterator_type = const char*; - using skip_type = ascii::space_type; - static const svg_transform_grammar g; + using iterator_type = char const*; iterator_type first = wkt; iterator_type last = wkt + std::strlen(wkt); - return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(tr)), skip_type()); + using space_type = mapnik::svg::grammar::space_type; + auto const grammar = x3::with(std::ref(tr)) + [mapnik::svg::svg_transform_grammar()]; + + try + { + if (!x3::phrase_parse(first, last, grammar, space_type()) + || first != last) + { + throw std::runtime_error("Failed to parse svg-transform"); + } + } + catch (...) + { + return false; + } + return true; } template bool MAPNIK_DECL parse_svg_transform(const char*, agg::trans_affine&); diff --git a/src/symbolizer.cpp b/src/symbolizer.cpp index 6d3109f8e..7833663b5 100644 --- a/src/symbolizer.cpp +++ b/src/symbolizer.cpp @@ -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 @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace mapnik { diff --git a/src/symbolizer_enumerations.cpp b/src/symbolizer_enumerations.cpp index 94227dfd2..1c8098271 100644 --- a/src/symbolizer_enumerations.cpp +++ b/src/symbolizer_enumerations.cpp @@ -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 diff --git a/src/symbolizer_keys.cpp b/src/symbolizer_keys.cpp index fa5c73d32..db04a296a 100644 --- a/src/symbolizer_keys.cpp +++ b/src/symbolizer_keys.cpp @@ -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 @@ -158,6 +158,7 @@ static const property_meta_type key_meta[const_max_key] = property_types::target_direction}, property_meta_type{ "avoid-edges",nullptr, property_types::target_bool }, property_meta_type{ "font-feature-settings", nullptr, property_types::target_font_feature_settings }, + property_meta_type{ "extend", nullptr, property_types::target_double}, }; diff --git a/src/text/face.cpp b/src/text/face.cpp index 1d3ad7820..1c3a4ba25 100644 --- a/src/text/face.cpp +++ b/src/text/face.cpp @@ -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 @@ -29,6 +29,7 @@ extern "C" { #include FT_GLYPH_H +#include FT_TRUETYPE_TABLES_H } #pragma GCC diagnostic pop @@ -37,16 +38,23 @@ namespace mapnik { font_face::font_face(FT_Face face) - : face_(face) {} + : face_(face) +{ + static const uint32_t tag = FT_MAKE_TAG('C', 'B', 'D', 'T'); + unsigned long length = 0; + FT_Load_Sfnt_Table(face_, tag, 0, nullptr, &length); + if (length) color_font_ = true; +} bool font_face::set_character_sizes(double size) { - return (FT_Set_Char_Size(face_,0,static_cast(size * (1<<6)),0,0) == 0); + return (FT_Set_Char_Size(face_, 0, static_cast(size * (1 << 6)), 0, 0) == 0); } bool font_face::set_unscaled_character_sizes() { - return (FT_Set_Char_Size(face_,0,face_->units_per_EM,0,0) == 0); + FT_F26Dot6 char_height = face_->units_per_EM > 0 ? face_->units_per_EM : 2048.0; + return (FT_Set_Char_Size(face_, 0, char_height, 0, 0) == 0); } bool font_face::glyph_dimensions(glyph_info & glyph) const @@ -54,11 +62,14 @@ bool font_face::glyph_dimensions(glyph_info & glyph) const FT_Vector pen; pen.x = 0; pen.y = 0; + if (color_font_) FT_Select_Size(face_, 0); FT_Set_Transform(face_, 0, &pen); - - if (FT_Load_Glyph(face_, glyph.glyph_index, FT_LOAD_NO_HINTING)) + FT_Int32 load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; + if (color_font_) load_flags |= FT_LOAD_COLOR ; + if (FT_Load_Glyph(face_, glyph.glyph_index, load_flags)) { - MAPNIK_LOG_ERROR(font_face) << "FT_Load_Glyph failed"; + MAPNIK_LOG_ERROR(font_face) << "FT_Load_Glyph failed :( index=" << glyph.glyph_index << " " << load_flags + << " " << face_->family_name << " " << face_->style_name ; return false; } FT_Glyph image; @@ -93,11 +104,11 @@ void font_face_set::add(face_ptr face) faces_.push_back(face); } -void font_face_set::set_character_sizes(double size) +void font_face_set::set_character_sizes(double _size) { for (face_ptr const& face : faces_) { - face->set_character_sizes(size); + face->set_character_sizes(_size); } } diff --git a/src/text/font_feature_settings.cpp b/src/text/font_feature_settings.cpp index 81a62f9dd..8a9b32b17 100644 --- a/src/text/font_feature_settings.cpp +++ b/src/text/font_feature_settings.cpp @@ -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 @@ -26,11 +26,10 @@ #pragma GCC diagnostic push #include -#include +#include #include #pragma GCC diagnostic pop - // stl #include #include @@ -52,23 +51,14 @@ font_feature_settings::font_feature_settings() void font_feature_settings::from_string(std::string const& features) { features_.clear(); - if (std::all_of(features.begin(), features.end(), isspace)) return; - namespace qi = boost::spirit::qi; - qi::char_type char_; - qi::as_string_type as_string; - -#if BOOST_VERSION <= 104800 - // Call correct overload. - using std::placeholders::_1; - void (font_feature_settings::*append)(std::string const&) = &font_feature_settings::append; - if (!qi::parse(features.begin(), features.end(), as_string[+(char_ - ',')][std::bind(append, this, _1)] % ',')) -#else - auto app = [&](std::string const& s) { append(s); }; - if (!qi::parse(features.begin(), features.end(), as_string[+(char_ - ',')][app] % ',')) -#endif - + namespace x3 = boost::spirit::x3; + auto appender = [&](auto const& ctx) + { + this->append(_attr(ctx)); + }; + if (!x3::parse(features.begin(), features.end(), (+(x3::char_ - ','))[appender] % ',')) { throw config_error("failed to parse font-feature-settings: '" + features + "'"); } diff --git a/src/text/font_library.cpp b/src/text/font_library.cpp index 37fd6a43b..2dca13fe6 100644 --- a/src/text/font_library.cpp +++ b/src/text/font_library.cpp @@ -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 diff --git a/src/text/formatting/base.cpp b/src/text/formatting/base.cpp index 8d8f0a1bb..c4e59fcc5 100644 --- a/src/text/formatting/base.cpp +++ b/src/text/formatting/base.cpp @@ -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 diff --git a/src/text/formatting/format.cpp b/src/text/formatting/format.cpp index 8a6a8cc9d..4f054af5f 100644 --- a/src/text/formatting/format.cpp +++ b/src/text/formatting/format.cpp @@ -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 diff --git a/src/text/formatting/layout.cpp b/src/text/formatting/layout.cpp index 9a5ca10aa..711422b8e 100644 --- a/src/text/formatting/layout.cpp +++ b/src/text/formatting/layout.cpp @@ -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 diff --git a/src/text/formatting/list.cpp b/src/text/formatting/list.cpp index 4bf7c4d2d..686e5424c 100644 --- a/src/text/formatting/list.cpp +++ b/src/text/formatting/list.cpp @@ -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 @@ -37,27 +37,27 @@ namespace formatting { void list_node::to_xml(boost::property_tree::ptree & xml) const { - for (node_ptr const& node : children_) + for (node_ptr const& n : children_) { - node->to_xml(xml); + n->to_xml(xml); } } void list_node::apply(evaluated_format_properties_ptr const& p, feature_impl const& feature, attributes const& vars, text_layout & output) const { - for (node_ptr const& node : children_) + for (node_ptr const& n : children_) { - node->apply(p, feature, vars, output); + n->apply(p, feature, vars, output); } } void list_node::add_expressions(expression_set &output) const { - for (node_ptr const& node : children_) + for (node_ptr const& n : children_) { - node->add_expressions(output); + n->add_expressions(output); } } diff --git a/src/text/formatting/registry.cpp b/src/text/formatting/registry.cpp index 6114f97e5..09c1ee89a 100644 --- a/src/text/formatting/registry.cpp +++ b/src/text/formatting/registry.cpp @@ -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 diff --git a/src/text/formatting/text.cpp b/src/text/formatting/text.cpp index 3158f20e2..6cc70b09d 100644 --- a/src/text/formatting/text.cpp +++ b/src/text/formatting/text.cpp @@ -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 diff --git a/src/text/glyph_positions.cpp b/src/text/glyph_positions.cpp index fdcb3a811..e56393c7c 100644 --- a/src/text/glyph_positions.cpp +++ b/src/text/glyph_positions.cpp @@ -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 diff --git a/src/text/itemizer.cpp b/src/text/itemizer.cpp index 9f01035f1..bf8d4b725 100644 --- a/src/text/itemizer.cpp +++ b/src/text/itemizer.cpp @@ -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 diff --git a/src/text/placement_finder.cpp b/src/text/placement_finder.cpp index e4adddf3e..a580ac297 100644 --- a/src/text/placement_finder.cpp +++ b/src/text/placement_finder.cpp @@ -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 @@ -35,6 +35,7 @@ // stl #include +#include namespace mapnik { diff --git a/src/text/placements/base.cpp b/src/text/placements/base.cpp index 861c5664a..b01adee66 100644 --- a/src/text/placements/base.cpp +++ b/src/text/placements/base.cpp @@ -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 diff --git a/src/text/placements/dummy.cpp b/src/text/placements/dummy.cpp index dd51db8b8..76b8537cf 100644 --- a/src/text/placements/dummy.cpp +++ b/src/text/placements/dummy.cpp @@ -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 diff --git a/src/text/placements/list.cpp b/src/text/placements/list.cpp index 7d609f2c4..ca3cda4b4 100644 --- a/src/text/placements/list.cpp +++ b/src/text/placements/list.cpp @@ -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 diff --git a/src/text/placements/registry.cpp b/src/text/placements/registry.cpp index e24131d03..cd5f44d1a 100644 --- a/src/text/placements/registry.cpp +++ b/src/text/placements/registry.cpp @@ -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 diff --git a/src/text/placements/simple.cpp b/src/text/placements/simple.cpp index 800a3d3e3..0bec3423d 100644 --- a/src/text/placements/simple.cpp +++ b/src/text/placements/simple.cpp @@ -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 @@ -32,9 +32,7 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include #include #pragma GCC diagnostic pop @@ -43,12 +41,9 @@ namespace mapnik { -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -using phoenix::push_back; -using phoenix::ref; +namespace x3 = boost::spirit::x3; -struct direction_name : qi::symbols +struct direction_name : x3::symbols { direction_name() { @@ -62,10 +57,10 @@ struct direction_name : qi::symbols ("NW", NORTHWEST) ("SW", SOUTHWEST) ("X" , EXACT_POSITION) + ("C" , CENTER) ; } - -}; +} names; // Position string: [POS][SIZE] // [POS] is any combination of @@ -82,28 +77,22 @@ bool parse_positions(std::string const& evaluated_positions, std::vector & direction, std::vector & text_sizes) { - direction_name names; - boost::spirit::ascii::space_type space; - qi::_1_type _1; - qi::float_type float_; - std::string::const_iterator first = evaluated_positions.begin(); - std::string::const_iterator last = evaluated_positions.end(); - bool r = qi::phrase_parse(first, last, - (names[push_back(phoenix::ref(direction), _1)] % ',') - >> *(',' >> float_[push_back(phoenix::ref(text_sizes), _1)]), - space); - if (first != last) - { - return false; - } - return r; + auto push_back_direction = [&](auto const& ctx) { direction.push_back(_attr(ctx));}; + auto push_back_size = [&](auto const& ctx) { text_sizes.push_back(_attr(ctx));}; + auto const first = evaluated_positions.begin(); + auto const last = evaluated_positions.end(); + bool r = x3::phrase_parse(first, last, + (names[push_back_direction] % ',') + >> *(',' >> x3::float_[push_back_size]), + x3::space); + return (r && first != last); } text_placement_info_simple::text_placement_info_simple(text_placements_simple const* parent, std::string const& evaluated_positions, - double scale_factor) -: text_placement_info(parent, scale_factor), + double scale_factor_) +: text_placement_info(parent, scale_factor_), state(0), position_state(0), direction_(parent->direction_), @@ -147,10 +136,10 @@ bool text_placement_info_simple::next_position_only() const return true; } -text_placement_info_ptr text_placements_simple::get_placement_info(double scale_factor, feature_impl const& feature, attributes const& vars) const +text_placement_info_ptr text_placements_simple::get_placement_info(double scale_factor_, feature_impl const& feature, attributes const& vars) const { std::string evaluated_positions = util::apply_visitor(extract_value(feature,vars), positions_); - return std::make_shared(this, evaluated_positions, scale_factor); + return std::make_shared(this, evaluated_positions, scale_factor_); } text_placements_simple::text_placements_simple(symbolizer_base::value_type const& positions) diff --git a/src/text/properties_util.cpp b/src/text/properties_util.cpp index e08d4fd55..fa3e60d08 100644 --- a/src/text/properties_util.cpp +++ b/src/text/properties_util.cpp @@ -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 diff --git a/src/text/renderer.cpp b/src/text/renderer.cpp index 163d11c6f..32e57f3ba 100644 --- a/src/text/renderer.cpp +++ b/src/text/renderer.cpp @@ -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 @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -66,8 +68,35 @@ void text_renderer::prepare_glyphs(glyph_positions const& positions) for (auto const& glyph_pos : positions) { glyph_info const& glyph = glyph_pos.glyph; - glyph.face->set_character_sizes(glyph.format->text_size * scale_factor_); //TODO: Optimize this? + FT_Int32 load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; + FT_Face face = glyph.face->get_face(); + if (glyph.face->is_color()) + { + load_flags |= FT_LOAD_COLOR ; + if (face->num_fixed_sizes > 0) + { + int scaled_size = static_cast(glyph.format->text_size * scale_factor_); + int best_match = 0; + int diff = std::abs(scaled_size - face->available_sizes[0].width); + for (int i = 1; i < face->num_fixed_sizes; ++i) + { + int ndiff = std::abs(scaled_size - face->available_sizes[i].height); + if (ndiff < diff) + { + best_match = i; + diff = ndiff; + } + } + error = FT_Select_Size(face, best_match); + } + } + else + { + glyph.face->set_character_sizes(glyph.format->text_size * scale_factor_); + } + + double size = glyph.format->text_size * scale_factor_; matrix.xx = static_cast( glyph_pos.rot.cos * 0x10000L); matrix.xy = static_cast(-glyph_pos.rot.sin * 0x10000L); matrix.yx = static_cast( glyph_pos.rot.sin * 0x10000L); @@ -77,17 +106,13 @@ void text_renderer::prepare_glyphs(glyph_positions const& positions) pen.x = static_cast(pos.x * 64); pen.y = static_cast(pos.y * 64); - FT_Face face = glyph.face->get_face(); FT_Set_Transform(face, &matrix, &pen); - - error = FT_Load_Glyph(face, glyph.glyph_index, FT_LOAD_NO_HINTING); + error = FT_Load_Glyph(face, glyph.glyph_index, load_flags); if (error) continue; - FT_Glyph image; error = FT_Get_Glyph(face->glyph, &image); if (error) continue; - - glyphs_.emplace_back(image, *glyph.format); + glyphs_.emplace_back(image, *glyph.format, pos, size); } } @@ -101,7 +126,7 @@ void composite_bitmap(T & pixmap, FT_Bitmap *bitmap, unsigned rgba, int x, int y { for (int j = y, q = 0; j < y_max; ++j, ++q) { - unsigned gray=bitmap->buffer[q*bitmap->width+p]; + unsigned gray = bitmap->buffer[q * bitmap->width + p]; if (gray) { mapnik::composite_pixel(pixmap, comp_op, i, j, rgba, gray, opacity); @@ -110,6 +135,31 @@ void composite_bitmap(T & pixmap, FT_Bitmap *bitmap, unsigned rgba, int x, int y } } +template +void composite_color_bitmap(T & pixmap, FT_Bitmap *bitmap, int x, int y, double size, double opacity, composite_mode_e comp_op) +{ + image_rgba8 image(bitmap->width, bitmap->rows); + + for (unsigned i = 0, p = 0; i < bitmap->width; ++i, p += 4) + { + for (unsigned j = 0, q = 0; j < bitmap->rows; ++j, ++q) + { + std::uint8_t b = bitmap->buffer[q * bitmap->width * 4 + p]; + std::uint8_t g = bitmap->buffer[q * bitmap->width * 4 + p + 1]; + std::uint8_t r = bitmap->buffer[q * bitmap->width * 4 + p + 2]; + std::uint8_t a = bitmap->buffer[q * bitmap->width * 4 + p + 3]; + unsigned c = static_cast((a << 24) | (b << 16) | (g << 8) | (r)); + image(i, j) = c; + } + } + double scale = size/image.height(); + int scaled_width = bitmap->width * scale; + int scaled_height = bitmap->rows * scale; + image_rgba8 scaled_image(scaled_width, scaled_height); + scale_image_agg(scaled_image, image , SCALING_BILINEAR , scale, scale, 0.0, 0.0, 1.0, 0); + composite(pixmap, scaled_image, comp_op, opacity, x, y); +} + template agg_text_renderer::agg_text_renderer (pixmap_type & pixmap, halo_rasterizer_e rasterizer, @@ -211,18 +261,38 @@ void agg_text_renderer::render(glyph_positions const& pos) { fill = glyph.properties.fill.rgba(); text_opacity = glyph.properties.text_opacity; + FT_Glyph_Transform(glyph.image, &matrix, &start); - error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL, 0, 1); - if (!error) + error = 0; + if ( glyph.image->format != FT_GLYPH_FORMAT_BITMAP ) + { + + error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL, 0, 1); + } + if (error == 0) { FT_BitmapGlyph bit = reinterpret_cast(glyph.image); - composite_bitmap(pixmap_, - &bit->bitmap, - fill, - bit->left, - height - bit->top, - text_opacity, - comp_op_); + int pixel_mode = bit->bitmap.pixel_mode; + if (pixel_mode == 7) + { + int x = (start.x >> 6) + glyph.pos.x; + int y = height - (start.y >> 6) + glyph.pos.y; + composite_color_bitmap(pixmap_, + &bit->bitmap, + x,y, glyph.size, + text_opacity, + comp_op_); + } + else + { + composite_bitmap(pixmap_, + &bit->bitmap, + fill, + bit->left, + height - bit->top, + text_opacity, + comp_op_); + } } FT_Done_Glyph(glyph.image); } @@ -257,7 +327,6 @@ void grid_text_renderer::render(glyph_positions const& pos, value_integer fea error = FT_Glyph_To_Bitmap(&glyph.image, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { - FT_BitmapGlyph bit = reinterpret_cast(glyph.image); render_halo_id(&bit->bitmap, feature_id, diff --git a/src/text/scrptrun.cpp b/src/text/scrptrun.cpp index 0cbb2c839..750998764 100644 --- a/src/text/scrptrun.cpp +++ b/src/text/scrptrun.cpp @@ -22,7 +22,7 @@ #include -#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) const char ScriptRun::fgClassID=0; @@ -124,7 +124,7 @@ UBool ScriptRun::next() if (scriptEnd >= charLimit) { return false; } - + scriptCode = USCRIPT_COMMON; for (scriptStart = scriptEnd; scriptEnd < charLimit; scriptEnd += 1) { @@ -178,7 +178,6 @@ UBool ScriptRun::next() if (sameScript(scriptCode, sc)) { if (scriptCode <= USCRIPT_INHERITED && sc > USCRIPT_INHERITED) { scriptCode = sc; - // now that we have a final script code, fix any open // characters we pushed before we knew the script code. while (startSP < parenSP) { @@ -205,4 +204,3 @@ UBool ScriptRun::next() return true; } - diff --git a/src/text/symbolizer_helpers.cpp b/src/text/symbolizer_helpers.cpp index 9eae83cfa..17b4cec08 100644 --- a/src/text/symbolizer_helpers.cpp +++ b/src/text/symbolizer_helpers.cpp @@ -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 @@ -29,14 +29,14 @@ #include #include #include -#include -#include +#include +#include #include #include #include #include #include -#include +#include #include #include #include @@ -110,7 +110,7 @@ struct split_multi_geometries split_multi_geometries(container_type & cont) : cont_(cont) { } - void operator() (geometry::geometry_empty const&) const {} + void operator() (geometry::geometry_empty const&) const {} void operator() (geometry::multi_point const& multi_pt) const { for ( auto const& pt : multi_pt ) @@ -187,23 +187,26 @@ base_symbolizer_helper::base_symbolizer_helper( initialize_points(); } -struct largest_bbox_first +template +static It largest_bbox(It begin, It end) { - bool operator() (geometry::geometry const* g0, geometry::geometry const* g1) const + if (begin == end) { - box2d b0 = geometry::envelope(*g0); - box2d b1 = geometry::envelope(*g1); - return b0.width() * b0.height() > b1.width() * b1.height(); + return end; } - bool operator() (base_symbolizer_helper::geometry_cref const& g0, - base_symbolizer_helper::geometry_cref const& g1) const + It largest_geom = begin; + double largest_bbox = geometry::envelope(*largest_geom).area(); + for (++begin; begin != end; ++begin) { - // TODO - this has got to be expensive! Can we cache bbox's if there are repeated calls to same geom? - box2d b0 = geometry::envelope(g0); - box2d b1 = geometry::envelope(g1); - return b0.width() * b0.height() > b1.width() * b1.height(); + double bbox = geometry::envelope(*begin).area(); + if (bbox > largest_bbox) + { + largest_bbox = bbox; + largest_geom = begin; + } } -}; + return largest_geom; +} void base_symbolizer_helper::initialize_geometries() const { @@ -216,10 +219,16 @@ void base_symbolizer_helper::initialize_geometries() const type == geometry::geometry_types::MultiPolygon) { bool largest_box_only = text_props_->largest_bbox_only; - if (largest_box_only) + if (largest_box_only && geometries_to_process_.size() > 1) { - geometries_to_process_.sort(largest_bbox_first()); + auto largest_geom = largest_bbox( + geometries_to_process_.begin(), + geometries_to_process_.end()); geo_itr_ = geometries_to_process_.begin(); + if (geo_itr_ != largest_geom) + { + std::swap(*geo_itr_, *largest_geom); + } geometries_to_process_.erase(++geo_itr_, geometries_to_process_.end()); } } @@ -318,10 +327,12 @@ text_symbolizer_helper::text_symbolizer_helper( value_bool clip = mapnik::get(sym_, feature_, vars_); value_double simplify_tolerance = mapnik::get(sym_, feature_, vars_); value_double smooth = mapnik::get(sym_, feature_, vars_); + value_double extend = mapnik::get(sym_, feature_, vars_); if (clip) converter_.template set(); converter_.template set(); //always transform converter_.template set(); + if (extend > 0.0) converter_.template set(); if (simplify_tolerance > 0.0) converter_.template set(); // optional simplify converter if (smooth > 0.0) converter_.template set(); // optional smooth converter @@ -443,12 +454,15 @@ text_symbolizer_helper::text_symbolizer_helper( value_bool clip = mapnik::get(sym_, feature_, vars_); value_double simplify_tolerance = mapnik::get(sym_, feature_, vars_); value_double smooth = mapnik::get(sym_, feature_, vars_); + value_double extend = mapnik::get(sym_, feature_, vars_); if (clip) converter_.template set(); converter_.template set(); //always transform converter_.template set(); + if (extend > 0.0) converter_.template set(); if (simplify_tolerance > 0.0) converter_.template set(); // optional simplify converter if (smooth > 0.0) converter_.template set(); // optional smooth converter + if (geometries_to_process_.size()) { init_marker(); diff --git a/src/text/text_layout.cpp b/src/text/text_layout.cpp index 3a3818c1f..9de48d44f 100644 --- a/src/text/text_layout.cpp +++ b/src/text/text_layout.cpp @@ -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 @@ -35,6 +35,7 @@ #pragma GCC diagnostic pop #include +#include namespace mapnik { @@ -62,31 +63,24 @@ pixel_position evaluate_displacement(double dx, double dy, directions_e dir) { case EXACT_POSITION: return pixel_position(dx,dy); - break; case NORTH: return pixel_position(0,-std::abs(dy)); - break; case EAST: return pixel_position(std::abs(dx),0); - break; case SOUTH: return pixel_position(0,std::abs(dy)); - break; case WEST: return pixel_position(-std::abs(dx),0); - break; case NORTHEAST: return pixel_position(std::abs(dx),-std::abs(dy)); - break; case SOUTHEAST: return pixel_position(std::abs(dx),std::abs(dy)); - break; case NORTHWEST: return pixel_position(-std::abs(dx),-std::abs(dy)); - break; case SOUTHWEST: return pixel_position(-std::abs(dx),std::abs(dy)); - break; + case CENTER: + return pixel_position(0, 0); default: return pixel_position(dx,dy); } diff --git a/src/text/text_line.cpp b/src/text/text_line.cpp index 2d0516731..77300aaf5 100644 --- a/src/text/text_line.cpp +++ b/src/text/text_line.cpp @@ -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 @@ -64,7 +64,7 @@ void text_line::add_glyph(glyph_info && glyph, double scale_factor_) // Only add character spacing if the character is not a zero-width part of a cluster. width_ += advance + glyphs_.back().format->character_spacing * scale_factor_; glyphs_width_ += advance; - space_count_++; + ++space_count_; } glyphs_.emplace_back(std::move(glyph)); } diff --git a/src/text/text_properties.cpp b/src/text/text_properties.cpp index 73210d109..b25478db8 100644 --- a/src/text/text_properties.cpp +++ b/src/text/text_properties.cpp @@ -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 @@ -39,6 +39,8 @@ #include #pragma GCC diagnostic pop +#include + namespace mapnik { using boost::optional; diff --git a/src/tiff_reader.cpp b/src/tiff_reader.cpp index 157e4d0cb..b6ccef80e 100644 --- a/src/tiff_reader.cpp +++ b/src/tiff_reader.cpp @@ -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 diff --git a/src/transform_expression.cpp b/src/transform_expression.cpp index 34c704866..996ba8873 100644 --- a/src/transform_expression.cpp +++ b/src/transform_expression.cpp @@ -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 @@ -22,7 +22,7 @@ // mapnik #include -#include +#include // stl #include diff --git a/src/transform_expression_grammar.cpp b/src/transform_expression_grammar.cpp deleted file mode 100644 index 170b0a823..000000000 --- a/src/transform_expression_grammar.cpp +++ /dev/null @@ -1,26 +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 - * - *****************************************************************************/ - -#include -#include - -template struct mapnik::transform_expression_grammar; diff --git a/src/json/mapnik_json_geometry_grammar.cpp b/src/transform_expression_grammar_x3.cpp similarity index 76% rename from src/json/mapnik_json_geometry_grammar.cpp rename to src/transform_expression_grammar_x3.cpp index f2b96f230..cc0839613 100644 --- a/src/json/mapnik_json_geometry_grammar.cpp +++ b/src/transform_expression_grammar_x3.cpp @@ -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,8 +20,11 @@ * *****************************************************************************/ -#include -#include +#include +#include -using iterator_type = char const*; -template struct mapnik::json::geometry_grammar; +namespace mapnik { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(transform_expression_grammar_type, iterator_type, context_type); + +}} diff --git a/src/twkb.cpp b/src/twkb.cpp index 64ef6aa34..099a1b098 100644 --- a/src/twkb.cpp +++ b/src/twkb.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include namespace mapnik { namespace detail { @@ -82,7 +82,7 @@ public: mapnik::geometry::geometry read() { - mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); + mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); // Read the metadata bytes, populating all the // information about optional fields, extended (z/m) dimensions // expansion factors and so on diff --git a/src/unicode.cpp b/src/unicode.cpp index c96c58914..0c0d4a1ef 100644 --- a/src/unicode.cpp +++ b/src/unicode.cpp @@ -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 @@ -22,7 +22,7 @@ // mapnik #include -#include +#include // std #include diff --git a/src/util/utf_conv_win.cpp b/src/util/utf_conv_win.cpp index 7bfcbc29f..f3a41ec55 100644 --- a/src/util/utf_conv_win.cpp +++ b/src/util/utf_conv_win.cpp @@ -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 diff --git a/src/value.cpp b/src/value.cpp index b5ad606c7..7dfb9f4ed 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -22,7 +22,7 @@ // mapnik #include -#include +#include #include // stl diff --git a/src/vertex_adapters.cpp b/src/vertex_adapters.cpp index dd7b0202f..3cd1745fc 100644 --- a/src/vertex_adapters.cpp +++ b/src/vertex_adapters.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include namespace mapnik { namespace geometry { diff --git a/src/vertex_cache.cpp b/src/vertex_cache.cpp index c0d575892..b6516953b 100644 --- a/src/vertex_cache.cpp +++ b/src/vertex_cache.cpp @@ -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 diff --git a/src/warp.cpp b/src/warp.cpp index 29cfa44cc..f4ecc22fe 100644 --- a/src/warp.cpp +++ b/src/warp.cpp @@ -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 @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/webp_reader.cpp b/src/webp_reader.cpp index ca611aeef..a1077bb5f 100644 --- a/src/webp_reader.cpp +++ b/src/webp_reader.cpp @@ -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 @@ -37,6 +37,7 @@ extern "C" // stl #include +#include namespace mapnik { diff --git a/src/well_known_srs.cpp b/src/well_known_srs.cpp index 445d84aee..7f8dec2a8 100644 --- a/src/well_known_srs.cpp +++ b/src/well_known_srs.cpp @@ -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 diff --git a/src/wkb.cpp b/src/wkb.cpp index 21a07fd97..8966afe3b 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -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 @@ -27,7 +27,9 @@ #include #include #include -#include +#include + +#include namespace mapnik { @@ -119,7 +121,7 @@ public: mapnik::geometry::geometry read() { - mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); + mapnik::geometry::geometry geom = mapnik::geometry::geometry_empty(); int type = read_integer(); switch (type) { diff --git a/src/wkt/geometry_to_wkt.cpp b/src/wkt/geometry_to_wkt.cpp new file mode 100644 index 000000000..3460dfec4 --- /dev/null +++ b/src/wkt/geometry_to_wkt.cpp @@ -0,0 +1,47 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include +// boost +#include + +namespace mapnik { namespace util { + +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) +{ + using sink_type = std::back_insert_iterator; + static const mapnik::wkt::wkt_generator_grammar> generator; + sink_type sink(wkt); + return boost::spirit::karma::generate(sink, generator, geom); +} + +bool to_wkt(std::string & wkt, mapnik::geometry::geometry const& geom) +{ + using sink_type = std::back_insert_iterator; + static const mapnik::wkt::wkt_generator_grammar> generator; + sink_type sink(wkt); + return boost::spirit::karma::generate(sink, generator, geom); +} + +}} diff --git a/src/wkt/mapnik_wkt_generator_grammar.cpp b/src/wkt/mapnik_wkt_generator_grammar.cpp index 07813fcc8..a7267b71f 100644 --- a/src/wkt/mapnik_wkt_generator_grammar.cpp +++ b/src/wkt/mapnik_wkt_generator_grammar.cpp @@ -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 @@ -19,10 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ - -#include -#include #include +#include +#include namespace mapnik { namespace wkt { diff --git a/src/wkt/wkt_factory.cpp b/src/wkt/wkt_factory.cpp new file mode 100644 index 000000000..acb388434 --- /dev/null +++ b/src/wkt/wkt_factory.cpp @@ -0,0 +1,47 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include + +namespace mapnik { + +bool from_wkt(std::string const& wkt, mapnik::geometry::geometry & geom) +{ + using namespace boost::spirit; + x3::ascii::space_type space; + std::string::const_iterator itr = wkt.begin(); + std::string::const_iterator end = wkt.end(); + bool result; + try + { + result = x3::phrase_parse(itr, end, wkt_grammar(), space, geom); + } + catch (x3::expectation_failure const& ex) + { + return false; + } + return result && itr==end; +} + +} diff --git a/src/expression_grammar.cpp b/src/wkt/wkt_grammar_x3.cpp similarity index 72% rename from src/expression_grammar.cpp rename to src/wkt/wkt_grammar_x3.cpp index 09234a07f..eeb602e7d 100644 --- a/src/expression_grammar.cpp +++ b/src/wkt/wkt_grammar_x3.cpp @@ -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,13 @@ * *****************************************************************************/ -// NOTE: we define this here in a cpp because def is needed twice: -// once by src/expression.cpp and once by mapnik/transform_expression_grammar_impl.hpp -#include -#include +#include -template struct mapnik::expression_grammar; +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; +BOOST_SPIRIT_INSTANTIATE(wkt_grammar_type, iterator_type, context_type); + +}} diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 2e2a7df8e..84e1f0d4d 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -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 @@ -38,6 +38,7 @@ // stl #include +#include namespace mapnik { @@ -133,13 +134,13 @@ node_not_found::node_not_found(std::string const& node_name) : node_name_(node_name), msg_() {} -const char* node_not_found::what() const throw() +const char* node_not_found::what() const noexcept { msg_ = std::string("Node "+node_name_+ "not found"); return msg_.c_str(); } -node_not_found::~node_not_found() throw() {} +node_not_found::~node_not_found() {} attribute_not_found::attribute_not_found(std::string const& node_name, @@ -148,25 +149,25 @@ attribute_not_found::attribute_not_found(std::string const& node_name, attribute_name_(attribute_name), msg_() {} -const char* attribute_not_found::what() const throw() +const char* attribute_not_found::what() const noexcept { msg_ = std::string("Attribute '" + attribute_name_ +"' not found in node '"+node_name_+ "'"); return msg_.c_str(); } -attribute_not_found::~attribute_not_found() throw() {} +attribute_not_found::~attribute_not_found() {} more_than_one_child::more_than_one_child(std::string const& node_name) : node_name_(node_name), msg_() {} -const char* more_than_one_child::what() const throw() +const char* more_than_one_child::what() const noexcept { msg_ = std::string("More than one child node in node '" + node_name_ +"'"); return msg_.c_str(); } -more_than_one_child::~more_than_one_child() throw() {} +more_than_one_child::~more_than_one_child() {} xml_node::xml_node(xml_tree &tree, std::string && name, unsigned line, bool is_text) : tree_(tree), @@ -229,9 +230,9 @@ xml_node & xml_node::add_child(const char * name, unsigned line, bool is_text) return children_.back(); } -void xml_node::add_attribute(const char * name, const char * value) +void xml_node::add_attribute(const char * name, const char * value_) { - auto result = attributes_.emplace(name,xml_attribute(value)); + auto result = attributes_.emplace(name,xml_attribute(value_)); if (!result.second) { MAPNIK_LOG_ERROR(xml_tree) << "ignoring duplicate attribute '" << name << "'"; @@ -345,16 +346,16 @@ boost::optional xml_node::get_opt_attr(std::string const& name) const template T xml_node::get_attr(std::string const& name, T const& default_opt_value) const { - boost::optional value = get_opt_attr(name); - if (value) return *value; + boost::optional val = get_opt_attr(name); + if (val) return *val; return default_opt_value; } template T xml_node::get_attr(std::string const& name) const { - boost::optional value = get_opt_attr(name); - if (value) return *value; + boost::optional val = get_opt_attr(name); + if (val) return *val; throw attribute_not_found(name_, name); } diff --git a/test/build.py b/test/build.py index 78fd9342a..8a9a44523 100644 --- a/test/build.py +++ b/test/build.py @@ -54,6 +54,7 @@ else: visual/report.cpp visual/runner.cpp visual/run.cpp + visual/parse_map_sizes.cpp """ ) test_program3 = test_env_local.Program('visual/run', source=source) diff --git a/test/data b/test/data index 6ce59adfc..dac50a321 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 6ce59adfc4f11b16a5dc0e2020c36dc614850989 +Subproject commit dac50a321bdcc92c6183ded08200eb8fa117532c diff --git a/test/data-visual b/test/data-visual index 941db3d00..b399ad677 160000 --- a/test/data-visual +++ b/test/data-visual @@ -1 +1 @@ -Subproject commit 941db3d00920dc7aceaa6797096a7228bc7bac14 +Subproject commit b399ad677146c9d7b1c11470691b7a332d95b156 diff --git a/test/standalone/font_registration_test.cpp b/test/standalone/font_registration_test.cpp index a5ba0b271..765406443 100644 --- a/test/standalone/font_registration_test.cpp +++ b/test/standalone/font_registration_test.cpp @@ -57,7 +57,7 @@ SECTION("registration") { mapnik::load_map_string(m3,""); REQUIRE( m3.get_font_memory_cache().size() == 0 ); REQUIRE( m3.load_fonts() ); - REQUIRE( m3.get_font_memory_cache().size() == 1 ); + REQUIRE( m3.get_font_memory_cache().size() == 2 ); std::vector face_names; std::string foo("foo"); diff --git a/test/unit/color/css_color.cpp b/test/unit/color/css_color.cpp index f1bc17196..a532cb1cf 100644 --- a/test/unit/color/css_color.cpp +++ b/test/unit/color/css_color.cpp @@ -1,63 +1,113 @@ #include "catch.hpp" -#include -#include + #include +#include +#include +#include + #include -TEST_CASE("css color") { +TEST_CASE("CSS color") { SECTION("conversions") { - mapnik::percent_conv_impl conv; - CHECK( conv(1.0) == 3 ); - CHECK( conv(60.0) == 153 ); + using namespace mapnik::css_color_grammar; + CHECK( percent_converter::call(1.0) == 3 ); + CHECK( percent_converter::call(60.0) == 153 ); // should not overflow on invalid input - CHECK( conv(100000.0) == 255 ); - CHECK( conv(-100000.0) == 0 ); - - mapnik::alpha_conv_impl conv2; - CHECK( conv2(0.5) == 128 ); - CHECK( conv2(1.0) == 255 ); - // should not overflow on invalid input - CHECK( conv2(60.0) == 255 ); - CHECK( conv2(100000.0) == 255 ); - CHECK( conv2(-100000.0) == 0 ); - - mapnik::hsl_conv_impl conv3; - mapnik::color c; - conv3(c, 1.0, 1.0, 1.0); - CHECK( c.alpha() == 255 ); - CHECK( c.red() == 3 ); - CHECK( c.green() == 3 ); - CHECK( c.blue() == 3 ); - // invalid - conv3(c, -1, -1, -1); - CHECK( c.alpha() == 255 ); // should not be touched by hsl converter - CHECK( c.red() == 0 ); - CHECK( c.green() == 0 ); - CHECK( c.blue() == 0 ); + CHECK( percent_converter::call(100000.0) == 255 ); + CHECK( percent_converter::call(-100000.0) == 0 ); } - SECTION("hex colors") + SECTION("CSS colors") { - mapnik::css_color_grammar color_grammar; - boost::spirit::qi::ascii::space_type space; - + auto const& color_grammar = mapnik::color_grammar(); + boost::spirit::x3::ascii::space_type space; + { + // rgb + std::string s("rgb(128,0,255)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0xff ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgb (percent) + std::string s("rgb(50%,0%,100%)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0xff ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgba + std::string s("rgba(128,0,255,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0x80 ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgba (percent) + std::string s("rgba(50%,0%,100%,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0x80 ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // named colours + std::string s("darksalmon"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 255 ); + CHECK( c.red() == 233 ); + CHECK( c.green() == 150 ); + CHECK( c.blue() == 122 ); + } + // hsl + { + std::string s("hsl(240,50%,50%)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 255 ); + CHECK( c.red() == 64 ); + CHECK( c.green() == 64 ); + CHECK( c.blue() == 191 ); + } + // hsla + { + std::string s("hsla(240,50%,50%,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 128 ); + CHECK( c.red() == 64 ); + CHECK( c.green() == 64 ); + CHECK( c.blue() == 191 ); + } + // hex colours { std::string s("#abcdef"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); CHECK( c.blue() == 0xef ); } - { std::string s("#abcdef12"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0x12 ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -67,7 +117,7 @@ TEST_CASE("css color") { { std::string s(" #abcdef"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -77,7 +127,7 @@ TEST_CASE("css color") { { std::string s(" #abcdef12"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0x12 ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -86,22 +136,26 @@ TEST_CASE("css color") { { std::string s("# abcdef"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("# abcdef12"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#ab cdef"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#ab cdef12"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } // hex_color_small @@ -109,7 +163,7 @@ TEST_CASE("css color") { { std::string s("#abc"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -119,7 +173,7 @@ TEST_CASE("css color") { { std::string s("#abcd"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xdd ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -129,7 +183,7 @@ TEST_CASE("css color") { { std::string s(" #abc"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -139,7 +193,7 @@ TEST_CASE("css color") { { std::string s(" #abcd"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xdd ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -148,22 +202,26 @@ TEST_CASE("css color") { { std::string s("# abc"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("# abcd"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#a bc"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#a bcd"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } } SECTION("operator<< / to_string()") diff --git a/test/unit/core/box2d_test.cpp b/test/unit/core/box2d_test.cpp index 8385bba7c..1db9a0a93 100644 --- a/test/unit/core/box2d_test.cpp +++ b/test/unit/core/box2d_test.cpp @@ -1,8 +1,7 @@ - #include "catch.hpp" #include -#include +#include #include "agg_trans_affine.h" TEST_CASE("box2d") { diff --git a/test/unit/core/comparison_test.cpp b/test/unit/core/comparison_test.cpp index 7e8e8e414..886b52960 100644 --- a/test/unit/core/comparison_test.cpp +++ b/test/unit/core/comparison_test.cpp @@ -1,7 +1,6 @@ - #include "catch.hpp" -#include +#include #include TEST_CASE("comparison") diff --git a/test/unit/core/conversions_test.cpp b/test/unit/core/conversions_test.cpp index 43592af01..98d2bacf4 100644 --- a/test/unit/core/conversions_test.cpp +++ b/test/unit/core/conversions_test.cpp @@ -1,7 +1,6 @@ - #include "catch.hpp" -#include +#include #include #include #include @@ -284,16 +283,19 @@ SECTION("to string") { REQUIRE( string2bool("true",val) ); REQUIRE( val == true ); - // mapnik::value hashability - using values_container = std::unordered_map; + // mapnik::value hash() and operator== works for all T in value + mapnik::transcoder tr("utf8"); + using values_container = std::unordered_map; values_container vc; - mapnik::value val2(1); - vc[val2] = 1; - REQUIRE( vc[1] == static_cast(1) ); + mapnik::value keys[5] = {true, 123456789, 3.14159f, tr.transcode("Мапник"), mapnik::value_null()} ; + for (auto const& k : keys) + { + vc.insert({k, k}); + REQUIRE( vc[k] == k ); + } // mapnik::value << to ostream std::stringstream s; - mapnik::transcoder tr("utf-8"); mapnik::value_unicode_string ustr = tr.transcode("hello world!"); mapnik::value streamable(ustr); s << streamable; diff --git a/test/unit/core/expressions_test.cpp b/test/unit/core/expressions_test.cpp index 22ba3c00d..a01c5bdea 100644 --- a/test/unit/core/expressions_test.cpp +++ b/test/unit/core/expressions_test.cpp @@ -125,9 +125,9 @@ TEST_CASE("expressions") // geometry types TRY_CHECK(eval(" [mapnik::geometry_type] = point ") == true); - TRY_CHECK(eval(" [mapnik::geometry_type] <> linestring ") == true); - TRY_CHECK(eval(" [mapnik::geometry_type] != polygon ") == true); - TRY_CHECK(eval(" [mapnik::geometry_type] neq collection ") == true); + TRY_CHECK(eval(" [ mapnik::geometry_type] <> linestring ") == true); + TRY_CHECK(eval(" [mapnik::geometry_type ] != polygon ") == true); + TRY_CHECK(eval(" [ mapnik::geometry_type ] neq collection ") == true); TRY_CHECK(eval(" [mapnik::geometry_type] eq collection ") == false); //unary expression @@ -183,7 +183,16 @@ TEST_CASE("expressions") auto val1 = eval("'♜♞♝♛♚♝♞♜'.replace('♞','♘')"); // ==> expected ♜♘♝♛♚♝♘♜ TRY_CHECK(val0 == val1); TRY_CHECK(val0.to_string() == val1.to_string()); // UTF-8 - TRY_CHECK(val0.to_unicode() == val1.to_unicode()); // Unicode (UTF-16) + TRY_CHECK(val0.to_unicode() == val1.to_unicode()); // Unicode + // \u+NNNN \U+NNNNNNNN \xNN\xNN + auto val3 = eval(u8"'\u262f\xF0\x9F\x8D\xB7'"); + auto val4 = eval(u8"'\U0000262f\U0001F377'"); + // UTF16 surrogate pairs work also ;) + // \ud83d\udd7a\ud83c\udffc => \U0001F57A\U0001F3FC works also + // TODO: find a way to enter UTF16 pairs + TRY_CHECK(val3 == val4); + TRY_CHECK(val3.to_string() == val4.to_string()); // UTF-8 + TRY_CHECK(val3.to_unicode() == val4.to_unicode()); // Unicode // following test will fail if boost_regex is built without ICU support (unpaired surrogates in output) TRY_CHECK(eval("[name].replace('(\\B)|( )',' ') ") == tr.transcode("Q u é b e c")); diff --git a/test/unit/core/params_test.cpp b/test/unit/core/params_test.cpp index 3131f0cbc..0363d24a4 100644 --- a/test/unit/core/params_test.cpp +++ b/test/unit/core/params_test.cpp @@ -1,8 +1,7 @@ - #include "catch.hpp" #include -#include +#include #include #include diff --git a/test/unit/core/transform_expressions_test.cpp b/test/unit/core/transform_expressions_test.cpp new file mode 100644 index 000000000..b2195fb50 --- /dev/null +++ b/test/unit/core/transform_expressions_test.cpp @@ -0,0 +1,60 @@ +#include "catch.hpp" + +#include +#include + +namespace { + + +bool test_transform_expressions(std::string const& in, std::string const& out) +{ + auto tr_list = mapnik::parse_transform(in); + return mapnik::to_expression_string(*tr_list) == out; +} + +} + +TEST_CASE("transform-expressions") +{ + // matrix + CHECK(test_transform_expressions("matrix( 1,2,3,4,5, 6)", "matrix(1, 2, 3, 4, 5, 6)")); + CHECK(test_transform_expressions("matrix(1 2 3 4 5 6)", "matrix(1, 2, 3, 4, 5, 6)")); + CHECK(test_transform_expressions("matrix(1,2,3,4,5,4*2-1)", "matrix(1, 2, 3, 4, 5, (4*2-1))")); + CHECK(test_transform_expressions("matrix(1,2,3,4,5,[value])", "matrix(1, 2, 3, 4, 5, [value])")); + CHECK(test_transform_expressions("matrix(1,2,@value,4,5,6)", "matrix(1, 2, @value, 4, 5, 6)")); + CHECK(test_transform_expressions("matrix(1,2,3,4,5,@value)", "matrix(1, 2, 3, 4, 5, @value)")); + + // translate + CHECK(test_transform_expressions("translate(100)", "translate(100)")); + CHECK(test_transform_expressions("translate([tx])", "translate([tx])")); + CHECK(test_transform_expressions("translate(100 200)", "translate(100, 200)")); + CHECK(test_transform_expressions("translate([tx],[ty])", "translate([tx], [ty])")); + CHECK(test_transform_expressions("translate([tx],200)", "translate([tx], 200)")); + CHECK(test_transform_expressions("translate(100,[ty])", "translate(100, [ty])")); + + // scale + CHECK(test_transform_expressions("scale(1.5)", "scale(1.5)")); + CHECK(test_transform_expressions("scale([sx])", "scale([sx])")); + CHECK(test_transform_expressions("scale([sx],1.5)", "scale([sx], 1.5)")); + CHECK(test_transform_expressions("scale(1.5,[sy])", "scale(1.5, [sy])")); + CHECK(test_transform_expressions("scale([sx],[sy]/2)", "scale([sx], [sy]/2)")); + + // rotate + CHECK(test_transform_expressions("rotate([a] -2)", "rotate(([a]-2))")); + CHECK(test_transform_expressions("rotate([a] -2 -3)", "rotate((([a]-2)-3))")); + CHECK(test_transform_expressions("rotate([a],-2,-3)", "rotate([a], -2, -3)")); + CHECK(test_transform_expressions("rotate([a] -2 -3 -4)", "rotate(((([a]-2)-3)-4))")); + CHECK(test_transform_expressions("rotate([a] -2, 3, 4)", "rotate(([a]-2), 3, 4)")); + + // skewX + CHECK(test_transform_expressions("skewX(2)", "skewX(2)")); + CHECK(test_transform_expressions("skewX(2*[x]+[y])", "skewX((2*[x]+[y]))")); + + // skewY + CHECK(test_transform_expressions("skewY(2)", "skewY(2)")); + CHECK(test_transform_expressions("skewY(2*[x]+[y])", "skewY((2*[x]+[y]))")); + + // compound + CHECK(test_transform_expressions("translate([tx]) rotate([a])", "translate([tx]) rotate([a])")); + CHECK(test_transform_expressions("rotate(30+@global_value) scale(2*[sx],[sy])", "rotate((30+@global_value)) scale(2*[sx], [sy])")); +} diff --git a/test/unit/core/value_test.cpp b/test/unit/core/value_test.cpp index cdb64dbbe..a76910a26 100644 --- a/test/unit/core/value_test.cpp +++ b/test/unit/core/value_test.cpp @@ -1,7 +1,6 @@ - #include "catch.hpp" -#include +#include #include TEST_CASE("mapnik::value") diff --git a/test/unit/datasource/csv.cpp b/test/unit/datasource/csv.cpp index 6142185ca..18c337702 100644 --- a/test/unit/datasource/csv.cpp +++ b/test/unit/datasource/csv.cpp @@ -28,8 +28,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/test/unit/datasource/ds_test_util.hpp b/test/unit/datasource/ds_test_util.hpp index dd2e4a242..cbdbe4921 100644 --- a/test/unit/datasource/ds_test_util.hpp +++ b/test/unit/datasource/ds_test_util.hpp @@ -29,8 +29,8 @@ #include #include #include -#include -#include +#include +#include namespace { @@ -131,7 +131,7 @@ struct feature_count return mapnik::util::apply_visitor(*this, geom); } - std::size_t operator()(mapnik::geometry::geometry_empty const &) const + std::size_t operator()(mapnik::geometry::geometry_empty const &) const { return 0; } diff --git a/test/unit/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp index c4951860b..2311c5273 100644 --- a/test/unit/datasource/geojson.cpp +++ b/test/unit/datasource/geojson.cpp @@ -27,10 +27,12 @@ #include #include #include -#include +#include +#include +#include #include #include - +#include #include /* @@ -115,6 +117,50 @@ TEST_CASE("geojson") { } } + SECTION("GeoJSON empty Geometries handling") + { + auto valid_empty_geometries = + { + "null", // Point can't be empty + "{ \"type\": \"LineString\", \"coordinates\": [] }", + "{ \"type\": \"Polygon\", \"coordinates\": [ [ ] ] } ", + "{ \"type\": \"MultiPoint\", \"coordinates\": [ ] }", + "{ \"type\": \"MultiLineString\", \"coordinates\": [ [] ] }", + "{ \"type\": \"MultiPolygon\", \"coordinates\": [[ []] ] }" + }; + + for (auto const& in : valid_empty_geometries) + { + std::string json(in); + mapnik::geometry::geometry geom; + CHECK(mapnik::json::from_geojson(json, geom)); + // round trip + std::string json_out; + CHECK(mapnik::util::to_geojson(json_out, geom)); + json.erase(std::remove_if( + std::begin(json), std::end(json), + [l = std::locale{}](auto ch) { return std::isspace(ch, l); } + ), std::end(json)); + REQUIRE(json == json_out); + } + + auto invalid_empty_geometries = + { + "{ \"type\": \"Point\", \"coordinates\": [] }", + "{ \"type\": \"LineString\", \"coordinates\": [[]] }" + "{ \"type\": \"Polygon\", \"coordinates\": [[[]]] }", + "{ \"type\": \"MultiPoint\", \"coordinates\": [[]] }", + "{ \"type\": \"MultiLineString\", \"coordinates\": [[[]]] }", + "{ \"type\": \"MultiPolygon\", \"coordinates\": [[[[]]]] }" + }; + + for (auto const& json : invalid_empty_geometries) + { + mapnik::geometry::geometry geom; + CHECK(!mapnik::json::from_geojson(json, geom)); + } + } + SECTION("GeoJSON num_features_to_query") { std::string filename = "./test/data/json/featurecollection-multipleprops.geojson"; diff --git a/test/unit/datasource/postgis.cpp b/test/unit/datasource/postgis.cpp index 95ee65851..f74ee1548 100644 --- a/test/unit/datasource/postgis.cpp +++ b/test/unit/datasource/postgis.cpp @@ -25,7 +25,8 @@ #include #include -#include +#include +#include #include /* @@ -185,6 +186,24 @@ TEST_CASE("postgis") { CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); } + SECTION("Postgis properly escapes names with single quotes") + { + mapnik::parameters params(base_params); + params["table"] = "\"test'single'quotes\""; + auto ds = mapnik::datasource_cache::instance().create(params); + REQUIRE(ds != nullptr); + CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); + } + + SECTION("Postgis properly escapes names with double quotes") + { + mapnik::parameters params(base_params); + params["table"] = "\"test\"\"double\"\"quotes\""; + auto ds = mapnik::datasource_cache::instance().create(params); + REQUIRE(ds != nullptr); + CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point); + } + SECTION("Postgis query field names") { mapnik::parameters params(base_params); @@ -270,6 +289,55 @@ TEST_CASE("postgis") { REQUIRE(ext.maxy() == 4); } + SECTION("Postgis doesn't interpret @domain in email address as @variable") + { + mapnik::parameters params(base_params); + params["table"] = "(SELECT gid, geom, 'fake@mail.ru' as email" + " FROM public.test LIMIT 1) AS data"; + auto ds = mapnik::datasource_cache::instance().create(params); + REQUIRE(ds != nullptr); + auto featureset = all_features(ds); + auto feature = featureset->next(); + CHECKED_IF(feature != nullptr) + { + CHECK(feature->get("email").to_string() == "fake@mail.ru"); + } + } + + SECTION("Postgis interpolates !@uservar! tokens in query") + { + mapnik::parameters params(base_params); + params["table"] = "(SELECT * FROM public.test" + " WHERE GeometryType(geom) = !@wantedGeomType!" + " LIMIT 1) AS data"; + auto ds = mapnik::datasource_cache::instance().create(params); + REQUIRE(ds != nullptr); + + mapnik::transcoder tr("utf8"); + mapnik::query qry(ds->envelope()); + qry.set_variables({{"wantedGeomType", tr.transcode("POINT")}}); + CHECK(qry.variables().count("wantedGeomType") == 1); + + auto featureset = ds->features(qry); + auto feature = featureset->next(); + CHECKED_IF(feature != nullptr) + { + auto const& geom = feature->get_geometry(); + CHECK(mapnik::geometry::geometry_type(geom) == mapnik::geometry::Point); + } + + qry.set_variables({{"wantedGeomType", tr.transcode("POLYGON")}}); + CHECK(qry.variables().count("wantedGeomType") == 1); + + featureset = ds->features(qry); + feature = featureset->next(); + CHECKED_IF(feature != nullptr) + { + auto const& geom = feature->get_geometry(); + CHECK(mapnik::geometry::geometry_type(geom) == mapnik::geometry::Polygon); + } + } + SECTION("Postgis query extent: full dataset") { //include schema to increase coverage diff --git a/test/unit/datasource/topojson.cpp b/test/unit/datasource/topojson.cpp index 7bf155e33..229e7d9b1 100644 --- a/test/unit/datasource/topojson.cpp +++ b/test/unit/datasource/topojson.cpp @@ -26,14 +26,11 @@ #include #include #include -#include +#include #include namespace { -using iterator_type = char const*; -const mapnik::topojson::topojson_grammar grammar; - bool parse_topology(std::string const& filename, mapnik::topojson::topology & topo) { mapnik::util::file file(filename); @@ -41,11 +38,22 @@ bool parse_topology(std::string const& filename, mapnik::topojson::topology & to buffer.resize(file.size()); std::fread(&buffer[0], buffer.size(), 1, file.get()); if (!file) return false; - boost::spirit::standard::space_type space; - iterator_type itr = buffer.c_str(); - iterator_type end = itr + buffer.length(); - bool result = boost::spirit::qi::phrase_parse(itr, end, grammar, space, topo); - return (result && (itr == end)); + using space_type = boost::spirit::x3::standard::space_type; + char const* itr = buffer.c_str(); + char const* end = itr + buffer.length(); + try + { + boost::spirit::x3::phrase_parse(itr, end, mapnik::json::topojson_grammar(), space_type() , topo); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + std::cerr << "failed to parse TopoJSON..." << std::endl; + std::cerr << ex.what() << std::endl; + std::cerr << "Expected: " << ex.which(); + std::cerr << " Got: \"" << std::string(ex.where(), ex.where() + 200) << "...\"" << std::endl; + return false; + } + return (itr == end); } } diff --git a/test/unit/font/fontset_runtime_test.cpp b/test/unit/font/fontset_runtime_test.cpp index bfbae2786..1182807cd 100644 --- a/test/unit/font/fontset_runtime_test.cpp +++ b/test/unit/font/fontset_runtime_test.cpp @@ -1,4 +1,3 @@ - #include "catch.hpp" #include @@ -12,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -69,4 +68,4 @@ SECTION("error") { REQUIRE(std::string(ex.what()) == std::string("Unable to find specified font face 'DejaVu Sans Book' in font set: 'fontset'")); } } -} \ No newline at end of file +} diff --git a/test/unit/geometry/centroid.cpp b/test/unit/geometry/centroid.cpp index 4549bec9b..c4b3619ac 100644 --- a/test/unit/geometry/centroid.cpp +++ b/test/unit/geometry/centroid.cpp @@ -1,12 +1,12 @@ #include "catch.hpp" -#include +#include TEST_CASE("geometry centroid") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; mapnik::geometry::point centroid; REQUIRE(!mapnik::geometry::centroid(geom, centroid)); } diff --git a/test/unit/geometry/geometry_envelope_test.cpp b/test/unit/geometry/geometry_envelope_test.cpp index 10551d363..2b26f91df 100644 --- a/test/unit/geometry/geometry_envelope_test.cpp +++ b/test/unit/geometry/geometry_envelope_test.cpp @@ -1,7 +1,7 @@ #include "catch.hpp" #include -#include +#include namespace { @@ -21,7 +21,7 @@ void envelope_test() } { // Test empty geom - geometry geom = mapnik::geometry::geometry_empty(); + geometry geom = mapnik::geometry::geometry_empty(); mapnik::box2d bbox = mapnik::geometry::envelope(geom); REQUIRE_FALSE( bbox.valid() ); } diff --git a/test/unit/geometry/geometry_equal.hpp b/test/unit/geometry/geometry_equal.hpp index 97e0bf26a..65c2bfbc7 100644 --- a/test/unit/geometry/geometry_equal.hpp +++ b/test/unit/geometry/geometry_equal.hpp @@ -107,7 +107,7 @@ struct geometry_equal_visitor } template - void operator() (geometry_empty const&, geometry_empty const&) const + void operator() (geometry_empty const&, geometry_empty const&) const { REQUIRE(true); } diff --git a/test/unit/geometry/geometry_hit_test.cpp b/test/unit/geometry/geometry_hit_test.cpp index afc7dfa9c..0f5196a7c 100644 --- a/test/unit/geometry/geometry_hit_test.cpp +++ b/test/unit/geometry/geometry_hit_test.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include TEST_CASE("geometry ops") { diff --git a/test/unit/geometry/geometry_is_simple.cpp b/test/unit/geometry/geometry_is_simple.cpp index 936c3caae..cb8421582 100644 --- a/test/unit/geometry/geometry_is_simple.cpp +++ b/test/unit/geometry/geometry_is_simple.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include TEST_CASE("geometry is_simple") { @@ -10,7 +10,7 @@ TEST_CASE("geometry is_simple") { #if BOOST_VERSION >= 105800 SECTION("point") { - mapnik::geometry::geometry_empty empty; + mapnik::geometry::geometry_empty empty; CHECK( mapnik::geometry::is_simple(empty) ); } @@ -280,6 +280,7 @@ SECTION("multi polygon") { mapnik::geometry::multi_polygon mp; mapnik::geometry::polygon poly; mapnik::geometry::linear_ring ring; + ring.emplace_back(0,0); ring.emplace_back(1,0); ring.emplace_back(1,1); diff --git a/test/unit/geometry/geometry_is_valid.cpp b/test/unit/geometry/geometry_is_valid.cpp index f8227b050..734cf5a3c 100644 --- a/test/unit/geometry/geometry_is_valid.cpp +++ b/test/unit/geometry/geometry_is_valid.cpp @@ -1,7 +1,7 @@ #include "catch.hpp" #include -#include +#include TEST_CASE("geometry is_valid") { @@ -10,7 +10,7 @@ TEST_CASE("geometry is_valid") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty empty; + mapnik::geometry::geometry_empty empty; CHECK( mapnik::geometry::is_valid(empty) ); std::string message; CHECK( mapnik::geometry::is_valid(empty, message) ); diff --git a/test/unit/geometry/geometry_reprojection.cpp b/test/unit/geometry/geometry_reprojection.cpp index 95bfdb099..cf64a41e8 100644 --- a/test/unit/geometry/geometry_reprojection.cpp +++ b/test/unit/geometry/geometry_reprojection.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include TEST_CASE("geometry reprojection") { @@ -15,10 +15,10 @@ SECTION("test_projection_4326_3857 - Empty Geometry Object") { mapnik::projection dest("+init=epsg:3857"); mapnik::proj_transform proj_trans(source, dest); { - geometry_empty geom; + geometry_empty geom; unsigned int err = 0; // Test Standard Transform - geometry_empty new_geom = reproject_copy(geom, proj_trans, err); + geometry_empty new_geom = reproject_copy(geom, proj_trans, err); REQUIRE(err == 0); // Transform providing projections not transfrom new_geom = reproject_copy(geom, source, dest, err); @@ -41,20 +41,20 @@ SECTION("test_projection_4326_3857 - Empty Geometry in Geometry Variant") { mapnik::projection dest("+init=epsg:3857"); mapnik::proj_transform proj_trans(source, dest); { - geometry geom = geometry_empty(); + geometry geom = geometry_empty(); unsigned int err = 0; // Test Standard Transform geometry new_geom = reproject_copy(geom, proj_trans, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); // Transform providing projections not transfrom new_geom = reproject_copy(geom, source, dest, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); // Transform providing projections in reverse new_geom = reproject_copy(geom, dest, source, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); // Transform in place REQUIRE(reproject(new_geom, proj_trans)); // Transform in place providing projections @@ -268,7 +268,7 @@ SECTION("test_projection_4326_3857 - Line_String Geometry Variant Object") { // Reprojecting empty line string will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -455,7 +455,7 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -595,7 +595,7 @@ SECTION("test_projection_4326_3857 - Multi_Point Geometry Variant Object") { // Reprojecting empty multi point will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -751,7 +751,7 @@ SECTION("test_projection_4326_3857 - Multi_Line_String Geometry Variant Object") // Reprojecting empty line string will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -945,7 +945,7 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform @@ -1139,7 +1139,7 @@ SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") { // Reprojecting empty poly will return a geometry_empty geometry new_geom = reproject_copy(geom0, proj_trans1, err); REQUIRE(err == 0); - REQUIRE(new_geom.is>()); + REQUIRE(new_geom.is()); } { // Test Standard Transform diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp index cb20cb74a..2e63cc9d4 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -5,11 +5,12 @@ #include #include #include -#include -#include +#include +#include #include #include +#if 0 TEST_CASE("geometry strategy tests") { SECTION("proj and view strategy") { using namespace mapnik::geometry; @@ -183,3 +184,4 @@ SECTION("scaling strategies - double to int64") { } } // END SECTION } // END TEST CASE +#endif diff --git a/test/unit/geometry/geometry_test_helper.cpp b/test/unit/geometry/geometry_test_helper.cpp index 44bcce596..98c254b55 100644 --- a/test/unit/geometry/geometry_test_helper.cpp +++ b/test/unit/geometry/geometry_test_helper.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include namespace mapnik { namespace geometry { diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp index ff2e40f23..79159d173 100644 --- a/test/unit/geometry/has_empty.cpp +++ b/test/unit/geometry/has_empty.cpp @@ -1,12 +1,12 @@ #include "catch.hpp" -#include +#include TEST_CASE("geometry has_empty") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; REQUIRE(!mapnik::geometry::has_empty(geom)); } @@ -18,7 +18,7 @@ SECTION("geometry collection") { } { mapnik::geometry::geometry_collection geom; - mapnik::geometry::geometry_empty geom1; + mapnik::geometry::geometry_empty geom1; geom.emplace_back(std::move(geom1)); REQUIRE(mapnik::geometry::has_empty(geom)); } diff --git a/test/unit/geometry/is_empty.cpp b/test/unit/geometry/is_empty.cpp index 25ed8a487..6f6ed2ed2 100644 --- a/test/unit/geometry/is_empty.cpp +++ b/test/unit/geometry/is_empty.cpp @@ -1,12 +1,12 @@ #include "catch.hpp" -#include +#include TEST_CASE("geometry is_empty") { SECTION("empty geometry") { - mapnik::geometry::geometry_empty geom; + mapnik::geometry::geometry_empty geom; REQUIRE(mapnik::geometry::is_empty(geom)); } @@ -18,7 +18,7 @@ SECTION("geometry collection") { } { mapnik::geometry::geometry_collection geom; - mapnik::geometry::geometry_empty geom1; + mapnik::geometry::geometry_empty geom1; geom.emplace_back(std::move(geom1)); REQUIRE(!mapnik::geometry::is_empty(geom)); } diff --git a/test/unit/geometry/remove_empty.cpp b/test/unit/geometry/remove_empty.cpp index 36a6955c5..b51d0c8e2 100644 --- a/test/unit/geometry/remove_empty.cpp +++ b/test/unit/geometry/remove_empty.cpp @@ -1,6 +1,6 @@ #include "catch.hpp" -#include +#include TEST_CASE("geometry remove_empty") { diff --git a/test/unit/projection/proj_transform.cpp b/test/unit/projection/proj_transform.cpp index 95c959587..bb56b888c 100644 --- a/test/unit/projection/proj_transform.cpp +++ b/test/unit/projection/proj_transform.cpp @@ -1,9 +1,8 @@ - #include "catch.hpp" #include #include -#include +#include #ifdef MAPNIK_USE_PROJ4 // proj4 diff --git a/test/unit/serialization/parse_hex.hpp b/test/unit/serialization/parse_hex.hpp index 48c70a5d4..4475bc946 100644 --- a/test/unit/serialization/parse_hex.hpp +++ b/test/unit/serialization/parse_hex.hpp @@ -23,19 +23,21 @@ #ifndef MAPNIK_PARSE_HEX_HPP #define MAPNIK_PARSE_HEX_HPP -#include -#include +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop namespace mapnik { namespace util { template bool parse_hex(std::string const& input, Out & output) { - boost::spirit::qi::lit_type lit; + using boost::spirit::x3::lit; auto itr = input.begin(); auto end = input.end(); - using hex2 = boost::spirit::qi::uint_parser< unsigned, 16, 2, 2 >; - return boost::spirit::qi::parse(itr, end, -(lit("\\x") | lit("0x")) > *hex2(), output); + using hex2 = boost::spirit::x3::uint_parser< unsigned, 16, 2, 2 >; + return boost::spirit::x3::parse(itr, end, -(lit("\\x") | lit("0x")) > *hex2(), output); } }} diff --git a/test/unit/serialization/wkb_formats_test.cpp b/test/unit/serialization/wkb_formats_test.cpp index 6d1a0ea2c..d74c7ed63 100644 --- a/test/unit/serialization/wkb_formats_test.cpp +++ b/test/unit/serialization/wkb_formats_test.cpp @@ -2,9 +2,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include TEST_CASE("geometry formats") { @@ -79,7 +79,7 @@ SECTION("wkb") { geom = mapnik::geometry_utils::from_wkb((const char*)sp_invalid_blob, sizeof(sp_invalid_blob) / sizeof(sp_invalid_blob[0]), mapnik::wkbAuto); - REQUIRE(geom.is>()); // returns geometry_empty + REQUIRE(geom.is()); // returns geometry_empty // sqlite generic wkb blob @@ -103,7 +103,7 @@ SECTION("wkb") { geom = mapnik::geometry_utils::from_wkb((const char*)sq_invalid_blob, sizeof(sq_invalid_blob) / sizeof(sq_invalid_blob[0]), mapnik::wkbGeneric); - REQUIRE(geom.is>()); // returns geometry_empty + REQUIRE(geom.is()); // returns geometry_empty } catch (std::exception const& ex) diff --git a/test/unit/serialization/wkb_test.cpp b/test/unit/serialization/wkb_test.cpp index 2dbb49cca..97c292486 100644 --- a/test/unit/serialization/wkb_test.cpp +++ b/test/unit/serialization/wkb_test.cpp @@ -2,8 +2,8 @@ // mapnik #include #include -#include -#include +#include +#include #include // bool #include @@ -23,7 +23,7 @@ struct spatially_equal_visitor { using result_type = bool; - result_type operator() (mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const + result_type operator() (mapnik::geometry::geometry_empty, mapnik::geometry::geometry_empty) const { return true; } @@ -100,7 +100,7 @@ TEST_CASE("Well-known-geometries") REQUIRE(mapnik::util::parse_hex(columns[2], twkb)); mapnik::geometry::geometry geom_0 = mapnik::geometry_utils::from_wkb(wkb.data(), wkb.size(), mapnik::wkbAuto); mapnik::geometry::geometry geom_1 = mapnik::geometry_utils::from_twkb(twkb.data(), twkb.size()); - // compare WKTs + // compare WKTs as doubles std::string wkt0, wkt1; REQUIRE(mapnik::util::to_wkt(wkt0, geom_0)); REQUIRE(mapnik::util::to_wkt(wkt1, geom_1)); @@ -112,6 +112,25 @@ TEST_CASE("Well-known-geometries") REQUIRE(spatially_equal(geom_0, geom_1)); #endif } + + // compare WKTS as ints + // note: mapnik::util::to_wkt used in mapnik-vt + std::string wkt2, wkt3; + mapnik::geometry::line_string geom_2; + geom_2.emplace_back(0,0); + geom_2.emplace_back(1,1); + geom_2.emplace_back(2,2); + mapnik::geometry::line_string geom_3; + geom_3.emplace_back(0,0); + geom_3.emplace_back(1,1); + geom_3.emplace_back(2,2); + REQUIRE(mapnik::util::to_wkt(wkt0, geom_2)); + REQUIRE(mapnik::util::to_wkt(wkt1, geom_3)); + if (!mapnik::geometry::is_empty(geom_2) && !mapnik::geometry::is_empty(geom_3)) + { + REQUIRE(wkt2 == wkt3); + // compare spatially (NOTE: GeometryCollection comparison also enforces strict order) + } } } } diff --git a/test/unit/text/shaping.cpp b/test/unit/text/shaping.cpp index d9da17efb..ea1fbd44a 100644 --- a/test/unit/text/shaping.cpp +++ b/test/unit/text/shaping.cpp @@ -1,25 +1,101 @@ - #include "catch.hpp" #include #include #include +#include -TEST_CASE("shapers compile") { +namespace { - mapnik::text_line line(0,0); - mapnik::text_itemizer itemizer; +void test_shaping( mapnik::font_set const& fontset, mapnik::face_manager& fm, + std::vector> const& expected, char const* str, bool debug = false) +{ + mapnik::transcoder tr("utf8"); std::map width_map; + mapnik::text_itemizer itemizer; + auto props = std::make_unique(); + props->fontset = fontset; + props->text_size = 32; + double scale_factor = 1; + auto ustr = tr.transcode(str); + auto length = ustr.length(); + itemizer.add_text(ustr, props); + + mapnik::text_line line(0, length); + mapnik::harfbuzz_shaper::shape_text(line, itemizer, + width_map, + fm, + scale_factor); + + std::size_t index = 0; + for (auto const& g : line) + { + if (debug) + { + if (index++ > 0) std::cerr << ","; + std::cerr << "{" << g.glyph_index << ", " << g.char_index + //<< ", " << g.face->family_name() << ":" << g.face->style_name() + << "}"; + } + else + { + unsigned glyph_index, char_index; + CHECK(index < expected.size()); + std::tie(glyph_index, char_index) = expected[index++]; + REQUIRE(glyph_index == g.glyph_index); + REQUIRE(char_index == g.char_index); + } + } +} +} + +TEST_CASE("shaping") +{ + mapnik::freetype_engine::register_font("test/data/fonts/NotoSans-Regular.ttc"); + mapnik::freetype_engine::register_fonts("test/data/fonts/Noto"); + mapnik::font_set fontset("fontset"); + for (auto const& name : mapnik::freetype_engine::face_names()) + { + fontset.add_face_name(name); + } + mapnik::font_library fl; mapnik::freetype_engine::font_file_mapping_type font_file_mapping; mapnik::freetype_engine::font_memory_cache_type font_memory_cache; - mapnik::face_manager fm(fl,font_file_mapping,font_memory_cache); - mapnik::harfbuzz_shaper::shape_text(line,itemizer, - width_map, - fm, - scale_factor); - mapnik::icu_shaper::shape_text(line,itemizer, - width_map, - fm, - scale_factor); -} \ No newline at end of file + mapnik::face_manager fm(fl, font_file_mapping, font_memory_cache); + + { + std::vector> expected = + {{977, 0}, {1094, 3}, {1038, 4}, {1168, 4}, {9, 7}, {3, 8}, {11, 9}, {68, 10}, {69, 11}, {70, 12}, {12, 13}}; + test_shaping(fontset, fm, expected, u8"སྤུ་ཧྲེང (abc)"); + } + + { + std::vector> expected = + {{977, 0}, {1094, 3}, {1038, 4}, {1168, 4}, {9, 7}, {3, 8}, {11, 9}, {0, 10}, {0, 11}, {0, 12}, {12, 13}}; + test_shaping(fontset, fm, expected, u8"སྤུ་ཧྲེང (普兰镇)"); + } + + { + std::vector> expected = + {{68, 0}, {69, 1}, {70, 2}, {3, 3}, {11, 4}, {0, 5}, {0, 6}, {0, 7}, {12, 8}}; + test_shaping(fontset, fm, expected, u8"abc (普兰镇)"); + } + + { + std::vector> expected = + {{68, 0}, {69, 1}, {70, 2}, {3, 3}, {11, 4}, {68, 5}, {69, 6}, {70, 7}, {12, 8}}; + test_shaping(fontset, fm, expected, "abc (abc)"); + } + + { + // "ⵃⴰⵢ ⵚⵉⵏⴰⵄⵉ الحي الصناعي" + std::vector> expected = + {{0, 0}, {0, 1}, {0, 2}, {3, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, + {0, 8}, {0, 9}, {3, 10}, {509, 22}, {481, 21}, {438, 20}, {503, 19}, + {470, 18}, {496, 17}, {43, 16}, {3, 15}, {509, 14}, {454, 13}, {496, 12}, {43, 11}}; + test_shaping(fontset, fm, expected, u8"ⵃⴰⵢ ⵚⵉⵏⴰⵄⵉ الحي الصناعي"); + } + + +} diff --git a/test/unit/vertex_adapter/extend_converter.cpp b/test/unit/vertex_adapter/extend_converter.cpp new file mode 100644 index 000000000..a8b0f080d --- /dev/null +++ b/test/unit/vertex_adapter/extend_converter.cpp @@ -0,0 +1,128 @@ +#include "catch.hpp" +#include "fake_path.hpp" + +// mapnik +#include + +// stl +#include + +namespace offset_test { + +TEST_CASE("extend converter") { + +SECTION("empty") { + try + { + fake_path path = {}; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +SECTION("one point") { + try + { + fake_path path = { 0, 0 }; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_MOVETO); + REQUIRE(x == 0); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +SECTION("two points") { + try + { + fake_path path = { 0, 0 , 1, 0}; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_MOVETO); + REQUIRE(x == -1000); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1001); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +SECTION("three points") { + try + { + fake_path path = { 0, 0, 1, 0, 2, 0 }; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_MOVETO); + REQUIRE(x == -1000); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1002); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +SECTION("more points") { + try + { + fake_path path = { 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0 }; + mapnik::extend_converter c(path, 1000); + double x, y; + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_MOVETO); + REQUIRE(x == -1000); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 2); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 3); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 4); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_LINETO); + REQUIRE(x == 1005); + REQUIRE(y == 0); + REQUIRE(c.vertex(&x, &y) == mapnik::SEG_END); + } + catch (std::exception const& ex) + { + std::cerr << ex.what() << "\n"; + REQUIRE(false); + } +} + +} + +} diff --git a/test/unit/vertex_adapter/fake_path.hpp b/test/unit/vertex_adapter/fake_path.hpp new file mode 100644 index 000000000..dc1b4aed2 --- /dev/null +++ b/test/unit/vertex_adapter/fake_path.hpp @@ -0,0 +1,93 @@ +/***************************************************************************** + * + * 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 + +// stl +#include +#include + +namespace detail +{ + +template +struct fake_path +{ + using coord_type = std::tuple; + using cont_type = std::vector; + cont_type vertices_; + typename cont_type::iterator itr_; + + fake_path(std::initializer_list l) + : fake_path(l.begin(), l.size()) + { + } + + fake_path(std::vector const &v, bool make_invalid = false) + : fake_path(v.begin(), v.size(), make_invalid) + { + } + + template + fake_path(Itr itr, size_t sz, bool make_invalid = false) + { + size_t num_coords = sz >> 1; + vertices_.reserve(num_coords + (make_invalid ? 1 : 0)); + if (make_invalid) + { + vertices_.push_back(std::make_tuple(0,0,mapnik::SEG_END)); + } + + for (size_t i = 0; i < num_coords; ++i) + { + T x = *itr++; + T y = *itr++; + unsigned cmd = (i == 0) ? mapnik::SEG_MOVETO : mapnik::SEG_LINETO; + vertices_.push_back(std::make_tuple(x, y, cmd)); + } + itr_ = vertices_.begin(); + } + + unsigned vertex(T *x, T *y) + { + if (itr_ == vertices_.end()) + { + return mapnik::SEG_END; + } + *x = std::get<0>(*itr_); + *y = std::get<1>(*itr_); + unsigned cmd = std::get<2>(*itr_); + ++itr_; + return cmd; + } + + void rewind(unsigned) + { + itr_ = vertices_.begin(); + } +}; + +} + +using fake_path = detail::fake_path; + diff --git a/test/unit/vertex_adapter/line_offset_test.cpp b/test/unit/vertex_adapter/line_offset_test.cpp index dcb8dc68b..75bfb0799 100644 --- a/test/unit/vertex_adapter/line_offset_test.cpp +++ b/test/unit/vertex_adapter/line_offset_test.cpp @@ -1,5 +1,6 @@ #include "catch.hpp" +#include "fake_path.hpp" // mapnik #include @@ -7,53 +8,6 @@ // stl #include -#include -#include - -struct fake_path -{ - using coord_type = std::tuple; - using cont_type = std::vector; - cont_type vertices_; - cont_type::iterator itr_; - - fake_path(std::initializer_list l) - : fake_path(l.begin(), l.size()) { - } - - fake_path(std::vector const &v) - : fake_path(v.begin(), v.size()) { - } - - template - fake_path(Itr itr, size_t sz) { - size_t num_coords = sz >> 1; - vertices_.reserve(num_coords); - - for (size_t i = 0; i < num_coords; ++i) { - double x = *itr++; - double y = *itr++; - unsigned cmd = (i == 0) ? agg::path_cmd_move_to : agg::path_cmd_line_to; - vertices_.push_back(std::make_tuple(x, y, cmd)); - } - itr_ = vertices_.begin(); - } - - unsigned vertex(double *x, double *y) { - if (itr_ == vertices_.end()) { - return agg::path_cmd_stop; - } - *x = std::get<0>(*itr_); - *y = std::get<1>(*itr_); - unsigned cmd = std::get<2>(*itr_); - ++itr_; - return cmd; - } - - void rewind(unsigned) { - itr_ = vertices_.begin(); - } -}; double dist(mapnik::pixel_position const &a, mapnik::pixel_position const &b) diff --git a/test/unit/vertex_adapter/offset_converter.cpp b/test/unit/vertex_adapter/offset_converter.cpp index 9255f7d97..96c796d06 100644 --- a/test/unit/vertex_adapter/offset_converter.cpp +++ b/test/unit/vertex_adapter/offset_converter.cpp @@ -1,66 +1,15 @@ #include "catch.hpp" +#include "fake_path.hpp" // mapnik -#include #include // stl #include -#include -#include namespace offset_test { -struct fake_path -{ - using coord_type = std::tuple; - using cont_type = std::vector; - cont_type vertices_; - cont_type::iterator itr_; - - fake_path(std::initializer_list l) - : fake_path(l.begin(), l.size()) { - } - - fake_path(std::vector const &v, bool make_invalid = false) - : fake_path(v.begin(), v.size(), make_invalid) { - } - - template - fake_path(Itr itr, size_t sz, bool make_invalid = false) { - size_t num_coords = sz >> 1; - vertices_.reserve(num_coords + (make_invalid ? 1 : 0)); - if (make_invalid) - { - vertices_.push_back(std::make_tuple(0,0,mapnik::SEG_END)); - } - - for (size_t i = 0; i < num_coords; ++i) { - double x = *itr++; - double y = *itr++; - unsigned cmd = (i == 0) ? mapnik::SEG_MOVETO : mapnik::SEG_LINETO; - vertices_.push_back(std::make_tuple(x, y, cmd)); - } - itr_ = vertices_.begin(); - } - - unsigned vertex(double *x, double *y) { - if (itr_ == vertices_.end()) { - return mapnik::SEG_END; - } - *x = std::get<0>(*itr_); - *y = std::get<1>(*itr_); - unsigned cmd = std::get<2>(*itr_); - ++itr_; - return cmd; - } - - void rewind(unsigned) { - itr_ = vertices_.begin(); - } -}; - static double DELTA_BUFF = 0.5; double dist(double x0, double y0, double x1, double y1) diff --git a/test/unit/vertex_adapter/vertex_adapter.cpp b/test/unit/vertex_adapter/vertex_adapter.cpp index d6c1ed592..6fe6dda44 100644 --- a/test/unit/vertex_adapter/vertex_adapter.cpp +++ b/test/unit/vertex_adapter/vertex_adapter.cpp @@ -1,7 +1,7 @@ #include "catch.hpp" #include -#include +#include TEST_CASE("vertex_adapters") { diff --git a/test/visual/map_sizes_grammar.hpp b/test/visual/parse_map_sizes.cpp similarity index 55% rename from test/visual/map_sizes_grammar.hpp rename to test/visual/parse_map_sizes.cpp index 2c79d90d8..7cea5df4a 100644 --- a/test/visual/map_sizes_grammar.hpp +++ b/test/visual/parse_map_sizes.cpp @@ -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,40 +20,36 @@ * *****************************************************************************/ -#ifndef MAP_SIZES_GRAMMAR_HPP -#define MAP_SIZES_GRAMMAR_HPP +#include "parse_map_sizes.hpp" #pragma GCC diagnostic push #include -#include -#include +#include +#include #pragma GCC diagnostic pop -namespace visual_tests -{ +BOOST_FUSION_ADAPT_STRUCT ( + visual_tests::map_size, + (std::size_t, width) + (std::size_t, height) + ) -namespace qi = boost::spirit::qi; -namespace ascii = boost::spirit::ascii; +namespace visual_tests { -template -struct map_sizes_grammar : qi::grammar(), ascii::space_type> +namespace x3 = boost::spirit::x3; +using x3::ulong_; +auto const map_sizes_grammar = x3::rule >{} = + (ulong_ >> ',' >> ulong_) % ';' ; + +void parse_map_sizes(std::string const & str, std::vector & sizes) { - map_sizes_grammar() : map_sizes_grammar::base_type(start) + boost::spirit::x3::ascii::space_type space; + std::string::const_iterator iter = str.begin(); + std::string::const_iterator end = str.end(); + if (!boost::spirit::x3::phrase_parse(iter, end, map_sizes_grammar, space, sizes)) { - using namespace boost::spirit::qi; - using namespace boost::phoenix; - - int_type int_; - _1_type _1; - _2_type _2; - _val_type _val; - - start = (int_ >> ',' >> int_)[push_back(_val, construct(_1, _2))] % ';'; + throw std::runtime_error("Failed to parse list of sizes: '" + str + "'"); } - - qi::rule(), ascii::space_type> start; -}; - } -#endif +} diff --git a/src/image_filter_grammar.cpp b/test/visual/parse_map_sizes.hpp similarity index 80% rename from src/image_filter_grammar.cpp rename to test/visual/parse_map_sizes.hpp index 9a4bea35a..5d0f0125b 100644 --- a/src/image_filter_grammar.cpp +++ b/test/visual/parse_map_sizes.hpp @@ -20,10 +20,17 @@ * *****************************************************************************/ -#include -#include -#include -#include -#include +#ifndef VISUAL_TESTS_PARSE_MAP_SIZES_HPP +#define VISUAL_TESTS_PARSE_MAP_SIZES_HPP -template struct mapnik::image_filter_grammar>; +#include "config.hpp" +#include +#include + +namespace visual_tests { + +void parse_map_sizes(std::string const & str, std::vector & sizes); + +} + +#endif //VISUAL_TESTS_PARSE_MAP_SIZES_HPP diff --git a/test/visual/runner.cpp b/test/visual/runner.cpp index d0c7222fb..18e6506ec 100644 --- a/test/visual/runner.cpp +++ b/test/visual/runner.cpp @@ -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 @@ -25,9 +25,11 @@ #include #include + #include #include "runner.hpp" +#include "parse_map_sizes.hpp" namespace visual_tests { @@ -348,19 +350,7 @@ result_list runner::test_one(runner::path_type const& style_path, } } } - return results; } -void runner::parse_map_sizes(std::string const & str, std::vector & sizes) const -{ - boost::spirit::ascii::space_type space; - std::string::const_iterator iter = str.begin(); - std::string::const_iterator end = str.end(); - if (!boost::spirit::qi::phrase_parse(iter, end, map_sizes_parser_, space, sizes)) - { - throw std::runtime_error("Failed to parse list of sizes: '" + str + "'"); - } -} - } diff --git a/test/visual/runner.hpp b/test/visual/runner.hpp index e38e39422..b5c031627 100644 --- a/test/visual/runner.hpp +++ b/test/visual/runner.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 @@ -26,7 +26,6 @@ #include "config.hpp" #include "report.hpp" #include "renderer.hpp" -#include "map_sizes_grammar.hpp" namespace visual_tests { @@ -58,9 +57,7 @@ private: result_list test_one(path_type const & style_path, report_type & report, std::atomic & fail_limit) const; - void parse_map_sizes(std::string const & str, std::vector & sizes) const; - const map_sizes_grammar map_sizes_parser_; const path_type styles_dir_; const config defaults_; const std::size_t jobs_; @@ -71,4 +68,4 @@ private: } -#endif +#endif //VISUAL_TEST_RUNNER_HPP diff --git a/utils/mapnik-index/build.py b/utils/mapnik-index/build.py index 358ce5f88..9bddaf196 100644 --- a/utils/mapnik-index/build.py +++ b/utils/mapnik-index/build.py @@ -32,8 +32,8 @@ source = Split( """ mapnik-index.cpp process_csv_file.cpp - process_geojson_file.cpp - ../../plugins/input/csv/csv_utils.cpp + process_geojson_file_x3.cpp + ../../plugins/input/csv/csv_utils.os """ ) diff --git a/utils/mapnik-index/mapnik-index.cpp b/utils/mapnik-index/mapnik-index.cpp index 9b1859bf2..1de90b6c4 100644 --- a/utils/mapnik-index/mapnik-index.cpp +++ b/utils/mapnik-index/mapnik-index.cpp @@ -24,12 +24,12 @@ #include #include #include - +#include #include #include #include "process_csv_file.hpp" -#include "process_geojson_file.hpp" +#include "process_geojson_file_x3.hpp" #pragma GCC diagnostic push #include @@ -87,12 +87,16 @@ int main (int argc, char** argv) po::positional_options_description p; p.add("files",-1); po::variables_map vm; - po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); + po::store(po::command_line_parser(argc, argv) + .options(desc) + .style(po::command_line_style::unix_style | po::command_line_style::allow_long_disguise) + .positional(p) + .run(), vm); po::notify(vm); if (vm.count("version")) { - std::clog << "version 1.0.0" << std::endl; + std::clog << "version " << MAPNIK_VERSION_STRING << std::endl; return 1; } if (vm.count("help")) @@ -190,7 +194,8 @@ int main (int argc, char** argv) else if (mapnik::detail::is_geojson(filename)) { std::clog << "processing '" << filename << "' as GeoJSON\n"; - auto result = mapnik::detail::process_geojson_file(boxes, filename, validate_features, verbose); + std::pair> result; + result = mapnik::detail::process_geojson_file_x3(boxes, filename, validate_features, verbose); if (!result.first) { std::clog << "Error: failed to process " << filename << std::endl; diff --git a/utils/mapnik-index/process_csv_file.cpp b/utils/mapnik-index/process_csv_file.cpp index a0342cff5..79802392c 100644 --- a/utils/mapnik-index/process_csv_file.cpp +++ b/utils/mapnik-index/process_csv_file.cpp @@ -24,7 +24,7 @@ #include "../../plugins/input/csv/csv_getline.hpp" #include "../../plugins/input/csv/csv_utils.hpp" #include -#include +#include #include #if defined(MAPNIK_MEMORY_MAPPED_FILE) diff --git a/utils/mapnik-index/process_csv_file.hpp b/utils/mapnik-index/process_csv_file.hpp index 395bf55c7..24cb71509 100644 --- a/utils/mapnik-index/process_csv_file.hpp +++ b/utils/mapnik-index/process_csv_file.hpp @@ -24,7 +24,7 @@ #define MAPNIK_UTILS_PROCESS_CSV_FILE_HPP #include -#include +#include namespace mapnik { namespace detail { diff --git a/utils/mapnik-index/process_geojson_file.cpp b/utils/mapnik-index/process_geojson_file.cpp deleted file mode 100644 index 44553185f..000000000 --- a/utils/mapnik-index/process_geojson_file.cpp +++ /dev/null @@ -1,146 +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 - * - *****************************************************************************/ - -#include "process_geojson_file.hpp" - -#if defined(MAPNIK_MEMORY_MAPPED_FILE) -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop -#include -#else -#include -#endif - -#include -#include - -namespace { - -template -struct feature_validate_callback -{ - feature_validate_callback(mapnik::box2d const& box) - : box_(box) {} - - void operator() (mapnik::feature_ptr const& f) const - { - if (box_ != box_) - { - throw std::runtime_error("Bounding boxes mismatch validation feature"); - } - } - mapnik::box2d const& box_; -}; - -using box_type = mapnik::box2d; -using boxes_type = std::vector>>; -using base_iterator_type = char const*; -const mapnik::json::extract_bounding_box_grammar geojson_datasource_static_bbox_grammar; -const mapnik::transcoder tr("utf8"); -const mapnik::json::feature_grammar_callback> fc_grammar(tr); -} - -namespace mapnik { namespace detail { - -template -std::pair process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose) -{ - using box_type = typename T::value_type::first_type; - box_type extent; -#if defined(MAPNIK_MEMORY_MAPPED_FILE) - mapnik::mapped_region_ptr mapped_region; - boost::optional memory = - mapnik::mapped_memory_cache::instance().find(filename, true); - if (!memory) - { - std::clog << "Error : cannot memory map " << filename << std::endl; - return std::make_pair(false, extent); - } - else - { - mapped_region = *memory; - } - char const* start = reinterpret_cast(mapped_region->get_address()); - char const* end = start + mapped_region->get_size(); -#else - mapnik::util::file file(filename); - if (!file) - { - std::clog << "Error : cannot open " << filename << std::endl; - return std::make_pair(false, extent); - } - std::string file_buffer; - file_buffer.resize(file.size()); - std::fread(&file_buffer[0], file.size(), 1, file.get()); - char const* start = file_buffer.c_str(); - char const* end = start + file_buffer.length(); -#endif - - boost::spirit::standard::space_type space; - auto const* itr = start; - try - { - if (!boost::spirit::qi::phrase_parse(itr, end, (geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space)) - { - std::clog << "mapnik-index (GeoJSON) : could not extract bounding boxes from : '" << filename << "'" << std::endl; - return std::make_pair(false, extent); - } - } - catch (std::exception const& ex) - { - std::clog << "mapnik-index (GeoJSON): " << ex.what() << std::endl; - } - mapnik::context_ptr ctx = std::make_shared(); - std::size_t start_id = 1; - for (auto const& item : boxes) - { - if (item.first.valid()) - { - if (!extent.valid()) extent = item.first; - else extent.expand_to_include(item.first); - - if (validate_features) - { - base_iterator_type feat_itr = start + item.second.first; - base_iterator_type feat_end = feat_itr + item.second.second; - feature_validate_callback callback(item.first); - bool result = boost::spirit::qi::phrase_parse(feat_itr, feat_end, (fc_grammar) - (boost::phoenix::ref(ctx), boost::phoenix::ref(start_id), boost::phoenix::ref(callback)), - space); - if (!result || feat_itr != feat_end) - { - if (verbose) std::clog << std::string(start + item.second.first, feat_end ) << std::endl; - return std::make_pair(false, extent); - } - } - } - } - return std::make_pair(true, extent); -} - -template std::pair process_geojson_file(boxes_type&, std::string const&, bool, bool); - -}} diff --git a/utils/mapnik-index/process_geojson_file_x3.cpp b/utils/mapnik-index/process_geojson_file_x3.cpp new file mode 100644 index 000000000..c55989bc7 --- /dev/null +++ b/utils/mapnik-index/process_geojson_file_x3.cpp @@ -0,0 +1,330 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#include "process_geojson_file_x3.hpp" + +#if defined(MAPNIK_MEMORY_MAPPED_FILE) +#pragma GCC diagnostic push +#include +#include +#include +#include +#pragma GCC diagnostic pop +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include + +namespace { + +constexpr mapnik::json::well_known_names feature_properties[] = { + mapnik::json::well_known_names::type, + mapnik::json::well_known_names::geometry, + mapnik::json::well_known_names::properties}; // sorted + +constexpr mapnik::json::well_known_names geometry_properties[] = { + mapnik::json::well_known_names::type, + mapnik::json::well_known_names::coordinates}; // sorted + +template +std::string join(Keys const& keys) +{ + std::string result; + bool first = true; + for (auto const& key : keys) + { + if (!first) result += ","; + result += "\"" + std::string(mapnik::json::wkn_to_string(key)) + "\""; + first = false; + } + return result; +} + +template +bool has_keys(Iterator first1, Iterator last1, Keys const& keys) +{ + auto first2 = std::begin(keys); + auto last2 = std::end(keys); + for (; first2 != last2; ++first1) + { + if (first1 == last1 || *first2 < std::get<0>(*first1)) + return false; + if (!(std::get<0>(*first1) < *first2)) + ++first2; + } + return true; +} + +template +bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& keys, bool verbose) +{ + if (!value.is()) + { + if (verbose) std::clog << "Expecting an GeoJSON object" << std::endl; + return false; + } + mapnik::json::geojson_object & feature = mapnik::util::get(value); + std::sort(feature.begin(), feature.end(), [](auto const& e0, auto const& e1) + { + return std::get<0>(e0) < std::get<0>(e1); + }); + + if (!has_keys(feature.begin(), feature.end(), feature_properties)) + { + if (verbose) std::clog << "Expecting one of " << join(feature_properties) << std::endl; + return false; + } + + for (auto & elem : feature) + { + auto const key = std::get<0>(elem); + if (key == mapnik::json::well_known_names::geometry) + { + auto & geom_value = std::get<1>(elem); + if (!geom_value.is()) + { + if (verbose) std::clog << "\"geometry\": xxx <-- expecting an JSON object here" << std::endl; + return false; + } + auto & geometry = mapnik::util::get(geom_value); + // sort by property name + std::sort(geometry.begin(), geometry.end(), [](auto const& e0, auto const& e1) + { + return std::get<0>(e0) < std::get<0>(e1); + }); + if (!has_keys(geometry.begin(), geometry.end(), geometry_properties)) + { + if (verbose) std::clog << "Expecting one of " << join(geometry_properties) << std::endl; + return false; + } + + 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()) + { + if (verbose) std::clog << "\"type\": xxx <-- expecting an GeoJSON geometry type here" << std::endl; + return false; + } + geom_type = mapnik::util::get(geom_type_value); + if (geom_type == mapnik::geometry::geometry_types::GeometryCollection) + { + if (verbose) std::clog << "GeometryCollections are not allowed" << std::endl;; + return false; + } + } + else if (key2 == mapnik::json::well_known_names::coordinates) + { + auto const& coordinates_value = std::get<1>(elem2); + if (!coordinates_value.is()) + { + if (verbose) std::clog << "\"coordinates\": xxx <-- expecting an GeoJSON positions here" << std::endl; + return false; + } + coordinates = &mapnik::util::get(coordinates_value); + } + } + if (geom_type == mapnik::geometry::geometry_types::Point) + { + // expecting single position + if (!coordinates->is()) + { + if (verbose) std::clog << "Expecting single position in Point" << std::endl; + return false; + } + } + else if (geom_type == mapnik::geometry::geometry_types::LineString) + { + // expecting + if (!coordinates->is()) + { + if (verbose) std::clog << "Expecting sequence of positions (ring) in LineString" << std::endl; + return false; + } + else + { + auto const& ring = mapnik::util::get(*coordinates); + if (ring.size() < 2) + { + if (verbose) std::clog << "Expecting at least two coordinates in LineString" << std::endl; + return false; + } + } + } + else if (geom_type == mapnik::geometry::geometry_types::Polygon) + { + // expecting + if (!coordinates->is()) + { + if (verbose) std::clog << "Expecting an array of rings in Polygon" << std::endl; + return false; + } + else + { + auto const& rings = mapnik::util::get(*coordinates); + if (rings.size() < 1) + { + if (verbose) std::clog << "Expecting at least one ring in Polygon" << std::endl; + return false; + } + for (auto const& ring : rings) + { + if (ring.size() < 4) + { + if (verbose) std::clog << "Expecting at least four coordinates in Polygon ring" << std::endl; + return false; + } + } + } + } + } + } + return true; +}; + +using box_type = mapnik::box2d; +using boxes_type = std::vector>>; +using base_iterator_type = char const*; + +auto const& geojson_value = mapnik::json::geojson_grammar(); + +} + +namespace mapnik { namespace detail { + + +template +std::pair process_geojson_file_x3(T & boxes, std::string const& filename, bool validate_features, bool verbose) +{ + using box_type = typename T::value_type::first_type; + box_type extent; +#if defined(MAPNIK_MEMORY_MAPPED_FILE) + mapnik::mapped_region_ptr mapped_region; + boost::optional memory = + mapnik::mapped_memory_cache::instance().find(filename, true); + if (!memory) + { + std::clog << "Error : cannot memory map " << filename << std::endl; + return std::make_pair(false, extent); + } + else + { + mapped_region = *memory; + } + base_iterator_type start = reinterpret_cast(mapped_region->get_address()); + base_iterator_type end = start + mapped_region->get_size(); +#else + mapnik::util::file file(filename); + if (!file) + { + std::clog << "Error : cannot open " << filename << std::endl; + return std::make_pair(false, extent); + } + std::string file_buffer; + file_buffer.resize(file.size()); + auto count = std::fread(&file_buffer[0], file.size(), 1, file.get()); + base_iterator_type start = file_buffer.c_str(); + base_iterator_type end = (count == 1) ? start + file_buffer.length() : start; +#endif + base_iterator_type itr = start; // make a copy to preserve `start` iterator state + try + { + mapnik::json::extract_bounding_boxes(itr, end, boxes); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + std::clog << ex.what() << std::endl; + std::clog << "Expected: " << ex.which(); + std::clog << " Got: \"" << std::string(ex.where(), ex.where() + 200) << '"' << std::endl; + return std::make_pair(false, extent); + } + catch (std::exception const& ex) + { + std::clog << "mapnik-index (GeoJSON) : could not extract bounding boxes from : '" << filename << "'" << std::endl; + return std::make_pair(false, extent); + } + + using namespace boost::spirit; + using space_type = mapnik::json::grammar::space_type; + auto keys = mapnik::json::get_keys(); + auto feature_grammar = x3::with(std::ref(keys)) + [ geojson_value ]; + for (auto const& item : boxes) + { + if (item.first.valid()) + { + if (!extent.valid()) extent = item.first; + else extent.expand_to_include(item.first); + if (validate_features) + { + base_iterator_type feat_itr = start + item.second.first; + base_iterator_type feat_end = feat_itr + item.second.second; + mapnik::json::geojson_value feature_value; + try + { + bool result = x3::phrase_parse(feat_itr, feat_end, feature_grammar, space_type(), feature_value); + if (!result || feat_itr != feat_end) + { + if (verbose) std::clog << "Failed to parse: offset=" << item.second.first << " size=" << item.second.second << std::endl; + return std::make_pair(false, extent); + } + } + catch (x3::expectation_failure const& ex) + { + if (verbose) std::clog << ex.what() << std::endl; + return std::make_pair(false, extent); + } + catch (...) + { + if (verbose) std::clog << "Failed to parse: offset=" << item.second.first << " size=" << item.second.second << std::endl; + return std::make_pair(false, extent); + } + if (!validate_geojson_feature(feature_value, keys, verbose)) + { + if (verbose) std::clog << "Failed to validate: [" << std::string(start + item.second.first, feat_end ) << "]" << std::endl; + return std::make_pair(false, extent); + } + } + } + else if (validate_features) + { + if (verbose) std::clog << "Invalid bbox encountered " << item.first << std::endl; + return std::make_pair(false, extent); + } + } + return std::make_pair(true, extent); +} + +template std::pair process_geojson_file_x3(boxes_type&, std::string const&, bool, bool); + +}} diff --git a/utils/mapnik-index/process_geojson_file.hpp b/utils/mapnik-index/process_geojson_file_x3.hpp similarity index 81% rename from utils/mapnik-index/process_geojson_file.hpp rename to utils/mapnik-index/process_geojson_file_x3.hpp index a377d23e3..17545db66 100644 --- a/utils/mapnik-index/process_geojson_file.hpp +++ b/utils/mapnik-index/process_geojson_file_x3.hpp @@ -20,17 +20,17 @@ * *****************************************************************************/ -#ifndef MAPNIK_UTILS_PROCESS_GEOJSON_FILE_HPP -#define MAPNIK_UTILS_PROCESS_GEOJSON_FILE_HPP +#ifndef MAPNIK_UTILS_PROCESS_GEOJSON_FILE_X3_HPP +#define MAPNIK_UTILS_PROCESS_GEOJSON_FILE_X3_HPP #include -#include +#include namespace mapnik { namespace detail { template -std::pair process_geojson_file(T & boxes, std::string const& filename, bool validate_features, bool verbose); +std::pair process_geojson_file_x3(T & boxes, std::string const& filename, bool validate_features, bool verbose); }} -#endif // MAPNIK_UTILS_PROCESS_GEOJSON_FILE_HPP +#endif // MAPNIK_UTILS_PROCESS_GEOJSON_FILE_X3_HPP diff --git a/utils/ogrindex/ogrindex.cpp b/utils/ogrindex/ogrindex.cpp index 3e7fd503c..4aa685abe 100644 --- a/utils/ogrindex/ogrindex.cpp +++ b/utils/ogrindex/ogrindex.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include diff --git a/utils/pgsql2sqlite/pgsql2sqlite.hpp b/utils/pgsql2sqlite/pgsql2sqlite.hpp index 9de886732..8e702a2fa 100644 --- a/utils/pgsql2sqlite/pgsql2sqlite.hpp +++ b/utils/pgsql2sqlite/pgsql2sqlite.hpp @@ -29,8 +29,8 @@ #include #include #include -#include -#include +#include +#include #include "connection_manager.hpp" #include "cursorresultset.hpp" diff --git a/utils/shapeindex/shapeindex.cpp b/utils/shapeindex/shapeindex.cpp index 9dcff1189..b8fef4a1a 100644 --- a/utils/shapeindex/shapeindex.cpp +++ b/utils/shapeindex/shapeindex.cpp @@ -20,13 +20,13 @@ * *****************************************************************************/ - #include #include #include +#include #include #include -#include +#include #include "shapefile.hpp" #include "shape_io.hpp" #include "shape_index_featureset.hpp" @@ -71,7 +71,7 @@ int main (int argc,char** argv) if (vm.count("version")) { - std::clog << "version 0.3.0" < Date: Wed, 29 Mar 2017 11:39:04 +0100 Subject: [PATCH 46/51] remove `has_empty` + fix `is_empty` implementaion to work with geometry.hpp --- include/mapnik/geometry/centroid.hpp | 20 ---- include/mapnik/geometry/is_empty.hpp | 85 +-------------- test/unit/geometry/has_empty.cpp | 150 --------------------------- 3 files changed, 2 insertions(+), 253 deletions(-) delete mode 100644 test/unit/geometry/has_empty.cpp diff --git a/include/mapnik/geometry/centroid.hpp b/include/mapnik/geometry/centroid.hpp index 3608d95ce..ab8b05ba4 100644 --- a/include/mapnik/geometry/centroid.hpp +++ b/include/mapnik/geometry/centroid.hpp @@ -107,26 +107,6 @@ private: template result_type centroid_multi(Geom const & multi_geom) const { -// https://github.com/mapnik/mapnik/issues/3169 -#if BOOST_VERSION <= 105900 - if (mapnik::geometry::has_empty(multi_geom)) - { - mapnik::geometry::multi_point multi_pt; - multi_pt.reserve(multi_geom.size()); - for (auto const& geom : multi_geom) - { - try - { - point c; - boost::geometry::centroid(geom, c); - multi_pt.push_back(std::move(c)); - - } - catch (boost::geometry::centroid_exception const & e) {} - } - return centroid_simple(multi_pt); - } -#endif return centroid_simple(multi_geom); } }; diff --git a/include/mapnik/geometry/is_empty.hpp b/include/mapnik/geometry/is_empty.hpp index 206fb185c..1ad0389aa 100644 --- a/include/mapnik/geometry/is_empty.hpp +++ b/include/mapnik/geometry/is_empty.hpp @@ -48,7 +48,7 @@ struct geometry_is_empty bool operator() (mapnik::geometry::polygon const& geom) const { - return geom.empty(); + return geom.empty() || geom.front().empty(); } bool operator() (mapnik::geometry::multi_point const& geom) const @@ -78,96 +78,15 @@ struct geometry_is_empty } }; - -struct geometry_has_empty -{ - bool operator() (mapnik::geometry::geometry const& geom) const - { - return mapnik::util::apply_visitor(*this, geom); - } - - bool operator() (mapnik::geometry::geometry_empty const&) const - { - return false; - } - - bool operator() (mapnik::geometry::point const&) const - { - return false; - } - - bool operator() (mapnik::geometry::line_string const&) const - { - return false; - } - - bool operator() (mapnik::geometry::polygon const&) const - { - return false; - } - - bool operator() (mapnik::geometry::multi_point const&) const - { - return false; - } - - bool operator() (mapnik::geometry::multi_line_string const& geom) const - { - return test_multigeometry(geom); - } - - bool operator() (mapnik::geometry::multi_polygon const& geom) const - { - return test_multigeometry(geom); - } - - bool operator() (mapnik::geometry::geometry_collection const& geom) const - { - for (auto const & item : geom) - { - if (geometry_is_empty()(item) || (*this)(item)) - { - return true; - } - } - return false; - } - - template - bool operator() (T const&) const - { - return true; - } - -private: - template - bool test_multigeometry(T const & geom) const - { - for (auto const & item : geom) - { - if (item.empty()) - { - return true; - } - } - return false; - } -}; - } +// returns true if the geometry is the empty set template inline bool is_empty(GeomType const& geom) { return detail::geometry_is_empty()(geom); } -template -inline bool has_empty(GeomType const& geom) -{ - return detail::geometry_has_empty()(geom); -} - }} #endif // MAPNIK_GEOMETRY_IS_EMPTY_HPP diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp deleted file mode 100644 index 79159d173..000000000 --- a/test/unit/geometry/has_empty.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include "catch.hpp" - -#include - -TEST_CASE("geometry has_empty") { - -SECTION("empty geometry") { - - mapnik::geometry::geometry_empty geom; - REQUIRE(!mapnik::geometry::has_empty(geom)); -} - -SECTION("geometry collection") { - - { - mapnik::geometry::geometry_collection geom; - REQUIRE(!mapnik::geometry::has_empty(geom)); - } - { - mapnik::geometry::geometry_collection geom; - mapnik::geometry::geometry_empty geom1; - geom.emplace_back(std::move(geom1)); - REQUIRE(mapnik::geometry::has_empty(geom)); - } - { - mapnik::geometry::geometry_collection geom; - mapnik::geometry::multi_line_string mls; - mapnik::geometry::line_string line; - mls.emplace_back(std::move(line)); - geom.emplace_back(std::move(mls)); - REQUIRE(mapnik::geometry::has_empty(geom)); - } - { - mapnik::geometry::geometry_collection geom; - mapnik::geometry::multi_line_string mls; - mapnik::geometry::line_string line; - line.emplace_back(0, 0); - mls.emplace_back(std::move(line)); - geom.emplace_back(std::move(mls)); - REQUIRE(!mapnik::geometry::has_empty(geom)); - } -} - -SECTION("point") { - - mapnik::geometry::point pt(10, 10); - REQUIRE(!mapnik::geometry::has_empty(pt)); -} - -SECTION("linestring") { - - { - mapnik::geometry::line_string line; - REQUIRE(!mapnik::geometry::has_empty(line)); - } - { - mapnik::geometry::line_string line; - line.emplace_back(0, 0); - line.emplace_back(25, 25); - line.emplace_back(50, 50); - REQUIRE(!mapnik::geometry::has_empty(line)); - } -} - -SECTION("polygon") { - - { - mapnik::geometry::polygon poly; - REQUIRE(!mapnik::geometry::has_empty(poly)); - } - { - mapnik::geometry::polygon poly; - mapnik::geometry::linear_ring ring; - poly.push_back(std::move(ring)); - REQUIRE(!mapnik::geometry::has_empty(poly)); - } - { - mapnik::geometry::polygon poly; - mapnik::geometry::linear_ring ring; - ring.emplace_back(0, 0); - ring.emplace_back(1, 0); - ring.emplace_back(1, 1); - ring.emplace_back(0, 1); - ring.emplace_back(0, 0); - poly.push_back(std::move(ring)); - REQUIRE(!mapnik::geometry::has_empty(poly)); - } -} - -SECTION("multi-point") { - - { - mapnik::geometry::multi_point geom; - REQUIRE(!mapnik::geometry::has_empty(geom)); - } - { - mapnik::geometry::multi_point geom; - geom.emplace_back(0, 0); - geom.emplace_back(25, 25); - geom.emplace_back(50, 50); - REQUIRE(!mapnik::geometry::has_empty(geom)); - } -} - -SECTION("multi-linestring") { - - { - mapnik::geometry::multi_line_string geom; - REQUIRE(!mapnik::geometry::has_empty(geom)); - } - { - mapnik::geometry::multi_line_string geom; - mapnik::geometry::line_string line; - geom.emplace_back(std::move(line)); - REQUIRE(mapnik::geometry::has_empty(geom)); - } - { - mapnik::geometry::multi_line_string geom; - mapnik::geometry::line_string line; - line.emplace_back(0, 0); - geom.emplace_back(std::move(line)); - REQUIRE(!mapnik::geometry::has_empty(geom)); - } -} - -SECTION("multi-polygon") { - - { - mapnik::geometry::multi_polygon geom; - REQUIRE(!mapnik::geometry::has_empty(geom)); - } - { - mapnik::geometry::multi_polygon geom; - mapnik::geometry::polygon poly; - mapnik::geometry::linear_ring ring; - poly.push_back(std::move(ring)); - geom.emplace_back(std::move(poly)); - REQUIRE(mapnik::geometry::has_empty(geom)); - } - { - mapnik::geometry::multi_polygon geom; - mapnik::geometry::polygon poly; - mapnik::geometry::linear_ring ring; - ring.emplace_back(0, 0); - poly.push_back(std::move(ring)); - geom.emplace_back(std::move(poly)); - REQUIRE(!mapnik::geometry::has_empty(geom)); - } -} -} From 433d95046b4b472c18918225fbc7deb1be49ad1a Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 29 Mar 2017 15:41:39 +0100 Subject: [PATCH 47/51] re-enable `strategy` tests --- test/unit/geometry/geometry_strategy_test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/unit/geometry/geometry_strategy_test.cpp b/test/unit/geometry/geometry_strategy_test.cpp index 2e63cc9d4..d052f9edf 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -10,7 +10,7 @@ #include #include -#if 0 + TEST_CASE("geometry strategy tests") { SECTION("proj and view strategy") { using namespace mapnik::geometry; @@ -184,4 +184,3 @@ SECTION("scaling strategies - double to int64") { } } // END SECTION } // END TEST CASE -#endif From dd079183c532b7edfaf02ce6b6a263d8277bcad9 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 29 Mar 2017 17:44:07 +0100 Subject: [PATCH 48/51] add `boost::geometry::resize` and `boost::geometry::clear` traits specialisations for `mapnik::interior_rings` --- include/mapnik/geometry/boost_adapters.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/mapnik/geometry/boost_adapters.hpp b/include/mapnik/geometry/boost_adapters.hpp index 63f135aea..c30143445 100644 --- a/include/mapnik/geometry/boost_adapters.hpp +++ b/include/mapnik/geometry/boost_adapters.hpp @@ -41,6 +41,7 @@ #include BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::geometry::point, double, boost::geometry::cs::cartesian, x, y) +BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point, std::int64_t, boost::geometry::cs::cartesian, x, y) BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(mapnik::geometry::line_string) BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(mapnik::geometry::linear_ring) // needed by box2d @@ -227,6 +228,25 @@ struct interior_rings > } }; +template +struct resize> +{ + static inline void apply(mapnik::interior_rings interiors, std::size_t new_size) + { + interiors.resize(new_size); + } +}; + +template +struct clear> +{ + static inline void apply(mapnik::interior_rings interiors) + { + interiors.clear(); + } +}; + }}} + #endif //MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP From f9bfa596f1be296886ab0c516d1fb61ad9c349e5 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 30 Mar 2017 08:05:24 +0100 Subject: [PATCH 49/51] update visual data --- test/data-visual | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/data-visual b/test/data-visual index b399ad677..13680134c 160000 --- a/test/data-visual +++ b/test/data-visual @@ -1 +1 @@ -Subproject commit b399ad677146c9d7b1c11470691b7a332d95b156 +Subproject commit 13680134c5d43c457dce3163b045b6ab70423a6b From e3bf8cb558b3f1c5cfe6fbbf720fef2c16d4bc03 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 30 Mar 2017 09:23:11 +0100 Subject: [PATCH 50/51] use range based loop via @flippmoke --- include/mapnik/json/create_geometry.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/mapnik/json/create_geometry.hpp b/include/mapnik/json/create_geometry.hpp index 5f241efc1..eb5569031 100644 --- a/include/mapnik/json/create_geometry.hpp +++ b/include/mapnik/json/create_geometry.hpp @@ -89,12 +89,12 @@ struct create_polygon mapnik::geometry::polygon poly; std::size_t num_rings = rngs.size(); poly.reserve(num_rings); - for ( std::size_t i = 0; i < num_rings; ++i) + for (auto const& r : rngs) { - std::size_t size = rngs[i].size(); + std::size_t size = r.size(); mapnik::geometry::linear_ring ring; ring.reserve(size); - for ( auto && pt : rngs[i]) + for ( auto && pt : r) { ring.emplace_back(std::move(pt)); } From ef7da04cc9c88867597eae92a73a4cd2c1beaaf5 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 30 Mar 2017 09:23:58 +0100 Subject: [PATCH 51/51] cleanup --- include/mapnik/geometry/boost_adapters.hpp | 47 ---------------------- 1 file changed, 47 deletions(-) diff --git a/include/mapnik/geometry/boost_adapters.hpp b/include/mapnik/geometry/boost_adapters.hpp index 115cfa46a..dd6b9e587 100644 --- a/include/mapnik/geometry/boost_adapters.hpp +++ b/include/mapnik/geometry/boost_adapters.hpp @@ -138,53 +138,6 @@ struct indexed_access, max_corner, 1> static inline void set(mapnik::box2d &b , ct const& value) { b.set_maxy(value); } }; -<<<<<<< HEAD:include/mapnik/geometry/boost_adapters.hpp -======= -// box2d -template<> struct tag > { using type = box_tag; }; -template<> struct point_type > { using type = mapnik::coord2f; }; - -template <> -struct indexed_access, min_corner, 0> -{ - using ct = coordinate_type::type; - static inline ct get(mapnik::box2d const& b) { return b.minx();} - static inline void set(mapnik::box2d &b, ct const& value) { b.set_minx(value); } -}; - -template <> -struct indexed_access, min_corner, 1> -{ - using ct = coordinate_type::type; - static inline ct get(mapnik::box2d const& b) { return b.miny();} - static inline void set(mapnik::box2d &b, ct const& value) { b.set_miny(value); } -}; - -template <> -struct indexed_access, max_corner, 0> -{ - using ct = coordinate_type::type; - static inline ct get(mapnik::box2d const& b) { return b.maxx();} - static inline void set(mapnik::box2d &b, ct const& value) { b.set_maxx(value); } -}; - -template <> -struct indexed_access, max_corner, 1> -{ - using ct = coordinate_type::type; - static inline ct get(mapnik::box2d const& b) { return b.maxy();} - static inline void set(mapnik::box2d &b , ct const& value) { b.set_maxy(value); } -}; - -// mapnik::geometry::line_string -template -struct tag > -{ - using type = linestring_tag; -}; - -// mapnik::geometry::polygon ->>>>>>> master:include/mapnik/geometry/boost_adapters.hpp template struct tag > {