]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/algorithms/detail/distance/interface.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / distance / interface.hpp
CommitLineData
7c673cae
FG
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
1e59de90
TL
9// This file was modified by Oracle on 2014-2021.
10// Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
7c673cae 11// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
92f5a8d4 12// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7c673cae
FG
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
1e59de90
TL
26#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
27#include <boost/geometry/algorithms/dispatch/distance.hpp>
28
7c673cae 29#include <boost/geometry/core/point_type.hpp>
1e59de90 30#include <boost/geometry/core/visit.hpp>
7c673cae 31
1e59de90 32#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
7c673cae
FG
33#include <boost/geometry/geometries/concepts/check.hpp>
34
1e59de90 35// TODO: move these to algorithms
7c673cae
FG
36#include <boost/geometry/strategies/default_distance_result.hpp>
37#include <boost/geometry/strategies/distance_result.hpp>
38
1e59de90
TL
39#include <boost/geometry/strategies/default_strategy.hpp>
40#include <boost/geometry/strategies/detail.hpp>
41#include <boost/geometry/strategies/distance/services.hpp>
7c673cae
FG
42
43
44namespace boost { namespace geometry
45{
46
47
48#ifndef DOXYGEN_NO_DISPATCH
49namespace dispatch
50{
51
52
53// If reversal is needed, perform it
54template
55<
56 typename Geometry1, typename Geometry2, typename Strategy,
57 typename Tag1, typename Tag2, typename StrategyTag
58>
59struct distance
60<
61 Geometry1, Geometry2, Strategy,
62 Tag1, Tag2, StrategyTag,
63 true
64>
65 : distance<Geometry2, Geometry1, Strategy, Tag2, Tag1, StrategyTag, false>
66{
1e59de90
TL
67 static inline auto apply(Geometry1 const& g1, Geometry2 const& g2,
68 Strategy const& strategy)
7c673cae
FG
69 {
70 return distance
71 <
72 Geometry2, Geometry1, Strategy,
73 Tag2, Tag1, StrategyTag,
74 false
75 >::apply(g2, g1, strategy);
76 }
77};
78
79
80} // namespace dispatch
81#endif // DOXYGEN_NO_DISPATCH
82
83
84namespace resolve_strategy
85{
86
1e59de90
TL
87template
88<
89 typename Strategy,
90 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
91>
7c673cae
FG
92struct distance
93{
92f5a8d4 94 template <typename Geometry1, typename Geometry2>
1e59de90
TL
95 static inline auto apply(Geometry1 const& geometry1,
96 Geometry2 const& geometry2,
97 Strategy const& strategy)
7c673cae
FG
98 {
99 return dispatch::distance
100 <
101 Geometry1, Geometry2, Strategy
102 >::apply(geometry1, geometry2, strategy);
103 }
92f5a8d4 104};
7c673cae 105
1e59de90
TL
106template <typename Strategy>
107struct is_strategy_converter_specialized
108{
109 typedef strategies::distance::services::strategy_converter<Strategy> converter;
110 static const bool value = ! std::is_same
111 <
112 decltype(converter::get(std::declval<Strategy>())),
113 strategies::detail::not_implemented
114 >::value;
115};
116
117template <typename Strategy>
118struct distance<Strategy, false>
119{
120 template
121 <
122 typename Geometry1, typename Geometry2, typename S,
123 std::enable_if_t<is_strategy_converter_specialized<S>::value, int> = 0
124 >
125 static inline auto apply(Geometry1 const& geometry1,
126 Geometry2 const& geometry2,
127 S const& strategy)
128 {
129 typedef strategies::distance::services::strategy_converter<Strategy> converter;
130 typedef decltype(converter::get(strategy)) strategy_type;
131
132 return dispatch::distance
133 <
134 Geometry1, Geometry2, strategy_type
135 >::apply(geometry1, geometry2, converter::get(strategy));
136 }
137
138 template
139 <
140 typename Geometry1, typename Geometry2, typename S,
141 std::enable_if_t<! is_strategy_converter_specialized<S>::value, int> = 0
142 >
143 static inline auto apply(Geometry1 const& geometry1,
144 Geometry2 const& geometry2,
145 S const& strategy)
146 {
147 typedef strategies::distance::services::custom_strategy_converter
148 <
149 Geometry1, Geometry2, Strategy
150 > converter;
151 typedef decltype(converter::get(strategy)) strategy_type;
152
153 return dispatch::distance
154 <
155 Geometry1, Geometry2, strategy_type
156 >::apply(geometry1, geometry2, converter::get(strategy));
157 }
158};
159
92f5a8d4 160template <>
1e59de90 161struct distance<default_strategy, false>
92f5a8d4 162{
7c673cae 163 template <typename Geometry1, typename Geometry2>
1e59de90
TL
164 static inline auto apply(Geometry1 const& geometry1,
165 Geometry2 const& geometry2,
166 default_strategy)
7c673cae 167 {
1e59de90 168 typedef typename strategies::distance::services::default_strategy
7c673cae
FG
169 <
170 Geometry1, Geometry2
171 >::type strategy_type;
172
173 return dispatch::distance
174 <
175 Geometry1, Geometry2, strategy_type
176 >::apply(geometry1, geometry2, strategy_type());
177 }
178};
179
180} // namespace resolve_strategy
181
182
1e59de90 183namespace resolve_dynamic
7c673cae
FG
184{
185
186
1e59de90
TL
187template
188<
189 typename Geometry1, typename Geometry2,
190 typename Tag1 = typename geometry::tag<Geometry1>::type,
191 typename Tag2 = typename geometry::tag<Geometry2>::type
192>
7c673cae
FG
193struct distance
194{
195 template <typename Strategy>
1e59de90
TL
196 static inline auto apply(Geometry1 const& geometry1,
197 Geometry2 const& geometry2,
198 Strategy const& strategy)
7c673cae 199 {
92f5a8d4
TL
200 return resolve_strategy::distance
201 <
202 Strategy
203 >::apply(geometry1, geometry2, strategy);
7c673cae
FG
204 }
205};
206
207
1e59de90
TL
208template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
209struct distance<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
7c673cae
FG
210{
211 template <typename Strategy>
1e59de90
TL
212 static inline auto apply(DynamicGeometry1 const& geometry1,
213 Geometry2 const& geometry2,
214 Strategy const& strategy)
7c673cae 215 {
1e59de90
TL
216 using result_t = typename geometry::distance_result<DynamicGeometry1, Geometry2, Strategy>::type;
217 result_t result = 0;
218 traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
7c673cae 219 {
1e59de90
TL
220 result = resolve_strategy::distance
221 <
222 Strategy
223 >::apply(g1, geometry2, strategy);
224 }, geometry1);
225 return result;
7c673cae
FG
226 }
227};
228
229
1e59de90
TL
230template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
231struct distance<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
7c673cae
FG
232{
233 template <typename Strategy>
1e59de90
TL
234 static inline auto apply(Geometry1 const& geometry1,
235 DynamicGeometry2 const& geometry2,
236 Strategy const& strategy)
7c673cae 237 {
1e59de90
TL
238 using result_t = typename geometry::distance_result<Geometry1, DynamicGeometry2, Strategy>::type;
239 result_t result = 0;
240 traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
7c673cae 241 {
1e59de90
TL
242 result = resolve_strategy::distance
243 <
244 Strategy
245 >::apply(geometry1, g2, strategy);
246 }, geometry2);
247 return result;
7c673cae
FG
248 }
249};
250
251
1e59de90
TL
252template <typename DynamicGeometry1, typename DynamicGeometry2>
253struct distance<DynamicGeometry1, DynamicGeometry2, dynamic_geometry_tag, dynamic_geometry_tag>
7c673cae
FG
254{
255 template <typename Strategy>
1e59de90
TL
256 static inline auto apply(DynamicGeometry1 const& geometry1,
257 DynamicGeometry2 const& geometry2,
258 Strategy const& strategy)
7c673cae 259 {
1e59de90
TL
260 using result_t = typename geometry::distance_result<DynamicGeometry1, DynamicGeometry2, Strategy>::type;
261 result_t result = 0;
262 traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
7c673cae 263 {
1e59de90
TL
264 result = resolve_strategy::distance
265 <
266 Strategy
267 >::apply(g1, g2, strategy);
268 }, geometry1, geometry2);
269 return result;
7c673cae
FG
270 }
271};
272
1e59de90 273} // namespace resolve_dynamic
7c673cae
FG
274
275
276/*!
92f5a8d4 277\brief Calculate the distance between two geometries \brief_strategy
7c673cae
FG
278\ingroup distance
279\details
92f5a8d4 280\details The free function distance calculates the distance between two geometries \brief_strategy. \details_strategy_reasons
7c673cae
FG
281
282\tparam Geometry1 \tparam_geometry
283\tparam Geometry2 \tparam_geometry
284\tparam Strategy \tparam_strategy{Distance}
285\param geometry1 \param_geometry
286\param geometry2 \param_geometry
287\param strategy \param_strategy{distance}
288\return \return_calc{distance}
289\note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
290 it may also be a point-segment strategy.
291
292\qbk{distinguish,with strategy}
293
294\qbk{
295[heading Available Strategies]
296\* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)]
297\* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)]
298\* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)]
299\* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)]
300\* more (currently extensions): Vincenty\, Andoyer (geographic)
301}
302 */
303
304/*
305Note, in case of a Compilation Error:
306if you get:
307 - "Failed to specialize function template ..."
308 - "error: no matching function for call to ..."
309for distance, it is probably so that there is no specialization
310for return_type<...> for your strategy.
311*/
312template <typename Geometry1, typename Geometry2, typename Strategy>
1e59de90
TL
313inline auto distance(Geometry1 const& geometry1,
314 Geometry2 const& geometry2,
315 Strategy const& strategy)
7c673cae
FG
316{
317 concepts::check<Geometry1 const>();
318 concepts::check<Geometry2 const>();
319
320 detail::throw_on_empty_input(geometry1);
321 detail::throw_on_empty_input(geometry2);
322
1e59de90 323 return resolve_dynamic::distance
7c673cae
FG
324 <
325 Geometry1,
326 Geometry2
327 >::apply(geometry1, geometry2, strategy);
328}
329
330
331/*!
92f5a8d4 332\brief Calculate the distance between two geometries.
7c673cae 333\ingroup distance
92f5a8d4
TL
334\details The free function distance calculates the distance between two geometries. \details_default_strategy
335
7c673cae
FG
336\tparam Geometry1 \tparam_geometry
337\tparam Geometry2 \tparam_geometry
338\param geometry1 \param_geometry
339\param geometry2 \param_geometry
340\return \return_calc{distance}
341
342\qbk{[include reference/algorithms/distance.qbk]}
343 */
344template <typename Geometry1, typename Geometry2>
1e59de90
TL
345inline auto distance(Geometry1 const& geometry1,
346 Geometry2 const& geometry2)
7c673cae 347{
7c673cae
FG
348 return geometry::distance(geometry1, geometry2, default_strategy());
349}
350
351}} // namespace boost::geometry
352
353#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP