From abe943c9831f5f5049e5da708bda3cd3d28e08f8 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 11 Apr 2016 14:00:27 -0700 Subject: [PATCH 1/6] revert geometry changes for now - will develop them in branch to reduce downstream breakage --- benchmark/test_polygon_clipping.cpp | 2 +- include/build.py | 1 - .../geometry/boost_geometry_adapters.hpp | 220 ------------------ include/mapnik/geometry/fusion_adapted.hpp | 52 ----- include/mapnik/geometry_centroid.hpp | 2 +- include/mapnik/geometry_correct.hpp | 2 +- include/mapnik/geometry_is_simple.hpp | 2 +- include/mapnik/geometry_is_valid.hpp | 10 +- include/mapnik/geometry_strategy.hpp | 30 +-- include/mapnik/geometry_transform.hpp | 2 +- .../extract_bounding_box_grammar_impl.hpp | 2 +- .../json/geometry_generator_grammar_impl.hpp | 2 +- include/mapnik/json/geometry_grammar_impl.hpp | 2 +- .../mapnik/json/positions_grammar_impl.hpp | 2 +- include/mapnik/json/topojson_grammar_impl.hpp | 2 +- include/mapnik/json/topojson_utils.hpp | 2 +- .../mapnik/wkt/wkt_generator_grammar_impl.hpp | 2 +- include/mapnik/wkt/wkt_grammar_impl.hpp | 2 +- plugins/input/csv/csv_datasource.cpp | 2 +- plugins/input/geojson/geojson_datasource.cpp | 2 +- .../input/topojson/topojson_datasource.cpp | 2 +- test/unit/serialization/wkb_test.cpp | 2 +- 22 files changed, 37 insertions(+), 310 deletions(-) delete mode 100644 include/mapnik/geometry/boost_geometry_adapters.hpp delete mode 100644 include/mapnik/geometry/fusion_adapted.hpp diff --git a/benchmark/test_polygon_clipping.cpp b/benchmark/test_polygon_clipping.cpp index 81d16eeef..b189a0443 100644 --- a/benchmark/test_polygon_clipping.cpp +++ b/benchmark/test_polygon_clipping.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/build.py b/include/build.py index 7b54af7ad..9c225a767 100644 --- a/include/build.py +++ b/include/build.py @@ -38,7 +38,6 @@ subdirs = [ 'text', 'text/placements', 'text/formatting', - 'geometry', 'markers_placements' ] diff --git a/include/mapnik/geometry/boost_geometry_adapters.hpp b/include/mapnik/geometry/boost_geometry_adapters.hpp deleted file mode 100644 index 7a708463a..000000000 --- a/include/mapnik/geometry/boost_geometry_adapters.hpp +++ /dev/null @@ -1,220 +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_ADAPTERS_HPP -#define MAPNIK_GEOMETRY_ADAPTERS_HPP - -#include - -// undef B0 to workaround https://svn.boost.org/trac/boost/ticket/10467 -#pragma GCC diagnostic push -#include -#undef B0 -#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 -#pragma GCC diagnostic pop - -#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_RING_TEMPLATED(mapnik::geometry::linear_ring) -// needed by box2d -BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y) - -namespace boost { - -template -struct range_iterator > -{ - using type = typename mapnik::geometry::line_string::iterator; -}; - -template -struct range_const_iterator > -{ - using type = typename mapnik::geometry::line_string::const_iterator; -}; - -template -inline typename mapnik::geometry::line_string::iterator -range_begin(mapnik::geometry::line_string & line) {return line.begin();} - -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; }; - -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 -template -struct tag > -{ - using type = polygon_tag; -}; - -template -struct point_order > -{ - static const order_selector value = counterclockwise; -}; - -template -struct tag > -{ - using type = multi_point_tag; -}; - -template -struct tag > -{ - using type = multi_linestring_tag; -}; - -template -struct tag > -{ - using type = multi_polygon_tag; -}; - -// ring -template -struct ring_const_type > -{ - using type = typename mapnik::geometry::linear_ring const&; -}; - -template -struct ring_mutable_type > -{ - using type = typename mapnik::geometry::linear_ring&; -}; - -// interior -template -struct interior_const_type > -{ - using type = typename mapnik::geometry::polygon::rings_container const&; -}; - -template -struct interior_mutable_type > -{ - using type = typename mapnik::geometry::polygon::rings_container&; -}; - -// exterior -template -struct exterior_ring > -{ - static mapnik::geometry::linear_ring & get(mapnik::geometry::polygon & p) - { - return p.exterior_ring; - } - - static mapnik::geometry::linear_ring const& get(mapnik::geometry::polygon const& p) - { - return p.exterior_ring; - } -}; - -template -struct interior_rings > -{ - using holes_type = typename mapnik::geometry::polygon::rings_container; - static holes_type& get(mapnik::geometry::polygon & p) - { - return p.interior_rings; - } - - static holes_type const& get(mapnik::geometry::polygon const& p) - { - return p.interior_rings; - } -}; - -}}} - - -#endif //MAPNIK_GEOMETRY_ADAPTERS_HPP diff --git a/include/mapnik/geometry/fusion_adapted.hpp b/include/mapnik/geometry/fusion_adapted.hpp deleted file mode 100644 index e3bdd7ef8..000000000 --- a/include/mapnik/geometry/fusion_adapted.hpp +++ /dev/null @@ -1,52 +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_FUSION_ADAPTED_HPP -#define MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP - -#include -#include - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::geometry::point, - (double, x) - (double, y) -) - -BOOST_FUSION_ADAPT_STRUCT( - mapnik::geometry::point, - (std::int64_t, x) - (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)) - -#endif // MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP diff --git a/include/mapnik/geometry_centroid.hpp b/include/mapnik/geometry_centroid.hpp index dab21f2b9..590ba4898 100644 --- a/include/mapnik/geometry_centroid.hpp +++ b/include/mapnik/geometry_centroid.hpp @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_CENTROID_HPP #include -#include +#include #include #include #include diff --git a/include/mapnik/geometry_correct.hpp b/include/mapnik/geometry_correct.hpp index 5da862394..dc83ad3a2 100644 --- a/include/mapnik/geometry_correct.hpp +++ b/include/mapnik/geometry_correct.hpp @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_CORRECT_HPP #include -#include +#include #include #pragma GCC diagnostic push diff --git a/include/mapnik/geometry_is_simple.hpp b/include/mapnik/geometry_is_simple.hpp index da3cac11c..868b41afd 100644 --- a/include/mapnik/geometry_is_simple.hpp +++ b/include/mapnik/geometry_is_simple.hpp @@ -29,7 +29,7 @@ #if BOOST_VERSION >= 105600 #include -#include +#include #include namespace mapnik { namespace geometry { diff --git a/include/mapnik/geometry_is_valid.hpp b/include/mapnik/geometry_is_valid.hpp index ac58f54b5..95319cce9 100644 --- a/include/mapnik/geometry_is_valid.hpp +++ b/include/mapnik/geometry_is_valid.hpp @@ -29,7 +29,7 @@ #if BOOST_VERSION >= 105800 #include -#include +#include #include #include @@ -102,7 +102,7 @@ struct geometry_is_valid struct geometry_is_valid_reason { using result_type = bool; - + boost::geometry::validity_failure_type & failure_; geometry_is_valid_reason(boost::geometry::validity_failure_type & failure): @@ -170,7 +170,7 @@ struct geometry_is_valid_reason struct geometry_is_valid_string { using result_type = bool; - + std::string & message_; geometry_is_valid_string(std::string & message): @@ -257,7 +257,7 @@ inline bool is_valid(T const& geom, boost::geometry::validity_failure_type & fai } template -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); @@ -270,7 +270,7 @@ inline bool is_valid(T const& geom, std::string & message) } 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); diff --git a/include/mapnik/geometry_strategy.hpp b/include/mapnik/geometry_strategy.hpp index 1ba643a54..cc4121e60 100644 --- a/include/mapnik/geometry_strategy.hpp +++ b/include/mapnik/geometry_strategy.hpp @@ -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_transform.hpp b/include/mapnik/geometry_transform.hpp index ad5a19403..a7bb2f13d 100644 --- a/include/mapnik/geometry_transform.hpp +++ b/include/mapnik/geometry_transform.hpp @@ -24,7 +24,7 @@ #define MAPNIK_GEOMETRY_TRANSFORM_HPP #include -#include +#include #include namespace mapnik { namespace geometry { namespace detail { diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp index d676ee4ee..8a7fc331c 100644 --- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp +++ b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp @@ -22,7 +22,7 @@ // mapnik #include -#include +#include // boost #include #include diff --git a/include/mapnik/json/geometry_generator_grammar_impl.hpp b/include/mapnik/json/geometry_generator_grammar_impl.hpp index d64491e7a..87a60db70 100644 --- a/include/mapnik/json/geometry_generator_grammar_impl.hpp +++ b/include/mapnik/json/geometry_generator_grammar_impl.hpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include // boost #pragma GCC diagnostic push diff --git a/include/mapnik/json/geometry_grammar_impl.hpp b/include/mapnik/json/geometry_grammar_impl.hpp index 46fd6a6d7..3c5693f91 100644 --- a/include/mapnik/json/geometry_grammar_impl.hpp +++ b/include/mapnik/json/geometry_grammar_impl.hpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include // boost #include #include diff --git a/include/mapnik/json/positions_grammar_impl.hpp b/include/mapnik/json/positions_grammar_impl.hpp index d3a85e510..90df172c5 100644 --- a/include/mapnik/json/positions_grammar_impl.hpp +++ b/include/mapnik/json/positions_grammar_impl.hpp @@ -22,7 +22,7 @@ // mapnik #include -#include +#include // boost #include #include diff --git a/include/mapnik/json/topojson_grammar_impl.hpp b/include/mapnik/json/topojson_grammar_impl.hpp index b6cc1d10c..ca8607996 100644 --- a/include/mapnik/json/topojson_grammar_impl.hpp +++ b/include/mapnik/json/topojson_grammar_impl.hpp @@ -33,7 +33,7 @@ BOOST_FUSION_ADAPT_STRUCT( mapnik::topojson::coordinate, (double, x) - (double, y) + (double, y) ) BOOST_FUSION_ADAPT_STRUCT( diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp index bece523f5..c4de30683 100644 --- a/include/mapnik/json/topojson_utils.hpp +++ b/include/mapnik/json/topojson_utils.hpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include namespace mapnik { namespace topojson { diff --git a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp index 6cb015562..8d950edd0 100644 --- a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp @@ -23,7 +23,7 @@ // mapnik #include #include -#include +#include #pragma GCC diagnostic push #include diff --git a/include/mapnik/wkt/wkt_grammar_impl.hpp b/include/mapnik/wkt/wkt_grammar_impl.hpp index a9ac43b1e..d2444130a 100644 --- a/include/mapnik/wkt/wkt_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_grammar_impl.hpp @@ -21,7 +21,7 @@ *****************************************************************************/ #include -#include +#include #pragma GCC diagnostic push #include diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 81be2535d..6c1ff1014 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 8eedf0d9f..e9456f8e1 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/input/topojson/topojson_datasource.cpp b/plugins/input/topojson/topojson_datasource.cpp index 2a7d1d9af..4c4e6b5df 100644 --- a/plugins/input/topojson/topojson_datasource.cpp +++ b/plugins/input/topojson/topojson_datasource.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/test/unit/serialization/wkb_test.cpp b/test/unit/serialization/wkb_test.cpp index 6536068e3..f82c4f32f 100644 --- a/test/unit/serialization/wkb_test.cpp +++ b/test/unit/serialization/wkb_test.cpp @@ -2,7 +2,7 @@ // mapnik #include #include -#include +#include #include #include // bool From 11487e681f50a75e831e2753e9d2a9e6e4d45159 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 11 Apr 2016 16:45:11 -0700 Subject: [PATCH 2/6] amend f8a8ec616a2 by fixing invalid search and replace --- plugins/input/pgraster/pgraster_datasource.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/input/pgraster/pgraster_datasource.cpp b/plugins/input/pgraster/pgraster_datasource.cpp index d846d0087..5c49a43aa 100644 --- a/plugins/input/pgraster/pgraster_datasource.cpp +++ b/plugins/input/pgraster/pgraster_datasource.cpp @@ -274,7 +274,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params) } else { - MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no response from metadata query " << s.str(); + MAPNIK_LOG_DEBUG(pgraster) << "pgraster_datasource: no response from metadata query " << s.str(); } rs->close(); } @@ -291,7 +291,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params) s.str(""); s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM " - << populate_tokens(table_) << " WHERE \"" << geometryColumn_ << "\" IS NOT nullptr LIMIT 1;"; + << populate_tokens(table_) << " WHERE \"" << geometryColumn_ << "\" IS NOT NULL LIMIT 1;"; shared_ptr rs = conn->executeQuery(s.str()); if (rs->next()) From c5d73a03cc3f5a71be9609a09622ff9d887fe6ba Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 11 Apr 2016 16:50:09 -0700 Subject: [PATCH 3/6] pin mason in mason_latest.sh script [skip ci] --- mason_latest.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mason_latest.sh b/mason_latest.sh index 7b3e02a54..d5db6963f 100755 --- a/mason_latest.sh +++ b/mason_latest.sh @@ -1,12 +1,14 @@ #!/usr/bin/env bash -set -eu - MASON_NAME=mapnik MASON_VERSION=latest MASON_LIB_FILE=lib/libmapnik-wkt.a -. ${MASON_DIR:-~/.mason}/mason.sh +# 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) From 15acb2b23f1c9d3d87372490e924f384854a3a09 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 11 Apr 2016 17:58:58 -0700 Subject: [PATCH 4/6] Add missing files after revert --- include/mapnik/geometry_adapters.hpp | 220 +++++++++++++++++++++ include/mapnik/geometry_fusion_adapted.hpp | 52 +++++ 2 files changed, 272 insertions(+) create mode 100644 include/mapnik/geometry_adapters.hpp create mode 100644 include/mapnik/geometry_fusion_adapted.hpp diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp new file mode 100644 index 000000000..7a708463a --- /dev/null +++ b/include/mapnik/geometry_adapters.hpp @@ -0,0 +1,220 @@ +/***************************************************************************** + * + * 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_ADAPTERS_HPP +#define MAPNIK_GEOMETRY_ADAPTERS_HPP + +#include + +// undef B0 to workaround https://svn.boost.org/trac/boost/ticket/10467 +#pragma GCC diagnostic push +#include +#undef B0 +#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 +#pragma GCC diagnostic pop + +#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_RING_TEMPLATED(mapnik::geometry::linear_ring) +// needed by box2d +BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y) + +namespace boost { + +template +struct range_iterator > +{ + using type = typename mapnik::geometry::line_string::iterator; +}; + +template +struct range_const_iterator > +{ + using type = typename mapnik::geometry::line_string::const_iterator; +}; + +template +inline typename mapnik::geometry::line_string::iterator +range_begin(mapnik::geometry::line_string & line) {return line.begin();} + +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; }; + +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 +template +struct tag > +{ + using type = polygon_tag; +}; + +template +struct point_order > +{ + static const order_selector value = counterclockwise; +}; + +template +struct tag > +{ + using type = multi_point_tag; +}; + +template +struct tag > +{ + using type = multi_linestring_tag; +}; + +template +struct tag > +{ + using type = multi_polygon_tag; +}; + +// ring +template +struct ring_const_type > +{ + using type = typename mapnik::geometry::linear_ring const&; +}; + +template +struct ring_mutable_type > +{ + using type = typename mapnik::geometry::linear_ring&; +}; + +// interior +template +struct interior_const_type > +{ + using type = typename mapnik::geometry::polygon::rings_container const&; +}; + +template +struct interior_mutable_type > +{ + using type = typename mapnik::geometry::polygon::rings_container&; +}; + +// exterior +template +struct exterior_ring > +{ + static mapnik::geometry::linear_ring & get(mapnik::geometry::polygon & p) + { + return p.exterior_ring; + } + + static mapnik::geometry::linear_ring const& get(mapnik::geometry::polygon const& p) + { + return p.exterior_ring; + } +}; + +template +struct interior_rings > +{ + using holes_type = typename mapnik::geometry::polygon::rings_container; + static holes_type& get(mapnik::geometry::polygon & p) + { + return p.interior_rings; + } + + static holes_type const& get(mapnik::geometry::polygon const& p) + { + return p.interior_rings; + } +}; + +}}} + + +#endif //MAPNIK_GEOMETRY_ADAPTERS_HPP diff --git a/include/mapnik/geometry_fusion_adapted.hpp b/include/mapnik/geometry_fusion_adapted.hpp new file mode 100644 index 000000000..e3bdd7ef8 --- /dev/null +++ b/include/mapnik/geometry_fusion_adapted.hpp @@ -0,0 +1,52 @@ +/***************************************************************************** + * + * 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_FUSION_ADAPTED_HPP +#define MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP + +#include +#include + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::geometry::point, + (double, x) + (double, y) +) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::geometry::point, + (std::int64_t, x) + (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)) + +#endif // MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP From c8902ac8759d91388bf1bb9fe5ef612951b2a333 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 18 Apr 2016 11:16:32 +0200 Subject: [PATCH 5/6] remove `is_clockwise`, use `mapnik::util::is_clockwise` to avoid duplication --- src/proj_transform.cpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp index 108e3f97c..1bc806188 100644 --- a/src/proj_transform.cpp +++ b/src/proj_transform.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef MAPNIK_USE_PROJ4 // proj4 @@ -370,21 +371,6 @@ void envelope_points(std::vector< coord > & coords, box2d& env } } -// determine if an ordered sequence of coordinates is in clockwise order -bool is_clockwise(const std::vector< coord > & coords) -{ - int n = coords.size(); - coord c1, c2; - double a = 0.0; - - for (int i=0; i calculate_bbox(std::vector > & points) { std::vector >::iterator it = points.begin(); std::vector >::iterator it_end = points.end(); @@ -425,7 +411,7 @@ bool proj_transform::backward(box2d& env, int points) const } box2d result = calculate_bbox(coords); - if (is_source_longlat_ && !is_clockwise(coords)) + if (is_source_longlat_ && !util::is_clockwise(coords)) { // we've gone to a geographic CS, and our clockwise envelope has // changed into an anticlockwise one. This means we've crossed the antimeridian, and @@ -466,7 +452,7 @@ bool proj_transform::forward(box2d& env, int points) const box2d result = calculate_bbox(coords); - if (is_dest_longlat_ && !is_clockwise(coords)) + if (is_dest_longlat_ && !util::is_clockwise(coords)) { // we've gone to a geographic CS, and our clockwise envelope has // changed into an anticlockwise one. This means we've crossed the antimeridian, and From 66160e9754764e0ce3dbb2065071ba883f51ee58 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 18 Apr 2016 16:08:30 +0200 Subject: [PATCH 6/6] mapnik::util::is_clockwise - translate coordinates relative to the origin (0,0) to avoid numeric precision issues while using double precision. (ref #3402) --- include/mapnik/util/is_clockwise.hpp | 11 ++++++++++- test/unit/geometry/is_clockwise.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/unit/geometry/is_clockwise.cpp diff --git a/include/mapnik/util/is_clockwise.hpp b/include/mapnik/util/is_clockwise.hpp index 248372722..1b06dd39e 100644 --- a/include/mapnik/util/is_clockwise.hpp +++ b/include/mapnik/util/is_clockwise.hpp @@ -23,6 +23,8 @@ #ifndef MAPNIK_UTIL_IS_CLOCKWISE_HPP #define MAPNIK_UTIL_IS_CLOCKWISE_HPP +#include + namespace mapnik { namespace util { template @@ -30,11 +32,18 @@ bool is_clockwise(T const& ring) { double area = 0.0; std::size_t num_points = ring.size(); + assert(num_point > 2); + double orig_x = ring[0].x; + double orig_y = ring[0].y; for (std::size_t i = 0; i < num_points; ++i) { auto const& p0 = ring[i]; auto const& p1 = ring[(i + 1) % num_points]; - area += p0.x * p1.y - p0.y * p1.x; + double x0 = p0.x - orig_x; + double y0 = p0.y - orig_y; + double x1 = p1.x - orig_x; + double y1 = p1.y - orig_y; + area += x0 * y1 - x1 * y0; } return (area < 0.0) ? true : false; } diff --git a/test/unit/geometry/is_clockwise.cpp b/test/unit/geometry/is_clockwise.cpp new file mode 100644 index 000000000..42aebf6cf --- /dev/null +++ b/test/unit/geometry/is_clockwise.cpp @@ -0,0 +1,27 @@ +#include "catch.hpp" + +#include +#include + +TEST_CASE("Ring is_clockwise") { + + // Input is rather thin triangle to test precision issues aren't getting in the way. + SECTION("Clockwise") + { + mapnik::geometry::linear_ring ring; + ring.emplace_back(-13499697.0366658326, 4698431.85179749783); + ring.emplace_back(-13499697.1113113686, 4698431.85179749783); + ring.emplace_back(-13499697.0366658326, 4698431.92644303292); + ring.emplace_back(-13499697.0366658326, 4698431.85179749783); + REQUIRE(mapnik::util::is_clockwise(ring) == true); + } + SECTION("Anti-Clockwise") + { + mapnik::geometry::linear_ring ring; + ring.emplace_back(-13499697.0366658326, 4698431.85179749783); + ring.emplace_back(-13499697.0366658326, 4698431.92644303292); + ring.emplace_back(-13499697.1113113686, 4698431.85179749783); + ring.emplace_back(-13499697.0366658326, 4698431.85179749783); + REQUIRE(mapnik::util::is_clockwise(ring) == false); + } +}