summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/relate/linear_linear.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/relate/linear_linear.hpp')
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_linear.hpp35
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 263c82d..20a22c3 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;
}