]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/test/algorithms/set_operations/intersection/intersection.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / set_operations / intersection / intersection.cpp
CommitLineData
7c673cae
FG
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
b32b8144
FG
8// This file was modified by Oracle on 2015, 2016, 2017.
9// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
7c673cae
FG
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
43BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(std::vector)
44
b32b8144
FG
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#if ! defined(BOOST_GEOMETRY_INCLUDE_SELF_TURNS)
50 #define TEST_INTERSECTION_IGNORE(caseid, clips, points, area) \
51 { ut_settings ignore_validity; ignore_validity.test_validity = false; \
52 (test_one<Polygon, Polygon, Polygon>) \
53 ( #caseid, caseid[0], caseid[1], clips, points, area, ignore_validity); }
54#endif
7c673cae
FG
55
56template <typename Polygon>
57void test_areal()
58{
59 typedef typename bg::coordinate_type<Polygon>::type ct;
60 bool const ccw = bg::point_order<Polygon>::value == bg::counterclockwise;
61 bool const open = bg::closure<Polygon>::value == bg::open;
62
7c673cae
FG
63 test_one<Polygon, Polygon, Polygon>("simplex_with_empty_1",
64 simplex_normal[0], polygon_empty,
65 0, 0, 0.0);
66 test_one<Polygon, Polygon, Polygon>("simplex_with_empty_2",
67 polygon_empty, simplex_normal[0],
68 0, 0, 0.0);
69
70 test_one<Polygon, Polygon, Polygon>("simplex_normal",
71 simplex_normal[0], simplex_normal[1],
72 1, 7, 5.47363293);
73 test_one<Polygon, Polygon, Polygon>("star_ring", example_star, example_ring,
74 1, 18, 2.80983);
75
76 test_one<Polygon, Polygon, Polygon>("star_poly", example_star, example_polygon,
77 1, 0, // CLN: 23 points, other types: 22 point (one is merged)
78 2.5020508);
79 test_one<Polygon, Polygon, Polygon>("first_within_second1",
80 first_within_second[0], first_within_second[1],
81 1, 5, 1.0);
82
83 test_one<Polygon, Polygon, Polygon>("first_within_second2",
84 first_within_second[1], first_within_second[0],
85 1, 5, 1.0);
86
87 test_one<Polygon, Polygon, Polygon>("first_within_hole_of_second",
88 first_within_hole_of_second[0], first_within_hole_of_second[1],
89 0, 0, 0.0);
90
91 // Two forming new hole
92 test_one<Polygon, Polygon, Polygon>("new_hole",
93 new_hole[0], new_hole[1],
94 2, 10, 2.0);
95
96 // Two identical
97 test_one<Polygon, Polygon, Polygon>("identical",
98 identical[0], identical[1],
99 1, 5, 1.0);
100
101 test_one<Polygon, Polygon, Polygon>("intersect_exterior_and_interiors_winded",
102 intersect_exterior_and_interiors_winded[0], intersect_exterior_and_interiors_winded[1],
103 1, 14, 25.2166667);
104
105 test_one<Polygon, Polygon, Polygon>("intersect_holes_disjoint",
106 intersect_holes_disjoint[0], intersect_holes_disjoint[1],
107 1, 15, 18.0);
108
109 test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect",
110 intersect_holes_intersect[0], intersect_holes_intersect[1],
111 1, 14, 18.25);
112
113 test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect_and_disjoint",
114 intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1],
115 1, 19, 17.25);
116
117 test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect_and_touch",
118 intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1],
119 1, 23, 17.25);
120
121 test_one<Polygon, Polygon, Polygon>("intersect_holes_new_ring",
122 intersect_holes_new_ring[0], intersect_holes_new_ring[1],
123 2, 23, 122.1039);
124
125 test_one<Polygon, Polygon, Polygon>("winded",
126 winded[0], winded[1],
127 1, 22, 40.0);
128
129 test_one<Polygon, Polygon, Polygon>("within_holes_disjoint",
130 within_holes_disjoint[0], within_holes_disjoint[1],
131 1, 15, 23.0);
132
133 test_one<Polygon, Polygon, Polygon>("side_side",
134 side_side[0], side_side[1],
135 0, 0, 0.0);
136
137 test_one<Polygon, Polygon, Polygon>("two_bends",
138 two_bends[0], two_bends[1],
139 1, 7, 24.0);
140
141 test_one<Polygon, Polygon, Polygon>("star_comb_15",
142 star_comb_15[0], star_comb_15[1],
143 28, 150, 189.952883);
144
145 test_one<Polygon, Polygon, Polygon>("simplex_normal",
146 simplex_normal[0], simplex_normal[1],
147 1, 7, 5.47363293);
148
149 test_one<Polygon, Polygon, Polygon>("distance_zero",
150 distance_zero[0], distance_zero[1],
151 1, 0 /* f: 4, other: 5 */, 0.29516139, ut_settings(0.01));
152
153 test_one<Polygon, Polygon, Polygon>("equal_holes_disjoint",
154 equal_holes_disjoint[0], equal_holes_disjoint[1],
155 1, 20, 81.0 - 2.0 * 3.0 * 3.0 - 3.0 * 7.0);
156
157 test_one<Polygon, Polygon, Polygon>("only_hole_intersections1",
158 only_hole_intersections[0], only_hole_intersections[1],
159 1, 21, 178.090909);
160 test_one<Polygon, Polygon, Polygon>("only_hole_intersection2",
161 only_hole_intersections[0], only_hole_intersections[2],
162 1, 21, 149.090909);
163
164 test_one<Polygon, Polygon, Polygon>("fitting",
165 fitting[0], fitting[1],
166 0, 0, 0.0);
167
168 test_one<Polygon, Polygon, Polygon>("crossed",
169 crossed[0], crossed[1],
170 3, 0, 1.5);
171
172 test_one<Polygon, Polygon, Polygon>("pie_2_3_23_0",
173 pie_2_3_23_0[0], pie_2_3_23_0[1],
174 1, 4, 163292.679042133, ut_settings(0.1));
175
b32b8144
FG
176 {
177 ut_settings settings(if_typed_tt<ct>(0.01, 0.1));
178
7c673cae 179#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
b32b8144 180 settings.test_validity = false;
7c673cae
FG
181#endif
182
b32b8144
FG
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
7c673cae
FG
191 test_one<Polygon, Polygon, Polygon>("geos_1",
192 geos_1[0], geos_1[1],
193 1, -1, 3461.0214843, // MSVC 14 reports 3461.025390625
194 ut_settings(0.005, false));
195
196 // Expectations:
197 // In most cases: 0 (no intersection)
198 // In some cases: 1.430511474609375e-05 (clang/gcc on Xubuntu using b2)
199 // In some cases: 5.6022983000000002e-05 (powerpc64le-gcc-6-0)
200 test_one<Polygon, Polygon, Polygon>("geos_2",
201 geos_2[0], geos_2[1],
202 0, 0, 6.0e-5, ut_settings(-1.0)); // -1 denotes: compare with <=
203
204#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
205 test_one<Polygon, Polygon, Polygon>("geos_3",
206 geos_3[0], geos_3[1],
207 0, 0, 0.0);
208#endif
209 test_one<Polygon, Polygon, Polygon>("geos_4",
210 geos_4[0], geos_4[1],
211 1, -1, 0.08368849);
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 is changed to 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,
234 #if defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
235 0.40
236 #else
237 0.397162651, ut_settings(0.01)
238 #endif
239 );
240
241#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
242 test_one<Polygon, Polygon, Polygon>("ggl_list_20110627_phillip",
243 ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
244 1, if_typed_tt<ct>(6, 5), 11151.6618);
245#endif
246
247 test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
248 ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
249 3, 16, 35723.8506317139);
250
251 test_one<Polygon, Polygon, Polygon>("ggl_list_20131119_james",
252 ggl_list_20131119_james[0], ggl_list_20131119_james[1],
253 1, 4, 6.6125873045, ut_settings(0.1));
254
255 test_one<Polygon, Polygon, Polygon>("ggl_list_20140223_shalabuda",
256 ggl_list_20140223_shalabuda[0], ggl_list_20140223_shalabuda[1],
257 1, 4, 3.77106, ut_settings(0.001));
258
259 // Mailed to the Boost.Geometry list on 2014/03/21 by 7415963@gmail.com
260 test_one<Polygon, Polygon, Polygon>("ggl_list_20140321_7415963",
261 ggl_list_20140321_7415963[0], ggl_list_20140321_7415963[1],
262 0, 0, 0, ut_settings(0.1));
263
264#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
265 test_one<Polygon, Polygon, Polygon>("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1],
266 1, 4, 0.00029437899183903937, ut_settings(0.01));
267
268 test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
269 1, 0, 2.914213562373);
270#endif
271
272 test_one<Polygon, Polygon, Polygon>("ticket_8254", ticket_8254[0], ticket_8254[1],
273 1, 4, 3.635930e-08, ut_settings(0.01));
274 test_one<Polygon, Polygon, Polygon>("ticket_6958", ticket_6958[0], ticket_6958[1],
275 1, 4, 4.34355e-05, ut_settings(0.01));
276 test_one<Polygon, Polygon, Polygon>("ticket_8652", ticket_8652[0], ticket_8652[1],
277 1, 4, 0.0003);
278
279 test_one<Polygon, Polygon, Polygon>("ticket_8310a", ticket_8310a[0], ticket_8310a[1],
280 1, 5, 0.3843747);
281 test_one<Polygon, Polygon, Polygon>("ticket_8310b", ticket_8310b[0], ticket_8310b[1],
282 1, 5, 0.3734379);
283 test_one<Polygon, Polygon, Polygon>("ticket_8310c", ticket_8310c[0], ticket_8310c[1],
284 1, 5, 0.4689541);
285
286 test_one<Polygon, Polygon, Polygon>("ticket_9081_15",
287 ticket_9081_15[0], ticket_9081_15[1],
288 1, 4, 0.0068895780745301394);
289
290 test_one<Polygon, Polygon, Polygon>("ticket_10108_a",
291 ticket_10108_a[0], ticket_10108_a[1],
292 0, 0, 0.0);
293
294#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
295 // msvc 5.6023011e-5
296 // mingw 5.6022954e-5
297 test_one<Polygon, Polygon, Polygon>("ticket_10108_b",
298 ticket_10108_b[0], ticket_10108_b[1],
299 0, 0, 5.6022983e-5);
300#endif
301
302 test_one<Polygon, Polygon, Polygon>("ticket_10747_a",
303 ticket_10747_a[0], ticket_10747_a[1],
b32b8144 304 1, 4, 70368744177664.0);
7c673cae
FG
305 test_one<Polygon, Polygon, Polygon>("ticket_10747_b",
306 ticket_10747_b[0], ticket_10747_b[1],
b32b8144 307 1, 4, 7036874417766400.0);
7c673cae
FG
308 test_one<Polygon, Polygon, Polygon>("ticket_10747_c",
309 ticket_10747_c[0], ticket_10747_c[1],
b32b8144 310 1, 4, 17592186044416.0);
7c673cae
FG
311 test_one<Polygon, Polygon, Polygon>("ticket_10747_d",
312 ticket_10747_d[0], ticket_10747_d[1],
b32b8144 313 1, 4, 703687777321.0);
7c673cae
FG
314 test_one<Polygon, Polygon, Polygon>("ticket_10747_e",
315 ticket_10747_e[0], ticket_10747_e[1],
316 1, 4, 7.0368748575710959e-15);
317
318 test_one<Polygon, Polygon, Polygon>("ticket_11576",
319 ticket_11576[0], ticket_11576[1],
320 1, 0, 5.585617332907136e-07);
321
322 test_one<Polygon, Polygon, Polygon>("ticket_9563", ticket_9563[0], ticket_9563[1],
323 1, 8, 129.90381);
324
325 test_one<Polygon, Polygon, Polygon>("buffer_mp1", buffer_mp1[0], buffer_mp1[1],
326 1, 31, 2.271707796);
327 test_one<Polygon, Polygon, Polygon>("buffer_mp2", buffer_mp2[0], buffer_mp2[1],
328 1, 29, 0.457126);
329
330 test_one<Polygon, Polygon, Polygon>("case_58_iet",
331 case_58[0], case_58[2],
332 2, -1, 1.0 / 3.0);
333
334 test_one<Polygon, Polygon, Polygon>("case_80",
335 case_80[0], case_80[1],
336 0, -1, 0.0);
337
338 test_one<Polygon, Polygon, Polygon>("case_81",
339 case_81[0], case_81[1],
340 0, -1, 0.0);
341
b32b8144
FG
342 test_one<Polygon, Polygon, Polygon>("case_101",
343 case_101[0], case_101[1],
344 0, -1, 6.25);
345 test_one<Polygon, Polygon, Polygon>("case_102",
346 case_102[0], case_102[1],
347 0, -1, 3.1875);
348
349 test_one<Polygon, Polygon, Polygon>("case_103",
350 case_103[0], case_103[1],
351 1, -1, 0.5);
352 test_one<Polygon, Polygon, Polygon>("case_104",
353 case_104[0], case_104[1],
354 0, -1, 0.0);
355
356 TEST_INTERSECTION(case_105, 1, 34, 76.0);
357
358#ifdef BOOST_GEOMETRY_INCLUDE_SELF_TURNS
359 TEST_INTERSECTION(case_106, 2, -1, 3.5);
360 TEST_INTERSECTION(case_107, 3, -1, 3.0);
361#else
362 TEST_INTERSECTION_IGNORE(case_106, 0, -1, 3.5);
363 TEST_INTERSECTION_IGNORE(case_107, 0, -1, 3.0);
364#endif
365
366
7c673cae
FG
367 test_one<Polygon, Polygon, Polygon>("mysql_21964049",
368 mysql_21964049[0], mysql_21964049[1],
369 0, -1, 0.0);
370
371 test_one<Polygon, Polygon, Polygon>("mysql_21964465",
372 mysql_21964465[0], mysql_21964465[1],
373 0, -1, 0.0);
374
375 test_one<Polygon, Polygon, Polygon>("mysql_21965285_b_inv",
376 mysql_21965285_b_inv[0],
377 mysql_21965285_b_inv[1],
378 2, -1, 183.71376870369406);
379
b32b8144
FG
380 // Needs self-intersections to solve validity
381#ifdef BOOST_GEOMETRY_INCLUDE_SELF_TURNS
382 TEST_INTERSECTION(mysql_23023665_6, 2, 0, 11.812440191387557);
383#else
384 TEST_INTERSECTION_IGNORE(mysql_23023665_6, 1, -1, 11.812440191387557);
385#endif
7c673cae
FG
386
387 test_one<Polygon, Polygon, Polygon>("mysql_23023665_10",
388 mysql_23023665_10[0], mysql_23023665_10[1],
b32b8144 389 1, 0, -1, 54.701340543162523);
7c673cae
FG
390
391 test_one<Polygon, Polygon, Polygon>("mysql_23023665_11",
392 mysql_23023665_11[0], mysql_23023665_11[1],
b32b8144 393 1, 0, -1, 35.933385462482065);
7c673cae
FG
394
395// test_one<Polygon, Polygon, Polygon>(
396// "polygon_pseudo_line",
397// "Polygon((0 0,0 4,4 4,4 0,0 0))",
398// "Polygon((2 -2,2 -1,2 6,2 -2))",
399// 5, 22, 1.1901714);
400}
401
402template <typename Polygon, typename Box>
403void test_areal_clip()
404{
405 test_one<Polygon, Box, Polygon>("boxring", example_box, example_ring,
406 2, 12, 1.09125);
407 test_one<Polygon, Polygon, Box>("boxring2", example_ring,example_box,
408 2, 12, 1.09125);
409
410 test_one<Polygon, Box, Polygon>("boxpoly", example_box, example_polygon,
411 3, 19, 0.840166);
412
413 test_one<Polygon, Box, Polygon>("poly1", example_box,
414 "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))",
415 2, 12, 1.09125);
416
417 test_one<Polygon, Box, Polygon>("clip_poly2", example_box,
418 "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))",
419 2, 12, 1.00375);
420
421 test_one<Polygon, Box, Polygon>("clip_poly3", example_box,
422 "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))",
423 2, 12, 1.00375);
424
425 test_one<Polygon, Box, Polygon>("clip_poly4", example_box,
426 "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))",
427 2, 16, 0.860892);
428
429 test_one<Polygon, Box, Polygon>("clip_poly5", example_box,
430 "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))",
431 2, 11, 0.7575961);
432
433 test_one<Polygon, Box, Polygon>("clip_poly6", example_box,
434 "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))",
435 2, 13, 1.0744456);
436
437 test_one<Polygon, Box, Polygon>("clip_poly7", "Box(0 0, 3 3)",
438 "POLYGON((2 2, 1 4, 2 4, 3 3, 2 2))",
439 1, 4, 0.75);
440}
441
442
443template <typename Box>
444void test_boxes(std::string const& wkt1, std::string const& wkt2, double expected_area, bool expected_result)
445{
446 Box box1, box2;
447 bg::read_wkt(wkt1, box1);
448 bg::read_wkt(wkt2, box2);
449
450 Box box_out;
451 bg::assign_zero(box_out);
452 bool detected = bg::intersection(box1, box2, box_out);
453 typename bg::default_area_result<Box>::type area = bg::area(box_out);
454
455 BOOST_CHECK_EQUAL(detected, expected_result);
456 if (detected && expected_result)
457 {
458 BOOST_CHECK_CLOSE(area, expected_area, 0.01);
459 }
460}
461
462template <typename P>
463void test_point_output()
464{
465 typedef bg::model::linestring<P> linestring;
466 typedef bg::model::polygon<P> polygon;
467 typedef bg::model::box<P> box;
468 //typedef bg::model::segment<P> segment;
469
470 test_point_output<polygon, polygon>(simplex_normal[0], simplex_normal[1], 6);
471 test_point_output<box, polygon>("box(1 1,6 4)", simplex_normal[0], 4);
472 test_point_output<linestring, polygon>("linestring(0 2,6 2)", simplex_normal[0], 2);
473 // NYI because of sectionize:
474 // test_point_output<segment, polygon>("linestring(0 2,6 2)", simplex_normal[0], 2);
475 // NYI because needs special treatment:
476 // test_point_output<box, box>("box(0 0,4 4)", "box(2 2,6 6)", 2);
477}
478
479
480template <typename Polygon, typename LineString>
481void test_areal_linear()
482{
483 std::string const poly_simplex = "POLYGON((1 1,1 3,3 3,3 1,1 1))";
484
485 test_one_lp<LineString, Polygon, LineString>("simplex", poly_simplex, "LINESTRING(0 2,4 2)", 1, 2, 2.0);
486 test_one_lp<LineString, Polygon, LineString>("case2", poly_simplex, "LINESTRING(0 1,4 3)", 1, 2, sqrt(5.0));
487 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));
488 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));
489
490 test_one_lp<LineString, Polygon, LineString>("case5", poly_simplex, "LINESTRING(0 1,3 4)", 1, 2, sqrt(2.0));
491 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,
492 // Pieces are 1 x 2/9:
493 4.0 * sqrt(1.0 + 4.0/81.0));
494 test_one_lp<LineString, Polygon, LineString>("case7", poly_simplex, "LINESTRING(1.5 1.5,2.5 2.5)", 1, 2, sqrt(2.0));
495 test_one_lp<LineString, Polygon, LineString>("case8", poly_simplex, "LINESTRING(1 0,2 0)", 0, 0, 0.0);
496
497 std::string const poly_9 = "POLYGON((1 1,1 4,4 4,4 1,1 1))";
498 test_one_lp<LineString, Polygon, LineString>("case9", poly_9, "LINESTRING(0 1,1 2,2 2)", 1, 2, 1.0);
499 test_one_lp<LineString, Polygon, LineString>("case10", poly_9, "LINESTRING(0 1,1 2,0 2)", 0, 0, 0.0);
500 test_one_lp<LineString, Polygon, LineString>("case11", poly_9, "LINESTRING(2 2,4 2,3 3)", 1, 3, 2.0 + sqrt(2.0));
501 test_one_lp<LineString, Polygon, LineString>("case12", poly_9, "LINESTRING(2 3,4 4,5 6)", 1, 2, sqrt(5.0));
502
503 test_one_lp<LineString, Polygon, LineString>("case13", poly_9, "LINESTRING(3 2,4 4,2 3)", 1, 3, 2.0 * sqrt(5.0));
504 test_one_lp<LineString, Polygon, LineString>("case14", poly_9, "LINESTRING(5 6,4 4,6 5)", 0, 0, 0.0);
505 test_one_lp<LineString, Polygon, LineString>("case15", poly_9, "LINESTRING(0 2,1 2,1 3,0 3)", 1, 2, 1.0);
506 test_one_lp<LineString, Polygon, LineString>("case16", poly_9, "LINESTRING(2 2,1 2,1 3,2 3)", 1, 4, 3.0);
507
508 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)";
509 // PROPERTIES CHANGED BY switch_to_integer
510 // TODO test_one_lp<LineString, Polygon, LineString>("case17", "POLYGON((1 1,1 5,4 5,4 1,1 1))", angly, 3, 8, 6.0);
511 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));
512 test_one_lp<LineString, Polygon, LineString>("case19", poly_9, "LINESTRING(1 2,1 3,0 3)", 1, 2, 1.0);
513 test_one_lp<LineString, Polygon, LineString>("case20", poly_9, "LINESTRING(1 2,1 3,2 3)", 1, 3, 2.0);
514
515 test_one_lp<LineString, Polygon, LineString>("case21",
516 "POLYGON((2 3,-9 -7,12 -13,2 3))",
517 "LINESTRING(-1.3 0,-15 0,-1.3 0)",
518 0, 0, 0);
519
520 test_one_lp<LineString, Polygon, LineString>("case22",
521 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
522 "LINESTRING(5 5,-10 5,5 5)",
523 2, 4, 10);
524
525 test_one_lp<LineString, Polygon, LineString>("case22a",
526 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
527 "LINESTRING(1 1,5 5,-10 5,5 5,6 6)",
528 2, 6, 17.071068);
529
530 test_one_lp<LineString, Polygon, LineString>("case23",
531 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
532 "LINESTRING(-10 5,5 5,-10 5)",
533 1, 3, 10);
534
535 test_one_lp<LineString, Polygon, LineString>("case23a",
536 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
537 "LINESTRING(-20 10,-10 5,5 5,-10 5,-20 -10)",
538 1, 3, 10);
539
540 test_one_lp<LineString, Polygon, LineString>("case24",
541 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
542 "LINESTRING(0 5,5 5,0 5)",
543 1, 3, 10);
544
545 test_one_lp<LineString, Polygon, LineString>("case24",
546 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
547 "LINESTRING(0 5,5 5,1 1,9 1,5 5,0 5)",
548 1, 6, 29.313708);
549
550 test_one_lp<LineString, Polygon, LineString>("case25",
551 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
552 "LINESTRING(5 5,0 5,5 5)",
553 1, 3, 10);
554
555 test_one_lp<LineString, Polygon, LineString>("case25a",
556 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
557 "LINESTRING(-10 10,5 5,0 5,5 5,20 10)",
558 1, 4, 20.540925);
559
560 test_one_lp<LineString, Polygon, LineString>("case25b",
561 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
562 "LINESTRING(-10 10,5 5,1 5,5 5,20 10)",
563 1, 4, 18.540925);
564
565 test_one_lp<LineString, Polygon, LineString>("case25c",
566 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
567 "LINESTRING(-10 10,5 5,-1 5,5 5,20 10)",
568 2, 6, 20.540925);
569
570 test_one_lp<LineString, Polygon, LineString>("case26",
571 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
572 "LINESTRING(-5 5,0 5,-5 5)",
573 0, 0, 0);
574
575 test_one_lp<LineString, Polygon, LineString>("case26a",
576 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
577 "LINESTRING(-10 10,-5 5,0 5,-5 5,-10 -10)",
578 0, 0, 0);
579
580 test_one_lp<LineString, Polygon, LineString>("case27",
581 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
582 "LINESTRING(5 5,0 5,5 5,5 4,0 4,5 4)",
583 1, 6, 21.0);
584
585 test_one_lp<LineString, Polygon, LineString>("case28",
586 "POLYGON((0 0,0 10,10 10,10 0,0 0))",
587 "LINESTRING(5 5,0 5,5 5,5 4,0 4,5 3)",
588 1, 6, 21.099019);
589
590 test_one_lp<LineString, Polygon, LineString>("case29",
591 "POLYGON((5 5,15 15,15 5,5 5))",
592 "LINESTRING(0 0,10 10)",
593 1, 2, 5 * std::sqrt(2.0));
594
595 // PROPERTIES CHANGED BY switch_to_integer
596 // 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);
597
598 // Compile test - arguments in any order:
599 test_one<LineString, Polygon, LineString>("simplex", poly_simplex, "LINESTRING(0 2,4 2)", 1, 2, 2.0);
600 test_one<LineString, LineString, Polygon>("simplex", "LINESTRING(0 2,4 2)", poly_simplex, 1, 2, 2.0);
601
602 typedef typename bg::point_type<Polygon>::type Point;
603 test_one<LineString, bg::model::ring<Point>, LineString>("simplex", poly_simplex, "LINESTRING(0 2,4 2)", 1, 2, 2.0);
604
b32b8144
FG
605 test_one_lp<LineString, Polygon, LineString>("case30",
606 "POLYGON((25 0,0 15,30 15,22 10,25 0))",
607 "LINESTRING(10 15,20 15)",
608 1, 2, 10.0);
609
610 test_one_lp<LineString, Polygon, LineString>("case31",
611 "POLYGON((25 0,0 15,30 15,22 10,25 0))",
612 "LINESTRING(0 15,20 15)",
613 1, 2, 20.0);
614
615 test_one_lp<LineString, Polygon, LineString>("case32",
616 "POLYGON((25 0,0 15,30 15,22 10,25 0))",
617 "LINESTRING(25 0, 0 15,20 15)",
618 1, 3, 49.15475947422650 /*sqrt(25^2+15^2)+20*/);
619
620 typedef typename bg::point_type<Polygon>::type P;
621
622 test_one_lp<P, Polygon, LineString>("case30p",
623 "POLYGON((25 0,0 15,30 15,22 10,25 0))",
624 "LINESTRING(10 15,20 15)",
625 2, 2, 0);
7c673cae
FG
626}
627
628
629template <typename Linestring, typename Box>
630void test_linear_box()
631{
632 typedef bg::model::multi_linestring<Linestring> multi_linestring_type;
633
634 test_one_lp<Linestring, Box, Linestring>
635 ("case-l-b-01",
636 "BOX(-10 -10,10 10)",
637 "LINESTRING(-20 -20, 0 0,20 20)",
638 1, 3, 20 * sqrt(2.0));
639
640 test_one_lp<Linestring, Box, Linestring>
641 ("case-l-b-02",
642 "BOX(-10 -10,10 10)",
643 "LINESTRING(-20 -20, 20 20)",
644 1, 2, 20.0 * sqrt(2.0));
645
646 test_one_lp<Linestring, Box, Linestring>
647 ("case-l-b-02",
648 "BOX(-10 -10,10 10)",
649 "LINESTRING(-20 -20, 20 20,15 0,0 -15)",
650 2, 4, 25.0 * sqrt(2.0));
651
652 test_one_lp<Linestring, Box, multi_linestring_type>
653 ("case-ml-b-01",
654 "BOX(-10 -10,10 10)",
655 "MULTILINESTRING((-20 -20, 20 20),(0 -15,15 0))",
656 2, 4, 25.0 * sqrt(2.0));
657}
658
659
660template <typename P>
661void test_all()
662{
663 typedef bg::model::linestring<P> linestring;
664 typedef bg::model::polygon<P> polygon;
665 typedef bg::model::box<P> box;
666 typedef bg::model::segment<P> segment;
667
668 typedef bg::model::polygon<P, false> polygon_ccw;
669 typedef bg::model::polygon<P, true, false> polygon_open;
670 typedef bg::model::polygon<P, false, false> polygon_ccw_open;
671 boost::ignore_unused<polygon_ccw, polygon_open, polygon_ccw_open>();
672
673 ut_settings ignore_validity;
674 ignore_validity.test_validity = false;
675
676 std::string clip = "box(2 2,8 8)";
677
678 test_areal_linear<polygon, linestring>();
679#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
680 test_areal_linear<polygon_open, linestring>();
681 test_areal_linear<polygon_ccw, linestring>();
682 test_areal_linear<polygon_ccw_open, linestring>();
683#endif
684
685 test_linear_box<linestring, box>();
686
687 // Test polygons clockwise and counter clockwise
688 test_areal<polygon>();
689
690#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
691 test_areal<polygon_ccw>();
692 test_areal<polygon_open>();
693 test_areal<polygon_ccw_open>();
694#endif
695
696 test_areal_clip<polygon, box>();
697#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
698 test_areal_clip<polygon_ccw, box>();
699#endif
700
701#if defined(TEST_FAIL_DIFFERENT_ORIENTATIONS)
702 // Should NOT compile
703 // NOTE: this can probably be relaxed later on.
704 test_one<polygon, polygon_ccw, polygon>("simplex_normal",
705 simplex_normal[0], simplex_normal[1],
706 1, 7, 5.47363293);
707 // Output ccw, nyi (should be just reversing afterwards)
708 test_one<polygon, polygon, polygon_ccw>("simplex_normal",
709 simplex_normal[0], simplex_normal[1],
710 1, 7, 5.47363293);
711#endif
712
713 // Basic check: box/linestring, is clipping OK? should compile in any order
714 test_one<linestring, linestring, box>("llb", "LINESTRING(0 0,10 10)", clip, 1, 2, sqrt(2.0 * 6.0 * 6.0));
715 test_one<linestring, box, linestring>("lbl", clip, "LINESTRING(0 0,10 10)", 1, 2, sqrt(2.0 * 6.0 * 6.0));
716
717 // Box/segment
718 test_one<linestring, segment, box>("lsb", "LINESTRING(0 0,10 10)", clip, 1, 2, sqrt(2.0 * 6.0 * 6.0));
719 test_one<linestring, box, segment>("lbs", clip, "LINESTRING(0 0,10 10)", 1, 2, sqrt(2.0 * 6.0 * 6.0));
720
721 // Completely inside
722 test_one<linestring, linestring, box>("llbi", "LINESTRING(3 3,7 7)", clip, 1, 2, sqrt(2.0 * 4.0 * 4.0));
723
724 // Completely outside
725 test_one<linestring, linestring, box>("llbo", "LINESTRING(9 9,10 10)", clip, 0, 0, 0.0);
726
727 // Touching with point (-> output linestring with ONE point)
728 test_one<linestring, linestring, box>("llb_touch", "LINESTRING(8 8,10 10)", clip, 1, 1, 0.0, ignore_validity);
729
730 // Along border
731 test_one<linestring, linestring, box>("llb_along", "LINESTRING(2 2,2 8)", clip, 1, 2, 6.0);
732
733 // Outputting two lines (because of 3-4-5 constructions (0.3,0.4,0.5)
734 // which occur 4 times, the length is expected to be 2.0)
735 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);
736
737 // linear
738 test_one<P, linestring, linestring>("llp1", "LINESTRING(0 0,1 1)", "LINESTRING(0 1,1 0)", 1, 1, 0.0);
739 test_one<P, segment, segment>("ssp1", "LINESTRING(0 0,1 1)", "LINESTRING(0 1,1 0)", 1, 1, 0.0);
740 test_one<P, linestring, linestring>("llp2", "LINESTRING(0 0,1 1)", "LINESTRING(0 0,2 2)", 2, 2, 0.0);
741
742 // polygons outputing points
743 //test_one<P, polygon, polygon>("ppp1", simplex_normal[0], simplex_normal[1], 1, 7, 5.47363293);
744
745 test_boxes<box>("box(2 2,8 8)", "box(4 4,10 10)", 16, true);
746 test_boxes<box>("box(2 2,8 7)", "box(4 4,10 10)", 12, true);
747 test_boxes<box>("box(2 2,8 7)", "box(14 4,20 10)", 0, false);
748 test_boxes<box>("box(2 2,4 4)", "box(4 4,8 8)", 0, true);
749
750 test_point_output<P>();
751
752
753 /*
754 test_one<polygon, box, polygon>(99, "box(115041.10 471900.10, 118334.60 474523.40)",
755 "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))",
756 1, 26, 3727690.74);
757 */
758
759}
760
761void test_pointer_version()
762{
763 std::vector<test::test_point_xy*> ln;
764 test::test_point_xy* p;
765 p = new test::test_point_xy; p->x = 0; p->y = 0; ln.push_back(p);
766 p = new test::test_point_xy; p->x = 10; p->y = 10; ln.push_back(p);
767
768 bg::model::box<bg::model::d2::point_xy<double> > box;
769 bg::assign_values(box, 2, 2, 8, 8);
770
771 typedef bg::model::linestring<bg::model::d2::point_xy<double> > output_type;
772 std::vector<output_type> clip;
773 bg::detail::intersection::intersection_insert<output_type>(box, ln, std::back_inserter(clip));
774
775 double length = 0;
776 std::size_t n = 0;
777 for (std::vector<output_type>::const_iterator it = clip.begin();
778 it != clip.end(); ++it)
779 {
780 length += bg::length(*it);
781 n += bg::num_points(*it);
782 }
783
784 BOOST_CHECK_EQUAL(clip.size(), 1u);
785 BOOST_CHECK_EQUAL(n, 2u);
786 BOOST_CHECK_CLOSE(length, sqrt(2.0 * 6.0 * 6.0), 0.001);
787
788 for (std::size_t i = 0; i < ln.size(); i++)
789 {
790 delete ln[i];
791 }
792}
793
794
795template <typename P>
796void test_exception()
797{
798 typedef bg::model::polygon<P> polygon;
799
800 try
801 {
802 // Define polygon with a spike (= invalid)
803 std::string spike = "POLYGON((0 0,0 4,2 4,2 6,2 4,4 4,4 0,0 0))";
804
805 test_one<polygon, polygon, polygon>("with_spike",
806 simplex_normal[0], spike,
807 0, 0, 0);
808 }
809 catch(bg::overlay_invalid_input_exception const& )
810 {
811 return;
812 }
813 BOOST_CHECK_MESSAGE(false, "No exception thrown");
814}
815
816template <typename Point>
817void test_rational()
818{
819 typedef bg::model::polygon<Point> polygon;
820 test_one<polygon, polygon, polygon>("simplex_normal",
821 simplex_normal[0], simplex_normal[1],
822 1, 7, 5.47363293);
823}
824
825
826template <typename P>
827void test_boxes_per_d(P const& min1, P const& max1, P const& min2, P const& max2, bool expected_result)
828{
829 typedef bg::model::box<P> box;
830
831 box box_out;
832 bool detected = bg::intersection(box(min1, max1), box(min2, max2), box_out);
833
834 BOOST_CHECK_EQUAL(detected, expected_result);
835 if ( detected && expected_result )
836 {
837 BOOST_CHECK( bg::equals(box_out, box(min2,max1)) );
838 }
839}
840
841template <typename CoordinateType>
842void test_boxes_nd()
843{
844 typedef bg::model::point<CoordinateType, 1, bg::cs::cartesian> p1;
845 typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> p2;
846 typedef bg::model::point<CoordinateType, 3, bg::cs::cartesian> p3;
847
848 test_boxes_per_d(p1(0), p1(5), p1(3), p1(6), true);
849 test_boxes_per_d(p2(0,0), p2(5,5), p2(3,3), p2(6,6), true);
850 test_boxes_per_d(p3(0,0,0), p3(5,5,5), p3(3,3,3), p3(6,6,6), true);
851}
852
853
854template <typename CoordinateType>
855void test_ticket_10868(std::string const& wkt_out)
856{
857 typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
858 typedef bg::model::polygon
859 <
860 point_type, /*ClockWise*/false, /*Closed*/false
861 > polygon_type;
862 typedef bg::model::multi_polygon<polygon_type> multipolygon_type;
863
864 polygon_type polygon1;
865 bg::read_wkt(ticket_10868[0], polygon1);
866 polygon_type polygon2;
867 bg::read_wkt(ticket_10868[1], polygon2);
868
869 multipolygon_type multipolygon_out;
870 bg::intersection(polygon1, polygon2, multipolygon_out);
871 std::stringstream stream;
872 stream << bg::wkt(multipolygon_out);
873
874 BOOST_CHECK_EQUAL(stream.str(), wkt_out);
875
876 test_one<polygon_type, polygon_type, polygon_type>("ticket_10868",
877 ticket_10868[0], ticket_10868[1],
b32b8144 878 1, 7, 20266195244586.0);
7c673cae
FG
879}
880
881int test_main(int, char* [])
882{
883 test_all<bg::model::d2::point_xy<double> >();
884
885#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
886 test_all<bg::model::d2::point_xy<float> >();
887
888#if defined(HAVE_TTMATH)
889 std::cout << "Testing TTMATH" << std::endl;
890 test_all<bg::model::d2::point_xy<ttmath_big> >();
891#endif
892
893#endif
894
895 // Commented, because exception is now disabled:
896 // test_exception<bg::model::d2::point_xy<double> >();
897
898 test_pointer_version();
899#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
900 test_rational<bg::model::d2::point_xy<boost::rational<int> > >();
901#endif
902
903 test_boxes_nd<double>();
904
905#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
906 // ticket #10868 still fails for 32-bit integers
907 test_ticket_10868<int32_t>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
908
909#if !defined(BOOST_NO_INT64) || defined(BOOST_HAS_INT64_T) || defined(BOOST_HAS_MS_INT64)
910 test_ticket_10868<int64_t>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
911#endif
912
913 if (BOOST_GEOMETRY_CONDITION(sizeof(long) * CHAR_BIT >= 64))
914 {
915 test_ticket_10868<long>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
916 }
917
918#if defined(BOOST_HAS_LONG_LONG)
919 test_ticket_10868<boost::long_long_type>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
920#endif
921#endif
922
923 return 0;
924}