3 // Copyright (c) 2021, Oracle and/or its affiliates.
5 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
10 #ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_SPHERICAL_HPP
11 #define BOOST_GEOMETRY_STRATEGIES_DISTANCE_SPHERICAL_HPP
14 #include <boost/geometry/strategies/distance/comparable.hpp>
15 #include <boost/geometry/strategies/distance/detail.hpp>
16 #include <boost/geometry/strategies/distance/services.hpp>
17 #include <boost/geometry/strategies/detail.hpp>
19 #include <boost/geometry/strategies/normalize.hpp>
20 #include <boost/geometry/strategies/relate/spherical.hpp>
22 #include <boost/geometry/strategies/spherical/azimuth.hpp>
24 #include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
25 #include <boost/geometry/strategies/spherical/distance_cross_track_box_box.hpp>
26 #include <boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp>
27 #include <boost/geometry/strategies/spherical/distance_haversine.hpp>
28 #include <boost/geometry/strategies/spherical/distance_segment_box.hpp>
31 namespace boost { namespace geometry
34 namespace strategies { namespace distance
37 #ifndef DOXYGEN_NO_DETAIL
41 // TODO: azimuth and normalize getters would not be needed if distance_segment_box was implemented differently
42 // right now it calls disjoint algorithm details.
44 template <typename RadiusTypeOrSphere, typename CalculationType>
46 : public strategies::relate::detail::spherical<RadiusTypeOrSphere, CalculationType>
48 using base_t = strategies::relate::detail::spherical<RadiusTypeOrSphere, CalculationType>;
51 spherical() = default;
53 template <typename RadiusOrSphere>
54 explicit spherical(RadiusOrSphere const& radius_or_sphere)
55 : base_t(radius_or_sphere)
62 return strategy::azimuth::spherical<CalculationType>();
67 template <typename Geometry1, typename Geometry2>
68 auto distance(Geometry1 const&, Geometry2 const&,
69 detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
71 return strategy::distance::haversine
73 typename base_t::radius_type, CalculationType
77 template <typename Geometry1, typename Geometry2>
78 auto distance(Geometry1 const&, Geometry2 const&,
79 detail::enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
81 return strategy::distance::cross_track
84 strategy::distance::haversine<typename base_t::radius_type, CalculationType>
88 template <typename Geometry1, typename Geometry2>
89 auto distance(Geometry1 const&, Geometry2 const&,
90 detail::enable_if_pb_t<Geometry1, Geometry2> * = nullptr) const
92 return strategy::distance::cross_track_point_box
95 strategy::distance::haversine<typename base_t::radius_type, CalculationType>
99 template <typename Geometry1, typename Geometry2>
100 auto distance(Geometry1 const&, Geometry2 const&,
101 detail::enable_if_sb_t<Geometry1, Geometry2> * = nullptr) const
103 return strategy::distance::spherical_segment_box
106 strategy::distance::haversine<typename base_t::radius_type, CalculationType>
110 template <typename Geometry1, typename Geometry2>
111 auto distance(Geometry1 const&, Geometry2 const&,
112 detail::enable_if_bb_t<Geometry1, Geometry2> * = nullptr) const
114 return strategy::distance::cross_track_box_box
117 strategy::distance::haversine<typename base_t::radius_type, CalculationType>
123 template <typename Geometry>
124 static auto normalize(Geometry const&,
127 util::is_point<Geometry>::value
130 return strategy::normalize::spherical_point();
135 } // namespace detail
136 #endif // DOXYGEN_NO_DETAIL
141 typename RadiusTypeOrSphere = double,
142 typename CalculationType = void
145 : public strategies::distance::detail::spherical<RadiusTypeOrSphere, CalculationType>
147 using base_t = strategies::distance::detail::spherical<RadiusTypeOrSphere, CalculationType>;
150 spherical() = default;
152 template <typename RadiusOrSphere>
153 explicit spherical(RadiusOrSphere const& radius_or_sphere)
154 : base_t(radius_or_sphere)
162 template <typename Geometry1, typename Geometry2>
163 struct default_strategy
165 Geometry1, Geometry2,
166 spherical_equatorial_tag, spherical_equatorial_tag
169 using type = strategies::distance::spherical<>;
173 template <typename R, typename CT>
174 struct strategy_converter<strategy::distance::haversine<R, CT> >
176 template <typename S>
177 static auto get(S const& s)
179 return strategies::distance::spherical<R, CT>(s.radius());
183 template <typename CT, typename PPS>
184 struct strategy_converter<strategy::distance::cross_track<CT, PPS> >
185 : strategy_converter<PPS>
188 template <typename CT, typename PPS>
189 struct strategy_converter<strategy::distance::cross_track_point_box<CT, PPS> >
190 : strategy_converter<PPS>
193 template <typename CT, typename PPS>
194 struct strategy_converter<strategy::distance::spherical_segment_box<CT, PPS> >
195 : strategy_converter<PPS>
198 template <typename CT, typename PPS>
199 struct strategy_converter<strategy::distance::cross_track_box_box<CT, PPS> >
200 : strategy_converter<PPS>
204 template <typename R, typename CT>
205 struct strategy_converter<strategy::distance::comparable::haversine<R, CT> >
207 template <typename S>
208 static auto get(S const& s)
210 return strategies::distance::detail::make_comparable(
211 strategies::distance::spherical<R, CT>(s.radius()));
215 template <typename CT, typename PPS>
216 struct strategy_converter<strategy::distance::comparable::cross_track<CT, PPS> >
217 : strategy_converter<PPS>
221 } // namespace services
223 }} // namespace strategies::distance
225 }} // namespace boost::geometry
227 #endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_SPHERICAL_HPP