diff --git a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp index 37a7a76519..40845f34c1 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp @@ -65,26 +65,31 @@ class no_turns_la_linestring_pred , m_result(res) , m_strategy(strategy) , m_boundary_checker(boundary_checker) - , m_interrupt_flags(0) + , m_interrupt_flags(0x00) { if ( ! may_update(m_result) ) { - m_interrupt_flags |= 1; + m_interrupt_flags |= 0x01; } if ( ! may_update(m_result) ) { - m_interrupt_flags |= 2; + m_interrupt_flags |= 0x02; } if ( ! may_update(m_result) ) { - m_interrupt_flags |= 4; + m_interrupt_flags |= 0x04; } if ( ! may_update(m_result) ) { - m_interrupt_flags |= 8; + m_interrupt_flags |= 0x08; + } + + if ( ! may_update(m_result) ) + { + m_interrupt_flags |= 0x10; } } @@ -94,7 +99,7 @@ class no_turns_la_linestring_pred std::size_t const count = boost::size(linestring); // invalid input - if ( count < 2 ) + if ( count < 1 ) { // ignore // TODO: throw an exception? @@ -102,7 +107,7 @@ class no_turns_la_linestring_pred } // if those flags are set nothing will change - if ( m_interrupt_flags == 0xF ) + if ( m_interrupt_flags == 0x1F ) { return false; } @@ -110,17 +115,24 @@ class no_turns_la_linestring_pred int const pig = detail::within::point_in_geometry(range::front(linestring), m_geometry2, m_strategy); - //BOOST_GEOMETRY_ASSERT_MSG(pig != 0, "There should be no IPs"); if ( pig > 0 ) { update(m_result); - m_interrupt_flags |= 1; + m_interrupt_flags |= 0x01; + } + else if ( pig == 0 ) + { + // no turns but still point on boundary can actually happen when the + // linestring is degenerate. so handle this case explicitly here. + // for consistency let's still report dimension 1 instead of 0 + update(m_result); + m_interrupt_flags |= 0x10; } else { update(m_result); - m_interrupt_flags |= 2; + m_interrupt_flags |= 0x02; } // check if there is a boundary @@ -131,16 +143,16 @@ class no_turns_la_linestring_pred if ( pig > 0 ) { update(m_result); - m_interrupt_flags |= 4; + m_interrupt_flags |= 0x04; } else { update(m_result); - m_interrupt_flags |= 8; + m_interrupt_flags |= 0x08; } } - return m_interrupt_flags != 0xF + return m_interrupt_flags != 0x1F && ! m_result.interrupt; } diff --git a/test/algorithms/covered_by/covered_by.cpp b/test/algorithms/covered_by/covered_by.cpp index 84f69b0ce7..f7716b4e4e 100644 --- a/test/algorithms/covered_by/covered_by.cpp +++ b/test/algorithms/covered_by/covered_by.cpp @@ -141,6 +141,31 @@ void test_all() test_geometry, poly

>("BOX(1 1,2 2)", "POLYGON((0 0,0 3,3 1,1 0,0 0))", false); test_geometry, mpoly

>("BOX(1 1,2 2)", "MULTIPOLYGON(((0 0,0 3,3 3,3 0,0 0)),((-1 -1,-3 -4,-7 -7,-4 -3,-1 -1)))", true); test_geometry, mpoly

>("BOX(1 1,2 2)", "MULTIPOLYGON(((0 0,0 3,3 1,1 0,0 0)),((-1 -1,-3 -4,-7 -7,-4 -3,-1 -1)))", false); + + // degenerate line segment - polygon + { + // on corner + test_geometry, poly

>("LINESTRING(0 0,0 0)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", true); + test_geometry, poly

>("LINESTRING(0 0)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", true); + // on edge + test_geometry, poly

>("LINESTRING(1 2,1 2)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", true); + test_geometry, poly

>("LINESTRING(1 2)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", true); + // inside + test_geometry, poly

>("LINESTRING(1 1,1 1)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", true); + test_geometry, poly

>("LINESTRING(1 1)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", true); + // outside + test_geometry, poly

>("LINESTRING(1 3,1 3)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", false); + test_geometry, poly

>("LINESTRING(1 3)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", false); + // inside hole + test_geometry, poly

>("LINESTRING(2 2,2 2)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", false); + test_geometry, poly

>("LINESTRING(2 2)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", false); + // on corner of hole + test_geometry, poly

>("LINESTRING(3 3,3 3)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", true); + test_geometry, poly

>("LINESTRING(3 3)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", true); + // on edge of hole + test_geometry, poly

>("LINESTRING(2 1,2 1)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", true); + test_geometry, poly

>("LINESTRING(2 1)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", true); + } } diff --git a/test/algorithms/relate/relate_linear_areal.cpp b/test/algorithms/relate/relate_linear_areal.cpp index 337cc32b4f..613d17af90 100644 --- a/test/algorithms/relate/relate_linear_areal.cpp +++ b/test/algorithms/relate/relate_linear_areal.cpp @@ -277,6 +277,31 @@ void test_linestring_polygon() test_geometry("LINESTRING(2 9, 1 1, 10 1, 10 10, 1 10, 0 6, 5 6)", "POLYGON((0 0,0 10,10 10,10 0,0 0),(4 4,4 6,6 6,6 4,4 4))", "11F00F212"); + + // degenerate line segment + { + // on corner + test_geometry("LINESTRING(0 0,0 0)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "F1FFFF212"); + test_geometry("LINESTRING(0 0)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "F1FFFF212"); + // on edge + test_geometry("LINESTRING(1 2,1 2)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "F1FFFF212"); + test_geometry("LINESTRING(1 2)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "F1FFFF212"); + // inside + test_geometry("LINESTRING(1 1,1 1)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "1FFFFF212"); + test_geometry("LINESTRING(1 1)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "1FFFFF212"); + // outside + test_geometry("LINESTRING(1 3,1 3)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "FF1FFF212"); + test_geometry("LINESTRING(1 3)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "FF1FFF212"); + // inside hole + test_geometry("LINESTRING(2 2,2 2)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", "FF1FFF212"); + test_geometry("LINESTRING(2 2)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", "FF1FFF212"); + // on corner of hole + test_geometry("LINESTRING(3 3,3 3)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", "F1FFFF212"); + test_geometry("LINESTRING(3 3)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", "F1FFFF212"); + // on edge of hole + test_geometry("LINESTRING(2 1,2 1)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", "F1FFFF212"); + test_geometry("LINESTRING(2 1)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))", "F1FFFF212"); + } } template