1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2014-2017, Oracle and/or its affiliates.
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9 // Licensed under the Boost Software License version 1.0.
10 // http://www.boost.org/users/license.html
12 #ifndef BOOST_TEST_MODULE
13 #define BOOST_TEST_MODULE test_is_simple
16 #include "test_is_simple.hpp"
19 namespace bg
= ::boost::geometry
;
21 typedef bg::model::point
<double, 2, bg::cs::cartesian
> point_type
;
22 typedef bg::model::segment
<point_type
> segment_type
;
23 typedef bg::model::linestring
<point_type
> linestring_type
;
24 typedef bg::model::multi_linestring
<linestring_type
> multi_linestring_type
;
25 // ccw open and closed polygons
26 typedef bg::model::polygon
<point_type
,false,false> open_ccw_polygon_type
;
27 typedef bg::model::polygon
<point_type
,false,true> closed_ccw_polygon_type
;
29 typedef bg::model::multi_point
<point_type
> multi_point_type
;
30 typedef bg::model::multi_polygon
<open_ccw_polygon_type
> multi_polygon_type
;
32 typedef bg::model::box
<point_type
> box_type
;
35 BOOST_AUTO_TEST_CASE( test_is_simple_point
)
37 #ifdef BOOST_GEOMETRY_TEST_DEBUG
38 std::cout
<< std::endl
<< std::endl
;
39 std::cout
<< "************************************" << std::endl
;
40 std::cout
<< " is_simple: POINT " << std::endl
;
41 std::cout
<< "************************************" << std::endl
;
46 test_simple(from_wkt
<G
>("POINT(0 0)"), true);
49 BOOST_AUTO_TEST_CASE( test_is_simple_multipoint
)
51 #ifdef BOOST_GEOMETRY_TEST_DEBUG
52 std::cout
<< std::endl
<< std::endl
;
53 std::cout
<< "************************************" << std::endl
;
54 std::cout
<< " is_simple: MULTIPOINT " << std::endl
;
55 std::cout
<< "************************************" << std::endl
;
58 typedef multi_point_type G
;
60 test_simple(from_wkt
<G
>("MULTIPOINT(0 0)"), true);
61 test_simple(from_wkt
<G
>("MULTIPOINT(0 0,1 0,1 1,0 1)"), true);
62 test_simple(from_wkt
<G
>("MULTIPOINT(0 0,1 0,1 1,1 0,0 1)"), false);
65 test_simple(from_wkt
<G
>("MULTIPOINT()"), true);
68 BOOST_AUTO_TEST_CASE( test_is_simple_segment
)
70 #ifdef BOOST_GEOMETRY_TEST_DEBUG
71 std::cout
<< std::endl
<< std::endl
;
72 std::cout
<< "************************************" << std::endl
;
73 std::cout
<< " is_simple: SEGMENT " << std::endl
;
74 std::cout
<< "************************************" << std::endl
;
77 typedef segment_type G
;
79 test_simple(from_wkt
<G
>("SEGMENT(0 0,1 0)"), true);
82 BOOST_AUTO_TEST_CASE( test_is_simple_linestring
)
84 #ifdef BOOST_GEOMETRY_TEST_DEBUG
85 std::cout
<< std::endl
<< std::endl
;
86 std::cout
<< "************************************" << std::endl
;
87 std::cout
<< " is_simple: LINESTRING " << std::endl
;
88 std::cout
<< "************************************" << std::endl
;
91 typedef linestring_type G
;
93 // valid linestrings with multiple points
94 test_simple(from_wkt
<G
>("LINESTRING(0 0,0 0,1 0)"), false);
95 test_simple(from_wkt
<G
>("LINESTRING(0 0,0 0,1 0,0 0)"), false);
96 test_simple(from_wkt
<G
>("LINESTRING(0 0,0 0,1 0,1 0,1 1,0 0)"), false);
97 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,2 0,1 1,1 0,1 -1)"), false);
99 // simple open linestrings
100 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 2)"), true);
101 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 2,2 3)"), true);
103 // simple closed linestrings
104 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,1 1,0 0)"), true);
105 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,1 1,0 1,0 0)"), true);
106 test_simple(from_wkt
<G
>("LINESTRING(0 0,10 0,10 10,0 10,0 0)"), true);
108 // non-simple linestrings
109 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,0 0)"), false);
110 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,2 10,0.5 -1)"), false);
111 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,2 1,1 0)"), false);
112 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,2 1,0.5 0)"), false);
113 test_simple(from_wkt
<G
>("LINESTRING(0 0,2 0,1 0)"), false);
114 test_simple(from_wkt
<G
>("LINESTRING(0 0,3 0,5 0,1 0)"), false);
115 test_simple(from_wkt
<G
>("LINESTRING(0 0,3 0,5 0,4 0)"), false);
116 test_simple(from_wkt
<G
>("LINESTRING(0 0,3 0,5 0,4 0,2 0)"), false);
117 test_simple(from_wkt
<G
>("LINESTRING(0 0,3 0,2 0,5 0)"), false);
118 test_simple(from_wkt
<G
>("LINESTRING(0 0,2 0,2 2,1 0,0 0)"), false);
119 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,2 0,2 2,1 0,0 0)"), false);
120 test_simple(from_wkt
<G
>("LINESTRING(0 0,10 0,10 10,0 10,0 0,0 0)"), false);
121 test_simple(from_wkt
<G
>("LINESTRING(0 0,0 10,5 10,0 0,10 10,10 5,10 0,0 0)"), false);
122 test_simple(from_wkt
<G
>("LINESTRING(0 0,0 0,10 0,10 10,0 10,0 0,0 0)"),
124 test_simple(from_wkt
<G
>("LINESTRING(0 0,0 0,0 0,10 0,10 10,0 10,0 0,0 0,0 0,0 0)"),
126 test_simple(from_wkt
<G
>("LINESTRING(0 0,0 0,10 0,10 10,10 10,10 10,10 10,10 10,0 10,0 0,0 0)"),
128 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,2 0,2 2,1 0)"), false);
129 test_simple(from_wkt
<G
>("LINESTRING(1 0,2 2,2 0,1 0,0 0)"), false);
130 test_simple(from_wkt
<G
>("LINESTRING(0 0,1 0,2 0,2 2,1 0,1 4,0 0)"), false);
131 test_simple(from_wkt
<G
>("LINESTRING(4 1,10 8,4 6,4 1,10 5,10 3)"),
133 test_simple(from_wkt
<G
>("LINESTRING(10 3,10 5,4 1,4 6,10 8,4 1)"),
137 // the simplicity result is irrelevant since an empty linestring
138 // is considered as invalid
139 test_simple(from_wkt
<G
>("LINESTRING()"), false, false);
142 BOOST_AUTO_TEST_CASE( test_is_simple_multilinestring
)
144 #ifdef BOOST_GEOMETRY_TEST_DEBUG
145 std::cout
<< std::endl
<< std::endl
;
146 std::cout
<< "************************************" << std::endl
;
147 std::cout
<< " is_simple: MULTILINESTRING " << std::endl
;
148 std::cout
<< "************************************" << std::endl
;
151 typedef multi_linestring_type G
;
153 // multilinestrings with linestrings with spikes
154 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0,0 0),(5 0,6 0,7 0))"),
156 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0,0 0),(5 0,1 0,4 1))"),
158 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0,0 0),(5 0,1 0,4 0))"),
160 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0,0 0),(1 0,2 0))"),
163 // simple multilinestrings
164 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 1),(1 1,1 0))"), true);
165 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 1),(1 1,1 0),(0 1,1 1))"),
167 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2),(0 0,1 0,2 0,2 2))"), true);
168 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2),(2 2,2 0,1 0,0 0))"), true);
169 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0),(0 0,-1 0),(1 0,2 0))"),
171 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0),(-1 0,0 0),(2 0,1 0))"),
173 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0),(0 0,0 1),(0 0,-1 0),(0 0,0 -1))"),
175 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,10 0,10 10,0 10,0 0))"), true);
177 // non-simple multilinestrings
178 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2),(0 0,2 2))"), false);
179 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2),(2 2,0 0))"), false);
180 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2),(0 0,1 0,1 1,2 0,2 2))"),
182 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 1,2 2),(0 0,1 0,1 1,2 0,2 2))"),
184 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 1,2 2),(2 2,0 0))"),
186 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2,4 4),(0 0,1 1))"),
188 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2,4 4),(0 0,3 3))"),
190 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2,4 4),(1 1,3 3))"),
192 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2,4 4),(1 1,2 2))"),
194 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2,4 4),(2 2,3 3))"),
196 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2,4 4),(2 2,4 4))"),
198 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 2,4 4),(4 4,2 2))"),
200 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 1),(0 1,1 0))"),
202 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,2 0),(1 0,0 1))"),
204 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 1),(1 1,1 0),(1 1,0 1,0.5,0.5))"),
206 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(1 0,1 -1))"),
208 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(-1 0,0 0))"),
210 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(0 0,-1 0,-1 -1,0 -1,0 0))"),
212 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(-1 -1,-1 0,0 0,0 -1,-1 -1))"),
214 test_simple(from_wkt
<G
>("MULTILINESTRING((0 0,0 10,5 10,0 0,10 10,10 5,10 0,0 0))"),
216 test_simple(from_wkt
<G
>("MULTILINESTRING((4 1,10 8,4 6,4 1,10 5,10 3))"),
218 test_simple(from_wkt
<G
>("MULTILINESTRING((10 3,10 5,4 1,4 6,10 8,4 1))"),
221 // empty multilinestring
222 test_simple(from_wkt
<G
>("MULTILINESTRING()"), true);
225 BOOST_AUTO_TEST_CASE( test_is_simple_areal
)
228 typedef open_ccw_polygon_type o_ccw_p
;
229 typedef multi_polygon_type mpl
;
231 // check that is_simple compiles for boxes
232 test_simple(from_wkt
<b
>("BOX(0 0,1 1)"), true);
234 // simple polygons and multi-polygons
235 test_simple(from_wkt
<o_ccw_p
>("POLYGON((0 0,1 0,1 1))"), true);
236 test_simple(from_wkt
<o_ccw_p
>("POLYGON((0 0,10 0,10 10,0 10),(1 1,1 9,9 9,9 1))"),
238 test_simple(from_wkt
<mpl
>("MULTIPOLYGON(((0 0,1 0,1 1)),((10 0,20 0,20 10,10 10)))"),
241 // non-simple polygons & multi-polygons (have duplicate points)
242 test_simple(from_wkt
<o_ccw_p
>("POLYGON((0 0,1 0,1 0,1 1))"), false);
243 test_simple(from_wkt
<o_ccw_p
>("POLYGON((0 0,10 0,10 10,0 10),(1 1,1 9,9 9,9 9,9 1))"),
245 test_simple(from_wkt
<mpl
>("MULTIPOLYGON(((0 0,1 0,1 1,1 1)),((10 0,20 0,20 0,20 10,10 10)))"),
249 // the simplicity result is irrelevant since an empty polygon
250 // is considered as invalid
251 test_simple(from_wkt
<o_ccw_p
>("POLYGON(())"), false, false);
253 // empty multipolygon
254 test_simple(from_wkt
<mpl
>("MULTIPOLYGON()"), true);
257 BOOST_AUTO_TEST_CASE( test_geometry_with_NaN_coordinates
)
259 #ifdef BOOST_GEOMETRY_TEST_DEBUG
260 std::cout
<< std::endl
<< std::endl
;
261 std::cout
<< "************************************" << std::endl
;
262 std::cout
<< " is_valid: geometry with NaN coordinates" << std::endl
;
263 std::cout
<< "************************************" << std::endl
;
266 linestring_type ls1
, ls2
;
267 bg::read_wkt("LINESTRING(1 1,1.115235e+308 1.738137e+308)", ls1
);
268 bg::read_wkt("LINESTRING(-1 1,1.115235e+308 1.738137e+308)", ls2
);
270 // the intersection of the two linestrings is a new linestring
271 // (multilinestring with a single element) that has NaN coordinates
272 multi_linestring_type mls
;
273 bg::intersection(ls1
, ls2
, mls
);
275 test_simple(mls
, true, false);
278 BOOST_AUTO_TEST_CASE( test_is_simple_variant
)
280 #ifdef BOOST_GEOMETRY_TEST_DEBUG
281 std::cout
<< std::endl
<< std::endl
;
282 std::cout
<< "************************************" << std::endl
;
283 std::cout
<< " is_simple: variant support" << std::endl
;
284 std::cout
<< "************************************" << std::endl
;
287 typedef bg::model::polygon
<point_type
> polygon_type
; // cw, closed
288 typedef boost::variant
290 linestring_type
, multi_linestring_type
, polygon_type
295 linestring_type simple_linestring
=
296 from_wkt
<linestring_type
>("LINESTRING(0 0,1 0)");
297 multi_linestring_type non_simple_multi_linestring
= from_wkt
299 multi_linestring_type
300 >("MULTILINESTRING((0 0,1 0,1 1,0 0),(10 0,1 1))");
301 polygon_type simple_polygon
=
302 from_wkt
<polygon_type
>("POLYGON((0 0,1 1,1 0,0 0))");
303 polygon_type non_simple_polygon
=
304 from_wkt
<polygon_type
>("POLYGON((0 0,1 1,1 0,1 0,0 0))");
306 vg
= simple_linestring
;
307 test_simple(vg
, true);
308 vg
= non_simple_multi_linestring
;
309 test_simple(vg
, false);
311 test_simple(vg
, true);
312 vg
= non_simple_polygon
;
313 test_simple(vg
, false);