1 // Boost.Geometry
2 
3 // Copyright (c) 2017-2018 Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7 
8 // Use, modification and distribution is subject to the Boost Software License,
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 
12 #ifndef BOOST_GEOMETRY_FORMULAS_MERIDIAN_SEGMENT_HPP
13 #define BOOST_GEOMETRY_FORMULAS_MERIDIAN_SEGMENT_HPP
14 
15 #include <boost/math/constants/constants.hpp>
16 
17 #include <boost/geometry/core/radius.hpp>
18 
19 #include <boost/geometry/util/condition.hpp>
20 #include <boost/geometry/util/math.hpp>
21 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
22 
23 namespace boost { namespace geometry { namespace formula
24 {
25 
26 /*!
27 \brief Test if a segment is meridian or not.
28 */
29 
30 class meridian_segment
31 {
32 
33 public :
34 
35     enum SegmentType {NonMeridian, MeridianCrossingPole, MeridianNotCrossingPole};
36 
37     template <typename T>
is_meridian(T lon1,T lat1,T lon2,T lat2)38     static inline SegmentType is_meridian(T lon1, T lat1, T lon2, T lat2)
39     {
40         SegmentType res = NonMeridian;
41         T diff = geometry::math::longitude_distance_signed<geometry::radian>(lon1, lon2);
42 
43         if ( meridian_not_crossing_pole(lat1, lat2, diff) )
44         {
45             res = MeridianNotCrossingPole;
46         }
47         else if ( meridian_crossing_pole(diff) )
48         {
49             res = MeridianCrossingPole;
50         }
51         return res;
52     }
53 
54     template <typename T>
meridian_not_crossing_pole(T lat1,T lat2,T diff)55     static bool meridian_not_crossing_pole(T lat1, T lat2, T diff)
56     {
57         T half_pi = math::half_pi<T>();
58         return math::equals(diff, T(0)) ||
59                (math::equals(lat2, half_pi) && math::equals(lat1, -half_pi));
60     }
61 
62     template <typename T>
meridian_crossing_pole(T diff)63     static bool meridian_crossing_pole(T diff)
64     {
65         return math::equals(math::abs(diff), math::pi<T>());
66     }
67 
68 };
69 
70 }}} // namespace boost::geometry::formula
71 
72 #endif //BOOST_GEOMETRY_FORMULAS_MERIDIAN_SEGMENT_HPP
73