diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp index 7a901c869..1e2e6e33c 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp @@ -345,6 +345,26 @@ struct visit_pieces_default_policy {} }; +template +< + typename OutputPointType, + typename Point, + typename Collection, + typename DistanceStrategy, + typename PointStrategy +> +inline void buffer_point(Point const& point, Collection& collection, + DistanceStrategy const& distance_strategy, + PointStrategy const& point_strategy) +{ + collection.start_new_ring(); + std::vector range_out; + point_strategy.apply(point, distance_strategy, range_out); + collection.add_piece(strategy::buffer::buffered_point, range_out, false); + collection.finish_ring(); +} + + }} // namespace detail::buffer #endif // DOXYGEN_NO_DETAIL @@ -389,13 +409,10 @@ struct buffer_inserter PointStrategy const& point_strategy, RobustPolicy const& ) { - typedef typename point_type::type output_point_type; - - collection.start_new_ring(); - std::vector range_out; - point_strategy.apply(point, distance_strategy, range_out); - collection.add_piece(strategy::buffer::buffered_point, range_out, false); - collection.finish_ring(); + detail::buffer::buffer_point + < + typename point_type::type + >(point, collection, distance_strategy, point_strategy); } }; @@ -577,10 +594,11 @@ struct buffer_inserter SideStrategy const& side_strategy, JoinStrategy const& join_strategy, EndStrategy const& end_strategy, - PointStrategy const& , + PointStrategy const& point_strategy, RobustPolicy const& robust_policy) { - if (boost::size(linestring) > 1) + std::size_t n = boost::size(linestring); + if (n > 1) { Linestring simplified; detail::buffer::simplify_input(linestring, distance, simplified); @@ -598,9 +616,14 @@ struct buffer_inserter first_p1); collection.finish_ring(); } - else + else if (n == 1) { // Use point_strategy to buffer degenerated linestring + detail::buffer::buffer_point + ( + geometry::range::front(linestring), + collection, distance, point_strategy + ); } } }; diff --git a/test/algorithms/buffer/linestring_buffer.cpp b/test/algorithms/buffer/linestring_buffer.cpp index bdca6e3d0..8329d961f 100644 --- a/test/algorithms/buffer/linestring_buffer.cpp +++ b/test/algorithms/buffer/linestring_buffer.cpp @@ -27,6 +27,10 @@ static std::string const overlapping = "LINESTRING(0 0,4 5,7 4,10 6, 10 2,2 2)"; static std::string const curve = "LINESTRING(2 7,3 5,5 4,7 5,8 7)"; static std::string const tripod = "LINESTRING(5 0,5 5,1 8,5 5,9 8)"; // with spike +static std::string const degenerate1 = "LINESTRING(5 5)"; +static std::string const degenerate2 = "LINESTRING(5 5,5 5)"; +static std::string const degenerate3 = "LINESTRING(5 5,5 5,5 5)"; + static std::string const for_collinear = "LINESTRING(2 0,0 0,0 4,6 4,6 0,4 0)"; static std::string const for_collinear2 = "LINESTRING(2 1,2 0,0 0,0 4,6 4,6 0,4 0,4 1)"; @@ -133,6 +137,16 @@ void test_all() test_one("field_sprayer1", field_sprayer1, join_round, end_round, 718.761877, 16.5, 6.5); test_one("field_sprayer1", field_sprayer1, join_miter, end_round, 718.939628, 16.5, 6.5); + test_one("degenerate1", degenerate1, join_round, end_round, 28.25, 3.0); +#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS) + test_one("degenerate2", degenerate2, join_miter, end_flat, 99.99, 3.0); + test_one("degenerate2", degenerate2, join_round, end_round, 99.99, 3.0); + test_one("degenerate3", degenerate3, join_miter, end_flat, 99.99, 3.0); + test_one("degenerate3", degenerate3, join_round, end_round, 99.99, 3.0); +#endif + + + double tolerance = 1.0e-10; test_one("aimes120", aimes120, join_miter, end_flat, 1.62669948622351512e-08, 0.000018, 0.000018, false, tolerance); diff --git a/test/algorithms/buffer/multi_linestring_buffer.cpp b/test/algorithms/buffer/multi_linestring_buffer.cpp index 6174e3c8e..8d1481c47 100644 --- a/test/algorithms/buffer/multi_linestring_buffer.cpp +++ b/test/algorithms/buffer/multi_linestring_buffer.cpp @@ -15,6 +15,11 @@ static std::string const simplex = "MULTILINESTRING((0 0,4 5),(5 4,10 0))"; static std::string const two_bends = "MULTILINESTRING((0 0,4 5,7 4,10 6),(1 5,5 9,8 6))"; static std::string const turn_inside = "MULTILINESTRING((0 0,4 5,7 4,10 6),(1 5,5 9,8 6),(0 4,-2 6))"; +static std::string const degenerate0 = "MULTILINESTRING()"; +static std::string const degenerate1 = "MULTILINESTRING((5 5))"; +static std::string const degenerate2 = "MULTILINESTRING((5 5),(9 9))"; +static std::string const degenerate3 = "MULTILINESTRING((5 5),(9 9),(4 10))"; + template void test_all() @@ -49,6 +54,11 @@ void test_all() test_one("two_bends", two_bends, join_round_by_divide, end_flat, 64.6217, 1.5, 1.5); test_one("two_bends", two_bends, join_miter, end_flat, 65.1834, 1.5, 1.5); test_one("two_bends", two_bends, join_miter, end_round, 75.2917, 1.5, 1.5); + + test_one("degenerate0", degenerate0, join_round, end_round, 0.0, 3.0, 3.0); + test_one("degenerate1", degenerate1, join_round, end_round, 28.2503, 3.0, 3.0); + test_one("degenerate2", degenerate2, join_round, end_round, 56.0457, 3.0, 3.0); + test_one("degenerate3", degenerate3, join_round, end_round, 80.4531, 3.0, 3.0); }