]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/comparable_distance.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / comparable_distance.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
6 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
7 // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
8
9 // This file was modified by Oracle on 2014, 2017.
10 // Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
11
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
13 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
14
15 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
16 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
17
18 // Use, modification and distribution is subject to the Boost Software License,
19 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
20 // http://www.boost.org/LICENSE_1_0.txt)
21
22
23 #include <sstream>
24
25 #include <boost/mpl/if.hpp>
26 #include <boost/type_traits/is_integral.hpp>
27 #include <boost/type_traits/is_same.hpp>
28 #include <geometry_test_common.hpp>
29
30 #include <boost/geometry/algorithms/comparable_distance.hpp>
31 #include <boost/geometry/algorithms/make.hpp>
32
33 #include <boost/geometry/geometries/geometries.hpp>
34 #include <boost/geometry/geometries/point_xy.hpp>
35 #include <boost/geometry/io/wkt/read.hpp>
36 #include <boost/geometry/strategies/strategies.hpp>
37
38 template <typename P>
39 void test_distance_result()
40 {
41 typedef typename bg::default_distance_result<P, P>::type distance_type;
42
43 P p1 = bg::make<P>(0, 0);
44 P p2 = bg::make<P>(3, 0);
45 P p3 = bg::make<P>(0, 4);
46
47 distance_type dr12 = bg::comparable_distance(p1, p2);
48 distance_type dr13 = bg::comparable_distance(p1, p3);
49 distance_type dr23 = bg::comparable_distance(p2, p3);
50
51 BOOST_CHECK_CLOSE(dr12, 9.000, 0.001);
52 BOOST_CHECK_CLOSE(dr13, 16.000, 0.001);
53 BOOST_CHECK_CLOSE(dr23, 25.000, 0.001);
54
55 }
56
57 template <typename P>
58 void test_distance_point()
59 {
60 P p1;
61 bg::set<0>(p1, 1);
62 bg::set<1>(p1, 1);
63
64 P p2;
65 bg::set<0>(p2, 2);
66 bg::set<1>(p2, 2);
67
68 typename bg::coordinate_type<P>::type d = bg::comparable_distance(p1, p2);
69 BOOST_CHECK_CLOSE(d, 2.0, 0.001);
70 }
71
72 template <typename P>
73 void test_distance_segment()
74 {
75 typedef typename bg::coordinate_type<P>::type coordinate_type;
76
77 P s1 = bg::make<P>(2, 2);
78 P s2 = bg::make<P>(3, 3);
79
80 // Check points left, right, projected-left, projected-right, on segment
81 P p1 = bg::make<P>(0, 0);
82 P p2 = bg::make<P>(4, 4);
83 P p3 = bg::make<P>(2.4, 2.6);
84 P p4 = bg::make<P>(2.6, 2.4);
85 P p5 = bg::make<P>(2.5, 2.5);
86
87 bg::model::referring_segment<P const> const seg(s1, s2);
88
89 coordinate_type d1 = bg::comparable_distance(p1, seg); BOOST_CHECK_CLOSE(d1, 8.0, 0.001);
90 coordinate_type d2 = bg::comparable_distance(p2, seg); BOOST_CHECK_CLOSE(d2, 2.0, 0.001);
91 coordinate_type d3 = bg::comparable_distance(p3, seg); BOOST_CHECK_CLOSE(d3, 0.02, 0.001);
92 coordinate_type d4 = bg::comparable_distance(p4, seg); BOOST_CHECK_CLOSE(d4, 0.02, 0.001);
93 coordinate_type d5 = bg::comparable_distance(p5, seg); BOOST_CHECK_CLOSE(d5, 0.0, 0.001);
94
95 // Reverse case
96 coordinate_type dr1 = bg::comparable_distance(seg, p1); BOOST_CHECK_CLOSE(dr1, d1, 0.001);
97 coordinate_type dr2 = bg::comparable_distance(seg, p2); BOOST_CHECK_CLOSE(dr2, d2, 0.001);
98 }
99
100 template <typename P>
101 void test_distance_linestring()
102 {
103 bg::model::linestring<P> points;
104 points.push_back(bg::make<P>(1, 1));
105 points.push_back(bg::make<P>(3, 3));
106
107 P p = bg::make<P>(2, 1);
108
109 typename bg::coordinate_type<P>::type d = bg::comparable_distance(p, points);
110 BOOST_CHECK_CLOSE(d, 0.5, 0.001);
111
112 p = bg::make<P>(5, 5);
113 d = bg::comparable_distance(p, points);
114 BOOST_CHECK_CLOSE(d, 8.0, 0.001);
115
116
117 bg::model::linestring<P> line;
118 line.push_back(bg::make<P>(1,1));
119 line.push_back(bg::make<P>(2,2));
120 line.push_back(bg::make<P>(3,3));
121
122 p = bg::make<P>(5, 5);
123
124 d = bg::comparable_distance(p, line);
125 BOOST_CHECK_CLOSE(d, 8.0, 0.001);
126
127 // Reverse case
128 d = bg::comparable_distance(line, p);
129 BOOST_CHECK_CLOSE(d, 8.0, 0.001);
130 }
131
132 template <typename P>
133 void test_all()
134 {
135 test_distance_result<P>();
136 test_distance_point<P>();
137 test_distance_segment<P>();
138 test_distance_linestring<P>();
139 }
140
141 template <typename T>
142 void test_double_result_from_integer()
143 {
144 typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
145
146 point_type point;
147
148 // Check linestring
149 bg::model::linestring<point_type> linestring;
150 bg::read_wkt("POINT(2 2)", point);
151 bg::read_wkt("LINESTRING(4 1,1 4)", linestring);
152
153 double normal_distance = bg::distance(point, linestring);
154 double comparable_distance = bg::comparable_distance(point, linestring);
155
156 BOOST_CHECK_CLOSE(normal_distance, std::sqrt(0.5), 0.001);
157 BOOST_CHECK_CLOSE(comparable_distance, 0.5, 0.001);
158
159 // Check polygon
160 bg::model::polygon<point_type> polygon;
161 bg::read_wkt("POLYGON((0 0,1 9,8 1,0 0),(1 1,4 1,1 4,1 1))", polygon);
162
163 normal_distance = bg::distance(point, polygon);
164 comparable_distance = bg::comparable_distance(point, polygon);
165
166 BOOST_CHECK_CLOSE(normal_distance, std::sqrt(0.5), 0.001);
167 BOOST_CHECK_CLOSE(comparable_distance, 0.5, 0.001);
168 }
169
170 template <typename T>
171 struct test_variant_different_default_strategy
172 {
173 static inline void apply()
174 {
175 typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
176 typedef bg::model::segment<point_type> segment_type;
177 typedef bg::model::box<point_type> box_type;
178 typedef boost::variant<point_type, segment_type, box_type> variant_type;
179
180 point_type point;
181 bg::read_wkt("POINT(1 3)", point);
182
183 segment_type seg;
184 bg::read_wkt("LINESTRING(1 1,4 4)", seg);
185
186 box_type box;
187 bg::read_wkt("BOX(-1 -1,0 0)", box);
188
189 variant_type v1, v2;
190
191 BOOST_MPL_ASSERT((
192 boost::is_same
193 <
194 typename bg::comparable_distance_result
195 <
196 variant_type, variant_type, bg::default_strategy
197 >::type,
198 typename bg::comparable_distance_result
199 <
200 point_type, point_type, bg::default_strategy
201 >::type
202 >
203 ));
204
205 // Default strategy
206 v1 = point;
207 v2 = point;
208 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2),
209 bg::comparable_distance(point, point),
210 0.0001);
211 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, point),
212 bg::comparable_distance(point, point),
213 0.0001);
214 BOOST_CHECK_CLOSE(bg::comparable_distance(point, v2),
215 bg::comparable_distance(point, point),
216 0.0001);
217 v1 = point;
218 v2 = seg;
219 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2),
220 bg::comparable_distance(point, seg),
221 0.0001);
222 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, seg),
223 bg::comparable_distance(point, seg),
224 0.0001);
225 BOOST_CHECK_CLOSE(bg::comparable_distance(point, v2),
226 bg::comparable_distance(point, seg), 0.0001);
227 v1 = point;
228 v2 = box;
229 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2),
230 bg::comparable_distance(point, box),
231 0.0001);
232 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, box),
233 bg::comparable_distance(point, box),
234 0.0001);
235 BOOST_CHECK_CLOSE(bg::comparable_distance(point, v2),
236 bg::comparable_distance(point, box), 0.0001);
237 }
238 };
239
240 template <typename T, typename ExpectedResultType = double>
241 struct test_variant_same_default_strategy
242 {
243 static inline void apply()
244 {
245 typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
246 typedef bg::model::segment<point_type> segment_type;
247 typedef bg::model::linestring<point_type> linestring_type;
248 typedef boost::variant
249 <
250 point_type, segment_type, linestring_type
251 > variant_type;
252
253 point_type point;
254 bg::read_wkt("POINT(1 3)", point);
255
256 segment_type seg;
257 bg::read_wkt("LINESTRING(1 1,4 4)", seg);
258
259 linestring_type linestring;
260 bg::read_wkt("LINESTRING(-1 -1,-1 0,0 0,0 -1,-1 -1)", linestring);
261
262 variant_type v1, v2;
263
264 BOOST_MPL_ASSERT((
265 boost::is_same
266 <
267 typename bg::comparable_distance_result
268 <
269 variant_type, variant_type, bg::default_strategy
270 >::type,
271 ExpectedResultType
272 >
273 ));
274
275 BOOST_MPL_ASSERT((
276 boost::is_same
277 <
278 typename bg::comparable_distance_result
279 <
280 point_type, point_type, bg::default_strategy
281 >::type,
282 ExpectedResultType
283 >
284 ));
285
286 // Default strategy
287 v1 = point;
288 v2 = point;
289 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2),
290 bg::comparable_distance(point, point),
291 0.0001);
292 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, point),
293 bg::comparable_distance(point, point),
294 0.0001);
295 BOOST_CHECK_CLOSE(bg::comparable_distance(point, v2),
296 bg::comparable_distance(point, point),
297 0.0001);
298 v1 = point;
299 v2 = seg;
300 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2),
301 bg::comparable_distance(point, seg),
302 0.0001);
303 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, seg),
304 bg::comparable_distance(point, seg),
305 0.0001);
306 BOOST_CHECK_CLOSE(bg::comparable_distance(point, v2),
307 bg::comparable_distance(point, seg),
308 0.0001);
309 v1 = point;
310 v2 = linestring;
311 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2),
312 bg::comparable_distance(point, linestring),
313 0.0001);
314 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, linestring),
315 bg::comparable_distance(point, linestring),
316 0.0001);
317 BOOST_CHECK_CLOSE(bg::comparable_distance(point, v2),
318 bg::comparable_distance(point, linestring),
319 0.0001);
320 }
321 };
322
323 template <typename T, typename ExpectedResultType = T>
324 struct test_variant_with_strategy
325 {
326 static inline void apply()
327 {
328 typedef bg::strategy::distance::projected_point<T> strategy_type;
329
330 typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
331 typedef bg::model::segment<point_type> segment_type;
332 typedef bg::model::linestring<point_type> linestring_type;
333 typedef bg::model::multi_linestring
334 <
335 linestring_type
336 > multi_linestring_type;
337 typedef boost::variant
338 <
339 segment_type, linestring_type, multi_linestring_type
340 > variant_type;
341
342 segment_type seg;
343 bg::read_wkt("LINESTRING(1 1,4 4)", seg);
344
345 linestring_type ls;
346 bg::read_wkt("LINESTRING(-1 -1,-1 0,0 0,0 -1,-1 -1)", ls);
347
348 multi_linestring_type mls;
349 bg::read_wkt("MULTILINESTRING((10 0,20 0),(30 0,40 0))", mls);
350
351 variant_type v1, v2;
352
353 strategy_type strategy;
354
355 BOOST_MPL_ASSERT((
356 boost::is_same
357 <
358 typename bg::comparable_distance_result
359 <
360 variant_type, variant_type, strategy_type
361 >::type,
362 ExpectedResultType
363 >
364 ));
365
366 BOOST_MPL_ASSERT((
367 boost::is_same
368 <
369 typename bg::comparable_distance_result
370 <
371 segment_type, linestring_type, strategy_type
372 >::type,
373 ExpectedResultType
374 >
375 ));
376
377 // Passed strategy
378 v1 = seg;
379 v2 = seg;
380 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2, strategy),
381 bg::comparable_distance(seg, seg, strategy),
382 0.0001);
383 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, seg, strategy),
384 bg::comparable_distance(seg, seg, strategy),
385 0.0001);
386 BOOST_CHECK_CLOSE(bg::comparable_distance(seg, v2, strategy),
387 bg::comparable_distance(seg, seg, strategy),
388 0.0001);
389 v1 = seg;
390 v2 = ls;
391 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2, strategy),
392 bg::comparable_distance(seg, ls, strategy),
393 0.0001);
394 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, ls, strategy),
395 bg::comparable_distance(seg, ls, strategy),
396 0.0001);
397 BOOST_CHECK_CLOSE(bg::comparable_distance(seg, v2, strategy),
398 bg::comparable_distance(seg, ls, strategy),
399 0.0001);
400 v1 = seg;
401 v2 = mls;
402 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2, strategy),
403 bg::comparable_distance(seg, mls, strategy),
404 0.0001);
405 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, mls, strategy),
406 bg::comparable_distance(seg, mls, strategy),
407 0.0001);
408 BOOST_CHECK_CLOSE(bg::comparable_distance(seg, v2, strategy),
409 bg::comparable_distance(seg, mls, strategy),
410 0.0001);
411 v1 = ls;
412 v2 = mls;
413 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, v2, strategy),
414 bg::comparable_distance(ls, mls, strategy),
415 0.0001);
416 BOOST_CHECK_CLOSE(bg::comparable_distance(v1, mls, strategy),
417 bg::comparable_distance(ls, mls, strategy),
418 0.0001);
419 BOOST_CHECK_CLOSE(bg::comparable_distance(ls, v2, strategy),
420 bg::comparable_distance(ls, mls, strategy),
421 0.0001);
422 }
423 };
424
425 template <typename T, bool IsIntergral = boost::is_integral<T>::value>
426 struct check_result
427 {
428 template <typename ExpectedResult>
429 static inline void apply(T const& value,
430 ExpectedResult const& expected_value)
431 {
432 BOOST_CHECK_EQUAL(value, expected_value);
433 }
434 };
435
436 template <typename T>
437 struct check_result<T, false>
438 {
439 template <typename ExpectedResult>
440 static inline void apply(T const& value,
441 ExpectedResult const& expected_value)
442 {
443 BOOST_CHECK_CLOSE(value, expected_value, 0.0001);
444 }
445 };
446
447 template <typename T>
448 struct test_variant_boxes
449 {
450 static inline void apply()
451 {
452 typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
453 typedef bg::model::box<point_type> box_type;
454 typedef boost::variant<box_type> variant_type;
455
456 box_type box1, box2;
457 bg::read_wkt("BOX(-1 -1,0 0)", box1);
458 bg::read_wkt("BOX(1 1,2 2)", box2);
459
460 variant_type v1 = box1, v2 = box2;
461
462 typedef typename boost::mpl::if_c
463 <
464 boost::is_float<T>::value,
465 double,
466 typename bg::util::detail::default_integral::type
467 >::type expected_result_type;
468
469 BOOST_MPL_ASSERT((
470 boost::is_same
471 <
472 typename bg::comparable_distance_result
473 <
474 variant_type, variant_type, bg::default_strategy
475 >::type,
476 expected_result_type
477 >
478 ));
479
480 // Default strategy
481 check_result<T>::apply(bg::comparable_distance(v1, v2),
482 bg::comparable_distance(box1, box2));
483 check_result<T>::apply(bg::comparable_distance(v1, box2),
484 bg::comparable_distance(box1, box2));
485 check_result<T>::apply(bg::comparable_distance(box1, v2),
486 bg::comparable_distance(box1, box2));
487 }
488 };
489
490
491 int test_main(int, char* [])
492 {
493 test_double_result_from_integer<int>();
494 test_double_result_from_integer<boost::long_long_type>();
495
496 test_all<bg::model::d2::point_xy<float> >();
497 test_all<bg::model::d2::point_xy<double> >();
498
499 #ifdef HAVE_TTMATH
500 test_all<bg::model::d2::point_xy<ttmath_big> >();
501 #endif
502
503 // test variant support
504 test_variant_different_default_strategy<double>::apply();
505
506 test_variant_same_default_strategy<double>::apply();
507 test_variant_same_default_strategy<int>::apply();
508 test_variant_same_default_strategy<long>::apply();
509
510 test_variant_with_strategy<double>::apply();
511 test_variant_with_strategy<float>::apply();
512 test_variant_with_strategy<long double>::apply();
513 test_variant_with_strategy<int, double>::apply();
514 #ifdef HAVE_TTMATH
515 test_variant_with_strategy<ttmath_big>::apply();
516 #endif
517
518 test_variant_boxes<double>::apply();
519 test_variant_boxes<int>::apply();
520 test_variant_boxes<long>::apply();
521
522 return 0;
523 }