diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/relate')
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) { |