diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index a5780d930..86d0b8743 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -19,6 +19,8 @@ [*Additional functionality] +* New algorithm num_segments, returning the number of segments of a geometry + [*Improvements] * Buffer now supports flat-ends for linestrings with a bend close to the start (such that buffered segment crosses flat-end). diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp index 394bb2664..efe996fc0 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp @@ -354,7 +354,8 @@ struct get_turn_info_linear_areal AssignPolicy >::apply(pi, pj, pk, qi, qj, qk, tp, out, inters.i_info(), inters.d_info(), - inters.sides(), transformer); + inters.sides(), transformer, + !is_p_last, true); // qk is always valid } } } diff --git a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp index 263c82de5..186440e28 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp @@ -250,6 +250,7 @@ struct linear_linear : m_previous_turn_ptr(NULL) , m_previous_operation(overlay::operation_none) , m_degenerated_turn_ptr(NULL) + , m_collinear_spike_exit(false) {} template operations[op_id].position != overlay::position_front ) + && it->operations[op_id].position != overlay::position_front + && ! m_collinear_spike_exit ) { update(res); @@ -402,6 +404,8 @@ struct linear_linear } } } + + m_collinear_spike_exit = false; } // u/i, u/u, u/x, x/i, x/u, x/x else if ( op == overlay::operation_union || op == overlay::operation_blocked ) @@ -418,6 +422,11 @@ struct linear_linear if ( !was_outside && is_collinear ) { m_exit_watcher.exit(*it, false); + // if the position is not set to back it must be a spike + if ( it->operations[op_id].position != overlay::position_back ) + { + m_collinear_spike_exit = true; + } } bool const op_blocked = op == overlay::operation_blocked; @@ -456,6 +465,7 @@ struct linear_linear // if we are truly outside if ( was_outside && it->operations[op_id].position != overlay::position_front + && ! m_collinear_spike_exit /*&& !is_collinear*/ ) { update(res); @@ -526,6 +536,7 @@ struct linear_linear && ( !this_b || op_blocked ) && was_outside && it->operations[op_id].position != overlay::position_front + && ! m_collinear_spike_exit /*&& !is_collinear*/ ) { bool const front_b = is_endpoint_on_boundary( @@ -607,6 +618,10 @@ struct linear_linear m_previous_turn_ptr = NULL; m_previous_operation = overlay::operation_none; m_degenerated_turn_ptr = NULL; + + // actually if this is set to true here there is some error + // in get_turns_ll or relate_ll, an assert could be checked here + m_collinear_spike_exit = false; } template ("LINESTRING(7 8, 6 10, 11 0)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", expected("miu+")("iuu+")); + + // 25.01.2015 + test_geometry("LINESTRING(2 3, 4 5, 0 6, 5 6)", + "POLYGON((0 0,0 10,10 10,10 0,0 0),(4 4,6 4,6 6,4 6,4 4))", + expected("miu+")("miu+")("mcu+")("mxc=")); + test_geometry("LINESTRING(0 6, 5 6)", + "POLYGON((0 0,0 10,10 10,10 0,0 0),(4 4,6 4,6 6,4 6,4 4))", + expected("miu+")("mcu+")("mxc=")); + } int test_main(int, char* []) diff --git a/test/algorithms/relational_operations/relate/relate_linear_areal.cpp b/test/algorithms/relational_operations/relate/relate_linear_areal.cpp index 6c7c5f683..c07c7c4ea 100644 --- a/test/algorithms/relational_operations/relate/relate_linear_areal.cpp +++ b/test/algorithms/relational_operations/relate/relate_linear_areal.cpp @@ -264,6 +264,17 @@ void test_linestring_polygon() test_geometry("LINESTRING(0 0, 7 7)", "POLYGON((5 5,5 15,15 15,15 5,5 5))", "1010F0212"); + + // 25.01.2015 + test_geometry("LINESTRING(4 5, 0 6, 5 6)", + "POLYGON((0 0,0 10,10 10,10 0,0 0),(4 4,6 4,6 6,4 6,4 4))", + "11FF0F212"); + test_geometry("LINESTRING(2 3, 4 5, 0 6, 5 6)", + "POLYGON((0 0,0 10,10 10,10 0,0 0),(4 4,6 4,6 6,4 6,4 4))", + "11F00F212"); + 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"); } template diff --git a/test/algorithms/relational_operations/relate/relate_linear_linear.cpp b/test/algorithms/relational_operations/relate/relate_linear_linear.cpp index 804feb5ad..1429e818a 100644 --- a/test/algorithms/relational_operations/relate/relate_linear_linear.cpp +++ b/test/algorithms/relational_operations/relate/relate_linear_linear.cpp @@ -333,9 +333,32 @@ void test_linestring_multi_linestring() "10FF0F102"); // | // | - // 22.01 2015 + // 22.01.2015 // inspired by L/A and A/A test_geometry("LINESTRING(1 1,2 2)", "MULTILINESTRING((0 0,1 1),(1 1,3 3))", "1FF0FF102"); + + // 25.01.2015 + test_geometry("LINESTRING(1 1, 5 5, 4 4)", + "MULTILINESTRING((2 5, 7 5, 8 3, 6 3, 4 0),(0 0,10 10))", + "1FF0FF102"); + test_geometry("LINESTRING(4 1, 4 5, 4 4)", + "MULTILINESTRING((2 5, 7 5, 8 3, 6 3, 4 0),(4 0, 4 8, 0 4))", + "1FF0FF102"); + test_geometry("LINESTRING(1 1,5 5,4 4)", + "MULTILINESTRING((5 0,5 5,5 10),(0 0,10 10))", + "1FF0FF102"); + test_geometry("LINESTRING(1 1,5 5,1 0)", + "MULTILINESTRING((5 0,5 5,5 10),(0 0,5 5,1 0))", + "1FF00F102"); + test_geometry("LINESTRING(5 5,4 4)", + "MULTILINESTRING((5 0,5 5,5 10),(0 0,10 10))", + "1FF0FF102"); + test_geometry("LINESTRING(6 6,5 5,4 4)", + "MULTILINESTRING((5 0,5 5,5 10),(0 0,10 10))", + "1FF0FF102"); + test_geometry("LINESTRING(5 5,4 4)", + "MULTILINESTRING((5 0,5 5,5 10))", + "FF10F0102"); } template