]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/distance/interface.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / distance / interface.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
6 // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
7 // Copyright (c) 2014 Samuel Debionne, Grenoble, France.
8
9 // This file was modified by Oracle on 2014.
10 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
11
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
13
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
16
17 // Use, modification and distribution is subject to the Boost Software License,
18 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
19 // http://www.boost.org/LICENSE_1_0.txt)
20
21 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP
22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP
23
24 #include <boost/concept_check.hpp>
25
26 #include <boost/mpl/always.hpp>
27 #include <boost/mpl/bool.hpp>
28 #include <boost/mpl/vector.hpp>
29
30 #include <boost/geometry/core/point_type.hpp>
31
32 #include <boost/geometry/geometries/concepts/check.hpp>
33
34 #include <boost/geometry/strategies/default_strategy.hpp>
35 #include <boost/geometry/strategies/distance.hpp>
36 #include <boost/geometry/strategies/default_distance_result.hpp>
37 #include <boost/geometry/strategies/distance_result.hpp>
38
39 #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
40 #include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
41
42 #include <boost/geometry/algorithms/dispatch/distance.hpp>
43
44
45 namespace boost { namespace geometry
46 {
47
48
49 #ifndef DOXYGEN_NO_DISPATCH
50 namespace dispatch
51 {
52
53
54 // If reversal is needed, perform it
55 template
56 <
57 typename Geometry1, typename Geometry2, typename Strategy,
58 typename Tag1, typename Tag2, typename StrategyTag
59 >
60 struct distance
61 <
62 Geometry1, Geometry2, Strategy,
63 Tag1, Tag2, StrategyTag,
64 true
65 >
66 : distance<Geometry2, Geometry1, Strategy, Tag2, Tag1, StrategyTag, false>
67 {
68 typedef typename strategy::distance::services::return_type
69 <
70 Strategy,
71 typename point_type<Geometry2>::type,
72 typename point_type<Geometry1>::type
73 >::type return_type;
74
75 static inline return_type apply(
76 Geometry1 const& g1,
77 Geometry2 const& g2,
78 Strategy const& strategy)
79 {
80 return distance
81 <
82 Geometry2, Geometry1, Strategy,
83 Tag2, Tag1, StrategyTag,
84 false
85 >::apply(g2, g1, strategy);
86 }
87 };
88
89
90 } // namespace dispatch
91 #endif // DOXYGEN_NO_DISPATCH
92
93
94 namespace resolve_strategy
95 {
96
97 struct distance
98 {
99 template <typename Geometry1, typename Geometry2, typename Strategy>
100 static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
101 apply(Geometry1 const& geometry1,
102 Geometry2 const& geometry2,
103 Strategy const& strategy)
104 {
105 return dispatch::distance
106 <
107 Geometry1, Geometry2, Strategy
108 >::apply(geometry1, geometry2, strategy);
109 }
110
111 template <typename Geometry1, typename Geometry2>
112 static inline
113 typename distance_result<Geometry1, Geometry2, default_strategy>::type
114 apply(Geometry1 const& geometry1,
115 Geometry2 const& geometry2,
116 default_strategy)
117 {
118 typedef typename detail::distance::default_strategy
119 <
120 Geometry1, Geometry2
121 >::type strategy_type;
122
123 return dispatch::distance
124 <
125 Geometry1, Geometry2, strategy_type
126 >::apply(geometry1, geometry2, strategy_type());
127 }
128 };
129
130 } // namespace resolve_strategy
131
132
133 namespace resolve_variant
134 {
135
136
137 template <typename Geometry1, typename Geometry2>
138 struct distance
139 {
140 template <typename Strategy>
141 static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
142 apply(Geometry1 const& geometry1,
143 Geometry2 const& geometry2,
144 Strategy const& strategy)
145 {
146 return
147 resolve_strategy::distance::apply(geometry1, geometry2, strategy);
148 }
149 };
150
151
152 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
153 struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
154 {
155 template <typename Strategy>
156 struct visitor: static_visitor
157 <
158 typename distance_result
159 <
160 variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
161 Geometry2,
162 Strategy
163 >::type
164 >
165 {
166 Geometry2 const& m_geometry2;
167 Strategy const& m_strategy;
168
169 visitor(Geometry2 const& geometry2,
170 Strategy const& strategy)
171 : m_geometry2(geometry2),
172 m_strategy(strategy)
173 {}
174
175 template <typename Geometry1>
176 typename distance_result<Geometry1, Geometry2, Strategy>::type
177 operator()(Geometry1 const& geometry1) const
178 {
179 return distance
180 <
181 Geometry1,
182 Geometry2
183 >::template apply
184 <
185 Strategy
186 >(geometry1, m_geometry2, m_strategy);
187 }
188 };
189
190 template <typename Strategy>
191 static inline typename distance_result
192 <
193 variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
194 Geometry2,
195 Strategy
196 >::type
197 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
198 Geometry2 const& geometry2,
199 Strategy const& strategy)
200 {
201 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
202 }
203 };
204
205
206 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
207 struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
208 {
209 template <typename Strategy>
210 struct visitor: static_visitor
211 <
212 typename distance_result
213 <
214 Geometry1,
215 variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
216 Strategy
217 >::type
218 >
219 {
220 Geometry1 const& m_geometry1;
221 Strategy const& m_strategy;
222
223 visitor(Geometry1 const& geometry1,
224 Strategy const& strategy)
225 : m_geometry1(geometry1),
226 m_strategy(strategy)
227 {}
228
229 template <typename Geometry2>
230 typename distance_result<Geometry1, Geometry2, Strategy>::type
231 operator()(Geometry2 const& geometry2) const
232 {
233 return distance
234 <
235 Geometry1,
236 Geometry2
237 >::template apply
238 <
239 Strategy
240 >(m_geometry1, geometry2, m_strategy);
241 }
242 };
243
244 template <typename Strategy>
245 static inline typename distance_result
246 <
247 Geometry1,
248 variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
249 Strategy
250 >::type
251 apply(
252 Geometry1 const& geometry1,
253 const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
254 Strategy const& strategy)
255 {
256 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
257 }
258 };
259
260
261 template
262 <
263 BOOST_VARIANT_ENUM_PARAMS(typename T1),
264 BOOST_VARIANT_ENUM_PARAMS(typename T2)
265 >
266 struct distance
267 <
268 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
269 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
270 >
271 {
272 template <typename Strategy>
273 struct visitor: static_visitor
274 <
275 typename distance_result
276 <
277 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
278 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
279 Strategy
280 >::type
281 >
282 {
283 Strategy const& m_strategy;
284
285 visitor(Strategy const& strategy)
286 : m_strategy(strategy)
287 {}
288
289 template <typename Geometry1, typename Geometry2>
290 typename distance_result<Geometry1, Geometry2, Strategy>::type
291 operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const
292 {
293 return distance
294 <
295 Geometry1,
296 Geometry2
297 >::template apply
298 <
299 Strategy
300 >(geometry1, geometry2, m_strategy);
301 }
302 };
303
304 template <typename Strategy>
305 static inline typename distance_result
306 <
307 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
308 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
309 Strategy
310 >::type
311 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
312 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
313 Strategy const& strategy)
314 {
315 return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
316 }
317 };
318
319 } // namespace resolve_variant
320
321
322 /*!
323 \brief \brief_calc2{distance} \brief_strategy
324 \ingroup distance
325 \details
326 \details \details_calc{area}. \brief_strategy. \details_strategy_reasons
327
328 \tparam Geometry1 \tparam_geometry
329 \tparam Geometry2 \tparam_geometry
330 \tparam Strategy \tparam_strategy{Distance}
331 \param geometry1 \param_geometry
332 \param geometry2 \param_geometry
333 \param strategy \param_strategy{distance}
334 \return \return_calc{distance}
335 \note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
336 it may also be a point-segment strategy.
337
338 \qbk{distinguish,with strategy}
339
340 \qbk{
341 [heading Available Strategies]
342 \* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)]
343 \* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)]
344 \* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)]
345 \* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)]
346 \* more (currently extensions): Vincenty\, Andoyer (geographic)
347 }
348 */
349
350 /*
351 Note, in case of a Compilation Error:
352 if you get:
353 - "Failed to specialize function template ..."
354 - "error: no matching function for call to ..."
355 for distance, it is probably so that there is no specialization
356 for return_type<...> for your strategy.
357 */
358 template <typename Geometry1, typename Geometry2, typename Strategy>
359 inline typename distance_result<Geometry1, Geometry2, Strategy>::type
360 distance(Geometry1 const& geometry1,
361 Geometry2 const& geometry2,
362 Strategy const& strategy)
363 {
364 concepts::check<Geometry1 const>();
365 concepts::check<Geometry2 const>();
366
367 detail::throw_on_empty_input(geometry1);
368 detail::throw_on_empty_input(geometry2);
369
370 return resolve_variant::distance
371 <
372 Geometry1,
373 Geometry2
374 >::apply(geometry1, geometry2, strategy);
375 }
376
377
378 /*!
379 \brief \brief_calc2{distance}
380 \ingroup distance
381 \details The default strategy is used, corresponding to the coordinate system of the geometries
382 \tparam Geometry1 \tparam_geometry
383 \tparam Geometry2 \tparam_geometry
384 \param geometry1 \param_geometry
385 \param geometry2 \param_geometry
386 \return \return_calc{distance}
387
388 \qbk{[include reference/algorithms/distance.qbk]}
389 */
390 template <typename Geometry1, typename Geometry2>
391 inline typename default_distance_result<Geometry1, Geometry2>::type
392 distance(Geometry1 const& geometry1,
393 Geometry2 const& geometry2)
394 {
395 concepts::check<Geometry1 const>();
396 concepts::check<Geometry2 const>();
397
398 return geometry::distance(geometry1, geometry2, default_strategy());
399 }
400
401 }} // namespace boost::geometry
402
403 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP