• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2015-2017, 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_BOX_COORDINATES_HPP
12 #define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
13 
14 #include <boost/geometry/core/assert.hpp>
15 #include <boost/geometry/util/math.hpp>
16 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
17 
18 
19 namespace boost { namespace geometry
20 {
21 
22 namespace math
23 {
24 
25 #ifndef DOXYGEN_NO_DETAIL
26 namespace detail
27 {
28 
29 
30 template <typename Units, typename CoordinateType, bool IsEquatorial = true>
31 class normalize_spheroidal_box_coordinates
32 {
33 private:
34     typedef normalize_spheroidal_coordinates<Units, CoordinateType> normalize;
35     typedef constants_on_spheroid<CoordinateType, Units> constants;
36 
is_band(CoordinateType const & longitude1,CoordinateType const & longitude2)37     static inline bool is_band(CoordinateType const& longitude1,
38                                CoordinateType const& longitude2)
39     {
40         return ! math::smaller(math::abs(longitude1 - longitude2),
41                                constants::period());
42     }
43 
44 public:
apply(CoordinateType & longitude1,CoordinateType & latitude1,CoordinateType & longitude2,CoordinateType & latitude2,bool band)45     static inline void apply(CoordinateType& longitude1,
46                              CoordinateType& latitude1,
47                              CoordinateType& longitude2,
48                              CoordinateType& latitude2,
49                              bool band)
50     {
51         normalize::apply(longitude1, latitude1, false);
52         normalize::apply(longitude2, latitude2, false);
53 
54         latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude1);
55         latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude2);
56 
57         if (math::equals(latitude1, constants::min_latitude())
58             && math::equals(latitude2, constants::min_latitude()))
59         {
60             // box degenerates to the south pole
61             longitude1 = longitude2 = CoordinateType(0);
62         }
63         else if (math::equals(latitude1, constants::max_latitude())
64                  && math::equals(latitude2, constants::max_latitude()))
65         {
66             // box degenerates to the north pole
67             longitude1 = longitude2 = CoordinateType(0);
68         }
69         else if (band)
70         {
71             // the box is a band between two small circles (parallel
72             // to the equator) on the spheroid
73             longitude1 = constants::min_longitude();
74             longitude2 = constants::max_longitude();
75         }
76         else if (longitude1 > longitude2)
77         {
78             // the box crosses the antimeridian, so we need to adjust
79             // the longitudes
80             longitude2 += constants::period();
81         }
82 
83         latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude1);
84         latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude2);
85 
86 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
87         BOOST_GEOMETRY_ASSERT(! math::larger(latitude1, latitude2));
88         BOOST_GEOMETRY_ASSERT(! math::smaller(latitude1, constants::min_latitude()));
89         BOOST_GEOMETRY_ASSERT(! math::larger(latitude2, constants::max_latitude()));
90 #endif
91 
92         BOOST_GEOMETRY_ASSERT(! math::larger(longitude1, longitude2));
93         BOOST_GEOMETRY_ASSERT(! math::smaller(longitude1, constants::min_longitude()));
94         BOOST_GEOMETRY_ASSERT
95             (! math::larger(longitude2 - longitude1, constants::period()));
96     }
97 
apply(CoordinateType & longitude1,CoordinateType & latitude1,CoordinateType & longitude2,CoordinateType & latitude2)98     static inline void apply(CoordinateType& longitude1,
99                              CoordinateType& latitude1,
100                              CoordinateType& longitude2,
101                              CoordinateType& latitude2)
102     {
103         bool const band = is_band(longitude1, longitude2);
104 
105         apply(longitude1, latitude1, longitude2, latitude2, band);
106     }
107 };
108 
109 
110 } // namespace detail
111 #endif // DOXYGEN_NO_DETAIL
112 
113 
114 /*!
115 \brief Short utility to normalize the coordinates of a box on a spheroid
116 \tparam Units The units of the coordindate system in the spheroid
117 \tparam CoordinateType The type of the coordinates
118 \param longitude1 Minimum longitude of the box
119 \param latitude1 Minimum latitude of the box
120 \param longitude2 Maximum longitude of the box
121 \param latitude2 Maximum latitude of the box
122 \ingroup utility
123 */
124 template <typename Units, typename CoordinateType>
normalize_spheroidal_box_coordinates(CoordinateType & longitude1,CoordinateType & latitude1,CoordinateType & longitude2,CoordinateType & latitude2)125 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
126                                                  CoordinateType& latitude1,
127                                                  CoordinateType& longitude2,
128                                                  CoordinateType& latitude2)
129 {
130     detail::normalize_spheroidal_box_coordinates
131         <
132             Units, CoordinateType
133         >::apply(longitude1, latitude1, longitude2, latitude2);
134 }
135 
136 template <typename Units, bool IsEquatorial, typename CoordinateType>
normalize_spheroidal_box_coordinates(CoordinateType & longitude1,CoordinateType & latitude1,CoordinateType & longitude2,CoordinateType & latitude2)137 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
138                                                  CoordinateType& latitude1,
139                                                  CoordinateType& longitude2,
140                                                  CoordinateType& latitude2)
141 {
142     detail::normalize_spheroidal_box_coordinates
143         <
144             Units, CoordinateType, IsEquatorial
145         >::apply(longitude1, latitude1, longitude2, latitude2);
146 }
147 
148 /*!
149 \brief Short utility to normalize the coordinates of a box on a spheroid
150 \tparam Units The units of the coordindate system in the spheroid
151 \tparam CoordinateType The type of the coordinates
152 \param longitude1 Minimum longitude of the box
153 \param latitude1 Minimum latitude of the box
154 \param longitude2 Maximum longitude of the box
155 \param latitude2 Maximum latitude of the box
156 \param band Indicates whether the box should be treated as a band or
157        not and avoid the computation done in the other version of the function
158 \ingroup utility
159 */
160 template <typename Units, typename CoordinateType>
normalize_spheroidal_box_coordinates(CoordinateType & longitude1,CoordinateType & latitude1,CoordinateType & longitude2,CoordinateType & latitude2,bool band)161 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
162                                                  CoordinateType& latitude1,
163                                                  CoordinateType& longitude2,
164                                                  CoordinateType& latitude2,
165                                                  bool band)
166 {
167     detail::normalize_spheroidal_box_coordinates
168         <
169             Units, CoordinateType
170         >::apply(longitude1, latitude1, longitude2, latitude2, band);
171 }
172 
173 template <typename Units, bool IsEquatorial, typename CoordinateType>
normalize_spheroidal_box_coordinates(CoordinateType & longitude1,CoordinateType & latitude1,CoordinateType & longitude2,CoordinateType & latitude2,bool band)174 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
175                                                  CoordinateType& latitude1,
176                                                  CoordinateType& longitude2,
177                                                  CoordinateType& latitude2,
178                                                  bool band)
179 {
180     detail::normalize_spheroidal_box_coordinates
181         <
182             Units, CoordinateType, IsEquatorial
183         >::apply(longitude1, latitude1, longitude2, latitude2, band);
184 }
185 
186 
187 } // namespace math
188 
189 
190 }} // namespace boost::geometry
191 
192 #endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
193