summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/relate
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/relate')
-rw-r--r--boost/geometry/algorithms/detail/relate/areal_areal.hpp38
-rw-r--r--boost/geometry/algorithms/detail/relate/boundary_checker.hpp40
-rw-r--r--boost/geometry/algorithms/detail/relate/topology_check.hpp36
-rw-r--r--boost/geometry/algorithms/detail/relate/turns.hpp4
4 files changed, 85 insertions, 33 deletions
diff --git a/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
index cc9c1b67ca..a74954326b 100644
--- a/boost/geometry/algorithms/detail/relate/areal_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
@@ -338,7 +338,7 @@ struct areal_areal
template <std::size_t OpId, typename Turn>
inline void per_turn(Turn const& turn)
{
- static const std::size_t other_op_id = (OpId + 1) % 2;
+ //static const std::size_t other_op_id = (OpId + 1) % 2;
static const bool transpose_result = OpId != 0;
overlay::operation_type const op = turn.operations[OpId].operation;
@@ -357,11 +357,14 @@ struct areal_areal
else if ( op == overlay::operation_intersection )
{
// ignore i/i
- if ( turn.operations[other_op_id].operation != overlay::operation_intersection )
+ /*if ( turn.operations[other_op_id].operation != overlay::operation_intersection )
{
- update<interior, interior, '2', transpose_result>(m_result);
+ // not correct e.g. for G1 touching G2 in a point where a hole is touching the exterior ring
+ // in this case 2 turns i/... and u/u will be generated for this IP
+ //update<interior, interior, '2', transpose_result>(m_result);
+
//update<boundary, interior, '1', transpose_result>(m_result);
- }
+ }*/
update<boundary, boundary, '0', transpose_result>(m_result);
}
@@ -473,8 +476,11 @@ struct areal_areal
// ignore i/i
if ( it->operations[other_op_id].operation != overlay::operation_intersection )
{
- // already set in interrupt policy
+ // this was set in the interrupt policy but it was wrong
+ // also here it's wrong since it may be a fake entry point
//update<interior, interior, '2', transpose_result>(result);
+
+ // already set in interrupt policy
//update<boundary, boundary, '0', transpose_result>(result);
m_enter_detected = true;
}
@@ -523,6 +529,7 @@ struct areal_areal
template <typename Result>
static inline void update_enter(Result & result)
{
+ update<interior, interior, '2', transpose_result>(result);
update<boundary, interior, '1', transpose_result>(result);
update<exterior, interior, '2', transpose_result>(result);
}
@@ -574,6 +581,7 @@ struct areal_areal
, m_flags(0)
{
// check which relations must be analysed
+ // NOTE: 1 and 4 could probably be connected
if ( ! may_update<interior, interior, '2', transpose_result>(m_result) )
{
@@ -662,21 +670,12 @@ struct areal_areal
if ( it->operations[0].operation == overlay::operation_intersection
&& it->operations[1].operation == overlay::operation_intersection )
{
- // ignore exterior ring
- if ( it->operations[OpId].seg_id.ring_index >= 0 )
- {
- found_ii = true;
- }
+ found_ii = true;
}
else if ( it->operations[0].operation == overlay::operation_union
&& it->operations[1].operation == overlay::operation_union )
{
- // ignore if u/u is for holes
- //if ( it->operations[OpId].seg_id.ring_index >= 0
- // && it->operations[other_id].seg_id.ring_index >= 0 )
- {
- found_uu = true;
- }
+ found_uu = true;
}
else // ignore
{
@@ -687,8 +686,11 @@ struct areal_areal
// only i/i was generated for this ring
if ( found_ii )
{
- //update<interior, interior, '0', transpose_result>(m_result);
- //update<boundary, boundary, '0', transpose_result>(m_result);
+ update<interior, interior, '2', transpose_result>(m_result);
+ m_flags |= 1;
+
+ //update<boundary, boundary, '0', transpose_result>(m_result);
+
update<boundary, interior, '1', transpose_result>(m_result);
update<exterior, interior, '2', transpose_result>(m_result);
m_flags |= 4;
diff --git a/boost/geometry/algorithms/detail/relate/boundary_checker.hpp b/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
index 9de1bacb7d..1a9a5a8fd7 100644
--- a/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
+++ b/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
@@ -17,6 +17,8 @@
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/util/has_nan_coordinate.hpp>
+
namespace boost { namespace geometry
{
@@ -90,19 +92,43 @@ public:
for ( multi_iterator it = boost::begin(geometry) ;
it != boost::end(geometry) ; ++ it )
{
+ typename boost::range_reference<Geometry const>::type
+ ls = *it;
+
// empty or point - no boundary
- if ( boost::size(*it) < 2 )
+ if (boost::size(ls) < 2)
+ {
continue;
+ }
- // linear ring or point - no boundary
- if ( equals::equals_point_point(range::front(*it), range::back(*it)) )
- continue;
+ typedef typename boost::range_reference
+ <
+ typename boost::range_value<Geometry const>::type const
+ >::type point_reference;
+
+ point_reference front_pt = range::front(ls);
+ point_reference back_pt = range::back(ls);
- boundary_points.push_back(range::front(*it));
- boundary_points.push_back(range::back(*it));
+ // linear ring or point - no boundary
+ if (! equals::equals_point_point(front_pt, back_pt))
+ {
+ // do not add points containing NaN coordinates
+ // because they cannot be reasonably compared, e.g. with MSVC
+ // an assertion failure is reported in std::equal_range()
+ if (! geometry::has_nan_coordinate(front_pt))
+ {
+ boundary_points.push_back(front_pt);
+ }
+ if (! geometry::has_nan_coordinate(back_pt))
+ {
+ boundary_points.push_back(back_pt);
+ }
+ }
}
- std::sort(boundary_points.begin(), boundary_points.end(), geometry::less<point_type>());
+ std::sort(boundary_points.begin(),
+ boundary_points.end(),
+ geometry::less<point_type>());
is_filled = true;
}
diff --git a/boost/geometry/algorithms/detail/relate/topology_check.hpp b/boost/geometry/algorithms/detail/relate/topology_check.hpp
index 98b857a488..caa8a3c22d 100644
--- a/boost/geometry/algorithms/detail/relate/topology_check.hpp
+++ b/boost/geometry/algorithms/detail/relate/topology_check.hpp
@@ -16,6 +16,8 @@
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/policies/compare.hpp>
+#include <boost/geometry/util/has_nan_coordinate.hpp>
+
namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
@@ -106,20 +108,42 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
typedef typename boost::range_iterator<MultiLinestring const>::type ls_iterator;
for ( ls_iterator it = boost::begin(mls) ; it != boost::end(mls) ; ++it )
{
- std::size_t count = boost::size(*it);
+ typename boost::range_reference<MultiLinestring const>::type
+ ls = *it;
+
+ std::size_t count = boost::size(ls);
- if ( count > 0 )
+ if (count > 0)
{
has_interior = true;
}
- if ( count > 1 )
+ if (count > 1)
{
+ typedef typename boost::range_reference
+ <
+ typename boost::range_value<MultiLinestring const>::type const
+ >::type point_reference;
+
+ point_reference front_pt = range::front(ls);
+ point_reference back_pt = range::back(ls);
+
// don't store boundaries of linear rings, this doesn't change anything
- if ( ! equals::equals_point_point(range::front(*it), range::back(*it)) )
+ if (! equals::equals_point_point(front_pt, back_pt))
{
- endpoints.push_back(range::front(*it));
- endpoints.push_back(range::back(*it));
+ // do not add points containing NaN coordinates
+ // because they cannot be reasonably compared, e.g. with MSVC
+ // an assertion failure is reported in std::equal_range()
+ // NOTE: currently ignoring_counter calling std::equal_range()
+ // is not used anywhere in the code, still it's safer this way
+ if (! geometry::has_nan_coordinate(front_pt))
+ {
+ endpoints.push_back(front_pt);
+ }
+ if (! geometry::has_nan_coordinate(back_pt))
+ {
+ endpoints.push_back(back_pt);
+ }
}
}
}
diff --git a/boost/geometry/algorithms/detail/relate/turns.hpp b/boost/geometry/algorithms/detail/relate/turns.hpp
index d54948e1f5..09d74dec3a 100644
--- a/boost/geometry/algorithms/detail/relate/turns.hpp
+++ b/boost/geometry/algorithms/detail/relate/turns.hpp
@@ -128,8 +128,8 @@ struct get_turns
template <int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0>
struct op_to_int
{
- template <typename SegmentRatio>
- inline int operator()(detail::overlay::turn_operation<SegmentRatio> const& op) const
+ template <typename Operation>
+ inline int operator()(Operation const& op) const
{
switch(op.operation)
{