distance_se_geo_ar_ar.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2017, 2018 Oracle and/or its affiliates.
  4. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_TEST_MODULE
  8. #define BOOST_TEST_MODULE test_distance_geographic_areal_areal
  9. #endif
  10. #include <boost/range.hpp>
  11. #include <boost/type_traits/is_same.hpp>
  12. #include <boost/test/included/unit_test.hpp>
  13. #include <boost/geometry/util/condition.hpp>
  14. #include <boost/geometry/strategies/strategies.hpp>
  15. #include "test_distance_geo_common.hpp"
  16. #include "test_empty_geometry.hpp"
  17. template <typename Point, typename Strategy_pp, typename Strategy_ps>
  18. void test_distance_ring_ring(Strategy_pp const& strategy_pp,
  19. Strategy_ps const& strategy_ps)
  20. {
  21. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  22. std::cout << std::endl;
  23. std::cout << "ring/ring distance tests" << std::endl;
  24. #endif
  25. typedef bg::model::ring<Point> ring_type;
  26. typedef test_distance_of_geometries<ring_type, ring_type> tester;
  27. std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
  28. tester::apply("rr1", ring, "POLYGON((16 0,13 0,15 1,16 0))",
  29. ps_distance<Point>("POINT(13 1)",
  30. "SEGMENT(13 0,15 1)", strategy_ps),
  31. strategy_ps, true, false, false);
  32. tester::apply("rr2", ring, "POLYGON((16 0,14 1,15 1,16 0))",
  33. pp_distance<Point>("POINT(13 1)", "POINT(14 1)", strategy_pp),
  34. strategy_ps, true, false, false);
  35. tester::apply("rr3", ring, ring,
  36. 0, strategy_ps, true, false, false);
  37. }
  38. //============================================================================
  39. template <typename Point, typename Strategy_pp, typename Strategy_ps>
  40. void test_distance_ring_polygon(Strategy_pp const& strategy_pp,
  41. Strategy_ps const& strategy_ps)
  42. {
  43. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  44. std::cout << std::endl;
  45. std::cout << "ring/polygon distance tests" << std::endl;
  46. #endif
  47. typedef bg::model::ring<Point> ring_type;
  48. typedef bg::model::polygon<Point> polygon_type;
  49. typedef test_distance_of_geometries<ring_type, polygon_type> tester;
  50. std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
  51. tester::apply("rp1", ring, "POLYGON((16 0,13 0,15 1,16 0))",
  52. ps_distance<Point>("POINT(13 1)",
  53. "SEGMENT(13 0,15 1)", strategy_ps),
  54. strategy_ps, true, false, false);
  55. tester::apply("rp2", ring, "POLYGON((16 0,14 1,15 1,16 0))",
  56. pp_distance<Point>("POINT(13 1)", "POINT(14 1)", strategy_pp),
  57. strategy_ps, true, false, false);
  58. tester::apply("rp3", ring, "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))",
  59. 0, strategy_ps, true, false, false);
  60. }
  61. template <typename Point, typename Strategy_pp, typename Strategy_ps>
  62. void test_distance_polygon_polygon(Strategy_pp const& strategy_pp,
  63. Strategy_ps const& strategy_ps)
  64. {
  65. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  66. std::cout << std::endl;
  67. std::cout << "polygon/polygon distance tests" << std::endl;
  68. #endif
  69. typedef bg::model::polygon<Point> polygon_type;
  70. typedef test_distance_of_geometries<polygon_type, polygon_type> tester;
  71. std::string const poly = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
  72. tester::apply("pp1", poly, "POLYGON((16 0,13 0,15 1,16 0))",
  73. ps_distance<Point>("POINT(13 1)",
  74. "SEGMENT(13 0,15 1)", strategy_ps),
  75. strategy_ps, true, false, false);
  76. tester::apply("pp2", poly, "POLYGON((16 0,14 1,15 1,16 0))",
  77. pp_distance<Point>("POINT(13 1)", "POINT(14 1)", strategy_pp),
  78. strategy_ps, true, false, false);
  79. tester::apply("pp3", poly, "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))",
  80. 0, strategy_ps, true, false, false);
  81. }
  82. //============================================================================
  83. template <typename Point, typename Strategy_pp, typename Strategy_ps>
  84. void test_distance_ring_multi_polygon(Strategy_pp const& strategy_pp,
  85. Strategy_ps const& strategy_ps)
  86. {
  87. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  88. std::cout << std::endl;
  89. std::cout << "ring/multi_polygon distance tests" << std::endl;
  90. #endif
  91. typedef bg::model::ring<Point> ring_type;
  92. typedef bg::model::polygon<Point> polygon_type;
  93. typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
  94. typedef test_distance_of_geometries<ring_type, multi_polygon_type> tester;
  95. std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
  96. tester::apply("rmp1", ring, "MULTIPOLYGON(((16 0,13 0,15 1,16 0)),\
  97. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  98. ps_distance<Point>("POINT(12.5 2.5)", "SEGMENT(12 3,13 1)",
  99. strategy_ps),
  100. strategy_ps, true, false, false);
  101. tester::apply("rmp2", ring, "MULTIPOLYGON(((16 0,13.1 1,15 1,16 0)),\
  102. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  103. pp_distance<Point>("POINT(13 1)", "POINT(13.1 1)", strategy_pp),
  104. strategy_ps, true, false, false);
  105. tester::apply("rmp3", ring, "MULTIPOLYGON(((16 0,13 1,15 1,16 0)),\
  106. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  107. 0, strategy_ps, true, false, false);
  108. tester::apply("rmp4", ring, "MULTIPOLYGON(((16 0,12 1,15 1,16 0)),\
  109. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  110. 0, strategy_ps, true, false, false);
  111. }
  112. template <typename Point, typename Strategy_pp, typename Strategy_ps>
  113. void test_distance_polygon_multi_polygon(Strategy_pp const& strategy_pp,
  114. Strategy_ps const& strategy_ps)
  115. {
  116. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  117. std::cout << std::endl;
  118. std::cout << "polygon/multi_polygon distance tests" << std::endl;
  119. #endif
  120. typedef bg::model::polygon<Point> polygon_type;
  121. typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
  122. typedef test_distance_of_geometries<polygon_type, multi_polygon_type> tester;
  123. std::string const poly = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
  124. tester::apply("pmp1", poly, "MULTIPOLYGON(((16 0,13 0,15 1,16 0)),\
  125. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  126. ps_distance<Point>("POINT(12.5 2.5)", "SEGMENT(12 3,13 1)",
  127. strategy_ps),
  128. strategy_ps, true, false, false);
  129. tester::apply("pmp2", poly, "MULTIPOLYGON(((16 0,13.1 1,15 1,16 0)),\
  130. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  131. pp_distance<Point>("POINT(13 1)", "POINT(13.1 1)", strategy_pp),
  132. strategy_ps, true, false, false);
  133. tester::apply("pmp3", poly, "MULTIPOLYGON(((16 0,13 1,15 1,16 0)),\
  134. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  135. 0, strategy_ps, true, false, false);
  136. tester::apply("pmp4", poly, "MULTIPOLYGON(((16 0,12 1,15 1,16 0)),\
  137. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  138. 0, strategy_ps, true, false, false);
  139. // w/ interior ring
  140. std::string const poly_interior = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0),\
  141. (12 1,11 1,12 2,12 1))";
  142. tester::apply("pmp1", poly_interior, "MULTIPOLYGON(((16 0,13 0,15 1,16 0)),\
  143. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  144. ps_distance<Point>("POINT(12.5 2.5)", "SEGMENT(12 3,13 1)",
  145. strategy_ps),
  146. strategy_ps, true, false, false);
  147. tester::apply("pmp2", poly_interior, "MULTIPOLYGON(((16 0,13.1 1,15 1,16 0)),\
  148. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  149. pp_distance<Point>("POINT(13 1)", "POINT(13.1 1)", strategy_pp),
  150. strategy_ps, true, false, false);
  151. tester::apply("pmp3", poly_interior, "MULTIPOLYGON(((16 0,13 1,15 1,16 0)),\
  152. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  153. 0, strategy_ps, true, false, false);
  154. tester::apply("pmp4", poly_interior, "MULTIPOLYGON(((16 0,12 1,15 1,16 0)),\
  155. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  156. 0, strategy_ps, true, false, false);
  157. }
  158. template <typename Point, typename Strategy_pp, typename Strategy_ps>
  159. void test_distance_multi_polygon_multi_polygon(Strategy_pp const& strategy_pp,
  160. Strategy_ps const& strategy_ps)
  161. {
  162. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  163. std::cout << std::endl;
  164. std::cout << "multi_polygon/multi_polygon distance tests" << std::endl;
  165. #endif
  166. typedef bg::model::polygon<Point> polygon_type;
  167. typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
  168. typedef test_distance_of_geometries<multi_polygon_type, multi_polygon_type>
  169. tester;
  170. std::string const mpoly = "MULTIPOLYGON(((11 0,10 1,11 2,12 3,13 1,11 0)),\
  171. ((0 0,0 1,1 1,1 0,0 0)))";
  172. tester::apply("mpmp1", mpoly, "MULTIPOLYGON(((16 0,13 0,15 1,16 0)),\
  173. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  174. ps_distance<Point>("POINT(12.5 2.5)", "SEGMENT(12 3,13 1)",
  175. strategy_ps),
  176. strategy_ps, true, false, false);
  177. tester::apply("mpmp2", mpoly, "MULTIPOLYGON(((16 0,13.1 1,15 1,16 0)),\
  178. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  179. pp_distance<Point>("POINT(13 1)", "POINT(13.1 1)", strategy_pp),
  180. strategy_ps, true, false, false);
  181. tester::apply("mpmp3", mpoly, "MULTIPOLYGON(((16 0,13 1,15 1,16 0)),\
  182. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  183. 0, strategy_ps, true, false, false);
  184. tester::apply("mpmp4", mpoly, "MULTIPOLYGON(((16 0,12 1,15 1,16 0)),\
  185. ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
  186. 0, strategy_ps, true, false, false);
  187. }
  188. //============================================================================
  189. template
  190. <
  191. typename Point,
  192. typename Strategy_pp,
  193. typename Strategy_ps,
  194. typename Strategy_sb
  195. >
  196. void test_distance_ring_box(Strategy_pp const& strategy_pp,
  197. Strategy_ps const& strategy_ps,
  198. Strategy_sb const& strategy_sb)
  199. {
  200. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  201. std::cout << std::endl;
  202. std::cout << "ring/box distance tests" << std::endl;
  203. #endif
  204. typedef bg::model::box<Point> box_type;
  205. typedef bg::model::ring<Point> ring_type;
  206. typedef test_distance_of_geometries<ring_type, box_type> tester;
  207. std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
  208. tester::apply("rb1", ring, "BOX(10 10,20 20)",
  209. sb_distance<Point>("SEGMENT(11 2,12 3)",
  210. "BOX(10 10,20 20)", strategy_sb),
  211. strategy_sb, true, false, false);
  212. tester::apply("rb2", ring, "BOX(17 0,20 3)",
  213. ps_distance<Point>("POINT(13 1)",
  214. "SEGMENT(17 0,17 3)", strategy_ps),
  215. strategy_sb, true, false, false);
  216. tester::apply("rb3", ring, "BOX(17 0,20 1)",
  217. pp_distance<Point>("POINT(17 1)", "POINT(13 1)", strategy_pp),
  218. strategy_sb, true, false, false);
  219. tester::apply("rb4", ring, "BOX(12 0,20 1)",
  220. 0, strategy_sb, true, false, false);
  221. }
  222. template
  223. <
  224. typename Point,
  225. typename Strategy_pp,
  226. typename Strategy_ps,
  227. typename Strategy_sb
  228. >
  229. void test_distance_polygon_box(Strategy_pp const& strategy_pp,
  230. Strategy_ps const& strategy_ps,
  231. Strategy_sb const& strategy_sb)
  232. {
  233. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  234. std::cout << std::endl;
  235. std::cout << "polygon/box distance tests" << std::endl;
  236. #endif
  237. typedef bg::model::box<Point> box_type;
  238. typedef bg::model::polygon<Point> polygon_type;
  239. typedef test_distance_of_geometries<polygon_type, box_type> tester;
  240. std::string const polygon = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
  241. tester::apply("pb1", polygon, "BOX(10 10,20 20)",
  242. sb_distance<Point>("SEGMENT(11 2,12 3)",
  243. "BOX(10 10,20 20)", strategy_sb),
  244. strategy_sb, true, false, false);
  245. tester::apply("pb2", polygon, "BOX(17 0,20 3)",
  246. ps_distance<Point>("POINT(13 1)",
  247. "SEGMENT(17 0,17 3)", strategy_ps),
  248. strategy_sb, true, false, false);
  249. tester::apply("pb3", polygon, "BOX(17 0,20 1)",
  250. pp_distance<Point>("POINT(17 1)", "POINT(13 1)", strategy_pp),
  251. strategy_sb, true, false, false);
  252. tester::apply("pb4", polygon, "BOX(12 0,20 1)",
  253. 0, strategy_sb, true, false, false);
  254. // w/ interior ring
  255. std::string const poly_interior = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0),\
  256. (12 1,11 1,12 2,12 1))";
  257. tester::apply("pb5", poly_interior, "BOX(10 10,20 20)",
  258. sb_distance<Point>("SEGMENT(11 2,12 3)",
  259. "BOX(10 10,20 20)", strategy_sb),
  260. strategy_sb, true, false, false);
  261. }
  262. template
  263. <
  264. typename Point,
  265. typename Strategy_pp,
  266. typename Strategy_ps,
  267. typename Strategy_sb
  268. >
  269. void test_distance_multi_polygon_box(Strategy_pp const& strategy_pp,
  270. Strategy_ps const& strategy_ps,
  271. Strategy_sb const& strategy_sb)
  272. {
  273. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  274. std::cout << std::endl;
  275. std::cout << "multi_polygon/box distance tests" << std::endl;
  276. #endif
  277. typedef bg::model::box<Point> box_type;
  278. typedef bg::model::polygon<Point> polygon_type;
  279. typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
  280. typedef test_distance_of_geometries<multi_polygon_type, box_type> tester;
  281. std::string const multi_polygon = "MULTIPOLYGON(((20 20,20 30,30 40,20 20)),\
  282. ((10 10,0 20,15 30,20 15,15 10,10 10)))";
  283. tester::apply("mpb1", multi_polygon, "BOX(0 0,5 5)",
  284. sb_distance<Point>("SEGMENT(10 10,0 20)",
  285. "BOX(0 0,5 5)", strategy_sb),
  286. strategy_sb, true, false, false);
  287. tester::apply("mpb2", multi_polygon, "BOX(27 0,30 16)",
  288. ps_distance<Point>("POINT(20 15)",
  289. "SEGMENT(27 0,27 16)", strategy_ps),
  290. strategy_sb, true, false, false);
  291. tester::apply("mpb3", multi_polygon, "BOX(27 0,30 15)",
  292. pp_distance<Point>("POINT(20 15)",
  293. "POINT(27 15)", strategy_pp),
  294. strategy_sb, true, false, false);
  295. tester::apply("mpb4", multi_polygon, "BOX(17 0,20 14)",
  296. 0, strategy_sb, true, false, false);
  297. }
  298. //===========================================================================
  299. // Cases for relative location of box2 wrt to box1
  300. //
  301. // | |
  302. // 11 | 7 | 4
  303. // | |
  304. // --10---+---------+---3---
  305. // | |
  306. // 9 | 6 | 2
  307. // | |
  308. // -------+---------+-------
  309. // | |
  310. // 8 | 5 | 1
  311. // | |
  312. //
  313. // case 6 includes all possible intersections
  314. // The picture assumes northern hemisphere location
  315. // southern hemisphere picture is mirrored wrt the equator
  316. template
  317. <
  318. typename Point,
  319. typename Strategy_pp,
  320. typename Strategy_ps,
  321. typename Strategy_bb
  322. >
  323. void test_distance_box_box(Strategy_pp const& strategy_pp,
  324. Strategy_ps const& strategy_ps,
  325. Strategy_bb const& strategy_bb)
  326. {
  327. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  328. std::cout << std::endl;
  329. std::cout << "box/box distance tests" << std::endl;
  330. #endif
  331. typedef bg::model::box<Point> box_type;
  332. typedef test_distance_of_geometries<box_type, box_type> tester;
  333. std::string const box1 = "BOX(10 10,20 20)";
  334. // case 1
  335. tester::apply("bb1", box1, "BOX(30 0,40 5)",
  336. pp_distance<Point>("POINT(20 10)", "POINT(30 5)", strategy_pp),
  337. strategy_bb);
  338. // case 2
  339. tester::apply("bb2-a", box1, "BOX(30 12, 40 17)",
  340. ps_distance<Point>("POINT(30 17)",
  341. "SEGMENT(20 10,20 20)", strategy_ps),
  342. strategy_bb);
  343. tester::apply("bb2-b", box1, "BOX(30 10, 40 17)",
  344. ps_distance<Point>("POINT(30 17)",
  345. "SEGMENT(20 10,20 20)", strategy_ps),
  346. strategy_bb);
  347. tester::apply("bb2-c", box1, "BOX(30 8, 40 17)",
  348. ps_distance<Point>("POINT(30 17)",
  349. "SEGMENT(20 10,20 20)", strategy_ps),
  350. strategy_bb);
  351. // case 3
  352. tester::apply("bb3-a", box1, "BOX(30 15, 40 25)",
  353. ps_distance<Point>("POINT(20 20)",
  354. "SEGMENT(30 15,30 25)", strategy_ps),
  355. strategy_bb);
  356. tester::apply("bb3-b", box1, "BOX(30 20, 40 40)",
  357. ps_distance<Point>("POINT(20 20)",
  358. "SEGMENT(30 20,30 40)", strategy_ps),
  359. strategy_bb);
  360. // case 4
  361. tester::apply("bb4", box1, "BOX(30 25, 40 40)",
  362. pp_distance<Point>("POINT(20 20)",
  363. "POINT(30 25)", strategy_pp),
  364. strategy_bb);
  365. // case 5
  366. tester::apply("bb5", box1, "BOX(12 2, 17 7)",
  367. pp_distance<Point>("POINT(17 7)", "POINT(17 10)", strategy_pp),
  368. strategy_bb);
  369. // case 6, boxes intersect thus distance is 0
  370. tester::apply("bb6-a", box1, "BOX(12 2, 17 10)",
  371. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  372. strategy_bb);
  373. tester::apply("bb6-b", box1, "BOX(12 2, 17 17)",
  374. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  375. strategy_bb);
  376. tester::apply("bb6-c", box1, "BOX(20 2, 30 10)",
  377. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  378. strategy_bb);
  379. tester::apply("bb6-d", box1, "BOX(20 11, 30 15)",
  380. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  381. strategy_bb);
  382. tester::apply("bb6-e", box1, "BOX(20 20, 30 30)",
  383. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  384. strategy_bb);
  385. tester::apply("bb6-f", box1, "BOX(15 20, 17 30)",
  386. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  387. strategy_bb);
  388. tester::apply("bb6-g", box1, "BOX(8 20, 10 25)",
  389. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  390. strategy_bb);
  391. tester::apply("bb6-h", box1, "BOX(8 15 , 10 17)",
  392. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  393. strategy_bb);
  394. tester::apply("bb6-i", box1, "BOX(8 8, 10 10)",
  395. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  396. strategy_bb);
  397. tester::apply("bb6-j", box1, "BOX(15 8, 17 10)",
  398. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  399. strategy_bb);
  400. // case 7
  401. tester::apply("bb7", box1, "BOX(12 22, 17 27)",
  402. pp_distance<Point>("POINT(17 20)",
  403. "POINT(17 22)", strategy_pp),
  404. strategy_bb);
  405. // case 8
  406. tester::apply("bb8", box1, "BOX(4 4, 8 8)",
  407. pp_distance<Point>("POINT(8 8)", "POINT(10 10)", strategy_pp),
  408. strategy_bb);
  409. // case 9
  410. tester::apply("bb9-a", box1, "BOX(4 14, 8 18)",
  411. ps_distance<Point>("POINT(8 18)",
  412. "SEGMENT(10 10, 10 20)", strategy_ps),
  413. strategy_bb);
  414. tester::apply("bb9-b", box1, "BOX(4 10, 8 18)",
  415. ps_distance<Point>("POINT(8 18)",
  416. "SEGMENT(10 10, 10 20)", strategy_ps),
  417. strategy_bb);
  418. tester::apply("bb9-c", box1, "BOX(4 8, 8 18)",
  419. ps_distance<Point>("POINT(8 18)",
  420. "SEGMENT(10 10, 10 20)", strategy_ps),
  421. strategy_bb);
  422. // case 10
  423. tester::apply("bb10a", box1, "BOX(4 18, 8 22)",
  424. ps_distance<Point>("POINT(10 20)",
  425. "SEGMENT(8 18, 8 22)", strategy_ps),
  426. strategy_bb);
  427. std::string const box1m = "BOX(10 -20,20 -10)";
  428. tester::apply("bb10am", box1m, "BOX(4 -22, 8 -18)",
  429. ps_distance<Point>("POINT(10 20)",
  430. "SEGMENT(8 18, 8 22)", strategy_ps),
  431. strategy_bb);
  432. tester::apply("bb10b", box1, "BOX(4 20, 8 22)",
  433. ps_distance<Point>("POINT(10 20)",
  434. "SEGMENT(8 20, 8 22)", strategy_ps),
  435. strategy_bb);
  436. tester::apply("bb10bm", box1m, "BOX(4 -22, 8 -20)",
  437. ps_distance<Point>("POINT(10 20)",
  438. "SEGMENT(8 22, 8 20)", strategy_ps),
  439. strategy_bb);
  440. // case 11
  441. tester::apply("bb11", box1, "BOX(4 22, 8 24)",
  442. pp_distance<Point>("POINT(8 22)", "POINT(10 20)", strategy_pp),
  443. strategy_bb);
  444. // far away boxes
  445. tester::apply("bb-far", "BOX(150 15, 170 25)", box1,
  446. ps_distance<Point>("POINT(20 20)",
  447. "SEGMENT(150 15, 150 25)", strategy_ps),
  448. strategy_bb);
  449. // crosses antimeridian
  450. tester::apply("bb-anti1", "BOX(170 15, -160 25)", box1,
  451. ps_distance<Point>("POINT(20 20)",
  452. "SEGMENT(170 15, 170 25)", strategy_ps),
  453. strategy_bb);
  454. tester::apply("bb-anti2", "BOX(170 15, -160 25)", "BOX(160 10, -170 20)",
  455. pp_distance<Point>("POINT(20 20)",
  456. "POINT(20 20)", strategy_pp),
  457. strategy_bb);
  458. tester::apply("bb-anti3", "BOX(170 15, -160 25)", "BOX(160 10, 170 20)",
  459. pp_distance<Point>("POINT(20 20)",
  460. "POINT(20 20)", strategy_pp),
  461. strategy_bb);
  462. tester::apply("bb-anti4", "BOX(170 10, -160 20)", "BOX(160 30, -170 40)",
  463. pp_distance<Point>("POINT(180 20)",
  464. "POINT(180 30)", strategy_pp),
  465. strategy_bb);
  466. // South hemisphere
  467. tester::apply("bb-south1", "BOX(10 -20, 20 -10)", "BOX(30 -15, 40 -12)",
  468. ps_distance<Point>("POINT(30 -15)",
  469. "SEGMENT(20 -10, 20 -20)", strategy_ps),
  470. strategy_bb);
  471. tester::apply("bb-south2", "BOX(10 -20, 20 -10)", "BOX(30 -30, 40 -25)",
  472. pp_distance<Point>("POINT(30 -25)",
  473. "POINT(20 -20)", strategy_pp),
  474. strategy_bb);
  475. tester::apply("bb-south3", "BOX(10 -20, 20 -10)", "BOX(30 -25, 40 -15)",
  476. ps_distance<Point>("POINT(20 -20)",
  477. "SEGMENT(30 -15, 30 -25)", strategy_ps),
  478. strategy_bb);
  479. tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -30, 30 -25)",
  480. pp_distance<Point>("POINT(10 -25)",
  481. "POINT(10 -20)", strategy_pp),
  482. strategy_bb);
  483. tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -7, 30 -5)",
  484. pp_distance<Point>("POINT(10 -7)",
  485. "POINT(10 -10)", strategy_pp),
  486. strategy_bb);
  487. // Crosses equator
  488. tester::apply("bb-eq1", "BOX(30 -15, 40 30)", "BOX(10 -20, 20 25)",
  489. ps_distance<Point>("POINT(20 25)",
  490. "SEGMENT(30 -15, 30 30)", strategy_ps),
  491. strategy_bb);
  492. tester::apply("bb-eq1b", "BOX(30 -15, 40 30)", "BOX(10 -20, 20 10)",
  493. ps_distance<Point>("POINT(30 -15)",
  494. "SEGMENT(20 10, 20 -20)", strategy_ps),
  495. strategy_bb);
  496. tester::apply("bb-eq1bm", "BOX(30 -30, 40 15)", "BOX(10 -10, 20 20)",
  497. ps_distance<Point>("POINT(30 15)",
  498. "SEGMENT(20 -10, 20 20)", strategy_ps),
  499. strategy_bb);
  500. tester::apply("bb-eq2", "BOX(30 -15, 40 20)", "BOX(10 -20, 20 25)",
  501. ps_distance<Point>("POINT(30 20)",
  502. "SEGMENT(20 -20, 20 25)", strategy_ps),
  503. strategy_bb);
  504. tester::apply("bb-eq3", "BOX(30 5, 40 20)", "BOX(10 -20, 20 25)",
  505. ps_distance<Point>("POINT(30 20)",
  506. "SEGMENT(20 -20, 20 25)", strategy_ps),
  507. strategy_bb);
  508. tester::apply("bb-eq4", "BOX(5 -30, 40 -25)", "BOX(10 -20, 20 25)",
  509. pp_distance<Point>("POINT(10 -25)",
  510. "POINT(10 -20)", strategy_pp),
  511. strategy_bb);
  512. tester::apply("bb-eq5", "BOX(30 5, 40 20)", "BOX(10 -20, 50 25)",
  513. pp_distance<Point>("POINT(30 20)",
  514. "POINT(30 20)", strategy_pp),
  515. strategy_bb);
  516. tester::apply("bb-eq6", "BOX(30 5, 40 20)", "BOX(10 -20, 35 25)",
  517. pp_distance<Point>("POINT(30 20)",
  518. "POINT(30 20)", strategy_pp),
  519. strategy_bb);
  520. // One box in the north and one in the south hemisphere
  521. tester::apply("bb-ns1", "BOX(30 15, 40 20)", "BOX(10 -20, 20 -15)",
  522. pp_distance<Point>("POINT(30 15)",
  523. "POINT(20 -15)", strategy_pp),
  524. strategy_bb);
  525. tester::apply("bb-ns2", "BOX(30 15, 40 20)", "BOX(25 -20, 50 -15)",
  526. pp_distance<Point>("POINT(30 15)",
  527. "POINT(30 -15)", strategy_pp),
  528. strategy_bb);
  529. //negative coordinates
  530. std::string const box1neg = "BOX(-20 10,-10 20)";
  531. // case 1
  532. tester::apply("bb1", box1neg, "BOX(-40 0,-30 5)",
  533. pp_distance<Point>("POINT(-20 10)",
  534. "POINT(-30 5)", strategy_pp),
  535. strategy_bb);
  536. // case 2
  537. tester::apply("bb2-a", box1neg, "BOX(-40 12, -30 17)",
  538. ps_distance<Point>("POINT(-30 17)",
  539. "SEGMENT(-20 10,-20 20)", strategy_ps),
  540. strategy_bb);
  541. tester::apply("bb2-b", box1neg, "BOX(-40 10, -30 17)",
  542. ps_distance<Point>("POINT(-30 17)",
  543. "SEGMENT(-20 10,-20 20)", strategy_ps),
  544. strategy_bb);
  545. tester::apply("bb2-c", box1neg, "BOX(-40 8, -30 17)",
  546. ps_distance<Point>("POINT(-30 17)",
  547. "SEGMENT(-20 10,-20 20)", strategy_ps),
  548. strategy_bb);
  549. // case 3
  550. tester::apply("bb3-a", box1neg, "BOX(-40 15, -30 25)",
  551. ps_distance<Point>("POINT(-20 20)",
  552. "SEGMENT(-30 15,-30 25)", strategy_ps),
  553. strategy_bb);
  554. tester::apply("bb3-b", box1neg, "BOX(-40 20, -30 40)",
  555. ps_distance<Point>("POINT(-20 20)",
  556. "SEGMENT(-30 20,-30 40)", strategy_ps),
  557. strategy_bb);
  558. // case 4
  559. tester::apply("bb4", box1neg, "BOX(-40 25, -30 40)",
  560. pp_distance<Point>("POINT(-20 20)",
  561. "POINT(-30 25)", strategy_pp),
  562. strategy_bb);
  563. // case 5
  564. tester::apply("bb5", box1neg, "BOX(-17 2,-12 7)",
  565. pp_distance<Point>("POINT(-17 7)",
  566. "POINT(-17 10)", strategy_pp),
  567. strategy_bb);
  568. // case 6, boxes intersect thus distance is 0
  569. tester::apply("bb6-a", box1neg, "BOX(-17 2, -12 10)",
  570. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  571. strategy_bb);
  572. tester::apply("bb6-b", box1neg, "BOX(-17 2, -12 17)",
  573. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  574. strategy_bb);
  575. tester::apply("bb6-c", box1neg, "BOX(-30 2, -20 10)",
  576. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  577. strategy_bb);
  578. tester::apply("bb6-d", box1neg, "BOX(-30 11, -20 15)",
  579. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  580. strategy_bb);
  581. tester::apply("bb6-e", box1neg, "BOX(-30 20, -20 30)",
  582. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  583. strategy_bb);
  584. tester::apply("bb6-f", box1neg, "BOX(-17 20, -15 30)",
  585. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  586. strategy_bb);
  587. tester::apply("bb6-g", box1neg, "BOX(-10 20, -8 25)",
  588. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  589. strategy_bb);
  590. tester::apply("bb6-h", box1neg, "BOX(-10 15 , -8 17)",
  591. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  592. strategy_bb);
  593. tester::apply("bb6-i", box1neg, "BOX(-10 8, -8 10)",
  594. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  595. strategy_bb);
  596. tester::apply("bb6-j", box1neg, "BOX(-17 8, -15 10)",
  597. pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
  598. strategy_bb);
  599. // case 7
  600. tester::apply("bb7", box1neg, "BOX(-17 22, -12 27)",
  601. pp_distance<Point>("POINT(-17 20)",
  602. "POINT(-17 22)", strategy_pp),
  603. strategy_bb);
  604. // case 8
  605. tester::apply("bb8", box1neg, "BOX(-8 4, -4 8)",
  606. pp_distance<Point>("POINT(-8 8)",
  607. "POINT(-10 10)", strategy_pp),
  608. strategy_bb);
  609. // case 9
  610. tester::apply("bb9-a", box1neg, "BOX(-8 14, -4 18)",
  611. ps_distance<Point>("POINT(-8 18)",
  612. "SEGMENT(-10 10, -10 20)", strategy_ps),
  613. strategy_bb);
  614. tester::apply("bb9-b", box1neg, "BOX(-8 10, -4 18)",
  615. ps_distance<Point>("POINT(-8 18)",
  616. "SEGMENT(-10 10, -10 20)", strategy_ps),
  617. strategy_bb);
  618. tester::apply("bb9-c", box1neg, "BOX(-8 8, -4 18)",
  619. ps_distance<Point>("POINT(-8 18)",
  620. "SEGMENT(-10 10, -10 20)", strategy_ps),
  621. strategy_bb);
  622. // case 10
  623. tester::apply("bb10", box1neg, "BOX(-8 18, -4 22)",
  624. ps_distance<Point>("POINT(-10 20)",
  625. "SEGMENT(-8 18, -8 22)", strategy_ps),
  626. strategy_bb);
  627. tester::apply("bb10", box1neg, "BOX(-8 20, -4 22)",
  628. ps_distance<Point>("POINT(-10 20)",
  629. "SEGMENT(-8 20, -8 22)", strategy_ps),
  630. strategy_bb);
  631. // case 11
  632. tester::apply("bb11", box1neg, "BOX(-8 22, -4 24)",
  633. pp_distance<Point>("POINT(-8 22)",
  634. "POINT(-10 20)", strategy_pp),
  635. strategy_bb);
  636. //Degenerate cases
  637. //1st box degenerates to a meridian segment
  638. std::string const box1deg = "BOX(0 10,0 20)";
  639. //2nd box generic
  640. tester::apply("pbd1", box1deg, "BOX(1 15, 2 25)",
  641. ps_distance<Point>("POINT(0 20)",
  642. "SEGMENT(1 15, 1 25)", strategy_ps),
  643. strategy_bb);
  644. //2nd box degenerates to a meridian segment
  645. tester::apply("pbd2", box1deg, "BOX(1 15, 1 25)",
  646. ps_distance<Point>("POINT(0 20)",
  647. "SEGMENT(1 15, 1 25)", strategy_ps),
  648. strategy_bb);
  649. //2nd box degenerates to a horizontal line
  650. //test fails for thomas strategy; test only for andoyer
  651. tester::apply("pbd3", box1deg, "BOX(1 15, 2 15)",
  652. pp_distance<Point>("POINT(1 15)",
  653. "POINT(0 15)", andoyer_pp()),
  654. andoyer_bb());
  655. //2nd box degenerates to a point
  656. tester::apply("pbd4", box1deg, "BOX(1 15, 1 15)",
  657. ps_distance<Point>("POINT(1 15)",
  658. "SEGMENT(0 10, 0 20)", strategy_ps),
  659. strategy_bb);
  660. //---
  661. //1st box degenerates to a horizontal line; that is not a geodesic segment
  662. std::string const box2deg = "BOX(10 10,20 10)";
  663. //2nd box generic
  664. tester::apply("pbd5", box2deg, "BOX(15 15, 25 20)",
  665. pp_distance<Point>("POINT(15 15)",
  666. "POINT(15 10)", strategy_pp),
  667. strategy_bb);
  668. //2nd box degenerates to a horizontal line
  669. tester::apply("pbd6", box2deg, "BOX(15 15, 25 15)",
  670. pp_distance<Point>("POINT(15 15)",
  671. "POINT(15 10)", strategy_pp),
  672. strategy_bb);
  673. //2nd box degenerates to a point
  674. tester::apply("pbd7", box2deg, "BOX(15 15, 15 15)",
  675. pp_distance<Point>("POINT(15 15)",
  676. "POINT(15 10)", strategy_pp),
  677. strategy_bb);
  678. //---
  679. //1st box degenerates to a point
  680. std::string const box3deg = "BOX(0 6,0 6)";
  681. //2nd box generic
  682. tester::apply("pbd8", box3deg, "BOX(15 15, 25 20)",
  683. ps_distance<Point>("POINT(0 6)",
  684. "SEGMENT(15 15, 15 20)", strategy_ps),
  685. strategy_bb);
  686. //2nd box degenerates to a point
  687. tester::apply("pbd9", box3deg, "BOX(15 15, 15 15)",
  688. pp_distance<Point>("POINT(0 6)",
  689. "POINT(15 15)", strategy_pp),
  690. strategy_bb);
  691. }
  692. //===========================================================================
  693. template
  694. <
  695. typename Point,
  696. typename Strategy_pp,
  697. typename Strategy_ps,
  698. typename Strategy_bb,
  699. typename Strategy_sb
  700. >
  701. void test_all_ar_ar(Strategy_pp pp_strategy,
  702. Strategy_ps ps_strategy,
  703. Strategy_bb bb_strategy,
  704. Strategy_sb sb_strategy)
  705. {
  706. test_distance_ring_ring<Point>(pp_strategy, ps_strategy);
  707. test_distance_ring_polygon<Point>(pp_strategy, ps_strategy);
  708. test_distance_polygon_polygon<Point>(pp_strategy, ps_strategy);
  709. test_distance_ring_multi_polygon<Point>(pp_strategy, ps_strategy);
  710. test_distance_polygon_multi_polygon<Point>(pp_strategy, ps_strategy);
  711. test_distance_multi_polygon_multi_polygon<Point>(pp_strategy, ps_strategy);
  712. test_distance_polygon_box<Point>(pp_strategy, ps_strategy, sb_strategy);
  713. test_distance_multi_polygon_box<Point>(pp_strategy, ps_strategy, sb_strategy);
  714. test_distance_ring_box<Point>(pp_strategy, ps_strategy, sb_strategy);
  715. test_distance_box_box<Point>(pp_strategy, ps_strategy, bb_strategy);
  716. test_more_empty_input_areal_areal<Point>(ps_strategy);
  717. }
  718. BOOST_AUTO_TEST_CASE( test_all_areal_areal )
  719. {
  720. typedef bg::model::point
  721. <
  722. double, 2,
  723. bg::cs::spherical_equatorial<bg::degree>
  724. > sph_point;
  725. test_all_ar_ar<sph_point>(spherical_pp(), spherical_ps(), spherical_bb(), spherical_sb());
  726. typedef bg::model::point
  727. <
  728. double, 2,
  729. bg::cs::geographic<bg::degree>
  730. > geo_point;
  731. test_all_ar_ar<geo_point>(vincenty_pp(), vincenty_ps(), vincenty_bb(), vincenty_sb());
  732. test_all_ar_ar<geo_point>(thomas_pp(), thomas_ps(), thomas_bb(), thomas_sb());
  733. test_all_ar_ar<geo_point>(andoyer_pp(), andoyer_ps(), andoyer_bb(), andoyer_sb());
  734. // test with different spheroid
  735. stype spheroid(6372000, 6370000);
  736. test_all_ar_ar<geo_point>(andoyer_pp(spheroid), andoyer_ps(spheroid),
  737. andoyer_bb(spheroid), andoyer_sb(spheroid));
  738. }