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.
10 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
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>
29 #include <boost/geometry/algorithms/comparable_distance.hpp>
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>
37 void test_distance_result()
39 typedef typename
bg::default_distance_result
<P
, P
>::type distance_type
;
41 P p1
= bg::make
<P
>(0, 0);
42 P p2
= bg::make
<P
>(3, 0);
43 P p3
= bg::make
<P
>(0, 4);
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
);
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);
56 void test_distance_point()
66 typename
bg::coordinate_type
<P
>::type d
= bg::comparable_distance(p1
, p2
);
67 BOOST_CHECK_CLOSE(d
, 2.0, 0.001);
71 void test_distance_segment()
73 typedef typename
bg::coordinate_type
<P
>::type coordinate_type
;
75 P s1
= bg::make
<P
>(2, 2);
76 P s2
= bg::make
<P
>(3, 3);
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);
85 bg::model::referring_segment
<P
const> const seg(s1
, s2
);
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);
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);
99 void test_distance_linestring()
101 bg::model::linestring
<P
> points
;
102 points
.push_back(bg::make
<P
>(1, 1));
103 points
.push_back(bg::make
<P
>(3, 3));
105 P p
= bg::make
<P
>(2, 1);
107 typename
bg::coordinate_type
<P
>::type d
= bg::comparable_distance(p
, points
);
108 BOOST_CHECK_CLOSE(d
, 0.5, 0.001);
110 p
= bg::make
<P
>(5, 5);
111 d
= bg::comparable_distance(p
, points
);
112 BOOST_CHECK_CLOSE(d
, 8.0, 0.001);
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));
120 p
= bg::make
<P
>(5, 5);
122 d
= bg::comparable_distance(p
, line
);
123 BOOST_CHECK_CLOSE(d
, 8.0, 0.001);
126 d
= bg::comparable_distance(line
, p
);
127 BOOST_CHECK_CLOSE(d
, 8.0, 0.001);
130 template <typename P
>
133 test_distance_result
<P
>();
134 test_distance_point
<P
>();
135 test_distance_segment
<P
>();
136 test_distance_linestring
<P
>();
139 template <typename T
>
140 void test_double_result_from_integer()
142 typedef bg::model::point
<T
, 2, bg::cs::cartesian
> point_type
;
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
);
151 double normal_distance
= bg::distance(point
, linestring
);
152 double comparable_distance
= bg::comparable_distance(point
, linestring
);
154 BOOST_CHECK_CLOSE(normal_distance
, std::sqrt(0.5), 0.001);
155 BOOST_CHECK_CLOSE(comparable_distance
, 0.5, 0.001);
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
);
161 normal_distance
= bg::distance(point
, polygon
);
162 comparable_distance
= bg::comparable_distance(point
, polygon
);
164 BOOST_CHECK_CLOSE(normal_distance
, std::sqrt(0.5), 0.001);
165 BOOST_CHECK_CLOSE(comparable_distance
, 0.5, 0.001);
168 template <typename T
>
169 struct test_variant_different_default_strategy
171 static inline void apply()
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
;
179 bg::read_wkt("POINT(1 3)", point
);
182 bg::read_wkt("LINESTRING(1 1,4 4)", seg
);
185 bg::read_wkt("BOX(-1 -1,0 0)", box
);
192 typename
bg::comparable_distance_result
194 variant_type
, variant_type
, bg::default_strategy
196 typename
bg::comparable_distance_result
198 point_type
, point_type
, bg::default_strategy
206 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
207 bg::comparable_distance(point
, point
),
209 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, point
),
210 bg::comparable_distance(point
, point
),
212 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
213 bg::comparable_distance(point
, point
),
217 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
218 bg::comparable_distance(point
, seg
),
220 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, seg
),
221 bg::comparable_distance(point
, seg
),
223 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
224 bg::comparable_distance(point
, seg
), 0.0001);
227 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
228 bg::comparable_distance(point
, box
),
230 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, box
),
231 bg::comparable_distance(point
, box
),
233 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
234 bg::comparable_distance(point
, box
), 0.0001);
238 template <typename T
, typename ExpectedResultType
= double>
239 struct test_variant_same_default_strategy
241 static inline void apply()
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
248 point_type
, segment_type
, linestring_type
252 bg::read_wkt("POINT(1 3)", point
);
255 bg::read_wkt("LINESTRING(1 1,4 4)", seg
);
257 linestring_type linestring
;
258 bg::read_wkt("LINESTRING(-1 -1,-1 0,0 0,0 -1,-1 -1)", linestring
);
265 typename
bg::comparable_distance_result
267 variant_type
, variant_type
, bg::default_strategy
276 typename
bg::comparable_distance_result
278 point_type
, point_type
, bg::default_strategy
287 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
288 bg::comparable_distance(point
, point
),
290 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, point
),
291 bg::comparable_distance(point
, point
),
293 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
294 bg::comparable_distance(point
, point
),
298 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
299 bg::comparable_distance(point
, seg
),
301 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, seg
),
302 bg::comparable_distance(point
, seg
),
304 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
305 bg::comparable_distance(point
, seg
),
309 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
),
310 bg::comparable_distance(point
, linestring
),
312 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, linestring
),
313 bg::comparable_distance(point
, linestring
),
315 BOOST_CHECK_CLOSE(bg::comparable_distance(point
, v2
),
316 bg::comparable_distance(point
, linestring
),
321 template <typename T
, typename ExpectedResultType
= T
>
322 struct test_variant_with_strategy
324 static inline void apply()
326 typedef bg::strategy::distance::projected_point
<T
> strategy_type
;
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
334 > multi_linestring_type
;
335 typedef boost::variant
337 segment_type
, linestring_type
, multi_linestring_type
341 bg::read_wkt("LINESTRING(1 1,4 4)", seg
);
344 bg::read_wkt("LINESTRING(-1 -1,-1 0,0 0,0 -1,-1 -1)", ls
);
346 multi_linestring_type mls
;
347 bg::read_wkt("MULTILINESTRING((10 0,20 0),(30 0,40 0))", mls
);
351 strategy_type strategy
;
356 typename
bg::comparable_distance_result
358 variant_type
, variant_type
, strategy_type
367 typename
bg::comparable_distance_result
369 segment_type
, linestring_type
, strategy_type
378 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
, strategy
),
379 bg::comparable_distance(seg
, seg
, strategy
),
381 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, seg
, strategy
),
382 bg::comparable_distance(seg
, seg
, strategy
),
384 BOOST_CHECK_CLOSE(bg::comparable_distance(seg
, v2
, strategy
),
385 bg::comparable_distance(seg
, seg
, strategy
),
389 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
, strategy
),
390 bg::comparable_distance(seg
, ls
, strategy
),
392 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, ls
, strategy
),
393 bg::comparable_distance(seg
, ls
, strategy
),
395 BOOST_CHECK_CLOSE(bg::comparable_distance(seg
, v2
, strategy
),
396 bg::comparable_distance(seg
, ls
, strategy
),
400 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
, strategy
),
401 bg::comparable_distance(seg
, mls
, strategy
),
403 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, mls
, strategy
),
404 bg::comparable_distance(seg
, mls
, strategy
),
406 BOOST_CHECK_CLOSE(bg::comparable_distance(seg
, v2
, strategy
),
407 bg::comparable_distance(seg
, mls
, strategy
),
411 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, v2
, strategy
),
412 bg::comparable_distance(ls
, mls
, strategy
),
414 BOOST_CHECK_CLOSE(bg::comparable_distance(v1
, mls
, strategy
),
415 bg::comparable_distance(ls
, mls
, strategy
),
417 BOOST_CHECK_CLOSE(bg::comparable_distance(ls
, v2
, strategy
),
418 bg::comparable_distance(ls
, mls
, strategy
),
423 template <typename T
, bool IsIntergral
= boost::is_integral
<T
>::value
>
426 template <typename ExpectedResult
>
427 static inline void apply(T
const& value
,
428 ExpectedResult
const& expected_value
)
430 BOOST_CHECK_EQUAL(value
, expected_value
);
434 template <typename T
>
435 struct check_result
<T
, false>
437 template <typename ExpectedResult
>
438 static inline void apply(T
const& value
,
439 ExpectedResult
const& expected_value
)
441 BOOST_CHECK_CLOSE(value
, expected_value
, 0.0001);
445 template <typename T
>
446 struct test_variant_boxes
448 static inline void apply()
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
;
455 bg::read_wkt("BOX(-1 -1,0 0)", box1
);
456 bg::read_wkt("BOX(1 1,2 2)", box2
);
458 variant_type v1
= box1
, v2
= box2
;
460 typedef typename
boost::mpl::if_c
462 boost::is_float
<T
>::value
,
464 typename
bg::util::detail::default_integral::type
465 >::type expected_result_type
;
470 typename
bg::comparable_distance_result
472 variant_type
, variant_type
, bg::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
));
489 int test_main(int, char* [])
491 test_double_result_from_integer
<int>();
492 test_double_result_from_integer
<boost::long_long_type
>();
494 test_all
<bg::model::d2::point_xy
<float> >();
495 test_all
<bg::model::d2::point_xy
<double> >();
498 test_all
<bg::model::d2::point_xy
<ttmath_big
> >();
501 // test variant support
502 test_variant_different_default_strategy
<double>::apply();
504 test_variant_same_default_strategy
<double>::apply();
505 test_variant_same_default_strategy
<int>::apply();
506 test_variant_same_default_strategy
<long>::apply();
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();
513 test_variant_with_strategy
<ttmath_big
>::apply();
516 test_variant_boxes
<double>::apply();
517 test_variant_boxes
<int>::apply();
518 test_variant_boxes
<long>::apply();