1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2015-2022, Oracle and/or its affiliates.
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
11 #ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
12 #define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
14 #include <boost/geometry/core/assert.hpp>
15 #include <boost/geometry/util/math.hpp>
16 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
19 namespace boost { namespace geometry
25 #ifndef DOXYGEN_NO_DETAIL
30 template <typename Units, typename CoordinateType, bool IsEquatorial = true>
31 class normalize_spheroidal_box_coordinates
34 typedef normalize_spheroidal_coordinates<Units, CoordinateType> normalize;
35 typedef constants_on_spheroid<CoordinateType, Units> constants;
37 static inline bool is_band(CoordinateType const& longitude1,
38 CoordinateType const& longitude2)
40 return math::larger_or_equals(math::abs(longitude1 - longitude2),
45 static inline void apply(CoordinateType& longitude1,
46 CoordinateType& latitude1,
47 CoordinateType& longitude2,
48 CoordinateType& latitude2,
51 normalize::apply(longitude1, latitude1, false);
52 normalize::apply(longitude2, latitude2, false);
54 latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude1);
55 latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude2);
57 if (math::equals(latitude1, constants::min_latitude())
58 && math::equals(latitude2, constants::min_latitude()))
60 // box degenerates to the south pole
61 longitude1 = longitude2 = CoordinateType(0);
63 else if (math::equals(latitude1, constants::max_latitude())
64 && math::equals(latitude2, constants::max_latitude()))
66 // box degenerates to the north pole
67 longitude1 = longitude2 = CoordinateType(0);
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();
76 else if (longitude1 > longitude2)
78 // the box crosses the antimeridian, so we need to adjust
80 longitude2 += constants::period();
83 latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude1);
84 latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude2);
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()));
92 BOOST_GEOMETRY_ASSERT(! math::larger(longitude1, longitude2));
93 BOOST_GEOMETRY_ASSERT(! math::smaller(longitude1, constants::min_longitude()));
94 BOOST_GEOMETRY_ASSERT(! math::larger(longitude2 - longitude1, constants::period()));
97 static inline void apply(CoordinateType& longitude1,
98 CoordinateType& latitude1,
99 CoordinateType& longitude2,
100 CoordinateType& latitude2)
102 bool const band = is_band(longitude1, longitude2);
104 apply(longitude1, latitude1, longitude2, latitude2, band);
109 } // namespace detail
110 #endif // DOXYGEN_NO_DETAIL
114 \brief Short utility to normalize the coordinates of a box on a spheroid
115 \tparam Units The units of the coordindate system in the spheroid
116 \tparam CoordinateType The type of the coordinates
117 \param longitude1 Minimum longitude of the box
118 \param latitude1 Minimum latitude of the box
119 \param longitude2 Maximum longitude of the box
120 \param latitude2 Maximum latitude of the box
123 template <typename Units, typename CoordinateType>
124 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
125 CoordinateType& latitude1,
126 CoordinateType& longitude2,
127 CoordinateType& latitude2)
129 detail::normalize_spheroidal_box_coordinates
131 Units, CoordinateType
132 >::apply(longitude1, latitude1, longitude2, latitude2);
135 template <typename Units, bool IsEquatorial, typename CoordinateType>
136 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
137 CoordinateType& latitude1,
138 CoordinateType& longitude2,
139 CoordinateType& latitude2)
141 detail::normalize_spheroidal_box_coordinates
143 Units, CoordinateType, IsEquatorial
144 >::apply(longitude1, latitude1, longitude2, latitude2);
148 \brief Short utility to normalize the coordinates of a box on a spheroid
149 \tparam Units The units of the coordindate system in the spheroid
150 \tparam CoordinateType The type of the coordinates
151 \param longitude1 Minimum longitude of the box
152 \param latitude1 Minimum latitude of the box
153 \param longitude2 Maximum longitude of the box
154 \param latitude2 Maximum latitude of the box
155 \param band Indicates whether the box should be treated as a band or
156 not and avoid the computation done in the other version of the function
159 template <typename Units, typename CoordinateType>
160 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
161 CoordinateType& latitude1,
162 CoordinateType& longitude2,
163 CoordinateType& latitude2,
166 detail::normalize_spheroidal_box_coordinates
168 Units, CoordinateType
169 >::apply(longitude1, latitude1, longitude2, latitude2, band);
172 template <typename Units, bool IsEquatorial, typename CoordinateType>
173 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
174 CoordinateType& latitude1,
175 CoordinateType& longitude2,
176 CoordinateType& latitude2,
179 detail::normalize_spheroidal_box_coordinates
181 Units, CoordinateType, IsEquatorial
182 >::apply(longitude1, latitude1, longitude2, latitude2, band);
189 }} // namespace boost::geometry
191 #endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP