]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/strategies/cartesian/point_in_box.hpp
update sources to v12.2.3
[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-2017.
8 // Modifications copyright (c) 2015-2017, 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/strategies/covered_by.hpp>
26 #include <boost/geometry/strategies/within.hpp>
27 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
28
29
30 namespace boost { namespace geometry { namespace strategy
31 {
32
33 namespace within
34 {
35
36 struct within_coord
37 {
38 template <typename Value1, typename Value2>
39 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
40 {
41 return value > min_value && value < max_value;
42 }
43 };
44
45 struct covered_by_coord
46 {
47 template <typename Value1, typename Value2>
48 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
49 {
50 return value >= min_value && value <= max_value;
51 }
52 };
53
54 template <typename Geometry, std::size_t Dimension, typename CSTag>
55 struct within_range
56 : within_coord
57 {};
58
59
60 template <typename Geometry, std::size_t Dimension, typename CSTag>
61 struct covered_by_range
62 : covered_by_coord
63 {};
64
65
66 // NOTE: the result would be the same if instead of structs defined below
67 // the above xxx_range were used with the following arguments:
68 // (min_value + diff_min, min_value, max_value)
69 struct within_longitude_diff
70 {
71 template <typename CalcT>
72 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
73 {
74 CalcT const c0 = 0;
75 return diff_min > c0
76 && (min_value + diff_min < max_value
77 /*|| max_value - diff_min > min_value*/);
78 }
79 };
80
81 struct covered_by_longitude_diff
82 {
83 template <typename CalcT>
84 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
85 {
86 return min_value + diff_min <= max_value
87 /*|| max_value - diff_min >= min_value*/;
88 }
89 };
90
91
92 template <typename Geometry,
93 typename CoordCheck,
94 typename DiffCheck>
95 struct longitude_range
96 {
97 template <typename Value1, typename Value2>
98 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
99 {
100 typedef typename select_most_precise
101 <
102 Value1, Value2
103 >::type calc_t;
104 typedef typename coordinate_system<Geometry>::type::units units_t;
105 typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
106
107 if (CoordCheck::apply(value, min_value, max_value))
108 {
109 return true;
110 }
111
112 // min <= max <=> diff >= 0
113 calc_t const diff_ing = max_value - min_value;
114
115 // if containing covers the whole globe it contains all
116 if (diff_ing >= constants::period())
117 {
118 return true;
119 }
120
121 // calculate positive longitude translation with min_value as origin
122 calc_t const diff_min = math::longitude_distance_unsigned<units_t, calc_t>(min_value, value);
123
124 return DiffCheck::template apply<calc_t>(diff_min, min_value, max_value);
125 }
126 };
127
128
129 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
130 template <typename Geometry>
131 struct within_range<Geometry, 0, spherical_tag>
132 : longitude_range<Geometry, within_coord, within_longitude_diff>
133 {};
134
135
136 template <typename Geometry>
137 struct covered_by_range<Geometry, 0, spherical_tag>
138 : longitude_range<Geometry, covered_by_coord, covered_by_longitude_diff>
139 {};
140
141
142 template
143 <
144 template <typename, std::size_t, typename> class SubStrategy,
145 typename Point,
146 typename Box,
147 std::size_t Dimension,
148 std::size_t DimensionCount
149 >
150 struct relate_point_box_loop
151 {
152 static inline bool apply(Point const& point, Box const& box)
153 {
154 typedef typename tag_cast<typename cs_tag<Point>::type, spherical_tag>::type cs_tag_t;
155
156 if (! SubStrategy<Point, Dimension, cs_tag_t>::apply(get<Dimension>(point),
157 get<min_corner, Dimension>(box),
158 get<max_corner, Dimension>(box))
159 )
160 {
161 return false;
162 }
163
164 return relate_point_box_loop
165 <
166 SubStrategy,
167 Point, Box,
168 Dimension + 1, DimensionCount
169 >::apply(point, box);
170 }
171 };
172
173
174 template
175 <
176 template <typename, std::size_t, typename> class SubStrategy,
177 typename Point,
178 typename Box,
179 std::size_t DimensionCount
180 >
181 struct relate_point_box_loop<SubStrategy, Point, Box, DimensionCount, DimensionCount>
182 {
183 static inline bool apply(Point const& , Box const& )
184 {
185 return true;
186 }
187 };
188
189
190 template
191 <
192 typename Point,
193 typename Box,
194 template <typename, std::size_t, typename> class SubStrategy = within_range
195 >
196 struct point_in_box
197 {
198 static inline bool apply(Point const& point, Box const& box)
199 {
200 return relate_point_box_loop
201 <
202 SubStrategy,
203 Point, Box,
204 0, dimension<Point>::type::value
205 >::apply(point, box);
206 }
207 };
208
209
210 } // namespace within
211
212
213 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
214
215
216 namespace within { namespace services
217 {
218
219 template <typename Point, typename Box>
220 struct default_strategy
221 <
222 Point, Box,
223 point_tag, box_tag,
224 pointlike_tag, areal_tag,
225 cartesian_tag, cartesian_tag
226 >
227 {
228 typedef within::point_in_box<Point, Box> type;
229 };
230
231 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
232 template <typename Point, typename Box>
233 struct default_strategy
234 <
235 Point, Box,
236 point_tag, box_tag,
237 pointlike_tag, areal_tag,
238 spherical_tag, spherical_tag
239 >
240 {
241 typedef within::point_in_box<Point, Box> type;
242 };
243
244
245 }} // namespace within::services
246
247
248 namespace covered_by { namespace services
249 {
250
251
252 template <typename Point, typename Box>
253 struct default_strategy
254 <
255 Point, Box,
256 point_tag, box_tag,
257 pointlike_tag, areal_tag,
258 cartesian_tag, cartesian_tag
259 >
260 {
261 typedef within::point_in_box
262 <
263 Point, Box,
264 within::covered_by_range
265 > type;
266 };
267
268 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
269 template <typename Point, typename Box>
270 struct default_strategy
271 <
272 Point, Box,
273 point_tag, box_tag,
274 pointlike_tag, areal_tag,
275 spherical_tag, spherical_tag
276 >
277 {
278 typedef within::point_in_box
279 <
280 Point, Box,
281 within::covered_by_range
282 > type;
283 };
284
285
286 }} // namespace covered_by::services
287
288
289 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
290
291
292 }}} // namespace boost::geometry::strategy
293
294
295 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP