within_pointlike_geometry.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
  4. // This file was modified by Oracle on 2014, 2015, 2016, 2017.
  5. // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
  6. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #include "test_within.hpp"
  11. #include <boost/geometry/geometries/geometries.hpp>
  12. #include <boost/geometry/geometries/point_xy.hpp>
  13. #include <boost/geometry/geometries/multi_point.hpp>
  14. #include <boost/geometry/geometries/multi_linestring.hpp>
  15. #include <boost/geometry/geometries/multi_polygon.hpp>
  16. template <typename P>
  17. void test_p_p()
  18. {
  19. typedef bg::model::multi_point<P> mpt;
  20. test_geometry<P, P>("POINT(0 0)", "POINT(0 0)", true);
  21. test_geometry<P, P>("POINT(0 0)", "POINT(1 1)", false);
  22. test_geometry<P, mpt>("POINT(0 0)", "MULTIPOINT(0 0, 1 1)", true);
  23. test_geometry<P, mpt>("POINT(0 0)", "MULTIPOINT(1 1, 2 2)", false);
  24. test_geometry<mpt, P>("MULTIPOINT(0 0)", "POINT(0 0)", true);
  25. test_geometry<mpt, P>("MULTIPOINT(0 0, 1 1)", "POINT(0 0)", false);
  26. test_geometry<mpt, P>("MULTIPOINT(0 0, 1 1)", "POINT(2 2)", false);
  27. test_geometry<mpt, mpt>("MULTIPOINT(0 0)", "MULTIPOINT(0 0, 1 1)", true);
  28. test_geometry<mpt, mpt>("MULTIPOINT(0 0, 1 1)", "MULTIPOINT(0 0, 1 1)", true);
  29. test_geometry<mpt, mpt>("MULTIPOINT(0 0, 1 1)", "MULTIPOINT(0 0)", false);
  30. test_geometry<mpt, mpt>("MULTIPOINT(0 0, 1 1)", "MULTIPOINT(1 1, 2 2)", false);
  31. test_geometry<mpt, mpt>("MULTIPOINT(0 0, 1 1)", "MULTIPOINT(2 2, 3 4)", false);
  32. }
  33. template <typename P>
  34. void test_p_l()
  35. {
  36. typedef bg::model::multi_point<P> mpt;
  37. typedef bg::model::segment<P> seg;
  38. typedef bg::model::linestring<P> ls;
  39. typedef bg::model::multi_linestring<ls> mls;
  40. test_geometry<P, seg>("POINT(1 1)", "LINESTRING(0 0, 2 2)", true);
  41. test_geometry<P, seg>("POINT(0 0)", "LINESTRING(0 0, 1 1)", false);
  42. test_geometry<P, seg>("POINT(1 0)", "LINESTRING(0 0, 1 1)", false);
  43. test_geometry<P, ls>("POINT(0 0)", "LINESTRING(0 0,1 1,2 2)", false);
  44. test_geometry<P, ls>("POINT(3 3)", "LINESTRING(0 0,1 1,2 2)", false);
  45. test_geometry<P, ls>("POINT(1 1)", "LINESTRING(0 0,2 2,3 3)", true);
  46. test_geometry<P, ls>("POINT(1 1)", "LINESTRING(0 0, 2 2)", true);
  47. test_geometry<P, ls>("POINT(0 0)", "LINESTRING(0 0, 1 1)", false);
  48. test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1))", true);
  49. test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1),(0 0,1 0))", false);
  50. test_geometry<P, mls>("POINT(1 1)", "MULTILINESTRING((0 0, 1 1),(1 1, 2 2))", true);
  51. test_geometry<P, mls>("POINT(1 1)", "MULTILINESTRING((0 0, 1 1),(2 2, 3 3))", false);
  52. test_geometry<mpt, seg>("MULTIPOINT(0 0, 1 1)", "LINESTRING(0 0, 2 2)", true);
  53. test_geometry<mpt, ls>("MULTIPOINT(0 0, 2 2)", "LINESTRING(0 0, 2 2)", false);
  54. test_geometry<mpt, ls>("MULTIPOINT(1 1, 3 3)", "LINESTRING(0 0, 2 2)", false);
  55. test_geometry<mpt, mls>("MULTIPOINT(0 0, 1 1)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", true);
  56. test_geometry<mpt, mls>("MULTIPOINT(0 0, 2 2)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", true);
  57. test_geometry<mpt, mls>("MULTIPOINT(0 0, 3 3)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", false);
  58. test_geometry<mpt, mls>("MULTIPOINT(1 1, 4 4)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", false);
  59. }
  60. template <typename P>
  61. void test_p_a()
  62. {
  63. typedef bg::model::multi_point<P> mpt;
  64. typedef bg::model::ring<P> ring;
  65. typedef bg::model::polygon<P> poly;
  66. typedef bg::model::multi_polygon<poly> mpoly;
  67. // trivial case
  68. test_ring<P>("POINT(1 1)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", true, false);
  69. // on border/corner
  70. test_ring<P>("POINT(0 0)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", false, true);
  71. test_ring<P>("POINT(0 1)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", false, true);
  72. // aligned to segment/vertex
  73. test_ring<P>("POINT(1 1)", "POLYGON((0 0,0 3,3 3,3 1,2 1,2 0,0 0))", true, false);
  74. test_ring<P>("POINT(1 1)", "POLYGON((0 0,0 3,4 3,3 1,2 2,2 0,0 0))", true, false);
  75. // same polygon, but point on border
  76. test_ring<P>("POINT(3 3)", "POLYGON((0 0,0 3,3 3,3 1,2 1,2 0,0 0))", false, true);
  77. test_ring<P>("POINT(3 3)", "POLYGON((0 0,0 3,4 3,3 1,2 2,2 0,0 0))", false, true);
  78. // holes
  79. test_geometry<P, poly>("POINT(2 2)",
  80. "POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,3 1,3 3,1 3,1 1))", false);
  81. // Real-life problem (solved now), point is in the middle, 409623 is also a coordinate
  82. // on the border, has been wrong in the past (2009)
  83. test_ring<P>("POINT(146383 409623)",
  84. "POLYGON((146351 410597,146521 410659,147906 410363,148088 410420"
  85. ",148175 410296,148281 409750,148215 409623,148154 409666,148154 409666"
  86. ",148130 409625,148035 409626,148035 409626,148008 409544,147963 409510"
  87. ",147993 409457,147961 409352,147261 408687,147008 408586,145714 408840"
  88. ",145001 409033,144486 409066,144616 409308,145023 410286,145254 410488"
  89. ",145618 410612,145618 410612,146015 410565,146190 410545,146351 410597))",
  90. true, false);
  91. test_geometry<P, mpoly>("POINT(2 2)",
  92. "MULTIPOLYGON(((0 0,0 4,4 4,4 0,0 0),(1 1,3 1,3 3,1 3,1 1)),((5 5,5 9,9 9,9 5,5 5)))", false);
  93. test_geometry<P, mpoly>("POINT(1 1)",
  94. "MULTIPOLYGON(((0 0,0 4,4 4,4 0,0 0),(1 1,3 1,3 3,1 3,1 1)),((5 5,5 9,9 9,9 5,5 5)))", false);
  95. test_geometry<P, mpoly>("POINT(1 1)",
  96. "MULTIPOLYGON(((0 0,0 5,5 5,5 0,0 0),(2 2,4 2,4 4,2 4,2 2)),((5 5,5 9,9 9,9 5,5 5)))", true);
  97. test_geometry<P, mpoly>("POINT(6 6)",
  98. "MULTIPOLYGON(((0 0,0 4,4 4,4 0,0 0),(1 1,3 1,3 3,1 3,1 1)),((5 5,5 9,9 9,9 5,5 5)))", true);
  99. test_geometry<P, poly>("POINT(6 4)",
  100. "POLYGON((0 5, 5 0, 6 1, 5 2, 8 4, 5 6, 6 7, 5 8, 6 9, 5 10, 0 5))", true);
  101. test_geometry<P, poly>("POINT(4 6)",
  102. "POLYGON((5 0, 0 5, 1 6, 2 5, 4 8, 6 5, 7 6, 8 5, 9 6, 10 5, 5 0))", true);
  103. test_geometry<mpt, ring>("MULTIPOINT(0 0, 1 1)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", true);
  104. test_geometry<mpt, poly>("MULTIPOINT(0 0, 2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", false);
  105. test_geometry<mpt, poly>("MULTIPOINT(1 1, 3 3)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", false);
  106. test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 1 1)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", true);
  107. test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 2 2)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", false);
  108. test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 3 3)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", false);
  109. test_geometry<mpt, mpoly>("MULTIPOINT(1 1, 4 4)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", false);
  110. }
  111. template <typename P>
  112. void test_all()
  113. {
  114. test_p_p<P>();
  115. test_p_l<P>();
  116. test_p_a<P>();
  117. }
  118. template <typename Point>
  119. void test_spherical_geographic()
  120. {
  121. bg::model::polygon<Point> wrangel;
  122. typename boost::mpl::if_
  123. <
  124. boost::is_same<typename bg::cs_tag<Point>::type, bg::geographic_tag>,
  125. bg::strategy::within::geographic_winding<Point>,
  126. bg::strategy::within::spherical_winding<Point>
  127. >::type ws;
  128. typename boost::mpl::if_
  129. <
  130. boost::is_same<typename bg::cs_tag<Point>::type, bg::geographic_tag>,
  131. bg::strategy::side::geographic<>,
  132. bg::strategy::side::spherical_side_formula<>
  133. >::type ss;
  134. boost::ignore_unused(ws, ss);
  135. // SQL Server check (no geography::STWithin, so check with intersection trick)
  136. /*
  137. with q as (
  138. select geography::STGeomFromText('POLYGON((-178.569 71.5641,-179.034 71.5977,-179.305 71.5514,-179.629 71.5772,-180 71.5358,179.53 71.4383,178.872 71.2175,178.618 71.0355,178.791 70.7964,179.273 70.8886,179.678 70.8955,-180 70.9972,-179.274 70.9078,-178.819 70.98,-177.939 71.0375,-177.62 71.1166,-177.439 71.2269,-177.503 71.2775,-177.833 71.3461,-178.018 71.4497,-178.569 71.5641))',4326) as wrangel
  139. )
  140. select wrangel.STArea()/1000000.0
  141. ,geography::STGeomFromText('POINT(-179.3 71.27)',4326).STIntersection(wrangel).STAsText() as workaround_within_1
  142. ,geography::STGeomFromText('POINT(-179.9 70.95)',4326).STIntersection(wrangel).STAsText() as workaround_within_2
  143. ,geography::STGeomFromText('POINT(179.9 70.95)',4326).STIntersection(wrangel).STAsText() as workaround_within_3
  144. from q
  145. -> 7669.10402181435 POINT (-179.3 71.27) GEOMETRYCOLLECTION EMPTY GEOMETRYCOLLECTION EMPTY
  146. PostGIS knows Within for Geography neither, and the intersection trick gives the same result
  147. */
  148. bg::read_wkt("POLYGON((-178.568604 71.564148,-178.017548 71.449692,-177.833313 71.3461,-177.502838 71.277466 ,-177.439453 71.226929,-177.620026 71.116638,-177.9389 71.037491,-178.8186 70.979965,-179.274445 70.907761,-180 70.9972,179.678314 70.895538,179.272766 70.888596,178.791016 70.7964,178.617737 71.035538,178.872192 71.217484,179.530273 71.4383 ,-180 71.535843 ,-179.628601 71.577194,-179.305298 71.551361,-179.03421 71.597748,-178.568604 71.564148))", wrangel);
  149. bool within = bg::within(Point(-179.3, 71.27), wrangel);
  150. BOOST_CHECK_EQUAL(within, true);
  151. within = bg::within(Point(-179.9, 70.95), wrangel);
  152. BOOST_CHECK_EQUAL(within, false);
  153. within = bg::within(Point(179.9, 70.95), wrangel);
  154. BOOST_CHECK_EQUAL(within, false);
  155. // Test using great circle mapper
  156. // http://www.gcmap.com/mapui?P=5E52N-9E53N-7E50N-5E52N,7E52.5N,8E51.5N,6E51N
  157. bg::model::polygon<Point> triangle;
  158. bg::read_wkt("POLYGON((5 52,9 53,7 50,5 52))", triangle);
  159. BOOST_CHECK_EQUAL(bg::within(Point(7, 52.5), triangle, ws), true);
  160. BOOST_CHECK_EQUAL(bg::within(Point(8.0, 51.5), triangle, ws), false);
  161. BOOST_CHECK_EQUAL(bg::within(Point(6.0, 51.0), triangle, ws), false);
  162. // northern hemisphere
  163. {
  164. bg::model::polygon<Point> poly_n;
  165. bg::read_wkt("POLYGON((10 50,30 50,30 40,10 40, 10 50))", poly_n);
  166. Point pt_n1(20, 50.00001);
  167. Point pt_n2(20, 40.00001);
  168. BOOST_CHECK_EQUAL(ss.apply(poly_n.outer()[0], poly_n.outer()[1], pt_n1), -1); // right of segment
  169. BOOST_CHECK_EQUAL(ss.apply(poly_n.outer()[2], poly_n.outer()[3], pt_n2), 1); // left of segment
  170. BOOST_CHECK_EQUAL(bg::within(pt_n1, poly_n, ws), true);
  171. BOOST_CHECK_EQUAL(bg::within(pt_n2, poly_n, ws), false);
  172. }
  173. // southern hemisphere
  174. {
  175. bg::model::polygon<Point> poly_s;
  176. bg::read_wkt("POLYGON((10 -40,30 -40,30 -50,10 -50, 10 -40))", poly_s);
  177. Point pt_s1(20, -40.00001);
  178. Point pt_s2(20, -50.00001);
  179. BOOST_CHECK_EQUAL(ss.apply(poly_s.outer()[0], poly_s.outer()[1], pt_s1), 1); // left of segment
  180. BOOST_CHECK_EQUAL(ss.apply(poly_s.outer()[2], poly_s.outer()[3], pt_s2), -1); // right of segment
  181. BOOST_CHECK_EQUAL(bg::within(pt_s1, poly_s, ws), false);
  182. BOOST_CHECK_EQUAL(bg::within(pt_s2, poly_s, ws), true);
  183. }
  184. // crossing antimeridian, northern hemisphere
  185. {
  186. bg::model::polygon<Point> poly_n;
  187. bg::read_wkt("POLYGON((170 50,-170 50,-170 40,170 40, 170 50))", poly_n);
  188. Point pt_n11(180, 50.00001);
  189. Point pt_n12(-180, 50.00001);
  190. Point pt_n13(179, 50.00001);
  191. Point pt_n14(-179, 50.00001);
  192. Point pt_n21(180, 40.00001);
  193. Point pt_n22(-180, 40.00001);
  194. Point pt_n23(179, 40.00001);
  195. Point pt_n24(-179, 40.00001);
  196. BOOST_CHECK_EQUAL(bg::within(pt_n11, poly_n, ws), true);
  197. BOOST_CHECK_EQUAL(bg::within(pt_n12, poly_n, ws), true);
  198. BOOST_CHECK_EQUAL(bg::within(pt_n13, poly_n, ws), true);
  199. BOOST_CHECK_EQUAL(bg::within(pt_n14, poly_n, ws), true);
  200. BOOST_CHECK_EQUAL(bg::within(pt_n21, poly_n, ws), false);
  201. BOOST_CHECK_EQUAL(bg::within(pt_n22, poly_n, ws), false);
  202. BOOST_CHECK_EQUAL(bg::within(pt_n23, poly_n, ws), false);
  203. BOOST_CHECK_EQUAL(bg::within(pt_n24, poly_n, ws), false);
  204. }
  205. // TODO: Move to covered_by tests
  206. // Segment going through pole
  207. {
  208. bg::model::polygon<Point> poly_n1;
  209. bg::read_wkt("POLYGON((-90 80,90 80,90 70,-90 70, -90 80))", poly_n1);
  210. // Points on segment
  211. BOOST_CHECK_EQUAL(bg::covered_by(Point(-90, 85), poly_n1, ws), true);
  212. BOOST_CHECK_EQUAL(bg::covered_by(Point(90, 85), poly_n1, ws), true);
  213. // Points on pole
  214. BOOST_CHECK_EQUAL(bg::covered_by(Point(90, 90), poly_n1, ws), true);
  215. BOOST_CHECK_EQUAL(bg::covered_by(Point(0, 90), poly_n1, ws), true);
  216. BOOST_CHECK_EQUAL(bg::covered_by(Point(45, 90), poly_n1, ws), true);
  217. }
  218. // Segment going through pole
  219. {
  220. bg::model::polygon<Point> poly_n2;
  221. bg::read_wkt("POLYGON((-90 80,90 70,0 70,-90 80))", poly_n2);
  222. // Points on segment
  223. BOOST_CHECK_EQUAL(bg::covered_by(Point(-90, 85), poly_n2, ws), true);
  224. BOOST_CHECK_EQUAL(bg::covered_by(Point(90, 75), poly_n2, ws), true);
  225. // Points outside but on the same level as segment
  226. BOOST_CHECK_EQUAL(bg::covered_by(Point(-90, 75), poly_n2, ws), false);
  227. }
  228. // Possibly invalid, 2-segment polygon with segment going through pole
  229. /*{
  230. bg::model::polygon<Point> poly_n;
  231. bg::read_wkt("POLYGON((-90 80,90 70,-90 80))", poly_n);
  232. // Point within
  233. BOOST_CHECK_EQUAL(bg::within(Point(0, 89), poly_n), true);
  234. // Points on segment
  235. BOOST_CHECK_EQUAL(bg::covered_by(Point(-90, 85), poly_n), true);
  236. BOOST_CHECK_EQUAL(bg::covered_by(Point(90, 75), poly_n), true);
  237. // Points outside but on the same level as segment
  238. BOOST_CHECK_EQUAL(bg::covered_by(Point(-90, 75), poly_n), false);
  239. }*/
  240. // Segment endpoints on pole with arbitrary longitudes
  241. {
  242. bg::model::polygon<Point> poly_n3;
  243. bg::read_wkt("POLYGON((45 90,45 80,0 80,45 90))", poly_n3);
  244. BOOST_CHECK_EQUAL(bg::covered_by(Point(0, 85), poly_n3, ws), true);
  245. BOOST_CHECK_EQUAL(bg::covered_by(Point(45, 85), poly_n3, ws), true);
  246. }
  247. // Segment going through pole
  248. {
  249. bg::model::polygon<Point> poly_s1;
  250. bg::read_wkt("POLYGON((-90 -80,-90 -70,90 -70,90 -80,-90 -80))", poly_s1);
  251. // Points on segment
  252. BOOST_CHECK_EQUAL(bg::covered_by(Point(-90, -85), poly_s1, ws), true);
  253. BOOST_CHECK_EQUAL(bg::covered_by(Point(90, -85), poly_s1, ws), true);
  254. // Points on pole
  255. BOOST_CHECK_EQUAL(bg::covered_by(Point(90, -90), poly_s1, ws), true);
  256. BOOST_CHECK_EQUAL(bg::covered_by(Point(0, -90), poly_s1, ws), true);
  257. BOOST_CHECK_EQUAL(bg::covered_by(Point(45, -90), poly_s1, ws), true);
  258. }
  259. // Segment endpoints on pole with arbitrary longitudes
  260. {
  261. bg::model::polygon<Point> poly_s2;
  262. bg::read_wkt("POLYGON((45 -90,0 -80,45 -80,45 -90))", poly_s2);
  263. BOOST_CHECK_EQUAL(bg::covered_by(Point(0, -85), poly_s2, ws), true);
  264. BOOST_CHECK_EQUAL(bg::covered_by(Point(45, -85), poly_s2, ws), true);
  265. }
  266. // Polygon covering nearly half of the globe but no poles
  267. {
  268. bg::model::polygon<Point> poly_h1;
  269. bg::read_wkt("POLYGON((170 0, 170 -80,10 -80,0 -80,0 -20,10 -20,10 20,0 20,0 80,10 80,170 80,170 0))", poly_h1);
  270. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 90), poly_h1, ws), false);
  271. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 85), poly_h1, ws), false);
  272. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 50), poly_h1, ws), true);
  273. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 0), poly_h1, ws), false);
  274. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -50), poly_h1, ws), true);
  275. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -85), poly_h1, ws), false);
  276. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -90), poly_h1, ws), false);
  277. }
  278. // Polygon covering more than half of the globe with both holes
  279. {
  280. bg::model::polygon<Point> poly_h2;
  281. bg::read_wkt("POLYGON((180 0, 180 -80,0 -80,10 -80,10 -20,0 -20,0 20,10 20,10 80,0 80,180 80,180 0))", poly_h2);
  282. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 90), poly_h2, ws), true);
  283. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 85), poly_h2, ws), true);
  284. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 50), poly_h2, ws), false);
  285. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 0), poly_h2, ws), true);
  286. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -50), poly_h2, ws), false);
  287. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -85), poly_h2, ws), true);
  288. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -90), poly_h2, ws), true);
  289. }
  290. // Polygon covering around half of the globe covering south pole
  291. {
  292. bg::model::polygon<Point> poly_h3;
  293. bg::read_wkt("POLYGON((180 0, 180 -80,0 -80,0 -20,10 -20,10 20,0 20,0 80,10 80,170 80,180 0))", poly_h3);
  294. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 90), poly_h3, ws), false);
  295. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 85), poly_h3, ws), false);
  296. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 50), poly_h3, ws), true);
  297. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 0), poly_h3, ws), false);
  298. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -50), poly_h3, ws), true);
  299. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -85), poly_h3, ws), true);
  300. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -90), poly_h3, ws), true);
  301. }
  302. // Polygon covering around half of the globe covering north pole
  303. {
  304. bg::model::polygon<Point> poly_h4;
  305. bg::read_wkt("POLYGON((180 0, 170 -80,10 -80,10 -20,0 -20,0 20,10 20,10 80,0 80,180 80,180 0))", poly_h4);
  306. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 90), poly_h4, ws), true);
  307. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 85), poly_h4, ws), true);
  308. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 50), poly_h4, ws), false);
  309. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, 0), poly_h4, ws), true);
  310. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -50), poly_h4, ws), false);
  311. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -85), poly_h4, ws), false);
  312. BOOST_CHECK_EQUAL(bg::covered_by(Point(5, -90), poly_h4, ws), false);
  313. }
  314. }
  315. void test_large_integers()
  316. {
  317. typedef bg::model::point<int, 2, bg::cs::cartesian> int_point_type;
  318. typedef bg::model::point<double, 2, bg::cs::cartesian> double_point_type;
  319. std::string const polygon_li = "POLYGON((1872000 528000,1872000 192000,1536119 192000,1536000 528000,1200000 528000,1200000 863880,1536000 863880,1872000 863880,1872000 528000))";
  320. bg::model::polygon<int_point_type> int_poly;
  321. bg::model::polygon<double_point_type> double_poly;
  322. bg::read_wkt(polygon_li, int_poly);
  323. bg::read_wkt(polygon_li, double_poly);
  324. std::string const point_li = "POINT(1592000 583950)";
  325. int_point_type int_point;
  326. double_point_type double_point;
  327. bg::read_wkt(point_li, int_point);
  328. bg::read_wkt(point_li, double_point);
  329. bool wi = bg::within(int_point, int_poly);
  330. bool wd = bg::within(double_point, double_poly);
  331. BOOST_CHECK_MESSAGE(wi == wd, "within<a double> different from within<an int>");
  332. }
  333. void test_tickets()
  334. {
  335. typedef boost::geometry::model::d2::point_xy<double> pt;
  336. typedef boost::geometry::model::ring<pt> ring;
  337. // https://svn.boost.org/trac/boost/ticket/9628
  338. {
  339. ring r;
  340. r.push_back(pt(-19155.669324773193,54820.312032458620));
  341. r.push_back(pt(-13826.169324773080,54820.312032458627));
  342. r.push_back(pt(-13826.169324773078,52720.312032458663));
  343. r.push_back(pt(-12755.169324773129,52720.312032458663));
  344. r.push_back(pt(-12755.169324773129,51087.312032458671));
  345. r.push_back(pt(-12760.669324773080,51087.312032458671));
  346. r.push_back(pt(-12760.669324773082,51070.312032458627));
  347. r.push_back(pt(-19155.669324779392,51070.312032458620));
  348. r.push_back(pt(-19155.669324773193,54820.312032458620));
  349. pt p( -12260.669324773118, 54820.312032458634 );
  350. //boost::geometry::correct(r);
  351. bool within = boost::geometry::within(p, r);
  352. BOOST_CHECK_EQUAL(within, false);
  353. }
  354. // similar
  355. {
  356. ring r;
  357. r.push_back(pt(-14155.6,54820.312032458620));
  358. r.push_back(pt(-13826.1,54820.312032458625));
  359. r.push_back(pt(-12155.6,53720.3));
  360. r.push_back(pt(-14155.6,54820.312032458620));
  361. pt p( -13826.0, 54820.312032458634 );
  362. bool within = boost::geometry::within(p, r);
  363. BOOST_CHECK_EQUAL(within, false);
  364. }
  365. // https://svn.boost.org/trac/boost/ticket/10234
  366. {
  367. pt p;
  368. ring r;
  369. bg::read_wkt("POINT(0.1377 5.00)", p);
  370. bg::read_wkt("POLYGON((0.1277 4.97, 0.1277 5.00, 0.1278 4.9999999999999982, 0.1278 4.97, 0.1277 4.97))", r);
  371. bool within = boost::geometry::within(p, r);
  372. BOOST_CHECK_EQUAL(within, false);
  373. bool covered_by = boost::geometry::covered_by(p, r);
  374. BOOST_CHECK_EQUAL(covered_by, false);
  375. }
  376. }
  377. int test_main( int , char* [] )
  378. {
  379. test_large_integers();
  380. test_all<bg::model::d2::point_xy<int> >();
  381. test_all<bg::model::d2::point_xy<double> >();
  382. test_spherical_geographic<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> > >();
  383. test_spherical_geographic<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
  384. #if defined(HAVE_TTMATH)
  385. test_all<bg::model::d2::point_xy<ttmath_big> >();
  386. test_spherical_geographic<bg::model::point<ttmath_big, 2, bg::cs::spherical_equatorial<bg::degree> > >();
  387. test_spherical_geographic<bg::model::point<ttmath_big, 2, bg::cs::geographic<bg::degree> > >();
  388. #endif
  389. test_tickets();
  390. return 0;
  391. }