1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2014-2015, Oracle and/or its affiliates.
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
10 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP
11 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP
13 #include <boost/range.hpp>
15 #include <boost/geometry/core/point_order.hpp>
16 #include <boost/geometry/core/tag.hpp>
17 #include <boost/geometry/core/tags.hpp>
19 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
22 namespace boost { namespace geometry
26 #ifndef DOXYGEN_NO_DETAIL
27 namespace detail { namespace is_valid
34 order_selector Order = geometry::point_order<Geometry>::value,
35 typename Tag = typename tag<Geometry>::type
37 struct acceptable_operation
40 template <typename Polygon>
41 struct acceptable_operation<Polygon, counterclockwise, polygon_tag>
43 static const detail::overlay::operation_type value =
44 detail::overlay::operation_union;
47 template <typename Polygon>
48 struct acceptable_operation<Polygon, clockwise, polygon_tag>
50 static const detail::overlay::operation_type value =
51 detail::overlay::operation_intersection;
54 template <typename MultiPolygon>
55 struct acceptable_operation<MultiPolygon, counterclockwise, multi_polygon_tag>
57 static const detail::overlay::operation_type value =
58 detail::overlay::operation_intersection;
61 template <typename MultiPolygon>
62 struct acceptable_operation<MultiPolygon, clockwise, multi_polygon_tag>
64 static const detail::overlay::operation_type value =
65 detail::overlay::operation_union;
71 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
72 struct is_acceptable_turn
75 template <typename Ring>
76 struct is_acceptable_turn<Ring, ring_tag>
78 template <typename Turn>
79 static inline bool apply(Turn const&)
85 template <typename Polygon>
86 class is_acceptable_turn<Polygon, polygon_tag>
89 template <typename Turn, typename Method, typename Operation>
90 static inline bool check_turn(Turn const& turn,
94 return turn.method == method
95 && turn.operations[0].operation == operation
96 && turn.operations[1].operation == operation;
101 template <typename Turn>
102 static inline bool apply(Turn const& turn)
104 using namespace detail::overlay;
106 if ( turn.operations[0].seg_id.ring_index
107 == turn.operations[1].seg_id.ring_index )
112 operation_type const op = acceptable_operation<Polygon>::value;
114 return check_turn(turn, method_touch_interior, op)
115 || check_turn(turn, method_touch, op)
120 template <typename MultiPolygon>
121 class is_acceptable_turn<MultiPolygon, multi_polygon_tag>
122 : is_acceptable_turn<typename boost::range_value<MultiPolygon>::type>
125 typedef typename boost::range_value<MultiPolygon>::type polygon;
126 typedef is_acceptable_turn<polygon> base;
129 template <typename Turn>
130 static inline bool apply(Turn const& turn)
132 using namespace detail::overlay;
134 if ( turn.operations[0].seg_id.multi_index
135 == turn.operations[1].seg_id.multi_index )
137 return base::apply(turn);
140 operation_type const op = acceptable_operation<MultiPolygon>::value;
142 return base::check_turn(turn, method_touch_interior, op)
143 || base::check_turn(turn, method_touch, op)
149 }} // namespace detail::is_valid
150 #endif // DOXYGEN_NO_DETAIL
152 }} // namespace boost::geometry
154 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP