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