[traverse] extend handling specific case of cc/ii with another variant,

now also solving #case_recursive_boxes_50
This commit is contained in:
Barend Gehrels 2017-06-04 11:23:42 +02:00
parent 463f778a36
commit b0cf8ffb59
6 changed files with 48 additions and 17 deletions

View File

@ -81,22 +81,35 @@ struct rank_with_rings
return all_equal(sort_by_side::dir_from);
}
inline bool is_c_i() const
inline bool has_only(operation_type op) const
{
bool has_c = false;
bool has_i = false;
for (std::set<ring_with_direction>::const_iterator it = rings.begin();
it != rings.end(); ++it)
{
const ring_with_direction& rwd = *it;
switch(rwd.operation)
if (rwd.operation != op)
{
case operation_continue : has_c = true; break;
case operation_intersection : has_i = true; break;
default : return false;
return false;
}
}
return has_c && has_i;
return true;
}
//! Check if set has both op1 and op2, but no others
inline bool has_only_both(operation_type op1, operation_type op2) const
{
bool has1 = false;
bool has2 = false;
for (std::set<ring_with_direction>::const_iterator it = rings.begin();
it != rings.end(); ++it)
{
const ring_with_direction& rwd = *it;
if (rwd.operation == op1) { has1 = true; }
else if (rwd.operation == op2) { has2 = true; }
else { return false; }
}
return has1 && has2;
}
inline bool is_isolated() const

View File

@ -469,23 +469,31 @@ struct traversal
&& aggregation[0].all_from()
&& aggregation[1].rings.size() == 2
&& aggregation[1].all_to()
&& aggregation[1].is_c_i()
&& aggregation[1].is_isolated()
&& aggregation[n - 2].rings.size() == 2
&& aggregation[n - 2].all_from()
&& aggregation[n - 2].is_c_i()
&& aggregation[n - 2].is_isolated()
&& aggregation[n - 1].rings.size() == 1
&& aggregation[n - 1].all_to())
{
// Pattern: coming from exterior ring, encountering an isolated
// parallel interior ring, which should be skipped, and the first
// left (normally intersection takes first right) should be taken.
// Solves cases #case_133_multi
// and #case_recursive_boxes_49
aggregation[1].has_only_both(operation_continue, operation_intersection)
&& aggregation[n - 2].has_only_both(operation_continue, operation_intersection);
selected_rank = n - 1;
return true;
bool const second =
aggregation[1].has_only(operation_continue)
&& aggregation[n - 2].has_only(operation_continue);
if (first || second)
{
// Pattern: coming from exterior ring, encountering an isolated
// parallel interior ring, which should be skipped, and the first
// left (normally intersection takes first right) should be taken.
// Solves cases #case_133_multi
// and #case_recursive_boxes_49
selected_rank = n - 1;
return true;
}
}
return false;
}

View File

@ -953,6 +953,13 @@ static std::string case_recursive_boxes_49[2] =
"MULTIPOLYGON(((5 1,4 1,4 3,3 3,3 6,2 6,2 9,5 9,5 7,4 7,4 4,5 4,5 3,6 3,6 2,8 2,8 1,9 1,9 0,5 0,5 1),(4 7,4 8,3 8,3 7,4 7)),((8 2,8 3,9 3,9 2,8 2)),((9 5,9 6,10 6,10 5,9 5)),((9 5,9 4,8 4,8 5,9 5)),((7 5,7 4,6 4,6 5,7 5)),((7 10,9 10,9 9,10 9,10 7,8 7,8 6,6 6,6 10,7 10),(7 9,7 8,8 8,8 9,7 9)))"
};
static std::string case_recursive_boxes_50[2] =
{
// Same as 49 but needs the second variant
"MULTIPOLYGON(((6 9,6 10,7 10,7 9,6 9)),((5 6,6 6,6 5,4 5,4 7,3 7,3 8,4 8,4 9,2 9,2 10,5 10,5 8,6 8,6 7,5 7,5 6)),((4 0,1 0,1 1,2 1,2 2,3 2,3 3,5 3,5 0,4 0)),((3 5,3 3,1 3,1 4,0 4,0 6,1 6,1 7,0 7,0 8,2 8,2 6,3 6,3 5),(2 5,1 5,1 4,2 4,2 5)),((1 1,0 1,0 2,1 2,1 1)),((6 5,7 5,7 4,6 4,6 5)),((10 5,8 5,8 6,9 6,9 7,10 7,10 5)),((6 0,6 1,8 1,8 2,10 2,10 0,6 0)),((9 7,7 7,7 8,8 8,8 9,9 9,9 7)),((8 2,6 2,6 3,8 3,8 2)),((9 9,9 10,10 10,10 9,9 9)))",
"MULTIPOLYGON(((5 3,5 4,6 4,6 3,5 3)),((5 7,6 7,6 5,4 5,4 6,3 6,3 7,4 7,4 8,5 8,5 7)),((3 6,3 4,4 4,4 3,1 3,1 2,0 2,0 9,1 9,1 10,3 10,3 9,2 9,2 8,3 8,3 7,1 7,1 6,3 6),(1 5,1 4,2 4,2 5,1 5)),((4 0,0 0,0 1,1 1,1 2,3 2,3 1,5 1,5 0,4 0)),((7 6,7 7,8 7,8 8,9 8,9 6,8 6,8 5,7 5,7 6)),((9 0,7 0,7 1,9 1,9 2,10 2,10 0,9 0)),((7 9,5 9,5 10,7 10,7 9)),((7 9,8 9,8 8,7 8,7 9)),((8 3,8 2,7 2,7 3,8 3)),((8 3,8 4,9 4,9 3,8 3)),((8 9,8 10,9 10,9 9,8 9)),((9 8,9 9,10 9,10 8,9 8)))"
};
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

@ -332,6 +332,7 @@ void test_areal()
#else
TEST_DIFFERENCE_IGNORE(case_recursive_boxes_49, 9, 22.0, 10, 17.0, 10);
#endif
TEST_DIFFERENCE(case_recursive_boxes_50, 14, 21.0, 16, 21.0, 14);
test_one<Polygon, MultiPolygon, MultiPolygon>("mysql_21965285_b",
mysql_21965285_b[0],

View File

@ -288,6 +288,7 @@ void test_areal()
TEST_INTERSECTION(case_recursive_boxes_47, 1, 5, 1.0);
TEST_INTERSECTION(case_recursive_boxes_48, 1, 5, 1.0);
TEST_INTERSECTION(case_recursive_boxes_49, 7, 57, 20.0);
TEST_INTERSECTION(case_recursive_boxes_50, 9, 71, 26.0);
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],

View File

@ -361,6 +361,7 @@ void test_areal()
#else
TEST_UNION_IGNORE(case_recursive_boxes_49, 1, 2, -1, 59.0);
#endif
TEST_UNION(case_recursive_boxes_50, 7, 4, -1, 68.0);
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],