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