// Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2014-2015, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP #include #include #include #include #include namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace is_valid { template < typename Geometry, order_selector Order = geometry::point_order::value, typename Tag = typename tag::type > struct acceptable_operation {}; template struct acceptable_operation { static const detail::overlay::operation_type value = detail::overlay::operation_union; }; template struct acceptable_operation { static const detail::overlay::operation_type value = detail::overlay::operation_intersection; }; template struct acceptable_operation { static const detail::overlay::operation_type value = detail::overlay::operation_intersection; }; template struct acceptable_operation { static const detail::overlay::operation_type value = detail::overlay::operation_union; }; template ::type> struct is_acceptable_turn {}; template struct is_acceptable_turn { template static inline bool apply(Turn const&) { return false; } }; template class is_acceptable_turn { protected: template static inline bool check_turn(Turn const& turn, Method method, Operation operation) { return turn.method == method && turn.operations[0].operation == operation && turn.operations[1].operation == operation; } public: template static inline bool apply(Turn const& turn) { using namespace detail::overlay; if ( turn.operations[0].seg_id.ring_index == turn.operations[1].seg_id.ring_index ) { return false; } operation_type const op = acceptable_operation::value; return check_turn(turn, method_touch_interior, op) || check_turn(turn, method_touch, op) ; } }; template class is_acceptable_turn : is_acceptable_turn::type> { private: typedef typename boost::range_value::type polygon; typedef is_acceptable_turn base; public: template static inline bool apply(Turn const& turn) { using namespace detail::overlay; if ( turn.operations[0].seg_id.multi_index == turn.operations[1].seg_id.multi_index ) { return base::apply(turn); } operation_type const op = acceptable_operation::value; if ( base::check_turn(turn, method_touch_interior, op) || base::check_turn(turn, method_touch, op)) { return true; } // Turn is acceptable only in case of a touch(interior) and both lines // (polygons) do not cross return (turn.method == method_touch || turn.method == method_touch_interior) && turn.touch_only; } }; }} // namespace detail::is_valid #endif // DOXYGEN_NO_DETAIL }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP