1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands.
5
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9
10 #include <iostream>
11 #include <string>
12
13 // If defined, tests are run without rescaling-to-integer or robustness policy
14 // This multi_difference currently contains no tests for double which then fail
15 // #define BOOST_GEOMETRY_NO_ROBUSTNESS
16
17 //#define HAVE_TTMATH
18 //#define BOOST_GEOMETRY_DEBUG_ASSEMBLE
19 //#define BOOST_GEOMETRY_CHECK_WITH_SQLSERVER
20
21 //#define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
22 //#define BOOST_GEOMETRY_DEBUG_FOLLOW
23 //#define BOOST_GEOMETRY_DEBUG_TRAVERSE
24
25
26 #include "test_difference.hpp"
27 #include <algorithms/test_overlay.hpp>
28 #include <algorithms/overlay/multi_overlay_cases.hpp>
29
30 #include <boost/geometry/algorithms/correct.hpp>
31 #include <boost/geometry/algorithms/intersection.hpp>
32 #include <boost/geometry/algorithms/within.hpp> // only for testing #77
33
34 #include <boost/geometry/geometries/point_xy.hpp>
35 #include <boost/geometry/geometries/multi_point.hpp>
36 #include <boost/geometry/geometries/multi_linestring.hpp>
37 #include <boost/geometry/geometries/multi_polygon.hpp>
38
39 #include <boost/geometry/io/wkt/read.hpp>
40
41 template <typename Ring, typename Polygon, typename MultiPolygon>
test_areal()42 void test_areal()
43 {
44 test_one<Polygon, MultiPolygon, MultiPolygon>("simplex_multi",
45 case_multi_simplex[0], case_multi_simplex[1],
46 5, 21, 5.58, 4, 17, 2.58);
47
48 test_one<Polygon, MultiPolygon, MultiPolygon>("case_multi_no_ip",
49 case_multi_no_ip[0], case_multi_no_ip[1],
50 2, 12, 24.0, 2, 12, 34.0);
51 test_one<Polygon, MultiPolygon, MultiPolygon>("case_multi_2",
52 case_multi_2[0], case_multi_2[1],
53 2, 15, 19.6, 2, 13, 33.6);
54
55 test_one<Polygon, MultiPolygon, Polygon>("simplex_multi_mp_p",
56 case_multi_simplex[0], case_single_simplex,
57 5, 21, 5.58, 4, 17, 2.58);
58 test_one<Polygon, Ring, MultiPolygon>("simplex_multi_r_mp",
59 case_single_simplex, case_multi_simplex[0],
60 4, 17, 2.58, 5, 21, 5.58);
61 test_one<Polygon, MultiPolygon, Ring>("simplex_multi_mp_r",
62 case_multi_simplex[0], case_single_simplex,
63 5, 21, 5.58, 4, 17, 2.58);
64
65 // Constructed cases for multi/touch/equal/etc
66 test_one<Polygon, MultiPolygon, MultiPolygon>("case_61_multi",
67 case_61_multi[0], case_61_multi[1],
68 2, 10, 2, 2, 10, 2, 1, 10, 4);
69 test_one<Polygon, MultiPolygon, MultiPolygon>("case_62_multi",
70 case_62_multi[0], case_62_multi[1],
71 0, 0, 0, 1, 5, 1);
72 test_one<Polygon, MultiPolygon, MultiPolygon>("case_63_multi",
73 case_63_multi[0], case_63_multi[1],
74 0, 0, 0, 1, 5, 1);
75 test_one<Polygon, MultiPolygon, MultiPolygon>("case_64_multi",
76 case_64_multi[0], case_64_multi[1],
77 1, 5, 1, 1, 5, 1, 1, 7, 2);
78 test_one<Polygon, MultiPolygon, MultiPolygon>("case_65_multi",
79 case_65_multi[0], case_65_multi[1],
80 0, 0, 0, 2, 10, 3);
81 /* TODO: fix
82 test_one<Polygon, MultiPolygon, MultiPolygon>("case_72_multi",
83 case_72_multi[0], case_72_multi[1],
84 3, 13, 1.65, 3, 17, 6.15);
85 test_one<Polygon, MultiPolygon, MultiPolygon>("case_77_multi",
86 case_77_multi[0], case_77_multi[1],
87 6, 31, 7, 6, 36, 13);
88 */
89
90 test_one<Polygon, MultiPolygon, MultiPolygon>("case_78_multi",
91 case_78_multi[0], case_78_multi[1],
92 1, 5, 1.0, 1, 5, 1.0);
93
94 // Ticket on GGL list 2011/10/25
95 // to mix polygon/multipolygon in call to difference
96 test_one<Polygon, Polygon, Polygon>("ggl_list_20111025_vd_pp",
97 ggl_list_20111025_vd[0], ggl_list_20111025_vd[1],
98 1, 4, 8.0, 1, 4, 12.5);
99 test_one<Polygon, Polygon, MultiPolygon>("ggl_list_20111025_vd_pm",
100 ggl_list_20111025_vd[0], ggl_list_20111025_vd[3],
101 1, 4, 8.0, 1, 4, 12.5);
102 test_one<Polygon, MultiPolygon, Polygon>("ggl_list_20111025_vd_mp",
103 ggl_list_20111025_vd[2], ggl_list_20111025_vd[1],
104 1, 4, 8.0, 1, 4, 12.5);
105 test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20111025_vd_mm",
106 ggl_list_20111025_vd[2], ggl_list_20111025_vd[3],
107 1, 4, 8.0, 1, 4, 12.5);
108
109 // Second case
110 // This can be tested with this SQL for SQL-Server
111 /*
112 with viewy as (select geometry::STGeomFromText(
113 'POLYGON((5 0,5 4,8 4,8 0,5 0))',0) as p,
114 geometry::STGeomFromText(
115 'MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((4 0,4 2,6 2,6 0,4 0)))',0) as q)
116 select
117 p.STDifference(q).STArea(),p.STDifference(q).STNumGeometries(),p.STDifference(q) as p_min_q,
118 q.STDifference(p).STArea(),q.STDifference(p).STNumGeometries(),q.STDifference(p) as q_min_p,
119 p.STSymDifference(q).STArea(),q.STSymDifference(p) as p_xor_q
120 from viewy
121
122 Outputting:
123 10, 1, <WKB>, 6, 2, <WKB>, 16, <WKB>
124 */
125
126 test_one<Polygon, Polygon, MultiPolygon>("ggl_list_20111025_vd_2",
127 ggl_list_20111025_vd_2[0], ggl_list_20111025_vd_2[1],
128 1, 7, 10.0, 2, 10, 6.0);
129
130 test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
131 ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],
132 2, 13, 17.0, 0, 0, 0.0);
133 test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_b",
134 ggl_list_20120915_h2[0], ggl_list_20120915_h2[2],
135 2, 13, 17.0, 0, 0, 0.0);
136
137 test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120221_volker",
138 ggl_list_20120221_volker[0], ggl_list_20120221_volker[1],
139 2, 12, 7962.66, 1, 18, 2775258.93,
140 0.001);
141
142 #if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
143 test_one<Polygon, MultiPolygon, MultiPolygon>("ticket_9081",
144 ticket_9081[0], ticket_9081[1],
145 2, 28, 0.0907392476356186, 4, 25, 0.126018011439877,
146 4, 42, 0.0907392476356186 + 0.126018011439877,
147 0.001);
148 #endif
149
150 /* TODO: fix
151 test_one<Polygon, MultiPolygon, MultiPolygon>("case_101_multi",
152 case_101_multi[0], case_101_multi[1],
153 5, 23, 4.75, 5, 40, 12.75);
154 test_one<Polygon, MultiPolygon, MultiPolygon>("case_102_multi",
155 case_102_multi[0], case_102_multi[1],
156 2, 8, 0.75, 6, 25, 3.75);
157 test_one<Polygon, MultiPolygon, MultiPolygon>("case_107_multi",
158 case_107_multi[0], case_107_multi[1],
159 2, 11, 2.25, 3, 14, 3.0);
160 */
161 /*
162 test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_1",
163 case_recursive_boxes_1[0], case_recursive_boxes_1[1],
164 1, 1, 1, 1, 1, 1);
165 test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_2",
166 case_recursive_boxes_2[0], case_recursive_boxes_2[1],
167 1, 1, 1, 1, 1, 1);
168
169 test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_3",
170 case_recursive_boxes_3[0], case_recursive_boxes_3[1],
171 1, 1, 1, 1, 1, 1);
172 */
173 }
174
175 template <typename MultiPolygon, typename MultiLineString>
test_areal_linear()176 void test_areal_linear()
177 {
178 typedef typename boost::range_value<MultiPolygon>::type Polygon;
179 typedef typename boost::range_value<MultiLineString>::type LineString;
180 typedef typename bg::point_type<Polygon>::type Point;
181 typedef bg::model::ring<Point> Ring;
182
183 test_one_lp<LineString, LineString, MultiPolygon>("case_mp_ls_1", "LINESTRING(2 0,2 5)", case_multi_simplex[0], 2, 4, 1.30);
184 test_one_lp<LineString, MultiLineString, Polygon>("case_p_mls_1", "MULTILINESTRING((2 0,2 5),(3 0,3 5))", case_single_simplex, 3, 6, 2.5);
185 test_one_lp<LineString, MultiLineString, MultiPolygon>("case_mp_mls_1", "MULTILINESTRING((2 0,2 5),(3 0,3 5))", case_multi_simplex[0], 5, 10, 3.1666667);
186 test_one_lp<LineString, MultiLineString, Ring>("case_r_mls_1", "MULTILINESTRING((2 0,2 5),(3 0,3 5))", case_single_simplex, 3, 6, 2.5);
187
188 // Collinear cases, with multiple turn points at the same location
189 test_one_lp<LineString, LineString, MultiPolygon>("case_mp_ls_2a", "LINESTRING(1 0,1 1,2 1,2 0)", "MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)),((1 1,1 2,2 2,2 1,1 1)))", 1, 2, 1.0);
190 test_one_lp<LineString, LineString, MultiPolygon>("case_mp_ls_2b", "LINESTRING(1 0,1 1,2 1,2 0)", "MULTIPOLYGON(((1 1,1 2,2 2,2 1,1 1)),((0 0,0 1,1 1,1 0,0 0)))", 1, 2, 1.0);
191
192 test_one_lp<LineString, LineString, MultiPolygon>("case_mp_ls_3",
193 "LINESTRING(6 6,6 7,7 7,7 6,8 6,8 7,9 7,9 6)",
194 "MULTIPOLYGON(((5 7,5 8,6 8,6 7,5 7)),((6 6,6 7,7 7,7 6,6 6)),((8 8,9 8,9 7,8 7,7 7,7 8,8 8)))", 2, 5, 3.0);
195
196 return;
197
198 // TODO: this case contains collinearities and should still be solved
199 test_one_lp<LineString, LineString, MultiPolygon>("case_mp_ls_4",
200 "LINESTRING(0 5,0 6,1 6,1 5,2 5,2 6,3 6,3 5,3 4,3 3,2 3,2 4,1 4,1 3,0 3,0 4)",
201 "MULTIPOLYGON(((0 2,0 3,1 2,0 2)),((2 5,3 6,3 5,2 5)),((1 5,1 6,2 6,2 5,1 5)),((2 3,2 4,3 4,2 3)),((0 3,1 4,1 3,0 3)),((4 3,3 3,3 5,4 5,4 4,4 3)))", 5, 11, 6.0);
202 }
203
204
205 template <typename P>
test_all()206 void test_all()
207 {
208 //typedef bg::model::box<P> box;
209 typedef bg::model::ring<P> ring;
210 typedef bg::model::polygon<P> polygon;
211 typedef bg::model::multi_polygon<polygon> multi_polygon;
212 test_areal<ring, polygon, multi_polygon>();
213 test_areal_linear<multi_polygon, bg::model::multi_linestring<bg::model::linestring<P> > >();
214 }
215
216
test_main(int,char * [])217 int test_main(int, char* [])
218 {
219 test_all<bg::model::d2::point_xy<double > >();
220
221 #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
222 test_all<bg::model::d2::point_xy<float> >();
223
224 #if defined(HAVE_TTMATH)
225 std::cout << "Testing TTMATH" << std::endl;
226 test_all<bg::model::d2::point_xy<ttmath_big> >();
227 #endif
228
229 #endif
230
231 return 0;
232 }
233