]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | // Boost.Geometry |
b32b8144 | 2 | |
11fdf7f2 | 3 | // Copyright (c) 2014-2018, Oracle and/or its affiliates. |
b32b8144 FG |
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_INTERFACE_HPP | |
12 | #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_INTERFACE_HPP | |
13 | ||
14 | #include <sstream> | |
15 | #include <string> | |
16 | ||
17 | #include <boost/variant/apply_visitor.hpp> | |
18 | #include <boost/variant/static_visitor.hpp> | |
19 | #include <boost/variant/variant_fwd.hpp> | |
20 | ||
b32b8144 | 21 | #include <boost/geometry/algorithms/dispatch/is_valid.hpp> |
11fdf7f2 TL |
22 | #include <boost/geometry/core/cs.hpp> |
23 | #include <boost/geometry/geometries/concepts/check.hpp> | |
b32b8144 FG |
24 | #include <boost/geometry/policies/is_valid/default_policy.hpp> |
25 | #include <boost/geometry/policies/is_valid/failing_reason_policy.hpp> | |
26 | #include <boost/geometry/policies/is_valid/failure_type_policy.hpp> | |
27 | #include <boost/geometry/strategies/default_strategy.hpp> | |
28 | #include <boost/geometry/strategies/intersection.hpp> | |
29 | ||
30 | ||
31 | namespace boost { namespace geometry | |
32 | { | |
33 | ||
34 | namespace resolve_strategy | |
35 | { | |
36 | ||
37 | struct is_valid | |
38 | { | |
39 | template <typename Geometry, typename VisitPolicy, typename Strategy> | |
40 | static inline bool apply(Geometry const& geometry, | |
41 | VisitPolicy& visitor, | |
42 | Strategy const& strategy) | |
43 | { | |
44 | return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy); | |
45 | } | |
46 | ||
47 | template <typename Geometry, typename VisitPolicy> | |
48 | static inline bool apply(Geometry const& geometry, | |
49 | VisitPolicy& visitor, | |
50 | default_strategy) | |
51 | { | |
52 | // NOTE: Currently the strategy is only used for Areal geometries | |
53 | typedef typename strategy::intersection::services::default_strategy | |
54 | < | |
55 | typename cs_tag<Geometry>::type | |
56 | >::type strategy_type; | |
57 | ||
58 | return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy_type()); | |
59 | } | |
60 | }; | |
61 | ||
62 | } // namespace resolve_strategy | |
63 | ||
64 | namespace resolve_variant | |
65 | { | |
66 | ||
67 | template <typename Geometry> | |
68 | struct is_valid | |
69 | { | |
70 | template <typename VisitPolicy, typename Strategy> | |
71 | static inline bool apply(Geometry const& geometry, | |
72 | VisitPolicy& visitor, | |
73 | Strategy const& strategy) | |
74 | { | |
75 | concepts::check<Geometry const>(); | |
76 | ||
77 | return resolve_strategy::is_valid::apply(geometry, visitor, strategy); | |
78 | } | |
79 | }; | |
80 | ||
81 | template <BOOST_VARIANT_ENUM_PARAMS(typename T)> | |
82 | struct is_valid<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > | |
83 | { | |
84 | template <typename VisitPolicy, typename Strategy> | |
85 | struct visitor : boost::static_visitor<bool> | |
86 | { | |
87 | visitor(VisitPolicy& policy, Strategy const& strategy) | |
88 | : m_policy(policy) | |
89 | , m_strategy(strategy) | |
90 | {} | |
91 | ||
92 | template <typename Geometry> | |
93 | bool operator()(Geometry const& geometry) const | |
94 | { | |
95 | return is_valid<Geometry>::apply(geometry, m_policy, m_strategy); | |
96 | } | |
97 | ||
98 | VisitPolicy& m_policy; | |
99 | Strategy const& m_strategy; | |
100 | }; | |
101 | ||
102 | template <typename VisitPolicy, typename Strategy> | |
103 | static inline bool | |
104 | apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry, | |
105 | VisitPolicy& policy_visitor, | |
106 | Strategy const& strategy) | |
107 | { | |
108 | return boost::apply_visitor(visitor<VisitPolicy, Strategy>(policy_visitor, strategy), | |
109 | geometry); | |
110 | } | |
111 | }; | |
112 | ||
113 | } // namespace resolve_variant | |
114 | ||
115 | ||
116 | // Undocumented for now | |
117 | template <typename Geometry, typename VisitPolicy, typename Strategy> | |
118 | inline bool is_valid(Geometry const& geometry, | |
119 | VisitPolicy& visitor, | |
120 | Strategy const& strategy) | |
121 | { | |
122 | return resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy); | |
123 | } | |
124 | ||
125 | ||
126 | /*! | |
127 | \brief \brief_check{is valid (in the OGC sense)} | |
128 | \ingroup is_valid | |
129 | \tparam Geometry \tparam_geometry | |
130 | \tparam Strategy \tparam_strategy{Is_valid} | |
131 | \param geometry \param_geometry | |
132 | \param strategy \param_strategy{is_valid} | |
133 | \return \return_check{is valid (in the OGC sense); | |
134 | furthermore, the following geometries are considered valid: | |
135 | multi-geometries with no elements, | |
136 | linear geometries containing spikes, | |
137 | areal geometries with duplicate (consecutive) points} | |
138 | ||
139 | \qbk{distinguish,with strategy} | |
140 | \qbk{[include reference/algorithms/is_valid.qbk]} | |
141 | */ | |
142 | template <typename Geometry, typename Strategy> | |
143 | inline bool is_valid(Geometry const& geometry, Strategy const& strategy) | |
144 | { | |
145 | is_valid_default_policy<> visitor; | |
146 | return resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy); | |
147 | } | |
148 | ||
149 | /*! | |
150 | \brief \brief_check{is valid (in the OGC sense)} | |
151 | \ingroup is_valid | |
152 | \tparam Geometry \tparam_geometry | |
153 | \param geometry \param_geometry | |
154 | \return \return_check{is valid (in the OGC sense); | |
155 | furthermore, the following geometries are considered valid: | |
156 | multi-geometries with no elements, | |
157 | linear geometries containing spikes, | |
158 | areal geometries with duplicate (consecutive) points} | |
159 | ||
160 | \qbk{[include reference/algorithms/is_valid.qbk]} | |
161 | */ | |
162 | template <typename Geometry> | |
163 | inline bool is_valid(Geometry const& geometry) | |
164 | { | |
165 | return is_valid(geometry, default_strategy()); | |
166 | } | |
167 | ||
168 | ||
169 | /*! | |
170 | \brief \brief_check{is valid (in the OGC sense)} | |
171 | \ingroup is_valid | |
172 | \tparam Geometry \tparam_geometry | |
173 | \tparam Strategy \tparam_strategy{Is_valid} | |
174 | \param geometry \param_geometry | |
175 | \param failure An enumeration value indicating that the geometry is | |
176 | valid or not, and if not valid indicating the reason why | |
177 | \param strategy \param_strategy{is_valid} | |
178 | \return \return_check{is valid (in the OGC sense); | |
179 | furthermore, the following geometries are considered valid: | |
180 | multi-geometries with no elements, | |
181 | linear geometries containing spikes, | |
182 | areal geometries with duplicate (consecutive) points} | |
183 | ||
184 | \qbk{distinguish,with failure value and strategy} | |
185 | \qbk{[include reference/algorithms/is_valid_with_failure.qbk]} | |
186 | */ | |
187 | template <typename Geometry, typename Strategy> | |
188 | inline bool is_valid(Geometry const& geometry, validity_failure_type& failure, Strategy const& strategy) | |
189 | { | |
190 | failure_type_policy<> visitor; | |
191 | bool result = resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy); | |
192 | failure = visitor.failure(); | |
193 | return result; | |
194 | } | |
195 | ||
196 | /*! | |
197 | \brief \brief_check{is valid (in the OGC sense)} | |
198 | \ingroup is_valid | |
199 | \tparam Geometry \tparam_geometry | |
200 | \param geometry \param_geometry | |
201 | \param failure An enumeration value indicating that the geometry is | |
202 | valid or not, and if not valid indicating the reason why | |
203 | \return \return_check{is valid (in the OGC sense); | |
204 | furthermore, the following geometries are considered valid: | |
205 | multi-geometries with no elements, | |
206 | linear geometries containing spikes, | |
207 | areal geometries with duplicate (consecutive) points} | |
208 | ||
209 | \qbk{distinguish,with failure value} | |
210 | \qbk{[include reference/algorithms/is_valid_with_failure.qbk]} | |
211 | */ | |
212 | template <typename Geometry> | |
213 | inline bool is_valid(Geometry const& geometry, validity_failure_type& failure) | |
214 | { | |
215 | return is_valid(geometry, failure, default_strategy()); | |
216 | } | |
217 | ||
218 | ||
219 | /*! | |
220 | \brief \brief_check{is valid (in the OGC sense)} | |
221 | \ingroup is_valid | |
222 | \tparam Geometry \tparam_geometry | |
223 | \tparam Strategy \tparam_strategy{Is_valid} | |
224 | \param geometry \param_geometry | |
225 | \param message A string containing a message stating if the geometry | |
226 | is valid or not, and if not valid a reason why | |
227 | \param strategy \param_strategy{is_valid} | |
228 | \return \return_check{is valid (in the OGC sense); | |
229 | furthermore, the following geometries are considered valid: | |
230 | multi-geometries with no elements, | |
231 | linear geometries containing spikes, | |
232 | areal geometries with duplicate (consecutive) points} | |
233 | ||
234 | \qbk{distinguish,with message and strategy} | |
235 | \qbk{[include reference/algorithms/is_valid_with_message.qbk]} | |
236 | */ | |
237 | template <typename Geometry, typename Strategy> | |
238 | inline bool is_valid(Geometry const& geometry, std::string& message, Strategy const& strategy) | |
239 | { | |
240 | std::ostringstream stream; | |
241 | failing_reason_policy<> visitor(stream); | |
242 | bool result = resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy); | |
243 | message = stream.str(); | |
244 | return result; | |
245 | } | |
246 | ||
247 | /*! | |
248 | \brief \brief_check{is valid (in the OGC sense)} | |
249 | \ingroup is_valid | |
250 | \tparam Geometry \tparam_geometry | |
251 | \param geometry \param_geometry | |
252 | \param message A string containing a message stating if the geometry | |
253 | is valid or not, and if not valid a reason why | |
254 | \return \return_check{is valid (in the OGC sense); | |
255 | furthermore, the following geometries are considered valid: | |
256 | multi-geometries with no elements, | |
257 | linear geometries containing spikes, | |
258 | areal geometries with duplicate (consecutive) points} | |
259 | ||
260 | \qbk{distinguish,with message} | |
261 | \qbk{[include reference/algorithms/is_valid_with_message.qbk]} | |
262 | */ | |
263 | template <typename Geometry> | |
264 | inline bool is_valid(Geometry const& geometry, std::string& message) | |
265 | { | |
266 | return is_valid(geometry, message, default_strategy()); | |
267 | } | |
268 | ||
269 | ||
270 | }} // namespace boost::geometry | |
271 | ||
272 | #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_INTERFACE_HPP |