traverse.cpp 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  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. #define BOOST_GEOMETRY_DEFINE_STREAM_OPERATOR_SEGMENT_RATIO
  8. //#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
  9. //#define BOOST_GEOMETRY_OVERLAY_NO_THROW
  10. //#define HAVE_TTMATH
  11. #include <iostream>
  12. #include <iomanip>
  13. #include <fstream>
  14. #include <sstream>
  15. #include <string>
  16. #include <boost/type_traits/is_same.hpp>
  17. #ifdef HAVE_TTMATH
  18. # include <boost/geometry/contrib/ttmath_stub.hpp>
  19. #endif
  20. #include <geometry_test_common.hpp>
  21. // #define BOOST_GEOMETRY_DEBUG_ENRICH
  22. //#define BOOST_GEOMETRY_DEBUG_RELATIVE_ORDER
  23. // #define BOOST_GEOMETRY_REPORT_OVERLAY_ERROR
  24. // #define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
  25. #define BOOST_GEOMETRY_TEST_OVERLAY_NOT_EXCHANGED
  26. #ifdef BOOST_GEOMETRY_DEBUG_ENRICH
  27. # define BOOST_GEOMETRY_DEBUG_IDENTIFIER
  28. #endif
  29. #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
  30. #include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
  31. #include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
  32. #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
  33. #include <boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp>
  34. #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
  35. #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
  36. #include <boost/geometry/algorithms/detail/overlay/traverse.hpp>
  37. #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
  38. #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
  39. #include <boost/geometry/algorithms/area.hpp>
  40. #include <boost/geometry/algorithms/correct.hpp>
  41. #include <boost/geometry/geometries/geometries.hpp>
  42. #include <boost/geometry/io/wkt/wkt.hpp>
  43. #if defined(TEST_WITH_SVG)
  44. # include <boost/geometry/io/svg/svg_mapper.hpp>
  45. #endif
  46. #include <boost/geometry/strategies/strategies.hpp>
  47. #include <algorithms/overlay/overlay_cases.hpp>
  48. template <bg::overlay_type Op>
  49. static inline std::string operation()
  50. {
  51. switch(Op)
  52. {
  53. case bg::overlay_union : return "union";
  54. case bg::overlay_intersection : return "intersection";
  55. case bg::overlay_difference : return "difference";
  56. }
  57. return "unknown";
  58. }
  59. namespace detail
  60. {
  61. template
  62. <
  63. typename G1, typename G2,
  64. bg::overlay_type OverlayType,
  65. bool Reverse1, bool Reverse2
  66. >
  67. struct test_traverse
  68. {
  69. static void apply(std::string const& id,
  70. std::size_t expected_count, double expected_area,
  71. G1 const& g1, G2 const& g2,
  72. double precision)
  73. {
  74. // DEBUG ONE or FEW CASE(S) ONLY
  75. //if (! boost::contains(id, "36") || Direction != 1) return;
  76. //if (! boost::contains(id, "iet_") || boost::contains(id, "st")) return;
  77. //if (! boost::contains(id, "66") || Direction != 1) return;
  78. //if (! boost::contains(id, "92") && ! boost::contains(id, "96") ) return;
  79. //if (! (boost::contains(id, "58_st") || boost::contains(id, "59_st") || boost::contains(id, "60_st") || boost::contains(id, "83")) ) return;
  80. //if (! (boost::contains(id, "81") || boost::contains(id, "82") || boost::contains(id, "84") || boost::contains(id, "85") || boost::contains(id, "68")) ) return;
  81. //if (! (boost::contains(id, "81") || boost::contains(id, "86") || boost::contains(id, "88")) ) return;
  82. //if (! boost::contains(id, "58_") || Direction != 1) return;
  83. //if (! boost::contains(id, "55") || Direction != 1) return;
  84. //if (! boost::contains(id, "55_iet_iet") || Direction != 1) return;
  85. //if (! boost::contains(id, "55_st_iet") || Direction != 1) return;
  86. //if (! boost::contains(id, "55_iet_st") || Direction != 1) return;
  87. //if (! boost::contains(id, "54_st_st") || Direction != 1) return;
  88. //if (! boost::contains(id, "54_iet_st") || Direction != 1) return;
  89. //if (! (boost::contains(id, "54_") || boost::contains(id, "55_")) || Direction != 1) return;
  90. //if (Direction != 1) return;
  91. // END DEBUG ONE ...
  92. /*** FOR REVERSING ONLY
  93. {
  94. // If one or both are invalid (e.g. ccw),
  95. // they can be corrected by uncommenting this section
  96. G1 cg1 = g1;
  97. G2 cg2 = g2;
  98. bg::correct(cg1);
  99. bg::correct(cg2);
  100. std::cout << std::setprecision(12)
  101. << bg::wkt(cg1) << std::endl
  102. << bg::wkt(cg2) << std::endl;
  103. }
  104. ***/
  105. #if defined(BOOST_GEOMETRY_DEBUG_OVERLAY) || defined(BOOST_GEOMETRY_DEBUG_ENRICH)
  106. bool const ccw =
  107. bg::point_order<G1>::value == bg::counterclockwise
  108. || bg::point_order<G2>::value == bg::counterclockwise;
  109. std::cout << std::endl
  110. << "TRAVERSE"
  111. << " " << id
  112. << (ccw ? "_ccw" : "")
  113. << " " << string_from_type<typename bg::coordinate_type<G1>::type>::name()
  114. << "(" << OverlayType << ")" << std::endl;
  115. //std::cout << bg::area(g1) << " " << bg::area(g2) << std::endl;
  116. #endif
  117. typedef typename bg::strategy::side::services::default_strategy
  118. <
  119. typename bg::cs_tag<G1>::type
  120. >::type side_strategy_type;
  121. typedef typename bg::point_type<G2>::type point_type;
  122. typedef typename bg::rescale_policy_type<point_type>::type
  123. rescale_policy_type;
  124. rescale_policy_type rescale_policy
  125. = bg::get_rescale_policy<rescale_policy_type>(g1, g2);
  126. typedef bg::detail::overlay::traversal_turn_info
  127. <
  128. point_type,
  129. typename bg::detail::segment_ratio_type<point_type, rescale_policy_type>::type
  130. > turn_info;
  131. std::vector<turn_info> turns;
  132. bg::detail::overlay::operation_type const op =
  133. OverlayType == bg::overlay_union
  134. ? bg::detail::overlay::operation_union
  135. : bg::detail::overlay::operation_intersection;
  136. bg::detail::get_turns::no_interrupt_policy policy;
  137. bg::get_turns<Reverse1, Reverse2, bg::detail::overlay::assign_null_policy>(g1, g2, rescale_policy, turns, policy);
  138. bg::enrich_intersection_points<Reverse1, Reverse2, OverlayType>(turns, op,
  139. g1, g2, rescale_policy, side_strategy_type());
  140. typedef bg::model::ring<typename bg::point_type<G2>::type> ring_type;
  141. typedef std::vector<ring_type> out_vector;
  142. out_vector v;
  143. bg::detail::overlay::overlay_null_visitor visitor;
  144. bg::detail::overlay::traverse
  145. <
  146. Reverse1, Reverse2,
  147. G1, G2
  148. >::apply(g1, g2, op, rescale_policy, turns, v, visitor);
  149. // Check number of resulting rings
  150. BOOST_CHECK_MESSAGE(expected_count == boost::size(v),
  151. "traverse: " << id
  152. << " (" << operation<OverlayType>() << ")"
  153. << " #shapes expected: " << expected_count
  154. << " detected: " << boost::size(v)
  155. << " type: " << string_from_type
  156. <typename bg::coordinate_type<G1>::type>::name()
  157. );
  158. // Check total area of resulting rings
  159. typename bg::default_area_result<G1>::type total_area = 0;
  160. BOOST_FOREACH(ring_type const& ring, v)
  161. {
  162. total_area += bg::area(ring);
  163. //std::cout << bg::wkt(ring) << std::endl;
  164. }
  165. BOOST_CHECK_CLOSE(expected_area, total_area, precision);
  166. #if defined(TEST_WITH_SVG)
  167. {
  168. std::ostringstream filename;
  169. filename << "traverse_" << operation<OverlayType>()
  170. << "_" << id
  171. << "_" << string_from_type<typename bg::coordinate_type<G1>::type>::name()
  172. << ".svg";
  173. std::ofstream svg(filename.str().c_str());
  174. bg::svg_mapper<typename bg::point_type<G2>::type> mapper(svg, 500, 500);
  175. mapper.add(g1);
  176. mapper.add(g2);
  177. // Input shapes in green (src=0) / blue (src=1)
  178. mapper.map(g1, "fill-opacity:0.5;fill:rgb(153,204,0);"
  179. "stroke:rgb(153,204,0);stroke-width:3");
  180. mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);"
  181. "stroke:rgb(51,51,153);stroke-width:3");
  182. // Traversal rings in magenta outline/red fill -> over blue/green this gives brown
  183. BOOST_FOREACH(ring_type const& ring, v)
  184. {
  185. mapper.map(ring, "fill-opacity:0.2;stroke-opacity:0.4;fill:rgb(255,0,0);"
  186. "stroke:rgb(255,0,255);stroke-width:8");
  187. }
  188. // turn points in orange, + enrichment/traversal info
  189. typedef typename bg::coordinate_type<G1>::type coordinate_type;
  190. // Simple map to avoid two texts at same place (note that can still overlap!)
  191. std::map<std::pair<int, int>, int> offsets;
  192. int index = 0;
  193. int const margin = 5;
  194. BOOST_FOREACH(turn_info const& turn, turns)
  195. {
  196. int lineheight = 8;
  197. mapper.map(turn.point, "fill:rgb(255,128,0);"
  198. "stroke:rgb(0,0,0);stroke-width:1", 3);
  199. {
  200. coordinate_type half = 0.5;
  201. coordinate_type ten = 10;
  202. // Map characteristics
  203. // Create a rounded off point
  204. std::pair<int, int> p
  205. = std::make_pair(
  206. boost::numeric_cast<int>(half
  207. + ten * bg::get<0>(turn.point)),
  208. boost::numeric_cast<int>(half
  209. + ten * bg::get<1>(turn.point))
  210. );
  211. std::string style = "fill:rgb(0,0,0);font-family:Arial;font-size:8px";
  212. if (turn.colocated)
  213. {
  214. style = "fill:rgb(255,0,0);font-family:Arial;font-size:8px";
  215. }
  216. else if (turn.discarded)
  217. {
  218. style = "fill:rgb(92,92,92);font-family:Arial;font-size:6px";
  219. lineheight = 6;
  220. }
  221. //if (! turn.is_discarded() && ! turn.blocked() && ! turn.both(bg::detail::overlay::operation_union))
  222. //if (! turn.discarded)
  223. {
  224. std::ostringstream out;
  225. out << index
  226. << ": " << bg::method_char(turn.method)
  227. << std::endl
  228. << "op: " << bg::operation_char(turn.operations[0].operation)
  229. << " / " << bg::operation_char(turn.operations[1].operation)
  230. //<< (turn.is_discarded() ? " (discarded) " : turn.blocked() ? " (blocked)" : "")
  231. << std::endl;
  232. out << "r: " << turn.operations[0].fraction
  233. << " ; " << turn.operations[1].fraction
  234. << std::endl;
  235. if (turn.operations[0].enriched.next_ip_index != -1)
  236. {
  237. out << "ip: " << turn.operations[0].enriched.next_ip_index;
  238. }
  239. else
  240. {
  241. out << "vx: " << turn.operations[0].enriched.travels_to_vertex_index
  242. << " -> ip: " << turn.operations[0].enriched.travels_to_ip_index;
  243. }
  244. out << " / ";
  245. if (turn.operations[1].enriched.next_ip_index != -1)
  246. {
  247. out << "ip: " << turn.operations[1].enriched.next_ip_index;
  248. }
  249. else
  250. {
  251. out << "vx: " << turn.operations[1].enriched.travels_to_vertex_index
  252. << " -> ip: " << turn.operations[1].enriched.travels_to_ip_index;
  253. }
  254. out << std::endl;
  255. /*out
  256. << std::setprecision(3)
  257. << "dist: " << boost::numeric_cast<double>(turn.operations[0].enriched.distance)
  258. << " / " << boost::numeric_cast<double>(turn.operations[1].enriched.distance)
  259. << std::endl
  260. << "vis: " << bg::visited_char(turn.operations[0].visited)
  261. << " / " << bg::visited_char(turn.operations[1].visited);
  262. */
  263. /*
  264. out << index
  265. << ": " << bg::operation_char(turn.operations[0].operation)
  266. << " " << bg::operation_char(turn.operations[1].operation)
  267. << " (" << bg::method_char(turn.method) << ")"
  268. << (turn.ignore() ? " (ignore) " : " ")
  269. << std::endl
  270. << "ip: " << turn.operations[0].enriched.travels_to_ip_index
  271. << "/" << turn.operations[1].enriched.travels_to_ip_index;
  272. if (turn.operations[0].enriched.next_ip_index != -1
  273. || turn.operations[1].enriched.next_ip_index != -1)
  274. {
  275. out << " [" << turn.operations[0].enriched.next_ip_index
  276. << "/" << turn.operations[1].enriched.next_ip_index
  277. << "]"
  278. ;
  279. }
  280. out << std::endl;
  281. out
  282. << "vx:" << turn.operations[0].enriched.travels_to_vertex_index
  283. << "/" << turn.operations[1].enriched.travels_to_vertex_index
  284. << std::endl
  285. << std::setprecision(3)
  286. << "dist: " << turn.operations[0].fraction
  287. << " / " << turn.operations[1].fraction
  288. << std::endl;
  289. */
  290. offsets[p] += lineheight;
  291. int offset = offsets[p];
  292. offsets[p] += lineheight * 3;
  293. mapper.text(turn.point, out.str(), style, margin, offset, lineheight);
  294. }
  295. index++;
  296. }
  297. }
  298. }
  299. #endif
  300. }
  301. };
  302. }
  303. template
  304. <
  305. typename G1, typename G2,
  306. bg::overlay_type OverlayType,
  307. bool Reverse1 = false,
  308. bool Reverse2 = false
  309. >
  310. struct test_traverse
  311. {
  312. typedef detail::test_traverse
  313. <
  314. G1, G2, OverlayType, Reverse1, Reverse2
  315. > detail_test_traverse;
  316. inline static void apply(std::string const& id, std::size_t expected_count, double expected_area,
  317. std::string const& wkt1, std::string const& wkt2,
  318. double precision = 0.001)
  319. {
  320. if (wkt1.empty() || wkt2.empty())
  321. {
  322. return;
  323. }
  324. G1 g1;
  325. bg::read_wkt(wkt1, g1);
  326. G2 g2;
  327. bg::read_wkt(wkt2, g2);
  328. bg::correct(g1);
  329. bg::correct(g2);
  330. //std::cout << bg::wkt(g1) << std::endl;
  331. //std::cout << bg::wkt(g2) << std::endl;
  332. // Try the overlay-function in both ways
  333. std::string caseid = id;
  334. //goto case_reversed;
  335. #ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
  336. std::cout << std::endl << std::endl << "# " << caseid << std::endl;
  337. #endif
  338. detail_test_traverse::apply(caseid, expected_count, expected_area, g1, g2, precision);
  339. #ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
  340. return;
  341. #endif
  342. //case_reversed:
  343. #if ! defined(BOOST_GEOMETRY_TEST_OVERLAY_NOT_EXCHANGED)
  344. caseid = id + "_rev";
  345. #ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
  346. std::cout << std::endl << std::endl << "# " << caseid << std::endl;
  347. #endif
  348. detail_test_traverse::apply(caseid, expected_count, expected_area, g2, g1, precision);
  349. #endif
  350. }
  351. };
  352. #if ! defined(BOOST_GEOMETRY_TEST_MULTI)
  353. template <typename T>
  354. void test_all(bool test_self_tangencies = true, bool test_mixed = false)
  355. {
  356. typedef bg::model::point<T, 2, bg::cs::cartesian> P;
  357. typedef bg::model::polygon<P> polygon;
  358. //typedef bg::model::box<P> box;
  359. typedef test_traverse
  360. <
  361. polygon, polygon, bg::overlay_intersection
  362. > test_traverse_intersection;
  363. typedef test_traverse
  364. <
  365. polygon, polygon, bg::overlay_union
  366. > test_traverse_union;
  367. // 1-6
  368. test_traverse_intersection::apply("1", 1, 5.4736, case_1[0], case_1[1]);
  369. test_traverse_intersection::apply("2", 1, 12.0545, case_2[0], case_2[1]);
  370. test_traverse_intersection::apply("3", 1, 5, case_3[0], case_3[1]);
  371. test_traverse_intersection::apply("4", 1, 10.2212, case_4[0], case_4[1]);
  372. test_traverse_intersection::apply("5", 2, 12.8155, case_5[0], case_5[1]);
  373. test_traverse_intersection::apply("6", 1, 4.5, case_6[0], case_6[1]);
  374. // 7-12
  375. test_traverse_intersection::apply("7", 0, 0, case_7[0], case_7[1]);
  376. test_traverse_intersection::apply("8", 0, 0, case_8[0], case_8[1]);
  377. test_traverse_intersection::apply("9", 0, 0, case_9[0], case_9[1]);
  378. test_traverse_intersection::apply("10", 0, 0, case_10[0], case_10[1]);
  379. test_traverse_intersection::apply("11", 1, 1, case_11[0], case_11[1]);
  380. test_traverse_intersection::apply("12", 2, 0.63333, case_12[0], case_12[1]);
  381. // 13-18
  382. test_traverse_intersection::apply("13", 0, 0, case_13[0], case_13[1]);
  383. test_traverse_intersection::apply("14", 0, 0, case_14[0], case_14[1]);
  384. test_traverse_intersection::apply("15", 0, 0, case_15[0], case_15[1]);
  385. test_traverse_intersection::apply("16", 0, 0, case_16[0], case_16[1]);
  386. test_traverse_intersection::apply("17", 1, 2, case_17[0], case_17[1]);
  387. test_traverse_intersection::apply("18", 1, 2, case_18[0], case_18[1]);
  388. // 19-24
  389. test_traverse_intersection::apply("19", 0, 0, case_19[0], case_19[1]);
  390. test_traverse_intersection::apply("20", 1, 5.5, case_20[0], case_20[1]);
  391. test_traverse_intersection::apply("21", 0, 0, case_21[0], case_21[1]);
  392. test_traverse_intersection::apply("22", 0, 0, case_22[0], case_22[1]);
  393. test_traverse_intersection::apply("23", 1, 1.4, case_23[0], case_23[1]);
  394. test_traverse_intersection::apply("24", 1, 1.0, case_24[0], case_24[1]);
  395. // 25-30
  396. test_traverse_intersection::apply("25", 0, 0, case_25[0], case_25[1]);
  397. test_traverse_intersection::apply("26", 0, 0, case_26[0], case_26[1]);
  398. test_traverse_intersection::apply("27", 1, 0.9545454, case_27[0], case_27[1]);
  399. test_traverse_intersection::apply("28", 1, 0.9545454, case_28[0], case_28[1]);
  400. test_traverse_intersection::apply("29", 1, 1.4, case_29[0], case_29[1]);
  401. test_traverse_intersection::apply("30", 1, 0.5, case_30[0], case_30[1]);
  402. // 31-36
  403. test_traverse_intersection::apply("31", 0, 0, case_31[0], case_31[1]);
  404. test_traverse_intersection::apply("32", 0, 0, case_32[0], case_32[1]);
  405. test_traverse_intersection::apply("33", 0, 0, case_33[0], case_33[1]);
  406. test_traverse_intersection::apply("34", 1, 0.5, case_34[0], case_34[1]);
  407. test_traverse_intersection::apply("35", 1, 1.0, case_35[0], case_35[1]);
  408. test_traverse_intersection::apply("36", 1, 1.625, case_36[0], case_36[1]);
  409. // 37-42
  410. test_traverse_intersection::apply("37", 2, 0.666666, case_37[0], case_37[1]);
  411. test_traverse_intersection::apply("38", 2, 0.971429, case_38[0], case_38[1]);
  412. test_traverse_intersection::apply("39", 1, 24, case_39[0], case_39[1]);
  413. test_traverse_intersection::apply("40", 0, 0, case_40[0], case_40[1]);
  414. test_traverse_intersection::apply("41", 1, 5, case_41[0], case_41[1]);
  415. test_traverse_intersection::apply("42", 1, 5, case_42[0], case_42[1]);
  416. // 43-48 - invalid polygons
  417. //test_traverse_intersection::apply("43", 2, 0.75, case_43[0], case_43[1]);
  418. //test_traverse_intersection::apply("44", 1, 44, case_44[0], case_44[1]);
  419. //test_traverse_intersection::apply("45", 1, 45, case_45[0], case_45[1]);
  420. //test_traverse_intersection::apply("46", 1, 46, case_46[0], case_46[1]);
  421. //test_traverse_intersection::apply("47", 1, 47, case_47[0], case_47[1]);
  422. // 49-54
  423. test_traverse_intersection::apply("50", 0, 0, case_50[0], case_50[1]);
  424. test_traverse_intersection::apply("51", 0, 0, case_51[0], case_51[1]);
  425. test_traverse_intersection::apply("52", 1, 10.5, case_52[0], case_52[1]);
  426. if (test_self_tangencies)
  427. {
  428. test_traverse_intersection::apply("53_st", 0, 0, case_53[0], case_53[1]);
  429. }
  430. test_traverse_intersection::apply("53_iet", 0, 0, case_53[0], case_53[2]);
  431. test_traverse_intersection::apply("54_iet_iet", 1, 2, case_54[1], case_54[3]);
  432. if (test_self_tangencies)
  433. {
  434. test_traverse_intersection::apply("54_st_iet", 1, 2, case_54[0], case_54[3]);
  435. test_traverse_intersection::apply("54_iet_st", 1, 2, case_54[1], case_54[2]);
  436. test_traverse_intersection::apply("54_st_st", 1, 2, case_54[0], case_54[2]);
  437. }
  438. if (test_self_tangencies)
  439. {
  440. // 55-60
  441. test_traverse_intersection::apply("55_st_st", 1, 2, case_55[0], case_55[2]);
  442. }
  443. test_traverse_intersection::apply("55_st_iet", 1, 2, case_55[0], case_55[3]);
  444. test_traverse_intersection::apply("55_iet_st", 1, 2, case_55[1], case_55[2]);
  445. if (test_self_tangencies)
  446. {
  447. test_traverse_intersection::apply("56", 2, 4.5, case_56[0], case_56[1]);
  448. }
  449. test_traverse_intersection::apply("55_iet_iet", 1, 2, case_55[1], case_55[3]);
  450. test_traverse_intersection::apply("57", 2, 5.9705882, case_57[0], case_57[1]);
  451. if (test_self_tangencies)
  452. {
  453. test_traverse_intersection::apply("58_st",
  454. 2, 0.333333, case_58[0], case_58[1]);
  455. test_traverse_intersection::apply("59_st",
  456. 2, 1.5416667, case_59[0], case_59[1]);
  457. test_traverse_intersection::apply("60_st",
  458. 3, 2, case_60[0], case_60[1]);
  459. }
  460. test_traverse_intersection::apply("58_iet",
  461. 2, 0.333333, case_58[0], case_58[2]);
  462. test_traverse_intersection::apply("59_iet",
  463. 2, 1.5416667, case_59[0], case_59[2]);
  464. test_traverse_intersection::apply("60_iet",
  465. 3, 2, case_60[0], case_60[2]);
  466. test_traverse_intersection::apply("61_st",
  467. 0, 0, case_61[0], case_61[1]);
  468. test_traverse_intersection::apply("70",
  469. 2, 4, case_70[0], case_70[1]);
  470. test_traverse_intersection::apply("71",
  471. 2, 2, case_71[0], case_71[1]);
  472. test_traverse_intersection::apply("72",
  473. 3, 2.85, case_72[0], case_72[1]);
  474. test_traverse_intersection::apply("79",
  475. 2, 20, case_79[0], case_79[1]);
  476. // Should be 3 shapes
  477. test_traverse_intersection::apply("82a",
  478. 2, 2.0, case_82[0], case_82[1]);
  479. // Should be 3 shapes
  480. test_traverse_intersection::apply("82b",
  481. 2, 2.0, case_82[0], case_82[2]);
  482. // other
  483. #ifdef BOOST_GEOMETRY_TEST_FAILURES
  484. // simplified version of 82, area should be different
  485. // missing IP at (1.5 3.5) from (1 4,1.5 3.5,2 4)x(2 4,1 3)
  486. test_traverse_intersection::apply("83",
  487. 1, 0.0, case_83[0], case_83[1]);
  488. #endif
  489. // pies (went wrong when not all cases where implemented, especially some collinear (opposite) cases
  490. test_traverse_intersection::apply("pie_16_4_12",
  491. 1, 491866.5, pie_16_4_12[0], pie_16_4_12[1]);
  492. test_traverse_intersection::apply("pie_23_21_12_500",
  493. 2, 2363199.3313, pie_23_21_12_500[0], pie_23_21_12_500[1]);
  494. test_traverse_intersection::apply("pie_23_23_3_2000",
  495. 2, 1867779.9349, pie_23_23_3_2000[0], pie_23_23_3_2000[1]);
  496. test_traverse_intersection::apply("pie_23_16_16",
  497. 2, 2128893.9555, pie_23_16_16[0], pie_23_16_16[1]);
  498. test_traverse_intersection::apply("pie_16_2_15_0",
  499. 0, 0, pie_16_2_15_0[0], pie_16_2_15_0[1]);
  500. test_traverse_intersection::apply("pie_4_13_15",
  501. 1, 490887.06678, pie_4_13_15[0], pie_4_13_15[1]);
  502. test_traverse_intersection::apply("pie_20_20_7_100",
  503. 2, 2183372.2718, pie_20_20_7_100[0], pie_20_20_7_100[1]);
  504. // 1-6
  505. test_traverse_union::apply("1", 1, 11.5264, case_1[0], case_1[1]);
  506. test_traverse_union::apply("2", 1, 17.9455, case_2[0], case_2[1]);
  507. test_traverse_union::apply("3", 1, 9, case_3[0], case_3[1]);
  508. test_traverse_union::apply("4", 3, 17.7788, case_4[0], case_4[1]);
  509. test_traverse_union::apply("5", 2, 18.4345, case_5[0], case_5[1]);
  510. test_traverse_union::apply("6", 1, 9, case_6[0], case_6[1]);
  511. // 7-12
  512. test_traverse_union::apply("7", 1, 9, case_7[0], case_7[1]);
  513. test_traverse_union::apply("8", 1, 12, case_8[0], case_8[1]);
  514. test_traverse_union::apply("9", 0, 0 /*UU 2, 11*/, case_9[0], case_9[1]);
  515. test_traverse_union::apply("10", 1, 9, case_10[0], case_10[1]);
  516. test_traverse_union::apply("11", 1, 8, case_11[0], case_11[1]);
  517. test_traverse_union::apply("12", 2, 8.36667, case_12[0], case_12[1]);
  518. // 13-18
  519. test_traverse_union::apply("13", 1, 4, case_13[0], case_13[1]);
  520. test_traverse_union::apply("14", 1, 12, case_14[0], case_14[1]);
  521. test_traverse_union::apply("15", 1, 12, case_15[0], case_15[1]);
  522. test_traverse_union::apply("16", 1, 9, case_16[0], case_16[1]);
  523. test_traverse_union::apply("17", 1, 8, case_17[0], case_17[1]);
  524. test_traverse_union::apply("18", 1, 8, case_18[0], case_18[1]);
  525. // 19-24
  526. test_traverse_union::apply("19", 1, 10, case_19[0], case_19[1]);
  527. test_traverse_union::apply("20", 1, 5.5, case_20[0], case_20[1]);
  528. test_traverse_union::apply("21", 0, 0, case_21[0], case_21[1]);
  529. test_traverse_union::apply("22", 0, 0 /*UU 2, 9.5*/, case_22[0], case_22[1]);
  530. test_traverse_union::apply("23", 1, 6.1, case_23[0], case_23[1]);
  531. test_traverse_union::apply("24", 1, 5.5, case_24[0], case_24[1]);
  532. // 25-30
  533. test_traverse_union::apply("25", 0, 0 /*UU 2, 7*/, case_25[0], case_25[1]);
  534. test_traverse_union::apply("26", 0, 0 /*UU 2, 7.5 */, case_26[0], case_26[1]);
  535. test_traverse_union::apply("27", 1, 8.04545, case_27[0], case_27[1]);
  536. test_traverse_union::apply("28", 1, 10.04545, case_28[0], case_28[1]);
  537. test_traverse_union::apply("29", 1, 8.1, case_29[0], case_29[1]);
  538. test_traverse_union::apply("30", 1, 6.5, case_30[0], case_30[1]);
  539. // 31-36
  540. test_traverse_union::apply("31", 0, 0 /*UU 2, 4.5 */, case_31[0], case_31[1]);
  541. test_traverse_union::apply("32", 0, 0 /*UU 2, 4.5 */, case_32[0], case_32[1]);
  542. test_traverse_union::apply("33", 0, 0 /*UU 2, 4.5 */, case_33[0], case_33[1]);
  543. test_traverse_union::apply("34", 1, 6.0, case_34[0], case_34[1]);
  544. test_traverse_union::apply("35", 1, 10.5, case_35[0], case_35[1]);
  545. test_traverse_union::apply("36", 1 /*UU 2*/, 14.375, case_36[0], case_36[1]);
  546. // 37-42
  547. test_traverse_union::apply("37", 1, 7.33333, case_37[0], case_37[1]);
  548. test_traverse_union::apply("38", 1, 9.52857, case_38[0], case_38[1]);
  549. test_traverse_union::apply("39", 1, 40.0, case_39[0], case_39[1]);
  550. test_traverse_union::apply("40", 0, 0 /*UU 2, 11 */, case_40[0], case_40[1]);
  551. test_traverse_union::apply("41", 1, 5, case_41[0], case_41[1]);
  552. test_traverse_union::apply("42", 1, 5, case_42[0], case_42[1]);
  553. // 43-48
  554. //test_traverse_union::apply("43", 3, 8.1875, case_43[0], case_43[1]);
  555. //test_traverse_union::apply("44", 1, 44, case_44[0], case_44[1]);
  556. //test_traverse_union::apply("45", 1, 45, case_45[0], case_45[1]);
  557. //test_traverse_union::apply("46", 1, 46, case_46[0], case_46[1]);
  558. //test_traverse_union::apply("47", 1, 47, case_47[0], case_47[1]);
  559. // 49-54
  560. test_traverse_union::apply("50", 1, 25, case_50[0], case_50[1]);
  561. test_traverse_union::apply("51", 0, 0, case_51[0], case_51[1]);
  562. test_traverse_union::apply("52", 1, 15.5, case_52[0], case_52[1]);
  563. if (test_self_tangencies)
  564. {
  565. test_traverse_union::apply("53_st", 2, 16, case_53[0], case_53[1]);
  566. }
  567. test_traverse_union::apply("53_iet",
  568. 2, 16, case_53[0], case_53[2]);
  569. if (test_self_tangencies)
  570. {
  571. test_traverse_union::apply("54_st_st", 2, 20, case_54[0], case_54[2]);
  572. test_traverse_union::apply("54_st_iet", 2, 20, case_54[0], case_54[3]);
  573. test_traverse_union::apply("54_iet_st", 2, 20, case_54[1], case_54[2]);
  574. }
  575. test_traverse_union::apply("54_iet_iet", 2, 20, case_54[1], case_54[3]);
  576. if (test_mixed)
  577. {
  578. test_traverse_union::apply("55_st_iet", 2, 18, case_55[0], case_55[3]);
  579. test_traverse_union::apply("55_iet_st", 2, 18, case_55[1], case_55[2]);
  580. // moved to mixed
  581. test_traverse_union::apply("55_iet_iet", 3, 18, case_55[1], case_55[3]);
  582. }
  583. // 55-60
  584. if (test_self_tangencies)
  585. {
  586. // 55 with both input polygons having self tangencies (st_st) generates 1 correct shape
  587. test_traverse_union::apply("55_st_st", 1, 18, case_55[0], case_55[2]);
  588. // 55 with one of them self-tangency, other int/ext ring tangency generate 2 correct shapes
  589. test_traverse_union::apply("56", 2, 14, case_56[0], case_56[1]);
  590. }
  591. test_traverse_union::apply("57", 1, 14.029412, case_57[0], case_57[1]);
  592. if (test_self_tangencies)
  593. {
  594. test_traverse_union::apply("58_st",
  595. 4, 12.16666, case_58[0], case_58[1]);
  596. test_traverse_union::apply("59_st",
  597. 2, 17.208333, case_59[0], case_59[1]);
  598. test_traverse_union::apply("60_st",
  599. 3, 19, case_60[0], case_60[1]);
  600. }
  601. test_traverse_union::apply("58_iet",
  602. 4, 12.16666, case_58[0], case_58[2]);
  603. test_traverse_union::apply("59_iet",
  604. 1, -3.791666, // 2, 17.208333), outer ring (ii/ix) is done by ASSEMBLE
  605. case_59[0], case_59[2]);
  606. test_traverse_union::apply("60_iet",
  607. 3, 19, case_60[0], case_60[2]);
  608. test_traverse_union::apply("61_st",
  609. 1, 4, case_61[0], case_61[1]);
  610. test_traverse_union::apply("70",
  611. 1, 9, case_70[0], case_70[1]);
  612. test_traverse_union::apply("71",
  613. 2, 9, case_71[0], case_71[1]);
  614. test_traverse_union::apply("72",
  615. 1, 10.65, case_72[0], case_72[1]);
  616. // other
  617. test_traverse_union::apply("box_poly5",
  618. 2, 4.7191,
  619. "POLYGON((1.5 1.5, 1.5 2.5, 4.5 2.5, 4.5 1.5, 1.5 1.5))",
  620. "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))");
  621. test_traverse_intersection::apply("collinear_overlaps",
  622. 1, 24,
  623. collinear_overlaps[0], collinear_overlaps[1]);
  624. test_traverse_union::apply("collinear_overlaps",
  625. 1, 50,
  626. collinear_overlaps[0], collinear_overlaps[1]);
  627. test_traverse_intersection::apply("many_situations", 1, 184, case_many_situations[0], case_many_situations[1]);
  628. test_traverse_union::apply("many_situations",
  629. 1, 207, case_many_situations[0], case_many_situations[1]);
  630. // From "intersection piets", robustness test.
  631. // This all went wrong in the past
  632. // (when not all cases (get_turns) where implemented,
  633. // especially important are some collinear (opposite) cases)
  634. test_traverse_union::apply("pie_16_4_12",
  635. 1, 3669665.5, pie_16_4_12[0], pie_16_4_12[1]);
  636. test_traverse_union::apply("pie_23_21_12_500",
  637. 1, 6295516.7185, pie_23_21_12_500[0], pie_23_21_12_500[1]);
  638. test_traverse_union::apply("pie_23_23_3_2000",
  639. 1, 7118735.0530, pie_23_23_3_2000[0], pie_23_23_3_2000[1]);
  640. test_traverse_union::apply("pie_23_16_16",
  641. 1, 5710474.5406, pie_23_16_16[0], pie_23_16_16[1]);
  642. test_traverse_union::apply("pie_16_2_15_0",
  643. 1, 3833641.5, pie_16_2_15_0[0], pie_16_2_15_0[1]);
  644. test_traverse_union::apply("pie_4_13_15",
  645. 1, 2208122.43322, pie_4_13_15[0], pie_4_13_15[1]);
  646. test_traverse_union::apply("pie_20_20_7_100",
  647. 1, 5577158.72823, pie_20_20_7_100[0], pie_20_20_7_100[1]);
  648. /*
  649. if (test_not_valid)
  650. {
  651. test_traverse_union::apply("pie_5_12_12_0_7s",
  652. 1, 3271710.48516, pie_5_12_12_0_7s[0], pie_5_12_12_0_7s[1]);
  653. }
  654. */
  655. static const bool is_float
  656. = boost::is_same<T, float>::value;
  657. static const double float_might_deviate_more = is_float ? 0.1 : 0.001; // In some cases up to 1 promille permitted
  658. // GCC: does not everywhere handle float correctly (in our algorithms)
  659. static bool const is_float_on_non_msvc =
  660. #if defined(_MSC_VER)
  661. false;
  662. #else
  663. is_float;
  664. #endif
  665. // From "Random Ellipse Stars", robustness test.
  666. // This all went wrong in the past
  667. // when using Determinant/ra/rb and comparing with 0/1
  668. // Solved now by avoiding determinant / using sides
  669. // ("hv" means "high volume")
  670. {
  671. double deviation = is_float ? 0.01 : 0.001;
  672. test_traverse_union::apply("hv1", 1, 1624.508688461573, hv_1[0], hv_1[1], deviation);
  673. test_traverse_intersection::apply("hv1", 1, 1622.7200125123809, hv_1[0], hv_1[1], deviation);
  674. test_traverse_union::apply("hv2", 1, 1622.9193392726836, hv_2[0], hv_2[1], deviation);
  675. test_traverse_intersection::apply("hv2", 1, 1622.1733591429329, hv_2[0], hv_2[1], deviation);
  676. test_traverse_union::apply("hv3", 1, 1624.22079205664, hv_3[0], hv_3[1], deviation);
  677. test_traverse_intersection::apply("hv3", 1, 1623.8265057282042, hv_3[0], hv_3[1], deviation);
  678. if ( BOOST_GEOMETRY_CONDITION(! is_float) )
  679. {
  680. test_traverse_union::apply("hv4", 1, 1626.5146964146334, hv_4[0], hv_4[1], deviation);
  681. test_traverse_intersection::apply("hv4", 1, 1626.2580370864305, hv_4[0], hv_4[1], deviation);
  682. test_traverse_union::apply("hv5", 1, 1624.2158307261871, hv_5[0], hv_5[1], deviation);
  683. test_traverse_intersection::apply("hv5", 1, 1623.4506071521519, hv_5[0], hv_5[1], deviation);
  684. // Case 2009-12-07
  685. test_traverse_intersection::apply("hv6", 1, 1604.6318757402121, hv_6[0], hv_6[1], deviation);
  686. test_traverse_union::apply("hv6", 1, 1790.091872401327, hv_6[0], hv_6[1], deviation);
  687. // Case 2009-12-08, needing sorting on side in enrich_intersection_points
  688. test_traverse_union::apply("hv7", 1, 1624.5779453641017, hv_7[0], hv_7[1], deviation);
  689. test_traverse_intersection::apply("hv7", 1, 1623.6936420295772, hv_7[0], hv_7[1], deviation);
  690. }
  691. }
  692. // From "Random Ellipse Stars", robustness test.
  693. // This all went wrong in the past when distances (see below) were zero (dz)
  694. // "Distance zero", dz, means: the distance between two intersection points
  695. // on a same segment is 0, therefore it can't be sorted normally, therefore
  696. // the chance is 50% that the segments are not sorted correctly and the wrong
  697. // decision is taken.
  698. // Solved now (by sorting on sides in those cases)
  699. if ( BOOST_GEOMETRY_CONDITION(! is_float_on_non_msvc) )
  700. {
  701. test_traverse_intersection::apply("dz_1",
  702. 2, 16.887537949472005, dz_1[0], dz_1[1]);
  703. test_traverse_union::apply("dz_1",
  704. 3, 1444.2621305732864, dz_1[0], dz_1[1]);
  705. test_traverse_intersection::apply("dz_2",
  706. 2, 68.678921274288541, dz_2[0], dz_2[1]);
  707. test_traverse_union::apply("dz_2",
  708. 1, 1505.4202304878663, dz_2[0], dz_2[1]);
  709. test_traverse_intersection::apply("dz_3",
  710. 5, 192.49316937645651, dz_3[0], dz_3[1]);
  711. test_traverse_union::apply("dz_3",
  712. 5, 1446.496005965641, dz_3[0], dz_3[1]);
  713. test_traverse_intersection::apply("dz_4",
  714. 1, 473.59423868207693, dz_4[0], dz_4[1]);
  715. test_traverse_union::apply("dz_4",
  716. 1, 1871.6125138873476, dz_4[0], dz_4[1]);
  717. }
  718. // Real-life problems
  719. // SNL (Subsidiestelsel Natuur & Landschap - verAANnen)
  720. test_traverse_intersection::apply("snl-1",
  721. 2, 286.996062095888,
  722. snl_1[0], snl_1[1],
  723. float_might_deviate_more);
  724. test_traverse_union::apply("snl-1",
  725. 2, 51997.5408506132,
  726. snl_1[0], snl_1[1],
  727. float_might_deviate_more);
  728. {
  729. test_traverse_intersection::apply("isov",
  730. 1, 88.1920, isovist[0], isovist[1],
  731. float_might_deviate_more);
  732. test_traverse_union::apply("isov",
  733. 1, 313.3604, isovist[0], isovist[1],
  734. float_might_deviate_more);
  735. }
  736. if ( BOOST_GEOMETRY_CONDITION(! is_float) )
  737. {
  738. /* TODO check this BSG 2013-09-24
  739. #if defined(_MSC_VER)
  740. double const expected = if_typed_tt<T>(3.63794e-17, 0.0);
  741. int expected_count = if_typed_tt<T>(1, 0);
  742. #else
  743. double const expected = if_typed<T, long double>(2.77555756156289135106e-17, 0.0);
  744. int expected_count = if_typed<T, long double>(1, 0);
  745. #endif
  746. // Calculate intersection/union of two triangles. Robustness case.
  747. // ttmath can form a very small intersection triangle
  748. // (which is even not accomplished by SQL Server/PostGIS)
  749. std::string const caseid = "ggl_list_20110820_christophe";
  750. test_traverse_intersection::apply(caseid,
  751. expected_count, expected,
  752. ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1]);
  753. test_traverse_union::apply(caseid,
  754. 1, 67.3550722317627,
  755. ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1]);
  756. */
  757. }
  758. test_traverse_union::apply("buffer_rt_f",
  759. 1, 4.60853,
  760. buffer_rt_f[0], buffer_rt_f[1]);
  761. test_traverse_intersection::apply("buffer_rt_f",
  762. 1, 0.0002943725152286,
  763. buffer_rt_f[0], buffer_rt_f[1], 0.01);
  764. test_traverse_union::apply("buffer_rt_g",
  765. 1, 16.571,
  766. buffer_rt_g[0], buffer_rt_g[1]);
  767. test_traverse_union::apply("buffer_rt_g_boxes1",
  768. 1, 20,
  769. buffer_rt_g_boxes[0], buffer_rt_g_boxes[1]);
  770. test_traverse_union::apply("buffer_rt_g_boxes2",
  771. 1, 24,
  772. buffer_rt_g_boxes[0], buffer_rt_g_boxes[2]);
  773. test_traverse_union::apply("buffer_rt_g_boxes3",
  774. 1, 28,
  775. buffer_rt_g_boxes[0], buffer_rt_g_boxes[3]);
  776. test_traverse_union::apply("buffer_rt_g_boxes43",
  777. 1, 30,
  778. buffer_rt_g_boxes[4], buffer_rt_g_boxes[3]);
  779. test_traverse_union::apply("buffer_rt_l",
  780. 1, 19.3995, buffer_rt_l[0], buffer_rt_l[1]);
  781. test_traverse_union::apply("buffer_mp2",
  782. 1, 36.7535642, buffer_mp2[0], buffer_mp2[1], 0.01);
  783. test_traverse_union::apply("collinear_opposite_rr",
  784. 1, 6.41, collinear_opposite_right[0], collinear_opposite_right[1]);
  785. test_traverse_union::apply("collinear_opposite_ll",
  786. 1, 11.75, collinear_opposite_left[0], collinear_opposite_left[1]);
  787. test_traverse_union::apply("collinear_opposite_ss",
  788. 1, 6, collinear_opposite_straight[0], collinear_opposite_straight[1]);
  789. test_traverse_union::apply("collinear_opposite_lr",
  790. 1, 8.66, collinear_opposite_left[0], collinear_opposite_right[1]);
  791. test_traverse_union::apply("collinear_opposite_rl",
  792. 1, 9, collinear_opposite_right[0], collinear_opposite_left[1]);
  793. test_traverse_intersection::apply("ticket_7462", 1, 0.220582, ticket_7462[0], ticket_7462[1]);
  794. test_traverse_intersection::apply
  795. ("ticket_9081_15", 1, 0.006889578,
  796. ticket_9081_15[0], ticket_9081_15[1]);
  797. #ifdef BOOST_GEOMETRY_OVERLAY_NO_THROW
  798. {
  799. // NOTE: currently throws (normally)
  800. std::string caseid = "ggl_list_20120229_volker";
  801. test_traverse_union::apply(caseid,
  802. 1, 99,
  803. ggl_list_20120229_volker[0], ggl_list_20120229_volker[1]);
  804. test_traverse_intersection::apply(caseid,
  805. 1, 99,
  806. ggl_list_20120229_volker[0], ggl_list_20120229_volker[1]);
  807. caseid = "ggl_list_20120229_volker_2";
  808. test_traverse_union::apply(caseid,
  809. 1, 99,
  810. ggl_list_20120229_volker[2], ggl_list_20120229_volker[1]);
  811. test_traverse_intersection::apply(caseid,
  812. 1, 99,
  813. ggl_list_20120229_volker[2], ggl_list_20120229_volker[1]);
  814. }
  815. #endif
  816. }
  817. #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
  818. template <typename T>
  819. void test_open()
  820. {
  821. typedef bg::model::polygon
  822. <
  823. bg::model::point<T, 2, bg::cs::cartesian>,
  824. true, false
  825. > polygon;
  826. typedef test_traverse
  827. <
  828. polygon, polygon, bg::overlay_intersection
  829. > test_traverse_intersection;
  830. typedef test_traverse
  831. <
  832. polygon, polygon, bg::overlay_union
  833. > test_traverse_union;
  834. test_traverse_intersection::apply("open_1", 1, 5.4736,
  835. open_case_1[0], open_case_1[1]);
  836. test_traverse_union::apply("open_1", 1, 11.5264,
  837. open_case_1[0], open_case_1[1]);
  838. }
  839. template <typename T>
  840. void test_ccw()
  841. {
  842. typedef bg::model::polygon
  843. <
  844. bg::model::point<T, 2, bg::cs::cartesian>,
  845. false, true
  846. > polygon;
  847. test_traverse<polygon, polygon, bg::overlay_intersection, true, true>::apply("ccw_1", 1, 5.4736,
  848. ccw_case_1[0], ccw_case_1[1]);
  849. test_traverse<polygon, polygon, bg::overlay_union, true, true>::apply("ccw_1", 1, 11.5264,
  850. ccw_case_1[0], ccw_case_1[1]);
  851. }
  852. #endif
  853. int test_main(int, char* [])
  854. {
  855. #if defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
  856. test_all<double>();
  857. #else
  858. test_all<float>();
  859. test_all<double>();
  860. test_open<double>();
  861. test_ccw<double>();
  862. #if ! defined(_MSC_VER)
  863. test_all<long double>();
  864. #endif
  865. #ifdef HAVE_TTMATH
  866. test_all<ttmath_big>();
  867. #endif
  868. #endif
  869. return 0;
  870. }
  871. #endif