1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2014-2015, Oracle and/or its affiliates.
4 
5 // Licensed under the Boost Software License version 1.0.
6 // http://www.boost.org/users/license.html
7 
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 
11 #ifndef BOOST_TEST_MODULE
12 #define BOOST_TEST_MODULE test_disjoint_coverage
13 #endif
14 
15 // unit test to test disjoint for all geometry combinations
16 
17 #include <iostream>
18 
19 #include <boost/test/included/unit_test.hpp>
20 
21 #include <boost/geometry/core/tag.hpp>
22 #include <boost/geometry/core/tags.hpp>
23 
24 #include <boost/geometry/strategies/strategies.hpp>
25 
26 #include <boost/geometry/io/wkt/wkt.hpp>
27 #include <boost/geometry/io/dsv/write.hpp>
28 
29 #include <boost/geometry/geometries/geometries.hpp>
30 
31 #include <boost/geometry/algorithms/disjoint.hpp>
32 
33 #include <from_wkt.hpp>
34 
35 namespace bg = ::boost::geometry;
36 
37 //============================================================================
38 
39 struct test_disjoint
40 {
41     template <typename Geometry1, typename Geometry2>
applytest_disjoint42     static inline void apply(std::string const& case_id,
43                              Geometry1 const& geometry1,
44                              Geometry2 const& geometry2,
45                              bool expected_result)
46     {
47         bool result = bg::disjoint(geometry1, geometry2);
48         BOOST_CHECK_MESSAGE(result == expected_result,
49             "case ID: " << case_id << ", G1: " << bg::wkt(geometry1)
50             << ", G2: " << bg::wkt(geometry2) << " -> Expected: "
51             << expected_result << ", detected: " << result);
52 
53         result = bg::disjoint(geometry2, geometry1);
54         BOOST_CHECK_MESSAGE(result == expected_result,
55             "case ID: " << case_id << ", G1: " << bg::wkt(geometry2)
56             << ", G2: " << bg::wkt(geometry1) << " -> Expected: "
57             << expected_result << ", detected: " << result);
58 
59 #ifdef BOOST_GEOMETRY_TEST_DEBUG
60         std::cout << "case ID: " << case_id << "; G1 - G2: ";
61         std::cout << bg::wkt(geometry1) << " - ";
62         std::cout << bg::wkt(geometry2) << std::endl;
63         std::cout << std::boolalpha;
64         std::cout << "expected/computed result: "
65                   << expected_result << " / " << result << std::endl;
66         std::cout << std::endl;
67         std::cout << std::noboolalpha;
68 #endif
69     }
70 };
71 
72 //============================================================================
73 
74 // linear-areal geometries
75 template <typename P>
test_segment_box()76 inline void test_segment_box()
77 {
78     typedef bg::model::segment<P> S;
79     typedef bg::model::box<P> B;
80 
81     typedef test_disjoint tester;
82 
83     tester::apply("s-b-01",
84                   from_wkt<S>("SEGMENT(0 0,2 0)"),
85                   from_wkt<B>("BOX(0 0,2 2)"),
86                   false);
87 
88     tester::apply("s-b-02",
89                   from_wkt<S>("SEGMENT(1 1,3 3)"),
90                   from_wkt<B>("BOX(0 0,2 2)"),
91                   false);
92 
93     tester::apply("s-b-03",
94                   from_wkt<S>("SEGMENT(2 2,3 3)"),
95                   from_wkt<B>("BOX(0 0,2 2)"),
96                   false);
97 
98     tester::apply("s-b-04",
99                   from_wkt<S>("SEGMENT(4 4,3 3)"),
100                   from_wkt<B>("BOX(0 0,2 2)"),
101                   true);
102 
103     tester::apply("s-b-05",
104                   from_wkt<S>("SEGMENT(0 4,4 4)"),
105                   from_wkt<B>("BOX(0 0,2 2)"),
106                   true);
107 
108     tester::apply("s-b-06",
109                   from_wkt<S>("SEGMENT(4 0,4 4)"),
110                   from_wkt<B>("BOX(0 0,2 2)"),
111                   true);
112 
113     tester::apply("s-b-07",
114                   from_wkt<S>("SEGMENT(0 -2,0 -1)"),
115                   from_wkt<B>("BOX(0 0,1 1)"),
116                   true);
117 
118     tester::apply("s-b-08",
119                   from_wkt<S>("SEGMENT(-2 -2,-2 -1)"),
120                   from_wkt<B>("BOX(0 0,1 1)"),
121                   true);
122 
123     tester::apply("s-b-09",
124                   from_wkt<S>("SEGMENT(-2 -2,-2 -2)"),
125                   from_wkt<B>("BOX(0 0,1 1)"),
126                   true);
127 
128     tester::apply("s-b-10",
129                   from_wkt<S>("SEGMENT(-2 0,-2 0)"),
130                   from_wkt<B>("BOX(0 0,1 1)"),
131                   true);
132 
133     tester::apply("s-b-11",
134                   from_wkt<S>("SEGMENT(0 -2,0 -2)"),
135                   from_wkt<B>("BOX(0 0,1 1)"),
136                   true);
137 
138     tester::apply("s-b-12",
139                   from_wkt<S>("SEGMENT(-2 0,-1 0)"),
140                   from_wkt<B>("BOX(0 0,1 1)"),
141                   true);
142 
143     // segment degenerates to a point
144     tester::apply("s-b-13",
145                   from_wkt<S>("SEGMENT(0 0,0 0)"),
146                   from_wkt<B>("BOX(0 0,1 1)"),
147                   false);
148 
149     tester::apply("s-b-14",
150                   from_wkt<S>("SEGMENT(1 1,1 1)"),
151                   from_wkt<B>("BOX(0 0,2 2)"),
152                   false);
153 
154     tester::apply("s-b-15",
155                   from_wkt<S>("SEGMENT(2 2,2 2)"),
156                   from_wkt<B>("BOX(0 0,2 2)"),
157                   false);
158 
159     tester::apply("s-b-16",
160                   from_wkt<S>("SEGMENT(2 0,2 0)"),
161                   from_wkt<B>("BOX(0 0,2 2)"),
162                   false);
163 
164     tester::apply("s-b-17",
165                   from_wkt<S>("SEGMENT(0 2,0 2)"),
166                   from_wkt<B>("BOX(0 0,2 2)"),
167                   false);
168 
169     tester::apply("s-b-18",
170                   from_wkt<S>("SEGMENT(2 2,2 2)"),
171                   from_wkt<B>("BOX(0 0,1 1)"),
172                   true);
173 }
174 
175 template <typename P>
test_segment_ring()176 inline void test_segment_ring()
177 {
178     typedef bg::model::segment<P> S;
179     typedef bg::model::ring<P, false, false> R; // ccw, open
180 
181     typedef test_disjoint tester;
182 
183     tester::apply("s-r-01",
184                   from_wkt<S>("SEGMENT(0 0,2 0)"),
185                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
186                   false);
187 
188     tester::apply("s-r-02",
189                   from_wkt<S>("SEGMENT(1 0,3 3)"),
190                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
191                   false);
192 
193     tester::apply("s-r-03",
194                   from_wkt<S>("SEGMENT(1 1,3 3)"),
195                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
196                   false);
197 
198     tester::apply("s-r-04",
199                   from_wkt<S>("SEGMENT(2 2,3 3)"),
200                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
201                   true);
202 }
203 
204 template <typename P>
test_segment_polygon()205 inline void test_segment_polygon()
206 {
207     typedef bg::model::segment<P> S;
208     typedef bg::model::polygon<P, false, false> PL; // ccw, open
209 
210     typedef test_disjoint tester;
211 
212     tester::apply("s-pg-01",
213                   from_wkt<S>("SEGMENT(0 0,2 0)"),
214                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
215                   false);
216 
217     tester::apply("s-pg-02",
218                   from_wkt<S>("SEGMENT(1 0,3 3)"),
219                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
220                   false);
221 
222     tester::apply("s-pg-03",
223                   from_wkt<S>("SEGMENT(1 1,3 3)"),
224                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
225                   false);
226 
227     tester::apply("s-pg-04",
228                   from_wkt<S>("SEGMENT(2 2,3 3)"),
229                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
230                   true);
231 }
232 
233 template <typename P>
test_segment_multipolygon()234 inline void test_segment_multipolygon()
235 {
236     typedef bg::model::segment<P> S;
237     typedef bg::model::polygon<P, false, false> PL; // ccw, open
238     typedef bg::model::multi_polygon<PL> MPL;
239 
240     typedef test_disjoint tester;
241 
242     tester::apply("s-mpg-01",
243                   from_wkt<S>("SEGMENT(0 0,2 0)"),
244                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
245                   false);
246 
247     tester::apply("s-mpg-02",
248                   from_wkt<S>("SEGMENT(1 0,3 3)"),
249                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
250                   false);
251 
252     tester::apply("s-mpg-03",
253                   from_wkt<S>("SEGMENT(1 1,3 3)"),
254                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
255                   false);
256 
257     tester::apply("s-mpg-04",
258                   from_wkt<S>("SEGMENT(2 2,3 3)"),
259                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
260                   true);
261 }
262 
263 template <typename P>
test_linestring_box()264 inline void test_linestring_box()
265 {
266     typedef bg::model::linestring<P> L;
267     typedef bg::model::box<P> B;
268 
269     typedef test_disjoint tester;
270 
271     tester::apply("l-b-01",
272                   from_wkt<L>("LINESTRING(0 0,2 0)"),
273                   from_wkt<B>("BOX(0 0,2 2)"),
274                   false);
275 
276     tester::apply("l-b-02",
277                   from_wkt<L>("LINESTRING(1 1,3 3)"),
278                   from_wkt<B>("BOX(0 0,2 2)"),
279                   false);
280 
281     tester::apply("l-b-03",
282                   from_wkt<L>("LINESTRING(2 2,3 3)"),
283                   from_wkt<B>("BOX(0 0,2 2)"),
284                   false);
285 
286     tester::apply("l-b-04",
287                   from_wkt<L>("LINESTRING(4 4,3 3)"),
288                   from_wkt<B>("BOX(0 0,2 2)"),
289                   true);
290 }
291 
292 template <typename P>
test_linestring_ring()293 inline void test_linestring_ring()
294 {
295     typedef bg::model::linestring<P> L;
296     typedef bg::model::ring<P, false, false> R; // ccw, open
297 
298     typedef test_disjoint tester;
299 
300     tester::apply("l-r-01",
301                   from_wkt<L>("LINESTRING(0 0,2 0)"),
302                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
303                   false);
304 
305     tester::apply("l-r-02",
306                   from_wkt<L>("LINESTRING(1 0,3 3)"),
307                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
308                   false);
309 
310     tester::apply("l-r-03",
311                   from_wkt<L>("LINESTRING(1 1,3 3)"),
312                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
313                   false);
314 
315     tester::apply("l-r-04",
316                   from_wkt<L>("LINESTRING(2 2,3 3)"),
317                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
318                   true);
319 }
320 
321 template <typename P>
test_linestring_polygon()322 inline void test_linestring_polygon()
323 {
324     typedef bg::model::linestring<P> L;
325     typedef bg::model::polygon<P, false, false> PL; // ccw, open
326 
327     typedef test_disjoint tester;
328 
329     tester::apply("l-pg-01",
330                   from_wkt<L>("LINESTRING(0 0,2 0)"),
331                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
332                   false);
333 
334     tester::apply("l-pg-02",
335                   from_wkt<L>("LINESTRING(1 0,3 3)"),
336                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
337                   false);
338 
339     tester::apply("l-pg-03",
340                   from_wkt<L>("LINESTRING(1 1,3 3)"),
341                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
342                   false);
343 
344     tester::apply("l-pg-04",
345                   from_wkt<L>("LINESTRING(2 2,3 3)"),
346                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
347                   true);
348 }
349 
350 template <typename P>
test_linestring_multipolygon()351 inline void test_linestring_multipolygon()
352 {
353     typedef bg::model::linestring<P> L;
354     typedef bg::model::polygon<P, false, false> PL; // ccw, open
355     typedef bg::model::multi_polygon<PL> MPL;
356 
357     typedef test_disjoint tester;
358 
359     tester::apply("l-mpg-01",
360                   from_wkt<L>("LINESTRING(0 0,2 0)"),
361                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
362                   false);
363 
364     tester::apply("l-mpg-02",
365                   from_wkt<L>("LINESTRING(1 0,3 3)"),
366                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
367                   false);
368 
369     tester::apply("l-mpg-03",
370                   from_wkt<L>("LINESTRING(1 1,3 3)"),
371                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
372                   false);
373 
374     tester::apply("l-mpg-04",
375                   from_wkt<L>("LINESTRING(2 2,3 3)"),
376                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
377                   true);
378 }
379 
380 template <typename P>
test_multilinestring_box()381 inline void test_multilinestring_box()
382 {
383     typedef bg::model::linestring<P> L;
384     typedef bg::model::multi_linestring<L> ML;
385     typedef bg::model::box<P> B;
386 
387     typedef test_disjoint tester;
388 
389     tester::apply("ml-b-01",
390                   from_wkt<ML>("MULTILINESTRING((0 0,2 0))"),
391                   from_wkt<B>("BOX(0 0,2 2)"),
392                   false);
393 
394     tester::apply("ml-b-02",
395                   from_wkt<ML>("MULTILINESTRING((1 1,3 3))"),
396                   from_wkt<B>("BOX(0 0,2 2)"),
397                   false);
398 
399     tester::apply("ml-b-03",
400                   from_wkt<ML>("MULTILINESTRING((2 2,3 3))"),
401                   from_wkt<B>("BOX(0 0,2 2)"),
402                   false);
403 
404     tester::apply("ml-b-04",
405                   from_wkt<ML>("MULTILINESTRING((4 4,3 3))"),
406                   from_wkt<B>("BOX(0 0,2 2)"),
407                   true);
408 }
409 
410 template <typename P>
test_multilinestring_ring()411 inline void test_multilinestring_ring()
412 {
413     typedef bg::model::linestring<P> L;
414     typedef bg::model::multi_linestring<L> ML;
415     typedef bg::model::ring<P, false, false> R; // ccw, open
416 
417     typedef test_disjoint tester;
418 
419     tester::apply("ml-r-01",
420                   from_wkt<ML>("MULTILINESTRING((0 0,2 0))"),
421                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
422                   false);
423 
424     tester::apply("ml-r-02",
425                   from_wkt<ML>("MULTILINESTRING((1 0,3 3))"),
426                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
427                   false);
428 
429     tester::apply("ml-r-03",
430                   from_wkt<ML>("MULTILINESTRING((1 1,3 3))"),
431                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
432                   false);
433 
434     tester::apply("ml-r-04",
435                   from_wkt<ML>("MULTILINESTRING((2 2,3 3))"),
436                   from_wkt<R>("POLYGON((0 0,2 0,0 2))"),
437                   true);
438 }
439 
440 template <typename P>
test_multilinestring_polygon()441 inline void test_multilinestring_polygon()
442 {
443     typedef bg::model::linestring<P> L;
444     typedef bg::model::multi_linestring<L> ML;
445     typedef bg::model::polygon<P, false, false> PL; // ccw, open
446 
447     typedef test_disjoint tester;
448 
449     tester::apply("ml-pg-01",
450                   from_wkt<ML>("MULTILINESTRING((0 0,2 0))"),
451                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
452                   false);
453 
454     tester::apply("ml-pg-02",
455                   from_wkt<ML>("MULTILINESTRING((1 0,3 3))"),
456                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
457                   false);
458 
459     tester::apply("ml-pg-03",
460                   from_wkt<ML>("MULTILINESTRING((1 1,3 3))"),
461                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
462                   false);
463 
464     tester::apply("ml-pg-04",
465                   from_wkt<ML>("MULTILINESTRING((2 2,3 3))"),
466                   from_wkt<PL>("POLYGON((0 0,2 0,0 2))"),
467                   true);
468 }
469 
470 template <typename P>
test_multilinestring_multipolygon()471 inline void test_multilinestring_multipolygon()
472 {
473     typedef bg::model::linestring<P> L;
474     typedef bg::model::multi_linestring<L> ML;
475     typedef bg::model::polygon<P, false, false> PL; // ccw, open
476     typedef bg::model::multi_polygon<PL> MPL;
477 
478     typedef test_disjoint tester;
479 
480     tester::apply("ml-mpg-01",
481                   from_wkt<ML>("MULTILINESTRING((0 0,2 0))"),
482                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
483                   false);
484 
485     tester::apply("ml-mpg-02",
486                   from_wkt<ML>("MULTILINESTRING((1 0,3 3))"),
487                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
488                   false);
489 
490     tester::apply("ml-mpg-03",
491                   from_wkt<ML>("MULTILINESTRING((1 1,3 3))"),
492                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
493                   false);
494 
495     tester::apply("ml-mpg-04",
496                   from_wkt<ML>("MULTILINESTRING((2 2,3 3))"),
497                   from_wkt<MPL>("MULTIPOLYGON(((0 0,2 0,0 2)))"),
498                   true);
499 }
500 
501 //============================================================================
502 
503 template <typename CoordinateType>
test_linear_areal()504 inline void test_linear_areal()
505 {
506     typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
507 
508     test_segment_polygon<point_type>();
509     test_segment_multipolygon<point_type>();
510     test_segment_ring<point_type>();
511     test_segment_box<point_type>();
512 
513     test_linestring_polygon<point_type>();
514     test_linestring_multipolygon<point_type>();
515     test_linestring_ring<point_type>();
516     test_linestring_box<point_type>();
517 
518     test_multilinestring_polygon<point_type>();
519     test_multilinestring_multipolygon<point_type>();
520     test_multilinestring_ring<point_type>();
521     test_multilinestring_box<point_type>();
522 }
523 
524 //============================================================================
525 
BOOST_AUTO_TEST_CASE(test_linear_areal_all)526 BOOST_AUTO_TEST_CASE( test_linear_areal_all )
527 {
528     test_linear_areal<double>();
529     test_linear_areal<int>();
530 }
531