diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp index 676c4c970..9917cc40e 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2012-2020 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017-2021. -// Modifications copyright (c) 2017-2021 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2022. +// Modifications copyright (c) 2017-2022 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -37,6 +37,8 @@ #include #include +#include + #include #include @@ -54,11 +56,11 @@ namespace boost { namespace geometry namespace detail { namespace buffer { -template -inline void simplify_input(Range const& range, - DistanceStrategy const& distance, - Range& simplified, - Strategies const& strategies) +template +inline void simplify_input(RangeIn const& range, + DistanceStrategy const& distance, + RangeOut& simplified, + Strategies const& strategies) { // We have to simplify the ring before to avoid very small-scaled // features in the original (convex/concave/convex) being enlarged @@ -524,7 +526,8 @@ struct buffer_inserter_ring RobustPolicy const& robust_policy, Strategies const& strategies) { - RingInput simplified; + using simplified_ring_t = typename helper_geometry::type; + simplified_ring_t simplified; detail::buffer::simplify_input(ring, distance, simplified, strategies); geometry::strategy::buffer::result_code code = geometry::strategy::buffer::result_no_output; @@ -532,12 +535,12 @@ struct buffer_inserter_ring std::size_t n = boost::size(simplified); std::size_t const min_points = core_detail::closure::minimum_ring_size < - geometry::closure::value + geometry::closure::value >::value; if (n >= min_points) { - detail::closed_clockwise_view view(simplified); + detail::closed_clockwise_view view(simplified); if (distance.negative()) { // Walk backwards (rings will be reversed afterwards) @@ -708,7 +711,7 @@ struct buffer_inserter RobustPolicy const& robust_policy, Strategies const& strategies) { - Linestring simplified; + typename helper_geometry::type simplified; detail::buffer::simplify_input(linestring, distance, simplified, strategies); geometry::strategy::buffer::result_code code = geometry::strategy::buffer::result_no_output; diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index cd077a62b..d087e604b 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -627,7 +627,7 @@ struct buffered_piece_collection return; } - if (! input_ring.empty()) + if (! boost::empty(input_ring)) { // Assign the ring to the original_ring collection // For rescaling, it is recalculated. Without rescaling, it @@ -638,8 +638,7 @@ struct buffered_piece_collection using view_type = detail::closed_clockwise_view; view_type const view(input_ring); - for (typename boost::range_iterator::type it = - boost::begin(view); it != boost::end(view); ++it) + for (auto it = boost::begin(view); it != boost::end(view); ++it) { clockwise_ring.push_back(*it); } diff --git a/include/boost/geometry/geometries/helper_geometry.hpp b/include/boost/geometry/geometries/helper_geometry.hpp index 699af88e5..881f143dd 100644 --- a/include/boost/geometry/geometries/helper_geometry.hpp +++ b/include/boost/geometry/geometries/helper_geometry.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015-2020, Oracle and/or its affiliates. +// Copyright (c) 2015-2022, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -12,15 +12,19 @@ #define BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP -#include +#include #include #include +#include +#include #include #include #include #include +#include #include +#include #include @@ -69,23 +73,50 @@ struct helper_geometry : not_implemented template struct helper_geometry { - typedef typename detail::helper_geometries::helper_point + using type = typename detail::helper_geometries::helper_point < Point, NewCoordinateType, NewUnits - >::type type; + >::type; }; template struct helper_geometry { - typedef model::box + using type = model::box < typename helper_geometry < typename point_type::type, NewCoordinateType, NewUnits >::type - > type; + >; +}; + + +template +struct helper_geometry +{ + using type = model::linestring + < + typename helper_geometry + < + typename point_type::type, NewCoordinateType, NewUnits + >::type + >; +}; + +template +struct helper_geometry +{ + using type = model::ring + < + typename helper_geometry + < + typename point_type::type, NewCoordinateType, NewUnits + >::type, + point_order::value != counterclockwise, + closure::value != open + >; }; @@ -103,10 +134,10 @@ template > struct helper_geometry { - typedef typename detail_dispatch::helper_geometry + using type = typename detail_dispatch::helper_geometry < Geometry, NewCoordinateType, NewUnits - >::type type; + >::type; }; diff --git a/test/algorithms/buffer/buffer_polygon.cpp b/test/algorithms/buffer/buffer_polygon.cpp index d132e897a..89a4fb218 100644 --- a/test/algorithms/buffer/buffer_polygon.cpp +++ b/test/algorithms/buffer/buffer_polygon.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2019 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016-2021. -// Modifications copyright (c) 2016-2021, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2022. +// Modifications copyright (c) 2016-2022, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -13,6 +13,9 @@ #include "test_buffer.hpp" +#include +#include + static std::string const simplex = "POLYGON ((0 0,1 5,6 1,0 0))"; @@ -842,6 +845,69 @@ void test_mixed() simplex, join_round, end_flat, 47.4831, 1.5); } + +template +struct triangle_ring +{ + triangle_ring(P const& p0, P const& p1, P const& p2) + : m_arr{p0, p1, p2, p0} + {} + using iterator = P const*; + using const_iterator = P const*; + const_iterator begin() const { return m_arr; } + const_iterator end() const { return m_arr + 4; } +private: + P m_arr[4]; +}; + +template +struct segment_linestring +{ + segment_linestring(P const& p0, P const& p1) + : m_arr{p0, p1} + {} + using iterator = P const*; + using const_iterator = P const*; + const_iterator begin() const { return m_arr; } + const_iterator end() const { return m_arr + 2; } +private: + P m_arr[2]; +}; + +BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(triangle_ring) +BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(segment_linestring) + +void test_different() +{ + using point_t = bg::model::point; + using segment_t = segment_linestring; + using triangle_t = triangle_ring; + using polygon_t = bg::model::polygon; + using mpolygon_t = bg::model::multi_polygon; + + bg::strategy::buffer::distance_symmetric distance_symmetric(1.5); + bg::strategy::buffer::side_straight side_straight; + bg::strategy::buffer::join_round join_round(100); + bg::strategy::buffer::end_flat end_flat; + bg::strategy::buffer::point_circle point_circle(100); + + { + triangle_t in{{0, 0}, {1, 5}, {6, 1}}; + mpolygon_t out; + bg::buffer(in, out, distance_symmetric, side_straight, join_round, end_flat, point_circle); + double a = bg::area(out); + BOOST_CHECK_CLOSE(a, 47.9408, 0.1); + } + + { + segment_t in{{0, 0}, {1, 1}}; + mpolygon_t out; + bg::buffer(in, out, distance_symmetric, side_straight, join_round, end_flat, point_circle); + double a = bg::area(out); + BOOST_CHECK_CLOSE(a, 4.2426, 0.1); + } +} + int test_main(int, char* []) { BoostGeometryWriteTestConfiguration(); @@ -876,5 +942,7 @@ int test_main(int, char* []) BoostGeometryWriteExpectedFailures(2, 1, 9, 1); #endif + test_different(); + return 0; }