distance_se_pl_l.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2014-2018, Oracle and/or its affiliates.
  4. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  5. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  6. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  7. // Licensed under the Boost Software License version 1.0.
  8. // http://www.boost.org/users/license.html
  9. #include <iostream>
  10. #ifndef BOOST_TEST_MODULE
  11. #define BOOST_TEST_MODULE test_distance_spherical_equatorial_pointlike_linear
  12. #endif
  13. #include <boost/test/included/unit_test.hpp>
  14. #include "test_distance_se_common.hpp"
  15. #include "test_empty_geometry.hpp"
  16. typedef bg::cs::spherical_equatorial<bg::degree> cs_type;
  17. typedef bg::model::point<double, 2, cs_type> point_type;
  18. typedef bg::model::segment<point_type> segment_type;
  19. typedef bg::model::multi_point<point_type> multi_point_type;
  20. typedef bg::model::segment<point_type> segment_type;
  21. typedef bg::model::linestring<point_type> linestring_type;
  22. typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
  23. namespace services = bg::strategy::distance::services;
  24. typedef bg::default_distance_result<point_type>::type return_type;
  25. typedef bg::strategy::distance::haversine<double> point_point_strategy;
  26. typedef bg::strategy::distance::cross_track<> point_segment_strategy;
  27. //===========================================================================
  28. template <typename Strategy>
  29. inline bg::default_distance_result<point_type>::type
  30. pp_distance(std::string const& wkt1,
  31. std::string const& wkt2,
  32. Strategy const& strategy)
  33. {
  34. point_type p1, p2;
  35. bg::read_wkt(wkt1, p1);
  36. bg::read_wkt(wkt2, p2);
  37. return bg::distance(p1, p2) * strategy.radius();
  38. }
  39. template <typename Strategy>
  40. inline bg::default_comparable_distance_result<point_type>::type
  41. pp_comparable_distance(std::string const& wkt1,
  42. std::string const& wkt2,
  43. Strategy const&)
  44. {
  45. point_type p1, p2;
  46. bg::read_wkt(wkt1, p1);
  47. bg::read_wkt(wkt2, p2);
  48. return bg::comparable_distance(p1, p2);
  49. }
  50. template <typename Strategy>
  51. inline bg::default_distance_result<point_type>::type
  52. ps_distance(std::string const& wkt1,
  53. std::string const& wkt2,
  54. Strategy const& strategy)
  55. {
  56. point_type p;
  57. segment_type s;
  58. bg::read_wkt(wkt1, p);
  59. bg::read_wkt(wkt2, s);
  60. return bg::distance(p, s, strategy);
  61. }
  62. template <typename Strategy>
  63. inline bg::default_comparable_distance_result<point_type>::type
  64. ps_comparable_distance(std::string const& wkt1,
  65. std::string const& wkt2,
  66. Strategy const& strategy)
  67. {
  68. point_type p;
  69. segment_type s;
  70. bg::read_wkt(wkt1, p);
  71. bg::read_wkt(wkt2, s);
  72. return bg::comparable_distance(p, s, strategy);
  73. }
  74. template <typename Strategy, typename T>
  75. T to_comparable(Strategy const& strategy, T const& distance)
  76. {
  77. namespace services = bg::strategy::distance::services;
  78. typedef typename services::comparable_type
  79. <
  80. Strategy
  81. >::type comparable_strategy;
  82. typedef typename services::result_from_distance
  83. <
  84. comparable_strategy,
  85. point_type,
  86. bg::point_type<segment_type>::type
  87. > get_comparable_distance;
  88. comparable_strategy cstrategy = services::get_comparable
  89. <
  90. Strategy
  91. >::apply(strategy);
  92. return get_comparable_distance::apply(cstrategy, distance);
  93. }
  94. //===========================================================================
  95. template <typename Strategy>
  96. void test_distance_point_segment(Strategy const& strategy)
  97. {
  98. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  99. std::cout << std::endl;
  100. std::cout << "point/segment distance tests" << std::endl;
  101. #endif
  102. typedef test_distance_of_geometries<point_type, segment_type> tester;
  103. double const d2r = bg::math::d2r<double>();
  104. tester::apply("p-s-01",
  105. "POINT(0 0)",
  106. "SEGMENT(2 0,3 0)",
  107. 2.0 * d2r * strategy.radius(),
  108. to_comparable(strategy, 2.0 * d2r * strategy.radius()),
  109. strategy);
  110. tester::apply("p-s-02",
  111. "POINT(2.5 3)",
  112. "SEGMENT(2 0,3 0)",
  113. 3.0 * d2r * strategy.radius(),
  114. to_comparable(strategy, 3.0 * d2r * strategy.radius()),
  115. strategy);
  116. tester::apply("p-s-03",
  117. "POINT(2 0)",
  118. "SEGMENT(2 0,3 0)",
  119. 0,
  120. strategy);
  121. tester::apply("p-s-04",
  122. "POINT(3 0)",
  123. "SEGMENT(2 0,3 0)",
  124. 0,
  125. strategy);
  126. tester::apply("p-s-05",
  127. "POINT(2.5 0)",
  128. "SEGMENT(2 0,3 0)",
  129. 0,
  130. strategy);
  131. tester::apply("p-s-06",
  132. "POINT(3.5 3)",
  133. "SEGMENT(2 0,3 0)",
  134. pp_distance("POINT(3 0)", "POINT(3.5 3)", strategy),
  135. pp_comparable_distance("POINT(3 0)",
  136. "POINT(3.5 3)",
  137. strategy),
  138. strategy);
  139. tester::apply("p-s-07",
  140. "POINT(0 0)",
  141. "SEGMENT(0 10,10 10)",
  142. ps_distance("POINT(0 0)", "SEGMENT(10 10,0 10)", strategy),
  143. pp_comparable_distance("POINT(0 0)",
  144. "POINT(0 10)",
  145. strategy),
  146. strategy);
  147. // very small distances to segment
  148. tester::apply("p-s-07",
  149. "POINT(90 1e-3)",
  150. "SEGMENT(0.5 0,175.5 0)",
  151. 1e-3 * d2r * strategy.radius(),
  152. to_comparable(strategy, 1e-3 * d2r * strategy.radius()),
  153. strategy);
  154. tester::apply("p-s-08",
  155. "POINT(90 1e-4)",
  156. "SEGMENT(0.5 0,175.5 0)",
  157. 1e-4 * d2r * strategy.radius(),
  158. to_comparable(strategy, 1e-4 * d2r * strategy.radius()),
  159. strategy);
  160. tester::apply("p-s-09",
  161. "POINT(90 1e-5)",
  162. "SEGMENT(0.5 0,175.5 0)",
  163. 1e-5 * d2r * strategy.radius(),
  164. to_comparable(strategy, 1e-5 * d2r * strategy.radius()),
  165. strategy);
  166. tester::apply("p-s-10",
  167. "POINT(90 1e-6)",
  168. "SEGMENT(0.5 0,175.5 0)",
  169. 1e-6 * d2r * strategy.radius(),
  170. to_comparable(strategy, 1e-6 * d2r * strategy.radius()),
  171. strategy);
  172. tester::apply("p-s-11",
  173. "POINT(90 1e-7)",
  174. "SEGMENT(0.5 0,175.5 0)",
  175. 1e-7 * d2r * strategy.radius(),
  176. to_comparable(strategy, 1e-7 * d2r * strategy.radius()),
  177. strategy);
  178. tester::apply("p-s-12",
  179. "POINT(90 1e-8)",
  180. "SEGMENT(0.5 0,175.5 0)",
  181. 1e-8 * d2r * strategy.radius(),
  182. to_comparable(strategy, 1e-8 * d2r * strategy.radius()),
  183. strategy);
  184. }
  185. //===========================================================================
  186. template <typename Strategy>
  187. void test_distance_point_linestring(Strategy const& strategy)
  188. {
  189. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  190. std::cout << std::endl;
  191. std::cout << "point/linestring distance tests" << std::endl;
  192. #endif
  193. typedef test_distance_of_geometries<point_type, linestring_type> tester;
  194. double const r = strategy.radius();
  195. double const d2r = bg::math::d2r<double>();
  196. tester::apply("p-l-01",
  197. "POINT(0 0)",
  198. "LINESTRING(2 0,2 0)",
  199. 2.0 * d2r * r,
  200. to_comparable(strategy, 2.0 * d2r * r),
  201. strategy);
  202. tester::apply("p-l-02",
  203. "POINT(0 0)",
  204. "LINESTRING(2 0,3 0)",
  205. 2.0 * d2r * r,
  206. to_comparable(strategy, 2.0 * d2r * r),
  207. strategy);
  208. tester::apply("p-l-03",
  209. "POINT(2.5 3)",
  210. "LINESTRING(2 0,3 0)",
  211. 3.0 * d2r * r,
  212. to_comparable(strategy, 3.0 * d2r * r),
  213. strategy);
  214. tester::apply("p-l-04",
  215. "POINT(2 0)",
  216. "LINESTRING(2 0,3 0)",
  217. 0,
  218. strategy);
  219. tester::apply("p-l-05",
  220. "POINT(3 0)",
  221. "LINESTRING(2 0,3 0)",
  222. 0,
  223. strategy);
  224. tester::apply("p-l-06",
  225. "POINT(2.5 0)",
  226. "LINESTRING(2 0,3 0)",
  227. 0,
  228. strategy);
  229. tester::apply("p-l-07",
  230. "POINT(7.5 10)",
  231. "LINESTRING(1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0)",
  232. 10.0 * d2r * r,
  233. to_comparable(strategy, 10.0 * d2r * r),
  234. strategy);
  235. tester::apply("p-l-08",
  236. "POINT(7.5 10)",
  237. "LINESTRING(1 1,2 1,3 1,4 1,5 1,6 1,7 1,20 2,21 2)",
  238. ps_distance("POINT(7.5 10)", "SEGMENT(7 1,20 2)", strategy),
  239. ps_comparable_distance("POINT(7.5 10)",
  240. "SEGMENT(7 1,20 2)",
  241. strategy),
  242. strategy);
  243. // https://svn.boost.org/trac/boost/ticket/11982
  244. tester::apply("p-l-09",
  245. "POINT(10.4 63.43)",
  246. "LINESTRING(10.733557 59.911923, 10.521812 59.887214)",
  247. 0.06146397739758279 * r,
  248. 0.000944156107132969,
  249. strategy);
  250. //https://github.com/boostorg/geometry/issues/557
  251. tester::apply("p-l-issue557",
  252. "POINT(51.99999790563572 43.71656981636763)",
  253. "LINESTRING(52.0000243071011 43.716569742012496,\
  254. 52.0000121532845 43.71656942616241,\
  255. 52.0 43.7165690998572,\
  256. 51.999987847203 43.7165687638793)",
  257. 1.35062e-08 * r,
  258. 4.5604e-17,
  259. strategy);
  260. }
  261. //===========================================================================
  262. template <typename Strategy>
  263. void test_distance_point_multilinestring(Strategy const& strategy)
  264. {
  265. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  266. std::cout << std::endl;
  267. std::cout << "point/multilinestring distance tests" << std::endl;
  268. #endif
  269. typedef test_distance_of_geometries
  270. <
  271. point_type, multi_linestring_type
  272. > tester;
  273. double const d2r = bg::math::d2r<double>();
  274. tester::apply("p-ml-01",
  275. "POINT(0 0)",
  276. "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
  277. 2.0 * d2r * strategy.radius(),
  278. to_comparable(strategy, 2.0 * d2r * strategy.radius()),
  279. strategy);
  280. tester::apply("p-ml-02",
  281. "POINT(2.5 3)",
  282. "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
  283. 3.0 * d2r * strategy.radius(),
  284. to_comparable(strategy, 3.0 * d2r * strategy.radius()),
  285. strategy);
  286. tester::apply("p-ml-03",
  287. "POINT(2 0)",
  288. "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
  289. 0,
  290. strategy);
  291. tester::apply("p-ml-04",
  292. "POINT(3 0)",
  293. "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
  294. 0,
  295. strategy);
  296. tester::apply("p-ml-05",
  297. "POINT(2.5 0)",
  298. "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
  299. 0,
  300. strategy);
  301. tester::apply("p-ml-06",
  302. "POINT(7.5 10)",
  303. "MULTILINESTRING((-5 0,-3 0),(2 0,3 0,4 0,5 0,6 0,20 1,21 1))",
  304. ps_distance("POINT(7.5 10)", "SEGMENT(6 0,20 1)", strategy),
  305. ps_comparable_distance("POINT(7.5 10)",
  306. "SEGMENT(6 0,20 1)",
  307. strategy),
  308. strategy);
  309. tester::apply("p-ml-07",
  310. "POINT(-8 10)",
  311. "MULTILINESTRING((-20 10,-19 11,-18 10,-6 0,-5 0,-3 0),(2 0,6 0,20 1,21 1))",
  312. ps_distance("POINT(-8 10)", "SEGMENT(-6 0,-18 10)", strategy),
  313. ps_comparable_distance("POINT(-8 10)",
  314. "SEGMENT(-6 0,-18 10)",
  315. strategy),
  316. strategy);
  317. }
  318. //===========================================================================
  319. template <typename Strategy>
  320. void test_distance_linestring_multipoint(Strategy const& strategy)
  321. {
  322. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  323. std::cout << std::endl;
  324. std::cout << "linestring/multipoint distance tests" << std::endl;
  325. #endif
  326. typedef test_distance_of_geometries
  327. <
  328. linestring_type, multi_point_type
  329. > tester;
  330. tester::apply("l-mp-01",
  331. "LINESTRING(2 0,0 2,100 80)",
  332. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  333. ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy),
  334. ps_comparable_distance("POINT(1 1)",
  335. "SEGMENT(2 0,0 2)",
  336. strategy),
  337. strategy);
  338. tester::apply("l-mp-02",
  339. "LINESTRING(4 0,0 4,100 80)",
  340. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  341. ps_distance("POINT(1 1)", "SEGMENT(0 4,4 0)", strategy),
  342. ps_comparable_distance("POINT(1 1)",
  343. "SEGMENT(0 4,4 0)",
  344. strategy),
  345. strategy);
  346. tester::apply("l-mp-03",
  347. "LINESTRING(1 1,2 2,100 80)",
  348. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  349. 0,
  350. strategy);
  351. tester::apply("l-mp-04",
  352. "LINESTRING(3 3,4 4,100 80)",
  353. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  354. pp_distance("POINT(1 1)", "POINT(3 3)", strategy),
  355. pp_comparable_distance("POINT(1 1)", "POINT(3 3)", strategy),
  356. strategy);
  357. tester::apply("l-mp-05",
  358. "LINESTRING(0 0,10 0,10 10,0 10,0 0)",
  359. "MULTIPOINT(1 -1,80 80,5 0,150 90)",
  360. 0,
  361. strategy);
  362. }
  363. //===========================================================================
  364. template <typename Strategy>
  365. void test_distance_multipoint_multilinestring(Strategy const& strategy)
  366. {
  367. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  368. std::cout << std::endl;
  369. std::cout << "multipoint/multilinestring distance tests" << std::endl;
  370. #endif
  371. typedef test_distance_of_geometries
  372. <
  373. multi_point_type, multi_linestring_type
  374. > tester;
  375. tester::apply("mp-ml-01",
  376. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  377. "MULTILINESTRING((2 0,0 2),(2 2,3 3))",
  378. ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy),
  379. ps_comparable_distance("POINT(1 1)",
  380. "SEGMENT(2 0,0 2)",
  381. strategy),
  382. strategy);
  383. tester::apply("mp-ml-02",
  384. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  385. "MULTILINESTRING((3 0,0 3),(4 4,5 5))",
  386. ps_distance("POINT(1 1)", "SEGMENT(3 0,0 3)", strategy),
  387. ps_comparable_distance("POINT(1 1)",
  388. "SEGMENT(3 0,0 3)",
  389. strategy),
  390. strategy);
  391. tester::apply("mp-ml-03",
  392. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  393. "MULTILINESTRING((4 4,5 5),(1 1,2 2))",
  394. 0,
  395. strategy);
  396. tester::apply("mp-ml-04",
  397. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  398. "MULTILINESTRING((4 4,3 3),(4 4,5 5))",
  399. pp_distance("POINT(1 1)", "POINT(3 3)", strategy),
  400. pp_comparable_distance("POINT(1 1)", "POINT(3 3)", strategy),
  401. strategy);
  402. }
  403. //===========================================================================
  404. template <typename Strategy>
  405. void test_distance_multipoint_segment(Strategy const& strategy)
  406. {
  407. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  408. std::cout << std::endl;
  409. std::cout << "multipoint/segment distance tests" << std::endl;
  410. #endif
  411. typedef test_distance_of_geometries<multi_point_type, segment_type> tester;
  412. double d2r = bg::math::d2r<double>();
  413. tester::apply("mp-s-01",
  414. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  415. "SEGMENT(2 0,0 2)",
  416. ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy),
  417. ps_comparable_distance("POINT(1 1)",
  418. "SEGMENT(2 0,0 2)",
  419. strategy),
  420. strategy);
  421. tester::apply("mp-s-02",
  422. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  423. "SEGMENT(0 -3,1 -10)",
  424. 3.0 * d2r * strategy.radius(),
  425. to_comparable(strategy, 3.0 * d2r * strategy.radius()),
  426. strategy);
  427. tester::apply("mp-s-03",
  428. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  429. "SEGMENT(1 1,2 2)",
  430. 0,
  431. strategy);
  432. tester::apply("mp-s-04",
  433. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  434. "SEGMENT(3 3,4 4)",
  435. pp_distance("POINT(1 1)", "POINT(3 3)", strategy),
  436. pp_comparable_distance("POINT(1 1)", "POINT(3 3)", strategy),
  437. strategy);
  438. tester::apply("mp-s-05",
  439. "MULTIPOINT(0 0,1 0,0 1,1 1)",
  440. "SEGMENT(0.5 -3,1 -10)",
  441. pp_distance("POINT(1 0)", "POINT(0.5 -3)", strategy),
  442. pp_comparable_distance("POINT(1 0)",
  443. "POINT(0.5 -3)",
  444. strategy),
  445. strategy);
  446. }
  447. //===========================================================================
  448. //===========================================================================
  449. //===========================================================================
  450. BOOST_AUTO_TEST_CASE( test_all_pointlike_linear )
  451. {
  452. test_distance_point_segment(point_segment_strategy());
  453. test_distance_point_segment(point_segment_strategy(earth_radius_km));
  454. test_distance_point_segment(point_segment_strategy(earth_radius_miles));
  455. }
  456. BOOST_AUTO_TEST_CASE( test_all_point_linestring )
  457. {
  458. test_distance_point_linestring(point_segment_strategy());
  459. test_distance_point_linestring(point_segment_strategy(earth_radius_km));
  460. test_distance_point_linestring(point_segment_strategy(earth_radius_miles));
  461. }
  462. BOOST_AUTO_TEST_CASE( test_all_point_multilinestring )
  463. {
  464. test_distance_point_multilinestring(point_segment_strategy());
  465. test_distance_point_multilinestring(point_segment_strategy(earth_radius_km));
  466. test_distance_point_multilinestring(point_segment_strategy(earth_radius_miles));
  467. }
  468. BOOST_AUTO_TEST_CASE( test_all_linestring_multipoint )
  469. {
  470. test_distance_linestring_multipoint(point_segment_strategy());
  471. test_distance_linestring_multipoint(point_segment_strategy(earth_radius_km));
  472. test_distance_linestring_multipoint(point_segment_strategy(earth_radius_miles));
  473. }
  474. BOOST_AUTO_TEST_CASE( test_all_multipoint_multilinestring )
  475. {
  476. test_distance_multipoint_multilinestring(point_segment_strategy());
  477. test_distance_multipoint_multilinestring(point_segment_strategy(earth_radius_km));
  478. test_distance_multipoint_multilinestring(point_segment_strategy(earth_radius_miles));
  479. }
  480. BOOST_AUTO_TEST_CASE( test_all_multipoint_segment )
  481. {
  482. test_distance_multipoint_segment(point_segment_strategy());
  483. test_distance_multipoint_segment(point_segment_strategy(earth_radius_km));
  484. test_distance_multipoint_segment(point_segment_strategy(earth_radius_miles));
  485. }
  486. BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_linear )
  487. {
  488. test_more_empty_input_pointlike_linear
  489. <
  490. point_type
  491. >(point_segment_strategy());
  492. test_more_empty_input_pointlike_linear
  493. <
  494. point_type
  495. >(point_segment_strategy(earth_radius_km));
  496. test_more_empty_input_pointlike_linear
  497. <
  498. point_type
  499. >(point_segment_strategy(earth_radius_miles));
  500. }