diff --git a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp index adf9b5f49..9d1668b95 100644 --- a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp @@ -314,7 +314,7 @@ inline void enrich_intersection_points(Turns& turns, ++mit) { detail::overlay::discard_lonely_uu_turns(mit->second, turns, - mapped_vector, colocated_cc_map); + mapped_vector, clusters, colocated_cc_map); } } diff --git a/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp b/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp index 940ca0b52..5b68b57de 100644 --- a/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp @@ -607,10 +607,12 @@ template typename Operations, typename Turns, typename Map, + typename Clusters, typename ColocatedCcMap > inline void discard_lonely_uu_turns(Operations& operations, Turns& turns, - Map& map, ColocatedCcMap const& colocated_cc_map) + Map& map, Clusters& clusters, + ColocatedCcMap const& colocated_cc_map) { typedef typename boost::range_value::type turn_type; typedef typename turn_type::turn_operation_type op_type; @@ -646,6 +648,16 @@ inline void discard_lonely_uu_turns(Operations& operations, Turns& turns, // should be discarded, otherwise it will be traveled twice turn.discarded = true; + if (turn.cluster_id >= 0) + { + // Remove from cluster + typename Clusters::iterator it = clusters.find(turn.cluster_id); + if (it != clusters.end()) + { + it->second.erase(turn_index); + } + turn.cluster_id = -1; + } operations.clear(); // Remove the turn from all other mapped items too diff --git a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp index ce1e9f6dc..e30d7f97c 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp @@ -268,6 +268,11 @@ struct traversal { signed_size_type turn_index = *sit; turn_type const& cturn = m_turns[turn_index]; + if (cturn.discarded) + { + // Defensive check, discarded turns should not be in cluster + continue; + } if (OperationType == operation_union && cturn.both(operation_union)) { diff --git a/test/algorithms/overlay/multi_overlay_cases.hpp b/test/algorithms/overlay/multi_overlay_cases.hpp index 9e54b4bf1..cbcf17d5b 100644 --- a/test/algorithms/overlay/multi_overlay_cases.hpp +++ b/test/algorithms/overlay/multi_overlay_cases.hpp @@ -585,6 +585,13 @@ static std::string case_recursive_boxes_26[2] = "MULTIPOLYGON(((2 3,0 3,0 4,1 4,1 5,3 5,3 4,2 4,2 3)),((2 3,3 2,2 2,2 3)))" }; +static std::string case_recursive_boxes_27[2] = +{ + // Combination of lonely uu-turn (which is discarded) and a cluster containing it + "MULTIPOLYGON(((2 2,3 1,3 0,2 0,2 2)),((2 2,1 2,1 3,2 2)))", + "MULTIPOLYGON(((1 2,0 1,0 2,1 2)),((2 1,2 0,1 0,1 1,2 2,2 1)),((1 3,2 2,1 2,1 3)),((1 3,0 3,1 4,1 3)))" +}; + 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 5d4cf1b07..44a7f0187 100644 --- a/test/algorithms/set_operations/intersection/intersection_multi.cpp +++ b/test/algorithms/set_operations/intersection/intersection_multi.cpp @@ -204,6 +204,9 @@ void test_areal() test_one("case_recursive_boxes_26", case_recursive_boxes_26[0], case_recursive_boxes_26[1], 1, 0, 2.5); + test_one("case_recursive_boxes_27", + case_recursive_boxes_27[0], case_recursive_boxes_27[1], + 1, 0, 0.5); 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 45daf44d6..bfb6ab2e9 100644 --- a/test/algorithms/set_operations/union/union_multi.cpp +++ b/test/algorithms/set_operations/union/union_multi.cpp @@ -195,6 +195,9 @@ void test_areal() test_one("case_recursive_boxes_26", case_recursive_boxes_26[0], case_recursive_boxes_26[1], 3, 0, -1, 6.0); + test_one("case_recursive_boxes_27", + case_recursive_boxes_27[0], case_recursive_boxes_27[1], + 4, 0, -1, 4.5); test_one("ggl_list_20120915_h2_a", ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],