]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/include/boost/geometry/strategies/cartesian/box_in_box.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / strategies / cartesian / box_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 // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
7
8 // This file was modified by Oracle on 2015, 2016.
9 // Modifications copyright (c) 2016, Oracle and/or its affiliates.
10
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19
20 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
21 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
22
23
24 #include <boost/geometry/core/access.hpp>
25 #include <boost/geometry/core/coordinate_dimension.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
35 namespace within
36 {
37
38
39 template <typename Geometry, std::size_t Dimension, typename CSTag>
40 struct box_within_range
41 {
42 template <typename BoxContainedValue, typename BoxContainingValue>
43 static inline bool apply(BoxContainedValue const& bed_min,
44 BoxContainedValue const& bed_max,
45 BoxContainingValue const& bing_min,
46 BoxContainingValue const& bing_max)
47 {
48 return bing_min <= bed_min && bed_max <= bing_max // contained in containing
49 && bed_min < bed_max; // interiors overlap
50 }
51 };
52
53
54 template <typename Geometry, std::size_t Dimension, typename CSTag>
55 struct box_covered_by_range
56 {
57 template <typename BoxContainedValue, typename BoxContainingValue>
58 static inline bool apply(BoxContainedValue const& bed_min,
59 BoxContainedValue const& bed_max,
60 BoxContainingValue const& bing_min,
61 BoxContainingValue const& bing_max)
62 {
63 return bed_min >= bing_min && bed_max <= bing_max;
64 }
65 };
66
67
68 struct box_within_longitude_check
69 {
70 template <typename CalcT>
71 static inline bool apply(CalcT const& diff_ed)
72 {
73 return diff_ed > CalcT(0);
74 }
75 };
76
77 struct box_covered_by_longitude_check
78 {
79 template <typename CalcT>
80 static inline bool apply(CalcT const&)
81 {
82 return true;
83 }
84 };
85
86 template <typename Geometry,
87 typename InteriorCheck>
88 struct box_longitude_range
89 {
90 template <typename BoxContainedValue, typename BoxContainingValue>
91 static inline bool apply(BoxContainedValue const& bed_min,
92 BoxContainedValue const& bed_max,
93 BoxContainingValue const& bing_min,
94 BoxContainingValue const& bing_max)
95 {
96 typedef typename select_most_precise
97 <
98 BoxContainedValue,
99 BoxContainingValue
100 >::type calc_t;
101 typedef typename coordinate_system<Geometry>::type::units units_t;
102 typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
103
104 // min <= max <=> diff >= 0
105 calc_t const diff_ed = bed_max - bed_min;
106 calc_t const diff_ing = bing_max - bing_min;
107
108 // if containing covers the whole globe it contains all
109 if (diff_ing >= constants::period())
110 {
111 return true;
112 }
113
114 // if containing is smaller it cannot contain
115 // and check interior (within vs covered_by)
116 if (diff_ing < diff_ed || ! InteriorCheck::apply(diff_ed))
117 {
118 return false;
119 }
120
121 // calculate positive longitude translation with bing_min as origin
122 calc_t const diff_min = math::longitude_distance_unsigned<units_t>(bing_min, bed_min);
123
124 // max of contained translated into the containing origin must be lesser than max of containing
125 return bing_min + diff_min + diff_ed <= bing_max;
126 }
127 };
128
129
130 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
131 template <typename Geometry>
132 struct box_within_range<Geometry, 0, spherical_tag>
133 : box_longitude_range<Geometry, box_within_longitude_check>
134 {};
135
136
137 template <typename Geometry>
138 struct box_covered_by_range<Geometry, 0, spherical_tag>
139 : box_longitude_range<Geometry, box_covered_by_longitude_check>
140 {};
141
142
143 template
144 <
145 template <typename, std::size_t, typename> class SubStrategy,
146 typename Box1,
147 typename Box2,
148 std::size_t Dimension,
149 std::size_t DimensionCount
150 >
151 struct relate_box_box_loop
152 {
153 static inline bool apply(Box1 const& b_contained, Box2 const& b_containing)
154 {
155 assert_dimension_equal<Box1, Box2>();
156 typedef typename tag_cast<typename cs_tag<Box1>::type, spherical_tag>::type cs_tag_t;
157
158 if (! SubStrategy<Box1, Dimension, cs_tag_t>::apply(
159 get<min_corner, Dimension>(b_contained),
160 get<max_corner, Dimension>(b_contained),
161 get<min_corner, Dimension>(b_containing),
162 get<max_corner, Dimension>(b_containing)
163 )
164 )
165 {
166 return false;
167 }
168
169 return relate_box_box_loop
170 <
171 SubStrategy,
172 Box1, Box2,
173 Dimension + 1, DimensionCount
174 >::apply(b_contained, b_containing);
175 }
176 };
177
178 template
179 <
180 template <typename, std::size_t, typename> class SubStrategy,
181 typename Box1,
182 typename Box2,
183 std::size_t DimensionCount
184 >
185 struct relate_box_box_loop<SubStrategy, Box1, Box2, DimensionCount, DimensionCount>
186 {
187 static inline bool apply(Box1 const& , Box2 const& )
188 {
189 return true;
190 }
191 };
192
193 template
194 <
195 typename Box1,
196 typename Box2,
197 template <typename, std::size_t, typename> class SubStrategy = box_within_range
198 >
199 struct box_in_box
200 {
201 static inline bool apply(Box1 const& box1, Box2 const& box2)
202 {
203 return relate_box_box_loop
204 <
205 SubStrategy,
206 Box1, Box2, 0, dimension<Box1>::type::value
207 >::apply(box1, box2);
208 }
209 };
210
211
212 } // namespace within
213
214
215 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
216
217
218 namespace within { namespace services
219 {
220
221 template <typename BoxContained, typename BoxContaining>
222 struct default_strategy
223 <
224 box_tag, box_tag,
225 box_tag, areal_tag,
226 cartesian_tag, cartesian_tag,
227 BoxContained, BoxContaining
228 >
229 {
230 typedef within::box_in_box<BoxContained, BoxContaining> type;
231 };
232
233 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
234 template <typename BoxContained, typename BoxContaining>
235 struct default_strategy
236 <
237 box_tag, box_tag,
238 box_tag, areal_tag,
239 spherical_tag, spherical_tag,
240 BoxContained, BoxContaining
241 >
242 {
243 typedef within::box_in_box<BoxContained, BoxContaining> type;
244 };
245
246
247 }} // namespace within::services
248
249 namespace covered_by { namespace services
250 {
251
252 template <typename BoxContained, typename BoxContaining>
253 struct default_strategy
254 <
255 box_tag, box_tag,
256 box_tag, areal_tag,
257 cartesian_tag, cartesian_tag,
258 BoxContained, BoxContaining
259 >
260 {
261 typedef within::box_in_box
262 <
263 BoxContained, BoxContaining,
264 within::box_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 BoxContained, typename BoxContaining>
270 struct default_strategy
271 <
272 box_tag, box_tag,
273 box_tag, areal_tag,
274 spherical_tag, spherical_tag,
275 BoxContained, BoxContaining
276 >
277 {
278 typedef within::box_in_box
279 <
280 BoxContained, BoxContaining,
281 within::box_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 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP