]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / policies / is_valid / failing_reason_policy.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2015, 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_POLICIES_IS_VALID_FAILING_REASON_POLICY_HPP
12 #define BOOST_GEOMETRY_POLICIES_IS_VALID_FAILING_REASON_POLICY_HPP
13
14 #include <sstream>
15
16 #include <boost/geometry/io/dsv/write.hpp>
17 #include <boost/geometry/util/condition.hpp>
18 #include <boost/geometry/util/range.hpp>
19 #include <boost/geometry/algorithms/validity_failure_type.hpp>
20 #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
21
22
23 namespace boost { namespace geometry
24 {
25
26
27 inline char const* validity_failure_type_message(validity_failure_type failure)
28 {
29 switch (failure)
30 {
31 case no_failure:
32 return "Geometry is valid";
33 case failure_few_points:
34 return "Geometry has too few points";
35 case failure_wrong_topological_dimension:
36 return "Geometry has wrong topological dimension";
37 case failure_not_closed:
38 return "Geometry is defined as closed but is open";
39 case failure_spikes:
40 return "Geometry has spikes";
41 case failure_self_intersections:
42 return "Geometry has invalid self-intersections";
43 case failure_wrong_orientation:
44 return "Geometry has wrong orientation";
45 case failure_interior_rings_outside:
46 return "Geometry has interior rings defined outside the outer boundary";
47 case failure_nested_interior_rings:
48 return "Geometry has nested interior rings";
49 case failure_disconnected_interior:
50 return "Geometry has disconnected interior";
51 case failure_intersecting_interiors:
52 return "Multi-polygon has intersecting interiors";
53 case failure_duplicate_points:
54 return "Geometry has duplicate (consecutive) points";
55 case failure_wrong_corner_order:
56 return "Box has corners in wrong order";
57 case failure_invalid_coordinate:
58 return "Geometry has point(s) with invalid coordinate(s)";
59 default: // to avoid -Wreturn-type warning
60 return "";
61 }
62 }
63
64
65 template <bool AllowDuplicates = true, bool AllowSpikes = true>
66 class failing_reason_policy
67 {
68 private:
69 static inline
70 validity_failure_type transform_failure_type(validity_failure_type failure)
71 {
72 if (BOOST_GEOMETRY_CONDITION(
73 AllowDuplicates && failure == failure_duplicate_points))
74 {
75 return no_failure;
76 }
77 return failure;
78 }
79
80 static inline
81 validity_failure_type transform_failure_type(validity_failure_type failure,
82 bool is_linear)
83 {
84 if (BOOST_GEOMETRY_CONDITION(
85 is_linear && AllowSpikes && failure == failure_spikes))
86 {
87 return no_failure;
88 }
89 return transform_failure_type(failure);
90 }
91
92 inline void set_failure_message(validity_failure_type failure)
93 {
94 m_oss.str("");
95 m_oss.clear();
96 m_oss << validity_failure_type_message(failure);
97 }
98
99 template
100 <
101 validity_failure_type Failure,
102 typename Data1,
103 typename Data2 = Data1,
104 typename Dummy = void
105 >
106 struct process_data
107 {
108 static inline void apply(std::ostringstream&, Data1 const&)
109 {
110 }
111
112 static inline void apply(std::ostringstream&,
113 Data1 const&,
114 Data2 const&)
115 {
116 }
117 };
118
119 template <typename SpikePoint>
120 struct process_data<failure_spikes, bool, SpikePoint>
121 {
122 static inline void apply(std::ostringstream& oss,
123 bool is_linear,
124 SpikePoint const& spike_point)
125 {
126 if (BOOST_GEOMETRY_CONDITION(is_linear && AllowSpikes))
127 {
128 return;
129 }
130
131 oss << ". A spike point was found with apex at "
132 << geometry::dsv(spike_point);
133 }
134 };
135
136 template <typename Turns>
137 struct process_data<failure_self_intersections, Turns>
138 {
139 static inline
140 void apply_to_segment_identifier(std::ostringstream& oss,
141 segment_identifier seg_id)
142 {
143 oss << "{" << seg_id.source_index
144 << ", " << seg_id.multi_index
145 << ", " << seg_id.ring_index
146 << ", " << seg_id.segment_index
147 << "}";
148 }
149
150 static inline void apply(std::ostringstream& oss,
151 Turns const& turns)
152 {
153 typedef typename boost::range_value<Turns>::type turn_type;
154 turn_type const& turn = range::front(turns);
155 oss << ". A self-intersection point was found at "
156 << geometry::dsv(turn.point);
157
158 oss << "; method: " << method_char(turn.method)
159 << "; operations: "
160 << operation_char(turn.operations[0].operation)
161 << "/"
162 << operation_char(turn.operations[1].operation)
163 << "; segment IDs {source, multi, ring, segment}: ";
164 apply_to_segment_identifier(oss, turn.operations[0].seg_id);
165 oss << "/";
166 apply_to_segment_identifier(oss, turn.operations[1].seg_id);
167 }
168 };
169
170 template <typename Point>
171 struct process_data<failure_duplicate_points, Point>
172 {
173 static inline void apply(std::ostringstream& oss,
174 Point const& point)
175 {
176 if (BOOST_GEOMETRY_CONDITION(AllowDuplicates))
177 {
178 return;
179 }
180 oss << ". Duplicate points were found near point "
181 << geometry::dsv(point);
182 }
183 };
184
185 public:
186 failing_reason_policy(std::ostringstream& oss)
187 : m_oss(oss)
188 {}
189
190 template <validity_failure_type Failure>
191 inline bool apply()
192 {
193 validity_failure_type const failure = transform_failure_type(Failure);
194 set_failure_message(failure);
195 return failure == no_failure;
196 }
197
198 template <validity_failure_type Failure, typename Data>
199 inline bool apply(Data const& data)
200 {
201 validity_failure_type const failure = transform_failure_type(Failure);
202 set_failure_message(failure);
203 process_data<Failure, Data>::apply(m_oss, data);
204 return failure == no_failure;
205 }
206
207 template <validity_failure_type Failure, typename Data1, typename Data2>
208 inline bool apply(Data1 const& data1, Data2 const& data2)
209 {
210 validity_failure_type const failure
211 = transform_failure_type(Failure, data1);
212 set_failure_message(failure);
213 process_data<Failure, Data1, Data2>::apply(m_oss, data1, data2);
214 return failure == no_failure;
215 }
216
217 private:
218 std::ostringstream& m_oss;
219 };
220
221
222 }} // namespace boost::geometry
223
224 #endif // BOOST_GEOMETRY_POLICIES_IS_VALID_FAILING_REASON_POLICY_HPP