1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
7 // This file was modified by Oracle on 2014-2021.
8 // Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
20 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
21 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
24 #include <boost/geometry/algorithms/detail/distance/interface.hpp>
26 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
27 #include <boost/geometry/geometries/concepts/check.hpp>
29 #include <boost/geometry/strategies/comparable_distance_result.hpp>
30 #include <boost/geometry/strategies/default_comparable_distance_result.hpp>
31 #include <boost/geometry/strategies/distance.hpp>
33 #include <boost/geometry/strategies/distance/comparable.hpp>
34 #include <boost/geometry/strategies/distance/services.hpp>
37 namespace boost { namespace geometry
41 namespace resolve_strategy
48 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategies>::value
50 struct comparable_distance
52 template <typename Geometry1, typename Geometry2>
54 typename comparable_distance_result<Geometry1, Geometry2, Strategies>::type
55 apply(Geometry1 const& geometry1,
56 Geometry2 const& geometry2,
57 Strategies const& strategies)
59 return dispatch::distance
62 strategies::distance::detail::comparable<Strategies>
65 strategies::distance::detail::comparable<Strategies>(strategies));
69 template <typename Strategy>
70 struct comparable_distance<Strategy, false>
72 template <typename Geometry1, typename Geometry2>
74 typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
75 apply(Geometry1 const& geometry1,
76 Geometry2 const& geometry2,
77 Strategy const& strategy)
79 using strategies::distance::services::strategy_converter;
81 typedef decltype(strategy_converter<Strategy>::get(strategy))
83 typedef strategies::distance::detail::comparable
86 > comparable_strategies_type;
88 return dispatch::distance
91 comparable_strategies_type
94 comparable_strategies_type(
95 strategy_converter<Strategy>::get(strategy)));
100 struct comparable_distance<default_strategy, false>
102 template <typename Geometry1, typename Geometry2>
103 static inline typename comparable_distance_result
105 Geometry1, Geometry2, default_strategy
107 apply(Geometry1 const& geometry1,
108 Geometry2 const& geometry2,
111 typedef strategies::distance::detail::comparable
113 typename strategies::distance::services::default_strategy
117 > comparable_strategy_type;
119 return dispatch::distance
121 Geometry1, Geometry2, comparable_strategy_type
122 >::apply(geometry1, geometry2, comparable_strategy_type());
126 } // namespace resolve_strategy
129 namespace resolve_variant
133 template <typename Geometry1, typename Geometry2>
134 struct comparable_distance
136 template <typename Strategy>
138 typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
139 apply(Geometry1 const& geometry1,
140 Geometry2 const& geometry2,
141 Strategy const& strategy)
143 return resolve_strategy::comparable_distance
146 >::apply(geometry1, geometry2, strategy);
151 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
152 struct comparable_distance
154 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
158 template <typename Strategy>
159 struct visitor: static_visitor
161 typename comparable_distance_result
163 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
169 Geometry2 const& m_geometry2;
170 Strategy const& m_strategy;
172 visitor(Geometry2 const& geometry2,
173 Strategy const& strategy)
174 : m_geometry2(geometry2),
178 template <typename Geometry1>
179 typename comparable_distance_result
181 Geometry1, Geometry2, Strategy
183 operator()(Geometry1 const& geometry1) const
185 return comparable_distance
192 >(geometry1, m_geometry2, m_strategy);
196 template <typename Strategy>
197 static inline typename comparable_distance_result
199 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
203 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
204 Geometry2 const& geometry2,
205 Strategy const& strategy)
207 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
212 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
213 struct comparable_distance
216 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>
219 template <typename Strategy>
220 struct visitor: static_visitor
222 typename comparable_distance_result
225 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
230 Geometry1 const& m_geometry1;
231 Strategy const& m_strategy;
233 visitor(Geometry1 const& geometry1,
234 Strategy const& strategy)
235 : m_geometry1(geometry1),
239 template <typename Geometry2>
240 typename comparable_distance_result
242 Geometry1, Geometry2, Strategy
244 operator()(Geometry2 const& geometry2) const
246 return comparable_distance
253 >(m_geometry1, geometry2, m_strategy);
257 template <typename Strategy>
258 static inline typename comparable_distance_result
261 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
264 apply(Geometry1 const& geometry1,
265 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
266 Strategy const& strategy)
268 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
275 BOOST_VARIANT_ENUM_PARAMS(typename T1),
276 BOOST_VARIANT_ENUM_PARAMS(typename T2)
278 struct comparable_distance
280 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
281 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
284 template <typename Strategy>
285 struct visitor: static_visitor
287 typename comparable_distance_result
289 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
290 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
295 Strategy const& m_strategy;
297 visitor(Strategy const& strategy)
298 : m_strategy(strategy)
301 template <typename Geometry1, typename Geometry2>
302 typename comparable_distance_result
304 Geometry1, Geometry2, Strategy
306 operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const
308 return comparable_distance
315 >(geometry1, geometry2, m_strategy);
319 template <typename Strategy>
320 static inline typename comparable_distance_result
322 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
323 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
326 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
327 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
328 Strategy const& strategy)
330 return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
334 } // namespace resolve_variant
339 \brief \brief_calc2{comparable distance measurement} \brief_strategy
341 \details The free function comparable_distance does not necessarily calculate the distance,
342 but it calculates a distance measure such that two distances are comparable to each other.
343 For example: for the Cartesian coordinate system, Pythagoras is used but the square root
344 is not taken, which makes it faster and the results of two point pairs can still be
345 compared to each other.
346 \tparam Geometry1 first geometry type
347 \tparam Geometry2 second geometry type
348 \tparam Strategy \tparam_strategy{Distance}
349 \param geometry1 \param_geometry
350 \param geometry2 \param_geometry
351 \param strategy \param_strategy{distance}
352 \return \return_calc{comparable distance}
354 \qbk{distinguish,with strategy}
356 template <typename Geometry1, typename Geometry2, typename Strategy>
357 inline typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
358 comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2,
359 Strategy const& strategy)
361 concepts::check<Geometry1 const>();
362 concepts::check<Geometry2 const>();
364 return resolve_variant::comparable_distance
368 >::apply(geometry1, geometry2, strategy);
374 \brief \brief_calc2{comparable distance measurement}
376 \details The free function comparable_distance does not necessarily calculate the distance,
377 but it calculates a distance measure such that two distances are comparable to each other.
378 For example: for the Cartesian coordinate system, Pythagoras is used but the square root
379 is not taken, which makes it faster and the results of two point pairs can still be
380 compared to each other.
381 \tparam Geometry1 first geometry type
382 \tparam Geometry2 second geometry type
383 \param geometry1 \param_geometry
384 \param geometry2 \param_geometry
385 \return \return_calc{comparable distance}
387 \qbk{[include reference/algorithms/comparable_distance.qbk]}
389 template <typename Geometry1, typename Geometry2>
390 inline typename default_comparable_distance_result<Geometry1, Geometry2>::type
391 comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2)
393 concepts::check<Geometry1 const>();
394 concepts::check<Geometry2 const>();
396 return geometry::comparable_distance(geometry1, geometry2, default_strategy());
400 }} // namespace boost::geometry
403 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP