diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/relate/linear_linear.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/relate/linear_linear.hpp | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/boost/geometry/algorithms/detail/relate/linear_linear.hpp index 263c82de56..20a22c3018 100644 --- a/boost/geometry/algorithms/detail/relate/linear_linear.hpp +++ b/boost/geometry/algorithms/detail/relate/linear_linear.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014. -// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015. +// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -16,6 +16,7 @@ #include <boost/core/ignore_unused.hpp> +#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/range.hpp> #include <boost/geometry/algorithms/detail/sub_range.hpp> @@ -117,7 +118,7 @@ struct linear_linear { // The result should be FFFFFFFFF relate::set<exterior, exterior, result_dimension<Geometry1>::value>(result);// FFFFFFFFd, d in [1,9] or T - if ( result.interrupt ) + if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; // get and analyse turns @@ -133,19 +134,19 @@ struct linear_linear detail::get_turns::get_turn_info_type<Geometry1, Geometry2, turns::assign_policy<true> > >::apply(turns, geometry1, geometry2, interrupt_policy); - if ( result.interrupt ) + if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; boundary_checker<Geometry1> boundary_checker1(geometry1); disjoint_linestring_pred<Result, boundary_checker<Geometry1>, false> pred1(result, boundary_checker1); for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1); - if ( result.interrupt ) + if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; boundary_checker<Geometry2> boundary_checker2(geometry2); disjoint_linestring_pred<Result, boundary_checker<Geometry2>, true> pred2(result, boundary_checker2); for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2); - if ( result.interrupt ) + if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; if ( turns.empty() ) @@ -171,7 +172,7 @@ struct linear_linear boundary_checker1, boundary_checker2); } - if ( result.interrupt ) + if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; if ( may_update<interior, interior, '1', true>(result) @@ -250,6 +251,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 <typename Result, @@ -383,7 +385,8 @@ struct linear_linear // if we didn't enter in the past, we were outside if ( was_outside && ! fake_enter_detected - && it->operations[op_id].position != overlay::position_front ) + && it->operations[op_id].position != overlay::position_front + && ! m_collinear_spike_exit ) { update<interior, exterior, '1', transpose_result>(res); @@ -402,6 +405,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 +423,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 +466,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<interior, exterior, '1', transpose_result>(res); @@ -526,6 +537,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<boundary_front>( @@ -607,6 +619,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 <typename Result, @@ -724,6 +740,7 @@ struct linear_linear const TurnInfo * m_previous_turn_ptr; overlay::operation_type m_previous_operation; const TurnInfo * m_degenerated_turn_ptr; + bool m_collinear_spike_exit; }; template <typename Result, @@ -750,7 +767,7 @@ struct linear_linear geometry, other_geometry, boundary_checker, other_boundary_checker); - if ( res.interrupt ) + if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) ) return; } |