mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
[buffer] We have to simplify the ring before to avoid very small-scaled
features in the original (convex/concave/convex) being enlarged in a very large scale and causing issues (IP's within pieces). This might be reconsidered later. Simplifying with a very small distance will never be visible in the result, if it is using round joins. For miter joins they are even more sensitive to small scale input features, however the result will look better. A distance strategy can change behaviour (make larger - set simplify distance to 0.0 to avoid simplification) This fixes the parcel issue(s)
This commit is contained in:
parent
7f3b509fb5
commit
7baf1a29e5
@ -27,6 +27,8 @@
|
||||
#include <boost/geometry/algorithms/detail/buffer/line_line_intersection.hpp>
|
||||
#include <boost/geometry/algorithms/detail/buffer/parallel_continue.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/simplify.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@ -240,6 +242,8 @@ struct buffer_range
|
||||
{
|
||||
robust_point_type robust_input;
|
||||
geometry::recalculate(robust_input, *it, robust_policy);
|
||||
// Check on equality - however, if input is simplified, this is highly
|
||||
// unlikely (though possible by rescaling)
|
||||
if (! detail::equals::equals_point_point(previous_robust_input, robust_input))
|
||||
{
|
||||
output_point_type p1, p2;
|
||||
@ -274,8 +278,6 @@ struct buffer_range
|
||||
previous_robust_input = robust_input;
|
||||
}
|
||||
|
||||
// TODO: take care of degenerate segments
|
||||
|
||||
// Might be replaced by specialization
|
||||
if(boost::is_same<Tag, ring_tag>::value)
|
||||
{
|
||||
@ -512,18 +514,30 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
|
||||
{
|
||||
if (boost::size(ring) > 3)
|
||||
{
|
||||
// We have to simplify the ring before to avoid very small-scaled
|
||||
// features in the original (convex/concave/convex) being enlarged
|
||||
// in a very large scale and causing issues (IP's within pieces).
|
||||
// This might be reconsidered later. Simplifying with a very small
|
||||
// distance (1%% of the buffer) will never be visible in the result,
|
||||
// if it is using round joins. For miter joins they are even more
|
||||
// sensitive to small scale input features, however the result will
|
||||
// look better.
|
||||
// It also get rid of duplicate points
|
||||
RingOutput simplified;
|
||||
geometry::simplify(ring, simplified, distance.simplify_distance());
|
||||
|
||||
if (distance.negative())
|
||||
{
|
||||
// Walk backwards (rings will be reversed afterwards)
|
||||
// It might be that this will be changed later.
|
||||
// TODO: decide this.
|
||||
base::iterate(collection, 0, boost::rbegin(ring), boost::rend(ring),
|
||||
base::iterate(collection, 0, boost::rbegin(simplified), boost::rend(simplified),
|
||||
strategy::buffer::buffer_side_right,
|
||||
distance, join_strategy, end_strategy, robust_policy);
|
||||
}
|
||||
else
|
||||
{
|
||||
base::iterate(collection, 0, boost::begin(ring), boost::end(ring),
|
||||
base::iterate(collection, 0, boost::begin(simplified), boost::end(simplified),
|
||||
strategy::buffer::buffer_side_left,
|
||||
distance, join_strategy, end_strategy, robust_policy);
|
||||
}
|
||||
@ -566,12 +580,15 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
|
||||
{
|
||||
if (boost::size(linestring) > 1)
|
||||
{
|
||||
Linestring simplified;
|
||||
geometry::simplify(linestring, simplified, distance.simplify_distance());
|
||||
|
||||
collection.start_new_ring();
|
||||
base::iterate(collection, 0, boost::begin(linestring), boost::end(linestring),
|
||||
base::iterate(collection, 0, boost::begin(simplified), boost::end(simplified),
|
||||
strategy::buffer::buffer_side_left,
|
||||
distance, join_strategy, end_strategy, robust_policy);
|
||||
|
||||
base::iterate(collection, 1, boost::rbegin(linestring), boost::rend(linestring),
|
||||
base::iterate(collection, 1, boost::rbegin(simplified), boost::rend(simplified),
|
||||
strategy::buffer::buffer_side_right,
|
||||
distance, join_strategy, end_strategy, robust_policy, true);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_DISTANCE_ASYMMETRIC_HPP
|
||||
|
||||
#include <boost/geometry/strategies/buffer.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -47,6 +48,14 @@ public :
|
||||
return m_left < 0 && m_right < 0;
|
||||
}
|
||||
|
||||
inline CoordinateType simplify_distance() const
|
||||
{
|
||||
CoordinateType const left = geometry::math::abs(m_left);
|
||||
CoordinateType const right = geometry::math::abs(m_right);
|
||||
return (left < right ? left : right) / 1000.0;
|
||||
}
|
||||
|
||||
|
||||
private :
|
||||
CoordinateType m_left;
|
||||
CoordinateType m_right;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_DISTANCE_SYMMETRIC_HPP
|
||||
|
||||
#include <boost/geometry/strategies/buffer.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -44,6 +45,12 @@ public :
|
||||
return m_distance < 0;
|
||||
}
|
||||
|
||||
inline CoordinateType simplify_distance() const
|
||||
{
|
||||
return geometry::math::abs(m_distance) / 1000.0;
|
||||
}
|
||||
|
||||
|
||||
private :
|
||||
CoordinateType m_distance;
|
||||
};
|
||||
|
@ -77,6 +77,11 @@ static std::string const parcel2
|
||||
static std::string const parcel3
|
||||
= "POLYGON((120528.56 462115.62,120533.4 462072.1,120533.4 462072.01,120533.39 462071.93,120533.36 462071.86,120533.33 462071.78,120533.28 462071.72,120533.22 462071.66,120533.15 462071.61,120533.08 462071.58,120533 462071.55,120532.92 462071.54,120467.68 462068.66,120468.55 462059.04,120517.39 462062.87,120517.47 462062.87,120517.55 462062.86,120517.62 462062.83,120517.69 462062.79,120517.76 462062.74,120517.81 462062.68,120517.86 462062.62,120517.89 462062.55,120517.92 462062.47,120530.49 461998.63,120530.5 461998.55,120530.49 461998.47,120530.47 461998.39,120530.44 461998.31,120530.4 461998.24,120530.35 461998.18,120530.28 461998.13,120530.21 461998.09,120530.13 461998.06,120482.19 461984.63,120485 461963.14,120528.2 461950.66,120528.28 461950.63,120528.35 461950.59,120528.42 461950.53,120528.47 461950.47,120528.51 461950.4,120528.54 461950.32,120528.56 461950.24,120528.56 461950.15,120528.55 461950.07,120528.53 461949.99,120528.49 461949.92,120528.44 461949.85,120497.49 461915.03,120497.43 461914.98,120497.37 461914.93,120497.3 461914.9,120497.23 461914.88,120497.15 461914.86,120424.61 461910.03,120424.53 461910.03,120424.45 461910.05,120424.37 461910.07,120424.3 461910.11,120424.24 461910.16,120424.18 461910.22,120424.14 461910.29,120424.11 461910.37,120424.09 461910.45,120424.08 461910.53,120424.08 461967.59,120424.08 461967.67,120424.1 461967.75,120424.14 461967.82,120424.18 461967.89,120424.23 461967.95,120424.3 461968,120424.37 461968.04,120424.44 461968.07,120424.52 461968.09,120473.31 461973.83,120469.63 461993.16,120399.48 461986.43,120399.4 461986.43,120399.32 461986.44,120399.25 461986.47,120399.17 461986.5,120399.11 461986.55,120399.05 461986.61,120399.01 461986.67,120398.97 461986.74,120398.95 461986.82,120398.93 461986.9,120394.1 462057.5,120394.1 462057.58,120394.11 462057.66,120394.14 462057.74,120394.18 462057.81,120394.23 462057.87,120394.29 462057.93,120394.35 462057.97,120394.43 462058,120394.5 462058.03,120394.58 462058.03,120458.74 462059.95,120455.16 462072.48,120396.57 462067.68,120396.49 462067.68,120396.4 462067.69,120396.32 462067.72,120396.25 462067.76,120396.18 462067.82,120396.13 462067.88,120396.08 462067.96,120396.05 462068.04,120396.03 462068.12,120392.17 462103.9,120392.16 462103.99,120392.18 462104.07,120392.2 462104.15,120392.24 462104.22,120392.29 462104.29,120392.35 462104.35,120392.42 462104.4,120392.5 462104.43,120392.58 462104.45,120392.66 462104.46,120393.63 462104.46,120393.63 462103.46,120393.22 462103.46,120396.98 462068.71,120455.49 462073.51,120455.57 462073.51,120455.66 462073.49,120455.74 462073.46,120455.81 462073.42,120455.88 462073.37,120455.93 462073.3,120455.98 462073.23,120456.01 462073.15,120459.88 462059.61,120459.89 462059.52,120459.9 462059.44,120459.88 462059.36,120459.86 462059.28,120459.82 462059.21,120459.77 462059.14,120459.72 462059.08,120459.65 462059.04,120459.57 462059,120459.49 462058.98,120459.41 462058.97,120395.13 462057.05,120399.9 461987.48,120469.99 461994.2,120470.07 461994.2,120470.15 461994.19,120470.23 461994.16,120470.3 461994.13,120470.37 461994.08,120470.42 461994.02,120470.47 461993.95,120470.5 461993.88,120470.53 461993.8,120474.4 461973.48,120474.4 461973.4,120474.4 461973.32,120474.38 461973.24,120474.35 461973.16,120474.31 461973.09,120474.25 461973.03,120474.19 461972.98,120474.12 461972.94,120474.04 461972.91,120473.96 461972.9,120425.08 461967.14,120425.08 461911.06,120496.88 461915.85,120527.16 461949.92,120484.4 461962.27,120484.33 461962.3,120484.25 461962.35,120484.19 461962.4,120484.14 461962.46,120484.09 461962.53,120484.06 461962.61,120484.05 461962.69,120481.14 461984.93,120481.14 461985.01,120481.15 461985.09,120481.17 461985.17,120481.2 461985.24,120481.25 461985.31,120481.3 461985.36,120481.36 461985.41,120481.43 461985.45,120481.51 461985.48,120529.42 461998.9,120517.02 462061.84,120468.14 462058,120468.05 462058,120467.97 462058.02,120467.89 462058.05,120467.81 462058.09,120467.75 462058.15,120467.69 462058.22,120467.65 462058.29,120467.62 462058.37,120467.6 462058.46,120466.64 462069.1,120466.63 462069.18,120466.65 462069.26,120466.67 462069.33,120466.71 462069.4,120466.76 462069.47,120466.81 462069.53,120466.88 462069.57,120466.95 462069.61,120467.03 462069.63,120467.11 462069.64,120532.34 462072.52,120527.62 462115.03,120391.73 462106.36,120391.66 462107.36,120528.03 462116.06,120528.12 462116.06,120528.2 462116.04,120528.28 462116.02,120528.35 462115.97,120528.42 462115.92,120528.47 462115.85,120528.51 462115.78,120528.54 462115.7,120528.56 462115.62))";
|
||||
|
||||
static std::string const parcel3_bend // of parcel_3 - clipped
|
||||
= "POLYGON((120399.40000152588 461986.43000030518, 120399.47999954224 461986.43000030518, 120403 461986.76769953477, 120403 461987.777217312, 120399.90000152588 461987.47999954224, 120399.72722010587 461990, 120398.71791817161 461990, 120398.93000030518 461986.90000152588, 120398.95000076294 461986.81999969482, 120398.9700012207 461986.74000167847, 120399.00999832153 461986.66999816895, 120399.04999923706 461986.61000061035, 120399.11000061035 461986.54999923706, 120399.16999816895 461986.5, 120399.25 461986.4700012207, 120399.31999969482 461986.43999862671, 120399.40000152588 461986.43000030518))";
|
||||
|
||||
|
||||
|
||||
template <typename P>
|
||||
void test_all()
|
||||
{
|
||||
@ -266,26 +271,30 @@ void test_all()
|
||||
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel1_10", parcel1, 7571.39121246337891, 10.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel1_10", parcel1, 8207.45314788818359, 10.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel1_20", parcel1, 11648.3068237304688, 20.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel1_20", parcel1, 14173.9223403930664, 20.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel1_30", parcel1, 16350.6157989501953, 30.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel1_30", parcel1, 22023.4705047607422, 30.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel1_20", parcel1, 11648.0537185668945, 20.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel1_20", parcel1, 14184.0223083496094, 20.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel1_30", parcel1, 16350.3611068725586, 30.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel1_30", parcel1, 22046.5098342895508, 30.0);
|
||||
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel2_10", parcel2, 5000.85063171386719, 10.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel2_10", parcel2, 5091.14096832275391, 10.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel2_10", parcel2, 5091.12226867675781, 10.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel2_20", parcel2, 9049.60844421386719, 20.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel2_20", parcel2, 9410.69154357910156, 20.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel2_30", parcel2, 13726.2614288330078, 30.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel2_30", parcel2, 14538.8463592529297, 30.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel2_30", parcel2, 13726.3790588378906, 30.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel2_30", parcel2, 14535.2319564819336, 30.0);
|
||||
|
||||
test_one<polygon_type, buf::join_round, buf::end_flat, polygon_type>("parcel3_10", parcel3, 19992.6824035644531, 10.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel3_10", parcel3, 20024.5579376220703, 10.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel3_20", parcel3, 34505.0746192932129, 20.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel3_20", parcel3, 34633.2606201171875, 20.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel3_30", parcel3, 45261.4196014404297, 30.0);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel3_30", parcel3, 45567.3875694274902, 30.0);
|
||||
|
||||
test_one<polygon_type, buf::join_round, buf::end_flat, polygon_type>("parcel3_bend_10", parcel3_bend, 155.6188, 5.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_flat, polygon_type>("parcel3_bend_10", parcel3_bend, 458.4187, 10.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_flat, polygon_type>("parcel3_bend_10", parcel3_bend, 917.9747, 15.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_flat, polygon_type>("parcel3_bend_10", parcel3_bend, 1534.4795, 20.0);
|
||||
|
||||
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel3_10", parcel3, 99, 10.0);
|
||||
#endif
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel3_10", parcel3, 20022.4271087646484, 10.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel3_20", parcel3, 34504.8032569885254, 20.0, -999, false);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel3_20", parcel3, 34615.6553726196289, 20.0);
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("parcel3_30", parcel3, 45263.0166702270508, 30.0, -999, false);
|
||||
test_one<polygon_type, buf::join_miter, buf::end_skip, polygon_type>("parcel3_30", parcel3, 45506.1910133361816, 30.0);
|
||||
|
||||
// Negative buffers making polygons smaller
|
||||
test_one<polygon_type, buf::join_round, buf::end_skip, polygon_type>("simplex", simplex, 7.04043, -0.5);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/buffer.hpp>
|
||||
#include <boost/geometry/algorithms/correct.hpp>
|
||||
#include <boost/geometry/algorithms/union.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
|
||||
@ -479,6 +480,7 @@ void test_one(std::string const& caseid, std::string const& wkt,
|
||||
namespace bg = boost::geometry;
|
||||
Geometry g;
|
||||
bg::read_wkt(wkt, g);
|
||||
bg::correct(g);
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_CHECK_WITH_POSTGIS
|
||||
|
Loading…
x
Reference in New Issue
Block a user