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