1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2014-2017, Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7 
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10 
11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP
12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP
13 
14 #include <vector>
15 
16 #include <boost/core/ignore_unused.hpp>
17 #include <boost/range.hpp>
18 
19 #include <boost/geometry/core/assert.hpp>
20 #include <boost/geometry/core/point_type.hpp>
21 
22 #include <boost/geometry/policies/predicate_based_interrupt_policy.hpp>
23 #include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
24 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
25 
26 #include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
27 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
28 #include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
29 
30 #include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
31 
32 namespace boost { namespace geometry
33 {
34 
35 
36 #ifndef DOXYGEN_NO_DETAIL
37 namespace detail { namespace is_valid
38 {
39 
40 
41 template
42 <
43     typename Geometry,
44     typename IsAcceptableTurn = is_acceptable_turn<Geometry>
45 >
46 class has_valid_self_turns
47 {
48 private:
49     typedef typename point_type<Geometry>::type point_type;
50 
51     typedef typename geometry::rescale_policy_type
52         <
53             point_type
54         >::type rescale_policy_type;
55 
56     typedef detail::overlay::get_turn_info
57         <
58             detail::overlay::assign_null_policy
59         > turn_policy;
60 
61 public:
62     typedef detail::overlay::turn_info
63         <
64             point_type,
65             typename geometry::segment_ratio_type
66                 <
67                     point_type,
68                     rescale_policy_type
69                 >::type
70         > turn_type;
71 
72     // returns true if all turns are valid
73     template <typename Turns, typename VisitPolicy, typename Strategy>
apply(Geometry const & geometry,Turns & turns,VisitPolicy & visitor,Strategy const & strategy)74     static inline bool apply(Geometry const& geometry,
75                              Turns& turns,
76                              VisitPolicy& visitor,
77                              Strategy const& strategy)
78     {
79         boost::ignore_unused(visitor);
80 
81         rescale_policy_type robust_policy
82             = geometry::get_rescale_policy<rescale_policy_type>(geometry);
83 
84         detail::overlay::stateless_predicate_based_interrupt_policy
85             <
86                 IsAcceptableTurn
87             > interrupt_policy;
88 
89         detail::self_get_turn_points::self_turns<false, turn_policy>(geometry,
90                                           strategy,
91                                           robust_policy,
92                                           turns,
93                                           interrupt_policy);
94 
95         if (interrupt_policy.has_intersections)
96         {
97             BOOST_GEOMETRY_ASSERT(! boost::empty(turns));
98             return visitor.template apply<failure_self_intersections>(turns);
99         }
100         else
101         {
102             return visitor.template apply<no_failure>();
103         }
104     }
105 
106     // returns true if all turns are valid
107     template <typename VisitPolicy, typename Strategy>
apply(Geometry const & geometry,VisitPolicy & visitor,Strategy const & strategy)108     static inline bool apply(Geometry const& geometry, VisitPolicy& visitor, Strategy const& strategy)
109     {
110         std::vector<turn_type> turns;
111         return apply(geometry, turns, visitor, strategy);
112     }
113 };
114 
115 
116 }} // namespace detail::is_valid
117 #endif // DOXYGEN_NO_DETAIL
118 
119 }} // namespace boost::geometry
120 
121 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP
122