point_iterator.cpp 26 KB

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