Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/issue 893 and 1299 #1347

Merged
merged 2 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/release_notes.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
* [@https://github.com/boostorg/geometry/issues/1309 1309] Fix some missing qbk includes
* [@https://github.com/boostorg/geometry/issues/1226 1226] [@https://github.com/boostorg/geometry/issues/1326 1326] Fix extra round on ring
* [@https://github.com/boostorg/geometry/issues/1293 1293] [@https://github.com/boostorg/geometry/issues/1294 1294] [@https://github.com/boostorg/geometry/issues/1295 1295] Fix traversal through non clustered rings
* [@https://github.com/boostorg/geometry/issues/893 893] [@https://github.com/boostorg/geometry/issues/1299 1299] Fix blocking rings for non union conditions
* [@https://github.com/boostorg/geometry/issues/1342 1342] Fix discarding a start turn for combination with touch

[/=================]
Expand Down
33 changes: 19 additions & 14 deletions include/boost/geometry/algorithms/detail/overlay/overlay.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,38 +102,42 @@ inline void get_ring_turn_info(TurnInfoMap& turn_info_map, Turns const& turns, C
= target_operation == operation_union
? operation_intersection
: operation_union;
static const bool is_union = target_operation == operation_union;

for (auto const& turn : turns)
{
bool cluster_checked = false;
bool has_blocked = false;

if (is_self_turn<OverlayType>(turn) && turn.discarded)
if (turn.discarded && (turn.method == method_start || is_self_turn<OverlayType>(turn)))
{
// Discarded self-turns don't count as traversed
// Discarded self-turns or start turns don't need to block the ring
continue;
}

for (auto const& op : turn.operations)
for (int i = 0; i < 2; i++)
{
auto const& op = turn.operations[i];
auto const& other_op = turn.operations[1 - i];
ring_identifier const ring_id = ring_id_by_seg_id(op.seg_id);

if (! is_self_turn<OverlayType>(turn)
&& (
(BOOST_GEOMETRY_CONDITION(target_operation == operation_union)
&& op.enriched.count_left > 0)
|| (BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection)
&& op.enriched.count_right <= 2)))
vissarion marked this conversation as resolved.
Show resolved Hide resolved
// If the turn (one of its operations) is used during traversal,
// and it is an intersection or difference, it cannot be set to blocked.
// This is a rare case, related to floating point precision,
// and can happen if there is, for example, only one start turn which is
// used to traverse through one of the rings (the other should be marked
// as not traversed, but neither blocked).
bool const can_block
= is_union
vissarion marked this conversation as resolved.
Show resolved Hide resolved
|| ! (op.visited.finalized() || other_op.visited.finalized());

if (! is_self_turn<OverlayType>(turn) && can_block)
{
// Avoid including untraversed rings which have polygons on
// their left side (union) or not two on their right side (int)
// This can only be done for non-self-turns because of count
// information
turn_info_map[ring_id].has_blocked_turn = true;
continue;
}

if (turn.any_blocked())
if (is_union && turn.any_blocked())
{
turn_info_map[ring_id].has_blocked_turn = true;
}
Expand All @@ -157,6 +161,7 @@ inline void get_ring_turn_info(TurnInfoMap& turn_info_map, Turns const& turns, C
// don't block (for union) i/u if there is an self-ii too
if (has_blocked
|| (op.operation == opposite_operation
&& can_block
&& ! turn.has_colocated_both
&& ! (turn.both(opposite_operation)
&& is_self_turn<OverlayType>(turn))))
Expand Down
6 changes: 6 additions & 0 deletions test/algorithms/overlay/multi_overlay_cases.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,12 @@ static std::string bug_21155501[2] =
"MULTIPOLYGON(((4.9658203125 18.729501999072138,-3.4868710311820115 24.246968623627644,8.3589904332912 33.833614418115445,8.3056640625 32.99023555965106,9.8876953125 31.728167146023935,9.7119140625 25.48295117535531,11.8212890625 23.563987128451217,4.9658203125 18.729501999072138)),((-3.88714525609152 24.508246314579743,-8.3935546875 27.449790329784214,-8.9208984375 29.458731185355344,-0.5712890625 32.02670629333614,-1.8896484375 35.60371874069731,8.5693359375 37.16031654673677,8.362166569827938 33.883846345901595,-3.88714525609152 24.508246314579743)))",
};

static std::string issue_1299[2] =
{
"MULTIPOLYGON(((1.2549999979079400 0.85000000411847698, -1.2550000020920500 0.84999999897038103, -1.2549999999999999 -0.85000000102961903, 1.2549999999999999 -0.84999999999999998)))",
"MULTIPOLYGON(((-0.87500000000000000 -0.84999999999999998, -0.87500000000000000 -0.070000000000000201, -1.2549999999999999 -0.070000000000000201, -1.2549999999999999 -0.84999999999999998)))"
};
vissarion marked this conversation as resolved.
Show resolved Hide resolved

static std::string mysql_21965285_b[2] =
{
"MULTIPOLYGON(((3 0, -19 -19, -7 3, -2 10, 15 0, 3 0)))",
Expand Down
6 changes: 6 additions & 0 deletions test/algorithms/overlay/overlay_cases.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,12 @@ static std::string issue_876b[2] =
"POLYGON((-71.6230763305201634 -132.587678014412745,-106.959839171856814 -102.936613347248112,-40.4477408440520776 -23.6705812141075285,-5.11097800271543878 -53.3216458812721612,-71.6230763305201634 -132.587678014412745))"
};

static std::string issue_893[2] =
{
"POLYGON((-9133.3885344331684 3976.3162451998137, -6748.2449169873034 -5735.0734557728138, 12359.886942916415 -1042.0645095456412, 5126.3084924076147 2226.9708710750697, -1604.5619839035633 573.85084904357439, -9133.3885344331684 3976.3162451998137))",
"POLYGON((-3228.4265340177531 1307.7159344890201, -4500.2645033380131 1882.4913860267370, -4294.7752070657516 1045.8178117890784, -3228.4265340177531 1307.7159344890201))"
};

static std::string issue_1076[2] =
{
"POLYGON((981.792858339935151 98, 927.152135631899114 0, 970 98, 981.792858339935151 98))",
Expand Down
8 changes: 8 additions & 0 deletions test/algorithms/set_operations/difference/difference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,14 @@ void test_all()
TEST_DIFFERENCE(issue_876a, 1, 4728.89916, 1, 786.29563, 2);
TEST_DIFFERENCE(issue_876b, 1, 6114.18234, 1, 4754.29449, count_set(1, 2));

{
// Results are still invalid
ut_settings settings;
settings.set_test_validity(false);
settings.validity_of_sym = false;
TEST_DIFFERENCE_WITH(issue_893, 1, 97213916.0, 0, 0.0, 1, settings);
}

TEST_DIFFERENCE(issue_1138, 1, 203161.751, 2, 1237551.0171, 1);

{
Expand Down
16 changes: 3 additions & 13 deletions test/algorithms/set_operations/difference/difference_multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,7 @@ void test_areal()
TEST_DIFFERENCE_WITH(0, 1, ggl_list_20120221_volker, 2, 7962.66, 2, 2775258.93, 4);
}

{
// 1: Very small sliver for B (discarded when rescaling)
// 2: sym difference is not considered as valid (without rescaling
// this is a false negative)
// 3: with rescaling A is considered as invalid (robustness problem)
ut_settings settings;
settings.validity_of_sym = true;
settings.validity_false_negative_sym = true;
TEST_DIFFERENCE_WITH(0, 1, bug_21155501,
(count_set(1, 4)), expectation_limits(3.75893, 3.75894),
(count_set(1, 4)), (expectation_limits(1.776357e-15, 7.661281e-15)),
(count_set(2, 5)));
}
TEST_DIFFERENCE(bug_21155501, 1, 3.758937, 1, 1.78e-15, 1);
vissarion marked this conversation as resolved.
Show resolved Hide resolved

#if defined(BOOST_GEOMETRY_TEST_FAILURES)
{
Expand Down Expand Up @@ -400,6 +388,8 @@ void test_areal()
TEST_DIFFERENCE(mysql_regression_1_65_2017_08_31,
optional(), optional_sliver(1e-6),
3, 152.064185, count_set(3, 4));

TEST_DIFFERENCE(issue_1299, 1, 3.9706, 0, 0, 1);
}


Expand Down
2 changes: 2 additions & 0 deletions test/algorithms/set_operations/intersection/intersection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ void test_areal()

TEST_INTERSECTION(issue_861, 1, -1, 1.4715007684573677693e-10);

TEST_INTERSECTION(issue_893, 1, -1, 473001.5082956461);

TEST_INTERSECTION(issue_1226, 1, -1, 0.00036722862);
TEST_INTERSECTION(issue_1229, 0, -1, 0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ void test_areal()
TEST_INTERSECTION(mysql_23023665_7, 2, 11, 9.80505786783);
TEST_INTERSECTION(mysql_23023665_12, 2, 0, 11.812440191387557);
TEST_INTERSECTION(mysql_regression_1_65_2017_08_31, 2, -1, 29.9022122);

TEST_INTERSECTION(issue_1299, 1, -1, 0.2964);
}

template <typename Polygon, typename MultiPolygon, typename Box>
Expand Down
3 changes: 3 additions & 0 deletions test/algorithms/set_operations/union/union.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,9 @@ void test_areal()
TEST_UNION(issue_838, 1, 0, -1, expectation_limits(1.3333, 1.33785));
TEST_UNION_REV(issue_838, 1, 0, -1, expectation_limits(1.3333, 1.33785));

TEST_UNION(issue_893, 1, 0, -1, 97686917.29298662);
TEST_UNION_REV(issue_893, 1, 0, -1, 97686917.29298662);

TEST_UNION(issue_1076, 1, 0, -1, 1225.0);
TEST_UNION_REV(issue_1076, 1, 0, -1, 1225.0);

Expand Down
2 changes: 2 additions & 0 deletions test/algorithms/set_operations/union/union_multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,8 @@ void test_areal()
1, 9, -1, 1250.0);

TEST_UNION(mysql_regression_1_65_2017_08_31, 3, 0, -1, 181.966397646608);

TEST_UNION(issue_1299, 1, 0, -1, 4.267);
}

// Test cases (generic)
Expand Down
Loading