Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / geometry / algorithms / detail / is_valid / has_valid_self_turns.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2014-2019, 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/algorithms/detail/is_valid/is_acceptable_turn.hpp>
20 #include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
21 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
22 #include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
23 #include <boost/geometry/algorithms/validity_failure_type.hpp>
24
25 #include <boost/geometry/core/assert.hpp>
26 #include <boost/geometry/core/point_type.hpp>
27
28 #include <boost/geometry/policies/predicate_based_interrupt_policy.hpp>
29 #include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
30 #include <boost/geometry/policies/robustness/get_rescale_policy.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 CSTag
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             CSTag
55         >::type rescale_policy_type;
56
57     typedef detail::overlay::get_turn_info
58         <
59             detail::overlay::assign_null_policy
60         > turn_policy;
61
62 public:
63     typedef detail::overlay::turn_info
64         <
65             point_type,
66             typename segment_ratio_type
67                 <
68                     point_type,
69                     rescale_policy_type
70                 >::type
71         > turn_type;
72
73     // returns true if all turns are valid
74     template <typename Turns, typename VisitPolicy, typename Strategy>
75     static inline bool apply(Geometry const& geometry,
76                              Turns& turns,
77                              VisitPolicy& visitor,
78                              Strategy const& strategy)
79     {
80         boost::ignore_unused(visitor);
81
82         rescale_policy_type robust_policy
83             = geometry::get_rescale_policy<rescale_policy_type>(geometry, strategy);
84
85         detail::overlay::stateless_predicate_based_interrupt_policy
86             <
87                 is_acceptable_turn<Geometry>
88             > interrupt_policy;
89
90         // Calculate self-turns, skipping adjacent segments
91         detail::self_get_turn_points::self_turns<false, turn_policy>(geometry,
92                                           strategy,
93                                           robust_policy,
94                                           turns,
95                                           interrupt_policy,
96                                           0, true);
97
98         if (interrupt_policy.has_intersections)
99         {
100             BOOST_GEOMETRY_ASSERT(! boost::empty(turns));
101             return visitor.template apply<failure_self_intersections>(turns);
102         }
103         else
104         {
105             return visitor.template apply<no_failure>();
106         }
107     }
108
109     // returns true if all turns are valid
110     template <typename VisitPolicy, typename Strategy>
111     static inline bool apply(Geometry const& geometry, VisitPolicy& visitor, Strategy const& strategy)
112     {
113         std::vector<turn_type> turns;
114         return apply(geometry, turns, visitor, strategy);
115     }
116 };
117
118
119 }} // namespace detail::is_valid
120 #endif // DOXYGEN_NO_DETAIL
121
122 }} // namespace boost::geometry
123
124 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP