diff --git a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp index bcfdb363c..c159e34de 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp @@ -246,6 +246,14 @@ struct traversal turn_type const& turn = m_turns[turn_index]; BOOST_ASSERT(turn.cluster_id >= 0); +#ifdef BOOST_GEOMETRY_DEBUG_TRAVERSE_BUFFER + std::cout << "Select Cluster " + << turn.cluster_id + << " from " << turn_index + << "[" << op_index << "]" + << std::boolalpha << std::endl; +#endif + typename Clusters::const_iterator mit = m_clusters.find(turn.cluster_id); BOOST_ASSERT(mit != m_clusters.end()); @@ -254,9 +262,6 @@ struct traversal sbs_type sbs; sbs.set_origin(point); - bool has_uu = false; - bool has_operation = false; - for (typename std::set::const_iterator sit = ids.begin(); sit != ids.end(); ++sit) { @@ -268,16 +273,6 @@ struct traversal continue; } - if (cluster_turn.both(operation_union)) - { - has_uu = true; - } - - if (cluster_turn.has(OperationType)) - { - has_operation = true; - } - for (int i = 0; i < 2; i++) { sbs.add(cluster_turn.operations[i], cluster_turn_index, i, @@ -286,7 +281,33 @@ struct traversal } sbs.apply(turn.point); - if (has_uu && is_union) + int open_count = 0; + if (is_union) + { + // Check how many open spaces there are. + // TODO: might be moved to sbs itself, though it also uses turns + + std::size_t last_rank = 0; + for (std::size_t i = 0; i < sbs.m_ranked_points.size(); i++) + { + typename sbs_type::rp const& ranked_point = sbs.m_ranked_points[i]; + + if (ranked_point.main_rank > last_rank + && ranked_point.index == sort_by_side::index_to) + { + turn_type const& ranked_turn = m_turns[ranked_point.turn_index]; + turn_operation_type const& ranked_op = ranked_turn.operations[ranked_point.op_index]; + if (ranked_op.enriched.count_left == 0 + && ranked_op.enriched.count_right > 0) + { + open_count++; + last_rank = ranked_point.main_rank; + } + } + } + } + + if (open_count > 1) { sbs.reverse(); diff --git a/test/algorithms/set_operations/union/union_multi.cpp b/test/algorithms/set_operations/union/union_multi.cpp index 5635306d3..52f31ec5d 100644 --- a/test/algorithms/set_operations/union/union_multi.cpp +++ b/test/algorithms/set_operations/union/union_multi.cpp @@ -155,19 +155,19 @@ void test_areal() 6, 0, -1, 6.0); test_one("case_recursive_boxes_13", case_recursive_boxes_13[0], case_recursive_boxes_13[1], - 2, 0, -1, 10.25); + 3, 0, -1, 10.25); test_one("case_recursive_boxes_14", case_recursive_boxes_14[0], case_recursive_boxes_14[1], 5, 0, -1, 4.5); test_one("case_recursive_boxes_15", case_recursive_boxes_15[0], case_recursive_boxes_15[1], - 2, 0, -1, 6.0); + 3, 0, -1, 6.0); test_one("case_recursive_boxes_16", case_recursive_boxes_16[0], case_recursive_boxes_16[1], - 1, 1, -1, 22.0); + 1, 0, -1, 22.0); test_one("case_recursive_boxes_17", case_recursive_boxes_17[0], case_recursive_boxes_17[1], - 4, 1, -1, 21.0); + 5, 1, -1, 21.0); test_one("case_recursive_boxes_18", case_recursive_boxes_18[0], case_recursive_boxes_18[1], 3, 0, -1, 2.5);