1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2017, 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_geographic_point_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_geo_common.hpp"
26 typedef bg::cs::geographic
<bg::degree
> cs_type
;
27 typedef bg::model::point
<double, 2, cs_type
> point_type
;
28 typedef bg::model::multi_point
<point_type
> multi_point_type
;
29 typedef bg::model::segment
<point_type
> segment_type
;
30 typedef bg::model::box
<point_type
> box_type
;
32 namespace services
= bg::strategy::distance::services
;
33 typedef bg::default_distance_result
<point_type
>::type return_type
;
35 typedef bg::srs::spheroid
<double> stype
;
37 // Strategies for point-point distance
39 typedef bg::strategy::distance::andoyer
<stype
> andoyer_pp
;
40 typedef bg::strategy::distance::thomas
<stype
> thomas_pp
;
41 typedef bg::strategy::distance::vincenty
<stype
> vincenty_pp
;
43 // Strategies for point-segment distance
45 typedef bg::strategy::distance::geographic_cross_track
<bg::strategy::andoyer
, stype
, double>
48 typedef bg::strategy::distance::geographic_cross_track
<bg::strategy::thomas
, stype
, double>
51 typedef bg::strategy::distance::geographic_cross_track
<bg::strategy::vincenty
, stype
, double>
54 // Strategies for point-box distance
56 typedef bg::strategy::distance::geographic_cross_track_point_box
58 bg::strategy::andoyer
,
59 bg::srs::spheroid
<double>,
63 typedef bg::strategy::distance::geographic_cross_track_point_box
66 bg::srs::spheroid
<double>,
70 typedef bg::strategy::distance::geographic_cross_track_point_box
72 bg::strategy::vincenty
,
73 bg::srs::spheroid
<double>,
77 //===========================================================================
79 template <typename Strategy
>
80 inline bg::default_distance_result
<point_type
>::type
81 pp_distance(std::string
const& wkt1
,
82 std::string
const& wkt2
,
83 Strategy
const& strategy
)
86 bg::read_wkt(wkt1
, p1
);
87 bg::read_wkt(wkt2
, p2
);
88 return bg::distance(p1
, p2
, strategy
);
91 template <typename Strategy
>
92 inline bg::default_distance_result
<point_type
>::type
93 ps_distance(std::string
const& wkt1
,
94 std::string
const& wkt2
,
95 Strategy
const& strategy
)
99 bg::read_wkt(wkt1
, p
);
100 bg::read_wkt(wkt2
, s
);
101 return bg::distance(p
, s
, strategy
);
104 //===========================================================================
105 // Cases for relative location of a point wrt to a box
119 // and also the following cases
133 // and finally we have the corners
147 // for each relative position we also have to test the shifted point
148 // (this is due to the fact that boxes have longitudes in the
150 //===========================================================================
152 template <typename Strategy_pp
, typename Strategy_ps
, typename Strategy_pb
>
153 void test_distance_point_box(Strategy_pp
const& strategy_pp
,
154 Strategy_ps
const& strategy_ps
,
155 Strategy_pb
const& strategy_pb
)
158 #ifdef BOOST_GEOMETRY_TEST_DEBUG
159 std::cout
<< std::endl
;
160 std::cout
<< "point/box distance tests" << std::endl
;
162 typedef test_distance_of_geometries
<point_type
, box_type
> tester
;
164 std::string
const box1
= "BOX(10 10,20 20)";
167 tester::apply("pb1-1a", "POINT(5 25)", box1
,
168 pp_distance("POINT(5 25)", "POINT(10 20)", strategy_pp
),
172 tester::apply("pb1-1b", "POINT(3 12)", box1
,
173 ps_distance("POINT(3 12)", "SEGMENT(10 10,10 20)", strategy_ps
),
177 tester::apply("pb1-1c", "POINT(3 17)", box1
,
178 ps_distance("POINT(3 17)", "SEGMENT(10 10,10 20)", strategy_ps
),
182 tester::apply("pb1-1d", "POINT(5 4)", box1
,
183 pp_distance("POINT(5 4)", "POINT(10 10)", strategy_pp
),
187 tester::apply("pb1-1e", "POINT(-100 20)", box1
,
188 pp_distance("POINT(-100 20)", "POINT(10 20)", strategy_pp
),
192 tester::apply("pb1-1g", "POINT(-100 10)", box1
,
193 ps_distance("POINT(-100 10)", "SEGMENT(10 10,10 20)", strategy_ps
),
197 tester::apply("pb1-2a", "POINT(31 25)", box1
,
198 pp_distance("POINT(31 25)", "POINT(20 20)", strategy_pp
),
202 tester::apply("pb1-2b", "POINT(23 17)", box1
,
203 ps_distance("POINT(23 17)", "SEGMENT(20 10,20 20)", strategy_ps
),
207 tester::apply("pb1-2c", "POINT(29 3)", box1
,
208 pp_distance("POINT(29 3)", "POINT(20 10)", strategy_pp
),
212 tester::apply("pb1-2d", "POINT(131 65)", box1
,
213 pp_distance("POINT(131 65)", "POINT(20 20)", strategy_pp
),
217 tester::apply("pb1-2e", "POINT(110 10)", box1
,
218 ps_distance("POINT(110 10)", "SEGMENT(20 10,20 20)", strategy_ps
),
222 tester::apply("pb1-2f", "POINT(150 20)", box1
,
223 pp_distance("POINT(150 20)", "POINT(20 20)", strategy_pp
),
227 tester::apply("pb1-3a", "POINT(11 25)", box1
,
228 pp_distance("POINT(11 25)", "POINT(11 20)", strategy_pp
),
232 tester::apply("pb1-3b", "POINT(15 25)", box1
,
233 pp_distance("POINT(15 25)", "POINT(15 20)", strategy_pp
),
237 tester::apply("pb1-3c", "POINT(18 25)", box1
,
238 pp_distance("POINT(18 25)", "POINT(18 20)", strategy_pp
),
242 tester::apply("pb1-4a", "POINT(13 4)", box1
,
243 pp_distance("POINT(13 4)", "POINT(13 10)", strategy_pp
),
247 tester::apply("pb1-4b", "POINT(19 4)", box1
,
248 pp_distance("POINT(19 4)", "POINT(19 10)", strategy_pp
),
252 tester::apply("pb1-5", "POINT(15 14)", box1
, 0, strategy_pb
);
255 tester::apply("pb1-A", "POINT(10 28)", box1
,
256 pp_distance("POINT(10 28)", "POINT(10 20)", strategy_pp
),
260 tester::apply("pb1-B", "POINT(20 28)", box1
,
261 pp_distance("POINT(20 28)", "POINT(20 20)", strategy_pp
),
266 tester::apply("pb1-C", "POINT(14 20)", box1
, 0, strategy_pb
);
269 tester::apply("pb1-D", "POINT(10 17)", box1
, 0, strategy_pb
);
272 tester::apply("pb1-E", "POINT(20 11)", box1
, 0, strategy_pb
);
275 tester::apply("pb1-F", "POINT(19 10)", box1
, 0, strategy_pb
);
278 tester::apply("pb1-G", "POINT(10 -40)", box1
,
279 pp_distance("POINT(10 -40)", "POINT(10 10)", strategy_pp
),
283 tester::apply("pb1-H", "POINT(20 -50)", box1
,
284 pp_distance("POINT(20 -50)", "POINT(20 10)", strategy_pp
),
288 tester::apply("pb1-a", "POINT(10 20)", box1
, 0, strategy_pb
);
290 tester::apply("pb1-b", "POINT(20 20)", box1
, 0, strategy_pb
);
292 tester::apply("pb1-c", "POINT(10 10)", box1
, 0, strategy_pb
);
294 tester::apply("pb1-d", "POINT(20 10)", box1
, 0, strategy_pb
);
297 std::string
const box2
= "BOX(170 -60,400 80)";
299 // case 1 - point is closer to western meridian
300 tester::apply("pb2-1a", "POINT(160 0)", box2
,
301 ps_distance("POINT(160 0)", "SEGMENT(170 -60,170 80)", strategy_ps
),
304 // case 1 - point is closer to eastern meridian
305 tester::apply("pb2-1b", "POINT(50 0)", box2
,
306 ps_distance("POINT(50 0)", "SEGMENT(40 -60,40 80)", strategy_ps
),
309 // case 3 - equivalent point POINT(390 85) is above the box
310 tester::apply("pb2-3", "POINT(30 85)", box2
,
311 pp_distance("POINT(30 85)", "POINT(30 80)", strategy_pp
),
314 // case 4 - equivalent point POINT(390 -75) is below the box
315 tester::apply("pb2-4", "POINT(30 -75)", box2
,
316 pp_distance("POINT(30 -75)", "POINT(30 -60)", strategy_pp
),
319 // case 5 - equivalent point POINT(390 0) is inside box
320 tester::apply("pb2-5", "POINT(30 0)", box2
, 0, strategy_pb
);
323 std::string
const box3
= "BOX(-150 -50,-40 70)";
325 // case 1 - point is closer to western meridian
326 tester::apply("pb3-1a", "POINT(-170 10)", box3
,
327 ps_distance("POINT(-170 10)", "SEGMENT(-150 -50,-150 70)", strategy_ps
),
330 // case 2 - point is closer to eastern meridian
331 tester::apply("pb3-2a", "POINT(5 10)", box3
,
332 ps_distance("POINT(5 10)", "SEGMENT(-40 -50,-40 70)", strategy_ps
),
335 // case 2 - point is closer to western meridian
336 tester::apply("pb3-2a", "POINT(160 10)", box3
,
337 ps_distance("POINT(160 10)", "SEGMENT(-150 -50,-150 70)", strategy_ps
),
340 // case 2 - point is at equal distance from eastern and western meridian
341 tester::apply("pb3-2c1", "POINT(85 20)", box3
,
342 ps_distance("POINT(85 20)", "SEGMENT(-150 -50,-150 70)", strategy_ps
),
345 // case 2 - point is at equal distance from eastern and western meridian
346 tester::apply("pb3-2c2", "POINT(85 20)", box3
,
347 ps_distance("POINT(85 20)", "SEGMENT(-40 -50,-40 70)", strategy_ps
),
350 // box that is symmetric wrt the prime meridian
351 std::string
const box4
= "BOX(-75 -45,75 65)";
353 // case 1 - point is closer to western meridian
354 tester::apply("pb4-1a", "POINT(-100 10)", box4
,
355 ps_distance("POINT(-100 10)", "SEGMENT(-75 -45,-75 65)", strategy_ps
),
358 // case 2 - point is closer to eastern meridian
359 tester::apply("pb4-2a", "POINT(90 15)", box4
,
360 ps_distance("POINT(90 15)", "SEGMENT(75 -45,75 65)", strategy_ps
),
363 // case 2 - point is at equal distance from eastern and western meridian
364 tester::apply("pb4-2c1", "POINT(-180 20)", box4
,
365 ps_distance("POINT(-180 20)", "SEGMENT(-75 -45,-75 65)", strategy_ps
),
368 // case 2 - point is at equal distance from eastern and western meridian
369 tester::apply("pb4-2c2", "POINT(-180 20)", box4
,
370 ps_distance("POINT(-180 20)", "SEGMENT(75 -45,75 65)", strategy_ps
),
374 template <typename Strategy_pp
, typename Strategy_ps
, typename Strategy_pb
>
375 void test_distance_point_deg_box(Strategy_pp
const& strategy_pp
,
376 Strategy_ps
const& strategy_ps
,
377 Strategy_pb
const& strategy_pb
)
380 #ifdef BOOST_GEOMETRY_TEST_DEBUG
381 std::cout
<< std::endl
;
382 std::cout
<< "point/box distance tests" << std::endl
;
384 typedef test_distance_of_geometries
<point_type
, box_type
> tester
;
386 //box degenerates to a meridian segment
387 std::string
const box1
= "BOX(0 10,0 20)";
389 tester::apply("pbd1", "POINT(1 10)", box1
,
390 ps_distance("POINT(1 10)", "SEGMENT(0 10, 0 20)", strategy_ps
),
392 tester::apply("pbd2", "POINT(1 5)", box1
,
393 ps_distance("POINT(1 5)", "SEGMENT(0 10, 0 20)", strategy_ps
),
395 tester::apply("pbd3", "POINT(1 15)", box1
,
396 ps_distance("POINT(1 15)", "SEGMENT(0 10, 0 20)", strategy_ps
),
398 tester::apply("pbd4", "POINT(1 25)", box1
,
399 ps_distance("POINT(1 25)", "SEGMENT(0 10, 0 20)", strategy_ps
),
402 //box degenerates to a horizontal line; that is not a geodesic segment
403 std::string
const box2
= "BOX(10 10,20 10)";
405 tester::apply("pbd5", "POINT(15 15)", box2
,
406 pp_distance("POINT(15 15)", "POINT(15 10)", strategy_pp
),
408 tester::apply("pbd6", "POINT(5 15)", box2
,
409 pp_distance("POINT(5 15)", "POINT(10 10)", strategy_pp
),
411 tester::apply("pbd7", "POINT(25 15)", box2
,
412 pp_distance("POINT(25 15)", "POINT(20 10)", strategy_pp
),
415 //box degenerates to a point
416 std::string
const box3
= "BOX(0 10,0 10)";
418 tester::apply("pbd8", "POINT(1 11)", box3
,
419 pp_distance("POINT(1 11)", "POINT(0 10)", strategy_pp
),
423 template <typename Strategy_pp
, typename Strategy_ps
, typename Strategy_pb
>
424 void test_distance_multipoint_box(Strategy_pp
const& strategy_pp
,
425 Strategy_ps
const& strategy_ps
,
426 Strategy_pb
const& strategy_pb
)
429 #ifdef BOOST_GEOMETRY_TEST_DEBUG
430 std::cout
<< std::endl
;
431 std::cout
<< "multipoint/box distance tests" << std::endl
;
433 typedef test_distance_of_geometries
<multi_point_type
, box_type
> tester
;
435 std::string
const box1
= "BOX(10 10,20 20)";
437 tester::apply("mpb1-1a", "MULTIPOINT(5 25,25 26)", box1
,
438 pp_distance("POINT(5 25)", "POINT(10 20)", strategy_pp
),
441 tester::apply("mpb1-2e", "MULTIPOINT(110 10,110 9,110 0)", box1
,
442 ps_distance("POINT(110 10)", "SEGMENT(20 10,20 20)", strategy_ps
),
446 //===========================================================================
447 //===========================================================================
448 //===========================================================================
450 BOOST_AUTO_TEST_CASE( test_all_point_segment
)
452 test_distance_point_box(vincenty_pp(), vincenty_ps(), vincenty_pb());
453 test_distance_point_box(thomas_pp(), thomas_ps(), thomas_pb());
454 test_distance_point_box(andoyer_pp(), andoyer_ps(), andoyer_pb());
456 test_distance_point_deg_box(vincenty_pp(), vincenty_ps(), vincenty_pb());
457 test_distance_point_deg_box(thomas_pp(), thomas_ps(), thomas_pb());
458 test_distance_point_deg_box(andoyer_pp(), andoyer_ps(), andoyer_pb());
460 test_distance_multipoint_box(vincenty_pp(), vincenty_ps(), vincenty_pb());
461 test_distance_multipoint_box(thomas_pp(), thomas_ps(), thomas_pb());
462 test_distance_multipoint_box(andoyer_pp(), andoyer_ps(), andoyer_pb());