[intersection] fix cases where intersection has to travel through uu/ux

This commit is contained in:
Barend Gehrels 2016-01-13 12:49:47 +01:00
parent d256e57487
commit 8364aed91b
4 changed files with 67 additions and 10 deletions

View File

@ -258,10 +258,10 @@ struct traversal
std::set<signed_size_type> const& ids = mit->second;
sbs_type sbs;
bool has_subject = false;
// Check if it is a combination with uu
bool uu_combi = false;
bool has_subject = false;
bool has_uu = false;
bool has_operation = false;
for (typename std::set<signed_size_type>::const_iterator sit = ids.begin();
sit != ids.end(); ++sit)
@ -273,11 +273,17 @@ struct traversal
// Defensive check, discarded turns should not be in cluster
continue;
}
if (OperationType == operation_union
&& cturn.both(operation_union))
if (cturn.both(operation_union))
{
uu_combi = true;
has_uu = true;
}
if (cturn.has(OperationType))
{
has_operation = true;
}
for (int i = 0; i < 2; i++)
{
turn_operation_type const& cop = cturn.operations[i];
@ -300,12 +306,13 @@ struct traversal
}
sbs.apply(turn.point);
if (uu_combi)
if (has_uu && OperationType == operation_union)
{
sbs.reverse();
}
if (uu_combi)
if (has_uu && OperationType == operation_union)
{
std::size_t index = sbs.first_open_index();
if (index < sbs.m_ranked_points.size())
@ -319,6 +326,11 @@ struct traversal
return false;
}
if (! has_operation && OperationType == operation_intersection)
{
sbs.find_open();
}
// Normal intersection or non-reversed union
// (TODO: move this to sbs too)
const std::size_t target_main_rank = 1;
@ -340,10 +352,29 @@ struct traversal
return false;
}
bool allow = ranked_point.operation == OperationType
|| ranked_point.operation == operation_continue;
if (! allow
&& !result
&& OperationType == operation_intersection
&& ranked_point.right_count == 2
&& ! has_operation)
{
// In some cases it is necessary for intersection to continue
// through a cluster with only uu and cc turns (because uu turns
// are not blocked anymore). For example an intersection of
// equal multi-polygons, both having a uu turn
turn_type const& ranked_turn = m_turns[ranked_point.turn_index];
if (ranked_turn.both(operation_union))
{
allow = true;
}
}
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))
&& allow)
{
turn_type const& ranked_turn = m_turns[ranked_point.turn_index];

View File

@ -613,6 +613,20 @@ static std::string case_recursive_boxes_30[2] =
"MULTIPOLYGON(((2 1,2 3,1 3,1 4,2 5,2 4,3 4,3 5,5 5,5 4,4 4,3.5 3.5,4 3,4 4,5 3,4.5 2.5,5 2,5 0,4 0,4 2,3 2,3 3,2.5 2.5,4 1,3 1,3 0,1 0,2 1)))"
};
static std::string case_recursive_boxes_31[2] =
{
// Requires allowing traverse through clusters having only uu/cc for intersection
"MULTIPOLYGON(((1 4,1 1,0 1,0 4,1 4)),((1 1,2 1,2 0,1 0,1 1)),((2 2,1 2,2 3,2 2)))",
"MULTIPOLYGON(((2 3,2 2,1 2,2 3)),((0 1,0 3,1 3,1 1,0 1)),((1 1,1 0,0 0,1 1)))"
};
static std::string case_recursive_boxes_32[2] =
{
// Similar to #31 but here uu/ux/cc
"MULTIPOLYGON(((1 3,2 3,2 2,1 1,1 3)),((2 2,3 1,3 0,2 0,2 2)),((1 1,2 1,1 0,0 0,0 1,1 1)))",
"MULTIPOLYGON(((3 1,3 0,2 0,2 2,3 1)),((1 1,0 1,0 2,1 2,2 1,1 1)))"
};
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)))",

View File

@ -216,6 +216,12 @@ void test_areal()
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_30",
case_recursive_boxes_30[0], case_recursive_boxes_30[1],
4, 0, 6.0);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_31",
case_recursive_boxes_31[0], case_recursive_boxes_31[1],
2, 0, 2.5);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_32",
case_recursive_boxes_32[0], case_recursive_boxes_32[1],
2, 0, 1.75);
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],

View File

@ -207,6 +207,12 @@ void test_areal()
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_30",
case_recursive_boxes_30[0], case_recursive_boxes_30[1],
1, 1, -1, 17.5);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_31",
case_recursive_boxes_31[0], case_recursive_boxes_31[1],
3, 0, -1, 5.0);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_32",
case_recursive_boxes_32[0], case_recursive_boxes_32[1],
2, 0, -1, 5.75);
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],