]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / util / normalize_spheroidal_coordinates.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2015-2016, Oracle and/or its affiliates.
4
5// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7
8// Licensed under the Boost Software License version 1.0.
9// http://www.boost.org/users/license.html
10
11#ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
12#define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
13
14#include <boost/geometry/core/assert.hpp>
15#include <boost/geometry/core/cs.hpp>
16#include <boost/geometry/util/math.hpp>
17
18
19namespace boost { namespace geometry
20{
21
22namespace math
23{
24
25#ifndef DOXYGEN_NO_DETAIL
26namespace detail
27{
28
29
30template <typename CoordinateType, typename Units>
31struct constants_on_spheroid
32{
33 static inline CoordinateType period()
34 {
35 return math::two_pi<CoordinateType>();
36 }
37
38 static inline CoordinateType half_period()
39 {
40 return math::pi<CoordinateType>();
41 }
42
43 static inline CoordinateType min_longitude()
44 {
45 static CoordinateType const minus_pi = -math::pi<CoordinateType>();
46 return minus_pi;
47 }
48
49 static inline CoordinateType max_longitude()
50 {
51 return math::pi<CoordinateType>();
52 }
53
54 static inline CoordinateType min_latitude()
55 {
56 static CoordinateType const minus_half_pi
57 = -math::half_pi<CoordinateType>();
58 return minus_half_pi;
59 }
60
61 static inline CoordinateType max_latitude()
62 {
63 return math::half_pi<CoordinateType>();
64 }
65};
66
67template <typename CoordinateType>
68struct constants_on_spheroid<CoordinateType, degree>
69{
70 static inline CoordinateType period()
71 {
72 return CoordinateType(360.0);
73 }
74
75 static inline CoordinateType half_period()
76 {
77 return CoordinateType(180.0);
78 }
79
80 static inline CoordinateType min_longitude()
81 {
82 return CoordinateType(-180.0);
83 }
84
85 static inline CoordinateType max_longitude()
86 {
87 return CoordinateType(180.0);
88 }
89
90 static inline CoordinateType min_latitude()
91 {
92 return CoordinateType(-90.0);
93 }
94
95 static inline CoordinateType max_latitude()
96 {
97 return CoordinateType(90.0);
98 }
99};
100
101
102template <typename Units, typename CoordinateType>
103class normalize_spheroidal_coordinates
104{
105 typedef constants_on_spheroid<CoordinateType, Units> constants;
106
107protected:
108 static inline CoordinateType normalize_up(CoordinateType const& value)
109 {
110 return
111 math::mod(value + constants::half_period(), constants::period())
112 - constants::half_period();
113 }
114
115 static inline CoordinateType normalize_down(CoordinateType const& value)
116 {
117 return
118 math::mod(value - constants::half_period(), constants::period())
119 + constants::half_period();
120 }
121
122public:
123 static inline void apply(CoordinateType& longitude)
124 {
125 // normalize longitude
126 if (math::equals(math::abs(longitude), constants::half_period()))
127 {
128 longitude = constants::half_period();
129 }
130 else if (longitude > constants::half_period())
131 {
132 longitude = normalize_up(longitude);
133 if (math::equals(longitude, -constants::half_period()))
134 {
135 longitude = constants::half_period();
136 }
137 }
138 else if (longitude < -constants::half_period())
139 {
140 longitude = normalize_down(longitude);
141 }
142 }
143
144 static inline void apply(CoordinateType& longitude,
145 CoordinateType& latitude,
146 bool normalize_poles = true)
147 {
148#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
149 // normalize latitude
150 if (math::larger(latitude, constants::half_period()))
151 {
152 latitude = normalize_up(latitude);
153 }
154 else if (math::smaller(latitude, -constants::half_period()))
155 {
156 latitude = normalize_down(latitude);
157 }
158
159 // fix latitude range
160 if (latitude < constants::min_latitude())
161 {
162 latitude = -constants::half_period() - latitude;
163 longitude -= constants::half_period();
164 }
165 else if (latitude > constants::max_latitude())
166 {
167 latitude = constants::half_period() - latitude;
168 longitude -= constants::half_period();
169 }
170#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
171
172 // normalize longitude
173 apply(longitude);
174
175 // finally normalize poles
176 if (normalize_poles)
177 {
178 if (math::equals(math::abs(latitude), constants::max_latitude()))
179 {
180 // for the north and south pole we set the longitude to 0
181 // (works for both radians and degrees)
182 longitude = CoordinateType(0);
183 }
184 }
185
186#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
187 BOOST_GEOMETRY_ASSERT(! math::larger(constants::min_latitude(), latitude));
188 BOOST_GEOMETRY_ASSERT(! math::larger(latitude, constants::max_latitude()));
189#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
190
191 BOOST_GEOMETRY_ASSERT(math::smaller(constants::min_longitude(), longitude));
192 BOOST_GEOMETRY_ASSERT(! math::larger(longitude, constants::max_longitude()));
193 }
194};
195
196
197} // namespace detail
198#endif // DOXYGEN_NO_DETAIL
199
200
201/*!
202\brief Short utility to normalize the coordinates on a spheroid
203\tparam Units The units of the coordindate system in the spheroid
204\tparam CoordinateType The type of the coordinates
205\param longitude Longitude
206\param latitude Latitude
207\ingroup utility
208*/
209template <typename Units, typename CoordinateType>
210inline void normalize_spheroidal_coordinates(CoordinateType& longitude,
211 CoordinateType& latitude)
212{
213 detail::normalize_spheroidal_coordinates
214 <
215 Units, CoordinateType
216 >::apply(longitude, latitude);
217}
218
219
220/*!
221\brief Short utility to normalize the longitude on a spheroid.
222 Note that in general both coordinates should be normalized at once.
223 This utility is suitable e.g. for normalization of the difference of longitudes.
224\tparam Units The units of the coordindate system in the spheroid
225\tparam CoordinateType The type of the coordinates
226\param longitude Longitude
227\ingroup utility
228*/
229template <typename Units, typename CoordinateType>
230inline void normalize_longitude(CoordinateType& longitude)
231{
232 detail::normalize_spheroidal_coordinates
233 <
234 Units, CoordinateType
235 >::apply(longitude);
236}
237
238
239/*!
240\brief Short utility to calculate difference between two longitudes
241 normalized in range (-180, 180].
242\tparam Units The units of the coordindate system in the spheroid
243\tparam CoordinateType The type of the coordinates
244\param longitude1 Longitude 1
245\param longitude2 Longitude 2
246\ingroup utility
247*/
248template <typename Units, typename CoordinateType>
249inline CoordinateType longitude_distance_signed(CoordinateType const& longitude1,
250 CoordinateType const& longitude2)
251{
252 CoordinateType diff = longitude2 - longitude1;
253 math::normalize_longitude<Units, CoordinateType>(diff);
254 return diff;
255}
256
257
258/*!
259\brief Short utility to calculate difference between two longitudes
260 normalized in range [0, 360).
261\tparam Units The units of the coordindate system in the spheroid
262\tparam CoordinateType The type of the coordinates
263\param longitude1 Longitude 1
264\param longitude2 Longitude 2
265\ingroup utility
266*/
267template <typename Units, typename CoordinateType>
268inline CoordinateType longitude_distance_unsigned(CoordinateType const& longitude1,
269 CoordinateType const& longitude2)
270{
271 typedef math::detail::constants_on_spheroid
272 <
273 CoordinateType, Units
274 > constants;
275
276 CoordinateType const c0 = 0;
277 CoordinateType diff = longitude_distance_signed<Units>(longitude1, longitude2);
278 if (diff < c0) // (-180, 180] -> [0, 360)
279 {
280 diff += constants::period();
281 }
282 return diff;
283}
284
285} // namespace math
286
287
288}} // namespace boost::geometry
289
290#endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP