File indexing completed on 2025-01-18 09:36:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP
0017 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP
0018
0019
0020 #include <boost/geometry/core/coordinate_promotion.hpp>
0021 #include <boost/geometry/core/coordinate_type.hpp>
0022 #include <boost/geometry/core/radian_access.hpp>
0023 #include <boost/geometry/core/radius.hpp>
0024
0025 #include <boost/geometry/formulas/andoyer_inverse.hpp>
0026 #include <boost/geometry/formulas/meridian_inverse.hpp>
0027 #include <boost/geometry/formulas/flattening.hpp>
0028
0029 #include <boost/geometry/srs/spheroid.hpp>
0030
0031 #include <boost/geometry/strategies/distance.hpp>
0032 #include <boost/geometry/strategies/geographic/parameters.hpp>
0033
0034 #include <boost/geometry/util/math.hpp>
0035 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
0036 #include <boost/geometry/util/select_calculation_type.hpp>
0037
0038 #include <boost/geometry/geometries/point_xy.hpp>
0039
0040 namespace boost { namespace geometry
0041 {
0042
0043 namespace strategy { namespace distance
0044 {
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 template
0060 <
0061 typename FormulaPolicy = strategy::andoyer,
0062 typename Spheroid = srs::spheroid<double>,
0063 typename CalculationType = void
0064 >
0065 class geographic
0066 {
0067 public :
0068 template <typename Point1, typename Point2>
0069 struct calculation_type
0070 : promote_floating_point
0071 <
0072 typename select_calculation_type
0073 <
0074 Point1,
0075 Point2,
0076 CalculationType
0077 >::type
0078 >
0079 {};
0080
0081 typedef Spheroid model_type;
0082
0083 inline geographic()
0084 : m_spheroid()
0085 {}
0086
0087 explicit inline geographic(Spheroid const& spheroid)
0088 : m_spheroid(spheroid)
0089 {}
0090
0091 template <typename CT>
0092 static inline CT apply(CT lon1, CT lat1, CT lon2, CT lat2,
0093 Spheroid const& spheroid)
0094 {
0095 typedef typename formula::meridian_inverse
0096 <
0097 CT, strategy::default_order<FormulaPolicy>::value
0098 > meridian_inverse;
0099
0100 typename meridian_inverse::result res =
0101 meridian_inverse::apply(lon1, lat1, lon2, lat2, spheroid);
0102
0103 if (res.meridian)
0104 {
0105 return res.distance;
0106 }
0107
0108 return FormulaPolicy::template inverse
0109 <
0110 CT, true, false, false, false, false
0111 >::apply(lon1, lat1, lon2, lat2, spheroid).distance;
0112 }
0113
0114 template <typename Point1, typename Point2>
0115 inline typename calculation_type<Point1, Point2>::type
0116 apply(Point1 const& point1, Point2 const& point2) const
0117 {
0118 typedef typename calculation_type<Point1, Point2>::type CT;
0119
0120 CT lon1 = get_as_radian<0>(point1);
0121 CT lat1 = get_as_radian<1>(point1);
0122 CT lon2 = get_as_radian<0>(point2);
0123 CT lat2 = get_as_radian<1>(point2);
0124
0125 return apply(lon1, lat1, lon2, lat2, m_spheroid);
0126 }
0127
0128 inline Spheroid const& model() const
0129 {
0130 return m_spheroid;
0131 }
0132
0133 private :
0134 Spheroid m_spheroid;
0135 };
0136
0137
0138 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0139 namespace services
0140 {
0141
0142 template
0143 <
0144 typename FormulaPolicy,
0145 typename Spheroid,
0146 typename CalculationType
0147 >
0148 struct tag<geographic<FormulaPolicy, Spheroid, CalculationType> >
0149 {
0150 typedef strategy_tag_distance_point_point type;
0151 };
0152
0153
0154 template
0155 <
0156 typename FormulaPolicy,
0157 typename Spheroid,
0158 typename CalculationType,
0159 typename P1,
0160 typename P2
0161 >
0162 struct return_type<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>
0163 : geographic<FormulaPolicy, Spheroid, CalculationType>::template calculation_type<P1, P2>
0164 {};
0165
0166
0167 template
0168 <
0169 typename FormulaPolicy,
0170 typename Spheroid,
0171 typename CalculationType
0172 >
0173 struct comparable_type<geographic<FormulaPolicy, Spheroid, CalculationType> >
0174 {
0175 typedef geographic<FormulaPolicy, Spheroid, CalculationType> type;
0176 };
0177
0178
0179 template
0180 <
0181 typename FormulaPolicy,
0182 typename Spheroid,
0183 typename CalculationType
0184 >
0185 struct get_comparable<geographic<FormulaPolicy, Spheroid, CalculationType> >
0186 {
0187 static inline geographic<FormulaPolicy, Spheroid, CalculationType>
0188 apply(geographic<FormulaPolicy, Spheroid, CalculationType> const& input)
0189 {
0190 return input;
0191 }
0192 };
0193
0194 template
0195 <
0196 typename FormulaPolicy,
0197 typename Spheroid,
0198 typename CalculationType,
0199 typename P1,
0200 typename P2
0201 >
0202 struct result_from_distance<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>
0203 {
0204 template <typename T>
0205 static inline typename return_type<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>::type
0206 apply(geographic<FormulaPolicy, Spheroid, CalculationType> const& , T const& value)
0207 {
0208 return value;
0209 }
0210 };
0211
0212
0213 template <typename Point1, typename Point2>
0214 struct default_strategy<point_tag, point_tag, Point1, Point2, geographic_tag, geographic_tag>
0215 {
0216 typedef strategy::distance::geographic
0217 <
0218 strategy::andoyer,
0219 srs::spheroid
0220 <
0221 typename select_coordinate_type<Point1, Point2>::type
0222 >
0223 > type;
0224 };
0225
0226
0227 }
0228 #endif
0229
0230
0231 }}
0232
0233
0234 }}
0235
0236
0237 #endif