]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | // Unit Test | |
3 | ||
11fdf7f2 TL |
4 | // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. |
5 | ||
b32b8144 | 6 | // Copyright (c) 2014-2017, Oracle and/or its affiliates. |
7c673cae FG |
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 | // Licensed under the Boost Software License version 1.0. | |
12 | // http://www.boost.org/users/license.html | |
13 | ||
14 | ||
15 | #ifndef BOOST_TEST_MODULE | |
16 | #define BOOST_TEST_MODULE test_point_iterator | |
17 | #endif | |
18 | ||
19 | #include <cstddef> | |
20 | #include <iostream> | |
21 | #include <string> | |
22 | #include <iterator> | |
23 | #include <algorithm> | |
24 | ||
25 | #include <boost/test/included/unit_test.hpp> | |
26 | ||
7c673cae FG |
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 | #include <boost/type_traits/is_const.hpp> | |
32 | #include <boost/optional.hpp> | |
33 | #include <boost/type_traits/is_reference.hpp> | |
34 | ||
35 | #include <boost/geometry/core/point_type.hpp> | |
36 | ||
37 | #include <boost/geometry/geometries/geometries.hpp> | |
38 | #include <boost/geometry/geometries/adapted/boost_tuple.hpp> | |
39 | #include <boost/geometry/geometries/register/linestring.hpp> | |
40 | #include <boost/geometry/geometries/register/multi_point.hpp> | |
41 | ||
42 | #include <boost/geometry/algorithms/equals.hpp> | |
43 | #include <boost/geometry/algorithms/make.hpp> | |
44 | #include <boost/geometry/algorithms/num_points.hpp> | |
45 | ||
46 | #include <boost/geometry/policies/compare.hpp> | |
47 | ||
48 | #include <boost/geometry/util/condition.hpp> | |
49 | ||
50 | #include <boost/geometry/io/wkt/wkt.hpp> | |
51 | #include <boost/geometry/io/dsv/write.hpp> | |
52 | ||
53 | #include <boost/geometry/iterators/point_iterator.hpp> | |
54 | #include <boost/geometry/iterators/point_reverse_iterator.hpp> | |
55 | ||
b32b8144 FG |
56 | #include <boost/geometry/strategies/strategies.hpp> |
57 | ||
7c673cae FG |
58 | #include <test_common/with_pointer.hpp> |
59 | #include <test_geometries/copy_on_dereference_geometries.hpp> | |
60 | ||
b32b8144 FG |
61 | // At the end because of conflicts with Boost.QVM |
62 | #include <boost/assign/list_of.hpp> | |
63 | ||
64 | ||
7c673cae FG |
65 | namespace bg = ::boost::geometry; |
66 | namespace ba = ::boost::assign; | |
67 | ||
68 | typedef bg::model::point<double, 2, bg::cs::cartesian> point_type; | |
69 | typedef bg::model::point<double, 3, bg::cs::cartesian> point_type_3d; | |
70 | typedef bg::model::linestring<point_type> linestring_type; | |
71 | typedef bg::model::polygon<point_type, false, false> polygon_type; //ccw, open | |
72 | ||
73 | // multi geometries | |
74 | typedef bg::model::multi_point<point_type> multi_point_type; | |
75 | typedef bg::model::multi_point<point_type_3d> multi_point_type_3d; | |
76 | typedef bg::model::multi_linestring<linestring_type> multi_linestring_type; | |
77 | typedef bg::model::multi_polygon<polygon_type> multi_polygon_type; | |
78 | ||
79 | typedef boost::tuple<double, double> tuple_point_type; | |
80 | typedef boost::tuple<double, double, double> tuple_point_type_3d; | |
81 | typedef std::vector<tuple_point_type> tuple_multi_point_type; | |
82 | typedef std::vector<tuple_point_type_3d> tuple_multi_point_type_3d; | |
83 | ||
84 | template <typename T> | |
85 | struct vector_as_multipoint : std::vector<T> {}; | |
86 | ||
87 | template <typename T> | |
88 | struct vector_as_linestring : std::vector<T> {}; | |
89 | ||
90 | BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) | |
91 | BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type) | |
92 | BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type_3d) | |
93 | ||
94 | BOOST_GEOMETRY_REGISTER_MULTI_POINT_TEMPLATED(vector_as_multipoint) | |
95 | BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(vector_as_linestring) | |
96 | ||
97 | ||
98 | ||
99 | template <typename Geometry> | |
100 | inline Geometry from_wkt(std::string const& wkt) | |
101 | { | |
102 | Geometry geometry; | |
103 | boost::geometry::read_wkt(wkt, geometry); | |
104 | return geometry; | |
105 | } | |
106 | ||
107 | ||
108 | // this function is implemented because std::max_element() requires ForwardIterator | |
109 | // but bg::point_iterator<> is InputIterator since it returns non-true reference | |
110 | template <typename InputIt, typename Pred> | |
111 | inline boost::optional<typename std::iterator_traits<InputIt>::value_type> | |
112 | max_value(InputIt first, InputIt last, Pred pred) | |
113 | { | |
114 | typedef typename std::iterator_traits<InputIt>::value_type value_type; | |
115 | if (first != last) | |
116 | { | |
117 | value_type found = *first++; | |
118 | for (; first != last; ) | |
119 | { | |
120 | value_type current = *first++; | |
121 | if (pred(current, found)) | |
122 | found = current; | |
123 | } | |
124 | return found; | |
125 | } | |
126 | return boost::none; | |
127 | } | |
128 | ||
129 | ||
130 | template <typename Iterator> | |
131 | inline std::ostream& print_point_range(std::ostream& os, | |
132 | Iterator first, | |
133 | Iterator beyond, | |
134 | std::string const& header) | |
135 | { | |
136 | os << header << "("; | |
137 | for (Iterator it = first; it != beyond; ++it) | |
138 | { | |
139 | os << " " << bg::dsv(*it); | |
140 | } | |
141 | os << " )"; | |
142 | return os; | |
143 | } | |
144 | ||
145 | ||
146 | template | |
147 | < | |
148 | typename Geometry, | |
149 | bool Enable = true, | |
150 | bool IsConst = boost::is_const<Geometry>::value | |
151 | > | |
152 | struct test_iterator_concepts | |
153 | { | |
154 | typedef bg::point_iterator<Geometry> iterator; | |
155 | BOOST_CONCEPT_ASSERT((boost::BidirectionalIteratorConcept<iterator>)); | |
156 | BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<iterator>)); | |
157 | BOOST_CONCEPT_ASSERT((boost_concepts::LvalueIteratorConcept<iterator>)); | |
158 | BOOST_CONCEPT_ASSERT | |
159 | ((boost_concepts::BidirectionalTraversalConcept<iterator>)); | |
160 | }; | |
161 | ||
162 | template <typename Geometry> | |
163 | struct test_iterator_concepts<Geometry, true, false> | |
164 | : test_iterator_concepts<Geometry, true, true> | |
165 | { | |
166 | typedef bg::point_iterator<Geometry> iterator; | |
167 | BOOST_CONCEPT_ASSERT | |
168 | ((boost::Mutable_BidirectionalIteratorConcept<iterator>)); | |
169 | BOOST_CONCEPT_ASSERT | |
170 | ((boost_concepts::WritableIteratorConcept<iterator>)); | |
171 | BOOST_CONCEPT_ASSERT | |
172 | ((boost_concepts::SwappableIteratorConcept<iterator>)); | |
173 | }; | |
174 | ||
175 | template <typename Geometry, bool IsConst> | |
176 | struct test_iterator_concepts<Geometry, false, IsConst> | |
177 | {}; | |
178 | ||
179 | ||
180 | ||
181 | struct equals | |
182 | { | |
183 | template <typename Iterator> | |
184 | static inline std::size_t number_of_elements(Iterator begin, | |
185 | Iterator end) | |
186 | { | |
187 | std::size_t size = std::distance(begin, end); | |
188 | ||
189 | std::size_t num_elems(0); | |
190 | for (Iterator it = begin; it != end; ++it) | |
191 | { | |
192 | ++num_elems; | |
193 | } | |
194 | BOOST_CHECK(size == num_elems); | |
195 | ||
196 | num_elems = 0; | |
197 | for (Iterator it = end; it != begin; --it) | |
198 | { | |
199 | ++num_elems; | |
200 | } | |
201 | BOOST_CHECK(size == num_elems); | |
202 | ||
203 | return num_elems; | |
204 | } | |
205 | ||
206 | template <typename Iterator1, typename Iterator2> | |
207 | static inline bool apply(Iterator1 begin1, Iterator1 end1, | |
208 | Iterator2 begin2, Iterator2 end2) | |
209 | { | |
210 | std::size_t num_points1 = number_of_elements(begin1, end1); | |
211 | std::size_t num_points2 = number_of_elements(begin2, end2); | |
212 | ||
213 | if (num_points1 != num_points2) | |
214 | { | |
215 | return false; | |
216 | } | |
217 | ||
218 | Iterator1 it1 = begin1; | |
219 | Iterator2 it2 = begin2; | |
220 | for (; it1 != end1; ++it1, ++it2) | |
221 | { | |
222 | if (! bg::equals(*it1, *it2)) | |
223 | { | |
224 | return false; | |
225 | } | |
226 | } | |
227 | return true; | |
228 | } | |
229 | }; | |
230 | ||
231 | ||
232 | template <bool Enable = true> | |
233 | struct test_assignment | |
234 | { | |
235 | template <typename Iterator, typename ConstIterator, typename Value> | |
236 | static inline void apply(Iterator it, ConstIterator cit, | |
237 | Value const& value1, Value const& value2) | |
238 | { | |
239 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
240 | std::cout << "== before assignment ==" << std::endl; | |
241 | std::cout << "value1: " << bg::wkt(value1) << std::endl; | |
242 | std::cout << "value2: " << bg::wkt(value2) << std::endl; | |
243 | std::cout << "*it : " << bg::wkt(*it) << std::endl; | |
244 | std::cout << "*cit : " << bg::wkt(*cit) << std::endl; | |
245 | #endif | |
246 | ||
247 | BOOST_CHECK(bg::equals(*it, value1)); | |
248 | BOOST_CHECK(! bg::equals(*it, value2)); | |
249 | BOOST_CHECK(bg::equals(*cit, value1)); | |
250 | BOOST_CHECK(! bg::equals(*cit, value2)); | |
251 | ||
252 | *it = value2; | |
253 | BOOST_CHECK(bg::equals(*it, value2)); | |
254 | BOOST_CHECK(! bg::equals(*it, value1)); | |
255 | BOOST_CHECK(bg::equals(*cit, value2)); | |
256 | BOOST_CHECK(! bg::equals(*cit, value1)); | |
257 | ||
258 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
259 | std::cout << "== after 1st assignment ==" << std::endl; | |
260 | std::cout << "value1: " << bg::wkt(value1) << std::endl; | |
261 | std::cout << "value2: " << bg::wkt(value2) << std::endl; | |
262 | std::cout << "*it : " << bg::wkt(*it) << std::endl; | |
263 | std::cout << "*cit : " << bg::wkt(*cit) << std::endl; | |
264 | #endif | |
265 | ||
266 | *it = value1; | |
267 | BOOST_CHECK(bg::equals(*it, value1)); | |
268 | BOOST_CHECK(! bg::equals(*it, value2)); | |
269 | BOOST_CHECK(bg::equals(*cit, value1)); | |
270 | BOOST_CHECK(! bg::equals(*cit, value2)); | |
271 | ||
272 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
273 | std::cout << "== after 2nd assignment ==" << std::endl; | |
274 | std::cout << "value1: " << bg::wkt(value1) << std::endl; | |
275 | std::cout << "value2: " << bg::wkt(value2) << std::endl; | |
276 | std::cout << "*it : " << bg::wkt(*it) << std::endl; | |
277 | std::cout << "*cit : " << bg::wkt(*cit) << std::endl; | |
278 | std::cout << std::endl; | |
279 | #endif | |
280 | } | |
281 | }; | |
282 | ||
283 | template <> | |
284 | struct test_assignment<false> | |
285 | { | |
286 | template <typename Iterator, typename ConstIterator, typename Value> | |
287 | static inline void apply(Iterator, ConstIterator, | |
288 | Value const&, Value const&) | |
289 | { | |
290 | } | |
291 | }; | |
292 | ||
293 | ||
294 | template | |
295 | < | |
296 | typename Geometry, | |
297 | typename PointRange, | |
298 | bool EnableConceptChecks = true | |
299 | > | |
300 | struct test_point_iterator_of_geometry | |
301 | { | |
302 | typedef typename bg::point_type<Geometry>::type point_type; | |
303 | ||
304 | template <typename G> | |
305 | static inline void base_test(G& geometry, | |
306 | PointRange const& point_range, | |
307 | std::string const& header) | |
308 | { | |
309 | typedef bg::point_iterator<G> point_iterator; | |
310 | ||
311 | test_iterator_concepts<G, EnableConceptChecks>(); | |
312 | ||
313 | point_iterator begin = bg::points_begin(geometry); | |
314 | point_iterator end = bg::points_end(geometry); | |
315 | ||
316 | BOOST_CHECK(std::size_t(std::distance(begin, end)) | |
317 | == | |
318 | bg::num_points(geometry)); | |
319 | ||
320 | BOOST_CHECK(equals::apply(begin, end, | |
321 | bg::points_begin(point_range), | |
322 | bg::points_end(point_range)) | |
323 | ); | |
324 | ||
325 | boost::ignore_unused(header); | |
326 | ||
327 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
328 | std::cout << header << " geometry: " << bg::wkt(geometry) << std::endl; | |
329 | print_point_range(std::cout, begin, end, "point range: "); | |
330 | std::cout << std::endl; | |
331 | ||
332 | typedef bg::point_iterator<PointRange const> point_range_iterator; | |
333 | ||
334 | print_point_range(std::cout, | |
335 | bg::points_begin(point_range), | |
336 | bg::points_end(point_range), | |
337 | "expected point range: "); | |
338 | std::cout << std::endl; | |
339 | #endif | |
340 | } | |
341 | ||
342 | template <typename G, bool Enable> | |
343 | struct test_reverse | |
344 | { | |
345 | template <typename Iterator> | |
346 | static inline void apply(Iterator first, Iterator last, | |
347 | G const& geometry) | |
348 | { | |
11fdf7f2 TL |
349 | boost::ignore_unused(geometry); |
350 | ||
7c673cae FG |
351 | std::reverse(first, last); |
352 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
353 | print_point_range(std::cout, first, last, "reversed:\n") | |
354 | << std::endl; | |
355 | std::cout << bg::wkt(geometry) << std::endl; | |
356 | std::cout << std::endl; | |
357 | #endif | |
358 | ||
359 | std::reverse(first, last); | |
360 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
361 | print_point_range(std::cout, first, last, "re-reversed:\n") | |
362 | << std::endl; | |
363 | std::cout << bg::wkt(geometry) << std::endl; | |
364 | std::cout << std::endl; | |
365 | std::cout << std::endl; | |
366 | #endif | |
367 | } | |
368 | }; | |
369 | ||
370 | template <typename G> | |
371 | struct test_reverse<G, false> | |
372 | { | |
373 | template <typename Iterator> | |
374 | static inline void apply(Iterator, Iterator, G const&) | |
375 | { | |
376 | } | |
377 | }; | |
378 | ||
379 | static inline void apply(Geometry geometry, | |
380 | PointRange const& point_range, | |
381 | point_type const& zero_point) | |
382 | { | |
383 | base_test<Geometry>(geometry, point_range, "non-const"); | |
384 | ||
385 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
386 | std::cout << std::endl; | |
387 | #endif | |
388 | ||
389 | base_test<Geometry const>(geometry, point_range, "const"); | |
390 | ||
391 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
392 | std::cout << std::endl << std::endl; | |
393 | #endif | |
394 | ||
395 | // testing construction of const and non-const iterator | |
396 | typedef bg::point_iterator<Geometry> point_iterator; | |
397 | typedef bg::point_iterator<Geometry const> const_point_iterator; | |
398 | ||
399 | point_iterator begin = bg::points_begin(geometry); | |
400 | point_iterator end = bg::points_end(geometry); | |
401 | ||
402 | const_point_iterator const_begin = bg::points_begin(geometry); | |
403 | const_point_iterator const_end = bg::points_end(geometry); | |
404 | ||
405 | // same for reverse iterator | |
406 | typedef bg::point_reverse_iterator<Geometry> point_reverse_iterator; | |
407 | typedef bg::point_reverse_iterator | |
408 | < | |
409 | Geometry const | |
410 | > const_point_reverse_iterator; | |
411 | ||
412 | point_reverse_iterator rbegin = bg::points_rbegin(geometry); | |
413 | point_reverse_iterator rend = bg::points_rend(geometry); | |
414 | ||
415 | const_point_reverse_iterator const_rbegin = bg::points_rbegin(geometry); | |
416 | const_point_reverse_iterator const_rend = bg::points_rend(geometry); | |
417 | ||
418 | // testing assignment of non-const to const iterator | |
419 | const_begin = begin; | |
420 | const_end = end; | |
421 | ||
422 | // testing assignment of non-const to const reverse_iterator | |
423 | const_rbegin = rbegin; | |
424 | const_rend = rend; | |
425 | ||
426 | // testing equality/inequality comparison | |
427 | BOOST_CHECK(begin == const_begin); | |
428 | BOOST_CHECK(end == const_end); | |
429 | if (begin != end) | |
430 | { | |
431 | BOOST_CHECK(begin != const_end); | |
432 | BOOST_CHECK(const_begin != end); | |
433 | } | |
434 | ||
435 | // testing equality/inequality comparison for reverse_iterator | |
436 | BOOST_CHECK(rbegin == const_rbegin); | |
437 | BOOST_CHECK(rend == const_rend); | |
438 | if (rbegin != rend) | |
439 | { | |
440 | BOOST_CHECK(rbegin != const_rend); | |
441 | BOOST_CHECK(const_rbegin != rend); | |
442 | } | |
443 | ||
444 | if (begin != end) | |
445 | { | |
446 | BOOST_CHECK(rbegin != rend); | |
447 | ||
448 | point_reverse_iterator rlast(rend); | |
449 | --rlast; | |
450 | BOOST_CHECK(bg::equals(*begin, *rlast)); | |
451 | ||
452 | point_iterator last(end); | |
453 | --last; | |
454 | BOOST_CHECK(bg::equals(*rbegin, *last)); | |
455 | } | |
456 | ||
457 | // testing dereferencing/assignment | |
458 | ||
459 | bool const is_reference = boost::is_reference | |
460 | < | |
461 | typename std::iterator_traits<point_iterator>::reference | |
462 | >::value; | |
463 | ||
464 | if (begin != end) | |
465 | { | |
466 | if (BOOST_GEOMETRY_CONDITION(is_reference)) | |
467 | { | |
468 | point_type p = *begin; | |
469 | point_type q = zero_point; | |
470 | ||
471 | test_assignment<is_reference>::apply(begin, const_begin, p, q); | |
472 | ||
473 | *begin = q; | |
474 | test_assignment<is_reference>::apply(begin, const_begin, q, p); | |
475 | ||
476 | *begin = p; | |
477 | } | |
478 | } | |
479 | ||
480 | // test with algorithms | |
481 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
482 | print_point_range(std::cout, begin, end, "original:\n") << std::endl; | |
483 | print_point_range(std::cout, rbegin, rend, "reverse traversal:\n") | |
484 | << std::endl; | |
485 | std::cout << bg::wkt(geometry) << std::endl; | |
486 | std::cout << std::endl; | |
487 | #endif | |
488 | test_reverse<Geometry, is_reference>::apply(begin, end, geometry); | |
489 | ||
490 | typedef typename std::iterator_traits | |
491 | < | |
492 | point_iterator | |
493 | >::value_type point; | |
494 | if (const_begin != const_end) | |
495 | { | |
496 | boost::optional<point> | |
497 | pt_max = max_value(const_begin, const_end, bg::less<point>()); | |
498 | ||
499 | BOOST_CHECK(bool(pt_max)); // to avoid warnings | |
500 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
501 | std::cout << "max point: " << bg::dsv(*pt_max) << std::endl; | |
502 | #endif | |
503 | } | |
504 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
505 | std::cout << std::endl; | |
506 | std::cout << std::endl; | |
507 | std::cout << std::endl; | |
508 | #endif | |
509 | } | |
510 | ||
511 | static inline void apply(Geometry geometry, PointRange const& point_range) | |
512 | { | |
513 | apply(geometry, point_range, bg::make_zero<point_type>()); | |
514 | } | |
515 | }; | |
516 | ||
517 | ||
518 | //====================================================================== | |
519 | //====================================================================== | |
520 | ||
521 | ||
522 | BOOST_AUTO_TEST_CASE( test_linestring_point_iterator ) | |
523 | { | |
524 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
525 | std::cout << "*** LINESTRING ***" << std::endl; | |
526 | #endif | |
527 | ||
528 | typedef tuple_multi_point_type TMP; | |
529 | typedef linestring_type L; | |
530 | ||
531 | typedef test_point_iterator_of_geometry<L, TMP> tester; | |
532 | ||
533 | tester::apply(from_wkt<L>("LINESTRING()"), | |
534 | TMP() | |
535 | ); | |
536 | ||
537 | tester::apply(from_wkt<L>("LINESTRING(3 3,4 4,5 5)"), | |
538 | ba::tuple_list_of(3,3)(4,4)(5,5) | |
539 | ); | |
540 | ||
541 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
542 | std::cout << std::endl << std::endl << std::endl; | |
543 | #endif | |
544 | } | |
545 | ||
546 | ||
547 | //====================================================================== | |
548 | //====================================================================== | |
549 | ||
550 | ||
551 | BOOST_AUTO_TEST_CASE( test_polygon_point_iterator ) | |
552 | { | |
553 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
554 | std::cout << "*** POLYGON ***" << std::endl; | |
555 | #endif | |
556 | ||
557 | typedef tuple_multi_point_type TMP; | |
558 | typedef polygon_type P; | |
559 | ||
560 | typedef test_point_iterator_of_geometry<P, TMP> tester; | |
561 | ||
562 | tester::apply(from_wkt<P>("POLYGON()"), | |
563 | TMP() | |
564 | ); | |
565 | ||
566 | tester::apply(from_wkt<P>("POLYGON(())"), | |
567 | TMP() | |
568 | ); | |
569 | ||
570 | tester::apply(from_wkt<P>("POLYGON((1 1,9 1,9 9,1 9),(5 5,6 5,6 6,5 6))"), | |
571 | ba::tuple_list_of(1,1)(9,1)(9,9)(1,9)(5,5)(6,5)(6,6)(5,6) | |
572 | ); | |
573 | ||
574 | tester::apply(from_wkt<P>("POLYGON((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),())"), | |
575 | ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9) | |
576 | ); | |
577 | ||
578 | tester::apply(from_wkt<P>("POLYGON((),(3 3,4 4,5 5),(),(),(6 6,7 7,8 8),(),(),(9 9),())"), | |
579 | ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9) | |
580 | ); | |
581 | ||
582 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
583 | std::cout << std::endl << std::endl; | |
584 | #endif | |
585 | } | |
586 | ||
587 | ||
588 | //====================================================================== | |
589 | //====================================================================== | |
590 | ||
591 | ||
592 | BOOST_AUTO_TEST_CASE( test_multipoint_point_iterator ) | |
593 | { | |
594 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
595 | std::cout << "*** MULTIPOINT ***" << std::endl; | |
596 | #endif | |
597 | ||
598 | typedef tuple_multi_point_type TMP; | |
599 | typedef multi_point_type MP; | |
600 | ||
601 | typedef test_point_iterator_of_geometry<MP, TMP> tester; | |
602 | ||
603 | tester::apply(from_wkt<MP>("MULTIPOINT()"), | |
604 | TMP() | |
605 | ); | |
606 | ||
607 | tester::apply(from_wkt<MP>("MULTIPOINT(3 3,4 4,5 5)"), | |
608 | ba::tuple_list_of(3,3)(4,4)(5,5) | |
609 | ); | |
610 | ||
611 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
612 | std::cout << std::endl << std::endl << std::endl; | |
613 | #endif | |
614 | } | |
615 | ||
616 | ||
617 | //====================================================================== | |
618 | //====================================================================== | |
619 | ||
620 | ||
621 | BOOST_AUTO_TEST_CASE( test_multipoint_3d_point_iterator ) | |
622 | { | |
623 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
624 | std::cout << "*** MULTIPOINT 3D ***" << std::endl; | |
625 | #endif | |
626 | ||
627 | typedef tuple_multi_point_type_3d TMP; | |
628 | typedef multi_point_type_3d MP; | |
629 | ||
630 | typedef test_point_iterator_of_geometry<MP, TMP> tester; | |
631 | ||
632 | tester::apply(from_wkt<MP>("MULTIPOINT()"), | |
633 | TMP() | |
634 | ); | |
635 | ||
636 | tester::apply(from_wkt<MP>("MULTIPOINT(3 3 3,4 4 4,5 5 5)"), | |
637 | ba::tuple_list_of(3,3,3)(4,4,4)(5,5,5) | |
638 | ); | |
639 | ||
640 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
641 | std::cout << std::endl << std::endl << std::endl; | |
642 | #endif | |
643 | } | |
644 | ||
645 | ||
646 | //====================================================================== | |
647 | //====================================================================== | |
648 | ||
649 | ||
650 | BOOST_AUTO_TEST_CASE( test_multilinestring_point_iterator ) | |
651 | { | |
652 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
653 | std::cout << "*** MULTILINESTRING ***" << std::endl; | |
654 | #endif | |
655 | ||
656 | typedef tuple_multi_point_type TMP; | |
657 | typedef multi_linestring_type ML; | |
658 | ||
659 | typedef test_point_iterator_of_geometry<ML, TMP> tester; | |
660 | ||
661 | tester::apply(from_wkt<ML>("MULTILINESTRING()"), | |
662 | TMP() | |
663 | ); | |
664 | ||
665 | tester::apply(from_wkt<ML>("MULTILINESTRING(())"), | |
666 | TMP() | |
667 | ); | |
668 | ||
669 | tester::apply(from_wkt<ML>("MULTILINESTRING((),(),())"), | |
670 | TMP() | |
671 | ); | |
672 | ||
673 | tester::apply(from_wkt<ML>("MULTILINESTRING((1 1,2 2,3 3),(3 3,4 4,5 5),(6 6))"), | |
674 | ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6) | |
675 | ); | |
676 | ||
677 | tester::apply(from_wkt<ML>("MULTILINESTRING((),(),(1 1,2 2,3 3),(),(),(3 3,4 4,5 5),(),(6 6),(),(),())"), | |
678 | ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6) | |
679 | ); | |
680 | ||
681 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
682 | std::cout << std::endl << std::endl; | |
683 | #endif | |
684 | } | |
685 | ||
686 | ||
687 | //====================================================================== | |
688 | //====================================================================== | |
689 | ||
690 | ||
691 | BOOST_AUTO_TEST_CASE( test_multipolygon_point_iterator ) | |
692 | { | |
693 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
694 | std::cout << "*** MULTIPOLYGON ***" << std::endl; | |
695 | #endif | |
696 | ||
697 | typedef tuple_multi_point_type TMP; | |
698 | typedef multi_polygon_type MPL; | |
699 | ||
700 | typedef test_point_iterator_of_geometry<MPL, TMP> tester; | |
701 | ||
702 | tester::apply(from_wkt<MPL>("MULTIPOLYGON()"), | |
703 | TMP() | |
704 | ); | |
705 | ||
706 | tester::apply(from_wkt<MPL>("MULTIPOLYGON( () )"), | |
707 | TMP() | |
708 | ); | |
709 | ||
710 | tester::apply(from_wkt<MPL>("MULTIPOLYGON( (()) )"), | |
711 | TMP() | |
712 | ); | |
713 | ||
714 | tester::apply(from_wkt<MPL>("MULTIPOLYGON( ((),()) )"), | |
715 | TMP() | |
716 | ); | |
717 | ||
718 | tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(6 6,7 7,8 8),(9 9)),((1 1,2 2,10 10),(11 11,12 12)))"), | |
719 | ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ | |
720 | (1,1)(2,2)(10,10)(11,11)(12,12) | |
721 | ); | |
722 | ||
723 | tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()))"), | |
724 | ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ | |
725 | (1,1)(2,2)(10,10)(11,11)(12,12)(13,13) | |
726 | ); | |
727 | ||
728 | tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()),((),(),()))"), | |
729 | ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ | |
730 | (1,1)(2,2)(10,10)(11,11)(12,12)(13,13) | |
731 | ); | |
732 | ||
733 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
734 | std::cout << std::endl << std::endl; | |
735 | #endif | |
736 | } | |
737 | ||
738 | ||
739 | //====================================================================== | |
740 | //====================================================================== | |
741 | ||
742 | ||
743 | BOOST_AUTO_TEST_CASE( test_multipoint_of_point_pointers ) | |
744 | { | |
745 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
746 | std::cout << "*** MULTIPOINT OF POINT POINTERS ***" << std::endl; | |
747 | #endif | |
748 | ||
749 | typedef tuple_multi_point_type TMP; | |
750 | typedef vector_as_multipoint<test::test_point_xy*> MP; | |
751 | ||
752 | MP multipoint; | |
753 | for (int i = 1; i < 10; i++) | |
754 | { | |
755 | test::test_point_xy* p = new test::test_point_xy; | |
756 | p->x = i; | |
757 | p->y = -i; | |
758 | multipoint.push_back(p); | |
759 | } | |
760 | ||
761 | test::test_point_xy* zero = new test::test_point_xy; | |
762 | zero->x = 0; | |
763 | zero->y = 0; | |
764 | ||
765 | typedef test_point_iterator_of_geometry<MP, TMP> tester; | |
766 | ||
767 | tester::apply(multipoint, | |
768 | ba::tuple_list_of(1,-1)(2,-2)(3,-3)(4,-4)(5,-5)(6,-6)\ | |
769 | (7,-7)(8,-8)(9,-9), | |
770 | zero | |
771 | ); | |
772 | ||
773 | for (unsigned int i = 0; i < multipoint.size(); i++) | |
774 | { | |
775 | delete multipoint[i]; | |
776 | } | |
777 | delete zero; | |
778 | } | |
779 | ||
780 | ||
781 | //====================================================================== | |
782 | //====================================================================== | |
783 | ||
784 | ||
785 | BOOST_AUTO_TEST_CASE( test_linestring_of_point_pointers ) | |
786 | { | |
787 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
788 | std::cout << "*** LINESTRING OF POINT POINTERS ***" << std::endl; | |
789 | #endif | |
790 | ||
791 | typedef tuple_multi_point_type TMP; | |
792 | typedef vector_as_linestring<test::test_point_xy*> L; | |
793 | ||
794 | L linestring; | |
795 | for (int i = 1; i < 10; i++) | |
796 | { | |
797 | test::test_point_xy* p = new test::test_point_xy; | |
798 | p->x = i; | |
799 | p->y = -i; | |
800 | linestring.push_back(p); | |
801 | } | |
802 | ||
803 | test::test_point_xy* zero = new test::test_point_xy; | |
804 | zero->x = 0; | |
805 | zero->y = 0; | |
806 | ||
807 | typedef test_point_iterator_of_geometry<L, TMP> tester; | |
808 | ||
809 | tester::apply(linestring, | |
810 | ba::tuple_list_of(1,-1)(2,-2)(3,-3)(4,-4)(5,-5)(6,-6)\ | |
811 | (7,-7)(8,-8)(9,-9), | |
812 | zero | |
813 | ); | |
814 | ||
815 | for (unsigned int i = 0; i < linestring.size(); i++) | |
816 | { | |
817 | delete linestring[i]; | |
818 | } | |
819 | delete zero; | |
820 | } | |
821 | ||
822 | ||
823 | //====================================================================== | |
824 | //====================================================================== | |
825 | ||
826 | ||
827 | BOOST_AUTO_TEST_CASE( test_multipoint_copy_on_dereference ) | |
828 | { | |
829 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
830 | std::cout << "*** MULTIPOINT WITH COPY-ON-DEREFERENCE ITERATOR ***" | |
831 | << std::endl; | |
832 | #endif | |
833 | ||
834 | typedef tuple_multi_point_type TMP; | |
835 | typedef multipoint_copy_on_dereference<point_type> MP; | |
836 | ||
837 | typedef test_point_iterator_of_geometry | |
838 | < | |
839 | MP, TMP, false // no concept checks | |
840 | > tester; | |
841 | ||
842 | // bg::read_wkt does not work for this multipoint type so we have | |
843 | // to initialize the multipoint manually | |
844 | MP multipoint; | |
845 | for (int i = 1; i < 10; ++i) | |
846 | { | |
847 | multipoint.push_back(point_type(i, -i)); | |
848 | } | |
849 | ||
850 | tester::apply(multipoint, | |
851 | // from_wkt<MP>("MULTIPOINT(1 -1,2 -2,3 -3,4 -4,5 -5,6 -6, 7 -7,8 -8,9 -9)"), | |
852 | ba::tuple_list_of(1,-1)(2,-2)(3,-3)(4,-4)(5,-5)(6,-6)\ | |
853 | (7,-7)(8,-8)(9,-9) | |
854 | ); | |
855 | } | |
856 | ||
857 | ||
858 | //====================================================================== | |
859 | //====================================================================== | |
860 | ||
861 | ||
862 | BOOST_AUTO_TEST_CASE( test_linestring_copy_on_dereference ) | |
863 | { | |
864 | #ifdef BOOST_GEOMETRY_TEST_DEBUG | |
865 | std::cout << "*** LINESTRING WITH COPY-ON-DEREFERENCE ITERATOR ***" | |
866 | << std::endl; | |
867 | #endif | |
868 | ||
869 | typedef tuple_multi_point_type TMP; | |
870 | typedef linestring_copy_on_dereference<point_type> L; | |
871 | ||
872 | typedef test_point_iterator_of_geometry | |
873 | < | |
874 | L, TMP, false // no concept checks | |
875 | > tester; | |
876 | ||
877 | tester::apply(from_wkt<L>("LINESTRING(1 -1,2 -2,3 -3,4 -4,5 -5,6 -6, 7 -7,8 -8,9 -9)"), | |
878 | ba::tuple_list_of(1,-1)(2,-2)(3,-3)(4,-4)(5,-5)(6,-6)\ | |
879 | (7,-7)(8,-8)(9,-9) | |
880 | ); | |
881 | } |