]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
3 | // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. | |
4 | // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. | |
5 | // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. | |
6 | ||
92f5a8d4 TL |
7 | // This file was modified by Oracle on 2015-2018. |
8 | // Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. | |
7c673cae FG |
9 | |
10 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle | |
11 | ||
12 | // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library | |
13 | // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. | |
14 | ||
15 | // Use, modification and distribution is subject to the Boost Software License, | |
16 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
17 | // http://www.boost.org/LICENSE_1_0.txt) | |
18 | ||
19 | #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP | |
20 | #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP | |
21 | ||
22 | ||
23 | #include <boost/geometry/core/access.hpp> | |
24 | #include <boost/geometry/core/coordinate_dimension.hpp> | |
92f5a8d4 | 25 | #include <boost/geometry/core/cs.hpp> |
7c673cae FG |
26 | #include <boost/geometry/strategies/covered_by.hpp> |
27 | #include <boost/geometry/strategies/within.hpp> | |
28 | #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> | |
29 | ||
30 | ||
31 | namespace boost { namespace geometry { namespace strategy | |
32 | { | |
33 | ||
34 | namespace within | |
35 | { | |
36 | ||
92f5a8d4 TL |
37 | #ifndef DOXYGEN_NO_DETAIL |
38 | namespace detail | |
39 | { | |
40 | ||
b32b8144 | 41 | struct within_coord |
7c673cae FG |
42 | { |
43 | template <typename Value1, typename Value2> | |
44 | static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value) | |
45 | { | |
46 | return value > min_value && value < max_value; | |
47 | } | |
48 | }; | |
49 | ||
b32b8144 | 50 | struct covered_by_coord |
7c673cae FG |
51 | { |
52 | template <typename Value1, typename Value2> | |
53 | static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value) | |
54 | { | |
55 | return value >= min_value && value <= max_value; | |
56 | } | |
57 | }; | |
58 | ||
b32b8144 FG |
59 | template <typename Geometry, std::size_t Dimension, typename CSTag> |
60 | struct within_range | |
61 | : within_coord | |
62 | {}; | |
63 | ||
64 | ||
65 | template <typename Geometry, std::size_t Dimension, typename CSTag> | |
66 | struct covered_by_range | |
67 | : covered_by_coord | |
68 | {}; | |
69 | ||
7c673cae FG |
70 | |
71 | // NOTE: the result would be the same if instead of structs defined below | |
72 | // the above xxx_range were used with the following arguments: | |
73 | // (min_value + diff_min, min_value, max_value) | |
b32b8144 | 74 | struct within_longitude_diff |
7c673cae FG |
75 | { |
76 | template <typename CalcT> | |
77 | static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value) | |
78 | { | |
79 | CalcT const c0 = 0; | |
b32b8144 FG |
80 | return diff_min > c0 |
81 | && (min_value + diff_min < max_value | |
82 | /*|| max_value - diff_min > min_value*/); | |
7c673cae FG |
83 | } |
84 | }; | |
85 | ||
b32b8144 | 86 | struct covered_by_longitude_diff |
7c673cae FG |
87 | { |
88 | template <typename CalcT> | |
89 | static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value) | |
90 | { | |
b32b8144 FG |
91 | return min_value + diff_min <= max_value |
92 | /*|| max_value - diff_min >= min_value*/; | |
7c673cae FG |
93 | } |
94 | }; | |
95 | ||
96 | ||
97 | template <typename Geometry, | |
b32b8144 FG |
98 | typename CoordCheck, |
99 | typename DiffCheck> | |
7c673cae FG |
100 | struct longitude_range |
101 | { | |
102 | template <typename Value1, typename Value2> | |
103 | static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value) | |
104 | { | |
105 | typedef typename select_most_precise | |
106 | < | |
107 | Value1, Value2 | |
108 | >::type calc_t; | |
92f5a8d4 | 109 | typedef typename geometry::detail::cs_angular_units<Geometry>::type units_t; |
7c673cae FG |
110 | typedef math::detail::constants_on_spheroid<calc_t, units_t> constants; |
111 | ||
b32b8144 FG |
112 | if (CoordCheck::apply(value, min_value, max_value)) |
113 | { | |
114 | return true; | |
115 | } | |
116 | ||
7c673cae FG |
117 | // min <= max <=> diff >= 0 |
118 | calc_t const diff_ing = max_value - min_value; | |
119 | ||
120 | // if containing covers the whole globe it contains all | |
121 | if (diff_ing >= constants::period()) | |
122 | { | |
123 | return true; | |
124 | } | |
125 | ||
126 | // calculate positive longitude translation with min_value as origin | |
127 | calc_t const diff_min = math::longitude_distance_unsigned<units_t, calc_t>(min_value, value); | |
128 | ||
b32b8144 | 129 | return DiffCheck::template apply<calc_t>(diff_min, min_value, max_value); |
7c673cae FG |
130 | } |
131 | }; | |
132 | ||
133 | ||
134 | // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag | |
135 | template <typename Geometry> | |
136 | struct within_range<Geometry, 0, spherical_tag> | |
b32b8144 | 137 | : longitude_range<Geometry, within_coord, within_longitude_diff> |
7c673cae FG |
138 | {}; |
139 | ||
140 | ||
141 | template <typename Geometry> | |
142 | struct covered_by_range<Geometry, 0, spherical_tag> | |
b32b8144 | 143 | : longitude_range<Geometry, covered_by_coord, covered_by_longitude_diff> |
7c673cae FG |
144 | {}; |
145 | ||
146 | ||
147 | template | |
148 | < | |
149 | template <typename, std::size_t, typename> class SubStrategy, | |
92f5a8d4 | 150 | typename CSTag, // cartesian_tag or spherical_tag |
7c673cae FG |
151 | std::size_t Dimension, |
152 | std::size_t DimensionCount | |
153 | > | |
154 | struct relate_point_box_loop | |
155 | { | |
92f5a8d4 | 156 | template <typename Point, typename Box> |
7c673cae FG |
157 | static inline bool apply(Point const& point, Box const& box) |
158 | { | |
92f5a8d4 | 159 | if (! SubStrategy<Point, Dimension, CSTag>::apply(get<Dimension>(point), |
7c673cae FG |
160 | get<min_corner, Dimension>(box), |
161 | get<max_corner, Dimension>(box)) | |
162 | ) | |
163 | { | |
164 | return false; | |
165 | } | |
166 | ||
167 | return relate_point_box_loop | |
168 | < | |
169 | SubStrategy, | |
92f5a8d4 | 170 | CSTag, |
7c673cae FG |
171 | Dimension + 1, DimensionCount |
172 | >::apply(point, box); | |
173 | } | |
174 | }; | |
175 | ||
176 | ||
177 | template | |
178 | < | |
179 | template <typename, std::size_t, typename> class SubStrategy, | |
92f5a8d4 | 180 | typename CSTag, |
7c673cae FG |
181 | std::size_t DimensionCount |
182 | > | |
92f5a8d4 | 183 | struct relate_point_box_loop<SubStrategy, CSTag, DimensionCount, DimensionCount> |
7c673cae | 184 | { |
92f5a8d4 | 185 | template <typename Point, typename Box> |
7c673cae FG |
186 | static inline bool apply(Point const& , Box const& ) |
187 | { | |
188 | return true; | |
189 | } | |
190 | }; | |
191 | ||
92f5a8d4 TL |
192 | } // namespace detail |
193 | #endif // DOXYGEN_NO_DETAIL | |
7c673cae | 194 | |
92f5a8d4 | 195 | struct cartesian_point_box |
7c673cae | 196 | { |
92f5a8d4 | 197 | template <typename Point, typename Box> |
7c673cae FG |
198 | static inline bool apply(Point const& point, Box const& box) |
199 | { | |
92f5a8d4 | 200 | return detail::relate_point_box_loop |
7c673cae | 201 | < |
92f5a8d4 TL |
202 | detail::within_range, |
203 | cartesian_tag, | |
204 | 0, dimension<Point>::value | |
7c673cae FG |
205 | >::apply(point, box); |
206 | } | |
207 | }; | |
208 | ||
92f5a8d4 TL |
209 | struct spherical_point_box |
210 | { | |
211 | template <typename Point, typename Box> | |
212 | static inline bool apply(Point const& point, Box const& box) | |
213 | { | |
214 | return detail::relate_point_box_loop | |
215 | < | |
216 | detail::within_range, | |
217 | spherical_tag, | |
218 | 0, dimension<Point>::value | |
219 | >::apply(point, box); | |
220 | } | |
221 | }; | |
7c673cae FG |
222 | |
223 | ||
224 | #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS | |
92f5a8d4 | 225 | namespace services |
7c673cae FG |
226 | { |
227 | ||
228 | template <typename Point, typename Box> | |
229 | struct default_strategy | |
230 | < | |
b32b8144 | 231 | Point, Box, |
7c673cae | 232 | point_tag, box_tag, |
b32b8144 FG |
233 | pointlike_tag, areal_tag, |
234 | cartesian_tag, cartesian_tag | |
7c673cae FG |
235 | > |
236 | { | |
92f5a8d4 | 237 | typedef within::cartesian_point_box type; |
7c673cae FG |
238 | }; |
239 | ||
240 | // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag | |
241 | template <typename Point, typename Box> | |
242 | struct default_strategy | |
243 | < | |
b32b8144 | 244 | Point, Box, |
7c673cae | 245 | point_tag, box_tag, |
b32b8144 FG |
246 | pointlike_tag, areal_tag, |
247 | spherical_tag, spherical_tag | |
7c673cae FG |
248 | > |
249 | { | |
92f5a8d4 | 250 | typedef within::spherical_point_box type; |
7c673cae FG |
251 | }; |
252 | ||
253 | ||
92f5a8d4 TL |
254 | } // namespace services |
255 | #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS | |
7c673cae | 256 | |
92f5a8d4 | 257 | } // namespace within |
7c673cae | 258 | |
92f5a8d4 TL |
259 | namespace covered_by |
260 | { | |
261 | ||
262 | struct cartesian_point_box | |
263 | { | |
264 | template <typename Point, typename Box> | |
265 | static inline bool apply(Point const& point, Box const& box) | |
266 | { | |
267 | return within::detail::relate_point_box_loop | |
268 | < | |
269 | within::detail::covered_by_range, | |
270 | cartesian_tag, | |
271 | 0, dimension<Point>::value | |
272 | >::apply(point, box); | |
273 | } | |
274 | }; | |
275 | ||
276 | struct spherical_point_box | |
277 | { | |
278 | template <typename Point, typename Box> | |
279 | static inline bool apply(Point const& point, Box const& box) | |
280 | { | |
281 | return within::detail::relate_point_box_loop | |
282 | < | |
283 | within::detail::covered_by_range, | |
284 | spherical_tag, | |
285 | 0, dimension<Point>::value | |
286 | >::apply(point, box); | |
287 | } | |
288 | }; | |
289 | ||
290 | ||
291 | #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS | |
292 | namespace services | |
7c673cae FG |
293 | { |
294 | ||
295 | ||
296 | template <typename Point, typename Box> | |
297 | struct default_strategy | |
298 | < | |
b32b8144 | 299 | Point, Box, |
7c673cae | 300 | point_tag, box_tag, |
b32b8144 FG |
301 | pointlike_tag, areal_tag, |
302 | cartesian_tag, cartesian_tag | |
7c673cae FG |
303 | > |
304 | { | |
92f5a8d4 | 305 | typedef covered_by::cartesian_point_box type; |
7c673cae FG |
306 | }; |
307 | ||
308 | // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag | |
309 | template <typename Point, typename Box> | |
310 | struct default_strategy | |
311 | < | |
b32b8144 | 312 | Point, Box, |
7c673cae | 313 | point_tag, box_tag, |
b32b8144 FG |
314 | pointlike_tag, areal_tag, |
315 | spherical_tag, spherical_tag | |
7c673cae FG |
316 | > |
317 | { | |
92f5a8d4 | 318 | typedef covered_by::spherical_point_box type; |
7c673cae FG |
319 | }; |
320 | ||
321 | ||
92f5a8d4 TL |
322 | } // namespace services |
323 | #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS | |
7c673cae FG |
324 | |
325 | ||
92f5a8d4 | 326 | } // namespace covered_by |
7c673cae FG |
327 | |
328 | ||
329 | }}} // namespace boost::geometry::strategy | |
330 | ||
331 | ||
332 | #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP |