diff --git a/include/boost/geometry/algorithms/detail/is_simple/linear.hpp b/include/boost/geometry/algorithms/detail/is_simple/linear.hpp index 62f2393b4..c92e33413 100644 --- a/include/boost/geometry/algorithms/detail/is_simple/linear.hpp +++ b/include/boost/geometry/algorithms/detail/is_simple/linear.hpp @@ -75,34 +75,71 @@ template class is_simple_multilinestring { private: - template - static inline bool is_boundary_point_of(Point const& point, - Linestring const& linestring) + class is_acceptable_turn { - BOOST_ASSERT( boost::size(linestring) > 1 ); - return - !geometry::equals(range::front(linestring), - range::back(linestring)) - && - ( geometry::equals(point, range::front(linestring)) - || geometry::equals(point, range::back(linestring)) ); - } + private: + template + static inline bool is_boundary_point_of(Point const& point, + Linestring const& linestring) + { + BOOST_ASSERT( boost::size(linestring) > 1 ); + return + !geometry::equals(range::front(linestring), + range::back(linestring)) + && + ( geometry::equals(point, range::front(linestring)) + || geometry::equals(point, range::back(linestring)) ); + } - template - static inline bool have_same_boundary_points(Linestring1 const& ls1, - Linestring2 const& ls2) - { - return - geometry::equals(range::front(ls1), range::front(ls2)) - ? - geometry::equals(range::back(ls1), range::back(ls2)) - : - (geometry::equals(range::front(ls1), range::back(ls2)) - && - geometry::equals(range::back(ls1), range::front(ls2)) - ) - ; - } + template + static inline bool have_same_boundary_points(Linestring1 const& ls1, + Linestring2 const& ls2) + { + return + geometry::equals(range::front(ls1), range::front(ls2)) + ? + geometry::equals(range::back(ls1), range::back(ls2)) + : + (geometry::equals(range::front(ls1), range::back(ls2)) + && + geometry::equals(range::back(ls1), range::front(ls2)) + ) + ; + } + + public: + is_acceptable_turn(MultiLinestring const& multilinestring) + : m_multilinestring(multilinestring) + {} + + template + inline bool apply(Turn const& turn) const + { + typedef typename boost::range_value + < + MultiLinestring + >::type linestring; + + linestring const& ls1 = + range::at(m_multilinestring, + turn.operations[0].seg_id.multi_index); + + linestring const& ls2 = + range::at(m_multilinestring, + turn.operations[0].other_id.multi_index); + + return + is_boundary_point_of(turn.point, ls1) + && is_boundary_point_of(turn.point, ls2) + && + ( boost::size(ls1) != 2 + || boost::size(ls2) != 2 + || !have_same_boundary_points(ls1, ls2) ); + } + + private: + MultiLinestring const& m_multilinestring; + }; public: @@ -143,8 +180,11 @@ public: detail::disjoint::assign_disjoint_policy > turn_policy; - detail::self_get_turn_points::no_interrupt_policy - interrupt_policy; + is_acceptable_turn predicate(multilinestring); + detail::overlay::predicate_based_interrupt_policy + < + is_acceptable_turn + > interrupt_policy(predicate); detail::self_get_turn_points::get_turns < @@ -157,34 +197,7 @@ public: debug_print_turns(turns.begin(), turns.end()); debug_print_boundary_points(multilinestring); - // check if the generated turns are all boundary points of the - // linestrings in the multi-linestring - for (typename std::deque::const_iterator tit = turns.begin(); - tit != turns.end(); ++tit) - { - linestring const& ls1 = - range::at(multilinestring, - tit->operations[0].seg_id.multi_index); - - linestring const& ls2 = - range::at(multilinestring, - tit->operations[0].other_id.multi_index); - - if ( !is_boundary_point_of(tit->point, ls1) - || !is_boundary_point_of(tit->point, ls2) ) - { - return false; - } - - if ( boost::size(ls1) == 2 - && boost::size(ls2) == 2 - && have_same_boundary_points(ls1, ls2) ) - { - return false; - } - } - - return true; + return !interrupt_policy.has_intersections; } };