[overlay] fix new case #case_recursive_boxes_48 for self-intersections

by discarding self ii turns NOT located within another geometry
This commit is contained in:
Barend Gehrels 2017-05-31 11:12:57 +02:00
parent 00ef210f69
commit 16be4bbdb2
4 changed files with 73 additions and 1 deletions

View File

@ -371,7 +371,12 @@ inline void enrich_intersection_points(Turns& turns,
OverlayType,
target_operation
>::apply(turns, geometry1, geometry2);
// detail::overlay::discard_open_turns
detail::overlay::discard_open_turns
<
OverlayType,
target_operation
>::apply(turns, geometry1, geometry2);
// Create a map of vectors of indexed operation-types to be able
// to sort intersection points PER RING
mapped_vector_type mapped_vector;

View File

@ -73,6 +73,66 @@ struct discard_closed_turns<overlay_union, operation_union>
}
};
struct discard_self_intersection_turns
{
template <typename Turns, typename Geometry0, typename Geometry1>
static inline
void apply(Turns& turns,
Geometry0 const& geometry0, Geometry1 const& geometry1)
{
typedef typename boost::range_value<Turns>::type turn_type;
for (typename boost::range_iterator<Turns>::type
it = boost::begin(turns);
it != boost::end(turns);
++it)
{
turn_type& turn = *it;
if (turn.cluster_id >= 0
|| turn.discarded
|| ! is_self_turn<overlay_intersection>(turn))
{
continue;
}
segment_identifier const& id0 = turn.operations[0].seg_id;
segment_identifier const& id1 = turn.operations[1].seg_id;
if (id0.multi_index != id1.multi_index
|| (id0.ring_index == -1 && id1.ring_index == -1)
|| (id0.ring_index >= 0 && id1.ring_index >= 0))
{
// Not an ii ring (int/ext) on same ring
continue;
}
// It is a non co-located ii self-turn
// Check if it is within the other geometry
// If not, it can be ignored
bool const within =
turn.operations[0].seg_id.source_index == 0
? geometry::within(turn.point, geometry1)
: geometry::within(turn.point, geometry0);
if (! within)
{
// It is not within another geometry, discard the turn
turn.discarded = true;
}
}
}
};
template <overlay_type OverlayType, operation_type OperationType>
struct discard_open_turns : discard_turns {};
// Handler it for intersection
template <>
struct discard_open_turns<overlay_intersection, operation_intersection>
: discard_self_intersection_turns {};
// For difference, it should be done in a different way (TODO)
}} // namespace detail::overlay
#endif //DOXYGEN_NO_DETAIL

View File

@ -932,6 +932,12 @@ static std::string case_recursive_boxes_47[2] =
"MULTIPOLYGON(((4 5,4 4,1 4,1 5,4 5)),((5 6,5 7,6 7,6 6,5 6)),((5 6,5 5,4 5,4 6,5 6)),((5 3,5 5,6 5,6 3,5 3)),((5 3,5 2,4 2,4 3,5 3)),((6 5,6 6,7 6,7 5,6 5)),((3 7,2 7,2 9,3 9,3 8,4 8,4 7,3 7)))"
};
static std::string case_recursive_boxes_48[2] =
{
"MULTIPOLYGON(((6 7,6 8,7 8,7 7,6 7)))",
"MULTIPOLYGON(((9 9,10 9,10 7,9 7,9 5,8 5,8 6,7 6,7 7,6 7,6 8,7 8,7 9,8 9,8 10,9 10,9 9),(9 8,8 8,8 7,9 7,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

@ -282,6 +282,7 @@ void test_areal()
TEST_INTERSECTION(case_recursive_boxes_43, 2, 0, 22.5);
TEST_INTERSECTION(case_recursive_boxes_44, 2, 0, 3.0);
TEST_INTERSECTION(case_recursive_boxes_45, 7, 0, 12.0);
TEST_INTERSECTION(case_recursive_boxes_48, 1, 0, 1.0);
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],