difference_multi.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Use, modification and distribution is subject to the Boost Software License,
  5. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. #include <iostream>
  8. #include <string>
  9. #include "test_difference.hpp"
  10. #include <algorithms/test_overlay.hpp>
  11. #include <algorithms/overlay/multi_overlay_cases.hpp>
  12. #include <boost/geometry/algorithms/correct.hpp>
  13. #include <boost/geometry/algorithms/intersection.hpp>
  14. #include <boost/geometry/geometries/point_xy.hpp>
  15. #include <boost/geometry/geometries/multi_point.hpp>
  16. #include <boost/geometry/geometries/multi_polygon.hpp>
  17. #include <boost/geometry/io/wkt/read.hpp>
  18. // Convenience macros (points are not checked)
  19. #define TEST_DIFFERENCE(caseid, clips1, area1, clips2, area2, clips3) \
  20. (test_one<Polygon, MultiPolygon, MultiPolygon>) \
  21. ( #caseid, caseid[0], caseid[1], clips1, -1, area1, clips2, -1, area2, \
  22. clips3, -1, area1 + area2)
  23. #define TEST_DIFFERENCE_IGNORE(caseid, clips1, area1, clips2, area2, clips3) \
  24. { ut_settings ignore_validity; ignore_validity.test_validity = false; \
  25. (test_one<Polygon, MultiPolygon, MultiPolygon>) \
  26. ( #caseid, caseid[0], caseid[1], clips1, -1, area1, clips2, -1, area2, \
  27. clips3, -1, area1 + area2, ignore_validity); }
  28. #define TEST_DIFFERENCE_WITH(index1, index2, caseid, clips1, area1, \
  29. clips2, area2, clips3) \
  30. (test_one<Polygon, MultiPolygon, MultiPolygon>) \
  31. ( #caseid "_" #index1 "_" #index2, caseid[index1], caseid[index2], \
  32. clips1, -1, area1, \
  33. clips2, -1, area2, \
  34. clips3, -1, area1 + area2, settings)
  35. template <typename Ring, typename Polygon, typename MultiPolygon>
  36. void test_areal()
  37. {
  38. test_one<Polygon, MultiPolygon, MultiPolygon>("simplex_multi",
  39. case_multi_simplex[0], case_multi_simplex[1],
  40. 5, 21, 5.58, 4, 17, 2.58);
  41. test_one<Polygon, MultiPolygon, MultiPolygon>("case_multi_no_ip",
  42. case_multi_no_ip[0], case_multi_no_ip[1],
  43. 2, 12, 24.0, 2, 12, 34.0);
  44. test_one<Polygon, MultiPolygon, MultiPolygon>("case_multi_2",
  45. case_multi_2[0], case_multi_2[1],
  46. 2, 15, 19.6, 2, 13, 33.6);
  47. test_one<Polygon, MultiPolygon, Polygon>("simplex_multi_mp_p",
  48. case_multi_simplex[0], case_single_simplex,
  49. 5, 21, 5.58, 4, 17, 2.58);
  50. test_one<Polygon, Ring, MultiPolygon>("simplex_multi_r_mp",
  51. case_single_simplex, case_multi_simplex[0],
  52. 4, 17, 2.58, 5, 21, 5.58);
  53. test_one<Polygon, MultiPolygon, Ring>("simplex_multi_mp_r",
  54. case_multi_simplex[0], case_single_simplex,
  55. 5, 21, 5.58, 4, 17, 2.58);
  56. // Constructed cases for multi/touch/equal/etc
  57. test_one<Polygon, MultiPolygon, MultiPolygon>("case_61_multi",
  58. case_61_multi[0], case_61_multi[1],
  59. 2, 10, 2, 2, 10, 2, 1, 10, 4);
  60. test_one<Polygon, MultiPolygon, MultiPolygon>("case_62_multi",
  61. case_62_multi[0], case_62_multi[1],
  62. 0, 0, 0, 1, 5, 1);
  63. test_one<Polygon, MultiPolygon, MultiPolygon>("case_63_multi",
  64. case_63_multi[0], case_63_multi[1],
  65. 0, 0, 0, 1, 5, 1);
  66. test_one<Polygon, MultiPolygon, MultiPolygon>("case_64_multi",
  67. case_64_multi[0], case_64_multi[1],
  68. 1, 5, 1, 1, 5, 1, 1, 7, 2);
  69. test_one<Polygon, MultiPolygon, MultiPolygon>("case_65_multi",
  70. case_65_multi[0], case_65_multi[1],
  71. 0, 0, 0, 2, 10, 3);
  72. test_one<Polygon, MultiPolygon, MultiPolygon>("case_72_multi",
  73. case_72_multi[0], case_72_multi[1],
  74. 3, 13, 1.65, 3, 17, 6.15);
  75. test_one<Polygon, MultiPolygon, MultiPolygon>("case_77_multi",
  76. case_77_multi[0], case_77_multi[1],
  77. 6, 31, 7.0,
  78. 5, 33, 13.0,
  79. 5, 38, 7.0 + 13.0);
  80. test_one<Polygon, MultiPolygon, MultiPolygon>("case_78_multi",
  81. case_78_multi[0], case_78_multi[1],
  82. 1, 5, 1.0, 1, 5, 1.0);
  83. TEST_DIFFERENCE(case_123_multi, 1, 0.25, 2, 0.625, 3);
  84. TEST_DIFFERENCE(case_124_multi, 1, 0.25, 2, 0.4375, 3);
  85. TEST_DIFFERENCE(case_125_multi, 1, 0.25, 2, 0.400, 3);
  86. // A should have 3 clips, B should have 5 clips
  87. TEST_DIFFERENCE(case_126_multi, 4, 16.0, 5, 27.0, 9);
  88. {
  89. ut_settings settings;
  90. settings.sym_difference = BG_IF_RESCALED(false, true);
  91. test_one<Polygon, MultiPolygon, MultiPolygon>("case_108_multi",
  92. case_108_multi[0], case_108_multi[1],
  93. 7, 32, 5.5,
  94. 4, 24, 9.75,
  95. 7, 45, 15.25,
  96. settings);
  97. }
  98. // Ticket on GGL list 2011/10/25
  99. // to mix polygon/multipolygon in call to difference
  100. test_one<Polygon, Polygon, Polygon>("ggl_list_20111025_vd_pp",
  101. ggl_list_20111025_vd[0], ggl_list_20111025_vd[1],
  102. 1, 4, 8.0, 1, 4, 12.5);
  103. test_one<Polygon, Polygon, MultiPolygon>("ggl_list_20111025_vd_pm",
  104. ggl_list_20111025_vd[0], ggl_list_20111025_vd[3],
  105. 1, 4, 8.0, 1, 4, 12.5);
  106. test_one<Polygon, MultiPolygon, Polygon>("ggl_list_20111025_vd_mp",
  107. ggl_list_20111025_vd[2], ggl_list_20111025_vd[1],
  108. 1, 4, 8.0, 1, 4, 12.5);
  109. test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20111025_vd_mm",
  110. ggl_list_20111025_vd[2], ggl_list_20111025_vd[3],
  111. 1, 4, 8.0, 1, 4, 12.5);
  112. test_one<Polygon, Polygon, MultiPolygon>("ggl_list_20111025_vd_2",
  113. ggl_list_20111025_vd_2[0], ggl_list_20111025_vd_2[1],
  114. 1, 7, 10.0, 2, 10, 6.0);
  115. test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
  116. ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],
  117. 2, 13, 17.0, 0, 0, 0.0);
  118. test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_b",
  119. ggl_list_20120915_h2[0], ggl_list_20120915_h2[2],
  120. 2, 13, 17.0, 0, 0, 0.0);
  121. {
  122. ut_settings settings;
  123. settings.percentage = 0.001;
  124. settings.test_validity = BG_IF_RESCALED(true, false);
  125. TEST_DIFFERENCE_WITH(0, 1, ggl_list_20120221_volker, 2, 7962.66, 2, 2775258.93, 4);
  126. }
  127. {
  128. // With rescaling, A is invalid (this is a robustness problem) and the other
  129. // output is discarded because of zero area
  130. // POSTGIS areas: 3.75893745345145, 2.5810000723917e-15
  131. ut_settings settings;
  132. settings.sym_difference = BG_IF_RESCALED(false, true);
  133. settings.test_validity = BG_IF_RESCALED(false, true);
  134. #if defined(BOOST_GEOMETRY_USE_RESCALING) || ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE)
  135. // No output for B
  136. TEST_DIFFERENCE_WITH(0, 1, bug_21155501, 1, 3.758937, 0, 0.0, 1);
  137. #else
  138. // Very small sliver for B, and sym difference is not considered valid
  139. settings.test_validity = false;
  140. TEST_DIFFERENCE_WITH(0, 1, bug_21155501, 1, 3.758937, 1, 1.7763568394002505e-15, 2);
  141. #endif
  142. }
  143. #if defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  144. {
  145. // With rescaling, it is complete but invalid
  146. ut_settings settings;
  147. settings.percentage = 0.001;
  148. settings.test_validity = BG_IF_RESCALED(false, true);
  149. TEST_DIFFERENCE_WITH(0, 1, ticket_9081,
  150. 2, 0.0907392476356186,
  151. 4, 0.126018011439877,
  152. BG_IF_RESCALED(4, 3));
  153. }
  154. #endif
  155. TEST_DIFFERENCE(ticket_12503, 46, 920.625, 4, 7.625, 50);
  156. {
  157. // Reported issues going wrong with rescaling (except for 630b)
  158. ut_settings settings;
  159. settings.percentage = 0.001;
  160. #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  161. TEST_DIFFERENCE_WITH(0, 1, issue_630_a, 0, 0.0, 1, BG_IF_KRAMER(2.023326, 2.200326), 1);
  162. #endif
  163. TEST_DIFFERENCE_WITH(0, 1, issue_630_b, 1, 0.0056089, 2, 1.498976, 3);
  164. #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  165. #if defined(BOOST_GEOMETRY_USE_KRAMER) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  166. // Only succeeds with Kramer rule and no rescaling
  167. TEST_DIFFERENCE_WITH(0, 1, issue_630_c, 0, 0, 1, 1.493367, 1);
  168. #endif
  169. TEST_DIFFERENCE_WITH(0, 1, issue_643, 1, 76.5385, BG_IF_KRAMER(1, 0), BG_IF_KRAMER(2.8634e-09, 0.0), 1);
  170. #endif
  171. }
  172. // Areas and #clips correspond with POSTGIS (except sym case)
  173. test_one<Polygon, MultiPolygon, MultiPolygon>("case_101_multi",
  174. case_101_multi[0], case_101_multi[1],
  175. 5, 23, 4.75,
  176. 5, 40, 12.75,
  177. 5, 48, 4.75 + 12.75);
  178. // Areas and #clips correspond with POSTGIS
  179. test_one<Polygon, MultiPolygon, MultiPolygon>("case_102_multi",
  180. case_102_multi[0], case_102_multi[1],
  181. 2, 8, 0.75,
  182. 6, 25, 3.75,
  183. 6, 27, 0.75 + 3.75);
  184. // Areas and #clips correspond with POSTGIS
  185. test_one<Polygon, MultiPolygon, MultiPolygon>("case_107_multi",
  186. case_107_multi[0], case_107_multi[1],
  187. 2, 11, 2.25,
  188. 3, 14, 3.0,
  189. 4, 21, 5.25);
  190. TEST_DIFFERENCE(case_133_multi, 3, 16.0, 2, 8.0, 5);
  191. TEST_DIFFERENCE(case_134_multi, 3, 16.0, 2, 8.0, 5);
  192. TEST_DIFFERENCE(case_135_multi, 2, 2.0, 2, 13.0, 2);
  193. TEST_DIFFERENCE(case_136_multi, 2, 2.0, 3, 13.5, 3);
  194. TEST_DIFFERENCE(case_137_multi, 2, 2.5, 2, 13.0, 2);
  195. TEST_DIFFERENCE(case_138_multi, 5, 16.6, 3, 8.225, 8);
  196. TEST_DIFFERENCE(case_139_multi, 4, 16.328125, 3, 8.078125, 7);
  197. TEST_DIFFERENCE(case_140_multi, 4, 16.328125, 3, 8.078125, 7);
  198. TEST_DIFFERENCE(case_141_multi, 5, 15.5, 5, 10.0, 10);
  199. // Areas correspond with POSTGIS,
  200. // #clips in PostGIS is 11,11,5 but should most probably be be 12,12,6
  201. TEST_DIFFERENCE(case_recursive_boxes_1, 12, 26.0, 12, 24.0, 6);
  202. // Areas and #clips correspond with POSTGIS
  203. test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_2",
  204. case_recursive_boxes_2[0], case_recursive_boxes_2[1],
  205. 3, 15, 3.0,
  206. 7, 33, 7.0,
  207. 10, 48, 10.0);
  208. // Areas and #clips by POSTGIS (except sym case)
  209. test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_3",
  210. case_recursive_boxes_3[0], case_recursive_boxes_3[1],
  211. 24, -1, 21.5,
  212. 25, -1, 22.5,
  213. 37, -1, 44.0);
  214. // 4, input is not valid
  215. TEST_DIFFERENCE(case_recursive_boxes_5, 16, 22.0, 12, 27.0, 10);
  216. TEST_DIFFERENCE(case_recursive_boxes_6, 7, 3.5, 3, 1.5, 9);
  217. test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_7",
  218. case_recursive_boxes_7[0], case_recursive_boxes_7[1],
  219. 3, 15, 2.75,
  220. 4, 19, 2.75,
  221. 3, 22, 5.5);
  222. test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_8",
  223. case_recursive_boxes_8[0], case_recursive_boxes_8[1],
  224. 2, -1, 2.50,
  225. 4, -1, 5.75,
  226. 4, -1, 8.25);
  227. test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_9",
  228. case_recursive_boxes_9[0], case_recursive_boxes_9[1],
  229. 3, -1, 1.5,
  230. 4, -1, 2.5,
  231. 6, -1, 4.0);
  232. test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_10",
  233. case_recursive_boxes_10[0], case_recursive_boxes_10[1],
  234. 2, -1, 1.25,
  235. 2, -1, 0.75,
  236. 4, -1, 2.00);
  237. test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_11",
  238. case_recursive_boxes_11[0], case_recursive_boxes_11[1],
  239. 3, -1, 2.5,
  240. 3, -1, 4.5,
  241. 3, -1, 7.0);
  242. TEST_DIFFERENCE(case_recursive_boxes_12, 4, 2.75, 3, 2.75, 6);
  243. TEST_DIFFERENCE(case_recursive_boxes_13, 4, 4.75, 3, 5.5, 3);
  244. TEST_DIFFERENCE(case_recursive_boxes_14, 3, 2.0, 4, 2.5, 5);
  245. TEST_DIFFERENCE(case_recursive_boxes_15, 3, 3.0, 2, 2.5, 3);
  246. TEST_DIFFERENCE(case_recursive_boxes_16, 8, 6.5, 3, 5.5, 9);
  247. TEST_DIFFERENCE(case_recursive_boxes_17, 10, 7.75, 7, 5.5, 13);
  248. TEST_DIFFERENCE(case_recursive_boxes_18, 2, 1.0, 1, 1.5, 3);
  249. TEST_DIFFERENCE(case_recursive_boxes_19, 2, 1.0, 2, 1.5, 3);
  250. TEST_DIFFERENCE(case_recursive_boxes_20, 2, 1.0, 0, 0.0, 2);
  251. TEST_DIFFERENCE(case_recursive_boxes_21, 2, 1.0, 1, 1.0, 1);
  252. TEST_DIFFERENCE(case_recursive_boxes_22, 2, 1.25, 2, 2.0, 2);
  253. TEST_DIFFERENCE(case_recursive_boxes_23, 2, 0.75, 1, 0.5, 3);
  254. TEST_DIFFERENCE(case_recursive_boxes_24, 3, 2.5, 2, 2.0, 5);
  255. TEST_DIFFERENCE(case_recursive_boxes_25, 2, 2.5, 3, 2.5, 2);
  256. TEST_DIFFERENCE(case_recursive_boxes_26, 2, 1.5, 3, 2.0, 4);
  257. TEST_DIFFERENCE(case_recursive_boxes_27, 1, 1.5, 3, 2.5, 3);
  258. TEST_DIFFERENCE(case_recursive_boxes_28, 3, 2.5, 2, 3.0, 4);
  259. TEST_DIFFERENCE(case_recursive_boxes_29, 5, 7.25, 5, 4.5, 5);
  260. TEST_DIFFERENCE(case_recursive_boxes_30, 6, 4.25, 3, 7.25, 7);
  261. TEST_DIFFERENCE(case_recursive_boxes_31, 2, 2.0, 1, 0.5, 2);
  262. TEST_DIFFERENCE(case_recursive_boxes_32, 2, 2.75, 2, 1.25, 2);
  263. TEST_DIFFERENCE(case_recursive_boxes_33, 4, 3.0, 3, 6.0, 4);
  264. TEST_DIFFERENCE(case_recursive_boxes_34, 7, 7.25, 1, 0.5, 8);
  265. TEST_DIFFERENCE(case_recursive_boxes_35, 5, 1.75, 5, 2.75, 10);
  266. TEST_DIFFERENCE(case_recursive_boxes_36, 2, 1.0, 2, 1.5, 3);
  267. TEST_DIFFERENCE(case_recursive_boxes_37, 3, 2.5, 2, 4.25, 2);
  268. TEST_DIFFERENCE(case_recursive_boxes_38, 5, 7.75, 4, 3.5, 3);
  269. TEST_DIFFERENCE(case_recursive_boxes_39, 3, 6.0, 3, 3.0, 4);
  270. TEST_DIFFERENCE(case_recursive_boxes_40, 11, 14.0, 9, 13.0, 11);
  271. TEST_DIFFERENCE(case_recursive_boxes_41, 1, 0.5, 1, 0.5, 2);
  272. TEST_DIFFERENCE(case_recursive_boxes_42, 1, 1.0, 4, 4.0, 5);
  273. TEST_DIFFERENCE(case_recursive_boxes_43, 1, 0.5, 3, 2.0, 4);
  274. TEST_DIFFERENCE(case_recursive_boxes_44, 3, 5.0, 0, 0.0, 3);
  275. TEST_DIFFERENCE(case_recursive_boxes_45, 6, 20.0, 7, 20.0, 3);
  276. TEST_DIFFERENCE(case_recursive_boxes_46, 4, 14.0, 5, 12.0, 5);
  277. TEST_DIFFERENCE(case_recursive_boxes_47, 4, 10.0, 7, 11.0, 1);
  278. TEST_DIFFERENCE(case_recursive_boxes_48, 0, 0.0, 1, 9.0, 1);
  279. TEST_DIFFERENCE(case_recursive_boxes_49, 10, 22.0, 10, 17.0, 11);
  280. TEST_DIFFERENCE(case_recursive_boxes_50, 14, 21.0, 16, 21.0, 14);
  281. TEST_DIFFERENCE(case_recursive_boxes_51, 14, 25.0, 12, 31.0, 7);
  282. TEST_DIFFERENCE(case_recursive_boxes_52, 13, 30.0, 15, 25.0, 8);
  283. TEST_DIFFERENCE(case_recursive_boxes_53, 6, 3.5, 4, 1.5, 9);
  284. TEST_DIFFERENCE(case_recursive_boxes_54, 6, 6.5, 8, 6.0, 7);
  285. TEST_DIFFERENCE(case_recursive_boxes_55, 4, 5.5, 6, 7.75, 4);
  286. TEST_DIFFERENCE(case_recursive_boxes_56, 4, 4.5, 5, 2.75, 6);
  287. TEST_DIFFERENCE(case_recursive_boxes_57, 5, 3.75, 9, 6.5, 10);
  288. TEST_DIFFERENCE(case_recursive_boxes_58, 4, 2.25, 6, 3.75, 7);
  289. TEST_DIFFERENCE(case_recursive_boxes_59, 8, 6.5, 7, 7.0, 12);
  290. TEST_DIFFERENCE(case_recursive_boxes_60, 6, 5.25, 7, 5.25, 11);
  291. TEST_DIFFERENCE(case_recursive_boxes_61, 2, 1.5, 6, 2.0, 7);
  292. #if defined(BOOST_GEOMETRY_TEST_FAILURES)
  293. // Misses one triangle, should be fixed in traversal.
  294. // It is not related to rescaling.
  295. TEST_DIFFERENCE(case_recursive_boxes_62, 5, 5.0, 11, 5.75, 12);
  296. #endif
  297. TEST_DIFFERENCE(case_recursive_boxes_63, 9, 10.5, 5, 27.75, 4);
  298. TEST_DIFFERENCE(case_recursive_boxes_64, 6, 2.75, 7, 4.5, 11);
  299. TEST_DIFFERENCE(case_recursive_boxes_65, 6, 4.25, 7, 3.0, 13);
  300. TEST_DIFFERENCE(case_recursive_boxes_66, 5, 4.75, 7, 4.0, 9);
  301. TEST_DIFFERENCE(case_recursive_boxes_67, 7, 6.25, 9, 6.0, 10);
  302. TEST_DIFFERENCE(case_recursive_boxes_68, 10, 6.5, 9, 6.5, 7);
  303. TEST_DIFFERENCE(case_recursive_boxes_69, 5, 6.25, 5, 6.75, 8);
  304. TEST_DIFFERENCE(case_recursive_boxes_70, 5, 2.0, 8, 4.5, 11);
  305. TEST_DIFFERENCE(case_recursive_boxes_71, 7, 8.25, 7, 5.75, 8);
  306. TEST_DIFFERENCE(case_recursive_boxes_72, 6, 6.5, 7, 4.0, 10);
  307. TEST_DIFFERENCE(case_recursive_boxes_73, 4, 1.75, 5, 4.0, 8);
  308. TEST_DIFFERENCE(case_recursive_boxes_74, 3, 3.00, 3, 1.5, 5);
  309. TEST_DIFFERENCE(case_recursive_boxes_75, 7, 4.5, 4, 2.0, 11);
  310. TEST_DIFFERENCE(case_recursive_boxes_76, 7, 3.75, 4, 2.5, 9);
  311. TEST_DIFFERENCE(case_recursive_boxes_77, 4, 3.75, 7, 6.25, 8);
  312. TEST_DIFFERENCE(case_recursive_boxes_78, 11, 5.5, 8, 4.5, 14);
  313. TEST_DIFFERENCE(case_recursive_boxes_79, 2, 1.25, 6, 4.5, 8);
  314. // one polygon is divided into two, for same reason as union creates a small
  315. // interior ring there
  316. TEST_DIFFERENCE(case_recursive_boxes_80, 1, 0.5, 2, 0.75, BG_IF_RESCALED(3, 2));
  317. TEST_DIFFERENCE(case_recursive_boxes_81, 3, 5.0, 6, 6.75, 6);
  318. TEST_DIFFERENCE(case_recursive_boxes_82, 5, 7.25, 7, 4.5, 8);
  319. TEST_DIFFERENCE(case_recursive_boxes_83, 9, 5.25, 8, 5.25, 12);
  320. TEST_DIFFERENCE(case_recursive_boxes_84, 4, 8.0, 7, 9.0, 4);
  321. #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  322. TEST_DIFFERENCE(case_recursive_boxes_85, 4, 4.0, 7, 3.75, 9);
  323. #endif
  324. TEST_DIFFERENCE(case_recursive_boxes_86, 1, 1.5, 2, 1.5, 3);
  325. TEST_DIFFERENCE(case_recursive_boxes_87, 4, 2.0, 4, 2.5, 8);
  326. TEST_DIFFERENCE(case_recursive_boxes_88, 3, 4.75, 5, 6.75, 4);
  327. // Output of A can be 0 or 1 polygons (with a very small area)
  328. TEST_DIFFERENCE(case_precision_m1, -1, 0.0, 1, 57.0, -1);
  329. // Output of A can be 1 or 2 polygons (one with a very small area)
  330. TEST_DIFFERENCE(case_precision_m2, -1, 1.0, 1, 57.75, -1);
  331. {
  332. ut_settings sym_settings;
  333. #if ! defined(BOOST_GEOMETRY_USE_RESCALING)
  334. sym_settings.sym_difference = false;
  335. #endif
  336. test_one<Polygon, MultiPolygon, MultiPolygon>("mysql_21965285_b",
  337. mysql_21965285_b[0],
  338. mysql_21965285_b[1],
  339. 2, -1, 183.71376870369406,
  340. 2, -1, 131.21376870369406,
  341. sym_settings);
  342. }
  343. TEST_DIFFERENCE(mysql_regression_1_65_2017_08_31,
  344. BG_IF_RESCALED(1, 0), BG_IF_RESCALED(4.30697514e-7, 0),
  345. 3, 152.0642, BG_IF_RESCALED(4, 3));
  346. }
  347. template <typename P>
  348. void test_all()
  349. {
  350. typedef bg::model::ring<P> ring;
  351. typedef bg::model::polygon<P> polygon;
  352. typedef bg::model::multi_polygon<polygon> multi_polygon;
  353. test_areal<ring, polygon, multi_polygon>();
  354. }
  355. // Test cases for integer coordinates / ccw / open
  356. template <typename Polygon, typename MultiPolygon>
  357. void test_specific_areal()
  358. {
  359. {
  360. // Spikes in a-b and b-a, failure in symmetric difference
  361. ut_settings settings;
  362. settings.sym_difference = false;
  363. settings.test_validity = false;
  364. TEST_DIFFERENCE_WITH(0, 1, ticket_11674,
  365. BG_IF_KRAMER(3, 4),
  366. BG_IF_KRAMER(9105781.5, 9105473.5),
  367. 5,
  368. BG_IF_KRAMER(119059.5, 119423), -1);
  369. }
  370. {
  371. // Ticket 12751 (Volker)
  372. // Spikes in a-b and b-a, failure in symmetric difference
  373. ut_settings settings;
  374. settings.remove_spikes = true;
  375. TEST_DIFFERENCE_WITH(0, 1, ticket_12751, 1,
  376. BG_IF_KRAMER(2781965.0, 2782114), 1,
  377. BG_IF_KRAMER(597.0, 598.0), 2);
  378. #if ! defined(BOOST_GEOMETRY_USE_KRAMER)
  379. // Fails with general line form intersection, symmetric version misses one outcut
  380. // TODO GENERAL FORM
  381. settings.test_validity = false;
  382. settings.sym_difference = false;
  383. #endif
  384. TEST_DIFFERENCE_WITH(2, 3, ticket_12751,
  385. 2, BG_IF_KRAMER(2537992.5, 2538305),
  386. 2, BG_IF_KRAMER(294963.5, 294737),
  387. 3);
  388. }
  389. {
  390. // Ticket 12752 (Volker)
  391. // Spikes in a-b and b-a, failure in symmetric difference
  392. ut_settings settings;
  393. settings.remove_spikes = true;
  394. settings.sym_difference = false;
  395. TEST_DIFFERENCE_WITH(0, 1, ticket_12752,
  396. BG_IF_KRAMER(3, 2), BG_IF_KRAMER(2776692.0, 2776657),
  397. 3, BG_IF_KRAMER(7893.0, 7710.5),
  398. 2);
  399. }
  400. {
  401. #if defined(BOOST_GEOMETRY_USE_KRAMER) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  402. // Fails completely with general line form intersection
  403. // There is something with scale.
  404. // TODO GENERAL FORM
  405. const std::string a_min_b =
  406. TEST_DIFFERENCE(ticket_10661, 2, 1441632.5, 2, 13167454, 4);
  407. test_one<Polygon, MultiPolygon, MultiPolygon>("ticket_10661_2",
  408. a_min_b, ticket_10661[2],
  409. 1, 8, 825192.0,
  410. 1, 10, BG_IF_KRAMER(27226370.5, 27842811),
  411. 1, -1, 825192.0 + 27226370.5);
  412. #endif
  413. }
  414. {
  415. ut_settings settings;
  416. settings.sym_difference = false;
  417. #if defined(BOOST_GEOMETRY_USE_KRAMER) || defined(BOOST_GEOMETRY_TEST_FAILURES)
  418. // Fails with general line form intersection
  419. // Misses one clip
  420. // TODO GENERAL FORM
  421. TEST_DIFFERENCE_WITH(0, 1, ticket_9942, 4, 7427727.5, 4,
  422. BG_IF_KRAMER(131506, 130083.5), 4);
  423. #endif
  424. TEST_DIFFERENCE_WITH(0, 1, ticket_9942a, 2,
  425. BG_IF_KRAMER(412676.5, 413183.5), 2,
  426. BG_IF_KRAMER(76779.5, 76924), 4);
  427. }
  428. }
  429. template <typename Point, bool ClockWise, bool Closed>
  430. void test_specific()
  431. {
  432. typedef bg::model::polygon<Point, ClockWise, Closed> polygon;
  433. typedef bg::model::multi_polygon<polygon> multi_polygon;
  434. test_specific_areal<polygon, multi_polygon>();
  435. }
  436. int test_main(int, char* [])
  437. {
  438. BoostGeometryWriteTestConfiguration();
  439. test_all<bg::model::d2::point_xy<default_test_type> >();
  440. test_specific<bg::model::d2::point_xy<int>, false, false>();
  441. #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
  442. test_all<bg::model::d2::point_xy<float> >();
  443. #if defined(HAVE_TTMATH)
  444. std::cout << "Testing TTMATH" << std::endl;
  445. test_all<bg::model::d2::point_xy<ttmath_big> >();
  446. #endif
  447. #endif
  448. return 0;
  449. }