From 9e00853dfa32b4b7645b658db34105bdd5a686ea Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 8 Apr 2014 15:33:18 +0200 Subject: [PATCH] [relate] fix: add missing handling of single geometries for which no IPs were generated (exterior ring inside, hole outside) --- .../algorithms/detail/relate/areal_areal.hpp | 35 ++++++++++++++++++- test/algorithms/relate.cpp | 19 +++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp index 393001130..e44c008a7 100644 --- a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp @@ -93,6 +93,38 @@ public: update(m_result); update(m_result); m_flags |= 1; + + // TODO: OPTIMIZE! + // Only the interior rings of other ONE single geometry must be checked + // NOT all geometries + + // Check if any interior ring is outside + ring_identifier ring_id(0, -1, 0); + for ( ; ring_id.ring_index < boost::numeric_cast(geometry::num_interior_rings(areal)) ; + ++ring_id.ring_index ) + { + typename detail::sub_range_return_type::type + range_ref = detail::sub_range(areal, ring_id); + + if ( boost::empty(range_ref) ) + { + // TODO: throw exception? + continue; // ignore + } + + // TODO: O(N) + // Optimize! + int pig = detail::within::point_in_geometry(range::front(range_ref), m_other_areal); + + // hole outside + if ( pig < 0 ) + { + update(m_result); + update(m_result); + m_flags |= 2; + break; + } + } } // outside else @@ -101,7 +133,7 @@ public: update(m_result); m_flags |= 2; - // If the exterior ring is outside, interior rings must be checked + // Check if any interior ring is inside ring_identifier ring_id(0, -1, 0); for ( ; ring_id.ring_index < boost::numeric_cast(geometry::num_interior_rings(areal)) ; ++ring_id.ring_index ) @@ -126,6 +158,7 @@ public: update(m_result); update(m_result); m_flags |= 1; + break; } } } diff --git a/test/algorithms/relate.cpp b/test/algorithms/relate.cpp index 6b4c6671b..64e187e02 100644 --- a/test/algorithms/relate.cpp +++ b/test/algorithms/relate.cpp @@ -696,7 +696,7 @@ void polygon_polygon() // fully containing, both with holes test_geometry("POLYGON((0 0,0 10,10 10,10 0,0 0),(3 3,7 3,7 7,3 7,3 3))", "POLYGON((1 1,1 9,9 9,9 1,1 1),(4 4,6 4,6 6,4 6,4 4))", - "2121F12F2"); + "2121F1212"); // overlapping test_geometry("POLYGON((0 0,0 10,10 10,10 0,0 0))", @@ -826,6 +826,23 @@ void polygon_polygon() "POLYGON((5 5,4 8,6 10,10 10,10 0,6 0,4 2,5 5))", "212101212"); + // no turns - disjoint inside a hole + test_geometry("POLYGON((0 0,0 10,10 10,10 0,0 0),(1 1,9 1,9 9,1 9,1 1))", + "POLYGON((3 3,3 7,7 7,7 3,3 3))", + "FF2FF1212"); + // no turns - within + test_geometry("POLYGON((0 0,0 10,10 10,10 0,0 0),(1 1,9 1,9 9,1 9,1 1))", + "POLYGON((-1 -1,-1 11,11 11,11 -1,-1 -1))", + "2FF1FF212"); + // no-turns - intersects + test_geometry("POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,8 2,8 8,2 8,2 2))", + "POLYGON((1 1,1 9,9 9,9 1,1 1))", + "2121F12F2"); + // no-turns - intersects, hole in a hole + test_geometry("POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,8 2,8 8,2 8,2 2))", + "POLYGON((1 1,1 9,9 9,9 1,1 1),(3 3,7 3,7 7,3 7,3 3))", + "2121F1212"); + { test_geometry("POLYGON((0 0,0 10,10 10,10 0,0 0))", "POLYGON((5 5,5 10,6 10,6 5,5 5))",