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