backward_compatibility.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // Boost.Geometry
  2. // Copyright (c) 2021, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  4. // Licensed under the Boost Software License version 1.0.
  5. // http://www.boost.org/users/license.html
  6. #ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_BACKWARD_COMPATIBILITY_HPP
  7. #define BOOST_GEOMETRY_STRATEGIES_DISTANCE_BACKWARD_COMPATIBILITY_HPP
  8. #include <boost/geometry/strategies/distance/cartesian.hpp>
  9. #include <boost/geometry/strategies/distance/comparable.hpp>
  10. #include <boost/geometry/strategies/distance/detail.hpp>
  11. #include <boost/geometry/strategies/distance/geographic.hpp>
  12. #include <boost/geometry/strategies/distance/spherical.hpp>
  13. namespace boost { namespace geometry
  14. {
  15. namespace strategies { namespace distance
  16. {
  17. #ifndef DOXYGEN_NO_DETAIL
  18. namespace detail
  19. {
  20. template
  21. <
  22. typename Strategy,
  23. typename CSTag,
  24. typename StrategyTag = typename strategy::distance::services::tag<Strategy>::type
  25. >
  26. struct custom_strategy
  27. {
  28. BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
  29. "Not implemented for this Strategy.",
  30. Strategy);
  31. };
  32. // NOTES:
  33. // - There is no guarantee that any of the custom strategies are compatible with other
  34. // strategies.
  35. // - In many cases it is not possible to pass the custom strategy into other strategies.
  36. // - The old backward compatibility code creating default Pt/Seg strategy from custom
  37. // Pt/Pt strategy worked the same way. The custom strategy is default-created.
  38. // - There are two versions of algorithm for Polyseg/Box, one for Seg/Box strategy the
  39. // other one for Pt/Seg strategy. However there is only one version of algorithm for
  40. // Seg/Box taking Seg/Box strategy.
  41. // - Geographic strategies are default-created which means WGS84 spheroid is used.
  42. // - Currently only Pt/Pt custom strategies are supported because this is what the old
  43. // backward compatibility code was addressing.
  44. template <typename Strategy>
  45. struct custom_strategy<Strategy, cartesian_tag, strategy_tag_distance_point_point>
  46. : cartesian<>
  47. {
  48. custom_strategy(Strategy const& strategy)
  49. : m_strategy(strategy)
  50. {}
  51. template <typename Geometry1, typename Geometry2>
  52. auto distance(Geometry1 const&, Geometry2 const&,
  53. enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
  54. {
  55. return m_strategy;
  56. }
  57. template <typename Geometry1, typename Geometry2>
  58. auto distance(Geometry1 const&, Geometry2 const&,
  59. enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
  60. {
  61. return strategy::distance::projected_point<void, Strategy>();
  62. }
  63. template <typename Geometry1, typename Geometry2>
  64. auto distance(Geometry1 const&, Geometry2 const&,
  65. enable_if_pb_t<Geometry1, Geometry2> * = nullptr) const
  66. {
  67. return strategy::distance::pythagoras_point_box<>();
  68. }
  69. template <typename Geometry1, typename Geometry2>
  70. auto distance(Geometry1 const&, Geometry2 const&,
  71. enable_if_sb_t<Geometry1, Geometry2> * = nullptr) const
  72. {
  73. return strategy::distance::cartesian_segment_box<void, Strategy>();
  74. }
  75. template <typename Geometry1, typename Geometry2>
  76. auto distance(Geometry1 const&, Geometry2 const&,
  77. enable_if_bb_t<Geometry1, Geometry2> * = nullptr) const
  78. {
  79. return strategy::distance::pythagoras_box_box<>();
  80. }
  81. private:
  82. Strategy const& m_strategy;
  83. };
  84. template <typename Strategy>
  85. struct custom_strategy<Strategy, spherical_tag, strategy_tag_distance_point_point>
  86. : detail::spherical<void, void>
  87. {
  88. custom_strategy(Strategy const& strategy)
  89. : m_strategy(strategy)
  90. {}
  91. template <typename Geometry1, typename Geometry2>
  92. auto distance(Geometry1 const&, Geometry2 const&,
  93. enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
  94. {
  95. return m_strategy;
  96. }
  97. template <typename Geometry1, typename Geometry2>
  98. auto distance(Geometry1 const&, Geometry2 const&,
  99. enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
  100. {
  101. return strategy::distance::cross_track<void, Strategy>(m_strategy);
  102. }
  103. template <typename Geometry1, typename Geometry2>
  104. auto distance(Geometry1 const&, Geometry2 const&,
  105. enable_if_pb_t<Geometry1, Geometry2> * = nullptr) const
  106. {
  107. return strategy::distance::cross_track_point_box<void, Strategy>(m_strategy);
  108. }
  109. template <typename Geometry1, typename Geometry2>
  110. auto distance(Geometry1 const&, Geometry2 const&,
  111. enable_if_sb_t<Geometry1, Geometry2> * = nullptr) const
  112. {
  113. return strategy::distance::spherical_segment_box<void, Strategy>(m_strategy);
  114. }
  115. template <typename Geometry1, typename Geometry2>
  116. auto distance(Geometry1 const&, Geometry2 const&,
  117. enable_if_bb_t<Geometry1, Geometry2> * = nullptr) const
  118. {
  119. return strategy::distance::cross_track_box_box<void, Strategy>(m_strategy);
  120. }
  121. private:
  122. Strategy const& m_strategy;
  123. };
  124. template <typename Strategy>
  125. struct custom_strategy<Strategy, geographic_tag, strategy_tag_distance_point_point>
  126. : geographic<>
  127. {
  128. custom_strategy(Strategy const& strategy)
  129. : m_strategy(strategy)
  130. {}
  131. template <typename Geometry1, typename Geometry2>
  132. auto distance(Geometry1 const&, Geometry2 const&,
  133. enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
  134. {
  135. return m_strategy;
  136. }
  137. template <typename Geometry1, typename Geometry2>
  138. auto distance(Geometry1 const&, Geometry2 const&,
  139. enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
  140. {
  141. return strategy::distance::geographic_cross_track<>();
  142. }
  143. template <typename Geometry1, typename Geometry2>
  144. auto distance(Geometry1 const&, Geometry2 const&,
  145. enable_if_pb_t<Geometry1, Geometry2> * = nullptr) const
  146. {
  147. return strategy::distance::geographic_cross_track_point_box<>();
  148. }
  149. template <typename Geometry1, typename Geometry2>
  150. auto distance(Geometry1 const&, Geometry2 const&,
  151. enable_if_sb_t<Geometry1, Geometry2> * = nullptr) const
  152. {
  153. return strategy::distance::geographic_segment_box<>();
  154. }
  155. template <typename Geometry1, typename Geometry2>
  156. auto distance(Geometry1 const&, Geometry2 const&,
  157. enable_if_bb_t<Geometry1, Geometry2> * = nullptr) const
  158. {
  159. return strategy::distance::geographic_cross_track_box_box<>();
  160. }
  161. private:
  162. Strategy const& m_strategy;
  163. };
  164. } // namespace detail
  165. #endif // DOXYGEN_NO_DETAIL
  166. namespace services
  167. {
  168. template <typename Geometry1, typename Geometry2, typename Strategy>
  169. struct custom_strategy_converter<Geometry1, Geometry2, Strategy, cartesian_tag, cartesian_tag>
  170. {
  171. static auto get(Strategy const& strategy)
  172. {
  173. return detail::custom_strategy<Strategy, cartesian_tag>(strategy);
  174. }
  175. };
  176. template <typename Geometry1, typename Geometry2, typename Strategy>
  177. struct custom_strategy_converter<Geometry1, Geometry2, Strategy, spherical_equatorial_tag, spherical_equatorial_tag>
  178. {
  179. static auto get(Strategy const& strategy)
  180. {
  181. return detail::custom_strategy<Strategy, spherical_tag>(strategy);
  182. }
  183. };
  184. template <typename Geometry1, typename Geometry2, typename Strategy>
  185. struct custom_strategy_converter<Geometry1, Geometry2, Strategy, geographic_tag, geographic_tag>
  186. {
  187. static auto get(Strategy const& strategy)
  188. {
  189. return detail::custom_strategy<Strategy, geographic_tag>(strategy);
  190. }
  191. };
  192. } // namespace services
  193. }} // namespace strategies::distance
  194. }} // namespace boost::geometry
  195. #endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_BACKWARD_COMPATIBILITY_HPP