is_simple.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2014-2017, Oracle and/or its affiliates.
  4. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  5. // Contributed and/or modified by Adam Wulkiewicz, 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_is_simple
  10. #endif
  11. #include "test_is_simple.hpp"
  12. namespace bg = ::boost::geometry;
  13. typedef bg::model::point<double, 2, bg::cs::cartesian> point_type;
  14. typedef bg::model::segment<point_type> segment_type;
  15. typedef bg::model::linestring<point_type> linestring_type;
  16. typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
  17. // ccw open and closed polygons
  18. typedef bg::model::polygon<point_type,false,false> open_ccw_polygon_type;
  19. typedef bg::model::polygon<point_type,false,true> closed_ccw_polygon_type;
  20. // multi-geometries
  21. typedef bg::model::multi_point<point_type> multi_point_type;
  22. typedef bg::model::multi_polygon<open_ccw_polygon_type> multi_polygon_type;
  23. // box
  24. typedef bg::model::box<point_type> box_type;
  25. BOOST_AUTO_TEST_CASE( test_is_simple_point )
  26. {
  27. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  28. std::cout << std::endl << std::endl;
  29. std::cout << "************************************" << std::endl;
  30. std::cout << " is_simple: POINT " << std::endl;
  31. std::cout << "************************************" << std::endl;
  32. #endif
  33. typedef point_type G;
  34. test_simple(from_wkt<G>("POINT(0 0)"), true);
  35. }
  36. BOOST_AUTO_TEST_CASE( test_is_simple_multipoint )
  37. {
  38. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  39. std::cout << std::endl << std::endl;
  40. std::cout << "************************************" << std::endl;
  41. std::cout << " is_simple: MULTIPOINT " << std::endl;
  42. std::cout << "************************************" << std::endl;
  43. #endif
  44. typedef multi_point_type G;
  45. test_simple(from_wkt<G>("MULTIPOINT(0 0)"), true);
  46. test_simple(from_wkt<G>("MULTIPOINT(0 0,1 0,1 1,0 1)"), true);
  47. test_simple(from_wkt<G>("MULTIPOINT(0 0,1 0,1 1,1 0,0 1)"), false);
  48. // empty multipoint
  49. test_simple(from_wkt<G>("MULTIPOINT()"), true);
  50. }
  51. BOOST_AUTO_TEST_CASE( test_is_simple_segment )
  52. {
  53. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  54. std::cout << std::endl << std::endl;
  55. std::cout << "************************************" << std::endl;
  56. std::cout << " is_simple: SEGMENT " << std::endl;
  57. std::cout << "************************************" << std::endl;
  58. #endif
  59. typedef segment_type G;
  60. test_simple(from_wkt<G>("SEGMENT(0 0,1 0)"), true);
  61. }
  62. BOOST_AUTO_TEST_CASE( test_is_simple_linestring )
  63. {
  64. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  65. std::cout << std::endl << std::endl;
  66. std::cout << "************************************" << std::endl;
  67. std::cout << " is_simple: LINESTRING " << std::endl;
  68. std::cout << "************************************" << std::endl;
  69. #endif
  70. typedef linestring_type G;
  71. // valid linestrings with multiple points
  72. test_simple(from_wkt<G>("LINESTRING(0 0,0 0,1 0)"), false);
  73. test_simple(from_wkt<G>("LINESTRING(0 0,0 0,1 0,0 0)"), false);
  74. test_simple(from_wkt<G>("LINESTRING(0 0,0 0,1 0,1 0,1 1,0 0)"), false);
  75. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 0,1 1,1 0,1 -1)"), false);
  76. // simple open linestrings
  77. test_simple(from_wkt<G>("LINESTRING(0 0,1 2)"), true);
  78. test_simple(from_wkt<G>("LINESTRING(0 0,1 2,2 3)"), true);
  79. // simple closed linestrings
  80. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,1 1,0 0)"), true);
  81. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,1 1,0 1,0 0)"), true);
  82. test_simple(from_wkt<G>("LINESTRING(0 0,10 0,10 10,0 10,0 0)"), true);
  83. // non-simple linestrings
  84. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,0 0)"), false);
  85. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 10,0.5 -1)"), false);
  86. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 1,1 0)"), false);
  87. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 1,0.5 0)"), false);
  88. test_simple(from_wkt<G>("LINESTRING(0 0,2 0,1 0)"), false);
  89. test_simple(from_wkt<G>("LINESTRING(0 0,3 0,5 0,1 0)"), false);
  90. test_simple(from_wkt<G>("LINESTRING(0 0,3 0,5 0,4 0)"), false);
  91. test_simple(from_wkt<G>("LINESTRING(0 0,3 0,5 0,4 0,2 0)"), false);
  92. test_simple(from_wkt<G>("LINESTRING(0 0,3 0,2 0,5 0)"), false);
  93. test_simple(from_wkt<G>("LINESTRING(0 0,2 0,2 2,1 0,0 0)"), false);
  94. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 0,2 2,1 0,0 0)"), false);
  95. test_simple(from_wkt<G>("LINESTRING(0 0,10 0,10 10,0 10,0 0,0 0)"), false);
  96. test_simple(from_wkt<G>("LINESTRING(0 0,0 10,5 10,0 0,10 10,10 5,10 0,0 0)"), false);
  97. test_simple(from_wkt<G>("LINESTRING(0 0,0 0,10 0,10 10,0 10,0 0,0 0)"),
  98. false);
  99. test_simple(from_wkt<G>("LINESTRING(0 0,0 0,0 0,10 0,10 10,0 10,0 0,0 0,0 0,0 0)"),
  100. false);
  101. test_simple(from_wkt<G>("LINESTRING(0 0,0 0,10 0,10 10,10 10,10 10,10 10,10 10,0 10,0 0,0 0)"),
  102. false);
  103. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 0,2 2,1 0)"), false);
  104. test_simple(from_wkt<G>("LINESTRING(1 0,2 2,2 0,1 0,0 0)"), false);
  105. test_simple(from_wkt<G>("LINESTRING(0 0,1 0,2 0,2 2,1 0,1 4,0 0)"), false);
  106. test_simple(from_wkt<G>("LINESTRING(4 1,10 8,4 6,4 1,10 5,10 3)"),
  107. false);
  108. test_simple(from_wkt<G>("LINESTRING(10 3,10 5,4 1,4 6,10 8,4 1)"),
  109. false);
  110. // empty linestring
  111. // the simplicity result is irrelevant since an empty linestring
  112. // is considered as invalid
  113. test_simple(from_wkt<G>("LINESTRING()"), false, false);
  114. }
  115. BOOST_AUTO_TEST_CASE( test_is_simple_multilinestring )
  116. {
  117. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  118. std::cout << std::endl << std::endl;
  119. std::cout << "************************************" << std::endl;
  120. std::cout << " is_simple: MULTILINESTRING " << std::endl;
  121. std::cout << "************************************" << std::endl;
  122. #endif
  123. typedef multi_linestring_type G;
  124. // multilinestrings with linestrings with spikes
  125. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,0 0),(5 0,6 0,7 0))"),
  126. false);
  127. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,0 0),(5 0,1 0,4 1))"),
  128. false);
  129. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,0 0),(5 0,1 0,4 0))"),
  130. false);
  131. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,0 0),(1 0,2 0))"),
  132. false);
  133. // simple multilinestrings
  134. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 1),(1 1,1 0))"), true);
  135. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 1),(1 1,1 0),(0 1,1 1))"),
  136. true);
  137. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2),(0 0,1 0,2 0,2 2))"), true);
  138. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2),(2 2,2 0,1 0,0 0))"), true);
  139. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0),(0 0,-1 0),(1 0,2 0))"),
  140. true);
  141. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0),(-1 0,0 0),(2 0,1 0))"),
  142. true);
  143. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0),(0 0,0 1),(0 0,-1 0),(0 0,0 -1))"),
  144. true);
  145. test_simple(from_wkt<G>("MULTILINESTRING((0 0,10 0,10 10,0 10,0 0))"), true);
  146. // non-simple multilinestrings
  147. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2),(0 0,2 2))"), false);
  148. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2),(2 2,0 0))"), false);
  149. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2),(0 0,1 0,1 1,2 0,2 2))"),
  150. false);
  151. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 1,2 2),(0 0,1 0,1 1,2 0,2 2))"),
  152. false);
  153. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 1,2 2),(2 2,0 0))"),
  154. false);
  155. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2,4 4),(0 0,1 1))"),
  156. false);
  157. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2,4 4),(0 0,3 3))"),
  158. false);
  159. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2,4 4),(1 1,3 3))"),
  160. false);
  161. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2,4 4),(1 1,2 2))"),
  162. false);
  163. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2,4 4),(2 2,3 3))"),
  164. false);
  165. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2,4 4),(2 2,4 4))"),
  166. false);
  167. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 2,4 4),(4 4,2 2))"),
  168. false);
  169. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 1),(0 1,1 0))"),
  170. false);
  171. test_simple(from_wkt<G>("MULTILINESTRING((0 0,2 0),(1 0,0 1))"),
  172. false);
  173. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 1),(1 1,1 0),(1 1,0 1,0.5,0.5))"),
  174. false);
  175. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(1 0,1 -1))"),
  176. false);
  177. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(-1 0,0 0))"),
  178. false);
  179. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(0 0,-1 0,-1 -1,0 -1,0 0))"),
  180. false);
  181. test_simple(from_wkt<G>("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(-1 -1,-1 0,0 0,0 -1,-1 -1))"),
  182. false);
  183. test_simple(from_wkt<G>("MULTILINESTRING((0 0,0 10,5 10,0 0,10 10,10 5,10 0,0 0))"),
  184. false);
  185. test_simple(from_wkt<G>("MULTILINESTRING((4 1,10 8,4 6,4 1,10 5,10 3))"),
  186. false);
  187. test_simple(from_wkt<G>("MULTILINESTRING((10 3,10 5,4 1,4 6,10 8,4 1))"),
  188. false);
  189. // empty multilinestring
  190. test_simple(from_wkt<G>("MULTILINESTRING()"), true);
  191. }
  192. BOOST_AUTO_TEST_CASE( test_is_simple_areal )
  193. {
  194. typedef box_type b;
  195. typedef open_ccw_polygon_type o_ccw_p;
  196. typedef multi_polygon_type mpl;
  197. // check that is_simple compiles for boxes
  198. test_simple(from_wkt<b>("BOX(0 0,1 1)"), true);
  199. // simple polygons and multi-polygons
  200. test_simple(from_wkt<o_ccw_p>("POLYGON((0 0,1 0,1 1))"), true);
  201. test_simple(from_wkt<o_ccw_p>("POLYGON((0 0,10 0,10 10,0 10),(1 1,1 9,9 9,9 1))"),
  202. true);
  203. test_simple(from_wkt<mpl>("MULTIPOLYGON(((0 0,1 0,1 1)),((10 0,20 0,20 10,10 10)))"),
  204. true);
  205. // non-simple polygons & multi-polygons (have duplicate points)
  206. test_simple(from_wkt<o_ccw_p>("POLYGON((0 0,1 0,1 0,1 1))"), false);
  207. test_simple(from_wkt<o_ccw_p>("POLYGON((0 0,10 0,10 10,0 10),(1 1,1 9,9 9,9 9,9 1))"),
  208. false);
  209. test_simple(from_wkt<mpl>("MULTIPOLYGON(((0 0,1 0,1 1,1 1)),((10 0,20 0,20 0,20 10,10 10)))"),
  210. false);
  211. // empty polygon
  212. // the simplicity result is irrelevant since an empty polygon
  213. // is considered as invalid
  214. test_simple(from_wkt<o_ccw_p>("POLYGON(())"), false, false);
  215. // empty multipolygon
  216. test_simple(from_wkt<mpl>("MULTIPOLYGON()"), true);
  217. }
  218. BOOST_AUTO_TEST_CASE( test_geometry_with_NaN_coordinates )
  219. {
  220. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  221. std::cout << std::endl << std::endl;
  222. std::cout << "************************************" << std::endl;
  223. std::cout << " is_valid: geometry with NaN coordinates" << std::endl;
  224. std::cout << "************************************" << std::endl;
  225. #endif
  226. linestring_type ls1, ls2;
  227. bg::read_wkt("LINESTRING(1 1,1.115235e+308 1.738137e+308)", ls1);
  228. bg::read_wkt("LINESTRING(-1 1,1.115235e+308 1.738137e+308)", ls2);
  229. // the intersection of the two linestrings is a new linestring
  230. // (multilinestring with a single element) that has NaN coordinates
  231. multi_linestring_type mls;
  232. bg::intersection(ls1, ls2, mls);
  233. test_simple(mls, true, false);
  234. }
  235. BOOST_AUTO_TEST_CASE( test_is_simple_variant )
  236. {
  237. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  238. std::cout << std::endl << std::endl;
  239. std::cout << "************************************" << std::endl;
  240. std::cout << " is_simple: variant support" << std::endl;
  241. std::cout << "************************************" << std::endl;
  242. #endif
  243. typedef bg::model::polygon<point_type> polygon_type; // cw, closed
  244. typedef boost::variant
  245. <
  246. linestring_type, multi_linestring_type, polygon_type
  247. > variant_geometry;
  248. variant_geometry vg;
  249. linestring_type simple_linestring =
  250. from_wkt<linestring_type>("LINESTRING(0 0,1 0)");
  251. multi_linestring_type non_simple_multi_linestring = from_wkt
  252. <
  253. multi_linestring_type
  254. >("MULTILINESTRING((0 0,1 0,1 1,0 0),(10 0,1 1))");
  255. polygon_type simple_polygon =
  256. from_wkt<polygon_type>("POLYGON((0 0,1 1,1 0,0 0))");
  257. polygon_type non_simple_polygon =
  258. from_wkt<polygon_type>("POLYGON((0 0,1 1,1 0,1 0,0 0))");
  259. vg = simple_linestring;
  260. test_simple(vg, true);
  261. vg = non_simple_multi_linestring;
  262. test_simple(vg, false);
  263. vg = simple_polygon;
  264. test_simple(vg, true);
  265. vg = non_simple_polygon;
  266. test_simple(vg, false);
  267. }