]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/distance/distance_se_point_box.cpp
Add patch for failing prerm scripts
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / distance / distance_se_point_box.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2015, Oracle and/or its affiliates.
5
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10
11 #include <iostream>
12
13 #ifndef BOOST_TEST_MODULE
14 #define BOOST_TEST_MODULE test_distance_spherical_equatorial_point_box
15 #endif
16
17 #include <boost/range.hpp>
18 #include <boost/type_traits/is_same.hpp>
19
20 #include <boost/test/included/unit_test.hpp>
21 #include <boost/geometry/util/condition.hpp>
22 #include <boost/geometry/strategies/strategies.hpp>
23
24 #include "test_distance_se_common.hpp"
25
26
27 typedef bg::cs::spherical_equatorial<bg::degree> cs_type;
28 typedef bg::model::point<double, 2, cs_type> point_type;
29 typedef bg::model::multi_point<point_type> multi_point_type;
30 typedef bg::model::segment<point_type> segment_type;
31 typedef bg::model::box<point_type> box_type;
32
33 namespace distance = bg::strategy::distance;
34 namespace services = distance::services;
35 typedef bg::default_distance_result<point_type, point_type>::type return_type;
36
37 typedef distance::cross_track_point_box<> point_box_strategy;
38 typedef distance::cross_track_point_box
39 <
40 void, distance::comparable::cross_track<>
41 > comparable_point_box_strategy;
42
43 //===========================================================================
44
45 inline bg::distance_result
46 <
47 point_type, point_type, distance::haversine<double>
48 >::type
49 distance_pp(std::string const& wkt1,
50 std::string const& wkt2,
51 double radius)
52 {
53 point_type p1, p2;
54 bg::read_wkt(wkt1, p1);
55 bg::read_wkt(wkt2, p2);
56
57 distance::haversine<double> strategy(radius);
58 return bg::distance(p1, p2, strategy);
59 }
60
61 inline bg::default_comparable_distance_result<point_type>::type
62 comparable_distance_pp(std::string const& wkt1,
63 std::string const& wkt2)
64 {
65 point_type p1, p2;
66 bg::read_wkt(wkt1, p1);
67 bg::read_wkt(wkt2, p2);
68 return bg::comparable_distance(p1, p2);
69 }
70
71 inline bg::distance_result
72 <
73 point_type, point_type, distance::cross_track<>
74 >::type
75 distance_ps(std::string const& wkt_point,
76 std::string const& wkt_segment,
77 double radius)
78 {
79 point_type point;
80 segment_type segment;
81 bg::read_wkt(wkt_point, point);
82 bg::read_wkt(wkt_segment, segment);
83
84 distance::cross_track<> strategy(radius);
85 return bg::distance(point, segment, strategy);
86 }
87
88 inline bg::default_comparable_distance_result<point_type>::type
89 comparable_distance_ps(std::string const& wkt_point,
90 std::string const& wkt_segment)
91 {
92 point_type point;
93 segment_type segment;
94 bg::read_wkt(wkt_point, point);
95 bg::read_wkt(wkt_segment, segment);
96 return bg::comparable_distance(point, segment);
97 }
98
99 enum features_type { pp, ps };
100
101 template <typename Geometry1, typename Geometry2>
102 struct test_distances
103 {
104 template <typename Strategy>
105 static inline void apply(std::string const& case_id,
106 std::string const& wkt1,
107 std::string const& wkt2,
108 double expected_distance,
109 double expected_comparable_distance,
110 Strategy const& strategy)
111 {
112 typedef test_distance_of_geometries<Geometry1, Geometry2> tester;
113
114 bool const is_comparable = boost::is_same
115 <
116 Strategy,
117 typename services::comparable_type<Strategy>::type
118 >::value;
119
120 if (BOOST_GEOMETRY_CONDITION(is_comparable))
121 {
122 tester::apply(case_id, wkt1, wkt2,
123 expected_comparable_distance,
124 expected_comparable_distance,
125 strategy);
126 }
127 else
128 {
129 tester::apply(case_id, wkt1, wkt2,
130 expected_distance,
131 expected_comparable_distance,
132 strategy);
133 }
134 }
135
136 template <typename Strategy>
137 static inline void apply(std::string const& case_id,
138 std::string const& wkt1,
139 std::string const& wkt2,
140 std::string const& feature1,
141 std::string const& feature2,
142 features_type ftype,
143 Strategy const& strategy)
144 {
145 double const radius = strategy.radius();
146 double expected_distance, expected_comparable_distance;
147
148 if (ftype == pp)
149 {
150 expected_distance = distance_pp(feature1, feature2, radius);
151 expected_comparable_distance
152 = comparable_distance_pp(feature1, feature2);
153 }
154 else
155 {
156 expected_distance = distance_ps(feature1, feature2, radius);
157 expected_comparable_distance
158 = comparable_distance_ps(feature1, feature2);
159 }
160
161 apply(case_id, wkt1, wkt2,
162 expected_distance, expected_comparable_distance,
163 strategy);
164 }
165 };
166
167 template <typename T, typename U>
168 T to_comparable(T const& value, U const& radius)
169 {
170 T x = sin(value / (radius * 2.0));
171 return x * x;
172 }
173
174 //===========================================================================
175
176 template <typename Strategy>
177 void test_distance_point_box(Strategy const& strategy)
178 {
179 #ifdef BOOST_GEOMETRY_TEST_DEBUG
180 std::cout << std::endl;
181 std::cout << "point/box distance tests" << std::endl;
182 #endif
183 typedef test_distances<point_type, box_type> tester;
184
185 double const radius = strategy.radius();
186 double const d2r = bg::math::d2r<double>();
187
188 // Cases for relative location of a point wrt to a box
189 //
190 // | |
191 // | 3 |
192 // | |
193 // +---------+
194 // | |
195 // 1 | 5 | 2
196 // | |
197 // +---------+
198 // | |
199 // | 4 |
200 // | |
201 //
202 // and also the following cases
203 //
204 // | |
205 // A B
206 // | |
207 // +----C----+
208 // | |
209 // D E
210 // | |
211 // +----F----+
212 // | |
213 // G H
214 // | |
215 //
216 // and finally we have the corners
217 //
218 // | |
219 // | |
220 // | |
221 // a---------b
222 // | |
223 // | |
224 // | |
225 // c---------d
226 // | |
227 // | |
228 // | |
229 //
230 // for each relative position we also have to test the shifted point
231 // (this is due to the fact that boxes have longitudes in the
232 // range [-180, 540)
233
234 std::string const box1 = "BOX(10 10,20 20)";
235
236 // case 1
237 tester::apply("pb1-1a", "POINT(5 25)", box1,
238 "POINT(5 25)", "POINT(10 20)", pp,
239 strategy);
240
241 // case 1
242 tester::apply("pb1-1b", "POINT(3 12)", box1,
243 "POINT(3 12)", "SEGMENT(10 10,10 20)", ps,
244 strategy);
245
246 // case 1
247 tester::apply("pb1-1c", "POINT(3 17)", box1,
248 "POINT(3 17)", "SEGMENT(10 10,10 20)", ps,
249 strategy);
250
251 // case 1
252 tester::apply("pb1-1d", "POINT(5 4)", box1,
253 "POINT(5 4)", "POINT(10 10)", pp,
254 strategy);
255
256 // case 1
257 tester::apply("pb1-1e", "POINT(-100 20)", box1,
258 "POINT(-100 20)", "POINT(10 20)", pp,
259 strategy);
260
261 // case 1
262 tester::apply("pb1-1g", "POINT(-100 10)", box1,
263 "POINT(-100 10)", "SEGMENT(10 10,10 20)", ps,
264 strategy);
265
266 // case 2
267 tester::apply("pb1-2a", "POINT(31 25)", box1,
268 "POINT(31 25)", "POINT(20 20)", pp,
269 strategy);
270
271 // case 2
272 tester::apply("pb1-2b", "POINT(23 17)", box1,
273 "POINT(23 17)", "SEGMENT(20 10,20 20)", ps,
274 strategy);
275
276 // case 2
277 tester::apply("pb1-2c", "POINT(29 3)", box1,
278 "POINT(29 3)", "POINT(20 10)", pp,
279 strategy);
280
281 // case 2
282 tester::apply("pb1-2d", "POINT(131 65)", box1,
283 "POINT(131 65)", "POINT(20 20)", pp,
284 strategy);
285
286 // case 2
287 tester::apply("pb1-2e", "POINT(110 10)", box1,
288 "POINT(110 10)", "SEGMENT(20 10,20 20)", ps,
289 strategy);
290
291 // case 2
292 tester::apply("pb1-2f", "POINT(150 20)", box1,
293 "POINT(150 20)", "POINT(20 20)", pp,
294 strategy);
295
296 // case 3
297 tester::apply("pb1-3a", "POINT(11 25)", box1,
298 5.0 * d2r * radius,
299 to_comparable(5.0 * d2r * radius, radius),
300 strategy);
301
302 // case 3
303 tester::apply("pb1-3b", "POINT(15 25)", box1,
304 5.0 * d2r * radius,
305 to_comparable(5.0 * d2r * radius, radius),
306 strategy);
307
308 // case 3
309 tester::apply("pb1-3c", "POINT(18 25)", box1,
310 5.0 * d2r * radius,
311 to_comparable(5.0 * d2r * radius, radius),
312 strategy);
313
314 // case 4
315 tester::apply("pb1-4a", "POINT(13 4)", box1,
316 6.0 * radius * d2r,
317 to_comparable(6.0 * radius * d2r, radius),
318 strategy);
319
320 // case 4
321 tester::apply("pb1-4b", "POINT(19 4)", box1,
322 6.0 * radius * d2r,
323 to_comparable(6.0 * radius * d2r, radius),
324 strategy);
325
326 // case 5
327 tester::apply("pb1-5", "POINT(15 14)", box1, 0, 0, strategy);
328
329 // case A
330 tester::apply("pb1-A", "POINT(10 28)", box1,
331 8.0 * d2r * radius,
332 to_comparable(8.0 * d2r * radius, radius),
333 strategy);
334
335 // case B
336 tester::apply("pb1-B", "POINT(20 28)", box1,
337 8.0 * d2r * radius,
338 to_comparable(8.0 * d2r * radius, radius),
339 strategy);
340
341 // case C
342 tester::apply("pb1-C", "POINT(14 20)", box1, 0, 0, strategy);
343
344 // case D
345 tester::apply("pb1-D", "POINT(10 17)", box1, 0, 0, strategy);
346
347 // case E
348 tester::apply("pb1-E", "POINT(20 11)", box1, 0, 0, strategy);
349
350 // case F
351 tester::apply("pb1-F", "POINT(19 10)", box1, 0, 0, strategy);
352
353 // case G
354 tester::apply("pb1-G", "POINT(10 -40)", box1,
355 50.0 * d2r * radius,
356 to_comparable(50.0 * d2r * radius, radius),
357 strategy);
358
359 // case H
360 tester::apply("pb1-H",
361 "POINT(20 -50)", box1,
362 60.0 * d2r * radius,
363 to_comparable(60.0 * d2r * radius, radius),
364 strategy);
365
366 // case a
367 tester::apply("pb1-a", "POINT(10 20)", box1, 0, 0, strategy);
368 // case b
369 tester::apply("pb1-b", "POINT(20 20)", box1, 0, 0, strategy);
370 // case c
371 tester::apply("pb1-c", "POINT(10 10)", box1, 0, 0, strategy);
372 // case d
373 tester::apply("pb1-d", "POINT(20 10)", box1, 0, 0, strategy);
374
375
376
377 std::string const box2 = "BOX(170 -60,400 80)";
378
379 // case 1 - point is closer to western meridian
380 tester::apply("pb2-1a", "POINT(160 0)", box2,
381 "POINT(160 0)", "SEGMENT(170 -60,170 80)", ps,
382 strategy);
383
384 // case 1 - point is closer to eastern meridian
385 tester::apply("pb2-1b", "POINT(50 0)", box2,
386 "POINT(50 0)", "SEGMENT(40 -60,40 80)", ps,
387 strategy);
388
389 // case 3 - equivalent point POINT(390 85) is above the box
390 tester::apply("pb2-3", "POINT(30 85)", box2,
391 5.0 * d2r * radius,
392 to_comparable(5.0 * d2r * radius, radius),
393 strategy);
394
395 // case 4 - equivalent point POINT(390 -75) is below the box
396 tester::apply("pb2-4", "POINT(30 -75)", box2,
397 15.0 * d2r * radius,
398 to_comparable(15.0 * d2r * radius, radius),
399 strategy);
400
401 // case 5 - equivalent point POINT(390 0) is inside box
402 tester::apply("pb2-5", "POINT(30 0)", box2, 0, 0, strategy);
403
404
405 std::string const box3 = "BOX(-150 -50,-40 70)";
406
407 // case 1 - point is closer to western meridian
408 tester::apply("pb3-1a", "POINT(-170 10)", box3,
409 "POINT(-170 10)", "SEGMENT(-150 -50,-150 70)", ps,
410 strategy);
411
412 // case 2 - point is closer to eastern meridian
413 tester::apply("pb3-2a", "POINT(5 10)", box3,
414 "POINT(5 10)", "SEGMENT(-40 -50,-40 70)", ps,
415 strategy);
416
417 // case 2 - point is closer to western meridian
418 tester::apply("pb3-2a", "POINT(160 10)", box3,
419 "POINT(160 10)", "SEGMENT(-150 -50,-150 70)", ps,
420 strategy);
421
422 // case 2 - point is at equal distance from eastern and western meridian
423 tester::apply("pb3-2c1", "POINT(85 20)", box3,
424 "POINT(85 20)", "SEGMENT(-150 -50,-150 70)", ps,
425 strategy);
426
427 // case 2 - point is at equal distance from eastern and western meridian
428 tester::apply("pb3-2c2", "POINT(85 20)", box3,
429 "POINT(85 20)", "SEGMENT(-40 -50,-40 70)", ps,
430 strategy);
431
432 // box that is symmetric wrt the prime meridian
433 std::string const box4 = "BOX(-75 -45,75 65)";
434
435 // case 1 - point is closer to western meridian
436 tester::apply("pb4-1a", "POINT(-100 10)", box4,
437 "POINT(-100 10)", "SEGMENT(-75 -45,-75 65)", ps,
438 strategy);
439
440 // case 2 - point is closer to eastern meridian
441 tester::apply("pb4-2a", "POINT(90 15)", box4,
442 "POINT(90 15)", "SEGMENT(75 -45,75 65)", ps,
443 strategy);
444
445 // case 2 - point is at equal distance from eastern and western meridian
446 tester::apply("pb4-2c1", "POINT(-180 20)", box4,
447 "POINT(-180 20)", "SEGMENT(-75 -45,-75 65)", ps,
448 strategy);
449
450 // case 2 - point is at equal distance from eastern and western meridian
451 tester::apply("pb4-2c2", "POINT(-180 20)", box4,
452 "POINT(-180 20)", "SEGMENT(75 -45,75 65)", ps,
453 strategy);
454
455 }
456
457 template <typename Strategy>
458 void test_distance_multipoint_box(Strategy const& strategy)
459 {
460
461 #ifdef BOOST_GEOMETRY_TEST_DEBUG
462 std::cout << std::endl;
463 std::cout << "multipoint/box distance tests" << std::endl;
464 #endif
465 typedef test_distances<multi_point_type, box_type> tester;
466
467 std::string const box1 = "BOX(10 10,20 20)";
468
469 tester::apply("mpb1-1a", "MULTIPOINT(5 25,25 26)", box1,
470 "POINT(5 25)", "POINT(10 20)", pp,
471 strategy);
472
473 tester::apply("mpb1-2e", "MULTIPOINT(110 10,110 9,110 0)", box1,
474 "POINT(110 10)", "SEGMENT(20 10,20 20)", ps,
475 strategy);
476 }
477
478 BOOST_AUTO_TEST_CASE( test_point_box )
479 {
480 test_distance_point_box(point_box_strategy());
481 test_distance_point_box(point_box_strategy(earth_radius_km));
482 test_distance_point_box(point_box_strategy(earth_radius_miles));
483
484 test_distance_point_box(comparable_point_box_strategy());
485 test_distance_point_box(comparable_point_box_strategy(earth_radius_km));
486 test_distance_point_box(comparable_point_box_strategy(earth_radius_miles));
487
488 test_distance_multipoint_box(point_box_strategy());
489 test_distance_multipoint_box(point_box_strategy(earth_radius_km));
490 test_distance_multipoint_box(point_box_strategy(earth_radius_miles));
491 }