]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/strategies/cartesian/point_in_box.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / strategies / cartesian / point_in_box.hpp
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
7 // This file was modified by Oracle on 2015-2018.
8 // Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
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>
25 #include <boost/geometry/core/cs.hpp>
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
37 #ifndef DOXYGEN_NO_DETAIL
38 namespace detail
39 {
40
41 struct within_coord
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
50 struct covered_by_coord
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
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
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)
74 struct within_longitude_diff
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;
80 return diff_min > c0
81 && (min_value + diff_min < max_value
82 /*|| max_value - diff_min > min_value*/);
83 }
84 };
85
86 struct covered_by_longitude_diff
87 {
88 template <typename CalcT>
89 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
90 {
91 return min_value + diff_min <= max_value
92 /*|| max_value - diff_min >= min_value*/;
93 }
94 };
95
96
97 template <typename Geometry,
98 typename CoordCheck,
99 typename DiffCheck>
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;
109 typedef typename geometry::detail::cs_angular_units<Geometry>::type units_t;
110 typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
111
112 if (CoordCheck::apply(value, min_value, max_value))
113 {
114 return true;
115 }
116
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
129 return DiffCheck::template apply<calc_t>(diff_min, min_value, max_value);
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>
137 : longitude_range<Geometry, within_coord, within_longitude_diff>
138 {};
139
140
141 template <typename Geometry>
142 struct covered_by_range<Geometry, 0, spherical_tag>
143 : longitude_range<Geometry, covered_by_coord, covered_by_longitude_diff>
144 {};
145
146
147 template
148 <
149 template <typename, std::size_t, typename> class SubStrategy,
150 typename CSTag, // cartesian_tag or spherical_tag
151 std::size_t Dimension,
152 std::size_t DimensionCount
153 >
154 struct relate_point_box_loop
155 {
156 template <typename Point, typename Box>
157 static inline bool apply(Point const& point, Box const& box)
158 {
159 if (! SubStrategy<Point, Dimension, CSTag>::apply(get<Dimension>(point),
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,
170 CSTag,
171 Dimension + 1, DimensionCount
172 >::apply(point, box);
173 }
174 };
175
176
177 template
178 <
179 template <typename, std::size_t, typename> class SubStrategy,
180 typename CSTag,
181 std::size_t DimensionCount
182 >
183 struct relate_point_box_loop<SubStrategy, CSTag, DimensionCount, DimensionCount>
184 {
185 template <typename Point, typename Box>
186 static inline bool apply(Point const& , Box const& )
187 {
188 return true;
189 }
190 };
191
192 } // namespace detail
193 #endif // DOXYGEN_NO_DETAIL
194
195 struct cartesian_point_box
196 {
197 template <typename Point, typename Box>
198 static inline bool apply(Point const& point, Box const& box)
199 {
200 return detail::relate_point_box_loop
201 <
202 detail::within_range,
203 cartesian_tag,
204 0, dimension<Point>::value
205 >::apply(point, box);
206 }
207 };
208
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 };
222
223
224 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
225 namespace services
226 {
227
228 template <typename Point, typename Box>
229 struct default_strategy
230 <
231 Point, Box,
232 point_tag, box_tag,
233 pointlike_tag, areal_tag,
234 cartesian_tag, cartesian_tag
235 >
236 {
237 typedef within::cartesian_point_box type;
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 <
244 Point, Box,
245 point_tag, box_tag,
246 pointlike_tag, areal_tag,
247 spherical_tag, spherical_tag
248 >
249 {
250 typedef within::spherical_point_box type;
251 };
252
253
254 } // namespace services
255 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
256
257 } // namespace within
258
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
293 {
294
295
296 template <typename Point, typename Box>
297 struct default_strategy
298 <
299 Point, Box,
300 point_tag, box_tag,
301 pointlike_tag, areal_tag,
302 cartesian_tag, cartesian_tag
303 >
304 {
305 typedef covered_by::cartesian_point_box type;
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 <
312 Point, Box,
313 point_tag, box_tag,
314 pointlike_tag, areal_tag,
315 spherical_tag, spherical_tag
316 >
317 {
318 typedef covered_by::spherical_point_box type;
319 };
320
321
322 } // namespace services
323 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
324
325
326 } // namespace covered_by
327
328
329 }}} // namespace boost::geometry::strategy
330
331
332 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP