]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
20effc67 | 3 | // Copyright (c) 2015-2020, Oracle and/or its affiliates. |
92f5a8d4 TL |
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_STRATEGIES_NORMALIZE_HPP | |
12 | #define BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP | |
13 | ||
14 | #include <cstddef> | |
20effc67 | 15 | #include <type_traits> |
92f5a8d4 TL |
16 | |
17 | #include <boost/numeric/conversion/cast.hpp> | |
18 | ||
19 | #include <boost/geometry/core/access.hpp> | |
20 | #include <boost/geometry/core/coordinate_system.hpp> | |
21 | #include <boost/geometry/core/coordinate_type.hpp> | |
22 | #include <boost/geometry/core/cs.hpp> | |
23 | #include <boost/geometry/core/tag.hpp> | |
24 | #include <boost/geometry/core/tags.hpp> | |
25 | ||
26 | #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> | |
27 | #include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp> | |
28 | ||
29 | #include <boost/geometry/views/detail/indexed_point_view.hpp> | |
30 | ||
31 | ||
32 | namespace boost { namespace geometry | |
33 | { | |
34 | ||
35 | namespace strategy { namespace normalize | |
36 | { | |
37 | ||
38 | #ifndef DOXYGEN_NO_DETAIL | |
39 | namespace detail | |
40 | { | |
41 | ||
42 | struct do_nothing | |
43 | { | |
44 | template <typename GeometryIn, typename GeometryOut> | |
45 | static inline void apply(GeometryIn const&, GeometryOut&) | |
46 | { | |
47 | } | |
48 | }; | |
49 | ||
50 | ||
51 | template <std::size_t Dimension, std::size_t DimensionCount> | |
52 | struct assign_loop | |
53 | { | |
54 | template <typename CoordinateType, typename PointIn, typename PointOut> | |
55 | static inline void apply(CoordinateType const& longitude, | |
56 | CoordinateType const& latitude, | |
57 | PointIn const& point_in, | |
58 | PointOut& point_out) | |
59 | { | |
60 | geometry::set<Dimension>(point_out, boost::numeric_cast | |
61 | < | |
62 | typename coordinate_type<PointOut>::type | |
63 | >(geometry::get<Dimension>(point_in))); | |
64 | ||
65 | assign_loop | |
66 | < | |
67 | Dimension + 1, DimensionCount | |
68 | >::apply(longitude, latitude, point_in, point_out); | |
69 | } | |
70 | }; | |
71 | ||
72 | template <std::size_t DimensionCount> | |
73 | struct assign_loop<DimensionCount, DimensionCount> | |
74 | { | |
75 | template <typename CoordinateType, typename PointIn, typename PointOut> | |
76 | static inline void apply(CoordinateType const&, | |
77 | CoordinateType const&, | |
78 | PointIn const&, | |
79 | PointOut&) | |
80 | { | |
81 | } | |
82 | }; | |
83 | ||
84 | template <std::size_t DimensionCount> | |
85 | struct assign_loop<0, DimensionCount> | |
86 | { | |
87 | template <typename CoordinateType, typename PointIn, typename PointOut> | |
88 | static inline void apply(CoordinateType const& longitude, | |
89 | CoordinateType const& latitude, | |
90 | PointIn const& point_in, | |
91 | PointOut& point_out) | |
92 | { | |
93 | geometry::set<0>(point_out, boost::numeric_cast | |
94 | < | |
95 | typename coordinate_type<PointOut>::type | |
96 | >(longitude)); | |
97 | ||
98 | assign_loop | |
99 | < | |
100 | 1, DimensionCount | |
101 | >::apply(longitude, latitude, point_in, point_out); | |
102 | } | |
103 | }; | |
104 | ||
105 | template <std::size_t DimensionCount> | |
106 | struct assign_loop<1, DimensionCount> | |
107 | { | |
108 | template <typename CoordinateType, typename PointIn, typename PointOut> | |
109 | static inline void apply(CoordinateType const& longitude, | |
110 | CoordinateType const& latitude, | |
111 | PointIn const& point_in, | |
112 | PointOut& point_out) | |
113 | { | |
114 | geometry::set<1>(point_out, boost::numeric_cast | |
115 | < | |
116 | typename coordinate_type<PointOut>::type | |
117 | >(latitude)); | |
118 | ||
119 | assign_loop | |
120 | < | |
121 | 2, DimensionCount | |
122 | >::apply(longitude, latitude, point_in, point_out); | |
123 | } | |
124 | }; | |
125 | ||
126 | ||
127 | template <typename PointIn, typename PointOut, bool IsEquatorial = true> | |
128 | struct normalize_point | |
129 | { | |
130 | static inline void apply(PointIn const& point_in, PointOut& point_out) | |
131 | { | |
132 | typedef typename coordinate_type<PointIn>::type in_coordinate_type; | |
133 | ||
134 | in_coordinate_type longitude = geometry::get<0>(point_in); | |
135 | in_coordinate_type latitude = geometry::get<1>(point_in); | |
136 | ||
137 | math::normalize_spheroidal_coordinates | |
138 | < | |
139 | typename geometry::detail::cs_angular_units<PointIn>::type, | |
140 | IsEquatorial, | |
141 | in_coordinate_type | |
142 | >(longitude, latitude); | |
143 | ||
144 | assign_loop | |
145 | < | |
146 | 0, dimension<PointIn>::value | |
147 | >::apply(longitude, latitude, point_in, point_out); | |
148 | } | |
149 | }; | |
150 | ||
151 | ||
152 | template <typename BoxIn, typename BoxOut, bool IsEquatorial = true> | |
153 | class normalize_box | |
154 | { | |
155 | template <typename UnitsIn, typename UnitsOut, typename CoordinateInType> | |
156 | static inline void apply_to_coordinates(CoordinateInType& lon_min, | |
157 | CoordinateInType& lat_min, | |
158 | CoordinateInType& lon_max, | |
159 | CoordinateInType& lat_max, | |
160 | BoxIn const& box_in, | |
161 | BoxOut& box_out) | |
162 | { | |
163 | geometry::detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out); | |
164 | assign_loop | |
165 | < | |
166 | 0, dimension<BoxIn>::value | |
167 | >::apply(lon_min, | |
168 | lat_min, | |
169 | geometry::detail::indexed_point_view | |
170 | < | |
171 | BoxIn const, min_corner | |
172 | >(box_in), | |
173 | p_min_out); | |
174 | ||
175 | geometry::detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out); | |
176 | assign_loop | |
177 | < | |
178 | 0, dimension<BoxIn>::value | |
179 | >::apply(lon_max, | |
180 | lat_max, | |
181 | geometry::detail::indexed_point_view | |
182 | < | |
183 | BoxIn const, max_corner | |
184 | >(box_in), | |
185 | p_max_out); | |
186 | } | |
187 | ||
188 | public: | |
189 | static inline void apply(BoxIn const& box_in, BoxOut& box_out) | |
190 | { | |
191 | typedef typename coordinate_type<BoxIn>::type in_coordinate_type; | |
192 | ||
193 | in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in); | |
194 | in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in); | |
195 | in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in); | |
196 | in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in); | |
197 | ||
198 | math::normalize_spheroidal_box_coordinates | |
199 | < | |
200 | typename geometry::detail::cs_angular_units<BoxIn>::type, | |
201 | IsEquatorial, | |
202 | in_coordinate_type | |
203 | >(lon_min, lat_min, lon_max, lat_max); | |
204 | ||
205 | apply_to_coordinates | |
206 | < | |
207 | typename geometry::detail::cs_angular_units<BoxIn>::type, | |
208 | typename geometry::detail::cs_angular_units<BoxOut>::type | |
209 | >(lon_min, lat_min, lon_max, lat_max, box_in, box_out); | |
210 | } | |
211 | }; | |
212 | ||
213 | ||
214 | } // namespace detail | |
215 | #endif // DOXYGEN_NO_DETAIL | |
216 | ||
217 | struct cartesian_point | |
218 | : detail::do_nothing | |
219 | {}; | |
220 | ||
221 | struct cartesian_box | |
222 | : detail::do_nothing | |
223 | {}; | |
224 | ||
225 | struct spherical_point | |
226 | { | |
227 | template <typename PointIn, typename PointOut> | |
228 | static inline void apply(PointIn const& point_in, PointOut& point_out) | |
229 | { | |
230 | detail::normalize_point | |
231 | < | |
232 | PointIn, PointOut, | |
20effc67 | 233 | (! std::is_same |
92f5a8d4 | 234 | < |
20effc67 TL |
235 | typename cs_tag<PointIn>::type, |
236 | spherical_polar_tag | |
237 | >::value) | |
92f5a8d4 TL |
238 | >::apply(point_in, point_out); |
239 | } | |
240 | }; | |
241 | ||
242 | struct spherical_box | |
243 | { | |
244 | template <typename BoxIn, typename BoxOut> | |
245 | static inline void apply(BoxIn const& box_in, BoxOut& box_out) | |
246 | { | |
247 | detail::normalize_box | |
248 | < | |
249 | BoxIn, BoxOut, | |
20effc67 | 250 | (! std::is_same |
92f5a8d4 | 251 | < |
20effc67 TL |
252 | typename cs_tag<BoxIn>::type, |
253 | spherical_polar_tag | |
254 | >::value) | |
92f5a8d4 TL |
255 | >::apply(box_in, box_out); |
256 | } | |
257 | }; | |
258 | ||
259 | }} // namespace strategy::normalize | |
260 | ||
261 | }} // namespace boost::geometry | |
262 | ||
263 | #endif // BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP |