interface.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  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. // This file was modified by Oracle on 2014, 2019.
  6. // Modifications copyright (c) 2014, 2019, Oracle and/or its affiliates.
  7. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  8. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  9. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  10. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  11. // Use, modification and distribution is subject to the Boost Software License,
  12. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
  15. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
  16. #include <boost/geometry/geometries/concepts/check.hpp>
  17. #include <boost/geometry/strategies/comparable_distance_result.hpp>
  18. #include <boost/geometry/strategies/default_comparable_distance_result.hpp>
  19. #include <boost/geometry/strategies/distance.hpp>
  20. #include <boost/geometry/algorithms/detail/distance/interface.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. namespace resolve_strategy
  24. {
  25. template <typename Strategy>
  26. struct comparable_distance
  27. {
  28. template <typename Geometry1, typename Geometry2>
  29. static inline
  30. typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
  31. apply(Geometry1 const& geometry1,
  32. Geometry2 const& geometry2,
  33. Strategy const& strategy)
  34. {
  35. typedef typename strategy::distance::services::comparable_type
  36. <
  37. Strategy
  38. >::type comparable_strategy_type;
  39. return dispatch::distance
  40. <
  41. Geometry1, Geometry2, comparable_strategy_type
  42. >::apply(geometry1,
  43. geometry2,
  44. strategy::distance::services::get_comparable
  45. <
  46. Strategy
  47. >::apply(strategy));
  48. }
  49. };
  50. template <>
  51. struct comparable_distance<default_strategy>
  52. {
  53. template <typename Geometry1, typename Geometry2>
  54. static inline typename comparable_distance_result
  55. <
  56. Geometry1, Geometry2, default_strategy
  57. >::type
  58. apply(Geometry1 const& geometry1,
  59. Geometry2 const& geometry2,
  60. default_strategy)
  61. {
  62. typedef typename strategy::distance::services::comparable_type
  63. <
  64. typename detail::distance::default_strategy
  65. <
  66. Geometry1, Geometry2
  67. >::type
  68. >::type comparable_strategy_type;
  69. return dispatch::distance
  70. <
  71. Geometry1, Geometry2, comparable_strategy_type
  72. >::apply(geometry1, geometry2, comparable_strategy_type());
  73. }
  74. };
  75. } // namespace resolve_strategy
  76. namespace resolve_variant
  77. {
  78. template <typename Geometry1, typename Geometry2>
  79. struct comparable_distance
  80. {
  81. template <typename Strategy>
  82. static inline
  83. typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
  84. apply(Geometry1 const& geometry1,
  85. Geometry2 const& geometry2,
  86. Strategy const& strategy)
  87. {
  88. return resolve_strategy::comparable_distance
  89. <
  90. Strategy
  91. >::apply(geometry1, geometry2, strategy);
  92. }
  93. };
  94. template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
  95. struct comparable_distance
  96. <
  97. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
  98. Geometry2
  99. >
  100. {
  101. template <typename Strategy>
  102. struct visitor: static_visitor
  103. <
  104. typename comparable_distance_result
  105. <
  106. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
  107. Geometry2,
  108. Strategy
  109. >::type
  110. >
  111. {
  112. Geometry2 const& m_geometry2;
  113. Strategy const& m_strategy;
  114. visitor(Geometry2 const& geometry2,
  115. Strategy const& strategy)
  116. : m_geometry2(geometry2),
  117. m_strategy(strategy)
  118. {}
  119. template <typename Geometry1>
  120. typename comparable_distance_result
  121. <
  122. Geometry1, Geometry2, Strategy
  123. >::type
  124. operator()(Geometry1 const& geometry1) const
  125. {
  126. return comparable_distance
  127. <
  128. Geometry1,
  129. Geometry2
  130. >::template apply
  131. <
  132. Strategy
  133. >(geometry1, m_geometry2, m_strategy);
  134. }
  135. };
  136. template <typename Strategy>
  137. static inline typename comparable_distance_result
  138. <
  139. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
  140. Geometry2,
  141. Strategy
  142. >::type
  143. apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
  144. Geometry2 const& geometry2,
  145. Strategy const& strategy)
  146. {
  147. return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
  148. }
  149. };
  150. template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  151. struct comparable_distance
  152. <
  153. Geometry1,
  154. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>
  155. >
  156. {
  157. template <typename Strategy>
  158. struct visitor: static_visitor
  159. <
  160. typename comparable_distance_result
  161. <
  162. Geometry1,
  163. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
  164. Strategy
  165. >::type
  166. >
  167. {
  168. Geometry1 const& m_geometry1;
  169. Strategy const& m_strategy;
  170. visitor(Geometry1 const& geometry1,
  171. Strategy const& strategy)
  172. : m_geometry1(geometry1),
  173. m_strategy(strategy)
  174. {}
  175. template <typename Geometry2>
  176. typename comparable_distance_result
  177. <
  178. Geometry1, Geometry2, Strategy
  179. >::type
  180. operator()(Geometry2 const& geometry2) const
  181. {
  182. return comparable_distance
  183. <
  184. Geometry1,
  185. Geometry2
  186. >::template apply
  187. <
  188. Strategy
  189. >(m_geometry1, geometry2, m_strategy);
  190. }
  191. };
  192. template <typename Strategy>
  193. static inline typename comparable_distance_result
  194. <
  195. Geometry1,
  196. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
  197. Strategy
  198. >::type
  199. apply(Geometry1 const& geometry1,
  200. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
  201. Strategy const& strategy)
  202. {
  203. return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
  204. }
  205. };
  206. template
  207. <
  208. BOOST_VARIANT_ENUM_PARAMS(typename T1),
  209. BOOST_VARIANT_ENUM_PARAMS(typename T2)
  210. >
  211. struct comparable_distance
  212. <
  213. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
  214. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
  215. >
  216. {
  217. template <typename Strategy>
  218. struct visitor: static_visitor
  219. <
  220. typename comparable_distance_result
  221. <
  222. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
  223. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
  224. Strategy
  225. >::type
  226. >
  227. {
  228. Strategy const& m_strategy;
  229. visitor(Strategy const& strategy)
  230. : m_strategy(strategy)
  231. {}
  232. template <typename Geometry1, typename Geometry2>
  233. typename comparable_distance_result
  234. <
  235. Geometry1, Geometry2, Strategy
  236. >::type
  237. operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const
  238. {
  239. return comparable_distance
  240. <
  241. Geometry1,
  242. Geometry2
  243. >::template apply
  244. <
  245. Strategy
  246. >(geometry1, geometry2, m_strategy);
  247. }
  248. };
  249. template <typename Strategy>
  250. static inline typename comparable_distance_result
  251. <
  252. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
  253. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
  254. Strategy
  255. >::type
  256. apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
  257. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
  258. Strategy const& strategy)
  259. {
  260. return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
  261. }
  262. };
  263. } // namespace resolve_variant
  264. /*!
  265. \brief \brief_calc2{comparable distance measurement} \brief_strategy
  266. \ingroup distance
  267. \details The free function comparable_distance does not necessarily calculate the distance,
  268. but it calculates a distance measure such that two distances are comparable to each other.
  269. For example: for the Cartesian coordinate system, Pythagoras is used but the square root
  270. is not taken, which makes it faster and the results of two point pairs can still be
  271. compared to each other.
  272. \tparam Geometry1 first geometry type
  273. \tparam Geometry2 second geometry type
  274. \tparam Strategy \tparam_strategy{Distance}
  275. \param geometry1 \param_geometry
  276. \param geometry2 \param_geometry
  277. \param strategy \param_strategy{distance}
  278. \return \return_calc{comparable distance}
  279. \qbk{distinguish,with strategy}
  280. */
  281. template <typename Geometry1, typename Geometry2, typename Strategy>
  282. inline typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
  283. comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2,
  284. Strategy const& strategy)
  285. {
  286. concepts::check<Geometry1 const>();
  287. concepts::check<Geometry2 const>();
  288. return resolve_variant::comparable_distance
  289. <
  290. Geometry1,
  291. Geometry2
  292. >::apply(geometry1, geometry2, strategy);
  293. }
  294. /*!
  295. \brief \brief_calc2{comparable distance measurement}
  296. \ingroup distance
  297. \details The free function comparable_distance does not necessarily calculate the distance,
  298. but it calculates a distance measure such that two distances are comparable to each other.
  299. For example: for the Cartesian coordinate system, Pythagoras is used but the square root
  300. is not taken, which makes it faster and the results of two point pairs can still be
  301. compared to each other.
  302. \tparam Geometry1 first geometry type
  303. \tparam Geometry2 second geometry type
  304. \param geometry1 \param_geometry
  305. \param geometry2 \param_geometry
  306. \return \return_calc{comparable distance}
  307. \qbk{[include reference/algorithms/comparable_distance.qbk]}
  308. */
  309. template <typename Geometry1, typename Geometry2>
  310. inline typename default_comparable_distance_result<Geometry1, Geometry2>::type
  311. comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2)
  312. {
  313. concepts::check<Geometry1 const>();
  314. concepts::check<Geometry2 const>();
  315. return geometry::comparable_distance(geometry1, geometry2, default_strategy());
  316. }
  317. }} // namespace boost::geometry
  318. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP