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