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