diff --git a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp index 2d98ed4e4..3c65c7ddd 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp @@ -259,16 +259,21 @@ struct traversal sbs_type sbs; bool has_subject = false; - bool only_uu = true; + bool only_uu_or_ux = true; for (typename std::set::const_iterator sit = ids.begin(); sit != ids.end(); ++sit) { signed_size_type turn_index = *sit; turn_type const& cturn = m_turns[turn_index]; - if (only_uu && ! cturn.both(operation_union)) + if (only_uu_or_ux) { - only_uu = false; + if (! (cturn.both(operation_union) + || (cturn.has(operation_union) && cturn.has(operation_blocked)))) + { + // not a u-turn and not a ux turn + only_uu_or_ux = false; + } } for (int i = 0; i < 2; i++) { @@ -292,12 +297,13 @@ struct traversal } sbs.apply(turn.point); - if (only_uu) + if (only_uu_or_ux) { sbs.reverse(); } bool result = false; + std::size_t target_main_rank = 1; for (std::size_t i = 0; i < sbs.m_ranked_points.size(); i++) { const typename sbs_type::rp& ranked_point = sbs.m_ranked_points[i]; @@ -309,14 +315,21 @@ struct traversal return false; } - if (ranked_point.main_rank == 1 + if (ranked_point.main_rank == target_main_rank && ranked_point.index == sort_by_side::index_to && ranked_point.operation == operation_blocked) { + if (only_uu_or_ux) + { + // Turns are reversed and ux is allowed, now aim for + // the next main_rank + target_main_rank++; + continue; + } return false; } - if (ranked_point.main_rank == 1 + if (ranked_point.main_rank == target_main_rank && ranked_point.index == sort_by_side::index_to && (ranked_point.operation == OperationType || ranked_point.operation == operation_continue)) @@ -351,7 +364,7 @@ struct traversal result = true; // Don't return yet, maybe there is a blocked } - if (ranked_point.main_rank > 1) + if (ranked_point.main_rank > target_main_rank) { return result; } diff --git a/test/algorithms/overlay/multi_overlay_cases.hpp b/test/algorithms/overlay/multi_overlay_cases.hpp index 691a59241..62c4a3800 100644 --- a/test/algorithms/overlay/multi_overlay_cases.hpp +++ b/test/algorithms/overlay/multi_overlay_cases.hpp @@ -522,11 +522,18 @@ static std::string case_recursive_boxes_17[2] = static std::string case_recursive_boxes_18[2] = { - // Very simple case having two colocated uu turns + // Simple case having two colocated uu turns "MULTIPOLYGON(((2 1,3 0,2 0,2 1)),((2 1,1 1,1 2,2 1)))", "MULTIPOLYGON(((2 2,2 3,3 3,3 2,2 1,2 2)))" }; +static std::string case_recursive_boxes_19[2] = +{ + // Simple case having two colocated uu and ux turns + "MULTIPOLYGON(((1 4,2 3,1 3,1 4)),((1 4,0 4,0 5,1 4)))", + "MULTIPOLYGON(((3 4,1 4,2 5,3 4)),((1 4,1 3,0 3,1 4)))" +}; + static std::string pie_21_7_21_0_3[2] = { "MULTIPOLYGON(((2500 2500,2500 3875,2855 3828,3187 3690,3472 3472,3690 3187,3828 2855,3875 2500,3828 2144,3690 1812,3472 1527,3187 1309,2855 1171,2499 1125,2144 1171,1812 1309,1527 1527,1309 1812,1171 2144,1125 2499,1171 2855,1309 3187,2500 2500)))", diff --git a/test/algorithms/set_operations/intersection/intersection_multi.cpp b/test/algorithms/set_operations/intersection/intersection_multi.cpp index 69397a664..ef66fab86 100644 --- a/test/algorithms/set_operations/intersection/intersection_multi.cpp +++ b/test/algorithms/set_operations/intersection/intersection_multi.cpp @@ -180,6 +180,9 @@ void test_areal() test_one("case_recursive_boxes_18", case_recursive_boxes_18[0], case_recursive_boxes_18[1], 0, 0, 0.0); + test_one("case_recursive_boxes_19", + case_recursive_boxes_19[0], case_recursive_boxes_19[1], + 0, 0, 0.0); test_one("ggl_list_20120915_h2_a", ggl_list_20120915_h2[0], ggl_list_20120915_h2[1], diff --git a/test/algorithms/set_operations/union/union_multi.cpp b/test/algorithms/set_operations/union/union_multi.cpp index d12b9578f..2d48486f9 100644 --- a/test/algorithms/set_operations/union/union_multi.cpp +++ b/test/algorithms/set_operations/union/union_multi.cpp @@ -171,6 +171,9 @@ void test_areal() test_one("case_recursive_boxes_18", case_recursive_boxes_18[0], case_recursive_boxes_18[1], 3, 0, -1, 2.5); + test_one("case_recursive_boxes_19", + case_recursive_boxes_19[0], case_recursive_boxes_19[1], + 3, 0, -1, 2.5); test_one("ggl_list_20120915_h2_a", ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],