distance.cpp 19 KB

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