]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | // Unit Test | |
3 | ||
4 | // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. | |
5 | // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. | |
6 | // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. | |
7 | ||
8 | // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library | |
9 | // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. | |
10 | ||
11 | // Use, modification and distribution is subject to the Boost Software License, | |
12 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
13 | // http://www.boost.org/LICENSE_1_0.txt) | |
14 | ||
92f5a8d4 | 15 | //#include <boost/geometry/geometry.hpp> |
7c673cae FG |
16 | |
17 | #include <string> | |
18 | #include <sstream> | |
19 | ||
20 | #include "test_distance.hpp" | |
21 | ||
7c673cae | 22 | #include <boost/array.hpp> |
b32b8144 FG |
23 | #include <boost/mpl/if.hpp> |
24 | #include <boost/typeof/typeof.hpp> | |
7c673cae FG |
25 | |
26 | #include <boost/geometry/geometries/geometries.hpp> | |
27 | #include <boost/geometry/geometries/point_xy.hpp> | |
28 | #include <boost/geometry/geometries/adapted/c_array.hpp> | |
29 | #include <boost/geometry/geometries/adapted/boost_tuple.hpp> | |
30 | ||
31 | #include <test_common/test_point.hpp> | |
32 | #include <test_geometries/custom_segment.hpp> | |
33 | #include <test_geometries/wrapped_boost_array.hpp> | |
34 | ||
35 | #include <boost/variant/variant.hpp> | |
36 | ||
37 | BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian) | |
38 | BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) | |
39 | ||
40 | // Register boost array as a linestring | |
41 | namespace boost { namespace geometry { namespace traits | |
42 | { | |
43 | template <typename Point, std::size_t PointCount> | |
44 | struct tag< boost::array<Point, PointCount> > | |
45 | { | |
46 | typedef linestring_tag type; | |
47 | }; | |
48 | ||
49 | }}} | |
50 | ||
51 | template <typename P> | |
52 | void test_distance_point() | |
53 | { | |
54 | namespace services = bg::strategy::distance::services; | |
55 | typedef typename bg::default_distance_result<P>::type return_type; | |
56 | ||
57 | // Basic, trivial test | |
58 | ||
59 | P p1; | |
60 | bg::set<0>(p1, 1); | |
61 | bg::set<1>(p1, 1); | |
62 | ||
63 | P p2; | |
64 | bg::set<0>(p2, 2); | |
65 | bg::set<1>(p2, 2); | |
66 | ||
67 | return_type d = bg::distance(p1, p2); | |
68 | BOOST_CHECK_CLOSE(d, return_type(1.4142135), 0.001); | |
69 | ||
70 | // Test specifying strategy manually | |
71 | typename services::default_strategy | |
72 | < | |
73 | bg::point_tag, bg::point_tag, P | |
74 | >::type strategy; | |
75 | ||
76 | d = bg::distance(p1, p2, strategy); | |
77 | BOOST_CHECK_CLOSE(d, return_type(1.4142135), 0.001); | |
78 | ||
79 | { | |
80 | // Test custom strategy | |
81 | BOOST_CONCEPT_ASSERT( (bg::concepts::PointDistanceStrategy<taxicab_distance, P, P>) ); | |
82 | ||
83 | typedef typename services::return_type<taxicab_distance, P, P>::type cab_return_type; | |
84 | BOOST_MPL_ASSERT((boost::is_same<cab_return_type, typename bg::coordinate_type<P>::type>)); | |
85 | ||
86 | taxicab_distance tcd; | |
87 | cab_return_type d = bg::distance(p1, p2, tcd); | |
88 | ||
89 | BOOST_CHECK( bg::math::abs(d - cab_return_type(2)) <= cab_return_type(0.01) ); | |
90 | } | |
91 | ||
92 | { | |
93 | // test comparability | |
94 | ||
95 | typedef typename services::default_strategy | |
96 | < | |
97 | bg::point_tag, bg::point_tag, P | |
98 | >::type strategy_type; | |
99 | typedef typename services::comparable_type<strategy_type>::type comparable_strategy_type; | |
100 | ||
101 | strategy_type strategy; | |
102 | comparable_strategy_type comparable_strategy = services::get_comparable<strategy_type>::apply(strategy); | |
103 | return_type comparable = services::result_from_distance<comparable_strategy_type, P, P>::apply(comparable_strategy, 3); | |
104 | ||
105 | BOOST_CHECK_CLOSE(comparable, return_type(9), 0.001); | |
106 | } | |
107 | } | |
108 | ||
109 | template <typename P> | |
110 | void test_distance_segment() | |
111 | { | |
112 | typedef typename bg::default_distance_result<P>::type return_type; | |
113 | ||
114 | P s1; bg::set<0>(s1, 1); bg::set<1>(s1, 1); | |
115 | P s2; bg::set<0>(s2, 4); bg::set<1>(s2, 4); | |
116 | ||
117 | // Check points left, right, projected-left, projected-right, on segment | |
118 | P p1; bg::set<0>(p1, 0); bg::set<1>(p1, 1); | |
119 | P p2; bg::set<0>(p2, 1); bg::set<1>(p2, 0); | |
120 | P p3; bg::set<0>(p3, 3); bg::set<1>(p3, 1); | |
121 | P p4; bg::set<0>(p4, 1); bg::set<1>(p4, 3); | |
122 | P p5; bg::set<0>(p5, 3); bg::set<1>(p5, 3); | |
123 | ||
124 | bg::model::referring_segment<P const> const seg(s1, s2); | |
125 | ||
126 | return_type d1 = bg::distance(p1, seg); | |
127 | return_type d2 = bg::distance(p2, seg); | |
128 | return_type d3 = bg::distance(p3, seg); | |
129 | return_type d4 = bg::distance(p4, seg); | |
130 | return_type d5 = bg::distance(p5, seg); | |
131 | ||
132 | BOOST_CHECK_CLOSE(d1, return_type(1), 0.001); | |
133 | BOOST_CHECK_CLOSE(d2, return_type(1), 0.001); | |
134 | BOOST_CHECK_CLOSE(d3, return_type(1.4142135), 0.001); | |
135 | BOOST_CHECK_CLOSE(d4, return_type(1.4142135), 0.001); | |
136 | BOOST_CHECK_CLOSE(d5, return_type(0), 0.001); | |
137 | ||
138 | // Reverse case: segment/point instead of point/segment | |
139 | return_type dr1 = bg::distance(seg, p1); | |
140 | return_type dr2 = bg::distance(seg, p2); | |
141 | ||
142 | BOOST_CHECK_CLOSE(dr1, d1, 0.001); | |
143 | BOOST_CHECK_CLOSE(dr2, d2, 0.001); | |
144 | ||
145 | // Test specifying strategy manually: | |
146 | // 1) point-point-distance | |
147 | typename bg::strategy::distance::services::default_strategy | |
148 | < | |
149 | bg::point_tag, bg::point_tag, P | |
150 | >::type pp_strategy; | |
151 | d1 = bg::distance(p1, seg, pp_strategy); | |
152 | BOOST_CHECK_CLOSE(d1, return_type(1), 0.001); | |
153 | ||
154 | // 2) point-segment-distance | |
155 | typename bg::strategy::distance::services::default_strategy | |
156 | < | |
157 | bg::point_tag, bg::segment_tag, P | |
158 | >::type ps_strategy; | |
159 | d1 = bg::distance(p1, seg, ps_strategy); | |
160 | BOOST_CHECK_CLOSE(d1, return_type(1), 0.001); | |
161 | ||
162 | // 3) custom point strategy | |
163 | taxicab_distance tcd; | |
164 | d1 = bg::distance(p1, seg, tcd); | |
165 | BOOST_CHECK_CLOSE(d1, return_type(1), 0.001); | |
166 | } | |
167 | ||
168 | template <typename Point, typename Geometry, typename T> | |
169 | void test_distance_linear(std::string const& wkt_point, std::string const& wkt_geometry, T const& expected) | |
170 | { | |
171 | Point p; | |
172 | bg::read_wkt(wkt_point, p); | |
173 | ||
174 | Geometry g; | |
175 | bg::read_wkt(wkt_geometry, g); | |
176 | ||
177 | typedef typename bg::default_distance_result<Point>::type return_type; | |
178 | return_type d = bg::distance(p, g); | |
179 | ||
180 | // For point-to-linestring (or point-to-polygon), both a point-strategy and a point-segment-strategy can be specified. | |
181 | // Test this. | |
182 | return_type ds1 = bg::distance(p, g, bg::strategy::distance::pythagoras<>()); | |
183 | return_type ds2 = bg::distance(p, g, bg::strategy::distance::projected_point<>()); | |
184 | ||
185 | BOOST_CHECK_CLOSE(d, return_type(expected), 0.001); | |
186 | BOOST_CHECK_CLOSE(ds1, return_type(expected), 0.001); | |
187 | BOOST_CHECK_CLOSE(ds2, return_type(expected), 0.001); | |
188 | } | |
189 | ||
190 | template <typename P> | |
191 | void test_distance_array_as_linestring() | |
192 | { | |
193 | typedef typename bg::default_distance_result<P>::type return_type; | |
194 | ||
195 | // Normal array does not have | |
196 | boost::array<P, 2> points; | |
197 | bg::set<0>(points[0], 1); | |
198 | bg::set<1>(points[0], 1); | |
199 | bg::set<0>(points[1], 3); | |
200 | bg::set<1>(points[1], 3); | |
201 | ||
202 | P p; | |
203 | bg::set<0>(p, 2); | |
204 | bg::set<1>(p, 1); | |
205 | ||
206 | return_type d = bg::distance(p, points); | |
207 | BOOST_CHECK_CLOSE(d, return_type(0.70710678), 0.001); | |
208 | ||
209 | bg::set<0>(p, 5); bg::set<1>(p, 5); | |
210 | d = bg::distance(p, points); | |
211 | BOOST_CHECK_CLOSE(d, return_type(2.828427), 0.001); | |
212 | } | |
213 | ||
214 | ||
215 | // code moved from the distance unit test in multi/algorithms -- start | |
216 | template <typename Geometry1, typename Geometry2> | |
217 | void test_distance(std::string const& wkt1, std::string const& wkt2, double expected) | |
218 | { | |
219 | Geometry1 g1; | |
220 | Geometry2 g2; | |
221 | bg::read_wkt(wkt1, g1); | |
222 | bg::read_wkt(wkt2, g2); | |
223 | typename bg::default_distance_result<Geometry1, Geometry2>::type d = bg::distance(g1, g2); | |
224 | ||
225 | BOOST_CHECK_CLOSE(d, expected, 0.0001); | |
226 | } | |
227 | ||
228 | template <typename Geometry1, typename Geometry2, typename Strategy> | |
229 | void test_distance(Strategy const& strategy, std::string const& wkt1, | |
230 | std::string const& wkt2, double expected) | |
231 | { | |
232 | Geometry1 g1; | |
233 | Geometry2 g2; | |
234 | bg::read_wkt(wkt1, g1); | |
235 | bg::read_wkt(wkt2, g2); | |
236 | typename bg::default_distance_result<Geometry1, Geometry2>::type d = bg::distance(g1, g2, strategy); | |
237 | ||
238 | BOOST_CHECK_CLOSE(d, expected, 0.0001); | |
239 | } | |
240 | ||
241 | ||
242 | template <typename P> | |
243 | void test_2d() | |
244 | { | |
245 | typedef bg::model::multi_point<P> mp; | |
246 | typedef bg::model::multi_linestring<bg::model::linestring<P> > ml; | |
247 | test_distance<P, P>("POINT(0 0)", "POINT(1 1)", sqrt(2.0)); | |
248 | test_distance<P, mp>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
249 | test_distance<mp, P>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
250 | test_distance<mp, mp>("MULTIPOINT((1 1),(1 0),(0 2))", "MULTIPOINT((2 2),(2 3))", sqrt(2.0)); | |
251 | test_distance<P, ml>("POINT(0 0)", "MULTILINESTRING((1 1,2 2),(1 0,2 0),(0 2,0 3))", 1.0); | |
252 | test_distance<ml, P>("MULTILINESTRING((1 1,2 2),(1 0,2 0),(0 2,0 3))", "POINT(0 0)", 1.0); | |
253 | test_distance<ml, mp>("MULTILINESTRING((1 1,2 2),(1 0,2 0),(0 2,0 3))", "MULTIPOINT((0 0),(1 1))", 0.0); | |
254 | ||
255 | // Test with a strategy | |
256 | bg::strategy::distance::pythagoras<> pyth; | |
257 | test_distance<P, P>(pyth, "POINT(0 0)", "POINT(1 1)", sqrt(2.0)); | |
258 | test_distance<P, mp>(pyth, "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
259 | test_distance<mp, P>(pyth, "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
260 | } | |
261 | ||
262 | ||
263 | template <typename P> | |
264 | void test_3d() | |
265 | { | |
266 | typedef bg::model::multi_point<P> mp; | |
267 | test_distance<P, P>("POINT(0 0 0)", "POINT(1 1 1)", sqrt(3.0)); | |
268 | test_distance<P, mp>("POINT(0 0 0)", "MULTIPOINT((1 1 1),(1 0 0),(0 1 2))", 1.0); | |
269 | test_distance<mp, mp>("MULTIPOINT((1 1 1),(1 0 0),(0 0 2))", "MULTIPOINT((2 2 2),(2 3 4))", sqrt(3.0)); | |
270 | } | |
271 | ||
272 | ||
273 | template <typename P1, typename P2> | |
274 | void test_mixed() | |
275 | { | |
276 | typedef bg::model::multi_point<P1> mp1; | |
277 | typedef bg::model::multi_point<P2> mp2; | |
278 | ||
279 | test_distance<P1, P2>("POINT(0 0)", "POINT(1 1)", sqrt(2.0)); | |
280 | ||
281 | test_distance<P1, mp1>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
282 | test_distance<P1, mp2>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
283 | test_distance<P2, mp1>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
284 | test_distance<P2, mp2>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
285 | ||
286 | // Test automatic reversal | |
287 | test_distance<mp1, P1>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
288 | test_distance<mp1, P2>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
289 | test_distance<mp2, P1>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
290 | test_distance<mp2, P2>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
291 | ||
292 | // Test multi-multi using different point types for each | |
293 | test_distance<mp1, mp2>("MULTIPOINT((1 1),(1 0),(0 2))", "MULTIPOINT((2 2),(2 3))", sqrt(2.0)); | |
294 | ||
295 | // Test with a strategy | |
296 | using namespace bg::strategy::distance; | |
297 | ||
298 | test_distance<P1, P2>(pythagoras<>(), "POINT(0 0)", "POINT(1 1)", sqrt(2.0)); | |
299 | ||
300 | test_distance<P1, mp1>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
301 | test_distance<P1, mp2>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
302 | test_distance<P2, mp1>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
303 | test_distance<P2, mp2>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0); | |
304 | ||
305 | // Most interesting: reversal AND a strategy (note that the stategy must be reversed automatically | |
306 | test_distance<mp1, P1>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
307 | test_distance<mp1, P2>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
308 | test_distance<mp2, P1>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
309 | test_distance<mp2, P2>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0); | |
310 | } | |
311 | // code moved from the distance unit test in multi/algorithms -- end | |
312 | ||
313 | ||
314 | ||
315 | ||
316 | template <typename P> | |
317 | void test_all() | |
318 | { | |
319 | test_distance_point<P>(); | |
320 | test_distance_segment<P>(); | |
321 | test_distance_array_as_linestring<P>(); | |
322 | ||
323 | test_geometry<P, bg::model::segment<P> >("POINT(1 3)", "LINESTRING(1 1,4 4)", sqrt(2.0)); | |
324 | test_geometry<P, bg::model::segment<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0)); | |
325 | ||
326 | test_geometry<P, P>("POINT(1 1)", "POINT(2 2)", sqrt(2.0)); | |
327 | test_geometry<P, P>("POINT(0 0)", "POINT(0 3)", 3.0); | |
328 | test_geometry<P, P>("POINT(0 0)", "POINT(4 0)", 4.0); | |
329 | test_geometry<P, P>("POINT(0 3)", "POINT(4 0)", 5.0); | |
330 | test_geometry<P, bg::model::linestring<P> >("POINT(1 3)", "LINESTRING(1 1,4 4)", sqrt(2.0)); | |
331 | test_geometry<P, bg::model::linestring<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0)); | |
332 | test_geometry<P, bg::model::linestring<P> >("POINT(50 50)", "LINESTRING(50 40, 40 50)", sqrt(50.0)); | |
333 | test_geometry<P, bg::model::linestring<P> >("POINT(50 50)", "LINESTRING(50 40, 40 50, 0 90)", sqrt(50.0)); | |
334 | test_geometry<bg::model::linestring<P>, P>("LINESTRING(1 1,4 4)", "POINT(1 3)", sqrt(2.0)); | |
335 | test_geometry<bg::model::linestring<P>, P>("LINESTRING(50 40, 40 50)", "POINT(50 50)", sqrt(50.0)); | |
336 | test_geometry<bg::model::linestring<P>, P>("LINESTRING(50 40, 40 50, 0 90)", "POINT(50 50)", sqrt(50.0)); | |
337 | ||
338 | // Rings | |
339 | test_geometry<P, bg::model::ring<P> >("POINT(1 3)", "POLYGON((1 1,4 4,5 0,1 1))", sqrt(2.0)); | |
340 | test_geometry<P, bg::model::ring<P> >("POINT(3 1)", "POLYGON((1 1,4 4,5 0,1 1))", 0.0); | |
341 | // other way round | |
342 | test_geometry<bg::model::ring<P>, P>("POLYGON((1 1,4 4,5 0,1 1))", "POINT(3 1)", 0.0); | |
343 | // open ring | |
344 | test_geometry<P, bg::model::ring<P, true, false> >("POINT(1 3)", "POLYGON((4 4,5 0,1 1))", sqrt(2.0)); | |
345 | ||
346 | // Polygons | |
347 | test_geometry<P, bg::model::polygon<P> >("POINT(1 3)", "POLYGON((1 1,4 4,5 0,1 1))", sqrt(2.0)); | |
348 | test_geometry<P, bg::model::polygon<P> >("POINT(3 1)", "POLYGON((1 1,4 4,5 0,1 1))", 0.0); | |
349 | // other way round | |
350 | test_geometry<bg::model::polygon<P>, P>("POLYGON((1 1,4 4,5 0,1 1))", "POINT(3 1)", 0.0); | |
351 | // open polygon | |
352 | test_geometry<P, bg::model::polygon<P, true, false> >("POINT(1 3)", "POLYGON((4 4,5 0,1 1))", sqrt(2.0)); | |
353 | ||
354 | // Polygons with holes | |
355 | std::string donut = "POLYGON ((0 0,1 9,8 1,0 0),(1 1,4 1,1 4,1 1))"; | |
356 | test_geometry<P, bg::model::polygon<P> >("POINT(2 2)", donut, 0.5 * sqrt(2.0)); | |
357 | test_geometry<P, bg::model::polygon<P> >("POINT(3 3)", donut, 0.0); | |
358 | // other way round | |
359 | test_geometry<bg::model::polygon<P>, P>(donut, "POINT(2 2)", 0.5 * sqrt(2.0)); | |
360 | // open | |
361 | test_geometry<P, bg::model::polygon<P, true, false> >("POINT(2 2)", "POLYGON ((0 0,1 9,8 1),(1 1,4 1,1 4))", 0.5 * sqrt(2.0)); | |
362 | ||
363 | // Should (currently) give compiler assertion | |
364 | // test_geometry<bg::model::polygon<P>, bg::model::polygon<P> >(donut, donut, 0.5 * sqrt(2.0)); | |
365 | ||
366 | // DOES NOT COMPILE - cannot do read_wkt (because boost::array is not variably sized) | |
367 | // test_geometry<P, boost::array<P, 2> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0)); | |
368 | ||
369 | test_geometry<P, test::wrapped_boost_array<P, 2> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0)); | |
370 | ||
371 | test_distance_linear<P, bg::model::linestring<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0)); | |
372 | } | |
373 | ||
374 | template <typename P> | |
375 | void test_empty_input() | |
376 | { | |
377 | P p; | |
378 | bg::model::linestring<P> line_empty; | |
379 | bg::model::polygon<P> poly_empty; | |
380 | bg::model::ring<P> ring_empty; | |
381 | bg::model::multi_point<P> mp_empty; | |
382 | bg::model::multi_linestring<bg::model::linestring<P> > ml_empty; | |
383 | ||
384 | test_empty_input(p, line_empty); | |
385 | test_empty_input(p, poly_empty); | |
386 | test_empty_input(p, ring_empty); | |
387 | ||
388 | test_empty_input(p, mp_empty); | |
389 | test_empty_input(p, ml_empty); | |
390 | test_empty_input(mp_empty, mp_empty); | |
391 | ||
392 | // Test behaviour if one of the inputs is empty | |
393 | bg::model::multi_point<P> mp; | |
394 | mp.push_back(p); | |
395 | test_empty_input(mp_empty, mp); | |
396 | test_empty_input(mp, mp_empty); | |
397 | } | |
398 | ||
399 | void test_large_integers() | |
400 | { | |
401 | typedef bg::model::point<int, 2, bg::cs::cartesian> int_point_type; | |
402 | typedef bg::model::point<double, 2, bg::cs::cartesian> double_point_type; | |
403 | ||
404 | // point-point | |
405 | { | |
406 | std::string const a = "POINT(2544000 528000)"; | |
407 | std::string const b = "POINT(2768040 528000)"; | |
408 | int_point_type ia, ib; | |
409 | double_point_type da, db; | |
410 | bg::read_wkt(a, ia); | |
411 | bg::read_wkt(b, ib); | |
412 | bg::read_wkt(a, da); | |
413 | bg::read_wkt(b, db); | |
414 | ||
415 | BOOST_AUTO(idist, bg::distance(ia, ib)); | |
416 | BOOST_AUTO(ddist, bg::distance(da, db)); | |
417 | ||
418 | BOOST_CHECK_MESSAGE(std::abs(idist - ddist) < 0.1, | |
419 | "within<a double> different from within<an int>"); | |
420 | } | |
421 | // Point-segment | |
422 | { | |
423 | std::string const a = "POINT(2600000 529000)"; | |
424 | std::string const b = "LINESTRING(2544000 528000, 2768040 528000)"; | |
425 | int_point_type ia; | |
426 | double_point_type da; | |
427 | bg::model::segment<int_point_type> ib; | |
428 | bg::model::segment<double_point_type> db; | |
429 | bg::read_wkt(a, ia); | |
430 | bg::read_wkt(b, ib); | |
431 | bg::read_wkt(a, da); | |
432 | bg::read_wkt(b, db); | |
433 | ||
434 | BOOST_AUTO(idist, bg::distance(ia, ib)); | |
435 | BOOST_AUTO(ddist, bg::distance(da, db)); | |
436 | ||
437 | BOOST_CHECK_MESSAGE(std::abs(idist - ddist) < 0.1, | |
438 | "within<a double> different from within<an int>"); | |
439 | } | |
440 | } | |
441 | ||
442 | template <typename T> | |
443 | void test_variant() | |
444 | { | |
445 | typedef bg::model::point<T, 2, bg::cs::cartesian> point_type; | |
446 | typedef bg::model::segment<point_type> segment_type; | |
447 | typedef bg::model::box<point_type> box_type; | |
448 | typedef boost::variant<point_type, segment_type, box_type> variant_type; | |
449 | ||
450 | point_type point; | |
451 | std::string const point_li = "POINT(1 3)"; | |
452 | bg::read_wkt(point_li, point); | |
453 | ||
454 | segment_type seg; | |
455 | std::string const seg_li = "LINESTRING(1 1,4 4)"; | |
456 | bg::read_wkt(seg_li, seg); | |
457 | ||
458 | variant_type v1, v2; | |
459 | ||
460 | BOOST_MPL_ASSERT(( | |
461 | boost::is_same | |
462 | < | |
463 | typename bg::distance_result | |
464 | < | |
465 | variant_type, variant_type, bg::default_strategy | |
466 | >::type, | |
467 | double | |
468 | > | |
469 | )); | |
470 | ||
471 | // Default strategy | |
472 | v1 = point; | |
473 | v2 = point; | |
474 | BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, point), 0.0001); | |
475 | BOOST_CHECK_CLOSE(bg::distance(v1, point), bg::distance(point, point), 0.0001); | |
476 | BOOST_CHECK_CLOSE(bg::distance(point, v2), bg::distance(point, point), 0.0001); | |
477 | v1 = point; | |
478 | v2 = seg; | |
479 | BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, seg), 0.0001); | |
480 | BOOST_CHECK_CLOSE(bg::distance(v1, seg), bg::distance(point, seg), 0.0001); | |
481 | BOOST_CHECK_CLOSE(bg::distance(point, v2), bg::distance(point, seg), 0.0001); | |
482 | ||
483 | // User defined strategy | |
484 | v1 = point; | |
485 | v2 = point; | |
486 | bg::strategy::distance::haversine<double> s; | |
487 | //BOOST_CHECK_CLOSE(bg::distance(v1, v2, s), bg::distance(point, point, s), 0.0001); | |
488 | //BOOST_CHECK_CLOSE(bg::distance(v1, point, s), bg::distance(point, point, s), 0.0001); | |
489 | //BOOST_CHECK_CLOSE(bg::distance(point, v2, s), bg::distance(point, point, s), 0.0001); | |
490 | } | |
491 | ||
492 | int test_main(int, char* []) | |
493 | { | |
494 | #ifdef TEST_ARRAY | |
495 | //test_all<int[2]>(); | |
496 | //test_all<float[2]>(); | |
497 | //test_all<double[2]>(); | |
498 | //test_all<test::test_point>(); // located here because of 3D | |
499 | #endif | |
500 | ||
501 | test_large_integers(); | |
502 | ||
503 | test_all<bg::model::d2::point_xy<int> >(); | |
504 | test_all<boost::tuple<float, float> >(); | |
505 | test_all<bg::model::d2::point_xy<float> >(); | |
506 | test_all<bg::model::d2::point_xy<double> >(); | |
507 | ||
508 | #ifdef HAVE_TTMATH | |
509 | test_all<bg::model::d2::point_xy<ttmath_big> >(); | |
510 | #endif | |
511 | ||
512 | test_empty_input<bg::model::d2::point_xy<int> >(); | |
513 | ||
514 | // below are the test cases moved here from the distance unit test | |
515 | // in test/multi/algorithms | |
516 | test_2d<boost::tuple<float, float> >(); | |
517 | test_2d<bg::model::d2::point_xy<float> >(); | |
518 | test_2d<bg::model::d2::point_xy<double> >(); | |
519 | ||
520 | test_3d<boost::tuple<float, float, float> >(); | |
521 | test_3d<bg::model::point<double, 3, bg::cs::cartesian> >(); | |
522 | ||
523 | test_mixed<bg::model::d2::point_xy<float>, bg::model::d2::point_xy<double> >(); | |
524 | ||
525 | #ifdef HAVE_TTMATH | |
526 | test_2d<bg::model::d2::point_xy<ttmath_big> >(); | |
527 | test_mixed<bg::model::d2::point_xy<ttmath_big>, bg::model::d2::point_xy<double> >(); | |
528 | #endif | |
529 | ||
530 | test_empty_input<bg::model::d2::point_xy<int> >(); | |
531 | ||
532 | test_variant<double>(); | |
533 | test_variant<int>(); | |
534 | ||
535 | return 0; | |
536 | } |