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 
BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(std::vector)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>
test_areal_clip()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>
test_boxes(std::string const & wkt1,std::string const & wkt2,double expected_area,bool expected_result)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>
test_point_output()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>
test_areal_linear()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>
test_linear_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>
test_all()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 
test_pointer_version()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>
test_exception()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>
test_rational()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>
test_boxes_per_d(P const & min1,P const & max1,P const & min2,P const & max2,bool expected_result)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>
test_boxes_nd()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>
test_ticket_10868(std::string const & wkt_out)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 
test_main(int,char * [])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 }
975