segment_iterator.cpp 26 KB

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