intersection.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  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. // This file was modified by Oracle on 2015, 2016, 2017.
  7. // Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
  8. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  9. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  10. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  11. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  12. // Use, modification and distribution is subject to the Boost Software License,
  13. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  14. // http://www.boost.org/LICENSE_1_0.txt)
  15. #include <climits>
  16. #include <iostream>
  17. #include <string>
  18. #include <boost/config.hpp>
  19. #include <boost/core/ignore_unused.hpp>
  20. #include <boost/geometry/geometries/point_xy.hpp>
  21. #include <boost/geometry/geometries/register/linestring.hpp>
  22. #include <boost/geometry/util/condition.hpp>
  23. #include <boost/geometry/util/rational.hpp>
  24. #include "test_intersection.hpp"
  25. #include <algorithms/test_overlay.hpp>
  26. #include <algorithms/overlay/overlay_cases.hpp>
  27. #include <test_common/test_point.hpp>
  28. #include <test_common/with_pointer.hpp>
  29. #include <test_geometries/custom_segment.hpp>
  30. BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(std::vector)
  31. #define TEST_INTERSECTION(caseid, clips, points, area) \
  32. (test_one<Polygon, Polygon, Polygon>) \
  33. ( #caseid, caseid[0], caseid[1], clips, points, area)
  34. #define TEST_INTERSECTION_REV(caseid, clips, points, area) \
  35. (test_one<Polygon, Polygon, Polygon>) \
  36. ( #caseid "_rev", caseid[1], caseid[0], clips, points, area)
  37. #define TEST_INTERSECTION_WITH(caseid, index1, index2, \
  38. clips, points, area, settings) \
  39. (test_one<Polygon, Polygon, Polygon>) \
  40. ( #caseid "_" #index1 "_" #index2, caseid[index1], caseid[index2], \
  41. clips, points, area, settings)
  42. template <typename Polygon>
  43. void test_areal()
  44. {
  45. typedef typename bg::coordinate_type<Polygon>::type ct;
  46. bool const ccw = bg::point_order<Polygon>::value == bg::counterclockwise;
  47. bool const open = bg::closure<Polygon>::value == bg::open;
  48. test_one<Polygon, Polygon, Polygon>("simplex_with_empty_1",
  49. simplex_normal[0], polygon_empty,
  50. 0, 0, 0.0);
  51. test_one<Polygon, Polygon, Polygon>("simplex_with_empty_2",
  52. polygon_empty, simplex_normal[0],
  53. 0, 0, 0.0);
  54. test_one<Polygon, Polygon, Polygon>("simplex_normal",
  55. simplex_normal[0], simplex_normal[1],
  56. 1, 7, 5.47363293);
  57. test_one<Polygon, Polygon, Polygon>("star_ring", example_star, example_ring,
  58. 1, 18, 2.80983);
  59. test_one<Polygon, Polygon, Polygon>("star_poly", example_star, example_polygon,
  60. 1, 0, // CLN: 23 points, other types: 22 point (one is merged)
  61. 2.5020508);
  62. test_one<Polygon, Polygon, Polygon>("first_within_second1",
  63. first_within_second[0], first_within_second[1],
  64. 1, 5, 1.0);
  65. test_one<Polygon, Polygon, Polygon>("first_within_second2",
  66. first_within_second[1], first_within_second[0],
  67. 1, 5, 1.0);
  68. test_one<Polygon, Polygon, Polygon>("first_within_hole_of_second",
  69. first_within_hole_of_second[0], first_within_hole_of_second[1],
  70. 0, 0, 0.0);
  71. // Two forming new hole
  72. test_one<Polygon, Polygon, Polygon>("new_hole",
  73. new_hole[0], new_hole[1],
  74. 2, 10, 2.0);
  75. // Two identical
  76. test_one<Polygon, Polygon, Polygon>("identical",
  77. identical[0], identical[1],
  78. 1, 5, 1.0);
  79. test_one<Polygon, Polygon, Polygon>("intersect_exterior_and_interiors_winded",
  80. intersect_exterior_and_interiors_winded[0], intersect_exterior_and_interiors_winded[1],
  81. 1, 14, 25.2166667);
  82. test_one<Polygon, Polygon, Polygon>("intersect_holes_disjoint",
  83. intersect_holes_disjoint[0], intersect_holes_disjoint[1],
  84. 1, 15, 18.0);
  85. test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect",
  86. intersect_holes_intersect[0], intersect_holes_intersect[1],
  87. 1, 14, 18.25);
  88. test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect_and_disjoint",
  89. intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1],
  90. 1, 19, 17.25);
  91. test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect_and_touch",
  92. intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1],
  93. 1, 23, 17.25);
  94. test_one<Polygon, Polygon, Polygon>("intersect_holes_new_ring",
  95. intersect_holes_new_ring[0], intersect_holes_new_ring[1],
  96. 2, 23, 122.1039);
  97. test_one<Polygon, Polygon, Polygon>("winded",
  98. winded[0], winded[1],
  99. 1, 22, 40.0);
  100. test_one<Polygon, Polygon, Polygon>("within_holes_disjoint",
  101. within_holes_disjoint[0], within_holes_disjoint[1],
  102. 1, 15, 23.0);
  103. test_one<Polygon, Polygon, Polygon>("side_side",
  104. side_side[0], side_side[1],
  105. 0, 0, 0.0);
  106. test_one<Polygon, Polygon, Polygon>("two_bends",
  107. two_bends[0], two_bends[1],
  108. 1, 7, 24.0);
  109. test_one<Polygon, Polygon, Polygon>("star_comb_15",
  110. star_comb_15[0], star_comb_15[1],
  111. 28, 150, 189.952883);
  112. test_one<Polygon, Polygon, Polygon>("simplex_normal",
  113. simplex_normal[0], simplex_normal[1],
  114. 1, 7, 5.47363293);
  115. test_one<Polygon, Polygon, Polygon>("distance_zero",
  116. distance_zero[0], distance_zero[1],
  117. 1, 0 /* f: 4, other: 5 */, 0.29516139, ut_settings(0.01));
  118. test_one<Polygon, Polygon, Polygon>("equal_holes_disjoint",
  119. equal_holes_disjoint[0], equal_holes_disjoint[1],
  120. 1, 20, 81.0 - 2.0 * 3.0 * 3.0 - 3.0 * 7.0);
  121. test_one<Polygon, Polygon, Polygon>("only_hole_intersections1",
  122. only_hole_intersections[0], only_hole_intersections[1],
  123. 1, 21, 178.090909);
  124. test_one<Polygon, Polygon, Polygon>("only_hole_intersection2",
  125. only_hole_intersections[0], only_hole_intersections[2],
  126. 1, 21, 149.090909);
  127. test_one<Polygon, Polygon, Polygon>("fitting",
  128. fitting[0], fitting[1],
  129. 0, 0, 0.0);
  130. test_one<Polygon, Polygon, Polygon>("crossed",
  131. crossed[0], crossed[1],
  132. 3, 0, 1.5);
  133. test_one<Polygon, Polygon, Polygon>("pie_2_3_23_0",
  134. pie_2_3_23_0[0], pie_2_3_23_0[1],
  135. 1, 4, 163292.679042133, ut_settings(0.1));
  136. {
  137. ut_settings settings(if_typed_tt<ct>(0.01, 0.1));
  138. settings.test_validity = BG_IF_RESCALED(true, false);
  139. // SQL Server gives: 88.1920416352664
  140. // PostGIS gives: 88.19203677911
  141. test_one<Polygon, Polygon, Polygon>("isovist",
  142. isovist1[0], isovist1[1],
  143. 1, 19, 88.192037,
  144. settings);
  145. }
  146. if (! BOOST_GEOMETRY_CONDITION((boost::is_same<ct, float>::value)) )
  147. {
  148. test_one<Polygon, Polygon, Polygon>("geos_1",
  149. geos_1[0], geos_1[1],
  150. 1, -1, BG_IF_RESCALED(3461.12321694, BG_IF_KRAMER(3461.02336, 3461.105448)), // MSVC 14 reports 3461.025390625
  151. ut_settings(0.01, false));
  152. }
  153. // Expectations:
  154. // In most cases: 0 (no intersection)
  155. // In some cases: 1.430511474609375e-05 (clang/gcc on Xubuntu using b2)
  156. // In some cases: 5.6022983000000002e-05 (powerpc64le-gcc-6-0)
  157. test_one<Polygon, Polygon, Polygon>("geos_2", geos_2[0], geos_2[1],
  158. 0, 0, 6.0e-5, ut_settings(-1.0)); // -1 denotes: compare with <=
  159. test_one<Polygon, Polygon, Polygon>("geos_3",
  160. geos_3[0], geos_3[1],
  161. 0, 0, 0.0);
  162. test_one<Polygon, Polygon, Polygon>("geos_4",
  163. geos_4[0], geos_4[1],
  164. 1, -1, 0.08368849, ut_settings(0.01));
  165. if ( BOOST_GEOMETRY_CONDITION(! ccw && open) )
  166. {
  167. // Pointcount for ttmath/double (both 5) or float (4)
  168. // double returns 5 (since method append_no_dups_or_spikes)
  169. // but not for ccw/open. Those cases has to be adapted once, anyway,
  170. // because for open always one point too much is generated...
  171. test_one<Polygon, Polygon, Polygon>("ggl_list_20110306_javier",
  172. ggl_list_20110306_javier[0], ggl_list_20110306_javier[1],
  173. 1, if_typed<ct, float>(4, 5),
  174. 0.6649875,
  175. ut_settings(if_typed<ct, float>(1.0, 0.01)));
  176. }
  177. // SQL Server reports: 0.400390625
  178. // PostGIS reports 0.4
  179. // BG did report 0.4 but with rescaling 0.397
  180. // when selecting other IP closer at endpoint or if segment B is smaller than A
  181. test_one<Polygon, Polygon, Polygon>("ggl_list_20110307_javier",
  182. ggl_list_20110307_javier[0], ggl_list_20110307_javier[1],
  183. 1, 4, BG_IF_RESCALED(0.397162651, 0.40), ut_settings(0.01));
  184. test_one<Polygon, Polygon, Polygon>("ggl_list_20110627_phillip",
  185. ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
  186. 1, if_typed_tt<ct>(6, 5), 11151.6618);
  187. test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
  188. ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
  189. 3, 16, 35723.8506317139);
  190. test_one<Polygon, Polygon, Polygon>("ggl_list_20131119_james",
  191. ggl_list_20131119_james[0], ggl_list_20131119_james[1],
  192. 1, 4, 6.6125873045, ut_settings(0.1));
  193. test_one<Polygon, Polygon, Polygon>("ggl_list_20140223_shalabuda",
  194. ggl_list_20140223_shalabuda[0], ggl_list_20140223_shalabuda[1],
  195. 1, 4, 3.77106, ut_settings(0.001));
  196. // Mailed to the Boost.Geometry list on 2014/03/21 by 7415963@gmail.com
  197. test_one<Polygon, Polygon, Polygon>("ggl_list_20140321_7415963",
  198. ggl_list_20140321_7415963[0], ggl_list_20140321_7415963[1],
  199. 0, 0, 0, ut_settings(0.1));
  200. TEST_INTERSECTION(ggl_list_20190307_matthieu_1, 2, -1, 0.035136);
  201. TEST_INTERSECTION(ggl_list_20190307_matthieu_2, 1, -1, 3.64285);
  202. #if defined(BOOST_GEOMETRY_USE_RESCALING) || ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  203. test_one<Polygon, Polygon, Polygon>("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1],
  204. 1, 4, 0.00029437899183903937, ut_settings(0.01));
  205. #endif
  206. test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
  207. 1, 0, 2.914213562373);
  208. test_one<Polygon, Polygon, Polygon>("ticket_8254", ticket_8254[0], ticket_8254[1],
  209. if_typed<ct, float>(0, 1), -1, if_typed<ct, float>(0.0, 3.635930e-08), ut_settings(0.01));
  210. test_one<Polygon, Polygon, Polygon>("ticket_6958", ticket_6958[0], ticket_6958[1],
  211. if_typed<ct, float>(0, 1), -1, if_typed<ct, float>(0.0, 4.34355e-05), ut_settings(0.01));
  212. test_one<Polygon, Polygon, Polygon>("ticket_8652", ticket_8652[0], ticket_8652[1],
  213. 1, 4, 0.0003);
  214. TEST_INTERSECTION(ticket_8310a, 1, 5, 0.3843747);
  215. TEST_INTERSECTION(ticket_8310b, 1, 5, 0.3734379);
  216. TEST_INTERSECTION(ticket_8310c, 1, 5, 0.4689541);
  217. TEST_INTERSECTION_REV(ticket_8310a, 1, 5, 0.3843747);
  218. TEST_INTERSECTION_REV(ticket_8310b, 1, 5, 0.3734379);
  219. TEST_INTERSECTION_REV(ticket_8310c, 1, 5, 0.4689541);
  220. test_one<Polygon, Polygon, Polygon>("ticket_9081_15",
  221. ticket_9081_15[0], ticket_9081_15[1],
  222. 1, 4, 0.0068895780745301394);
  223. test_one<Polygon, Polygon, Polygon>("ticket_10108_a",
  224. ticket_10108_a[0], ticket_10108_a[1],
  225. 0, 0, 0.0);
  226. // msvc 5.6023011e-5
  227. // mingw 5.6022954e-5
  228. test_one<Polygon, Polygon, Polygon>("ticket_10108_b",
  229. ticket_10108_b[0], ticket_10108_b[1],
  230. 0, 0, 5.6022983e-5, ut_settings(-1.0));
  231. test_one<Polygon, Polygon, Polygon>("ticket_10747_a",
  232. ticket_10747_a[0], ticket_10747_a[1],
  233. 1, 4, 70368744177664.0);
  234. test_one<Polygon, Polygon, Polygon>("ticket_10747_b",
  235. ticket_10747_b[0], ticket_10747_b[1],
  236. 1, 4, 7036874417766400.0);
  237. test_one<Polygon, Polygon, Polygon>("ticket_10747_c",
  238. ticket_10747_c[0], ticket_10747_c[1],
  239. 1, 4, 17592186044416.0);
  240. test_one<Polygon, Polygon, Polygon>("ticket_10747_d",
  241. ticket_10747_d[0], ticket_10747_d[1],
  242. 1, 4, 703687777321.0);
  243. // Delivers very small triangle < 1.0e-13, or zero
  244. test_one<Polygon, Polygon, Polygon>("ticket_10747_e",
  245. ticket_10747_e[0], ticket_10747_e[1],
  246. BG_IF_RESCALED(1, 0), -1, 1.0e-13, ut_settings(-1.0));
  247. test_one<Polygon, Polygon, Polygon>("ticket_11576",
  248. ticket_11576[0], ticket_11576[1],
  249. if_typed<ct, float>(0, 1), -1, if_typed<ct, float>(0.0, 5.585617332907136e-07));
  250. {
  251. // Not yet valid when rescaling is turned off
  252. ut_settings settings;
  253. settings.test_validity = BG_IF_RESCALED(true, false);
  254. test_one<Polygon, Polygon, Polygon>("ticket_9563", ticket_9563[0], ticket_9563[1],
  255. 1, 8, 129.90381, settings);
  256. }
  257. #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  258. // With rescaling the output is empty
  259. TEST_INTERSECTION(issue_548, 1, -1, 1958824415.2151);
  260. #endif
  261. TEST_INTERSECTION(issue_566_a, 1, -1, 70.7107);
  262. TEST_INTERSECTION(issue_566_b, 1, -1, 70.7107);
  263. test_one<Polygon, Polygon, Polygon>("buffer_mp1", buffer_mp1[0], buffer_mp1[1],
  264. 1, 31, 2.271707796);
  265. test_one<Polygon, Polygon, Polygon>("buffer_mp2", buffer_mp2[0], buffer_mp2[1],
  266. 1, 29, 0.457126);
  267. test_one<Polygon, Polygon, Polygon>("case_58_iet",
  268. case_58[0], case_58[2],
  269. 2, -1, 1.0 / 3.0);
  270. test_one<Polygon, Polygon, Polygon>("case_80",
  271. case_80[0], case_80[1],
  272. 0, -1, 0.0);
  273. test_one<Polygon, Polygon, Polygon>("case_81",
  274. case_81[0], case_81[1],
  275. 0, -1, 0.0);
  276. test_one<Polygon, Polygon, Polygon>("case_101",
  277. case_101[0], case_101[1],
  278. 0, -1, 6.25);
  279. test_one<Polygon, Polygon, Polygon>("case_102",
  280. case_102[0], case_102[1],
  281. 0, -1, 3.1875);
  282. test_one<Polygon, Polygon, Polygon>("case_103",
  283. case_103[0], case_103[1],
  284. 1, -1, 0.5);
  285. test_one<Polygon, Polygon, Polygon>("case_104",
  286. case_104[0], case_104[1],
  287. 0, -1, 0.0);
  288. TEST_INTERSECTION(case_105, 1, 34, 76.0);
  289. TEST_INTERSECTION(case_106, 2, -1, 3.5);
  290. TEST_INTERSECTION(case_107, 3, -1, 3.0);
  291. TEST_INTERSECTION(case_precision_1, 0, 0, 0.0);
  292. TEST_INTERSECTION(case_precision_2, 0, 0, 0.0);
  293. TEST_INTERSECTION(case_precision_3, 0, 0, 0.0);
  294. TEST_INTERSECTION(case_precision_4, 0, 0, 0.0);
  295. TEST_INTERSECTION(case_precision_5, 0, 0, 0.0);
  296. TEST_INTERSECTION(case_precision_6, 1, -1, 14.0);
  297. TEST_INTERSECTION(case_precision_7, 0, -1, 0.0);
  298. TEST_INTERSECTION(case_precision_8, 1, -1, 14.0);
  299. TEST_INTERSECTION(case_precision_9, 1, -1, 14.0);
  300. TEST_INTERSECTION(case_precision_10, 1, -1, 14.0);
  301. TEST_INTERSECTION(case_precision_11, 1, -1, 14.0);
  302. TEST_INTERSECTION(case_precision_12, 1, -1, 2.0);
  303. TEST_INTERSECTION(case_precision_13, 1, -1, 1.99998);
  304. TEST_INTERSECTION(case_precision_14, 0, -1, 0.0);
  305. TEST_INTERSECTION(case_precision_15, 1, -1, 14.0);
  306. TEST_INTERSECTION(case_precision_16, 1, -1, 14.0);
  307. TEST_INTERSECTION(case_precision_17, 1, -1, 14.0);
  308. TEST_INTERSECTION(case_precision_18, 1, -1, 14.0);
  309. TEST_INTERSECTION(case_precision_19, 1, -1, 14.0);
  310. TEST_INTERSECTION(case_precision_20, 0, 0, 0.0);
  311. TEST_INTERSECTION(case_precision_21, 0, 0, 0.0);
  312. TEST_INTERSECTION(case_precision_22, 1, -1, 14.0);
  313. TEST_INTERSECTION(case_precision_23, 1, -1, 14.0);
  314. TEST_INTERSECTION(case_precision_24, 0, 0, 0.0);
  315. TEST_INTERSECTION(case_precision_25, 0, 0, 0.0);
  316. TEST_INTERSECTION(case_precision_26, 1, -1, 14.0);
  317. TEST_INTERSECTION_REV(case_precision_1, 0, 0, 0.0);
  318. TEST_INTERSECTION_REV(case_precision_2, 0, 0, 0.0);
  319. TEST_INTERSECTION_REV(case_precision_3, 0, 0, 0.0);
  320. TEST_INTERSECTION_REV(case_precision_4, 0, 0, 0.0);
  321. TEST_INTERSECTION_REV(case_precision_5, 0, 0, 0.0);
  322. TEST_INTERSECTION_REV(case_precision_6, 1, -1, 14.0);
  323. TEST_INTERSECTION_REV(case_precision_7, 0, -1, 0.0);
  324. TEST_INTERSECTION_REV(case_precision_8, 1, -1, 14.0);
  325. TEST_INTERSECTION_REV(case_precision_9, 1, -1, 14.0);
  326. TEST_INTERSECTION_REV(case_precision_10, 1, -1, 14.0);
  327. TEST_INTERSECTION_REV(case_precision_11, 1, -1, 14.0);
  328. TEST_INTERSECTION_REV(case_precision_12, 1, -1, 2.0);
  329. TEST_INTERSECTION_REV(case_precision_13, 1, -1, 1.99998);
  330. TEST_INTERSECTION_REV(case_precision_14, 0, -1, 0.0);
  331. TEST_INTERSECTION_REV(case_precision_15, 1, -1, 14.0);
  332. TEST_INTERSECTION_REV(case_precision_16, 1, -1, 14.0);
  333. TEST_INTERSECTION_REV(case_precision_17, 1, -1, 14.0);
  334. TEST_INTERSECTION_REV(case_precision_18, 1, -1, 14.0);
  335. TEST_INTERSECTION_REV(case_precision_19, 1, -1, 14.0);
  336. TEST_INTERSECTION_REV(case_precision_20, 0, 0, 0.0);
  337. TEST_INTERSECTION_REV(case_precision_21, 0, 0, 0.0);
  338. TEST_INTERSECTION_REV(case_precision_22, 1, -1, 14.0);
  339. TEST_INTERSECTION_REV(case_precision_23, 1, -1, 14.0);
  340. TEST_INTERSECTION_REV(case_precision_24, 0, 0, 0.0);
  341. TEST_INTERSECTION_REV(case_precision_25, 0, 0, 0.0);
  342. TEST_INTERSECTION_REV(case_precision_26, 1, -1, 14.0);
  343. test_one<Polygon, Polygon, Polygon>("mysql_21964049",
  344. mysql_21964049[0], mysql_21964049[1],
  345. 0, -1, 0.0);
  346. test_one<Polygon, Polygon, Polygon>("mysql_21964465",
  347. mysql_21964465[0], mysql_21964465[1],
  348. 0, -1, 0.0);
  349. test_one<Polygon, Polygon, Polygon>("mysql_21965285_b_inv",
  350. mysql_21965285_b_inv[0],
  351. mysql_21965285_b_inv[1],
  352. 2, -1, 183.71376870369406);
  353. TEST_INTERSECTION(mysql_23023665_6, 2, 0, 11.812440191387557);
  354. test_one<Polygon, Polygon, Polygon>("mysql_23023665_10",
  355. mysql_23023665_10[0], mysql_23023665_10[1],
  356. 1, 0, -1, 54.701340543162523);
  357. test_one<Polygon, Polygon, Polygon>("mysql_23023665_11",
  358. mysql_23023665_11[0], mysql_23023665_11[1],
  359. 1, 0, -1, 35.933385462482065);
  360. // test_one<Polygon, Polygon, Polygon>(
  361. // "polygon_pseudo_line",
  362. // "Polygon((0 0,0 4,4 4,4 0,0 0))",
  363. // "Polygon((2 -2,2 -1,2 6,2 -2))",
  364. // 5, 22, 1.1901714);
  365. }
  366. template <typename Polygon, typename Box>
  367. void test_areal_clip()
  368. {
  369. test_one<Polygon, Box, Polygon>("boxring", example_box, example_ring,
  370. 2, 12, 1.09125);
  371. test_one<Polygon, Polygon, Box>("boxring2", example_ring,example_box,
  372. 2, 12, 1.09125);
  373. test_one<Polygon, Box, Polygon>("boxpoly", example_box, example_polygon,
  374. 3, 19, 0.840166);
  375. test_one<Polygon, Box, Polygon>("poly1", example_box,
  376. "POLYGON((3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2))",
  377. 2, 12, 1.09125);
  378. test_one<Polygon, Box, Polygon>("clip_poly2", example_box,
  379. "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,5.3 2.5,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))",
  380. 2, 12, 1.00375);
  381. test_one<Polygon, Box, Polygon>("clip_poly3", example_box,
  382. "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,4.5 2.5,4.5 1.2,4.9 0.8,2.9 0.7,2 1.3))",
  383. 2, 12, 1.00375);
  384. test_one<Polygon, Box, Polygon>("clip_poly4", example_box,
  385. "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,4.5 2.5,4.5 2.3,5.0 2.3,5.0 2.1,4.5 2.1,4.5 1.9,4.0 1.9,4.5 1.2,4.9 0.8,2.9 0.7,2 1.3))",
  386. 2, 16, 0.860892);
  387. test_one<Polygon, Box, Polygon>("clip_poly5", example_box,
  388. "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,4.5 1.2,2.9 0.7,2 1.3))",
  389. 2, 11, 0.7575961);
  390. test_one<Polygon, Box, Polygon>("clip_poly6", example_box,
  391. "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.0 3.0,5.0 2.0,2.9 0.7,2 1.3))",
  392. 2, 13, 1.0744456);
  393. test_one<Polygon, Box, Polygon>("clip_poly7", "Box(0 0, 3 3)",
  394. "POLYGON((2 2, 1 4, 2 4, 3 3, 2 2))",
  395. 1, 4, 0.75);
  396. }
  397. template <typename Box>
  398. void test_boxes(std::string const& wkt1, std::string const& wkt2, double expected_area, bool expected_result)
  399. {
  400. Box box1, box2;
  401. bg::read_wkt(wkt1, box1);
  402. bg::read_wkt(wkt2, box2);
  403. Box box_out;
  404. bg::assign_zero(box_out);
  405. bool detected = bg::intersection(box1, box2, box_out);
  406. typename bg::default_area_result<Box>::type area = bg::area(box_out);
  407. BOOST_CHECK_EQUAL(detected, expected_result);
  408. if (detected && expected_result)
  409. {
  410. BOOST_CHECK_CLOSE(area, expected_area, 0.01);
  411. }
  412. }
  413. template <typename P>
  414. void test_point_output()
  415. {
  416. typedef bg::model::linestring<P> linestring;
  417. typedef bg::model::polygon<P> polygon;
  418. typedef bg::model::box<P> box;
  419. //typedef bg::model::segment<P> segment;
  420. test_point_output<polygon, polygon>(simplex_normal[0], simplex_normal[1], 6);
  421. test_point_output<box, polygon>("box(1 1,6 4)", simplex_normal[0], 4);
  422. test_point_output<linestring, polygon>("linestring(0 2,6 2)", simplex_normal[0], 2);
  423. // NYI because of sectionize:
  424. // test_point_output<segment, polygon>("linestring(0 2,6 2)", simplex_normal[0], 2);
  425. // NYI because needs special treatment:
  426. // test_point_output<box, box>("box(0 0,4 4)", "box(2 2,6 6)", 2);
  427. }
  428. template <typename Polygon, typename LineString>
  429. void test_areal_linear()
  430. {
  431. std::string const poly_simplex = "POLYGON((1 1,1 3,3 3,3 1,1 1))";
  432. test_one_lp<LineString, Polygon, LineString>("simplex", poly_simplex, "LINESTRING(0 2,4 2)", 1, 2, 2.0);
  433. test_one_lp<LineString, Polygon, LineString>("case2", poly_simplex, "LINESTRING(0 1,4 3)", 1, 2, sqrt(5.0));
  434. test_one_lp<LineString, Polygon, LineString>("case3", "POLYGON((2 0,2 5,5 5,5 0,2 0))", "LINESTRING(0 1,1 2,3 2,4 3,6 3,7 4)", 1, 4, 2 + sqrt(2.0));
  435. test_one_lp<LineString, Polygon, LineString>("case4", "POLYGON((0 0,0 4,2 4,2 0,0 0))", "LINESTRING(1 1,3 2,1 3)", 2, 4, sqrt(5.0));
  436. test_one_lp<LineString, Polygon, LineString>("case5", poly_simplex, "LINESTRING(0 1,3 4)", 1, 2, sqrt(2.0));
  437. test_one_lp<LineString, Polygon, LineString>("case6", "POLYGON((2 0,2 4,3 4,3 1,4 1,4 3,5 3,5 1,6 1,6 3,7 3,7 1,8 1,8 3,9 3,9 0,2 0))", "LINESTRING(1 1,10 3)", 4, 8,
  438. // Pieces are 1 x 2/9:
  439. 4.0 * sqrt(1.0 + 4.0/81.0));
  440. test_one_lp<LineString, Polygon, LineString>("case7", poly_simplex, "LINESTRING(1.5 1.5,2.5 2.5)", 1, 2, sqrt(2.0));
  441. test_one_lp<LineString, Polygon, LineString>("case8", poly_simplex, "LINESTRING(1 0,2 0)", 0, 0, 0.0);
  442. std::string const poly_9 = "POLYGON((1 1,1 4,4 4,4 1,1 1))";
  443. test_one_lp<LineString, Polygon, LineString>("case9", poly_9, "LINESTRING(0 1,1 2,2 2)", 1, 2, 1.0);
  444. test_one_lp<LineString, Polygon, LineString>("case10", poly_9, "LINESTRING(0 1,1 2,0 2)", 0, 0, 0.0);
  445. test_one_lp<LineString, Polygon, LineString>("case11", poly_9, "LINESTRING(2 2,4 2,3 3)", 1, 3, 2.0 + sqrt(2.0));
  446. test_one_lp<LineString, Polygon, LineString>("case12", poly_9, "LINESTRING(2 3,4 4,5 6)", 1, 2, sqrt(5.0));
  447. test_one_lp<LineString, Polygon, LineString>("case13", poly_9, "LINESTRING(3 2,4 4,2 3)", 1, 3, 2.0 * sqrt(5.0));
  448. test_one_lp<LineString, Polygon, LineString>("case14", poly_9, "LINESTRING(5 6,4 4,6 5)", 0, 0, 0.0);
  449. test_one_lp<LineString, Polygon, LineString>("case15", poly_9, "LINESTRING(0 2,1 2,1 3,0 3)", 1, 2, 1.0);
  450. test_one_lp<LineString, Polygon, LineString>("case16", poly_9, "LINESTRING(2 2,1 2,1 3,2 3)", 1, 4, 3.0);
  451. std::string const angly = "LINESTRING(2 2,2 1,4 1,4 2,5 2,5 3,4 3,4 4,5 4,3 6,3 5,2 5,2 6,0 4)";
  452. // PROPERTIES CHANGED BY switch_to_integer
  453. // TODO test_one_lp<LineString, Polygon, LineString>("case17", "POLYGON((1 1,1 5,4 5,4 1,1 1))", angly, 3, 8, 6.0);
  454. test_one_lp<LineString, Polygon, LineString>("case18", "POLYGON((1 1,1 5,5 5,5 1,1 1))", angly, 2, 12, 10.0 + sqrt(2.0));
  455. test_one_lp<LineString, Polygon, LineString>("case19", poly_9, "LINESTRING(1 2,1 3,0 3)", 1, 2, 1.0);
  456. test_one_lp<LineString, Polygon, LineString>("case20", poly_9, "LINESTRING(1 2,1 3,2 3)", 1, 3, 2.0);
  457. test_one_lp<LineString, Polygon, LineString>("case21",
  458. "POLYGON((2 3,-9 -7,12 -13,2 3))",
  459. "LINESTRING(-1.3 0,-15 0,-1.3 0)",
  460. 0, 0, 0);
  461. test_one_lp<LineString, Polygon, LineString>("case22",
  462. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  463. "LINESTRING(5 5,-10 5,5 5)",
  464. 2, 4, 10);
  465. test_one_lp<LineString, Polygon, LineString>("case22a",
  466. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  467. "LINESTRING(1 1,5 5,-10 5,5 5,6 6)",
  468. 2, 6, 17.071068);
  469. test_one_lp<LineString, Polygon, LineString>("case23",
  470. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  471. "LINESTRING(-10 5,5 5,-10 5)",
  472. 1, 3, 10);
  473. test_one_lp<LineString, Polygon, LineString>("case23a",
  474. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  475. "LINESTRING(-20 10,-10 5,5 5,-10 5,-20 -10)",
  476. 1, 3, 10);
  477. test_one_lp<LineString, Polygon, LineString>("case24",
  478. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  479. "LINESTRING(0 5,5 5,0 5)",
  480. 1, 3, 10);
  481. test_one_lp<LineString, Polygon, LineString>("case24",
  482. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  483. "LINESTRING(0 5,5 5,1 1,9 1,5 5,0 5)",
  484. 1, 6, 29.313708);
  485. test_one_lp<LineString, Polygon, LineString>("case25",
  486. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  487. "LINESTRING(5 5,0 5,5 5)",
  488. 1, 3, 10);
  489. test_one_lp<LineString, Polygon, LineString>("case25a",
  490. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  491. "LINESTRING(-10 10,5 5,0 5,5 5,20 10)",
  492. 1, 4, 20.540925);
  493. test_one_lp<LineString, Polygon, LineString>("case25b",
  494. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  495. "LINESTRING(-10 10,5 5,1 5,5 5,20 10)",
  496. 1, 4, 18.540925);
  497. test_one_lp<LineString, Polygon, LineString>("case25c",
  498. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  499. "LINESTRING(-10 10,5 5,-1 5,5 5,20 10)",
  500. 2, 6, 20.540925);
  501. test_one_lp<LineString, Polygon, LineString>("case26",
  502. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  503. "LINESTRING(-5 5,0 5,-5 5)",
  504. 0, 0, 0);
  505. test_one_lp<LineString, Polygon, LineString>("case26a",
  506. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  507. "LINESTRING(-10 10,-5 5,0 5,-5 5,-10 -10)",
  508. 0, 0, 0);
  509. test_one_lp<LineString, Polygon, LineString>("case27",
  510. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  511. "LINESTRING(5 5,0 5,5 5,5 4,0 4,5 4)",
  512. 1, 6, 21.0);
  513. test_one_lp<LineString, Polygon, LineString>("case28",
  514. "POLYGON((0 0,0 10,10 10,10 0,0 0))",
  515. "LINESTRING(5 5,0 5,5 5,5 4,0 4,5 3)",
  516. 1, 6, 21.099019);
  517. test_one_lp<LineString, Polygon, LineString>("case29",
  518. "POLYGON((5 5,15 15,15 5,5 5))",
  519. "LINESTRING(0 0,10 10)",
  520. 1, 2, 5 * std::sqrt(2.0));
  521. // PROPERTIES CHANGED BY switch_to_integer
  522. // TODO test_one_lp<LineString, Polygon, LineString>("case21", poly_9, "LINESTRING(1 2,1 4,4 4,4 1,2 1,2 2)", 1, 6, 11.0);
  523. // Compile test - arguments in any order:
  524. test_one<LineString, Polygon, LineString>("simplex", poly_simplex, "LINESTRING(0 2,4 2)", 1, 2, 2.0);
  525. test_one<LineString, LineString, Polygon>("simplex", "LINESTRING(0 2,4 2)", poly_simplex, 1, 2, 2.0);
  526. typedef typename bg::point_type<Polygon>::type Point;
  527. test_one<LineString, bg::model::ring<Point>, LineString>("simplex", poly_simplex, "LINESTRING(0 2,4 2)", 1, 2, 2.0);
  528. test_one_lp<LineString, Polygon, LineString>("case30",
  529. "POLYGON((25 0,0 15,30 15,22 10,25 0))",
  530. "LINESTRING(10 15,20 15)",
  531. 1, 2, 10.0);
  532. test_one_lp<LineString, Polygon, LineString>("case31",
  533. "POLYGON((25 0,0 15,30 15,22 10,25 0))",
  534. "LINESTRING(0 15,20 15)",
  535. 1, 2, 20.0);
  536. test_one_lp<LineString, Polygon, LineString>("case32",
  537. "POLYGON((25 0,0 15,30 15,22 10,25 0))",
  538. "LINESTRING(25 0, 0 15,20 15)",
  539. 1, 3, 49.15475947422650 /*sqrt(25^2+15^2)+20*/);
  540. typedef typename bg::point_type<Polygon>::type P;
  541. test_one_lp<P, Polygon, LineString>("case30p",
  542. "POLYGON((25 0,0 15,30 15,22 10,25 0))",
  543. "LINESTRING(10 15,20 15)",
  544. 2, 2, 0);
  545. }
  546. template <typename Linestring, typename Box>
  547. void test_linear_box()
  548. {
  549. typedef bg::model::multi_linestring<Linestring> multi_linestring_type;
  550. test_one_lp<Linestring, Box, Linestring>
  551. ("case-l-b-01",
  552. "BOX(-10 -10,10 10)",
  553. "LINESTRING(-20 -20, 0 0,20 20)",
  554. 1, 3, 20 * sqrt(2.0));
  555. test_one_lp<Linestring, Box, Linestring>
  556. ("case-l-b-02",
  557. "BOX(-10 -10,10 10)",
  558. "LINESTRING(-20 -20, 20 20)",
  559. 1, 2, 20.0 * sqrt(2.0));
  560. test_one_lp<Linestring, Box, Linestring>
  561. ("case-l-b-02",
  562. "BOX(-10 -10,10 10)",
  563. "LINESTRING(-20 -20, 20 20,15 0,0 -15)",
  564. 2, 4, 25.0 * sqrt(2.0));
  565. test_one_lp<Linestring, Box, multi_linestring_type>
  566. ("case-ml-b-01",
  567. "BOX(-10 -10,10 10)",
  568. "MULTILINESTRING((-20 -20, 20 20),(0 -15,15 0))",
  569. 2, 4, 25.0 * sqrt(2.0));
  570. }
  571. template <typename P>
  572. void test_all()
  573. {
  574. typedef bg::model::linestring<P> linestring;
  575. typedef bg::model::polygon<P> polygon;
  576. typedef bg::model::box<P> box;
  577. typedef bg::model::segment<P> segment;
  578. typedef bg::model::polygon<P, false> polygon_ccw;
  579. typedef bg::model::polygon<P, true, false> polygon_open;
  580. typedef bg::model::polygon<P, false, false> polygon_ccw_open;
  581. boost::ignore_unused<polygon_ccw, polygon_open, polygon_ccw_open>();
  582. ut_settings ignore_validity;
  583. ignore_validity.test_validity = false;
  584. std::string clip = "box(2 2,8 8)";
  585. test_areal_linear<polygon, linestring>();
  586. #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
  587. test_areal_linear<polygon_open, linestring>();
  588. test_areal_linear<polygon_ccw, linestring>();
  589. test_areal_linear<polygon_ccw_open, linestring>();
  590. #endif
  591. test_linear_box<linestring, box>();
  592. // Test polygons clockwise and counter clockwise
  593. test_areal<polygon>();
  594. #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
  595. test_areal<polygon_ccw>();
  596. test_areal<polygon_open>();
  597. test_areal<polygon_ccw_open>();
  598. #endif
  599. test_areal_clip<polygon, box>();
  600. #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
  601. test_areal_clip<polygon_ccw, box>();
  602. #endif
  603. #if defined(TEST_FAIL_DIFFERENT_ORIENTATIONS)
  604. // Should NOT compile
  605. // NOTE: this can probably be relaxed later on.
  606. test_one<polygon, polygon_ccw, polygon>("simplex_normal",
  607. simplex_normal[0], simplex_normal[1],
  608. 1, 7, 5.47363293);
  609. // Output ccw, nyi (should be just reversing afterwards)
  610. test_one<polygon, polygon, polygon_ccw>("simplex_normal",
  611. simplex_normal[0], simplex_normal[1],
  612. 1, 7, 5.47363293);
  613. #endif
  614. // Basic check: box/linestring, is clipping OK? should compile in any order
  615. test_one<linestring, linestring, box>("llb", "LINESTRING(0 0,10 10)", clip, 1, 2, sqrt(2.0 * 6.0 * 6.0));
  616. test_one<linestring, box, linestring>("lbl", clip, "LINESTRING(0 0,10 10)", 1, 2, sqrt(2.0 * 6.0 * 6.0));
  617. // Box/segment
  618. test_one<linestring, segment, box>("lsb", "LINESTRING(0 0,10 10)", clip, 1, 2, sqrt(2.0 * 6.0 * 6.0));
  619. test_one<linestring, box, segment>("lbs", clip, "LINESTRING(0 0,10 10)", 1, 2, sqrt(2.0 * 6.0 * 6.0));
  620. // Completely inside
  621. test_one<linestring, linestring, box>("llbi", "LINESTRING(3 3,7 7)", clip, 1, 2, sqrt(2.0 * 4.0 * 4.0));
  622. // Completely outside
  623. test_one<linestring, linestring, box>("llbo", "LINESTRING(9 9,10 10)", clip, 0, 0, 0.0);
  624. // Touching with point (-> output linestring with ONE point)
  625. test_one<linestring, linestring, box>("llb_touch", "LINESTRING(8 8,10 10)", clip, 1, 1, 0.0, ignore_validity);
  626. // Along border
  627. test_one<linestring, linestring, box>("llb_along", "LINESTRING(2 2,2 8)", clip, 1, 2, 6.0);
  628. // Outputting two lines (because of 3-4-5 constructions (0.3,0.4,0.5)
  629. // which occur 4 times, the length is expected to be 2.0)
  630. test_one<linestring, linestring, box>("llb_2", "LINESTRING(1.7 1.6,2.3 2.4,2.9 1.6,3.5 2.4,4.1 1.6)", clip, 2, 6, 4.0 * 0.5);
  631. // linear
  632. test_one<P, linestring, linestring>("llp1", "LINESTRING(0 0,1 1)", "LINESTRING(0 1,1 0)", 1, 1, 0.0);
  633. test_one<P, segment, segment>("ssp1", "LINESTRING(0 0,1 1)", "LINESTRING(0 1,1 0)", 1, 1, 0.0);
  634. test_one<P, linestring, linestring>("llp2", "LINESTRING(0 0,1 1)", "LINESTRING(0 0,2 2)", 2, 2, 0.0);
  635. // polygons outputing points
  636. //test_one<P, polygon, polygon>("ppp1", simplex_normal[0], simplex_normal[1], 1, 7, 5.47363293);
  637. test_boxes<box>("box(2 2,8 8)", "box(4 4,10 10)", 16, true);
  638. test_boxes<box>("box(2 2,8 7)", "box(4 4,10 10)", 12, true);
  639. test_boxes<box>("box(2 2,8 7)", "box(14 4,20 10)", 0, false);
  640. test_boxes<box>("box(2 2,4 4)", "box(4 4,8 8)", 0, true);
  641. test_point_output<P>();
  642. /*
  643. test_one<polygon, box, polygon>(99, "box(115041.10 471900.10, 118334.60 474523.40)",
  644. "POLYGON ((115483.40 474533.40, 116549.40 474059.20, 117199.90 473762.50, 117204.90 473659.50, 118339.40 472796.90, 118334.50 472757.90, 118315.10 472604.00, 118344.60 472520.90, 118277.90 472419.10, 118071.40 472536.80, 118071.40 472536.80, 117943.10 472287.70, 117744.90 472248.40, 117708.00 472034.50, 117481.90 472056.90, 117481.90 472056.90, 117272.30 471890.10, 117077.90 472161.20, 116146.60 473054.50, 115031.10 473603.30, 115483.40 474533.40))",
  645. 1, 26, 3727690.74);
  646. */
  647. }
  648. void test_pointer_version()
  649. {
  650. std::vector<test::test_point_xy*> ln;
  651. test::test_point_xy* p;
  652. p = new test::test_point_xy; p->x = 0; p->y = 0; ln.push_back(p);
  653. p = new test::test_point_xy; p->x = 10; p->y = 10; ln.push_back(p);
  654. bg::model::box<bg::model::d2::point_xy<double> > box;
  655. bg::assign_values(box, 2, 2, 8, 8);
  656. typedef bg::model::linestring<bg::model::d2::point_xy<double> > output_type;
  657. std::vector<output_type> clip;
  658. bg::detail::intersection::intersection_insert<output_type>(box, ln, std::back_inserter(clip));
  659. double length = 0;
  660. std::size_t n = 0;
  661. for (std::vector<output_type>::const_iterator it = clip.begin();
  662. it != clip.end(); ++it)
  663. {
  664. length += bg::length(*it);
  665. n += bg::num_points(*it);
  666. }
  667. BOOST_CHECK_EQUAL(clip.size(), 1u);
  668. BOOST_CHECK_EQUAL(n, 2u);
  669. BOOST_CHECK_CLOSE(length, sqrt(2.0 * 6.0 * 6.0), 0.001);
  670. for (std::size_t i = 0; i < ln.size(); i++)
  671. {
  672. delete ln[i];
  673. }
  674. }
  675. template <typename P>
  676. void test_exception()
  677. {
  678. typedef bg::model::polygon<P> polygon;
  679. try
  680. {
  681. // Define polygon with a spike (= invalid)
  682. std::string spike = "POLYGON((0 0,0 4,2 4,2 6,2 4,4 4,4 0,0 0))";
  683. test_one<polygon, polygon, polygon>("with_spike",
  684. simplex_normal[0], spike,
  685. 0, 0, 0);
  686. }
  687. catch(bg::overlay_invalid_input_exception const& )
  688. {
  689. return;
  690. }
  691. BOOST_CHECK_MESSAGE(false, "No exception thrown");
  692. }
  693. template <typename Point>
  694. void test_rational()
  695. {
  696. typedef bg::model::polygon<Point> polygon;
  697. test_one<polygon, polygon, polygon>("simplex_normal",
  698. simplex_normal[0], simplex_normal[1],
  699. 1, 7, 5.47363293);
  700. }
  701. template <typename P>
  702. void test_boxes_per_d(P const& min1, P const& max1, P const& min2, P const& max2, bool expected_result)
  703. {
  704. typedef bg::model::box<P> box;
  705. box box_out;
  706. bool detected = bg::intersection(box(min1, max1), box(min2, max2), box_out);
  707. BOOST_CHECK_EQUAL(detected, expected_result);
  708. if ( detected && expected_result )
  709. {
  710. BOOST_CHECK( bg::equals(box_out, box(min2,max1)) );
  711. }
  712. }
  713. template <typename CoordinateType>
  714. void test_boxes_nd()
  715. {
  716. typedef bg::model::point<CoordinateType, 1, bg::cs::cartesian> p1;
  717. typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> p2;
  718. typedef bg::model::point<CoordinateType, 3, bg::cs::cartesian> p3;
  719. test_boxes_per_d(p1(0), p1(5), p1(3), p1(6), true);
  720. test_boxes_per_d(p2(0,0), p2(5,5), p2(3,3), p2(6,6), true);
  721. test_boxes_per_d(p3(0,0,0), p3(5,5,5), p3(3,3,3), p3(6,6,6), true);
  722. }
  723. template <typename CoordinateType>
  724. void test_ticket_10868(std::string const& wkt_out)
  725. {
  726. typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
  727. typedef bg::model::polygon
  728. <
  729. point_type, /*ClockWise*/false, /*Closed*/false
  730. > polygon_type;
  731. typedef bg::model::multi_polygon<polygon_type> multipolygon_type;
  732. polygon_type polygon1;
  733. bg::read_wkt(ticket_10868[0], polygon1);
  734. polygon_type polygon2;
  735. bg::read_wkt(ticket_10868[1], polygon2);
  736. multipolygon_type multipolygon_out;
  737. bg::intersection(polygon1, polygon2, multipolygon_out);
  738. std::stringstream stream;
  739. stream << bg::wkt(multipolygon_out);
  740. BOOST_CHECK_EQUAL(stream.str(), wkt_out);
  741. test_one<polygon_type, polygon_type, polygon_type>("ticket_10868",
  742. ticket_10868[0], ticket_10868[1],
  743. 1, 7, 20266195244586.0);
  744. }
  745. int test_main(int, char* [])
  746. {
  747. BoostGeometryWriteTestConfiguration();
  748. test_all<bg::model::d2::point_xy<default_test_type> >();
  749. #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
  750. test_all<bg::model::d2::point_xy<float> >();
  751. #if defined(HAVE_TTMATH)
  752. std::cout << "Testing TTMATH" << std::endl;
  753. test_all<bg::model::d2::point_xy<ttmath_big> >();
  754. #endif
  755. // Commented, because exception is now disabled:
  756. // test_exception<bg::model::d2::point_xy<double> >();
  757. test_pointer_version();
  758. #if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
  759. test_rational<bg::model::d2::point_xy<boost::rational<int> > >();
  760. #endif
  761. test_boxes_nd<double>();
  762. #if defined(BOOST_GEOMETRY_TEST_FAILURES)
  763. // ticket #10868 still fails for 32-bit integers
  764. test_ticket_10868<int32_t>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
  765. #if !defined(BOOST_NO_INT64) || defined(BOOST_HAS_INT64_T) || defined(BOOST_HAS_MS_INT64)
  766. test_ticket_10868<int64_t>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
  767. #endif
  768. if (BOOST_GEOMETRY_CONDITION(sizeof(long) * CHAR_BIT >= 64))
  769. {
  770. test_ticket_10868<long>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
  771. }
  772. #if defined(BOOST_HAS_LONG_LONG)
  773. test_ticket_10868<boost::long_long_type>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
  774. #endif
  775. #endif
  776. #endif
  777. return 0;
  778. }