1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2016 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2014-2018.
6 // Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
8 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
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)
16 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP
17 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP
20 #include <boost/geometry/core/coordinate_type.hpp>
21 #include <boost/geometry/core/radian_access.hpp>
22 #include <boost/geometry/core/radius.hpp>
24 #include <boost/geometry/formulas/andoyer_inverse.hpp>
25 #include <boost/geometry/formulas/elliptic_arc_length.hpp>
26 #include <boost/geometry/formulas/flattening.hpp>
28 #include <boost/geometry/srs/spheroid.hpp>
30 #include <boost/geometry/strategies/distance.hpp>
31 #include <boost/geometry/strategies/geographic/parameters.hpp>
33 #include <boost/geometry/util/math.hpp>
34 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
35 #include <boost/geometry/util/promote_floating_point.hpp>
36 #include <boost/geometry/util/select_calculation_type.hpp>
38 #include <boost/geometry/geometries/point_xy.hpp>
40 namespace boost { namespace geometry
43 namespace strategy { namespace distance
47 \brief Distance calculation for geographic coordinates on a spheroid
49 \tparam FormulaPolicy Formula used to calculate azimuths
50 \tparam Spheroid The spheroid model
51 \tparam CalculationType \tparam_calculation
55 \* [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
56 \* [link geometry.reference.srs.srs_spheroid srs::spheroid]
61 typename FormulaPolicy = strategy::andoyer,
62 typename Spheroid = srs::spheroid<double>,
63 typename CalculationType = void
68 template <typename Point1, typename Point2>
69 struct calculation_type
70 : promote_floating_point
72 typename select_calculation_type
81 typedef Spheroid model_type;
87 explicit inline geographic(Spheroid const& spheroid)
88 : m_spheroid(spheroid)
91 template <typename CT>
92 static inline CT apply(CT lon1, CT lat1, CT lon2, CT lat2,
93 Spheroid const& spheroid)
95 typedef typename formula::elliptic_arc_length
97 CT, strategy::default_order<FormulaPolicy>::value
98 > elliptic_arc_length;
100 typename elliptic_arc_length::result res =
101 elliptic_arc_length::apply(lon1, lat1, lon2, lat2, spheroid);
108 return FormulaPolicy::template inverse
110 CT, true, false, false, false, false
111 >::apply(lon1, lat1, lon2, lat2, spheroid).distance;
114 template <typename Point1, typename Point2>
115 inline typename calculation_type<Point1, Point2>::type
116 apply(Point1 const& point1, Point2 const& point2) const
118 typedef typename calculation_type<Point1, Point2>::type CT;
120 CT lon1 = get_as_radian<0>(point1);
121 CT lat1 = get_as_radian<1>(point1);
122 CT lon2 = get_as_radian<0>(point2);
123 CT lat2 = get_as_radian<1>(point2);
125 return apply(lon1, lat1, lon2, lat2, m_spheroid);
128 // points on a meridian not crossing poles
129 template <typename CT>
130 inline CT meridian(CT lat1, CT lat2) const
132 typedef typename formula::elliptic_arc_length
134 CT, strategy::default_order<FormulaPolicy>::value
135 > elliptic_arc_length;
137 return elliptic_arc_length::meridian_not_crossing_pole_dist(lat1, lat2,
141 inline Spheroid const& model() const
151 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
157 typename FormulaPolicy,
159 typename CalculationType
161 struct tag<geographic<FormulaPolicy, Spheroid, CalculationType> >
163 typedef strategy_tag_distance_point_point type;
169 typename FormulaPolicy,
171 typename CalculationType,
175 struct return_type<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>
176 : geographic<FormulaPolicy, Spheroid, CalculationType>::template calculation_type<P1, P2>
182 typename FormulaPolicy,
184 typename CalculationType
186 struct comparable_type<geographic<FormulaPolicy, Spheroid, CalculationType> >
188 typedef geographic<FormulaPolicy, Spheroid, CalculationType> type;
194 typename FormulaPolicy,
196 typename CalculationType
198 struct get_comparable<geographic<FormulaPolicy, Spheroid, CalculationType> >
200 static inline geographic<FormulaPolicy, Spheroid, CalculationType>
201 apply(geographic<FormulaPolicy, Spheroid, CalculationType> const& input)
209 typename FormulaPolicy,
211 typename CalculationType,
215 struct result_from_distance<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>
217 template <typename T>
218 static inline typename return_type<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>::type
219 apply(geographic<FormulaPolicy, Spheroid, CalculationType> const& , T const& value)
226 template <typename Point1, typename Point2>
227 struct default_strategy<point_tag, point_tag, Point1, Point2, geographic_tag, geographic_tag>
229 typedef strategy::distance::geographic
234 typename select_coordinate_type<Point1, Point2>::type
240 } // namespace services
241 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
244 }} // namespace strategy::distance
247 }} // namespace boost::geometry
250 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP