Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:44

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2021, Oracle and/or its affiliates.
0004 
0005 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0006 
0007 // Licensed under the Boost Software License version 1.0.
0008 // http://www.boost.org/users/license.html
0009 
0010 #ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_GEOGRAPHIC_HPP
0011 #define BOOST_GEOMETRY_STRATEGIES_DISTANCE_GEOGRAPHIC_HPP
0012 
0013 
0014 #include <boost/geometry/strategies/distance/comparable.hpp>
0015 #include <boost/geometry/strategies/distance/detail.hpp>
0016 #include <boost/geometry/strategies/distance/services.hpp>
0017 #include <boost/geometry/strategies/detail.hpp>
0018 
0019 #include <boost/geometry/strategies/geographic/azimuth.hpp>
0020 
0021 #include <boost/geometry/strategies/geographic/distance.hpp>
0022 #include <boost/geometry/strategies/geographic/distance_cross_track.hpp>
0023 #include <boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp>
0024 #include <boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp>
0025 #include <boost/geometry/strategies/geographic/distance_segment_box.hpp>
0026 // TODO - for backwards compatibility, remove?
0027 #include <boost/geometry/strategies/geographic/distance_andoyer.hpp>
0028 #include <boost/geometry/strategies/geographic/distance_thomas.hpp>
0029 #include <boost/geometry/strategies/geographic/distance_vincenty.hpp>
0030 
0031 #include <boost/geometry/strategies/normalize.hpp>
0032 #include <boost/geometry/strategies/relate/geographic.hpp>
0033 
0034 
0035 namespace boost { namespace geometry
0036 {
0037 
0038 namespace strategies { namespace distance
0039 {
0040 
0041 // TODO: azimuth and normalize getters would not be needed if distance_segment_box was implemented differently
0042 //       right now it calls disjoint algorithm details.
0043 
0044 template
0045 <
0046     typename FormulaPolicy = strategy::andoyer,
0047     typename Spheroid = srs::spheroid<double>,
0048     typename CalculationType = void
0049 >
0050 class geographic
0051     : public strategies::relate::geographic<FormulaPolicy, Spheroid, CalculationType>
0052 {
0053     using base_t = strategies::relate::geographic<FormulaPolicy, Spheroid, CalculationType>;
0054 
0055 public:
0056     geographic() = default;
0057 
0058     explicit geographic(Spheroid const& spheroid)
0059         : base_t(spheroid)
0060     {}
0061 
0062     // azimuth
0063 
0064     auto azimuth() const
0065     {
0066         return strategy::azimuth::geographic
0067             <
0068                 FormulaPolicy, Spheroid, CalculationType
0069             >(base_t::m_spheroid);
0070     }
0071 
0072     // distance
0073 
0074     template <typename Geometry1, typename Geometry2>
0075     auto distance(Geometry1 const&, Geometry2 const&,
0076                   detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
0077     {
0078         return strategy::distance::geographic
0079                 <
0080                     FormulaPolicy, Spheroid, CalculationType
0081                 >(base_t::m_spheroid);
0082     }
0083 
0084     template <typename Geometry1, typename Geometry2>
0085     auto distance(Geometry1 const&, Geometry2 const&,
0086                   detail::enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
0087     {
0088         return strategy::distance::geographic_cross_track
0089             <
0090                 FormulaPolicy, Spheroid, CalculationType
0091             >(base_t::m_spheroid);
0092     }
0093 
0094     template <typename Geometry1, typename Geometry2>
0095     auto distance(Geometry1 const&, Geometry2 const&,
0096                   detail::enable_if_pb_t<Geometry1, Geometry2> * = nullptr) const
0097     {
0098         return strategy::distance::geographic_cross_track_point_box
0099             <
0100                 FormulaPolicy, Spheroid, CalculationType
0101             >(base_t::m_spheroid);
0102     }
0103 
0104     template <typename Geometry1, typename Geometry2>
0105     auto distance(Geometry1 const&, Geometry2 const&,
0106                   detail::enable_if_sb_t<Geometry1, Geometry2> * = nullptr) const
0107     {
0108         return strategy::distance::geographic_segment_box
0109             <
0110                 FormulaPolicy, Spheroid, CalculationType
0111             >(base_t::m_spheroid);
0112     }
0113 
0114     template <typename Geometry1, typename Geometry2>
0115     auto distance(Geometry1 const&, Geometry2 const&,
0116                   detail::enable_if_bb_t<Geometry1, Geometry2> * = nullptr) const
0117     {
0118         return strategy::distance::geographic_cross_track_box_box
0119             <
0120                 FormulaPolicy, Spheroid, CalculationType
0121             >(base_t::m_spheroid);
0122     }
0123 
0124     // normalize
0125 
0126     template <typename Geometry>
0127     static auto normalize(Geometry const&,
0128                           std::enable_if_t
0129                             <
0130                                 util::is_point<Geometry>::value
0131                             > * = nullptr)
0132     {
0133         return strategy::normalize::spherical_point();
0134     }
0135 };
0136 
0137 
0138 namespace services
0139 {
0140 
0141 template <typename Geometry1, typename Geometry2>
0142 struct default_strategy<Geometry1, Geometry2, geographic_tag, geographic_tag>
0143 {
0144     using type = strategies::distance::geographic<>;
0145 };
0146 
0147 
0148 template <typename FP, typename S, typename CT>
0149 struct strategy_converter<strategy::distance::geographic<FP, S, CT> >
0150 {
0151     static auto get(strategy::distance::geographic<FP, S, CT> const& s)
0152     {
0153         return strategies::distance::geographic<FP, S, CT>(s.model());
0154     }
0155 };
0156 // TODO - for backwards compatibility, remove?
0157 template <typename S, typename CT>
0158 struct strategy_converter<strategy::distance::andoyer<S, CT> >
0159 {
0160     static auto get(strategy::distance::andoyer<S, CT> const& s)
0161     {
0162         return strategies::distance::geographic<strategy::andoyer, S, CT>(s.model());
0163     }
0164 };
0165 // TODO - for backwards compatibility, remove?
0166 template <typename S, typename CT>
0167 struct strategy_converter<strategy::distance::thomas<S, CT> >
0168 {
0169     static auto get(strategy::distance::thomas<S, CT> const& s)
0170     {
0171         return strategies::distance::geographic<strategy::thomas, S, CT>(s.model());
0172     }
0173 };
0174 // TODO - for backwards compatibility, remove?
0175 template <typename S, typename CT>
0176 struct strategy_converter<strategy::distance::vincenty<S, CT> >
0177 {
0178     static auto get(strategy::distance::vincenty<S, CT> const& s)
0179     {
0180         return strategies::distance::geographic<strategy::vincenty, S, CT>(s.model());
0181     }
0182 };
0183 
0184 template <typename FP, typename S, typename CT>
0185 struct strategy_converter<strategy::distance::geographic_cross_track<FP, S, CT> >
0186 {
0187     static auto get(strategy::distance::geographic_cross_track<FP, S, CT> const& s)
0188     {
0189         return strategies::distance::geographic<FP, S, CT>(s.model());
0190     }
0191 };
0192 
0193 template <typename FP, typename S, typename CT>
0194 struct strategy_converter<strategy::distance::geographic_cross_track_point_box<FP, S, CT> >
0195 {
0196     static auto get(strategy::distance::geographic_cross_track_point_box<FP, S, CT> const& s)
0197     {
0198         return strategies::distance::geographic<FP, S, CT>(s.model());
0199     }
0200 };
0201 
0202 template <typename FP, typename S, typename CT>
0203 struct strategy_converter<strategy::distance::geographic_segment_box<FP, S, CT> >
0204 {
0205     static auto get(strategy::distance::geographic_segment_box<FP, S, CT> const& s)
0206     {
0207         return strategies::distance::geographic<FP, S, CT>(s.model());
0208     }
0209 };
0210 
0211 template <typename FP, typename S, typename CT>
0212 struct strategy_converter<strategy::distance::geographic_cross_track_box_box<FP, S, CT> >
0213 {
0214     static auto get(strategy::distance::geographic_cross_track_box_box<FP, S, CT> const& s)
0215     {
0216         return strategies::distance::geographic<FP, S, CT>(s.model());
0217     }
0218 };
0219 
0220 
0221 // details
0222 
0223 // TODO: This specialization wouldn't be needed if strategy::distance::geographic_cross_track was implemented as an alias
0224 template <typename FP, typename S, typename CT, bool B, bool ECP>
0225 struct strategy_converter<strategy::distance::detail::geographic_cross_track<FP, S, CT, B, ECP> >
0226 {
0227     struct altered_strategy
0228         : strategies::distance::geographic<FP, S, CT>
0229     {
0230         typedef strategies::distance::geographic<FP, S, CT> base_t;
0231 
0232         explicit altered_strategy(S const& s) : base_t(s) {}
0233 
0234         using base_t::distance;
0235 
0236         template <typename Geometry1, typename Geometry2>
0237         auto distance(Geometry1 const&, Geometry2 const&,
0238                       detail::enable_if_ps_t<Geometry1, Geometry2> * = nullptr) const
0239         {
0240             return strategy::distance::detail::geographic_cross_track
0241                 <
0242                     FP, S, CT, B, ECP
0243                 >(base_t::m_spheroid);
0244         }
0245     };
0246 
0247     static auto get(strategy::distance::detail::geographic_cross_track<FP, S, CT, B, ECP> const& s)
0248     {
0249         return altered_strategy(s.model());
0250     }
0251 };
0252 
0253 
0254 } // namespace services
0255 
0256 }} // namespace strategies::distance
0257 
0258 }} // namespace boost::geometry
0259 
0260 #endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_GEOGRAPHIC_HPP