]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
3 | // Copyright (c) 2015, Oracle and/or its affiliates. | |
4 | ||
5 | // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle | |
6 | ||
7 | // Licensed under the Boost Software License version 1.0. | |
8 | // http://www.boost.org/users/license.html | |
9 | ||
10 | #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP | |
11 | #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP | |
12 | ||
13 | #include <cstddef> | |
14 | ||
15 | #include <boost/numeric/conversion/cast.hpp> | |
16 | ||
17 | #include <boost/geometry/core/access.hpp> | |
18 | #include <boost/geometry/core/coordinate_system.hpp> | |
19 | #include <boost/geometry/core/coordinate_type.hpp> | |
20 | #include <boost/geometry/core/cs.hpp> | |
21 | #include <boost/geometry/core/tag.hpp> | |
22 | #include <boost/geometry/core/tags.hpp> | |
23 | ||
24 | #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> | |
25 | #include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp> | |
26 | ||
27 | #include <boost/geometry/views/detail/indexed_point_view.hpp> | |
28 | ||
29 | ||
30 | namespace boost { namespace geometry | |
31 | { | |
32 | ||
33 | #ifndef DOXYGEN_NO_DETAIL | |
34 | namespace detail { namespace normalization | |
35 | { | |
36 | ||
37 | ||
38 | struct do_nothing | |
39 | { | |
40 | template <typename GeometryIn, typename GeometryOut> | |
41 | static inline void apply(GeometryIn const&, GeometryOut&) | |
42 | { | |
43 | } | |
44 | }; | |
45 | ||
46 | ||
47 | template <std::size_t Dimension, std::size_t DimensionCount> | |
48 | struct assign_loop | |
49 | { | |
50 | template <typename CoordinateType, typename PointIn, typename PointOut> | |
51 | static inline void apply(CoordinateType const& longitude, | |
52 | CoordinateType const& latitude, | |
53 | PointIn const& point_in, | |
54 | PointOut& point_out) | |
55 | { | |
56 | geometry::set<Dimension>(point_out, boost::numeric_cast | |
57 | < | |
58 | typename coordinate_type<PointOut>::type | |
59 | >(geometry::get<Dimension>(point_in))); | |
60 | ||
61 | assign_loop | |
62 | < | |
63 | Dimension + 1, DimensionCount | |
64 | >::apply(longitude, latitude, point_in, point_out); | |
65 | } | |
66 | }; | |
67 | ||
68 | template <std::size_t DimensionCount> | |
69 | struct assign_loop<DimensionCount, DimensionCount> | |
70 | { | |
71 | template <typename CoordinateType, typename PointIn, typename PointOut> | |
72 | static inline void apply(CoordinateType const&, | |
73 | CoordinateType const&, | |
74 | PointIn const&, | |
75 | PointOut&) | |
76 | { | |
77 | } | |
78 | }; | |
79 | ||
80 | template <std::size_t DimensionCount> | |
81 | struct assign_loop<0, DimensionCount> | |
82 | { | |
83 | template <typename CoordinateType, typename PointIn, typename PointOut> | |
84 | static inline void apply(CoordinateType const& longitude, | |
85 | CoordinateType const& latitude, | |
86 | PointIn const& point_in, | |
87 | PointOut& point_out) | |
88 | { | |
89 | geometry::set<0>(point_out, boost::numeric_cast | |
90 | < | |
91 | typename coordinate_type<PointOut>::type | |
92 | >(longitude)); | |
93 | ||
94 | assign_loop | |
95 | < | |
96 | 1, DimensionCount | |
97 | >::apply(longitude, latitude, point_in, point_out); | |
98 | } | |
99 | }; | |
100 | ||
101 | template <std::size_t DimensionCount> | |
102 | struct assign_loop<1, DimensionCount> | |
103 | { | |
104 | template <typename CoordinateType, typename PointIn, typename PointOut> | |
105 | static inline void apply(CoordinateType const& longitude, | |
106 | CoordinateType const& latitude, | |
107 | PointIn const& point_in, | |
108 | PointOut& point_out) | |
109 | { | |
110 | geometry::set<1>(point_out, boost::numeric_cast | |
111 | < | |
112 | typename coordinate_type<PointOut>::type | |
113 | >(latitude)); | |
114 | ||
115 | assign_loop | |
116 | < | |
117 | 2, DimensionCount | |
118 | >::apply(longitude, latitude, point_in, point_out); | |
119 | } | |
120 | }; | |
121 | ||
122 | ||
123 | template <typename PointIn, typename PointOut> | |
124 | struct normalize_point | |
125 | { | |
126 | static inline void apply(PointIn const& point_in, PointOut& point_out) | |
127 | { | |
128 | typedef typename coordinate_type<PointIn>::type in_coordinate_type; | |
129 | ||
130 | in_coordinate_type longitude = geometry::get<0>(point_in); | |
131 | in_coordinate_type latitude = geometry::get<1>(point_in); | |
132 | ||
133 | math::normalize_spheroidal_coordinates | |
134 | < | |
135 | typename coordinate_system<PointIn>::type::units, | |
136 | in_coordinate_type | |
137 | >(longitude, latitude); | |
138 | ||
139 | assign_loop | |
140 | < | |
141 | 0, dimension<PointIn>::value | |
142 | >::apply(longitude, latitude, point_in, point_out); | |
143 | } | |
144 | }; | |
145 | ||
146 | ||
147 | template <typename BoxIn, typename BoxOut> | |
148 | class normalize_box | |
149 | { | |
150 | template <typename UnitsIn, typename UnitsOut, typename CoordinateInType> | |
151 | static inline void apply_to_coordinates(CoordinateInType& lon_min, | |
152 | CoordinateInType& lat_min, | |
153 | CoordinateInType& lon_max, | |
154 | CoordinateInType& lat_max, | |
155 | BoxIn const& box_in, | |
156 | BoxOut& box_out) | |
157 | { | |
158 | detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out); | |
159 | assign_loop | |
160 | < | |
161 | 0, dimension<BoxIn>::value | |
162 | >::apply(lon_min, | |
163 | lat_min, | |
164 | detail::indexed_point_view | |
165 | < | |
166 | BoxIn const, min_corner | |
167 | >(box_in), | |
168 | p_min_out); | |
169 | ||
170 | detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out); | |
171 | assign_loop | |
172 | < | |
173 | 0, dimension<BoxIn>::value | |
174 | >::apply(lon_max, | |
175 | lat_max, | |
176 | detail::indexed_point_view | |
177 | < | |
178 | BoxIn const, max_corner | |
179 | >(box_in), | |
180 | p_max_out); | |
181 | } | |
182 | ||
183 | public: | |
184 | static inline void apply(BoxIn const& box_in, BoxOut& box_out) | |
185 | { | |
186 | typedef typename coordinate_type<BoxIn>::type in_coordinate_type; | |
187 | ||
188 | in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in); | |
189 | in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in); | |
190 | in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in); | |
191 | in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in); | |
192 | ||
193 | math::normalize_spheroidal_box_coordinates | |
194 | < | |
195 | typename coordinate_system<BoxIn>::type::units, | |
196 | in_coordinate_type | |
197 | >(lon_min, lat_min, lon_max, lat_max); | |
198 | ||
199 | apply_to_coordinates | |
200 | < | |
201 | typename coordinate_system<BoxIn>::type::units, | |
202 | typename coordinate_system<BoxOut>::type::units | |
203 | >(lon_min, lat_min, lon_max, lat_max, box_in, box_out); | |
204 | } | |
205 | }; | |
206 | ||
207 | ||
208 | }} // namespace detail::normalization | |
209 | #endif // DOXYGEN_NO_DETAIL | |
210 | ||
211 | #ifndef DOXYGEN_NO_DISPATCH | |
212 | namespace dispatch | |
213 | { | |
214 | ||
215 | template | |
216 | < | |
217 | typename GeometryIn, | |
218 | typename GeometryOut, | |
219 | typename TagIn = typename tag<GeometryIn>::type, | |
220 | typename TagOut = typename tag<GeometryOut>::type, | |
221 | typename CSTagIn = typename cs_tag<GeometryIn>::type, | |
222 | typename CSTagOut = typename cs_tag<GeometryOut>::type | |
223 | > | |
224 | struct normalize : detail::normalization::do_nothing | |
225 | {}; | |
226 | ||
227 | ||
228 | template <typename PointIn, typename PointOut> | |
229 | struct normalize | |
230 | < | |
231 | PointIn, PointOut, point_tag, point_tag, | |
232 | spherical_equatorial_tag, spherical_equatorial_tag | |
233 | > : detail::normalization::normalize_point<PointIn, PointOut> | |
234 | {}; | |
235 | ||
236 | ||
237 | template <typename PointIn, typename PointOut> | |
238 | struct normalize | |
239 | < | |
240 | PointIn, PointOut, point_tag, point_tag, geographic_tag, geographic_tag | |
241 | > : detail::normalization::normalize_point<PointIn, PointOut> | |
242 | {}; | |
243 | ||
244 | ||
245 | template <typename BoxIn, typename BoxOut> | |
246 | struct normalize | |
247 | < | |
248 | BoxIn, BoxOut, box_tag, box_tag, | |
249 | spherical_equatorial_tag, spherical_equatorial_tag | |
250 | > : detail::normalization::normalize_box<BoxIn, BoxOut> | |
251 | {}; | |
252 | ||
253 | ||
254 | template <typename BoxIn, typename BoxOut> | |
255 | struct normalize | |
256 | < | |
257 | BoxIn, BoxOut, box_tag, box_tag, geographic_tag, geographic_tag | |
258 | > : detail::normalization::normalize_box<BoxIn, BoxOut> | |
259 | {}; | |
260 | ||
261 | ||
262 | } // namespace dispatch | |
263 | #endif // DOXYGEN_NO_DISPATCH | |
264 | ||
265 | ||
266 | #ifndef DOXYGEN_NO_DETAIL | |
267 | namespace detail | |
268 | { | |
269 | ||
270 | ||
271 | template <typename GeometryIn, typename GeometryOut> | |
272 | inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out) | |
273 | { | |
274 | dispatch::normalize | |
275 | < | |
276 | GeometryIn, GeometryOut | |
277 | >::apply(geometry_in, geometry_out); | |
278 | } | |
279 | ||
280 | template <typename GeometryOut, typename GeometryIn> | |
281 | inline GeometryOut return_normalized(GeometryIn const& geometry_in) | |
282 | { | |
283 | GeometryOut geometry_out; | |
284 | detail::normalize(geometry_in, geometry_out); | |
285 | return geometry_out; | |
286 | } | |
287 | ||
288 | ||
289 | } // namespace detail | |
290 | #endif // DOXYGEN_NO_DETAIL | |
291 | ||
292 | }} // namespace boost::geometry | |
293 | ||
294 | #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP |