[traverse] fix, take the right operation in a cluster instead of using

select_operation
This commit is contained in:
Barend Gehrels 2015-12-30 15:18:54 +01:00
parent dbb92e7088
commit eee10489ad
5 changed files with 58 additions and 15 deletions

View File

@ -214,8 +214,8 @@ struct traversal
return result;
}
inline bool select_turn_from_cluster(
typename boost::range_iterator<Turns>::type& turn_it,
inline bool select_turn_from_cluster(turn_iterator& turn_it,
turn_operation_iterator_type& op_it,
turn_operation_type const& op)
{
turn_type const& turn = *turn_it;
@ -273,6 +273,7 @@ struct traversal
|| ranked_point.operation == operation_continue))
{
turn_type const& ranked_turn = m_turns[ranked_point.turn_index];
if (ranked_turn.discarded)
{
// Might be collocated u/u turn
@ -284,7 +285,23 @@ struct traversal
signed_size_type const turn_index = ranked_point.turn_index;
if (turn_index != -1)
{
turn_operation_type const& ranked_op = ranked_turn.operations[ranked_point.op_index];
turn_it = m_turns.begin() + turn_index;
if (ranked_turn.both(operation_intersection)
&& ranked_op.visited.finalized())
{
// For a ii turn, even though one operation might be selected,
// it should take the other one if the first one is used in a completed ring
op_it = turn_it->operations.begin() + (1 - ranked_point.op_index);
}
else
{
// Normal behaviour
op_it = turn_it->operations.begin() + ranked_point.op_index;
}
return true;
}
}
@ -305,6 +322,8 @@ struct traversal
Ring& current_ring,
bool is_start)
{
turn_operation_iterator_type previous_op_it = op_it;
turn_iterator previous_turn_it = turn_it;
turn_type& previous_turn = *turn_it;
turn_operation_type& previous_op = *op_it;
@ -345,14 +364,20 @@ struct traversal
seg_id = previous_op.seg_id;
}
if (turn_it->cluster_id >= 0)
bool const has_cluster = turn_it->cluster_id >= 0;
if (has_cluster)
{
if (! select_turn_from_cluster(turn_it, previous_op))
if (! select_turn_from_cluster(turn_it, op_it, previous_op))
{
return is_start
? traverse_error_no_next_ip_at_start
: traverse_error_no_next_ip;
}
if (is_start && turn_it == previous_turn_it)
{
op_it = previous_op_it;
}
}
detail::overlay::append_no_dups_or_spikes(current_ring, turn_it->point,
@ -366,14 +391,17 @@ struct traversal
m_visitor.visit_traverse(m_turns, previous_turn, previous_op, "Start");
}
if (! select_operation(*turn_it,
start_turn_index,
seg_id,
op_it))
if (! has_cluster)
{
return is_start
? traverse_error_dead_end_at_start
: traverse_error_dead_end;
if (! select_operation(*turn_it,
start_turn_index,
seg_id,
op_it))
{
return is_start
? traverse_error_dead_end_at_start
: traverse_error_dead_end;
}
}
turn_operation_type& op = *op_it;
@ -585,9 +613,9 @@ public :
{
op_type& start_op = *op_it;
if (!start_op.visited.none()
if (! start_op.visited.none()
|| start_op.visited.rejected()
|| !(start_op.operation == OpType
|| ! (start_op.operation == OpType
|| start_op.operation == detail::overlay::operation_continue))
{
continue;

View File

@ -51,6 +51,7 @@ public:
inline bool started() const { return m_visit_code == STARTED; }
inline bool finished() const { return m_visit_code == FINISHED; }
inline bool rejected() const { return m_rejected; }
inline bool finalized() const { return m_final; }
inline void clear()
{

View File

@ -122,11 +122,14 @@ static std::string case_71_multi[2] =
"MULTIPOLYGON(((0 2,0 3,3 3,3 2,0 2)))"
};
static std::string case_72_multi[2] =
static std::string case_72_multi[3] =
{
// cluster with ii, done by both traverse and assemble
"MULTIPOLYGON(((0 3,4 4,3 0,3 3,0 3)),((3 3,2 1,1 2,3 3)))",
"MULTIPOLYGON(((0 0,1 4,3 3,4 1,0 0)))"
"MULTIPOLYGON(((0 0,1 4,3 3,4 1,0 0)))",
// Inverse version of a
"MULTIPOLYGON(((-1 -1,-1 5,5 5,5 -1,-1 -1),(0 3,3 3,3 0,4 4,0 3),(3 3,1 2,2 1,3 3)))"
};
static std::string case_73_multi[2] =

View File

@ -422,6 +422,14 @@ void test_all()
case_58_multi[6], case_58_multi[2],
13.25
);
test_overlay<multi_polygon, bg::overlay_intersection>
(
"case_72_multi_intersection_inv_b",
case_72_multi[2], case_72_multi[1],
6.15
);
test_overlay<multi_polygon, bg::overlay_union>
(
"case_recursive_boxes_12_union",
case_recursive_boxes_12[0], case_recursive_boxes_12[1],
6.0

View File

@ -99,6 +99,9 @@ void test_areal()
test_one<Polygon, MultiPolygon, MultiPolygon>("case_72_multi",
case_72_multi[0], case_72_multi[1],
3, 14, 2.85);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_72_multi_inv_b",
case_72_multi[1], case_72_multi[2],
3, 16, 6.15);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_77_multi",
case_77_multi[0], case_77_multi[1],
5, 33, 9);