]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/distance/test_distance_se_common.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / distance / test_distance_se_common.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2014-2015, Oracle and/or its affiliates.
5
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10
11 #ifndef BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP
12 #define BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP
13
14 #include <iostream>
15 #include <string>
16
17 #include <boost/mpl/assert.hpp>
18 #include <boost/type_traits/is_integral.hpp>
19 #include <boost/type_traits/is_same.hpp>
20
21 #include <boost/geometry/geometries/point.hpp>
22 #include <boost/geometry/geometries/point_xy.hpp>
23 #include <boost/geometry/geometries/segment.hpp>
24 #include <boost/geometry/geometries/linestring.hpp>
25 #include <boost/geometry/geometries/polygon.hpp>
26 #include <boost/geometry/geometries/ring.hpp>
27 #include <boost/geometry/geometries/box.hpp>
28 #include <boost/geometry/geometries/multi_point.hpp>
29 #include <boost/geometry/geometries/multi_linestring.hpp>
30 #include <boost/geometry/geometries/multi_polygon.hpp>
31
32 #include <boost/geometry/io/wkt/write.hpp>
33 #include <boost/geometry/io/dsv/write.hpp>
34
35 #include <boost/geometry/algorithms/num_interior_rings.hpp>
36 #include <boost/geometry/algorithms/distance.hpp>
37 #include <boost/geometry/algorithms/comparable_distance.hpp>
38
39 #include <from_wkt.hpp>
40 #include <string_from_type.hpp>
41
42 #include "distance_brute_force.hpp"
43
44 namespace bg = ::boost::geometry;
45
46 static const double earth_radius_km = 6371.0;
47 static const double earth_radius_miles = 3959.0;
48
49
50 //========================================================================
51
52
53 template <typename T>
54 struct check_equal
55 {
56 template <typename Value, typename = void>
57 struct equal_to
58 {
59 static inline void apply(Value const& x, Value const& y)
60 {
61 BOOST_CHECK(x == y);
62 }
63 };
64
65 template <typename Dummy>
66 struct equal_to<double, Dummy>
67 {
68 static inline void apply(double x, double y)
69 {
70 BOOST_CHECK_CLOSE(x, y, 0.001);
71 }
72 };
73
74 template <typename Geometry1, typename Geometry2>
75 static inline void apply(std::string const& /*case_id*/,
76 std::string const& /*subcase_id*/,
77 Geometry1 const& /*geometry1*/,
78 Geometry2 const& /*geometry2*/,
79 T const& detected,
80 T const& expected)
81 {
82 equal_to<T>::apply(expected, detected);
83 /*
84 TODO:
85 Ideally we would want the following, but it does not work well
86 approximate equality test.
87
88 BOOST_CHECK_MESSAGE(equal_to<T>::apply(expected, detected),
89 "case ID: " << case_id << "-" << subcase_id << "; "
90 << "G1: " << bg::wkt(geometry1)
91 << " - "
92 << "G2: " << bg::wkt(geometry2)
93 << " -> Detected: " << detected
94 << "; Expected: " << expected);
95 */
96 }
97 };
98
99 //========================================================================
100
101 template
102 <
103 typename Geometry1, typename Geometry2,
104 int id1 = bg::geometry_id<Geometry1>::value,
105 int id2 = bg::geometry_id<Geometry2>::value
106 >
107 struct test_distance_of_geometries
108 : public test_distance_of_geometries<Geometry1, Geometry2, 0, 0>
109 {};
110
111
112 template <typename Geometry1, typename Geometry2>
113 struct test_distance_of_geometries<Geometry1, Geometry2, 0, 0>
114 {
115 template
116 <
117 typename DistanceType,
118 typename ComparableDistanceType,
119 typename Strategy
120 >
121 static inline
122 void apply(std::string const& case_id,
123 std::string const& wkt1,
124 std::string const& wkt2,
125 DistanceType const& expected_distance,
126 ComparableDistanceType const& expected_comparable_distance,
127 Strategy const& strategy,
128 bool test_reversed = true)
129 {
130 Geometry1 geometry1 = from_wkt<Geometry1>(wkt1);
131 Geometry2 geometry2 = from_wkt<Geometry2>(wkt2);
132
133 apply(case_id, geometry1, geometry2,
134 expected_distance, expected_comparable_distance,
135 strategy, test_reversed);
136 }
137
138 template <typename DistanceType, typename Strategy>
139 static inline
140 void apply(std::string const& case_id,
141 std::string const& wkt1,
142 std::string const& wkt2,
143 DistanceType const& expected_distance,
144 Strategy const& strategy,
145 bool test_reversed = true)
146 {
147 Geometry1 geometry1 = from_wkt<Geometry1>(wkt1);
148 Geometry2 geometry2 = from_wkt<Geometry2>(wkt2);
149
150 apply(case_id, geometry1, geometry2,
151 expected_distance, expected_distance,
152 strategy, test_reversed);
153 }
154
155
156 template
157 <
158 typename DistanceType,
159 typename ComparableDistanceType,
160 typename Strategy
161 >
162 static inline
163 void apply(std::string const& case_id,
164 Geometry1 const& geometry1,
165 Geometry2 const& geometry2,
166 DistanceType const& expected_distance,
167 ComparableDistanceType const& expected_comparable_distance,
168 Strategy const& strategy,
169 bool test_reversed = true)
170 {
171 #ifdef BOOST_GEOMETRY_TEST_DEBUG
172 std::cout << "case ID: " << case_id << "; "
173 << "G1: " << bg::wkt(geometry1)
174 << " - "
175 << "G2: " << bg::wkt(geometry2)
176 << std::endl;
177 #endif
178 namespace services = bg::strategy::distance::services;
179
180 using bg::unit_test::distance_brute_force;
181
182 typedef typename bg::default_distance_result
183 <
184 Geometry1, Geometry2
185 >::type default_distance_result;
186
187 typedef typename services::return_type
188 <
189 Strategy, Geometry1, Geometry2
190 >::type distance_result_from_strategy;
191
192 static const bool same_regular = boost::is_same
193 <
194 default_distance_result,
195 distance_result_from_strategy
196 >::type::value;
197
198 BOOST_CHECK(same_regular);
199
200 typedef typename bg::default_comparable_distance_result
201 <
202 Geometry1, Geometry2
203 >::type default_comparable_distance_result;
204
205 typedef typename services::return_type
206 <
207 typename services::comparable_type<Strategy>::type,
208 Geometry1,
209 Geometry2
210 >::type comparable_distance_result_from_strategy;
211
212 static const bool same_comparable = boost::is_same
213 <
214 default_comparable_distance_result,
215 comparable_distance_result_from_strategy
216 >::type::value;
217
218 BOOST_CHECK( same_comparable );
219
220 // check distance with passed strategy
221 distance_result_from_strategy dist =
222 bg::distance(geometry1, geometry2, strategy);
223
224 check_equal
225 <
226 distance_result_from_strategy
227 >::apply(case_id, "a", geometry1, geometry2,
228 dist, expected_distance);
229
230 // check against the comparable distance computed in a
231 // brute-force manner
232 default_distance_result dist_brute_force
233 = distance_brute_force(geometry1, geometry2, strategy);
234
235 check_equal
236 <
237 default_distance_result
238 >::apply(case_id, "b", geometry1, geometry2,
239 dist_brute_force, expected_distance);
240
241 // check comparable distance with passed strategy
242 comparable_distance_result_from_strategy cdist =
243 bg::comparable_distance(geometry1, geometry2, strategy);
244
245 check_equal
246 <
247 default_comparable_distance_result
248 >::apply(case_id, "c", geometry1, geometry2,
249 cdist, expected_comparable_distance);
250
251 // check against the comparable distance computed in a
252 // brute-force manner
253 default_comparable_distance_result cdist_brute_force
254 = distance_brute_force(geometry1,
255 geometry2,
256 services::get_comparable
257 <
258 Strategy
259 >::apply(strategy));
260
261 check_equal
262 <
263 default_comparable_distance_result
264 >::apply(case_id, "d", geometry1, geometry2,
265 cdist_brute_force, expected_comparable_distance);
266
267 #ifdef BOOST_GEOMETRY_TEST_DEBUG
268 std::cout << string_from_type<typename bg::coordinate_type<Geometry1>::type>::name()
269 << string_from_type<typename bg::coordinate_type<Geometry2>::type>::name()
270 << " -> "
271 << string_from_type<default_distance_result>::name()
272 << string_from_type<default_comparable_distance_result>::name()
273 << std::endl;
274 std::cout << "strategy radius: " << strategy.radius() << std::endl;
275 std::cout << "expected distance = "
276 << expected_distance << " ; "
277 << "expected comp. distance = "
278 << expected_comparable_distance
279 << std::endl;
280 std::cout << "distance = "
281 << dist << " ; "
282 << "comp. distance = "
283 << cdist
284 << std::endl;
285
286 if ( !test_reversed )
287 {
288 std::cout << std::endl;
289 }
290 #endif
291
292 if ( test_reversed )
293 {
294 // check distance with given strategy
295 dist = bg::distance(geometry2, geometry1, strategy);
296
297 check_equal
298 <
299 default_distance_result
300 >::apply(case_id, "ra", geometry2, geometry1,
301 dist, expected_distance);
302
303 // check comparable distance with given strategy
304 cdist = bg::comparable_distance(geometry2, geometry1, strategy);
305
306 check_equal
307 <
308 default_comparable_distance_result
309 >::apply(case_id, "rc", geometry2, geometry1,
310 cdist, expected_comparable_distance);
311
312 #ifdef BOOST_GEOMETRY_TEST_DEBUG
313 std::cout << "distance[reversed args] = "
314 << dist << " ; "
315 << "comp. distance[reversed args] = "
316 << cdist
317 << std::endl;
318 std::cout << std::endl;
319 #endif
320 }
321 }
322 };
323
324
325 //========================================================================
326
327
328 template <typename Geometry1, typename Geometry2, typename Strategy>
329 void test_empty_input(Geometry1 const& geometry1,
330 Geometry2 const& geometry2,
331 Strategy const& strategy)
332 {
333 try
334 {
335 bg::distance(geometry1, geometry2);
336 }
337 catch(bg::empty_input_exception const& )
338 {
339 return;
340 }
341 BOOST_CHECK_MESSAGE(false,
342 "A empty_input_exception should have been thrown");
343
344 try
345 {
346 bg::distance(geometry2, geometry1);
347 }
348 catch(bg::empty_input_exception const& )
349 {
350 return;
351 }
352 BOOST_CHECK_MESSAGE(false,
353 "A empty_input_exception should have been thrown");
354
355 try
356 {
357 bg::distance(geometry1, geometry2, strategy);
358 }
359 catch(bg::empty_input_exception const& )
360 {
361 return;
362 }
363 BOOST_CHECK_MESSAGE(false,
364 "A empty_input_exception should have been thrown");
365
366 try
367 {
368 bg::distance(geometry2, geometry1, strategy);
369 }
370 catch(bg::empty_input_exception const& )
371 {
372 return;
373 }
374 BOOST_CHECK_MESSAGE(false,
375 "A empty_input_exception should have been thrown");
376 }
377
378 #endif // BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP