interface.hpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
  5. // Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
  6. // This file was modified by Oracle on 2014-2021.
  7. // Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
  8. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  9. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  10. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  11. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  12. // Use, modification and distribution is subject to the Boost Software License,
  13. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  14. // http://www.boost.org/LICENSE_1_0.txt)
  15. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
  16. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
  17. #include <boost/geometry/algorithms/detail/distance/interface.hpp>
  18. #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
  19. #include <boost/geometry/geometries/concepts/check.hpp>
  20. #include <boost/geometry/strategies/comparable_distance_result.hpp>
  21. #include <boost/geometry/strategies/default_comparable_distance_result.hpp>
  22. #include <boost/geometry/strategies/distance.hpp>
  23. #include <boost/geometry/strategies/distance/comparable.hpp>
  24. #include <boost/geometry/strategies/distance/services.hpp>
  25. namespace boost { namespace geometry
  26. {
  27. namespace resolve_strategy
  28. {
  29. template
  30. <
  31. typename Strategies,
  32. bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategies>::value
  33. >
  34. struct comparable_distance
  35. {
  36. template <typename Geometry1, typename Geometry2>
  37. static inline auto apply(Geometry1 const& geometry1,
  38. Geometry2 const& geometry2,
  39. Strategies const& strategies)
  40. {
  41. return dispatch::distance
  42. <
  43. Geometry1, Geometry2,
  44. strategies::distance::detail::comparable<Strategies>
  45. >::apply(geometry1,
  46. geometry2,
  47. strategies::distance::detail::comparable<Strategies>(strategies));
  48. }
  49. };
  50. template <typename Strategy>
  51. struct comparable_distance<Strategy, false>
  52. {
  53. template <typename Geometry1, typename Geometry2>
  54. static inline auto apply(Geometry1 const& geometry1,
  55. Geometry2 const& geometry2,
  56. Strategy const& strategy)
  57. {
  58. using strategies::distance::services::strategy_converter;
  59. using comparable_strategies_type = strategies::distance::detail::comparable
  60. <
  61. decltype(strategy_converter<Strategy>::get(strategy))
  62. >;
  63. return dispatch::distance
  64. <
  65. Geometry1, Geometry2,
  66. comparable_strategies_type
  67. >::apply(geometry1,
  68. geometry2,
  69. comparable_strategies_type(
  70. strategy_converter<Strategy>::get(strategy)));
  71. }
  72. };
  73. template <>
  74. struct comparable_distance<default_strategy, false>
  75. {
  76. template <typename Geometry1, typename Geometry2>
  77. static inline auto apply(Geometry1 const& geometry1,
  78. Geometry2 const& geometry2,
  79. default_strategy)
  80. {
  81. using comparable_strategy_type = strategies::distance::detail::comparable
  82. <
  83. typename strategies::distance::services::default_strategy
  84. <
  85. Geometry1, Geometry2
  86. >::type
  87. >;
  88. return dispatch::distance
  89. <
  90. Geometry1, Geometry2, comparable_strategy_type
  91. >::apply(geometry1, geometry2, comparable_strategy_type());
  92. }
  93. };
  94. } // namespace resolve_strategy
  95. namespace resolve_dynamic
  96. {
  97. template
  98. <
  99. typename Geometry1, typename Geometry2,
  100. typename Tag1 = typename geometry::tag<Geometry1>::type,
  101. typename Tag2 = typename geometry::tag<Geometry2>::type
  102. >
  103. struct comparable_distance
  104. {
  105. template <typename Strategy>
  106. static inline auto apply(Geometry1 const& geometry1,
  107. Geometry2 const& geometry2,
  108. Strategy const& strategy)
  109. {
  110. return resolve_strategy::comparable_distance
  111. <
  112. Strategy
  113. >::apply(geometry1, geometry2, strategy);
  114. }
  115. };
  116. template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
  117. struct comparable_distance<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
  118. {
  119. template <typename Strategy>
  120. static inline auto apply(DynamicGeometry1 const& geometry1,
  121. Geometry2 const& geometry2,
  122. Strategy const& strategy)
  123. {
  124. using result_t = typename geometry::comparable_distance_result
  125. <
  126. DynamicGeometry1, Geometry2, Strategy
  127. >::type;
  128. result_t result = 0;
  129. traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
  130. {
  131. result = resolve_strategy::comparable_distance
  132. <
  133. Strategy
  134. >::apply(g1, geometry2, strategy);
  135. }, geometry1);
  136. return result;
  137. }
  138. };
  139. template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
  140. struct comparable_distance<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
  141. {
  142. template <typename Strategy>
  143. static inline auto apply(Geometry1 const& geometry1,
  144. DynamicGeometry2 const& geometry2,
  145. Strategy const& strategy)
  146. {
  147. using result_t = typename geometry::comparable_distance_result
  148. <
  149. Geometry1, DynamicGeometry2, Strategy
  150. >::type;
  151. result_t result = 0;
  152. traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
  153. {
  154. result = resolve_strategy::comparable_distance
  155. <
  156. Strategy
  157. >::apply(geometry1, g2, strategy);
  158. }, geometry2);
  159. return result;
  160. }
  161. };
  162. template <typename DynamicGeometry1, typename DynamicGeometry2>
  163. struct comparable_distance
  164. <
  165. DynamicGeometry1, DynamicGeometry2,
  166. dynamic_geometry_tag, dynamic_geometry_tag
  167. >
  168. {
  169. template <typename Strategy>
  170. static inline auto apply(DynamicGeometry1 const& geometry1,
  171. DynamicGeometry2 const& geometry2,
  172. Strategy const& strategy)
  173. {
  174. using result_t = typename geometry::comparable_distance_result
  175. <
  176. DynamicGeometry1, DynamicGeometry2, Strategy
  177. >::type;
  178. result_t result = 0;
  179. traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
  180. {
  181. result = resolve_strategy::comparable_distance
  182. <
  183. Strategy
  184. >::apply(g1, g2, strategy);
  185. }, geometry1, geometry2);
  186. return result;
  187. }
  188. };
  189. } // namespace resolve_dynamic
  190. /*!
  191. \brief \brief_calc2{comparable distance measurement} \brief_strategy
  192. \ingroup distance
  193. \details The free function comparable_distance does not necessarily calculate the distance,
  194. but it calculates a distance measure such that two distances are comparable to each other.
  195. For example: for the Cartesian coordinate system, Pythagoras is used but the square root
  196. is not taken, which makes it faster and the results of two point pairs can still be
  197. compared to each other.
  198. \tparam Geometry1 first geometry type
  199. \tparam Geometry2 second geometry type
  200. \tparam Strategy \tparam_strategy{Distance}
  201. \param geometry1 \param_geometry
  202. \param geometry2 \param_geometry
  203. \param strategy \param_strategy{distance}
  204. \return \return_calc{comparable distance}
  205. \qbk{distinguish,with strategy}
  206. */
  207. template <typename Geometry1, typename Geometry2, typename Strategy>
  208. inline auto comparable_distance(Geometry1 const& geometry1,
  209. Geometry2 const& geometry2,
  210. Strategy const& strategy)
  211. {
  212. concepts::check<Geometry1 const>();
  213. concepts::check<Geometry2 const>();
  214. return resolve_dynamic::comparable_distance
  215. <
  216. Geometry1,
  217. Geometry2
  218. >::apply(geometry1, geometry2, strategy);
  219. }
  220. /*!
  221. \brief \brief_calc2{comparable distance measurement}
  222. \ingroup distance
  223. \details The free function comparable_distance does not necessarily calculate the distance,
  224. but it calculates a distance measure such that two distances are comparable to each other.
  225. For example: for the Cartesian coordinate system, Pythagoras is used but the square root
  226. is not taken, which makes it faster and the results of two point pairs can still be
  227. compared to each other.
  228. \tparam Geometry1 first geometry type
  229. \tparam Geometry2 second geometry type
  230. \param geometry1 \param_geometry
  231. \param geometry2 \param_geometry
  232. \return \return_calc{comparable distance}
  233. \qbk{[include reference/algorithms/comparable_distance.qbk]}
  234. */
  235. template <typename Geometry1, typename Geometry2>
  236. inline auto comparable_distance(Geometry1 const& geometry1,
  237. Geometry2 const& geometry2)
  238. {
  239. return geometry::comparable_distance(geometry1, geometry2, default_strategy());
  240. }
  241. }} // namespace boost::geometry
  242. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP