1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2016-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
11 #ifndef BOOST_TEST_MODULE
12 #define BOOST_TEST_MODULE test_distance_geographic_pl_l
15 #include <boost/geometry/core/srs.hpp>
16 #include <boost/test/included/unit_test.hpp>
18 #include "test_distance_geo_common.hpp"
20 typedef bg::cs::geographic
<bg::degree
> cs_type
;
21 typedef bg::model::point
<double, 2, cs_type
> point_type
;
22 typedef bg::model::segment
<point_type
> segment_type
;
23 typedef bg::model::multi_point
<point_type
> multi_point_type
;
24 typedef bg::model::segment
<point_type
> segment_type
;
25 typedef bg::model::linestring
<point_type
> linestring_type
;
26 typedef bg::model::multi_linestring
<linestring_type
> multi_linestring_type
;
28 namespace services
= bg::strategy::distance::services
;
29 typedef bg::default_distance_result
<point_type
>::type return_type
;
31 typedef bg::srs::spheroid
<double> stype
;
33 // Strategies for point-point distance
35 typedef bg::strategy::distance::andoyer
<stype
> andoyer_pp
;
36 typedef bg::strategy::distance::thomas
<stype
> thomas_pp
;
37 typedef bg::strategy::distance::vincenty
<stype
> vincenty_pp
;
39 // Strategies for point-segment distance
41 typedef bg::strategy::distance::geographic_cross_track
<bg::strategy::andoyer
, stype
, double>
44 typedef bg::strategy::distance::geographic_cross_track
<bg::strategy::thomas
, stype
, double>
47 typedef bg::strategy::distance::geographic_cross_track
<bg::strategy::vincenty
, stype
, double>
50 //===========================================================================
52 template <typename Strategy
>
53 inline bg::default_distance_result
<point_type
>::type
54 pp_distance(std::string
const& wkt1
,
55 std::string
const& wkt2
,
56 Strategy
const& strategy
)
59 bg::read_wkt(wkt1
, p1
);
60 bg::read_wkt(wkt2
, p2
);
61 return bg::distance(p1
, p2
, strategy
);
64 template <typename Strategy
>
65 inline bg::default_distance_result
<point_type
>::type
66 ps_distance(std::string
const& wkt1
,
67 std::string
const& wkt2
,
68 Strategy
const& strategy
)
72 bg::read_wkt(wkt1
, p
);
73 bg::read_wkt(wkt2
, s
);
74 return bg::distance(p
, s
, strategy
);
77 //===========================================================================
79 template <typename Strategy_pp
, typename Strategy_ps
>
80 void test_distance_point_segment(Strategy_pp
const& strategy_pp
,
81 Strategy_ps
const& strategy_ps
)
84 #ifdef BOOST_GEOMETRY_TEST_DEBUG
85 std::cout
<< std::endl
;
86 std::cout
<< "point/segment distance tests" << std::endl
;
88 typedef test_distance_of_geometries
<point_type
, segment_type
> tester
;
90 tester::apply("p-s-01",
93 pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp
),
95 tester::apply("p-s-02",
98 pp_distance("POINT(2.5 3)", "POINT(2.49777 0)", strategy_pp
),
100 tester::apply("p-s-03",
105 tester::apply("p-s-04",
110 tester::apply("p-s-05",
115 tester::apply("p-s-06",
118 pp_distance("POINT(3 0)", "POINT(3.5 3)", strategy_pp
),
120 tester::apply("p-s-07",
122 "SEGMENT(10 15,30 15)",
125 tester::apply("p-s-08",
127 "SEGMENT(10 15,30 15)",
130 tester::apply("p-s-09",
132 "SEGMENT(10 15,30 15)",
133 pp_distance("POINT(5 10)", "POINT(10 15)", strategy_pp
),
135 tester::apply("p-s-10",
137 "SEGMENT(10 15,30 15)",
138 pp_distance("POINT(35 10)", "POINT(30 15)", strategy_pp
),
140 tester::apply("p-s-11",
142 "SEGMENT(30 15,10 15)",
143 pp_distance("POINT(5 10)", "POINT(10 15)", strategy_pp
),
145 tester::apply("p-s-12",
147 "SEGMENT(30 15,10 15)",
148 pp_distance("POINT(35 10)", "POINT(30 15)", strategy_pp
),
151 tester::apply("p-s-right-up",
154 pp_distance("POINT(3 2)", "POINT(3.5 3)", strategy_pp
),
157 tester::apply("p-s-left-up",
160 pp_distance("POINT(2 2)", "POINT(1.5 3)", strategy_pp
),
163 tester::apply("p-s-up-1",
166 pp_distance("POINT(2.0003 2)", "POINT(2 3)", strategy_pp
),
169 tester::apply("p-s-up-2",
172 pp_distance("POINT(2.9997 2)", "POINT(3 3)", strategy_pp
),
175 tester::apply("p-s-right-down",
178 pp_distance("POINT(3 2)", "POINT(3.5 1)", strategy_pp
),
181 tester::apply("p-s-left-down",
184 pp_distance("POINT(2 2)", "POINT(1.5 1)", strategy_pp
),
187 tester::apply("p-s-down-1",
190 pp_distance("POINT(2.0003 2)", "POINT(2 1)", strategy_pp
),
193 tester::apply("p-s-down-2",
196 pp_distance("POINT(2.9997 2)", "POINT(3 1)", strategy_pp
),
199 tester::apply("p-s-south",
201 "SEGMENT(2 -2,3 -2)",
202 pp_distance("POINT(2.9997 -2)", "POINT(3 -1)", strategy_pp
),
205 tester::apply("p-s-antimeridian-1",
207 "SEGMENT(220 2,3 2)",
208 pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp
),
211 tester::apply("p-s-antimeridian-2",
213 "SEGMENT(220 2,3 2)",
214 pp_distance("POINT(220 2)", "POINT(220 1)", strategy_pp
),
217 // equator special case
218 tester::apply("p-s-eq1",
223 tester::apply("p-s-eq2",
226 pp_distance("POINT(2.5 0)", "POINT(2.5 2)", strategy_pp
),
228 tester::apply("p-s-eq3",
231 pp_distance("POINT(2 0)", "POINT(2 2)", strategy_pp
),
233 tester::apply("p-s-eq4",
236 pp_distance("POINT(3 0)", "POINT(3 2)", strategy_pp
),
239 // meridian special case
240 tester::apply("p-s-mer1",
243 pp_distance("POINT(2.5 2)", "POINT(2 2)", strategy_pp
),
245 tester::apply("p-s-mer3",
248 pp_distance("POINT(2.5 5)", "POINT(2 4)", strategy_pp
),
252 tester::apply("p-s-deg",
255 pp_distance("POINT(0 0)", "POINT(1 80)", strategy_pp
),
259 tester::apply("p-s-deg",
265 // very small distances to segment
266 tester::apply("p-s-07",
268 "SEGMENT(0.5 0,175.5 0)",
269 pp_distance("POINT(90 0)", "POINT(90 1e-3)", strategy_pp
),
271 tester::apply("p-s-08",
273 "SEGMENT(0.5 0,175.5 0)",
274 pp_distance("POINT(90 0)", "POINT(90 1e-4)", strategy_pp
),
276 tester::apply("p-s-09",
278 "SEGMENT(0.5 0,175.5 0)",
279 pp_distance("POINT(90 0)", "POINT(90 1e-5)", strategy_pp
),
281 tester::apply("p-s-10",
283 "SEGMENT(0.5 0,175.5 0)",
284 pp_distance("POINT(90 0)", "POINT(90 1e-6)", strategy_pp
),
286 tester::apply("p-s-11",
288 "SEGMENT(0.5 0,175.5 0)",
289 pp_distance("POINT(90 0)", "POINT(90 1e-7)", strategy_pp
),
291 tester::apply("p-s-12",
293 "SEGMENT(0.5 0,175.5 0)",
294 pp_distance("POINT(90 0)", "POINT(90 1e-8)", strategy_pp
),
297 // very large distance to segment
298 tester::apply("p-s-13",
300 "SEGMENT(0.5 0,175.5 0)",
301 pp_distance("POINT(90 0)", "POINT(90 90)", strategy_pp
),
303 tester::apply("p-s-14",
305 "SEGMENT(0.5 -89,175.5 -89)",
306 pp_distance("POINT(90 -89)", "POINT(90 90)", strategy_pp
),
308 // degenerate segment
309 tester::apply("p-s-15",
311 "SEGMENT(0.5 -90,175.5 -90)",
312 pp_distance("POINT(0.5 -90)", "POINT(90 90)", strategy_pp
),
314 tester::apply("p-s-16",
316 "SEGMENT(0.5 -90,175.5 -90)",
317 pp_distance("POINT(90 -90)", "POINT(90 90)", strategy_pp
),
319 // equatorial segment
320 tester::apply("p-s-17",
322 "SEGMENT(0 0,175.5 0)",
323 pp_distance("POINT(90 90)", "POINT(0 0)", strategy_pp
),
325 // segment pass by pole
326 tester::apply("p-s-18",
328 "SEGMENT(0 0,180 0)",
334 template <typename Strategy_pp
, typename Strategy_ps
>
335 void test_distance_point_segment_no_thomas(Strategy_pp
const& strategy_pp
,
336 Strategy_ps
const& strategy_ps
)
339 #ifdef BOOST_GEOMETRY_TEST_DEBUG
340 std::cout
<< std::endl
;
341 std::cout
<< "point/segment distance tests" << std::endl
;
343 typedef test_distance_of_geometries
<point_type
, segment_type
> tester
;
345 // thomas strategy is failing for those test cases
347 // meridian special case
348 tester::apply("p-s-mer2",
351 pp_distance("POINT(2.5 3)", "POINT(2 3.000114792872075)", strategy_pp
),
354 tester::apply("p-s-mer4",
357 pp_distance("POINT(1 80)", "POINT(0 80.00149225834545)", strategy_pp
),
360 // Half meridian segment passing through pole
361 tester::apply("p-s-19",
363 "SEGMENT(0 0,180 0)",
364 pp_distance("POINT(90 89)", "POINT(90 90)", strategy_pp
),
367 tester::apply("p-s-20",
369 "SEGMENT(0 0,180 0)",
370 pp_distance("POINT(80 89)", "POINT(0 89.82633489283377)", strategy_pp
),
373 tester::apply("p-s-20",
375 "SEGMENT(0 -1,180 1)",
376 pp_distance("POINT(80 89)", "POINT(0 89.82633489283377)", strategy_pp
),
380 //===========================================================================
382 template <typename Strategy_pp
, typename Strategy_ps
>
383 void test_distance_point_linestring(Strategy_pp
const& strategy_pp
,
384 Strategy_ps
const& strategy_ps
)
386 #ifdef BOOST_GEOMETRY_TEST_DEBUG
387 std::cout
<< std::endl
;
388 std::cout
<< "point/linestring distance tests" << std::endl
;
390 typedef test_distance_of_geometries
<point_type
, linestring_type
> tester
;
392 tester::apply("p-l-01",
394 "LINESTRING(2 0,2 0)",
395 pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp
),
397 tester::apply("p-l-02",
399 "LINESTRING(2 0,3 0)",
400 pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp
),
402 tester::apply("p-l-03",
404 "LINESTRING(2 0,3 0)",
405 pp_distance("POINT(2.5 3)", "POINT(2.5 0)", strategy_pp
),
407 tester::apply("p-l-04",
409 "LINESTRING(2 0,3 0)",
412 tester::apply("p-l-05",
414 "LINESTRING(2 0,3 0)",
417 tester::apply("p-l-06",
419 "LINESTRING(2 0,3 0)",
422 tester::apply("p-l-07",
424 "LINESTRING(1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0)",
425 ps_distance("POINT(7.5 10)", "SEGMENT(7 0,8 0)", strategy_ps
),
427 tester::apply("p-l-08",
429 "LINESTRING(1 1,2 1,3 1,4 1,5 1,6 1,7 1,20 2,21 2)",
430 ps_distance("POINT(7.5 10)", "SEGMENT(7 1,20 2)", strategy_ps
),
434 void test_distance_point_linestring_strategies()
436 typedef test_distance_of_geometries
<point_type
, linestring_type
> tester
;
438 tester::apply("p-l-03",
440 "LINESTRING(2 1,3 1)",
442 vincenty_strategy());
444 tester::apply("p-l-03",
446 "LINESTRING(2 1,3 1)",
450 tester::apply("p-l-03",
452 "LINESTRING(2 1,3 1)",
457 //===========================================================================
459 template <typename Strategy_pp
, typename Strategy_ps
>
460 void test_distance_point_multilinestring(Strategy_pp
const& strategy_pp
,
461 Strategy_ps
const& strategy_ps
)
463 #ifdef BOOST_GEOMETRY_TEST_DEBUG
464 std::cout
<< std::endl
;
465 std::cout
<< "point/multilinestring distance tests" << std::endl
;
467 typedef test_distance_of_geometries
469 point_type
, multi_linestring_type
472 tester::apply("p-ml-01",
474 "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
475 pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp
),
477 tester::apply("p-ml-02",
479 "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
480 pp_distance("POINT(2.5 3)", "POINT(2.5 0)", strategy_pp
),
482 tester::apply("p-ml-03",
484 "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
487 tester::apply("p-ml-04",
489 "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
492 tester::apply("p-ml-05",
494 "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
497 tester::apply("p-ml-06",
499 "MULTILINESTRING((-5 0,-3 0),(2 0,3 0,4 0,5 0,6 0,20 1,21 1))",
500 ps_distance("POINT(7.5 10)", "SEGMENT(6 0,20 1)", strategy_ps
),
502 tester::apply("p-ml-07",
504 "MULTILINESTRING((-20 10,-19 11,-18 10,-6 0,-5 0,-3 0),(2 0,6 0,20 1,21 1))",
505 ps_distance("POINT(-8 10)", "SEGMENT(-6 0,-18 10)", strategy_ps
),
509 //===========================================================================
511 template <typename Strategy_pp
, typename Strategy_ps
>
512 void test_distance_linestring_multipoint(Strategy_pp
const& strategy_pp
,
513 Strategy_ps
const& strategy_ps
)
515 #ifdef BOOST_GEOMETRY_TEST_DEBUG
516 std::cout
<< std::endl
;
517 std::cout
<< "linestring/multipoint distance tests" << std::endl
;
519 typedef test_distance_of_geometries
521 linestring_type
, multi_point_type
524 tester::apply("l-mp-01",
525 "LINESTRING(2 0,0 2,100 80)",
526 "MULTIPOINT(0 0,1 0,0 1,1 1)",
527 ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps
),
530 tester::apply("l-mp-02",
531 "LINESTRING(4 0,0 4,100 80)",
532 "MULTIPOINT(0 0,1 0,0 1,1 1)",
533 ps_distance("POINT(1 1)", "SEGMENT(0 4,4 0)", strategy_ps
),
535 tester::apply("l-mp-03",
536 "LINESTRING(1 1,2 2,100 80)",
537 "MULTIPOINT(0 0,1 0,0 1,1 1)",
540 tester::apply("l-mp-04",
541 "LINESTRING(3 3,4 4,100 80)",
542 "MULTIPOINT(0 0,1 0,0 1,1 1)",
543 pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp
),
545 tester::apply("l-mp-05",
546 "LINESTRING(0 0,10 0,10 10,0 10,0 0)",
547 "MULTIPOINT(1 -1,80 80,5 0,150 90)",
552 //===========================================================================
553 template <typename Strategy_pp
, typename Strategy_ps
>
554 void test_distance_multipoint_multilinestring(Strategy_pp
const& strategy_pp
,
555 Strategy_ps
const& strategy_ps
)
557 #ifdef BOOST_GEOMETRY_TEST_DEBUG
558 std::cout
<< std::endl
;
559 std::cout
<< "multipoint/multilinestring distance tests" << std::endl
;
561 typedef test_distance_of_geometries
563 multi_point_type
, multi_linestring_type
566 tester::apply("mp-ml-01",
567 "MULTIPOINT(0 0,1 0,0 1,1 1)",
568 "MULTILINESTRING((2 0,0 2),(2 2,3 3))",
569 ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps
),
571 tester::apply("mp-ml-02",
572 "MULTIPOINT(0 0,1 0,0 1,1 1)",
573 "MULTILINESTRING((3 0,0 3),(4 4,5 5))",
574 ps_distance("POINT(1 1)", "SEGMENT(3 0,0 3)", strategy_ps
),
576 tester::apply("mp-ml-03",
577 "MULTIPOINT(0 0,1 0,0 1,1 1)",
578 "MULTILINESTRING((4 4,5 5),(1 1,2 2))",
581 tester::apply("mp-ml-04",
582 "MULTIPOINT(0 0,1 0,0 1,1 1)",
583 "MULTILINESTRING((4 4,3 3),(4 4,5 5))",
584 pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp
),
588 //===========================================================================
590 template <typename Strategy_pp
, typename Strategy_ps
>
591 void test_distance_multipoint_segment(Strategy_pp
const& strategy_pp
,
592 Strategy_ps
const& strategy_ps
)
594 #ifdef BOOST_GEOMETRY_TEST_DEBUG
595 std::cout
<< std::endl
;
596 std::cout
<< "multipoint/segment distance tests" << std::endl
;
598 typedef test_distance_of_geometries
<multi_point_type
, segment_type
> tester
;
600 tester::apply("mp-s-01",
601 "MULTIPOINT(0 0,1 0,0 1,1 1)",
603 ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps
),
605 tester::apply("mp-s-02",
606 "MULTIPOINT(0 0,1 0,0 1,1 1)",
607 "SEGMENT(0 -3,1 -10)",
608 pp_distance("POINT(0 0)", "POINT(0 -3)", strategy_pp
),
610 tester::apply("mp-s-03",
611 "MULTIPOINT(0 0,1 0,0 1,1 1)",
615 tester::apply("mp-s-04",
616 "MULTIPOINT(0 0,1 0,0 1,1 1)",
618 pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp
),
620 tester::apply("mp-s-05",
621 "MULTIPOINT(0 0,1 0,0 1,1 1)",
622 "SEGMENT(0.5 -3,1 -10)",
623 pp_distance("POINT(1 0)", "POINT(0.5 -3)", strategy_pp
),
627 //===========================================================================
629 template <typename Point
, typename Strategy
>
630 void test_empty_input_pointlike_linear(Strategy
const& strategy
)
632 #ifdef BOOST_GEOMETRY_TEST_DEBUG
633 std::cout
<< std::endl
;
634 std::cout
<< "testing on empty inputs... " << std::flush
;
636 bg::model::linestring
<Point
> line_empty
;
637 bg::model::multi_point
<Point
> multipoint_empty
;
638 bg::model::multi_linestring
<bg::model::linestring
<Point
> > multiline_empty
;
640 Point point
= from_wkt
<Point
>("POINT(0 0)");
641 bg::model::linestring
<Point
> line
=
642 from_wkt
<bg::model::linestring
<Point
> >("LINESTRING(0 0,1 1)");
644 // 1st geometry is empty
645 //test_empty_input(multipoint_empty, line, strategy);
647 // 2nd geometry is empty
648 test_empty_input(point
, line_empty
, strategy
);
649 test_empty_input(point
, multiline_empty
, strategy
);
651 // both geometries are empty
652 //test_empty_input(multipoint_empty, line_empty, strategy);
653 //test_empty_input(multipoint_empty, multiline_empty, strategy);
655 #ifdef BOOST_GEOMETRY_TEST_DEBUG
656 std::cout
<< "done!" << std::endl
;
660 //===========================================================================
661 //===========================================================================
662 //===========================================================================
664 BOOST_AUTO_TEST_CASE( test_all_point_segment
)
666 //TODO: Operations with multipoints need geographic pt-box strategy
669 test_distance_point_segment(vincenty_pp(), vincenty_strategy());
670 test_distance_point_segment(thomas_pp(), thomas_strategy());
671 test_distance_point_segment(andoyer_pp(), andoyer_strategy());
673 test_distance_point_segment_no_thomas(vincenty_pp(), vincenty_strategy());
674 //test_distance_point_segment_no_thomas(thomas_pp(), thomas_strategy());
675 test_distance_point_segment_no_thomas(andoyer_pp(), andoyer_strategy());
677 test_distance_point_linestring(vincenty_pp(), vincenty_strategy());
678 test_distance_point_linestring(thomas_pp(), thomas_strategy());
679 test_distance_point_linestring(andoyer_pp(), andoyer_strategy());
680 test_distance_point_linestring_strategies();
682 test_distance_point_multilinestring(vincenty_pp(), vincenty_strategy());
683 test_distance_point_multilinestring(thomas_pp(), thomas_strategy());
684 test_distance_point_multilinestring(andoyer_pp(), andoyer_strategy());
686 // test_distance_linestring_multipoint(vincenty_pp(), vincenty_strategy());
687 // test_distance_linestring_multipoint(thomas_pp(), thomas_strategy());
688 // test_distance_linestring_multipoint(andoyer_pp(), andoyer_strategy());
690 // test_distance_multipoint_multilinestring(vincenty_pp(), vincenty_strategy());
691 // test_distance_multipoint_multilinestring(thomas_pp(), thomas_strategy());
692 // test_distance_multipoint_multilinestring(andoyer_pp(), andoyer_strategy());
694 // test_distance_multipoint_segment(vincenty_pp(), vincenty_strategy());
695 // test_distance_multipoint_segment(thomas_pp(), thomas_strategy());
696 // test_distance_multipoint_segment(andoyer_pp(), andoyer_strategy());
698 test_empty_input_pointlike_linear
<point_type
>(vincenty_strategy());