]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/is_valid/linear.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / is_valid / linear.hpp
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_LINEAR_HPP
12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_LINEAR_HPP
13
14 #include <cstddef>
15
16 #include <boost/range.hpp>
17
18 #include <boost/geometry/core/closure.hpp>
19 #include <boost/geometry/core/point_type.hpp>
20 #include <boost/geometry/core/tags.hpp>
21
22 #include <boost/geometry/util/condition.hpp>
23 #include <boost/geometry/util/range.hpp>
24
25 #include <boost/geometry/algorithms/equals.hpp>
26 #include <boost/geometry/algorithms/validity_failure_type.hpp>
27 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
28 #include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp>
29 #include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp>
30 #include <boost/geometry/algorithms/detail/num_distinct_consecutive_points.hpp>
31
32 #include <boost/geometry/algorithms/dispatch/is_valid.hpp>
33
34
35 namespace boost { namespace geometry
36 {
37
38 #ifndef DOXYGEN_NO_DETAIL
39 namespace detail { namespace is_valid
40 {
41
42
43 template <typename Linestring>
44 struct is_valid_linestring
45 {
46 template <typename VisitPolicy, typename Strategy>
47 static inline bool apply(Linestring const& linestring,
48 VisitPolicy& visitor,
49 Strategy const& strategy)
50 {
51 if (has_invalid_coordinate<Linestring>::apply(linestring, visitor))
52 {
53 return false;
54 }
55
56 if (boost::size(linestring) < 2)
57 {
58 return visitor.template apply<failure_few_points>();
59 }
60
61 std::size_t num_distinct = detail::num_distinct_consecutive_points
62 <
63 Linestring,
64 3u,
65 true,
66 not_equal_to<typename point_type<Linestring>::type>
67 >::apply(linestring);
68
69 if (num_distinct < 2u)
70 {
71 return
72 visitor.template apply<failure_wrong_topological_dimension>();
73 }
74
75 if (num_distinct == 2u)
76 {
77 return visitor.template apply<no_failure>();
78 }
79
80 return ! has_spikes
81 <
82 Linestring, closed
83 >::apply(linestring, visitor,
84 strategy.get_side_strategy());
85 }
86 };
87
88
89 }} // namespace detail::is_valid
90 #endif // DOXYGEN_NO_DETAIL
91
92
93
94
95 #ifndef DOXYGEN_NO_DISPATCH
96 namespace dispatch
97 {
98
99
100 // A linestring is a curve.
101 // A curve is 1-dimensional so it has to have at least two distinct
102 // points.
103 // A curve is simple if it does not pass through the same point twice,
104 // with the possible exception of its two endpoints
105 //
106 // There is an option here as to whether spikes are allowed for linestrings;
107 // here we pass this as an additional template parameter: allow_spikes
108 // If allow_spikes is set to true, spikes are allowed, false otherwise.
109 // By default, spikes are disallowed
110 //
111 // Reference: OGC 06-103r4 (6.1.6.1)
112 template <typename Linestring, bool AllowEmptyMultiGeometries>
113 struct is_valid
114 <
115 Linestring, linestring_tag, AllowEmptyMultiGeometries
116 > : detail::is_valid::is_valid_linestring<Linestring>
117 {};
118
119
120 // A MultiLinestring is a MultiCurve
121 // A MultiCurve is simple if all of its elements are simple and the
122 // only intersections between any two elements occur at Points that
123 // are on the boundaries of both elements.
124 //
125 // Reference: OGC 06-103r4 (6.1.8.1; Fig. 9)
126 template <typename MultiLinestring, bool AllowEmptyMultiGeometries>
127 class is_valid
128 <
129 MultiLinestring, multi_linestring_tag, AllowEmptyMultiGeometries
130 >
131 {
132 private:
133 template <typename VisitPolicy, typename Strategy>
134 struct per_linestring
135 {
136 per_linestring(VisitPolicy& policy, Strategy const& strategy)
137 : m_policy(policy)
138 , m_strategy(strategy)
139 {}
140
141 template <typename Linestring>
142 inline bool apply(Linestring const& linestring) const
143 {
144 return detail::is_valid::is_valid_linestring
145 <
146 Linestring
147 >::apply(linestring, m_policy, m_strategy);
148 }
149
150 VisitPolicy& m_policy;
151 Strategy const& m_strategy;
152 };
153
154 public:
155 template <typename VisitPolicy, typename Strategy>
156 static inline bool apply(MultiLinestring const& multilinestring,
157 VisitPolicy& visitor,
158 Strategy const& strategy)
159 {
160 if (BOOST_GEOMETRY_CONDITION(
161 AllowEmptyMultiGeometries && boost::empty(multilinestring)))
162 {
163 return visitor.template apply<no_failure>();
164 }
165
166 typedef per_linestring<VisitPolicy, Strategy> per_ls;
167
168 return detail::check_iterator_range
169 <
170 per_ls,
171 false // do not check for empty multilinestring (done above)
172 >::apply(boost::begin(multilinestring),
173 boost::end(multilinestring),
174 per_ls(visitor, strategy));
175 }
176 };
177
178
179 } // namespace dispatch
180 #endif // DOXYGEN_NO_DISPATCH
181
182
183 }} // namespace boost::geometry
184
185
186 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_LINEAR_HPP