1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2016-2018, Oracle and/or its affiliates.
5 
6 // Contributed and/or modified by Vissarion Fysikopoulos, 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 #ifndef BOOST_TEST_MODULE
12 #define BOOST_TEST_MODULE test_distance_geographic_pointlike_linear
13 #endif
14 
15 #include <sstream>
16 
17 #include <boost/geometry/srs/spheroid.hpp>
18 #include <boost/test/included/unit_test.hpp>
19 
20 #include "test_distance_geo_common.hpp"
21 #include "test_empty_geometry.hpp"
22 
23 typedef bg::cs::geographic<bg::degree> cs_type;
24 typedef bg::model::point<double, 2, cs_type> point_type;
25 typedef bg::model::segment<point_type> segment_type;
26 typedef bg::model::multi_point<point_type> multi_point_type;
27 typedef bg::model::segment<point_type> segment_type;
28 typedef bg::model::linestring<point_type> linestring_type;
29 typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
30 
31 typedef bg::cs::geographic<bg::radian> cs_type_rad;
32 typedef bg::model::point<double, 2, cs_type_rad> point_type_rad;
33 typedef bg::model::segment<point_type_rad> segment_type_rad;
34 
35 //===========================================================================
36 
37 template <typename Strategy>
38 inline bg::default_distance_result<point_type>::type
pp_distance(std::string const & wkt1,std::string const & wkt2,Strategy const & strategy)39 pp_distance(std::string const& wkt1,
40             std::string const& wkt2,
41             Strategy const& strategy)
42 {
43     point_type p1, p2;
44     bg::read_wkt(wkt1, p1);
45     bg::read_wkt(wkt2, p2);
46     return bg::distance(p1, p2, strategy);
47 }
48 
49 template <typename Strategy>
50 inline bg::default_distance_result<point_type>::type
ps_distance(std::string const & wkt1,std::string const & wkt2,Strategy const & strategy)51 ps_distance(std::string const& wkt1,
52             std::string const& wkt2,
53             Strategy const& strategy)
54 {
55     point_type p;
56     segment_type s;
57     bg::read_wkt(wkt1, p);
58     bg::read_wkt(wkt2, s);
59     return bg::distance(p, s, strategy);
60 }
61 
62 //===========================================================================
63 
64 template <typename Strategy_pp, typename Strategy_ps>
test_distance_point_segment(Strategy_pp const & strategy_pp,Strategy_ps const & strategy_ps,bool WGS84)65 void test_distance_point_segment(Strategy_pp const& strategy_pp,
66                                  Strategy_ps const& strategy_ps,
67                                  bool WGS84)
68 {
69 
70 #ifdef BOOST_GEOMETRY_TEST_DEBUG
71     std::cout << std::endl;
72     std::cout << "point/segment distance tests" << std::endl;
73 #endif
74     typedef test_distance_of_geometries<point_type, segment_type> tester;
75 
76     tester::apply("p-s-01",
77                   "POINT(0 0)",
78                   "SEGMENT(2 0,3 0)",
79                   pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp),
80                   strategy_ps, true, true);
81     tester::apply("p-s-02",
82                   "POINT(2.5 3)",
83                   "SEGMENT(2 0,3 0)",
84                   pp_distance("POINT(2.5 3)", "POINT(2.5 0)", strategy_pp),
85                   strategy_ps, true, true);
86     tester::apply("p-s-03",
87                   "POINT(2 0)",
88                   "SEGMENT(2 0,3 0)",
89                   0,
90                   strategy_ps, true, true);
91     tester::apply("p-s-04",
92                   "POINT(3 0)",
93                   "SEGMENT(2 0,3 0)",
94                   0,
95                   strategy_ps, true, true);
96     tester::apply("p-s-05",
97                   "POINT(2.5 0)",
98                   "SEGMENT(2 0,3 0)",
99                   0,
100                   strategy_ps, true, true);
101     tester::apply("p-s-06",
102                   "POINT(3.5 3)",
103                   "SEGMENT(2 0,3 0)",
104                   pp_distance("POINT(3 0)", "POINT(3.5 3)", strategy_pp),
105                   strategy_ps, true, true);
106     if(WGS84)
107     {
108         tester::apply("p-s-07",
109                       "POINT(15 80)",
110                       "SEGMENT(10 15,30 15)",
111                       7204174.8264546748,
112                       strategy_ps, true, true);
113         tester::apply("p-s-08",
114                       "POINT(15 10)",
115                       "SEGMENT(10 15,30 15)",
116                       571412.71247283253,
117                       strategy_ps, true, true);
118     }
119     tester::apply("p-s-09",
120                   "POINT(5 10)",
121                   "SEGMENT(10 15,30 15)",
122                   pp_distance("POINT(5 10)", "POINT(10 15)", strategy_pp),
123                   strategy_ps, true, true);
124     tester::apply("p-s-10",
125                   "POINT(35 10)",
126                   "SEGMENT(10 15,30 15)",
127                   pp_distance("POINT(35 10)", "POINT(30 15)", strategy_pp),
128                   strategy_ps, true, true);
129     tester::apply("p-s-11",
130                   "POINT(5 10)",
131                   "SEGMENT(30 15,10 15)",
132                   pp_distance("POINT(5 10)", "POINT(10 15)", strategy_pp),
133                   strategy_ps, true, true);
134     tester::apply("p-s-12",
135                   "POINT(35 10)",
136                   "SEGMENT(30 15,10 15)",
137                   pp_distance("POINT(35 10)", "POINT(30 15)", strategy_pp),
138                   strategy_ps, true, true);
139 
140     tester::apply("p-s-right-up",
141                   "POINT(3.5 3)",
142                   "SEGMENT(2 2,3 2)",
143                   pp_distance("POINT(3 2)", "POINT(3.5 3)", strategy_pp),
144                   strategy_ps, true, true);
145 
146     tester::apply("p-s-left-up",
147                   "POINT(1.5 3)",
148                   "SEGMENT(2 2,3 2)",
149                   pp_distance("POINT(2 2)", "POINT(1.5 3)", strategy_pp),
150                   strategy_ps, true, true);
151 
152     tester::apply("p-s-up-1",
153                   "POINT(2 3)",
154                   "SEGMENT(2 2,3 2)",
155                   pp_distance("POINT(2.0003 2)", "POINT(2 3)", strategy_pp),
156                   strategy_ps, true, true);
157 
158     tester::apply("p-s-up-2",
159                   "POINT(3 3)",
160                   "SEGMENT(2 2,3 2)",
161                   pp_distance("POINT(2.9997 2)", "POINT(3 3)", strategy_pp),
162                   strategy_ps, true, true);
163 
164     tester::apply("p-s-right-down",
165                   "POINT(3.5 1)",
166                   "SEGMENT(2 2,3 2)",
167                   pp_distance("POINT(3 2)", "POINT(3.5 1)", strategy_pp),
168                   strategy_ps, true, true);
169 
170     tester::apply("p-s-left-down",
171                   "POINT(1.5 1)",
172                   "SEGMENT(2 2,3 2)",
173                   pp_distance("POINT(2 2)", "POINT(1.5 1)", strategy_pp),
174                   strategy_ps, true, true);
175 
176     tester::apply("p-s-down-1",
177                   "POINT(2 1)",
178                   "SEGMENT(2 2,3 2)",
179                   pp_distance("POINT(2 2)", "POINT(2 1)", strategy_pp),
180                   strategy_ps, true, true);
181 
182     tester::apply("p-s-down-2",
183                   "POINT(3 1)",
184                   "SEGMENT(2 2,3 2)",
185                   pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
186                   strategy_ps, true, true);
187 
188     tester::apply("p-s-south",
189                   "POINT(3 -1)",
190                   "SEGMENT(2 -2,3 -2)",
191                   pp_distance("POINT(3 -2)", "POINT(3 -1)", strategy_pp),
192                   strategy_ps, true, true);
193 
194     tester::apply("p-s-antimeridian-1",
195                   "POINT(3 1)",
196                   "SEGMENT(220 2,3 2)",
197                   pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
198                   strategy_ps, true, true);
199 
200     tester::apply("p-s-antimeridian-2",
201                   "POINT(220 1)",
202                   "SEGMENT(220 2,3 2)",
203                   pp_distance("POINT(220 2)", "POINT(220 1)", strategy_pp),
204                   strategy_ps, true, true);
205 
206     // equator special case
207     tester::apply("p-s-eq1",
208                   "POINT(2.5 0)",
209                   "SEGMENT(2 0,3 0)",
210                   0,
211                   strategy_ps, true, true);
212     tester::apply("p-s-eq2",
213                   "POINT(2.5 2)",
214                   "SEGMENT(2 0,3 0)",
215                   pp_distance("POINT(2.5 0)", "POINT(2.5 2)", strategy_pp),
216                   strategy_ps, true, true);
217     tester::apply("p-s-eq3",
218                   "POINT(2 2)",
219                   "SEGMENT(2 0,3 0)",
220                   pp_distance("POINT(2 0)", "POINT(2 2)", strategy_pp),
221                   strategy_ps, true, true);
222     tester::apply("p-s-eq4",
223                   "POINT(3 2)",
224                   "SEGMENT(2 0,3 0)",
225                   pp_distance("POINT(3 0)", "POINT(3 2)", strategy_pp),
226                   strategy_ps, true, true);
227 
228     // meridian special case
229     tester::apply("p-s-mer1",
230                   "POINT(2.5 2)",
231                   "SEGMENT(2 2,2 4)",
232                   pp_distance("POINT(2.5 2)", "POINT(2 2.000076608014728)", strategy_pp),
233                   strategy_ps, true, true);
234     tester::apply("p-s-mer3",
235                   "POINT(2.5 5)",
236                   "SEGMENT(2 2,2 4)",
237                   pp_distance("POINT(2.5 5)", "POINT(2 4)", strategy_pp),
238                   strategy_ps, true, true);
239     tester::apply("p-s-mer4",
240                   "POINT(0 20)",
241                   "SEGMENT(0 40,180 80)",
242                   pp_distance("POINT(0 20)", "POINT(0 40)", strategy_pp),
243                   strategy_ps, true, true);
244     tester::apply("p-s-mer5",
245                   "POINT(0 20)",
246                   "SEGMENT(0 40,0 80)",
247                   pp_distance("POINT(0 20)", "POINT(0 40)", strategy_pp),
248                   strategy_ps, true, true);
249 
250     //degenerate segment
251     tester::apply("p-s-deg",
252                   "POINT(1 80)",
253                   "SEGMENT(0 0,0 0)",
254                   pp_distance("POINT(0 0)", "POINT(1 80)", strategy_pp),
255                   strategy_ps, true, true);
256 
257     //point on segment
258     tester::apply("p-s-deg",
259                   "POINT(0 80)",
260                   "SEGMENT(0 0,0 90)",
261                   0,
262                   strategy_ps, true, true);
263 
264     // very small distances to segment
265     tester::apply("p-s-07",
266                   "POINT(90 1e-3)",
267                   "SEGMENT(0.5 0,175.5 0)",
268                   pp_distance("POINT(90 0)", "POINT(90 1e-3)", strategy_pp),
269                   strategy_ps, true, true);
270     tester::apply("p-s-08",
271                   "POINT(90 1e-4)",
272                   "SEGMENT(0.5 0,175.5 0)",
273                   pp_distance("POINT(90 0)", "POINT(90 1e-4)", strategy_pp),
274                   strategy_ps, true, true);
275     tester::apply("p-s-09",
276                   "POINT(90 1e-5)",
277                   "SEGMENT(0.5 0,175.5 0)",
278                   pp_distance("POINT(90 0)", "POINT(90 1e-5)", strategy_pp),
279                   strategy_ps, true, true);
280     tester::apply("p-s-10",
281                   "POINT(90 1e-6)",
282                   "SEGMENT(0.5 0,175.5 0)",
283                   pp_distance("POINT(90 0)", "POINT(90 1e-6)", strategy_pp),
284                   strategy_ps, true, true);
285     tester::apply("p-s-11",
286                   "POINT(90 1e-7)",
287                   "SEGMENT(0.5 0,175.5 0)",
288                   pp_distance("POINT(90 0)", "POINT(90 1e-7)", strategy_pp),
289                   strategy_ps, true, true);
290     tester::apply("p-s-12",
291                   "POINT(90 1e-8)",
292                   "SEGMENT(0.5 0,175.5 0)",
293                   pp_distance("POINT(90 0)", "POINT(90 1e-8)", strategy_pp),
294                   strategy_ps, true, true);
295 
296     // very large distance to segment
297     tester::apply("p-s-13",
298                   "POINT(90 90)",
299                   "SEGMENT(0.5 0,175.5 0)",
300                   pp_distance("POINT(90 0)", "POINT(90 90)", strategy_pp),
301                   strategy_ps, true, true);
302     tester::apply("p-s-14",
303                   "POINT(90 90)",
304                   "SEGMENT(0.5 -89,175.5 -89)",
305                   pp_distance("POINT(90 -89)", "POINT(90 90)", strategy_pp),
306                   strategy_ps, true, true);
307     // degenerate segment
308     tester::apply("p-s-15",
309                   "POINT(90 90)",
310                   "SEGMENT(0.5 -90,175.5 -90)",
311                   pp_distance("POINT(0.5 -90)", "POINT(90 90)", strategy_pp),
312                   strategy_ps, true, true);
313     tester::apply("p-s-16",
314                   "POINT(90 90)",
315                   "SEGMENT(0.5 -90,175.5 -90)",
316                   pp_distance("POINT(90 -90)", "POINT(90 90)", strategy_pp),
317                   strategy_ps, true, true);
318     // equatorial segment
319     tester::apply("p-s-17",
320                   "POINT(90 90)",
321                   "SEGMENT(0 0,175.5 0)",
322                   pp_distance("POINT(90 90)", "POINT(0 0)", strategy_pp),
323                   strategy_ps, true, true);
324     // segment pass by pole
325     tester::apply("p-s-18",
326                   "POINT(90 90)",
327                   "SEGMENT(0 0,180 0)",
328                   0,
329                   strategy_ps, true, true);
330 
331     tester::apply("p-s-20",
332                   "POINT(80 89)",
333                   "SEGMENT(0 0,180 0)",
334                   pp_distance("POINT(80 89)", "POINT(0 89.82633489283377)", strategy_pp),
335                   strategy_ps, true, true);
336 
337     tester::apply("p-s-21",
338                   "POINT(80 89)",
339                   "SEGMENT(0 -1,180 1)",
340                   pp_distance("POINT(80 89)", "POINT(0 89.82633489283377)", strategy_pp),
341                   strategy_ps, true, true);
342 
343     // meridian special case
344     tester::apply("p-s-mer1",
345                   "POINT(2.5 3)",
346                   "SEGMENT(2 2,2 4)",
347                   pp_distance("POINT(2.5 3)", "POINT(2 3.000114792872075)", strategy_pp),
348                   strategy_ps, true, true);
349     tester::apply("p-s-mer2",
350                   "POINT(1 80)",
351                   "SEGMENT(0 0,0 90)",
352                   pp_distance("POINT(1 80)", "POINT(0 80.00149225834545)", strategy_pp),
353                   strategy_ps, true, true);
354     tester::apply("p-s-mer3",
355                   "POINT(2 0)",
356                   "SEGMENT(1 -1,1 0)",
357                   pp_distance("POINT(2 0)", "POINT(1 0)", strategy_pp),
358                   strategy_ps, true, true);
359 
360     tester::apply("p-s-acos",
361                   "POINT(0 90)",
362                   "SEGMENT(90 0,0 1.000005)",
363                   pp_distance("POINT(0 90)", "POINT(0.3017072304435489 1.000018955050697)",
364                               strategy_pp),
365                   strategy_ps, true, true);
366 }
367 
368 template <typename Strategy_pp, typename Strategy_ps>
test_distance_point_segment_no_thomas(Strategy_pp const & strategy_pp,Strategy_ps const & strategy_ps)369 void test_distance_point_segment_no_thomas(Strategy_pp const& strategy_pp,
370                                            Strategy_ps const& strategy_ps)
371 {
372 
373 #ifdef BOOST_GEOMETRY_TEST_DEBUG
374     std::cout << std::endl;
375     std::cout << "point/segment distance tests" << std::endl;
376 #endif
377     typedef test_distance_of_geometries<point_type, segment_type> tester;
378 
379     // thomas strategy is failing for those test cases
380     // this is because of inaccurate results for points close to poles
381 
382     tester::apply("p-s-19",
383                   "POINT(90 89)",
384                   "SEGMENT(0 0,180 0)",
385                   pp_distance("POINT(90 89)", "POINT(90 90)", strategy_pp),
386                   strategy_ps, true, true);
387 }
388 
389 template <typename Strategy_pp, typename Strategy_ps>
test_distance_point_segment_rad_mix(Strategy_pp const & strategy_pp,Strategy_ps const & strategy_ps)390 void test_distance_point_segment_rad_mix(Strategy_pp const& strategy_pp,
391                                          Strategy_ps const& strategy_ps)
392 {
393 
394 #ifdef BOOST_GEOMETRY_TEST_DEBUG
395     std::cout << std::endl;
396     std::cout << "point/segment distance tests" << std::endl;
397 #endif
398     typedef test_distance_of_geometries<point_type, segment_type> tester1;
399     typedef test_distance_of_geometries<point_type_rad, segment_type> tester2;
400     typedef test_distance_of_geometries<point_type, segment_type_rad> tester3;
401     typedef test_distance_of_geometries<point_type_rad, segment_type_rad> tester4;
402 
403     const double d2r = bg::math::d2r<double>();
404 
405     std::ostringstream s1;
406     s1 << 1*d2r;
407     std::ostringstream s2;
408     s2 << 2*d2r;
409     std::ostringstream s3;
410     s3 << 3*d2r;
411 
412     tester1::apply("p-s-mix1",
413                    "POINT(3 1)",
414                    "SEGMENT(2 2,3 2)",
415                    pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
416                    strategy_ps, true, true);
417     tester2::apply("p-s-mix2",
418                    "POINT(" + s3.str() + " " + s1.str() + ")",
419                    "SEGMENT(2 2,3 2)",
420                    pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
421                    strategy_ps, true, true);
422     tester3::apply("p-s-mix3",
423                    "POINT(3 1)",
424                    "SEGMENT(" + s2.str() + " " + s2.str() + ","
425                               + s3.str() + " " + s2.str() + ")",
426                    pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
427                    strategy_ps, true, true);
428     tester4::apply("p-s-mix4",
429                    "POINT(" + s3.str() + " " + s1.str() + ")",
430                    "SEGMENT(" + s2.str() + " " + s2.str() + ","
431                               + s3.str() + " " + s2.str() + ")",
432                    pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
433                    strategy_ps, true, true);
434 }
435 
436 //===========================================================================
437 
438 template <typename Strategy_pp, typename Strategy_ps>
test_distance_point_linestring(Strategy_pp const & strategy_pp,Strategy_ps const & strategy_ps)439 void test_distance_point_linestring(Strategy_pp const& strategy_pp,
440                                     Strategy_ps const& strategy_ps)
441 {
442 #ifdef BOOST_GEOMETRY_TEST_DEBUG
443     std::cout << std::endl;
444     std::cout << "point/linestring distance tests" << std::endl;
445 #endif
446     typedef test_distance_of_geometries<point_type, linestring_type> tester;
447 
448     tester::apply("p-l-01",
449                   "POINT(0 0)",
450                   "LINESTRING(2 0,2 0)",
451                   pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp),
452                   strategy_ps, true, false, false);
453     tester::apply("p-l-02",
454                   "POINT(0 0)",
455                   "LINESTRING(2 0,3 0)",
456                   pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp),
457                   strategy_ps, true, false, false);
458     tester::apply("p-l-03",
459                   "POINT(2.5 3)",
460                   "LINESTRING(2 0,3 0)",
461                   pp_distance("POINT(2.5 3)", "POINT(2.5 0)", strategy_pp),
462                   strategy_ps, true, false, false);
463     tester::apply("p-l-04",
464                   "POINT(2 0)",
465                   "LINESTRING(2 0,3 0)",
466                   0,
467                   strategy_ps, true, false, false);
468     tester::apply("p-l-05",
469                   "POINT(3 0)",
470                   "LINESTRING(2 0,3 0)",
471                   0,
472                   strategy_ps, true, false, false);
473     tester::apply("p-l-06",
474                   "POINT(2.5 0)",
475                   "LINESTRING(2 0,3 0)",
476                   0,
477                   strategy_ps, true, false, false);
478     tester::apply("p-l-07",
479                   "POINT(7.5 10)",
480                   "LINESTRING(1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0)",
481                   ps_distance("POINT(7.5 10)", "SEGMENT(7 0,8 0)", strategy_ps),
482                   strategy_ps, true, false, false);
483     tester::apply("p-l-08",
484                   "POINT(7.5 10)",
485                   "LINESTRING(1 1,2 1,3 1,4 1,5 1,6 1,7 1,20 2,21 2)",
486                   ps_distance("POINT(7.5 10)", "SEGMENT(7 1,20 2)", strategy_ps),
487                   strategy_ps, true, false, false);
488 }
489 
test_distance_point_linestring_strategies()490 void test_distance_point_linestring_strategies()
491 {
492     typedef test_distance_of_geometries<point_type, linestring_type> tester;
493 
494     tester::apply("p-l-s-01",
495                   "POINT(2.5 3)",
496                   "LINESTRING(2 1,3 1)",
497                   221147.24332788656,
498                   vincenty_ps(),
499                   true, false, false);
500 
501     tester::apply("p-l-s-02",
502                   "POINT(2.5 3)",
503                   "LINESTRING(2 1,3 1)",
504                   221147.36682199029,
505                   thomas_ps(),
506                   true, false, false);
507 
508     tester::apply("p-l-s-03",
509                   "POINT(2.5 3)",
510                   "LINESTRING(2 1,3 1)",
511                   221144.76527049288,
512                   andoyer_ps(),
513                   true, false, false);
514 }
515 
516 //===========================================================================
517 
518 template <typename Strategy_pp, typename Strategy_ps>
test_distance_point_multilinestring(Strategy_pp const & strategy_pp,Strategy_ps const & strategy_ps)519 void test_distance_point_multilinestring(Strategy_pp const& strategy_pp,
520                                          Strategy_ps const& strategy_ps)
521 {
522 #ifdef BOOST_GEOMETRY_TEST_DEBUG
523     std::cout << std::endl;
524     std::cout << "point/multilinestring distance tests" << std::endl;
525 #endif
526     typedef test_distance_of_geometries
527         <
528             point_type, multi_linestring_type
529         > tester;
530 
531     tester::apply("p-ml-01",
532                   "POINT(0 0)",
533                   "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
534                   pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp),
535                   strategy_ps, true, false, false);
536     tester::apply("p-ml-02",
537                   "POINT(2.5 3)",
538                   "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
539                   pp_distance("POINT(2.5 3)", "POINT(2.5 0)", strategy_pp),
540                   strategy_ps, true, false, false);
541     tester::apply("p-ml-03",
542                   "POINT(2 0)",
543                   "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
544                   0,
545                   strategy_ps, true, false, false);
546     tester::apply("p-ml-04",
547                   "POINT(3 0)",
548                   "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
549                   0,
550                   strategy_ps, true, false, false);
551     tester::apply("p-ml-05",
552                   "POINT(2.5 0)",
553                   "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
554                   0,
555                   strategy_ps, true, false, false);
556     tester::apply("p-ml-06",
557                   "POINT(7.5 10)",
558                   "MULTILINESTRING((-5 0,-3 0),(2 0,3 0,4 0,5 0,6 0,20 1,21 1))",
559                   ps_distance("POINT(7.5 10)", "SEGMENT(6 0,20 1)", strategy_ps),
560                   strategy_ps, true, false, false);
561     tester::apply("p-ml-07",
562                   "POINT(-8 10)",
563                   "MULTILINESTRING((-20 10,-19 11,-18 10,-6 0,-5 0,-3 0),(2 0,6 0,20 1,21 1))",
564                   ps_distance("POINT(-8 10)", "SEGMENT(-6 0,-18 10)", strategy_ps),
565                   strategy_ps, true, false, false);
566 }
567 
568 //===========================================================================
569 
570 template <typename Strategy_pp, typename Strategy_ps>
test_distance_linestring_multipoint(Strategy_pp const & strategy_pp,Strategy_ps const & strategy_ps)571 void test_distance_linestring_multipoint(Strategy_pp const& strategy_pp,
572                                          Strategy_ps const& strategy_ps)
573 {
574 #ifdef BOOST_GEOMETRY_TEST_DEBUG
575     std::cout << std::endl;
576     std::cout << "linestring/multipoint distance tests" << std::endl;
577 #endif
578     typedef test_distance_of_geometries
579         <
580             linestring_type, multi_point_type
581         > tester;
582 
583     tester::apply("l-mp-01",
584                   "LINESTRING(2 0,0 2,100 80)",
585                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
586                   ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps),
587                   strategy_ps, true, false, false);
588     tester::apply("l-mp-02",
589                   "LINESTRING(4 0,0 4,100 80)",
590                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
591                   ps_distance("POINT(1 1)", "SEGMENT(0 4,4 0)", strategy_ps),
592                   strategy_ps, true, false, false);
593     tester::apply("l-mp-03",
594                   "LINESTRING(1 1,2 2,100 80)",
595                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
596                   0,
597                   strategy_ps, true, false, false);
598     tester::apply("l-mp-04",
599                   "LINESTRING(3 3,4 4,100 80)",
600                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
601                   pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp),
602                   strategy_ps, true, false, false);
603     tester::apply("l-mp-05",
604                   "LINESTRING(0 0,10 0,10 10,0 10,0 0)",
605                   "MULTIPOINT(1 -1,80 80,5 0,150 90)",
606                   0,
607                   strategy_ps, true, false, false);
608     tester::apply("l-mp-06",
609                   "LINESTRING(90 0,0 1.00005)",
610                   "MULTIPOINT((0 0),(0 0),(0 0),(0 0),(0 0),(0 0),(0 0 ),(0 0),\
611                               (0 0),(0 0 ),(0 0),(0 0),(69.35235 155.0205),\
612                               (75.72081 37.97683),(0 0),(0 0),(0 0))",
613                   pp_distance("POINT(0 0)", "POINT(0 1.00005)", strategy_pp),
614                   strategy_ps, true, false, false);
615 }
616 
617 //===========================================================================
618 template <typename Strategy_pp, typename Strategy_ps>
test_distance_multipoint_multilinestring(Strategy_pp const & strategy_pp,Strategy_ps const & strategy_ps)619 void test_distance_multipoint_multilinestring(Strategy_pp const& strategy_pp,
620                                               Strategy_ps const& strategy_ps)
621 {
622 #ifdef BOOST_GEOMETRY_TEST_DEBUG
623     std::cout << std::endl;
624     std::cout << "multipoint/multilinestring distance tests" << std::endl;
625 #endif
626     typedef test_distance_of_geometries
627         <
628             multi_point_type, multi_linestring_type
629         > tester;
630 
631     tester::apply("mp-ml-01",
632                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
633                   "MULTILINESTRING((2 0,0 2),(2 2,3 3))",
634                   ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps),
635                   strategy_ps, true, false, false);
636     tester::apply("mp-ml-02",
637                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
638                   "MULTILINESTRING((3 0,0 3),(4 4,5 5))",
639                   ps_distance("POINT(1 1)", "SEGMENT(3 0,0 3)", strategy_ps),
640                   strategy_ps, true, false, false);
641     tester::apply("mp-ml-03",
642                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
643                   "MULTILINESTRING((4 4,5 5),(1 1,2 2))",
644                   0,
645                   strategy_ps, true, false, false);
646     tester::apply("mp-ml-04",
647                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
648                   "MULTILINESTRING((4 4,3 3),(4 4,5 5))",
649                   pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp),
650                   strategy_ps, true, false, false);
651 }
652 
653 //===========================================================================
654 
655 template <typename Strategy_pp, typename Strategy_ps>
test_distance_multipoint_segment(Strategy_pp const & strategy_pp,Strategy_ps const & strategy_ps)656 void test_distance_multipoint_segment(Strategy_pp const& strategy_pp,
657                                       Strategy_ps const& strategy_ps)
658 {
659 #ifdef BOOST_GEOMETRY_TEST_DEBUG
660     std::cout << std::endl;
661     std::cout << "multipoint/segment distance tests" << std::endl;
662 #endif
663     typedef test_distance_of_geometries<multi_point_type, segment_type> tester;
664 
665     tester::apply("mp-s-01",
666                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
667                   "SEGMENT(2 0,0 2)",
668                   ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps),
669                   strategy_ps, true, false, false);
670     tester::apply("mp-s-02",
671                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
672                   "SEGMENT(0 -3,1 -10)",
673                   pp_distance("POINT(0 0)", "POINT(0 -3)", strategy_pp),
674                   strategy_ps, true, false, false);
675     tester::apply("mp-s-03",
676                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
677                   "SEGMENT(1 1,2 2)",
678                   0,
679                   strategy_ps, true, false, false);
680     tester::apply("mp-s-04",
681                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
682                   "SEGMENT(3 3,4 4)",
683                   pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp),
684                   strategy_ps, true, false, false);
685     tester::apply("mp-s-05",
686                   "MULTIPOINT(0 0,1 0,0 1,1 1)",
687                   "SEGMENT(0.5 -3,1 -10)",
688                   pp_distance("POINT(1 0)", "POINT(0.5 -3)", strategy_pp),
689                   strategy_ps, true, false, false);
690 }
691 
692 //===========================================================================
693 //===========================================================================
694 //===========================================================================
695 
696 template <typename Strategy_pp, typename Strategy_ps>
test_all_pl_l(Strategy_pp pp_strategy,Strategy_ps ps_strategy,bool WGS84=true)697 void test_all_pl_l(Strategy_pp pp_strategy, Strategy_ps ps_strategy,
698                    bool WGS84 = true)
699 {
700     test_distance_point_segment(pp_strategy, ps_strategy, WGS84);
701     test_distance_point_linestring(pp_strategy, ps_strategy);
702     test_distance_point_multilinestring(pp_strategy, ps_strategy);
703     test_distance_linestring_multipoint(pp_strategy, ps_strategy);
704     test_distance_multipoint_multilinestring(pp_strategy, ps_strategy);
705     test_distance_multipoint_segment(pp_strategy, ps_strategy);
706 
707     test_more_empty_input_pointlike_linear<point_type>(ps_strategy);
708 }
709 
BOOST_AUTO_TEST_CASE(test_all_pointlike_linear)710 BOOST_AUTO_TEST_CASE( test_all_pointlike_linear )
711 {
712     test_all_pl_l(vincenty_pp(), vincenty_ps_bisection());
713     test_all_pl_l(vincenty_pp(), vincenty_ps());
714     test_all_pl_l(thomas_pp(), thomas_ps());
715     test_all_pl_l(andoyer_pp(), andoyer_ps());
716 
717     // test with different spheroid
718     stype spheroid(6372000, 6370000);
719     test_all_pl_l(andoyer_pp(spheroid), andoyer_ps(spheroid), false);
720 
721     test_distance_point_segment_no_thomas(vincenty_pp(), vincenty_ps());
722     //test_distance_point_segment_no_thomas(thomas_pp(), thomas_ps());
723     test_distance_point_segment_no_thomas(andoyer_pp(), andoyer_ps());
724 
725     test_distance_point_segment_rad_mix(vincenty_pp(), vincenty_ps());
726     test_distance_point_segment_rad_mix(thomas_pp(), thomas_ps());
727     test_distance_point_segment_rad_mix(andoyer_pp(), andoyer_ps());
728 }
729