]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/strategies/geographic/distance.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / geometry / strategies / geographic / distance.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2016 Barend Gehrels, Amsterdam, the Netherlands.
4
5 // This file was modified by Oracle on 2014-2018.
6 // Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
7
8 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
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)
14
15
16 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP
17 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP
18
19
20 #include <boost/geometry/core/coordinate_type.hpp>
21 #include <boost/geometry/core/radian_access.hpp>
22 #include <boost/geometry/core/radius.hpp>
23
24 #include <boost/geometry/formulas/andoyer_inverse.hpp>
25 #include <boost/geometry/formulas/elliptic_arc_length.hpp>
26 #include <boost/geometry/formulas/flattening.hpp>
27
28 #include <boost/geometry/srs/spheroid.hpp>
29
30 #include <boost/geometry/strategies/distance.hpp>
31 #include <boost/geometry/strategies/geographic/parameters.hpp>
32
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>
37
38 #include <boost/geometry/geometries/point_xy.hpp>
39
40 namespace boost { namespace geometry
41 {
42
43 namespace strategy { namespace distance
44 {
45
46 /*!
47 \brief Distance calculation for geographic coordinates on a spheroid
48 \ingroup strategies
49 \tparam FormulaPolicy Formula used to calculate azimuths
50 \tparam Spheroid The spheroid model
51 \tparam CalculationType \tparam_calculation
52
53 \qbk{
54 [heading See also]
55 \* [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
56 \* [link geometry.reference.srs.srs_spheroid srs::spheroid]
57 }
58 */
59 template
60 <
61 typename FormulaPolicy = strategy::andoyer,
62 typename Spheroid = srs::spheroid<double>,
63 typename CalculationType = void
64 >
65 class geographic
66 {
67 public :
68 template <typename Point1, typename Point2>
69 struct calculation_type
70 : promote_floating_point
71 <
72 typename select_calculation_type
73 <
74 Point1,
75 Point2,
76 CalculationType
77 >::type
78 >
79 {};
80
81 typedef Spheroid model_type;
82
83 inline geographic()
84 : m_spheroid()
85 {}
86
87 explicit inline geographic(Spheroid const& spheroid)
88 : m_spheroid(spheroid)
89 {}
90
91 template <typename CT>
92 static inline CT apply(CT lon1, CT lat1, CT lon2, CT lat2,
93 Spheroid const& spheroid)
94 {
95 typedef typename formula::elliptic_arc_length
96 <
97 CT, strategy::default_order<FormulaPolicy>::value
98 > elliptic_arc_length;
99
100 typename elliptic_arc_length::result res =
101 elliptic_arc_length::apply(lon1, lat1, lon2, lat2, spheroid);
102
103 if (res.meridian)
104 {
105 return res.distance;
106 }
107
108 return FormulaPolicy::template inverse
109 <
110 CT, true, false, false, false, false
111 >::apply(lon1, lat1, lon2, lat2, spheroid).distance;
112 }
113
114 template <typename Point1, typename Point2>
115 inline typename calculation_type<Point1, Point2>::type
116 apply(Point1 const& point1, Point2 const& point2) const
117 {
118 typedef typename calculation_type<Point1, Point2>::type CT;
119
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);
124
125 return apply(lon1, lat1, lon2, lat2, m_spheroid);
126 }
127
128 // points on a meridian not crossing poles
129 template <typename CT>
130 inline CT meridian(CT lat1, CT lat2) const
131 {
132 typedef typename formula::elliptic_arc_length
133 <
134 CT, strategy::default_order<FormulaPolicy>::value
135 > elliptic_arc_length;
136
137 return elliptic_arc_length::meridian_not_crossing_pole_dist(lat1, lat2,
138 m_spheroid);
139 }
140
141 inline Spheroid const& model() const
142 {
143 return m_spheroid;
144 }
145
146 private :
147 Spheroid m_spheroid;
148 };
149
150
151 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
152 namespace services
153 {
154
155 template
156 <
157 typename FormulaPolicy,
158 typename Spheroid,
159 typename CalculationType
160 >
161 struct tag<geographic<FormulaPolicy, Spheroid, CalculationType> >
162 {
163 typedef strategy_tag_distance_point_point type;
164 };
165
166
167 template
168 <
169 typename FormulaPolicy,
170 typename Spheroid,
171 typename CalculationType,
172 typename P1,
173 typename P2
174 >
175 struct return_type<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>
176 : geographic<FormulaPolicy, Spheroid, CalculationType>::template calculation_type<P1, P2>
177 {};
178
179
180 template
181 <
182 typename FormulaPolicy,
183 typename Spheroid,
184 typename CalculationType
185 >
186 struct comparable_type<geographic<FormulaPolicy, Spheroid, CalculationType> >
187 {
188 typedef geographic<FormulaPolicy, Spheroid, CalculationType> type;
189 };
190
191
192 template
193 <
194 typename FormulaPolicy,
195 typename Spheroid,
196 typename CalculationType
197 >
198 struct get_comparable<geographic<FormulaPolicy, Spheroid, CalculationType> >
199 {
200 static inline geographic<FormulaPolicy, Spheroid, CalculationType>
201 apply(geographic<FormulaPolicy, Spheroid, CalculationType> const& input)
202 {
203 return input;
204 }
205 };
206
207 template
208 <
209 typename FormulaPolicy,
210 typename Spheroid,
211 typename CalculationType,
212 typename P1,
213 typename P2
214 >
215 struct result_from_distance<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>
216 {
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)
220 {
221 return value;
222 }
223 };
224
225
226 template <typename Point1, typename Point2>
227 struct default_strategy<point_tag, point_tag, Point1, Point2, geographic_tag, geographic_tag>
228 {
229 typedef strategy::distance::geographic
230 <
231 strategy::andoyer,
232 srs::spheroid
233 <
234 typename select_coordinate_type<Point1, Point2>::type
235 >
236 > type;
237 };
238
239
240 } // namespace services
241 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
242
243
244 }} // namespace strategy::distance
245
246
247 }} // namespace boost::geometry
248
249
250 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP