1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2015-2017, 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::smaller(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()));
95 (! math::larger(longitude2 - longitude1, constants::period()));
98 static inline void apply(CoordinateType& longitude1,
99 CoordinateType& latitude1,
100 CoordinateType& longitude2,
101 CoordinateType& latitude2)
103 bool const band = is_band(longitude1, longitude2);
105 apply(longitude1, latitude1, longitude2, latitude2, band);
110 } // namespace detail
111 #endif // DOXYGEN_NO_DETAIL
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
124 template <typename Units, typename CoordinateType>
125 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
126 CoordinateType& latitude1,
127 CoordinateType& longitude2,
128 CoordinateType& latitude2)
130 detail::normalize_spheroidal_box_coordinates
132 Units, CoordinateType
133 >::apply(longitude1, latitude1, longitude2, latitude2);
136 template <typename Units, bool IsEquatorial, typename CoordinateType>
137 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
138 CoordinateType& latitude1,
139 CoordinateType& longitude2,
140 CoordinateType& latitude2)
142 detail::normalize_spheroidal_box_coordinates
144 Units, CoordinateType, IsEquatorial
145 >::apply(longitude1, latitude1, longitude2, latitude2);
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
160 template <typename Units, typename CoordinateType>
161 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
162 CoordinateType& latitude1,
163 CoordinateType& longitude2,
164 CoordinateType& latitude2,
167 detail::normalize_spheroidal_box_coordinates
169 Units, CoordinateType
170 >::apply(longitude1, latitude1, longitude2, latitude2, band);
173 template <typename Units, bool IsEquatorial, typename CoordinateType>
174 inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
175 CoordinateType& latitude1,
176 CoordinateType& longitude2,
177 CoordinateType& latitude2,
180 detail::normalize_spheroidal_box_coordinates
182 Units, CoordinateType, IsEquatorial
183 >::apply(longitude1, latitude1, longitude2, latitude2, band);
190 }} // namespace boost::geometry
192 #endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP