1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
9 // This file was modified by Oracle on 2014, 2017.
10 // Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
13 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
15 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
16 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
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>
30 #include <boost/geometry/algorithms/comparable_distance.hpp>
31 #include <boost/geometry/algorithms/make.hpp>
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>
39 void test_distance_result()
41 typedef typename
bg::default_distance_result
<P
, P
>::type distance_type
;
43 P p1
= bg::make
<P
>(0, 0);
44 P p2
= bg::make
<P
>(3, 0);
45 P p3
= bg::make
<P
>(0, 4);
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
);
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);
58 void test_distance_point()
68 typename
bg::coordinate_type
<P
>::type d
= bg::comparable_distance(p1
, p2
);
69 BOOST_CHECK_CLOSE(d
, 2.0, 0.001);
73 void test_distance_segment()
75 typedef typename
bg::coordinate_type
<P
>::type coordinate_type
;
77 P s1
= bg::make
<P
>(2, 2);
78 P s2
= bg::make
<P
>(3, 3);
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);
87 bg::model::referring_segment
<P
const> const seg(s1
, s2
);
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);
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);
100 template <typename P
>
101 void test_distance_linestring()
103 bg::model::linestring
<P
> points
;
104 points
.push_back(bg::make
<P
>(1, 1));
105 points
.push_back(bg::make
<P
>(3, 3));
107 P p
= bg::make
<P
>(2, 1);
109 typename
bg::coordinate_type
<P
>::type d
= bg::comparable_distance(p
, points
);
110 BOOST_CHECK_CLOSE(d
, 0.5, 0.001);
112 p
= bg::make
<P
>(5, 5);
113 d
= bg::comparable_distance(p
, points
);
114 BOOST_CHECK_CLOSE(d
, 8.0, 0.001);
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));
122 p
= bg::make
<P
>(5, 5);
124 d
= bg::comparable_distance(p
, line
);
125 BOOST_CHECK_CLOSE(d
, 8.0, 0.001);
128 d
= bg::comparable_distance(line
, p
);
129 BOOST_CHECK_CLOSE(d
, 8.0, 0.001);
132 template <typename P
>
135 test_distance_result
<P
>();
136 test_distance_point
<P
>();
137 test_distance_segment
<P
>();
138 test_distance_linestring
<P
>();
141 template <typename T
>
142 void test_double_result_from_integer()
144 typedef bg::model::point
<T
, 2, bg::cs::cartesian
> point_type
;
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
);
153 double normal_distance
= bg::distance(point
, linestring
);
154 double comparable_distance
= bg::comparable_distance(point
, linestring
);
156 BOOST_CHECK_CLOSE(normal_distance
, std::sqrt(0.5), 0.001);
157 BOOST_CHECK_CLOSE(comparable_distance
, 0.5, 0.001);
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
);
163 normal_distance
= bg::distance(point
, polygon
);
164 comparable_distance
= bg::comparable_distance(point
, polygon
);
166 BOOST_CHECK_CLOSE(normal_distance
, std::sqrt(0.5), 0.001);
167 BOOST_CHECK_CLOSE(comparable_distance
, 0.5, 0.001);
170 template <typename T
>
171 struct test_variant_different_default_strategy
173 static inline void apply()
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
;
181 bg::read_wkt("POINT(1 3)", point
);
184 bg::read_wkt("LINESTRING(1 1,4 4)", seg
);
187 bg::read_wkt("BOX(-1 -1,0 0)", box
);
194 typename
bg::comparable_distance_result
196 variant_type
, variant_type
, bg::default_strategy
198 typename
bg::comparable_distance_result
200 point_type
, point_type
, bg::default_strategy
208 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
209 bg::comparable_distance(point
, point
),
211 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, point
),
212 bg::comparable_distance(point
, point
),
214 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
215 bg::comparable_distance(point
, point
),
219 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
220 bg::comparable_distance(point
, seg
),
222 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, seg
),
223 bg::comparable_distance(point
, seg
),
225 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
226 bg::comparable_distance(point
, seg
), 0.0001);
229 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
230 bg::comparable_distance(point
, box
),
232 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, box
),
233 bg::comparable_distance(point
, box
),
235 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
236 bg::comparable_distance(point
, box
), 0.0001);
240 template <typename T
, typename ExpectedResultType
= double>
241 struct test_variant_same_default_strategy
243 static inline void apply()
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
250 point_type
, segment_type
, linestring_type
254 bg::read_wkt("POINT(1 3)", point
);
257 bg::read_wkt("LINESTRING(1 1,4 4)", seg
);
259 linestring_type linestring
;
260 bg::read_wkt("LINESTRING(-1 -1,-1 0,0 0,0 -1,-1 -1)", linestring
);
267 typename
bg::comparable_distance_result
269 variant_type
, variant_type
, bg::default_strategy
278 typename
bg::comparable_distance_result
280 point_type
, point_type
, bg::default_strategy
289 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
290 bg::comparable_distance(point
, point
),
292 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, point
),
293 bg::comparable_distance(point
, point
),
295 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
296 bg::comparable_distance(point
, point
),
300 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
301 bg::comparable_distance(point
, seg
),
303 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, seg
),
304 bg::comparable_distance(point
, seg
),
306 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
307 bg::comparable_distance(point
, seg
),
311 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
312 bg::comparable_distance(point
, linestring
),
314 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, linestring
),
315 bg::comparable_distance(point
, linestring
),
317 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
318 bg::comparable_distance(point
, linestring
),
323 template <typename T
, typename ExpectedResultType
= T
>
324 struct test_variant_with_strategy
326 static inline void apply()
328 typedef bg::strategy::distance::projected_point
<T
> strategy_type
;
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
336 > multi_linestring_type
;
337 typedef boost::variant
339 segment_type
, linestring_type
, multi_linestring_type
343 bg::read_wkt("LINESTRING(1 1,4 4)", seg
);
346 bg::read_wkt("LINESTRING(-1 -1,-1 0,0 0,0 -1,-1 -1)", ls
);
348 multi_linestring_type mls
;
349 bg::read_wkt("MULTILINESTRING((10 0,20 0),(30 0,40 0))", mls
);
353 strategy_type strategy
;
358 typename
bg::comparable_distance_result
360 variant_type
, variant_type
, strategy_type
369 typename
bg::comparable_distance_result
371 segment_type
, linestring_type
, strategy_type
380 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
, strategy
),
381 bg::comparable_distance(seg
, seg
, strategy
),
383 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, seg
, strategy
),
384 bg::comparable_distance(seg
, seg
, strategy
),
386 BOOST_CHECK_CLOSE(bg::comparable_distance(seg
, v2
, strategy
),
387 bg::comparable_distance(seg
, seg
, strategy
),
391 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
, strategy
),
392 bg::comparable_distance(seg
, ls
, strategy
),
394 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, ls
, strategy
),
395 bg::comparable_distance(seg
, ls
, strategy
),
397 BOOST_CHECK_CLOSE(bg::comparable_distance(seg
, v2
, strategy
),
398 bg::comparable_distance(seg
, ls
, strategy
),
402 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
, strategy
),
403 bg::comparable_distance(seg
, mls
, strategy
),
405 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, mls
, strategy
),
406 bg::comparable_distance(seg
, mls
, strategy
),
408 BOOST_CHECK_CLOSE(bg::comparable_distance(seg
, v2
, strategy
),
409 bg::comparable_distance(seg
, mls
, strategy
),
413 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
, strategy
),
414 bg::comparable_distance(ls
, mls
, strategy
),
416 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, mls
, strategy
),
417 bg::comparable_distance(ls
, mls
, strategy
),
419 BOOST_CHECK_CLOSE(bg::comparable_distance(ls
, v2
, strategy
),
420 bg::comparable_distance(ls
, mls
, strategy
),
425 template <typename T
, bool IsIntergral
= boost::is_integral
<T
>::value
>
428 template <typename ExpectedResult
>
429 static inline void apply(T
const& value
,
430 ExpectedResult
const& expected_value
)
432 BOOST_CHECK_EQUAL(value
, expected_value
);
436 template <typename T
>
437 struct check_result
<T
, false>
439 template <typename ExpectedResult
>
440 static inline void apply(T
const& value
,
441 ExpectedResult
const& expected_value
)
443 BOOST_CHECK_CLOSE(value
, expected_value
, 0.0001);
447 template <typename T
>
448 struct test_variant_boxes
450 static inline void apply()
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
;
457 bg::read_wkt("BOX(-1 -1,0 0)", box1
);
458 bg::read_wkt("BOX(1 1,2 2)", box2
);
460 variant_type v1
= box1
, v2
= box2
;
462 typedef typename
boost::mpl::if_c
464 boost::is_float
<T
>::value
,
466 typename
bg::util::detail::default_integral::type
467 >::type expected_result_type
;
472 typename
bg::comparable_distance_result
474 variant_type
, variant_type
, bg::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
));
491 int test_main(int, char* [])
493 test_double_result_from_integer
<int>();
494 test_double_result_from_integer
<boost::long_long_type
>();
496 test_all
<bg::model::d2::point_xy
<float> >();
497 test_all
<bg::model::d2::point_xy
<double> >();
500 test_all
<bg::model::d2::point_xy
<ttmath_big
> >();
503 // test variant support
504 test_variant_different_default_strategy
<double>::apply();
506 test_variant_same_default_strategy
<double>::apply();
507 test_variant_same_default_strategy
<int>::apply();
508 test_variant_same_default_strategy
<long>::apply();
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();
515 test_variant_with_strategy
<ttmath_big
>::apply();
518 test_variant_boxes
<double>::apply();
519 test_variant_boxes
<int>::apply();
520 test_variant_boxes
<long>::apply();