1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
5
6 // Copyright (c) 2014, Oracle and/or its affiliates.
7
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9
10 // Licensed under the Boost Software License version 1.0.
11 // http://www.boost.org/users/license.html
12
13
14 #ifndef BOOST_TEST_MODULE
15 #define BOOST_TEST_MODULE test_segment_iterator
16 #endif
17
18 #include <algorithm>
19 #include <iostream>
20 #include <iterator>
21 #include <string>
22 #include <vector>
23
24 #include <boost/test/included/unit_test.hpp>
25
26 #include <boost/assign/list_of.hpp>
27 #include <boost/concept_check.hpp>
28 #include <boost/core/ignore_unused.hpp>
29 #include <boost/iterator/iterator_concepts.hpp>
30 #include <boost/tuple/tuple.hpp>
31
32 #include <boost/geometry/geometries/geometries.hpp>
33 #include <boost/geometry/geometries/adapted/boost_tuple.hpp>
34 #include <boost/geometry/geometries/register/linestring.hpp>
35 #include <boost/geometry/geometries/register/multi_linestring.hpp>
36
37 #include <boost/geometry/io/wkt/wkt.hpp>
38 #include <boost/geometry/io/dsv/write.hpp>
39
40 #include <boost/geometry/core/closure.hpp>
41
42 #include <boost/geometry/algorithms/convert.hpp>
43 #include <boost/geometry/algorithms/equals.hpp>
44 #include <boost/geometry/algorithms/num_segments.hpp>
45
46 #include <boost/geometry/policies/compare.hpp>
47
48 #include <boost/geometry/iterators/segment_iterator.hpp>
49
50 #include <test_common/with_pointer.hpp>
51 #include <test_geometries/copy_on_dereference_geometries.hpp>
52
53 namespace ba = ::boost::assign;
54 namespace bg = ::boost::geometry;
55 namespace bgm = bg::model;
56
57 typedef bgm::point<double, 2, bg::cs::cartesian> point_type;
58 typedef bgm::linestring<point_type> linestring_type;
59 typedef bgm::ring<point_type, true, true> ring_cw_closed_type;
60 typedef bgm::ring<point_type, true, false> ring_cw_open_type;
61 typedef bgm::polygon<point_type, true, true> polygon_cw_closed_type;
62 typedef bgm::polygon<point_type, true, false> polygon_cw_open_type;
63
64 // multi-geometries
65 typedef bgm::multi_linestring<linestring_type> multi_linestring_type;
66 typedef bgm::multi_polygon<polygon_cw_closed_type> multi_polygon_cw_closed_type;
67 typedef bgm::multi_polygon<polygon_cw_open_type> multi_polygon_cw_open_type;
68
69 // tuple-based geometries
70 typedef boost::tuple<double, double> tuple_point_type;
71 typedef std::vector<tuple_point_type> tuple_linestring_type;
72 typedef std::vector<tuple_linestring_type> tuple_multi_linestring_type;
73
74 BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
BOOST_GEOMETRY_REGISTER_LINESTRING(tuple_linestring_type)75 BOOST_GEOMETRY_REGISTER_LINESTRING(tuple_linestring_type)
76 BOOST_GEOMETRY_REGISTER_MULTI_LINESTRING(tuple_multi_linestring_type)
77
78 BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(std::vector)
79
80
81 template <typename Geometry>
82 inline Geometry from_wkt(std::string const& wkt)
83 {
84 Geometry geometry;
85 boost::geometry::read_wkt(wkt, geometry);
86 return geometry;
87 }
88
89 template <typename Iterator>
print_geometry_range(std::ostream & os,Iterator first,Iterator beyond,std::string const & header)90 inline std::ostream& print_geometry_range(std::ostream& os,
91 Iterator first,
92 Iterator beyond,
93 std::string const& header)
94 {
95 os << header << "(";
96 for (Iterator it = first; it != beyond; ++it)
97 {
98 os << " " << bg::dsv(*it);
99 }
100 os << " )";
101 return os;
102 }
103
104 template <typename Geometry>
105 struct test_iterator_concepts
106 {
107 typedef bg::segment_iterator<Geometry> iterator;
108 BOOST_CONCEPT_ASSERT(( boost::BidirectionalIteratorConcept<iterator> ));
109 BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<iterator> ));
110 BOOST_CONCEPT_ASSERT
111 (( boost_concepts::BidirectionalTraversalConcept<iterator> ));
112 };
113
114 struct equals
115 {
116 template <typename Iterator>
number_of_elementsequals117 static inline std::size_t number_of_elements(Iterator begin,
118 Iterator end)
119 {
120 std::size_t size = std::distance(begin, end);
121
122 std::size_t num_elems(0);
123 for (Iterator it = begin; it != end; ++it)
124 {
125 ++num_elems;
126 }
127 BOOST_CHECK(size == num_elems);
128
129 num_elems = 0;
130 for (Iterator it = end; it != begin; --it)
131 {
132 ++num_elems;
133 }
134 BOOST_CHECK(size == num_elems);
135
136 return num_elems;
137 }
138
139 template <typename Iterator1, typename Iterator2>
applyequals140 static inline bool apply(Iterator1 begin1, Iterator1 end1,
141 Iterator2 begin2, Iterator2 end2)
142 {
143 std::size_t num_points1 = number_of_elements(begin1, end1);
144 std::size_t num_points2 = number_of_elements(begin2, end2);
145
146 if (num_points1 != num_points2)
147 {
148 return false;
149 }
150
151 Iterator1 it1 = begin1;
152 Iterator2 it2 = begin2;
153 for (; it1 != end1; ++it1, ++it2)
154 {
155 if (! bg::equals(*it1, *it2))
156 {
157 return false;
158 }
159 }
160 return true;
161 }
162 };
163
164
165 template <typename Geometry, typename SegmentRange>
166 struct test_segment_iterator_of_geometry
167 {
168 template <typename G>
base_testtest_segment_iterator_of_geometry169 static inline void base_test(G const& geometry,
170 SegmentRange const& segment_range,
171 std::string const& header,
172 bool check_num_segments)
173 {
174 boost::ignore_unused(header);
175
176 typedef bg::segment_iterator<G const> segment_iterator;
177
178 test_iterator_concepts<G const>();
179
180 segment_iterator begin = bg::segments_begin(geometry);
181 segment_iterator end = bg::segments_end(geometry);
182
183 if (check_num_segments)
184 {
185 BOOST_CHECK(std::size_t(std::distance(begin, end))
186 ==
187 bg::num_segments(geometry));
188 }
189
190 BOOST_CHECK(equals::apply(begin, end,
191 bg::segments_begin(segment_range),
192 bg::segments_end(segment_range))
193 );
194
195 #ifdef BOOST_GEOMETRY_TEST_DEBUG
196 std::string closure
197 = (
198 (bg::closure<Geometry>::value == bg::closed)
199 ? "closed"
200 : "open"
201 );
202
203 std::cout << header << " geometry (WKT): "
204 << bg::wkt(geometry) << std::endl;
205 std::cout << header << " geometry (DSV): "
206 << bg::dsv(geometry) << std::endl;
207 std::cout << "geometry's closure: " << closure << std::endl;
208 print_geometry_range(std::cout, begin, end, "segment range: ");
209
210 std::cout << std::endl;
211
212 print_geometry_range(std::cout,
213 bg::segments_begin(segment_range),
214 bg::segments_end(segment_range),
215 "expected segment range: ");
216 std::cout << std::endl;
217 #endif
218
219 // testing dereferencing
220 typedef typename std::iterator_traits
221 <
222 segment_iterator
223 >::value_type value_type;
224
225 if (bg::segments_begin(geometry) != bg::segments_end(geometry))
226 {
227 value_type first_segment = *bg::segments_begin(geometry);
228
229 boost::ignore_unused(first_segment);
230
231 #ifdef BOOST_GEOMETRY_TEST_DEBUG
232 typedef bg::model::segment
233 <
234 bg::model::point<double, 2, bg::cs::cartesian>
235 > other_segment;
236 other_segment other_seg;
237 // convert is used as a workaround for geometries whose
238 // point is a pointer. WKT does not seem to work for
239 // segment iterators created this way.
240 bg::convert(first_segment, other_seg);
241 std::cout << "first segment in geometry: "
242 << bg::wkt(other_seg)
243 << std::endl;
244 std::cout << "first segment in geometry (DSV): "
245 << bg::dsv(first_segment)
246 << std::endl;
247
248 std::cout << std::endl << std::endl;
249 #endif
250 }
251
252 // test copying all segments to a vector
253 std::vector<value_type> segments;
254 std::copy(bg::segments_begin(geometry),
255 bg::segments_end(geometry),
256 std::back_inserter(segments));
257
258 BOOST_CHECK(std::size_t( std::distance(bg::segments_begin(geometry),
259 bg::segments_end(geometry)) )
260 ==
261 segments.size());
262 }
263
applytest_segment_iterator_of_geometry264 static inline void apply(Geometry geometry,
265 SegmentRange const& segment_range,
266 bool check_num_segments = true)
267 {
268 base_test<Geometry>(geometry, segment_range, "const",
269 check_num_segments);
270 }
271 };
272
273 //======================================================================
274 //======================================================================
275
276 template <typename ClosedGeometry, typename ExpectedResult>
277 struct dual_tester
278 {
279 template <typename OpenGeometry>
applydual_tester280 static inline void apply(OpenGeometry const& open_g,
281 ExpectedResult expected,
282 bool check_num_segments = true)
283 {
284 typedef test_segment_iterator_of_geometry
285 <
286 OpenGeometry, ExpectedResult
287 > otester;
288
289 typedef test_segment_iterator_of_geometry
290 <
291 ClosedGeometry, ExpectedResult
292 > ctester;
293
294 otester::apply(open_g, expected, check_num_segments);
295
296 #ifdef BOOST_GEOMETRY_TEST_DEBUG
297 std::cout << std::endl << std::endl;
298 #endif
299
300 ClosedGeometry closed_g;
301
302 bg::convert(open_g, closed_g);
303
304 ctester::apply(closed_g, expected, check_num_segments);
305 }
306 };
307
308 //======================================================================
309 //======================================================================
310
BOOST_AUTO_TEST_CASE(test_linestring_segment_iterator)311 BOOST_AUTO_TEST_CASE( test_linestring_segment_iterator )
312 {
313 #ifdef BOOST_GEOMETRY_TEST_DEBUG
314 std::cout << "*** LINESTRING ***" << std::endl;
315 #endif
316
317 typedef tuple_multi_linestring_type TML;
318 typedef linestring_type G;
319
320 typedef test_segment_iterator_of_geometry<G, TML> tester;
321
322 tester::apply(from_wkt<G>("LINESTRING(0 0,1 1,2 2,3 3,4 4)"),
323 ba::list_of<tuple_linestring_type>
324 ( ba::tuple_list_of(0,0)(1,1) )
325 ( ba::tuple_list_of(1,1)(2,2) )
326 ( ba::tuple_list_of(2,2)(3,3) )
327 ( ba::tuple_list_of(3,3)(4,4) )
328 );
329
330 // linestring with no points
331 tester::apply(from_wkt<G>("LINESTRING()"),
332 ba::list_of<tuple_linestring_type>()
333 );
334
335 // linestring with a single point
336 tester::apply(from_wkt<G>("LINESTRING(1 0)"),
337 ba::list_of<tuple_linestring_type>
338 ( ba::tuple_list_of(1,0)(1,0) ),
339 false
340 );
341
342 #ifdef BOOST_GEOMETRY_TEST_DEBUG
343 std::cout << std::endl << std::endl << std::endl;
344 #endif
345 }
346
347 //======================================================================
348 //======================================================================
349
BOOST_AUTO_TEST_CASE(test_ring_segment_iterator)350 BOOST_AUTO_TEST_CASE( test_ring_segment_iterator )
351 {
352 #ifdef BOOST_GEOMETRY_TEST_DEBUG
353 std::cout << "*** RING ***" << std::endl;
354 #endif
355
356 typedef tuple_multi_linestring_type TML;
357 typedef ring_cw_open_type OG;
358 typedef ring_cw_closed_type CG;
359
360 typedef dual_tester<CG, TML> tester;
361
362 tester::apply(from_wkt<OG>("POLYGON((0 0,0 10,10 10,10 0))"),
363 ba::list_of<tuple_linestring_type>
364 ( ba::tuple_list_of(0,0)(0,10) )
365 ( ba::tuple_list_of(0,10)(10,10) )
366 ( ba::tuple_list_of(10,10)(10,0) )
367 ( ba::tuple_list_of(10,0)(0,0) )
368 );
369
370 // open ring with no points
371 tester::apply(from_wkt<OG>("POLYGON(())"),
372 ba::list_of<tuple_linestring_type>()
373 );
374
375 // open ring with a single point (one segment)
376 tester::apply(from_wkt<OG>("POLYGON((0 0))"),
377 ba::list_of<tuple_linestring_type>
378 ( ba::tuple_list_of(0,0)(0,0) ),
379 false
380 );
381
382 // open ring with a two points (two segments)
383 tester::apply(from_wkt<OG>("POLYGON((0 0,0 10))"),
384 ba::list_of<tuple_linestring_type>
385 ( ba::tuple_list_of(0,0)(0,10) )
386 ( ba::tuple_list_of(0,10)(0,0) )
387 );
388
389 // open ring with a three points (three segments)
390 tester::apply(from_wkt<OG>("POLYGON((0 0,0 10,10 10))"),
391 ba::list_of<tuple_linestring_type>
392 ( ba::tuple_list_of(0,0)(0,10) )
393 ( ba::tuple_list_of(0,10)(10,10) )
394 ( ba::tuple_list_of(10,10)(0,0) )
395 );
396
397 tester::apply(from_wkt<CG>("POLYGON((0 0,0 10,10 10,10 0,0 0))"),
398 ba::list_of<tuple_linestring_type>
399 ( ba::tuple_list_of(0,0)(0,10) )
400 ( ba::tuple_list_of(0,10)(10,10) )
401 ( ba::tuple_list_of(10,10)(10,0) )
402 ( ba::tuple_list_of(10,0)(0,0) )
403 );
404
405 // closed ring with no points
406 tester::apply(from_wkt<CG>("POLYGON(())"),
407 ba::list_of<tuple_linestring_type>()
408 );
409
410 // closed ring with a single point (one segment)
411 tester::apply(from_wkt<CG>("POLYGON((0 0))"),
412 ba::list_of<tuple_linestring_type>
413 ( ba::tuple_list_of(0,0)(0,0) ),
414 false
415 );
416
417 // closed ring with two points (one segment)
418 tester::apply(from_wkt<CG>("POLYGON((0 0,0 0))"),
419 ba::list_of<tuple_linestring_type>
420 ( ba::tuple_list_of(0,0)(0,0) )
421 );
422
423 // closed ring with three points (two segments)
424 tester::apply(from_wkt<CG>("POLYGON((0 0,0 10,0 0))"),
425 ba::list_of<tuple_linestring_type>
426 ( ba::tuple_list_of(0,0)(0,10) )
427 ( ba::tuple_list_of(0,10)(0,0) )
428 );
429
430 // closed ring with four points (three segments)
431 tester::apply(from_wkt<CG>("POLYGON((0 0,0 10,10 10,0 0))"),
432 ba::list_of<tuple_linestring_type>
433 ( ba::tuple_list_of(0,0)(0,10) )
434 ( ba::tuple_list_of(0,10)(10,10) )
435 ( ba::tuple_list_of(10,10)(0,0) )
436 );
437
438 #ifdef BOOST_GEOMETRY_TEST_DEBUG
439 std::cout << std::endl << std::endl << std::endl;
440 #endif
441 }
442
443 //======================================================================
444 //======================================================================
445
BOOST_AUTO_TEST_CASE(test_polygon_segment_iterator)446 BOOST_AUTO_TEST_CASE( test_polygon_segment_iterator )
447 {
448 #ifdef BOOST_GEOMETRY_TEST_DEBUG
449 std::cout << "*** POLYGON ***" << std::endl;
450 #endif
451
452 typedef tuple_multi_linestring_type TML;
453 typedef polygon_cw_open_type OG;
454 typedef polygon_cw_closed_type CG;
455
456 typedef dual_tester<CG, TML> tester;
457
458 tester::apply(from_wkt<OG>("POLYGON((0 0,0 10,10 10,10 0),(1 1,9 1,9 9,1 9))"),
459 ba::list_of<tuple_linestring_type>
460 ( ba::tuple_list_of(0,0)(0,10) )
461 ( ba::tuple_list_of(0,10)(10,10) )
462 ( ba::tuple_list_of(10,10)(10,0) )
463 ( ba::tuple_list_of(10,0)(0,0) )
464 ( ba::tuple_list_of(1,1)(9,1) )
465 ( ba::tuple_list_of(9,1)(9,9) )
466 ( ba::tuple_list_of(9,9)(1,9) )
467 ( ba::tuple_list_of(1,9)(1,1) )
468 );
469
470 // open polygon with no points
471 tester::apply(from_wkt<OG>("POLYGON(())"),
472 ba::list_of<tuple_linestring_type>()
473 );
474
475 // open polygons with single-point rings
476 tester::apply(from_wkt<OG>("POLYGON((0 0,0 10,10 10,10 0),(1 1))"),
477 ba::list_of<tuple_linestring_type>
478 ( ba::tuple_list_of(0,0)(0,10) )
479 ( ba::tuple_list_of(0,10)(10,10) )
480 ( ba::tuple_list_of(10,10)(10,0) )
481 ( ba::tuple_list_of(10,0)(0,0) )
482 ( ba::tuple_list_of(1,1)(1,1) ),
483 false
484 );
485
486 tester::apply(from_wkt<OG>("POLYGON((0 0),(1 1,9 1,9 9,1 9))"),
487 ba::list_of<tuple_linestring_type>
488 ( ba::tuple_list_of(0,0)(0,0) )
489 ( ba::tuple_list_of(1,1)(9,1) )
490 ( ba::tuple_list_of(9,1)(9,9) )
491 ( ba::tuple_list_of(9,9)(1,9) )
492 ( ba::tuple_list_of(1,9)(1,1) ),
493 false
494 );
495
496
497 tester::apply(from_wkt<CG>("POLYGON((0 0,0 10,10 10,10 0,0 0),(1 1,9 1,9 9,1 9,1 1))"),
498 ba::list_of<tuple_linestring_type>
499 ( ba::tuple_list_of(0,0)(0,10) )
500 ( ba::tuple_list_of(0,10)(10,10) )
501 ( ba::tuple_list_of(10,10)(10,0) )
502 ( ba::tuple_list_of(10,0)(0,0) )
503 ( ba::tuple_list_of(1,1)(9,1) )
504 ( ba::tuple_list_of(9,1)(9,9) )
505 ( ba::tuple_list_of(9,9)(1,9) )
506 ( ba::tuple_list_of(1,9)(1,1) )
507 );
508
509 // closed polygons with no points
510 tester::apply(from_wkt<CG>("POLYGON(())"),
511 ba::list_of<tuple_linestring_type>()
512 );
513 tester::apply(from_wkt<CG>("POLYGON((),())"),
514 ba::list_of<tuple_linestring_type>()
515 );
516 tester::apply(from_wkt<CG>("POLYGON((),(),())"),
517 ba::list_of<tuple_linestring_type>()
518 );
519
520 // closed polygons with single-point rings
521 tester::apply(from_wkt<CG>("POLYGON((0 0,0 10,10 10,10 0,0 0),(1 1))"),
522 ba::list_of<tuple_linestring_type>
523 ( ba::tuple_list_of(0,0)(0,10) )
524 ( ba::tuple_list_of(0,10)(10,10) )
525 ( ba::tuple_list_of(10,10)(10,0) )
526 ( ba::tuple_list_of(10,0)(0,0) )
527 ( ba::tuple_list_of(1,1)(1,1) ),
528 false
529 );
530
531 tester::apply(from_wkt<CG>("POLYGON((0 0),(1 1,9 1,9 9,1 9,1 1))"),
532 ba::list_of<tuple_linestring_type>
533 ( ba::tuple_list_of(0,0)(0,0) )
534 ( ba::tuple_list_of(1,1)(9,1) )
535 ( ba::tuple_list_of(9,1)(9,9) )
536 ( ba::tuple_list_of(9,9)(1,9) )
537 ( ba::tuple_list_of(1,9)(1,1) ),
538 false
539 );
540
541 #ifdef BOOST_GEOMETRY_TEST_DEBUG
542 std::cout << std::endl << std::endl << std::endl;
543 #endif
544 }
545
546 //======================================================================
547 //======================================================================
548
BOOST_AUTO_TEST_CASE(test_multi_linestring_segment_iterator)549 BOOST_AUTO_TEST_CASE( test_multi_linestring_segment_iterator )
550 {
551 #ifdef BOOST_GEOMETRY_TEST_DEBUG
552 std::cout << "*** MULTILINESTRING ***" << std::endl;
553 #endif
554
555 typedef tuple_multi_linestring_type TML;
556 typedef multi_linestring_type G;
557
558 typedef test_segment_iterator_of_geometry<G, TML> tester;
559
560 tester::apply(from_wkt<G>("MULTILINESTRING((0 0,1 1,2 2,3 3,4 4),(5 5,6 6,7 7,8 8),(9 9,10 10))"),
561 ba::list_of<tuple_linestring_type>
562 ( ba::tuple_list_of(0,0)(1,1) )
563 ( ba::tuple_list_of(1,1)(2,2) )
564 ( ba::tuple_list_of(2,2)(3,3) )
565 ( ba::tuple_list_of(3,3)(4,4) )
566 ( ba::tuple_list_of(5,5)(6,6) )
567 ( ba::tuple_list_of(6,6)(7,7) )
568 ( ba::tuple_list_of(7,7)(8,8) )
569 ( ba::tuple_list_of(9,9)(10,10) )
570 );
571
572 // empty multi-linestrings
573 tester::apply(from_wkt<G>("MULTILINESTRING()"),
574 ba::list_of<tuple_linestring_type>()
575 );
576 tester::apply(from_wkt<G>("MULTILINESTRING(())"),
577 ba::list_of<tuple_linestring_type>()
578 );
579 tester::apply(from_wkt<G>("MULTILINESTRING((),())"),
580 ba::list_of<tuple_linestring_type>()
581 );
582
583 // multi-linestring with a linestring with one point
584 tester::apply(from_wkt<G>("MULTILINESTRING((0 0,1 1,2 2,3 3,4 4),(5 5),(9 9,10 10))"),
585 ba::list_of<tuple_linestring_type>
586 ( ba::tuple_list_of(0,0)(1,1) )
587 ( ba::tuple_list_of(1,1)(2,2) )
588 ( ba::tuple_list_of(2,2)(3,3) )
589 ( ba::tuple_list_of(3,3)(4,4) )
590 ( ba::tuple_list_of(5,5)(5,5) )
591 ( ba::tuple_list_of(9,9)(10,10) ),
592 false
593 );
594
595 #ifdef BOOST_GEOMETRY_TEST_DEBUG
596 std::cout << std::endl << std::endl << std::endl;
597 #endif
598 }
599
600 //======================================================================
601 //======================================================================
602
BOOST_AUTO_TEST_CASE(test_multi_polygon_segment_iterator)603 BOOST_AUTO_TEST_CASE( test_multi_polygon_segment_iterator )
604 {
605 #ifdef BOOST_GEOMETRY_TEST_DEBUG
606 std::cout << "*** MULTIPOLYGON ***" << std::endl;
607 #endif
608
609 typedef tuple_multi_linestring_type TML;
610 typedef multi_polygon_cw_open_type OG;
611 typedef multi_polygon_cw_closed_type CG;
612
613 typedef dual_tester<CG, TML> tester;
614
615 tester::apply(from_wkt<OG>("MULTIPOLYGON(((0 0,0 10,10 10,10 0),(1 1,9 1,9 9,1 9)),((20 0,20 10,30 10,30 0),(21 1,29 1,29 9,21 9)))"),
616 ba::list_of<tuple_linestring_type>
617 ( ba::tuple_list_of(0,0)(0,10) )
618 ( ba::tuple_list_of(0,10)(10,10) )
619 ( ba::tuple_list_of(10,10)(10,0) )
620 ( ba::tuple_list_of(10,0)(0,0) )
621 ( ba::tuple_list_of(1,1)(9,1) )
622 ( ba::tuple_list_of(9,1)(9,9) )
623 ( ba::tuple_list_of(9,9)(1,9) )
624 ( ba::tuple_list_of(1,9)(1,1) )
625 ( ba::tuple_list_of(20,0)(20,10) )
626 ( ba::tuple_list_of(20,10)(30,10) )
627 ( ba::tuple_list_of(30,10)(30,0) )
628 ( ba::tuple_list_of(30,0)(20,0) )
629 ( ba::tuple_list_of(21,1)(29,1) )
630 ( ba::tuple_list_of(29,1)(29,9) )
631 ( ba::tuple_list_of(29,9)(21,9) )
632 ( ba::tuple_list_of(21,9)(21,1) )
633 );
634
635 tester::apply(from_wkt<CG>("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0),(1 1,9 1,9 9,1 9,1 1)),((20 0,20 10,30 10,30 0,20 0),(21 1,29 1,29 9,21 9,21 1)))"),
636 ba::list_of<tuple_linestring_type>
637 ( ba::tuple_list_of(0,0)(0,10) )
638 ( ba::tuple_list_of(0,10)(10,10) )
639 ( ba::tuple_list_of(10,10)(10,0) )
640 ( ba::tuple_list_of(10,0)(0,0) )
641 ( ba::tuple_list_of(1,1)(9,1) )
642 ( ba::tuple_list_of(9,1)(9,9) )
643 ( ba::tuple_list_of(9,9)(1,9) )
644 ( ba::tuple_list_of(1,9)(1,1) )
645 ( ba::tuple_list_of(20,0)(20,10) )
646 ( ba::tuple_list_of(20,10)(30,10) )
647 ( ba::tuple_list_of(30,10)(30,0) )
648 ( ba::tuple_list_of(30,0)(20,0) )
649 ( ba::tuple_list_of(21,1)(29,1) )
650 ( ba::tuple_list_of(29,1)(29,9) )
651 ( ba::tuple_list_of(29,9)(21,9) )
652 ( ba::tuple_list_of(21,9)(21,1) )
653 );
654
655 // test empty closed multi-polygons
656 tester::apply(from_wkt<CG>("MULTIPOLYGON()"),
657 ba::list_of<tuple_linestring_type>()
658 );
659 tester::apply(from_wkt<CG>("MULTIPOLYGON((()))"),
660 ba::list_of<tuple_linestring_type>()
661 );
662 tester::apply(from_wkt<CG>("MULTIPOLYGON(((),()))"),
663 ba::list_of<tuple_linestring_type>()
664 );
665 tester::apply(from_wkt<CG>("MULTIPOLYGON(((),(),()))"),
666 ba::list_of<tuple_linestring_type>()
667 );
668 tester::apply(from_wkt<CG>("MULTIPOLYGON(((),(),()),(()))"),
669 ba::list_of<tuple_linestring_type>()
670 );
671 tester::apply(from_wkt<CG>("MULTIPOLYGON(((),(),()),((),()))"),
672 ba::list_of<tuple_linestring_type>()
673 );
674
675 #ifdef BOOST_GEOMETRY_TEST_DEBUG
676 std::cout << std::endl << std::endl << std::endl;
677 #endif
678 }
679
680 //======================================================================
681 //======================================================================
682
BOOST_AUTO_TEST_CASE(test_linestring_of_point_pointers)683 BOOST_AUTO_TEST_CASE( test_linestring_of_point_pointers )
684 {
685 #ifdef BOOST_GEOMETRY_TEST_DEBUG
686 std::cout << "*** LINESTRING OF POINT POINTERS ***" << std::endl;
687 #endif
688
689 typedef tuple_multi_linestring_type TML;
690 typedef std::vector<test::test_point_xy*> L;
691
692 std::vector<test::test_point_xy*> linestring;
693 for (int i = 1; i < 10; i++)
694 {
695 test::test_point_xy* p = new test::test_point_xy;
696 p->x = i;
697 p->y = -i;
698 linestring.push_back(p);
699 }
700
701 test::test_point_xy* zero = new test::test_point_xy;
702 zero->x = 0;
703 zero->y = 0;
704 delete zero;
705
706 typedef test_segment_iterator_of_geometry<L, TML> tester;
707
708 tester::apply(linestring,
709 ba::list_of<tuple_linestring_type>
710 ( ba::tuple_list_of(1,-1)(2,-2) )
711 ( ba::tuple_list_of(2,-2)(3,-3) )
712 ( ba::tuple_list_of(3,-3)(4,-4) )
713 ( ba::tuple_list_of(4,-4)(5,-5) )
714 ( ba::tuple_list_of(5,-5)(6,-6) )
715 ( ba::tuple_list_of(6,-6)(7,-7) )
716 ( ba::tuple_list_of(7,-7)(8,-8) )
717 ( ba::tuple_list_of(8,-8)(9,-9) )
718 );
719
720 for (unsigned int i = 0; i < linestring.size(); i++)
721 {
722 delete linestring[i];
723 }
724 }
725
726 //======================================================================
727 //======================================================================
728
BOOST_AUTO_TEST_CASE(test_linestring_copy_on_dereference)729 BOOST_AUTO_TEST_CASE( test_linestring_copy_on_dereference )
730 {
731 #ifdef BOOST_GEOMETRY_TEST_DEBUG
732 std::cout << "*** LINESTRING WITH COPY-ON-DEREFERENCE ITERATOR ***"
733 << std::endl;
734 #endif
735
736 typedef tuple_multi_linestring_type TML;
737 typedef linestring_copy_on_dereference<point_type> L;
738
739 typedef test_segment_iterator_of_geometry<L, TML> tester;
740
741 tester::apply(from_wkt<L>("LINESTRING(1 -1,2 -2,3 -3,4 -4,5 -5,6 -6, 7 -7,8 -8,9 -9)"),
742 ba::list_of<tuple_linestring_type>
743 ( ba::tuple_list_of(1,-1)(2,-2) )
744 ( ba::tuple_list_of(2,-2)(3,-3) )
745 ( ba::tuple_list_of(3,-3)(4,-4) )
746 ( ba::tuple_list_of(4,-4)(5,-5) )
747 ( ba::tuple_list_of(5,-5)(6,-6) )
748 ( ba::tuple_list_of(6,-6)(7,-7) )
749 ( ba::tuple_list_of(7,-7)(8,-8) )
750 ( ba::tuple_list_of(8,-8)(9,-9) )
751 );
752 }
753