[relate] Fix L/L : handling of MLs containing overlapping, collinear Linestrings.

It's also consistent with the behavior for Point-like Linestrings.

E.g. some MultiLinestring may have boundary and interior in the same point:

Ls1:
  |--------------|
MLs2:
  |------------|
|------|

In this case the current version of the algorithm will set BB=0 and BI=0.
This commit is contained in:
Adam Wulkiewicz 2014-04-18 14:43:07 +02:00
parent 89955b787b
commit a99fda5362
3 changed files with 42 additions and 8 deletions

View File

@ -248,7 +248,7 @@ public:
point_info(turn.operations[other_op_id].seg_id, turn.point) );
}
void exit(TurnInfo const& turn)
void exit(TurnInfo const& turn, bool exit_per_geometry = true)
{
//segment_identifier const& seg_id = turn.operations[op_id].seg_id;
segment_identifier const& other_id = turn.operations[other_op_id].seg_id;
@ -263,13 +263,16 @@ public:
// this end point has corresponding entry point
if ( entry_it != other_entry_points.end() )
{
// here we know that we possibly left LS
// we must still check if we didn't get back on the same point
exit_operation = exit_op;
exit_turn = boost::addressof(turn);
// erase the corresponding entry point
other_entry_points.erase(entry_it);
if ( exit_per_geometry || other_entry_points.empty() )
{
// here we know that we possibly left LS
// we must still check if we didn't get back on the same point
exit_operation = exit_op;
exit_turn = boost::addressof(turn);
}
}
}

View File

@ -496,7 +496,9 @@ struct linear_linear
else
{
// if we didn't enter in the past, we were outside
if ( was_outside && !fake_enter_detected )
if ( was_outside
&& ! fake_enter_detected
&& it->operations[op_id].position != overlay::position_front )
{
update<interior, exterior, '1', transpose_result>(res);
@ -528,7 +530,7 @@ struct linear_linear
// to exit we must be currently inside and the current segment must be collinear
if ( !was_outside && is_collinear )
{
m_exit_watcher.exit(*it);
m_exit_watcher.exit(*it, false);
}
bool op_blocked = op == overlay::operation_blocked;

View File

@ -243,6 +243,35 @@ void test_linestring_multi_linestring()
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
"MULTILINESTRING((1 0, 2 0),(0 0, 0 0))", // * |------|
"1010F0FF2");
// for consistency
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
"MULTILINESTRING((0 0, 5 0),(0 0, 2 0))", // |--------------|
"10F00FFF2"); // |------|
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
"MULTILINESTRING((0 0, 5 0),(3 0, 5 0))", // |--------------|
"10F00FFF2"); // |------|
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
"MULTILINESTRING((0 0, 5 0),(0 0, 6 0))", // |--------------|
"1FF00F102"); // |----------------|
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
"MULTILINESTRING((0 0, 5 0),(-1 0, 5 0))", // |--------------|
"1FF00F102"); // |----------------|
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
"MULTILINESTRING((0 0, 5 0),(-1 0, 6 0))", // |--------------|
"1FF00F102"); // |------------------|
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
"MULTILINESTRING((0 0, 5 0),(-1 0, 2 0))", // |--------------|
"10F00F102"); // |-------|
test_geometry<ls, mls>("LINESTRING(0 0, 5 0)", // |--------------|
"MULTILINESTRING((0 0, 5 0),(2 0, 6 0))", // |--------------|
"10F00F102"); // |-------|
}
template <typename P>