diff --git a/.gitmodules b/.gitmodules index 2d66e5fc0..f674d341a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,4 +9,8 @@ [submodule "deps/mapbox/variant"] path = deps/mapbox/variant url = https://github.com/mapbox/variant.git - branch = master \ No newline at end of file + branch = master +[submodule "deps/mapbox/geometry"] + path = deps/mapbox/geometry + url = https://github.com/mapbox/geometry.hpp.git + branch = master diff --git a/SConstruct b/SConstruct index b00dfecba..d640afe15 100644 --- a/SConstruct +++ b/SConstruct @@ -1602,6 +1602,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/benchmark/test_polygon_clipping.cpp b/benchmark/test_polygon_clipping.cpp index d65ec34e2..aed74fe33 100644 --- a/benchmark/test_polygon_clipping.cpp +++ b/benchmark/test_polygon_clipping.cpp @@ -123,12 +123,12 @@ 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)); + poly2.push_back(std::move(ring)); // interior rings ring.clear(); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) @@ -139,12 +139,12 @@ public: } else if (cmd == mapnik::SEG_CLOSE) { - ring.add_coord(x0,y0); - poly2.add_hole(std::move(ring)); + ring.emplace_back(x0,y0); + poly2.push_back(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 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/deps/mapbox/geometry b/deps/mapbox/geometry new file mode 160000 index 000000000..b0d64e6e8 --- /dev/null +++ b/deps/mapbox/geometry @@ -0,0 +1 @@ +Subproject commit b0d64e6e8d55026781325df1068e8043ff880aff 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: diff --git a/include/build.py b/include/build.py index f2e94e5f5..aa122d9a5 100644 --- a/include/build.py +++ b/include/build.py @@ -27,6 +27,7 @@ Import('env') base = './mapnik/' subdirs = [ '', + 'geometry', 'csv', 'svg', 'wkt', diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 4a9ef956c..eb0505a82 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -23,115 +23,28 @@ #ifndef MAPNIK_GEOMETRY_HPP #define MAPNIK_GEOMETRY_HPP +// mapnik +#include +#include +#include +#include +#include +#include +// #include +// stl #include +#include #include #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 == rhs); -} - -template -struct line_string : std::vector > -{ - using coord_type = T; - 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 -{ - using coord_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) {} -}; - -template -using rings_container = std::vector>; - -template class InteriorRings = rings_container> -struct polygon -{ - using coord_type = T; - using rings_container = InteriorRings; - linear_ring exterior_ring; - 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 -{ - using coord_type = T; -}; - -template -struct multi_line_string : std::vector> -{ - using coord_type = T; -}; - -template -struct multi_polygon : std::vector> -{ - using coord_type = T; -}; - -template +template class Cont = std::vector> struct geometry_collection; struct geometry_empty {}; - template using geometry_base = mapnik::util::variant, @@ -144,7 +57,7 @@ using geometry_base = mapnik::util::variant struct geometry : geometry_base { - using coord_type = T; + using coordinate_type = T; #if __cpp_inheriting_constructors >= 200802 @@ -161,10 +74,11 @@ struct geometry : geometry_base #endif }; -template -struct geometry_collection : std::vector> + +template class Cont> +struct geometry_collection : Cont> { - using coord_type = T; + using coordinate_type = T; }; }} diff --git a/include/mapnik/geometry/boost_adapters.hpp b/include/mapnik/geometry/boost_adapters.hpp index dd7e9265a..dd6b9e587 100644 --- a/include/mapnik/geometry/boost_adapters.hpp +++ b/include/mapnik/geometry/boost_adapters.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2016 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,64 +30,79 @@ #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 - +// mapnik #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, float, boost::geometry::cs::cartesian, x, y) +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_LINESTRING_TEMPLATED(mapnik::geometry::line_string) 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) BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2f, float, 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; }; @@ -122,50 +138,6 @@ struct indexed_access, max_corner, 1> static inline void set(mapnik::box2d &b , ct const& value) { b.set_maxy(value); } }; -// 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 template struct tag > { @@ -213,46 +185,69 @@ struct ring_mutable_type > template struct interior_const_type > { - using type = typename mapnik::geometry::polygon::rings_container const&; + using type = typename mapnik::interior_rings const; }; template struct interior_mutable_type > { - using type = typename mapnik::geometry::polygon::rings_container&; + using type = typename mapnik::interior_rings ; }; -// exterior 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) { - return p.exterior_ring; + if (p.empty()) p.resize(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) { - return p.exterior_ring; + if (p.empty()) throw std::runtime_error("Exterior ring must be initialized!"); + return p[0]; } }; template struct interior_rings > { - using holes_type = typename mapnik::geometry::polygon::rings_container; - static holes_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 p.interior_rings; + return mapnik::interior_rings(const_cast&>(p)); } - static holes_type const& get(mapnik::geometry::polygon const& p) + static interior_mutable_type get(mapnik::geometry::polygon& p) { - return p.interior_rings; + return mapnik::interior_rings(p); + } +}; + +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_GEOMETRY_ADAPTERS_HPP +#endif //MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP diff --git a/include/mapnik/geometry/centroid.hpp b/include/mapnik/geometry/centroid.hpp index c7180e6dd..ab8b05ba4 100644 --- a/include/mapnik/geometry/centroid.hpp +++ b/include/mapnik/geometry/centroid.hpp @@ -41,8 +41,8 @@ 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); } @@ -105,17 +105,9 @@ 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)) - { - Geom stripped = mapnik::geometry::remove_empty(geom); - return centroid_simple(stripped); - } -#endif - return centroid_simple(geom); + return centroid_simple(multi_geom); } }; diff --git a/include/mapnik/geometry/correct.hpp b/include/mapnik/geometry/correct.hpp index 16a35c93a..42bdf1826 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 diff --git a/include/mapnik/geometry/envelope.hpp b/include/mapnik/geometry/envelope.hpp index 6bf489c1d..d42d517a7 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 8c030eb77..b6cf47403 100644 --- a/include/mapnik/geometry/envelope_impl.hpp +++ b/include/mapnik/geometry/envelope_impl.hpp @@ -31,11 +31,11 @@ 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; - geometry_envelope(bbox_type & bbox_) + explicit geometry_envelope(bbox_type & bbox_) : bbox(bbox_) {} template @@ -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); - } - } + if (!poly.empty()) _envelope_impl(poly[0], 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,16 +98,35 @@ 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 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/fusion_adapted.hpp b/include/mapnik/geometry/fusion_adapted.hpp index df4e3d87d..3abdb478c 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( @@ -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/geometry_type.hpp b/include/mapnik/geometry/geometry_type.hpp index 12f3627f8..a5a4658a5 100644 --- a/include/mapnik/geometry/geometry_type.hpp +++ b/include/mapnik/geometry/geometry_type.hpp @@ -29,10 +29,10 @@ 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); } @@ -42,43 +42,36 @@ struct geometry_type 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 coordinate_type = typename T::coordinate_type; + return detail::geometry_type()(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/include/mapnik/geometry/line_string.hpp b/include/mapnik/geometry/line_string.hpp new file mode 100644 index 000000000..df6b28fcc --- /dev/null +++ b/include/mapnik/geometry/line_string.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_GEOMETRY_LINE_STRING_HPP +#define MAPNIK_GEOMETRY_LINE_STRING_HPP + +// mapnik +#include + +namespace mapnik { namespace geometry { + +template +using line_string = mapbox::geometry::line_string; +}} + +#endif // MAPNIK_GEOMETRY_LINE_STRING_HPP diff --git a/include/mapnik/geometry/multi_line_string.hpp b/include/mapnik/geometry/multi_line_string.hpp new file mode 100644 index 000000000..7c77229e2 --- /dev/null +++ b/include/mapnik/geometry/multi_line_string.hpp @@ -0,0 +1,36 @@ +/***************************************************************************** + * + * 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 + +// geometry +#include + +namespace mapnik { namespace geometry { + +template +using multi_line_string = mapbox::geometry::multi_line_string; + +}} + +#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..908e7c011 --- /dev/null +++ b/include/mapnik/geometry/multi_point.hpp @@ -0,0 +1,36 @@ +/***************************************************************************** + * + * 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 + +// geometry +#include + +namespace mapnik { namespace geometry { + +template +using multi_point = mapbox::geometry::multi_point; + +}} + +#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..735df3c44 --- /dev/null +++ b/include/mapnik/geometry/multi_polygon.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_GEOMETRY_MULTI_POLYGON_HPP +#define MAPNIK_GEOMETRY_MULTI_POLYGON_HPP + +// geometry +#include + +namespace mapnik { namespace geometry { + +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; +}; + + +}} + +#endif // MAPNIK_GEOMETRY_MULTI_POLYGON_HPP diff --git a/include/mapnik/geometry/point.hpp b/include/mapnik/geometry/point.hpp new file mode 100644 index 000000000..ba1050cb4 --- /dev/null +++ b/include/mapnik/geometry/point.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_GEOMETRY_POINT_HPP +#define MAPNIK_GEOMETRY_POINT_HPP + +#include + +namespace mapnik { namespace geometry { + +template +using point = mapbox::geometry::point; + +}} + +#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..efb65e60f --- /dev/null +++ b/include/mapnik/geometry/polygon.hpp @@ -0,0 +1,39 @@ +/***************************************************************************** + * + * 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 + +// geometry +#include + +namespace mapnik { namespace geometry { + +template +using linear_ring = mapbox::geometry::linear_ring; + +template +using polygon = mapbox::geometry::polygon; + +}} + +#endif // MAPNIK_GEOMETRY_POLYGON_HPP diff --git a/include/mapnik/geometry/remove_empty.hpp b/include/mapnik/geometry/remove_empty.hpp index b2945b6c6..7ae365235 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) diff --git a/include/mapnik/geometry/reprojection_impl.hpp b/include/mapnik/geometry/reprojection_impl.hpp index b08efe388..77f9a9e2e 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) 2016 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 @@ -24,12 +24,9 @@ #include #include -namespace mapnik { - -namespace geometry { - -namespace detail { +namespace mapnik { namespace geometry { namespace detail { +//template geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &) { return geometry_empty(); @@ -62,31 +59,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; } @@ -145,7 +133,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)); } @@ -178,7 +166,7 @@ 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(); } @@ -207,7 +195,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; } @@ -289,6 +277,7 @@ struct geom_reproj_visitor { return mapnik::util::apply_visitor((*this), geom); } + //template bool operator() (geometry_empty &) const { return true; } template @@ -314,12 +303,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) { @@ -332,7 +316,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 @@ -397,5 +385,4 @@ bool reproject(T & geom, projection const& source, projection const& dest) } } // end geometry ns - } // end mapnik ns diff --git a/include/mapnik/geometry/to_path.hpp b/include/mapnik/geometry/to_path.hpp index 51afffd8f..afa432246 100644 --- a/include/mapnik/geometry/to_path.hpp +++ b/include/mapnik/geometry/to_path.hpp @@ -28,13 +28,12 @@ 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); @@ -45,7 +44,6 @@ struct geometry_to_path // 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,34 +65,16 @@ struct geometry_to_path } // polygon - template 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; } @@ -112,7 +91,6 @@ struct geometry_to_path } // multi point - template void operator() (multi_point const& multi_pt) const { for (auto const& pt : multi_pt) @@ -121,7 +99,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 +108,6 @@ struct geometry_to_path } // multi_polygon - template void operator() (multi_polygon const& multi_poly) const { for (auto const& poly : multi_poly) @@ -139,8 +115,7 @@ struct geometry_to_path (*this)(poly); } } - - template + // geometry_collection void operator() (geometry_collection const& collection) const { for (auto const& geom : collection) @@ -157,7 +132,8 @@ struct geometry_to_path template void to_path(T const& geom, path_type & p) { - 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/transform.hpp b/include/mapnik/geometry/transform.hpp index 1a71d070b..11848e019 100644 --- a/include/mapnik/geometry/transform.hpp +++ b/include/mapnik/geometry/transform.hpp @@ -105,7 +105,7 @@ struct geometry_transform geometry operator() (geometry_empty const& empty) const { - return empty; + return geometry_empty(); } template diff --git a/include/mapnik/hit_test_filter.hpp b/include/mapnik/hit_test_filter.hpp index e5a6274f5..11fcb1504 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) @@ -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.num_points(); - 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/create_geometry.hpp b/include/mapnik/json/create_geometry.hpp index 54270a848..eb5569031 100644 --- a/include/mapnik/json/create_geometry.hpp +++ b/include/mapnik/json/create_geometry.hpp @@ -88,22 +88,17 @@ struct create_polygon { mapnik::geometry::polygon poly; std::size_t num_rings = rngs.size(); - if (num_rings > 1) + poly.reserve(num_rings); + for (auto const& r : rngs) { - poly.interior_rings.reserve(num_rings - 1); - } - - for ( std::size_t i = 0; i < num_rings; ++i) - { - 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)); } - 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_); @@ -192,9 +187,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(); @@ -204,8 +197,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/geometry_generator_grammar.hpp b/include/mapnik/json/geometry_generator_grammar.hpp index 802d70974..7d4e9df28 100644 --- a/include/mapnik/json/geometry_generator_grammar.hpp +++ b/include/mapnik/json/geometry_generator_grammar.hpp @@ -75,7 +75,7 @@ template struct geometry_generator_grammar : karma::grammar { - using coord_type = typename Geometry::coord_type; + using coord_type = typename Geometry::coordinate_type; geometry_generator_grammar(); karma::rule geometry; karma::rule()> point; @@ -84,8 +84,7 @@ struct geometry_generator_grammar : karma::rule()> linestring_coord; karma::rule()> polygon; karma::rule()> polygon_coord; - karma::rule()> exterior_ring_coord; - karma::rule >()> interior_ring_coord; + karma::rule()> linear_ring_coord; karma::rule()> multi_point; karma::rule()> multi_point_coord; karma::rule()> multi_linestring; @@ -96,7 +95,6 @@ struct geometry_generator_grammar : 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 b00e2bb21..e9ba6dd91 100644 --- a/include/mapnik/json/geometry_generator_grammar_impl.hpp +++ b/include/mapnik/json/geometry_generator_grammar_impl.hpp @@ -24,7 +24,6 @@ #include #include - namespace mapnik { namespace json { namespace karma = boost::spirit::karma; @@ -80,16 +79,13 @@ geometry_generator_grammar::geometry_generator_grammar linestring_coord = lit('[') << -(point_coord % lit(',')) << lit(']') ; - polygon_coord = lit('[') << exterior_ring_coord << interior_ring_coord << lit(']') + linear_ring_coord = lit('[') << -(point_coord % lit(',')) << lit(']')//linestring_coord.alias() ; - exterior_ring_coord = linestring_coord.alias() + polygon_coord = lit('[') << linear_ring_coord % lit(',') << lit(']') ; - interior_ring_coord = *(lit(",") << exterior_ring_coord) - ; - - 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(']') @@ -98,7 +94,7 @@ geometry_generator_grammar::geometry_generator_grammar multi_polygon_coord = lit('[') << polygon_coord % lit(',') << lit("]") ; - geometries = geometry % lit(',') + geometries = geometry % lit(',') ; } diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp index 72737bb02..0ac888602 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); } } @@ -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) { @@ -524,27 +514,19 @@ 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); } } } } - 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/path.hpp b/include/mapnik/path.hpp index 6d93d66d0..3f713a553 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_strategy.hpp b/include/mapnik/proj_strategy.hpp index 30a798483..6330e233d 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; diff --git a/include/mapnik/proj_transform.hpp b/include/mapnik/proj_transform.hpp index d4827a4b5..28791dd3d 100644 --- a/include/mapnik/proj_transform.hpp +++ b/include/mapnik/proj_transform.hpp @@ -26,13 +26,12 @@ // mapnik #include #include +#include +// stl +#include namespace mapnik { -namespace geometry { -template struct point; -template struct line_string; -} class projection; template class box2d; @@ -50,8 +49,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/svg/geometry_svg_generator.hpp b/include/mapnik/svg/geometry_svg_generator.hpp index 44982b2a9..e06db6f39 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 f970fa5bd..779abd771 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/text/symbolizer_helpers.hpp b/include/mapnik/text/symbolizer_helpers.hpp index b5c3df0ad..222c6f89e 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_wkb.hpp b/include/mapnik/util/geometry_to_wkb.hpp index cbb29963a..bf3a3dd10 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) @@ -288,7 +279,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) diff --git a/include/mapnik/util/spirit_transform_attribute.hpp b/include/mapnik/util/spirit_transform_attribute.hpp index 75877e007..31b80e38c 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/vertex.hpp b/include/mapnik/vertex.hpp index 3190b164b..25c5213e4 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 ff36dec4b..eeee90785 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 coord_type = typename point::coord_type; - + 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_; @@ -45,23 +44,23 @@ struct point_vertex_adapter template struct line_string_vertex_adapter { - using coord_type = typename point::coord_type; + 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_; mutable std::size_t current_index_; - const std::size_t end_index_; + const std::size_t end_index_; }; template struct polygon_vertex_adapter { - using coord_type = typename point::coord_type; + 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_; @@ -75,10 +74,10 @@ private: template struct ring_vertex_adapter { - using coord_type = typename point::coord_type; + 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_processor.hpp b/include/mapnik/vertex_processor.hpp index c9c1c6330..5d30b77da 100644 --- a/include/mapnik/vertex_processor.hpp +++ b/include/mapnik/vertex_processor.hpp @@ -39,6 +39,7 @@ struct vertex_processor { util::apply_visitor(*this, geom); } + void operator() (geometry_empty const&) const { // no-op diff --git a/include/mapnik/vertex_vector.hpp b/include/mapnik/vertex_vector.hpp index f625b68a4..6b397f41f 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/well_known_srs.hpp b/include/mapnik/well_known_srs.hpp index 12e9e86d5..09ed22275 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 { @@ -92,9 +93,9 @@ static inline bool merc2lonlat(double * x, double * y, std::size_t 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; @@ -107,7 +108,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/include/mapnik/wkt/wkt_generator_grammar.hpp b/include/mapnik/wkt/wkt_generator_grammar.hpp index d392bbb36..c8ea23da6 100644 --- a/include/mapnik/wkt/wkt_generator_grammar.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar.hpp @@ -89,28 +89,27 @@ 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()> point; - karma::rule()> point_coord; - karma::rule()> linestring; - karma::rule()> linestring_coord; - karma::rule()> polygon; - karma::rule()> polygon_coord; - karma::rule()> exterior_ring_coord; - karma::rule >()> interior_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::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; + 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 4daa2547a..cdbb4546b 100644 --- a/include/mapnik/wkt/wkt_generator_grammar_impl.hpp +++ b/include/mapnik/wkt/wkt_generator_grammar_impl.hpp @@ -73,19 +73,16 @@ wkt_generator_grammar::wkt_generator_grammar() point_coord = coordinate << lit(' ') << coordinate ; - linestring_coord = lit("(") << point_coord % lit(',') << lit(")") + linestring_coord = lit('(') << point_coord % lit(',') << lit(')') ; - polygon_coord = lit("(") << exterior_ring_coord << interior_ring_coord << lit(")") + linear_ring_coord = lit('(') << point_coord % lit(',') << lit(')');//linestring_coord.alias() ; - exterior_ring_coord = linestring_coord.alias() + polygon_coord = linear_ring_coord % lit(',') ; - interior_ring_coord = *(lit(",") << exterior_ring_coord) - ; - - 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(")") diff --git a/include/mapnik/wkt/wkt_grammar_x3_def.hpp b/include/mapnik/wkt/wkt_grammar_x3_def.hpp index 2b6addcf4..ad1e271ed 100644 --- a/include/mapnik/wkt/wkt_grammar_x3_def.hpp +++ b/include/mapnik/wkt/wkt_grammar_x3_def.hpp @@ -51,14 +51,10 @@ auto make_empty = [](auto const& ctx) _val(ctx) = geometry::geometry_empty(); }; -auto set_exterior = [](auto const& ctx) +auto add_ring = [](auto const& ctx) { - _val(ctx).set_exterior_ring(std::move(_attr(ctx))); -}; - -auto add_hole = [](auto const& ctx) -{ - _val(ctx).add_hole(std::move(_attr(ctx))); + auto & ring = reinterpret_cast &>(_attr(ctx)); + _val(ctx).push_back(std::move(ring)); }; // start rule @@ -84,7 +80,7 @@ x3::rule > const 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(')'); diff --git a/plugins/input/ogr/ogr_converter.cpp b/plugins/input/ogr/ogr_converter.cpp index d3ec5ac2d..91ba612ad 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; } @@ -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 cd4e910ef..cafa04a7d 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)); } @@ -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 42b45cd61..7d0feed40 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/geometry/box2d.cpp b/src/geometry/box2d.cpp index 754a6d4da..07ceda0eb 100644 --- a/src/geometry/box2d.cpp +++ b/src/geometry/box2d.cpp @@ -26,6 +26,7 @@ namespace mapnik { template class box2d; +//template class box2d; template class box2d; template class box2d; diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp index a81612806..c3b5aa098 100644 --- a/src/proj_transform.cpp +++ b/src/proj_transform.cpp @@ -103,7 +103,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; @@ -244,7 +244,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/src/twkb.cpp b/src/twkb.cpp index bcb9dc07a..099a1b098 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 446a61550..3cd1745fc 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_) { @@ -102,22 +102,22 @@ 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 -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_) { @@ -125,8 +125,7 @@ unsigned polygon_vertex_adapter::vertex(coord_type * x, coord_type * y) const } 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(coord_type * x, coord_type * y) const 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; @@ -177,7 +176,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_) { diff --git a/src/wkb.cpp b/src/wkb.cpp index 96f2a0c22..8966afe3b 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -331,11 +331,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; @@ -345,8 +341,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/ds_test_util.hpp b/test/unit/datasource/ds_test_util.hpp index 2a0d2ac90..cbdbe4921 100644 --- a/test/unit/datasource/ds_test_util.hpp +++ b/test/unit/datasource/ds_test_util.hpp @@ -121,48 +121,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); @@ -174,7 +179,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/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp index 6d513bd02..2311c5273 100644 --- a/test/unit/datasource/geojson.cpp +++ b/test/unit/datasource/geojson.cpp @@ -289,10 +289,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)); } @@ -346,8 +345,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 bd13ba9b8..c4b3619ac 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,12 +50,12 @@ 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); - poly.set_exterior_ring(std::move(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)); 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)); } @@ -83,9 +84,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 +105,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 +127,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,23 +151,23 @@ 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); - poly.set_exterior_ring(std::move(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)); } { 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); geom.emplace_back(std::move(poly)); } @@ -178,22 +179,22 @@ SECTION("multi-polygon") { 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); - poly.set_exterior_ring(std::move(ring)); - geom.emplace_back(std::move(poly)); - geom.emplace_back(); - - mapnik::geometry::point centroid; - REQUIRE(mapnik::geometry::centroid(geom, centroid)); - REQUIRE(centroid.x == 0.5); - REQUIRE(centroid.y == 0.5); + 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") { diff --git a/test/unit/geometry/geometry_envelope_test.cpp b/test/unit/geometry/geometry_envelope_test.cpp index 6c3d68048..2b26f91df 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,12 +59,12 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); geometry geom(poly); mapnik::box2d bbox = mapnik::geometry::envelope(geom); REQUIRE( bbox.minx() == -10 ); @@ -102,19 +102,19 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(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); - poly.add_hole(std::move(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.push_back(std::move(hole)); geometry geom(poly); mapnik::box2d bbox = mapnik::geometry::envelope(poly); REQUIRE( bbox.minx() == -10 ); @@ -124,12 +124,12 @@ 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); - poly.add_hole(std::move(fill)); + 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.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 4ff80abab..65c2bfbc7 100644 --- a/test/unit/geometry/geometry_equal.hpp +++ b/test/unit/geometry/geometry_equal.hpp @@ -106,6 +106,7 @@ struct geometry_equal_visitor REQUIRE(false); } + template void operator() (geometry_empty const&, geometry_empty const&) const { REQUIRE(true); @@ -119,7 +120,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()) { @@ -136,25 +137,33 @@ 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>())); + (*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)); + } + 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 { diff --git a/test/unit/geometry/geometry_hit_test.cpp b/test/unit/geometry/geometry_hit_test.cpp index 7208785d1..0f5196a7c 100644 --- a/test/unit/geometry/geometry_hit_test.cpp +++ b/test/unit/geometry/geometry_hit_test.cpp @@ -26,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); @@ -45,12 +45,12 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); geometry geom(poly); REQUIRE( mapnik::hit_test(geom,-5,5,0) ); @@ -77,30 +77,30 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(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); - poly.add_hole(std::move(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.push_back(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); - poly.add_hole(std::move(fill)); + 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.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 061bcd799..cb8421582 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,24 +112,24 @@ 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); - poly.set_exterior_ring(std::move(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)); CHECK( mapnik::geometry::is_simple(poly) ); } 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -138,13 +138,13 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_simple(poly) ); } // repeated points are not considered invalid in a polygon @@ -152,14 +152,14 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_simple(poly) ); } @@ -167,27 +167,28 @@ 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) ); } 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); - poly.set_exterior_ring(std::move(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)); mapnik::geometry::linear_ring ring2; - poly.add_hole(std::move(ring2)); + poly.push_back(std::move(ring2)); CHECK( !mapnik::geometry::is_simple(poly) ); } @@ -201,21 +202,21 @@ 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) ); } 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); - poly.set_exterior_ring(std::move(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)); mapnik::geometry::linear_ring ring2; - poly.add_hole(std::move(ring2)); + poly.push_back(std::move(ring2)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -225,33 +226,33 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); CHECK( mapnik::geometry::is_simple(poly) ); } 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(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); - poly.add_hole(std::move(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.push_back(std::move(hole)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -259,19 +260,19 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(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); - poly.add_hole(std::move(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.push_back(std::move(hole)); CHECK( mapnik::geometry::is_simple(poly) ); } @@ -279,20 +280,21 @@ 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); - poly.set_exterior_ring(std::move(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)); 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); - poly2.set_exterior_ring(std::move(ring2)); + 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.push_back(std::move(ring2)); mp.emplace_back(poly); mp.emplace_back(poly2); CHECK( mapnik::geometry::is_simple(mp) ); @@ -302,34 +304,34 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(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); - poly.add_hole(std::move(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.push_back(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); - poly2.set_exterior_ring(std::move(ring2)); + 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.push_back(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); - poly2.add_hole(std::move(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.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 aa5f1ecaf..734cf5a3c 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,12 +219,12 @@ 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); - poly.set_exterior_ring(std::move(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)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; CHECK( mapnik::geometry::is_valid(poly, message) ); @@ -237,12 +237,12 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; CHECK( !mapnik::geometry::is_valid(poly, message) ); @@ -256,13 +256,13 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; CHECK( mapnik::geometry::is_valid(poly, message) ); @@ -275,14 +275,14 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.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) ); @@ -306,14 +307,14 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(std::move(ring)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; CHECK( !mapnik::geometry::is_valid(poly, message) ); @@ -326,19 +327,19 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(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); - poly.add_hole(std::move(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.push_back(std::move(hole)); CHECK( mapnik::geometry::is_valid(poly) ); std::string message; CHECK( mapnik::geometry::is_valid(poly, message) ); @@ -351,14 +352,14 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.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) ); @@ -372,19 +373,19 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(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); - poly.add_hole(std::move(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.push_back(std::move(hole)); CHECK( !mapnik::geometry::is_valid(poly) ); std::string message; CHECK( !mapnik::geometry::is_valid(poly, message) ); @@ -398,20 +399,20 @@ 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); - poly.set_exterior_ring(std::move(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)); 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); - poly2.set_exterior_ring(std::move(ring2)); + 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.push_back(std::move(ring2)); mp.emplace_back(poly); mp.emplace_back(poly2); CHECK( mapnik::geometry::is_valid(mp) ); @@ -427,34 +428,34 @@ 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); - poly.set_exterior_ring(std::move(ring)); + 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.push_back(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); - poly.add_hole(std::move(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.push_back(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); - poly2.set_exterior_ring(std::move(ring2)); + 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.push_back(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); - poly2.add_hole(std::move(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.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 764a190f2..cf64a41e8 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 c79a5e2d9..d052f9edf 100644 --- a/test/unit/geometry/geometry_strategy_test.cpp +++ b/test/unit/geometry/geometry_strategy_test.cpp @@ -10,8 +10,8 @@ #include #include -TEST_CASE("geometry strategy tests") { +TEST_CASE("geometry strategy tests") { SECTION("proj and view strategy") { using namespace mapnik::geometry; mapnik::box2d e(-20037508.342789,-20037508.342789,20037508.342789,20037508.342789); @@ -183,5 +183,4 @@ SECTION("scaling strategies - double to int64") { assert_g_equal(r, o); } } // END SECTION - } // END TEST CASE diff --git a/test/unit/geometry/has_empty.cpp b/test/unit/geometry/has_empty.cpp deleted file mode 100644 index 671ffdea2..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.add_coord(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.add_coord(0, 0); - line.add_coord(25, 25); - line.add_coord(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.set_exterior_ring(std::move(ring)); - REQUIRE(!mapnik::geometry::has_empty(poly)); - } - { - 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); - poly.set_exterior_ring(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.add_coord(0, 0); - geom.add_coord(25, 25); - geom.add_coord(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.add_coord(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.set_exterior_ring(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.add_coord(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 28b290b39..6f6ed2ed2 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)); } } @@ -54,18 +54,18 @@ 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::is_empty(poly)); } { 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); - poly.set_exterior_ring(std::move(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::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)); } } @@ -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 c160182a6..b51d0c8e2 100644 --- a/test/unit/geometry/remove_empty.cpp +++ b/test/unit/geometry/remove_empty.cpp @@ -18,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(); @@ -36,18 +36,18 @@ 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); - poly.set_exterior_ring(std::move(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(); //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 487f6bbd9..6fe6dda44 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.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.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,27 +47,28 @@ 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.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.add_coord(-7,7); - hole.add_coord(-7,3); - hole.add_coord(-3,3); - hole.add_coord(-3,7); - hole.add_coord(-7,7); - g.add_hole(std::move(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); + g.push_back(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); - g.add_hole(std::move(hole_in_hole)); + 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.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 );