1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2016, Oracle and/or its affiliates.
6 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
13 #ifndef BOOST_TEST_MODULE
14 #define BOOST_TEST_MODULE test_distance_spherical_equatorial_box_box
17 #include <boost/range.hpp>
18 #include <boost/type_traits/is_same.hpp>
20 #include <boost/test/included/unit_test.hpp>
21 #include <boost/geometry/util/condition.hpp>
22 #include <boost/geometry/strategies/strategies.hpp>
24 #include "test_distance_se_common.hpp"
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::segment
<point_type
> segment_type
;
30 typedef bg::model::box
<point_type
> box_type
;
32 namespace distance
= bg::strategy::distance
;
33 namespace services
= distance::services
;
34 typedef bg::default_distance_result
<point_type
, point_type
>::type return_type
;
36 typedef distance::cross_track_box_box
<> box_box_strategy
;
37 typedef distance::cross_track_box_box
39 void, distance::comparable::cross_track
<>
40 > comparable_box_box_strategy
;
42 //===========================================================================
44 inline bg::distance_result
46 point_type
, point_type
, distance::haversine
<double>
48 distance_pp(std::string
const& wkt1
,
49 std::string
const& wkt2
,
53 bg::read_wkt(wkt1
, p1
);
54 bg::read_wkt(wkt2
, p2
);
56 distance::haversine
<double> strategy(radius
);
57 return bg::distance(p1
, p2
, strategy
);
60 inline bg::default_comparable_distance_result
<point_type
>::type
61 comparable_distance_pp(std::string
const& wkt1
,
62 std::string
const& wkt2
)
65 bg::read_wkt(wkt1
, p1
);
66 bg::read_wkt(wkt2
, p2
);
67 return bg::comparable_distance(p1
, p2
);
70 inline bg::distance_result
72 point_type
, point_type
, distance::cross_track
<>
74 distance_ps(std::string
const& wkt_point
,
75 std::string
const& wkt_segment
,
80 bg::read_wkt(wkt_point
, point
);
81 bg::read_wkt(wkt_segment
, segment
);
83 distance::cross_track
<> strategy(radius
);
84 return bg::distance(point
, segment
, strategy
);
87 inline bg::default_comparable_distance_result
<point_type
>::type
88 comparable_distance_ps(std::string
const& wkt_point
,
89 std::string
const& wkt_segment
)
93 bg::read_wkt(wkt_point
, point
);
94 bg::read_wkt(wkt_segment
, segment
);
95 return bg::comparable_distance(point
, segment
);
98 enum features_type
{ pp
, ps
};
100 template <typename Geometry1
, typename Geometry2
>
101 struct test_distances
103 template <typename Strategy
>
104 static inline void apply(std::string
const& case_id
,
105 std::string
const& wkt1
,
106 std::string
const& wkt2
,
107 double expected_distance
,
108 double expected_comparable_distance
,
109 Strategy
const& strategy
)
111 typedef test_distance_of_geometries
<Geometry1
, Geometry2
> tester
;
113 bool const is_comparable
= boost::is_same
116 typename
services::comparable_type
<Strategy
>::type
119 if (BOOST_GEOMETRY_CONDITION(is_comparable
))
121 tester::apply(case_id
, wkt1
, wkt2
,
122 expected_comparable_distance
,
123 expected_comparable_distance
,
128 tester::apply(case_id
, wkt1
, wkt2
,
130 expected_comparable_distance
,
135 template <typename Strategy
>
136 static inline void apply(std::string
const& case_id
,
137 std::string
const& wkt1
,
138 std::string
const& wkt2
,
139 std::string
const& feature1
,
140 std::string
const& feature2
,
142 Strategy
const& strategy
)
144 double const radius
= strategy
.radius();
145 double expected_distance
, expected_comparable_distance
;
149 expected_distance
= distance_pp(feature1
, feature2
, radius
);
150 expected_comparable_distance
151 = comparable_distance_pp(feature1
, feature2
);
155 expected_distance
= distance_ps(feature1
, feature2
, radius
);
156 expected_comparable_distance
157 = comparable_distance_ps(feature1
, feature2
);
160 apply(case_id
, wkt1
, wkt2
,
161 expected_distance
, expected_comparable_distance
,
166 template <typename T
, typename U
>
167 T
to_comparable(T
const& value
, U
const& radius
)
169 T x
= sin(value
/ (radius
* 2.0));
174 //===========================================================================
177 // Cases for relative location of box2 wrt to box1
182 // --10---+---------+---3---
186 // -------+---------+-------
191 // case 6 includes all possible intersections
192 // The picture assumes northern hemisphere location
193 // southern hemisphere picture is mirrored wrt the equator
195 template <typename Strategy
>
196 void test_distance_box_box(Strategy
const& strategy
)
198 typedef test_distances
<box_type
, box_type
> tester
;
200 std::string
const box1
= "BOX(10 10,20 20)";
203 tester::apply("bb1", box1
, "BOX(30 0,40 5)",
204 "POINT(20 10)", "POINT(30 5)", pp
,
208 tester::apply("bb2-a", box1
, "BOX(30 12, 40 17)",
209 "POINT(30 17)", "SEGMENT(20 10,20 20)", ps
,
212 tester::apply("bb2-b", box1
, "BOX(30 10, 40 17)",
213 "POINT(30 17)", "SEGMENT(20 10,20 20)", ps
,
216 tester::apply("bb2-c", box1
, "BOX(30 8, 40 17)",
217 "POINT(30 17)", "SEGMENT(20 10,20 20)", ps
,
222 tester::apply("bb3-a", box1
, "BOX(30 15, 40 25)",
223 "POINT(20 20)", "SEGMENT(30 15,30 25)", ps
,
226 tester::apply("bb3-b", box1
, "BOX(30 20, 40 40)",
227 "POINT(20 20)", "SEGMENT(30 20,30 40)", ps
,
231 tester::apply("bb4", box1
, "BOX(30 25, 40 40)",
232 "POINT(20 20)", "POINT(30 25)", pp
,
236 tester::apply("bb5", box1
, "BOX(12 2, 17 7)",
237 "POINT(17 7)", "POINT(17 10)", pp
,
240 // case 6, boxes intersect thus distance is 0
241 tester::apply("bb6-a", box1
, "BOX(12 2, 17 10)",
242 "POINT(0 0)", "POINT(0 0)", pp
,
245 tester::apply("bb6-b", box1
, "BOX(12 2, 17 17)",
246 "POINT(0 0)", "POINT(0 0)", pp
,
249 tester::apply("bb6-c", box1
, "BOX(20 2, 30 10)",
250 "POINT(0 0)", "POINT(0 0)", pp
,
253 tester::apply("bb6-d", box1
, "BOX(20 11, 30 15)",
254 "POINT(0 0)", "POINT(0 0)", pp
,
257 tester::apply("bb6-e", box1
, "BOX(20 20, 30 30)",
258 "POINT(0 0)", "POINT(0 0)", pp
,
261 tester::apply("bb6-f", box1
, "BOX(15 20, 17 30)",
262 "POINT(0 0)", "POINT(0 0)", pp
,
265 tester::apply("bb6-g", box1
, "BOX(8 20, 10 25)",
266 "POINT(0 0)", "POINT(0 0)", pp
,
269 tester::apply("bb6-h", box1
, "BOX(8 15 , 10 17)",
270 "POINT(0 0)", "POINT(0 0)", pp
,
273 tester::apply("bb6-i", box1
, "BOX(8 8, 10 10)",
274 "POINT(0 0)", "POINT(0 0)", pp
,
277 tester::apply("bb6-j", box1
, "BOX(15 8, 17 10)",
278 "POINT(0 0)", "POINT(0 0)", pp
,
282 tester::apply("bb7", box1
, "BOX(12 22, 17 27)",
283 "POINT(17 20)", "POINT(17 22)", pp
,
287 tester::apply("bb8", box1
, "BOX(4 4, 8 8)",
288 "POINT(8 8)", "POINT(10 10)", pp
,
292 tester::apply("bb9-a", box1
, "BOX(4 14, 8 18)",
293 "POINT(8 18)", "SEGMENT(10 10, 10 20)", ps
,
296 tester::apply("bb9-b", box1
, "BOX(4 10, 8 18)",
297 "POINT(8 18)", "SEGMENT(10 10, 10 20)", ps
,
300 tester::apply("bb9-c", box1
, "BOX(4 8, 8 18)",
301 "POINT(8 18)", "SEGMENT(10 10, 10 20)", ps
,
305 tester::apply("bb10", box1
, "BOX(4 18, 8 22)",
306 "POINT(10 20)", "SEGMENT(8 18, 8 22)", ps
,
309 tester::apply("bb10", box1
, "BOX(4 20, 8 22)",
310 "POINT(10 20)", "SEGMENT(8 20, 8 22)", ps
,
314 tester::apply("bb11", box1
, "BOX(4 22, 8 24)",
315 "POINT(8 22)", "POINT(10 20)", pp
,
319 tester::apply("bb-far", "BOX(150 15, 170 25)", box1
,
320 "POINT(20 20)", "SEGMENT(150 15, 150 25)", ps
,
323 // crosses antimeridian
324 tester::apply("bb-anti1", "BOX(170 15, -160 25)", box1
,
325 "POINT(20 20)", "SEGMENT(170 15, 170 25)", ps
,
328 tester::apply("bb-anti2", "BOX(170 15, -160 25)", "BOX(160 10, -170 20)",
329 "POINT(20 20)", "POINT(20 20)", pp
,
332 tester::apply("bb-anti3", "BOX(170 15, -160 25)", "BOX(160 10, 170 20)",
333 "POINT(20 20)", "POINT(20 20)", pp
,
336 tester::apply("bb-anti4", "BOX(170 10, -160 20)", "BOX(160 30, -170 40)",
337 "POINT(180 20)", "POINT(180 30)", pp
,
342 tester::apply("bb-south1", "BOX(10 -20, 20 -10)", "BOX(30 -15, 40 -12)",
343 "POINT(30 -15)", "SEGMENT(20 -10, 20 -20)", ps
,
346 tester::apply("bb-south2", "BOX(10 -20, 20 -10)", "BOX(30 -30, 40 -25)",
347 "POINT(30 -25)", "POINT(20 -20)", pp
,
350 tester::apply("bb-south3", "BOX(10 -20, 20 -10)", "BOX(30 -25, 40 -15)",
351 "POINT(20 -20)", "SEGMENT(30 -15, 30 -25)", ps
,
354 tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -30, 30 -25)",
355 "POINT(10 -25)", "POINT(10 -20)", pp
,
358 tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -7, 30 -5)",
359 "POINT(10 -7)", "POINT(10 -10)", pp
,
365 tester::apply("bb-eq1", "BOX(30 -15, 40 30)", "BOX(10 -20, 20 25)",
366 "POINT(20 25)", "SEGMENT(30 -15, 30 30)", ps
,
369 tester::apply("bb-eq2", "BOX(30 -15, 40 20)", "BOX(10 -20, 20 25)",
370 "POINT(30 20)", "SEGMENT(20 -20, 20 25)", ps
,
373 tester::apply("bb-eq3", "BOX(30 5, 40 20)", "BOX(10 -20, 20 25)",
374 "POINT(30 20)", "SEGMENT(20 -20, 20 25)", ps
,
377 tester::apply("bb-eq4", "BOX(5 -30, 40 -25)", "BOX(10 -20, 20 25)",
378 "POINT(10 -25)", "POINT(10 -20)", pp
,
381 tester::apply("bb-eq5", "BOX(30 5, 40 20)", "BOX(10 -20, 50 25)",
382 "POINT(30 20)", "POINT(30 20)", pp
,
385 tester::apply("bb-eq6", "BOX(30 5, 40 20)", "BOX(10 -20, 35 25)",
386 "POINT(30 20)", "POINT(30 20)", pp
,
389 // One box in the north and one in the south hemisphere
391 tester::apply("bb-ns1", "BOX(30 15, 40 20)", "BOX(10 -20, 20 -15)",
392 "POINT(30 15)", "POINT(20 -15)", pp
,
395 tester::apply("bb-ns2", "BOX(30 15, 40 20)", "BOX(25 -20, 50 -15)",
396 "POINT(30 15)", "POINT(30 -15)", pp
,
400 template <typename Strategy
>
401 void test_distance_box_box_negative(Strategy
const& strategy
)
403 typedef test_distances
<box_type
, box_type
> tester
;
404 std::string
const box1neg
= "BOX(-20 10,-10 20)";
407 tester::apply("bb1", box1neg
, "BOX(-40 0,-30 5)",
408 "POINT(-20 10)", "POINT(-30 5)", pp
,
412 tester::apply("bb2-a", box1neg
, "BOX(-40 12, -30 17)",
413 "POINT(-30 17)", "SEGMENT(-20 10,-20 20)", ps
,
416 tester::apply("bb2-b", box1neg
, "BOX(-40 10, -30 17)",
417 "POINT(-30 17)", "SEGMENT(-20 10,-20 20)", ps
,
420 tester::apply("bb2-c", box1neg
, "BOX(-40 8, -30 17)",
421 "POINT(-30 17)", "SEGMENT(-20 10,-20 20)", ps
,
426 tester::apply("bb3-a", box1neg
, "BOX(-40 15, -30 25)",
427 "POINT(-20 20)", "SEGMENT(-30 15,-30 25)", ps
,
430 tester::apply("bb3-b", box1neg
, "BOX(-40 20, -30 40)",
431 "POINT(-20 20)", "SEGMENT(-30 20,-30 40)", ps
,
435 tester::apply("bb4", box1neg
, "BOX(-40 25, -30 40)",
436 "POINT(-20 20)", "POINT(-30 25)", pp
,
440 tester::apply("bb5", box1neg
, "BOX(-17 2,-12 7)",
441 "POINT(-17 7)", "POINT(-17 10)", pp
,
444 // case 6, boxes intersect thus distance is 0
445 tester::apply("bb6-a", box1neg
, "BOX(-17 2, -12 10)",
446 "POINT(0 0)", "POINT(0 0)", pp
,
449 tester::apply("bb6-b", box1neg
, "BOX(-17 2, -12 17)",
450 "POINT(0 0)", "POINT(0 0)", pp
,
453 tester::apply("bb6-c", box1neg
, "BOX(-30 2, -20 10)",
454 "POINT(0 0)", "POINT(0 0)", pp
,
457 tester::apply("bb6-d", box1neg
, "BOX(-30 11, -20 15)",
458 "POINT(0 0)", "POINT(0 0)", pp
,
461 tester::apply("bb6-e", box1neg
, "BOX(-30 20, -20 30)",
462 "POINT(0 0)", "POINT(0 0)", pp
,
465 tester::apply("bb6-f", box1neg
, "BOX(-17 20, -15 30)",
466 "POINT(0 0)", "POINT(0 0)", pp
,
469 tester::apply("bb6-g", box1neg
, "BOX(-10 20, -8 25)",
470 "POINT(0 0)", "POINT(0 0)", pp
,
473 tester::apply("bb6-h", box1neg
, "BOX(-10 15 , -8 17)",
474 "POINT(0 0)", "POINT(0 0)", pp
,
477 tester::apply("bb6-i", box1neg
, "BOX(-10 8, -8 10)",
478 "POINT(0 0)", "POINT(0 0)", pp
,
481 tester::apply("bb6-j", box1neg
, "BOX(-17 8, -15 10)",
482 "POINT(0 0)", "POINT(0 0)", pp
,
486 tester::apply("bb7", box1neg
, "BOX(-17 22, -12 27)",
487 "POINT(-17 20)", "POINT(-17 22)", pp
,
491 tester::apply("bb8", box1neg
, "BOX(-8 4, -4 8)",
492 "POINT(-8 8)", "POINT(-10 10)", pp
,
496 tester::apply("bb9-a", box1neg
, "BOX(-8 14, -4 18)",
497 "POINT(-8 18)", "SEGMENT(-10 10, -10 20)", ps
,
500 tester::apply("bb9-b", box1neg
, "BOX(-8 10, -4 18)",
501 "POINT(-8 18)", "SEGMENT(-10 10, -10 20)", ps
,
504 tester::apply("bb9-c", box1neg
, "BOX(-8 8, -4 18)",
505 "POINT(-8 18)", "SEGMENT(-10 10, -10 20)", ps
,
509 tester::apply("bb10", box1neg
, "BOX(-8 18, -4 22)",
510 "POINT(-10 20)", "SEGMENT(-8 18, -8 22)", ps
,
513 tester::apply("bb10", box1neg
, "BOX(-8 20, -4 22)",
514 "POINT(-10 20)", "SEGMENT(-8 20, -8 22)", ps
,
518 tester::apply("bb11", box1neg
, "BOX(-8 22, -4 24)",
519 "POINT(-8 22)", "POINT(-10 20)", pp
,
523 BOOST_AUTO_TEST_CASE( test_box_box
)
525 test_distance_box_box(box_box_strategy());
526 test_distance_box_box_negative(box_box_strategy());