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