2
2
3
3
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
4
4
5
- // Copyright (c) 2015-2022 , Oracle and/or its affiliates.
5
+ // Copyright (c) 2015-2025 , Oracle and/or its affiliates.
6
6
7
+ // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
7
8
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
8
9
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9
10
// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program
@@ -151,11 +152,7 @@ struct constants_on_spheroid<CoordinateType, degree, false>
151
152
template <typename Units, typename CoordinateType>
152
153
inline CoordinateType latitude_convert_ep (CoordinateType const & lat)
153
154
{
154
- typedef math::detail::constants_on_spheroid
155
- <
156
- CoordinateType,
157
- Units
158
- > constants;
155
+ using constants = math::detail::constants_on_spheroid<CoordinateType, Units>;
159
156
160
157
return constants::quarter_period () - lat;
161
158
}
@@ -164,31 +161,21 @@ inline CoordinateType latitude_convert_ep(CoordinateType const& lat)
164
161
template <typename Units, bool IsEquatorial, typename T>
165
162
static bool is_latitude_pole (T const & lat)
166
163
{
167
- typedef math::detail::constants_on_spheroid
168
- <
169
- T,
170
- Units
171
- > constants;
164
+ using constants = math::detail::constants_on_spheroid<T, Units>;
172
165
173
166
return math::equals (math::abs (IsEquatorial
174
167
? lat
175
168
: math::latitude_convert_ep<Units>(lat)),
176
169
constants::quarter_period ());
177
-
178
170
}
179
171
180
172
181
173
template <typename Units, typename T>
182
174
static bool is_longitude_antimeridian (T const & lon)
183
175
{
184
- typedef math::detail::constants_on_spheroid
185
- <
186
- T,
187
- Units
188
- > constants;
176
+ using constants = math::detail::constants_on_spheroid<T, Units>;
189
177
190
178
return math::equals (math::abs (lon), constants::half_period ());
191
-
192
179
}
193
180
194
181
@@ -218,7 +205,7 @@ struct latitude_convert_if_polar<Units, false>
218
205
template <typename Units, typename CoordinateType, bool IsEquatorial = true >
219
206
class normalize_spheroidal_coordinates
220
207
{
221
- typedef constants_on_spheroid<CoordinateType, Units> constants ;
208
+ using constants = constants_on_spheroid<CoordinateType, Units>;
222
209
223
210
protected:
224
211
static inline CoordinateType normalize_up (CoordinateType const & value)
@@ -236,17 +223,22 @@ class normalize_spheroidal_coordinates
236
223
}
237
224
238
225
public:
239
- static inline void apply (CoordinateType& longitude)
226
+ static inline void apply (CoordinateType& longitude, bool exact = true )
240
227
{
241
228
// normalize longitude
242
- if (math::equals (math::abs (longitude), constants::half_period ()))
229
+ CoordinateType const epsilon = std::numeric_limits<float >::epsilon ();
230
+ static constexpr bool is_integer = std::numeric_limits<CoordinateType>::is_integer;
231
+
232
+ if (exact || is_integer ? math::equals (math::abs (longitude), constants::half_period ())
233
+ : math::abs (math::abs (longitude) - constants::half_period ()) <= epsilon)
243
234
{
244
235
longitude = constants::half_period ();
245
236
}
246
237
else if (longitude > constants::half_period ())
247
238
{
248
239
longitude = normalize_up (longitude);
249
- if (math::equals (longitude, -constants::half_period ()))
240
+ if (exact || is_integer ? math::equals (longitude, -constants::half_period ())
241
+ : math::abs (longitude + constants::half_period ()) <= epsilon)
250
242
{
251
243
longitude = constants::half_period ();
252
244
}
@@ -259,7 +251,8 @@ class normalize_spheroidal_coordinates
259
251
260
252
static inline void apply (CoordinateType& longitude,
261
253
CoordinateType& latitude,
262
- bool normalize_poles = true )
254
+ bool normalize_poles = true ,
255
+ bool exact = true )
263
256
{
264
257
latitude_convert_if_polar<Units, IsEquatorial>::apply (latitude);
265
258
@@ -288,7 +281,7 @@ class normalize_spheroidal_coordinates
288
281
#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
289
282
290
283
// normalize longitude
291
- apply (longitude);
284
+ apply (longitude, exact );
292
285
293
286
// finally normalize poles
294
287
if (normalize_poles)
@@ -317,7 +310,7 @@ class normalize_spheroidal_coordinates
317
310
template <typename Units, typename CoordinateType>
318
311
inline void normalize_angle_loop (CoordinateType& angle)
319
312
{
320
- typedef constants_on_spheroid<CoordinateType, Units> constants ;
313
+ using constants = constants_on_spheroid<CoordinateType, Units>;
321
314
CoordinateType const pi = constants::half_period ();
322
315
CoordinateType const two_pi = constants::period ();
323
316
while (angle > pi)
@@ -329,7 +322,7 @@ inline void normalize_angle_loop(CoordinateType& angle)
329
322
template <typename Units, typename CoordinateType>
330
323
inline void normalize_angle_cond (CoordinateType& angle)
331
324
{
332
- typedef constants_on_spheroid<CoordinateType, Units> constants ;
325
+ using constants = constants_on_spheroid<CoordinateType, Units>;
333
326
CoordinateType const pi = constants::half_period ();
334
327
CoordinateType const two_pi = constants::period ();
335
328
if (angle > pi)
@@ -353,22 +346,24 @@ inline void normalize_angle_cond(CoordinateType& angle)
353
346
*/
354
347
template <typename Units, typename CoordinateType>
355
348
inline void normalize_spheroidal_coordinates (CoordinateType& longitude,
356
- CoordinateType& latitude)
349
+ CoordinateType& latitude,
350
+ bool exact = true )
357
351
{
358
352
detail::normalize_spheroidal_coordinates
359
353
<
360
354
Units, CoordinateType
361
- >::apply (longitude, latitude);
355
+ >::apply (longitude, latitude, true , exact );
362
356
}
363
357
364
358
template <typename Units, bool IsEquatorial, typename CoordinateType>
365
359
inline void normalize_spheroidal_coordinates (CoordinateType& longitude,
366
- CoordinateType& latitude)
360
+ CoordinateType& latitude,
361
+ bool exact = true )
367
362
{
368
363
detail::normalize_spheroidal_coordinates
369
364
<
370
365
Units, CoordinateType, IsEquatorial
371
- >::apply (longitude, latitude);
366
+ >::apply (longitude, latitude, true , exact );
372
367
}
373
368
374
369
/* !
@@ -381,12 +376,12 @@ inline void normalize_spheroidal_coordinates(CoordinateType& longitude,
381
376
\ingroup utility
382
377
*/
383
378
template <typename Units, typename CoordinateType>
384
- inline void normalize_longitude (CoordinateType& longitude)
379
+ inline void normalize_longitude (CoordinateType& longitude, bool exact = true )
385
380
{
386
381
detail::normalize_spheroidal_coordinates
387
382
<
388
383
Units, CoordinateType
389
- >::apply (longitude);
384
+ >::apply (longitude, exact );
390
385
}
391
386
392
387
/* !
@@ -400,7 +395,7 @@ inline void normalize_longitude(CoordinateType& longitude)
400
395
template <typename Units, typename CoordinateType>
401
396
inline void normalize_azimuth (CoordinateType& angle)
402
397
{
403
- normalize_longitude<Units, CoordinateType>(angle);
398
+ math:: normalize_longitude<Units, CoordinateType>(angle, true );
404
399
}
405
400
406
401
/* !
@@ -435,7 +430,7 @@ inline CoordinateType longitude_distance_signed(CoordinateType const& longitude1
435
430
CoordinateType const & longitude2)
436
431
{
437
432
CoordinateType diff = longitude2 - longitude1;
438
- math::normalize_longitude<Units, CoordinateType>(diff);
433
+ math::normalize_longitude<Units, CoordinateType>(diff, true );
439
434
return diff;
440
435
}
441
436
@@ -453,10 +448,7 @@ template <typename Units, typename CoordinateType>
453
448
inline CoordinateType longitude_distance_unsigned (CoordinateType const & longitude1,
454
449
CoordinateType const & longitude2)
455
450
{
456
- typedef math::detail::constants_on_spheroid
457
- <
458
- CoordinateType, Units
459
- > constants;
451
+ using constants = math::detail::constants_on_spheroid<CoordinateType, Units>;
460
452
461
453
CoordinateType const c0 = 0 ;
462
454
CoordinateType diff = longitude_distance_signed<Units>(longitude1, longitude2);
0 commit comments