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 
6 // This file was modified by Oracle on 2014, 2015, 2016, 2017.
7 // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
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>
test_p_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);
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);
43 }
44 
45 template <typename P>
test_p_l()46 void test_p_l()
47 {
48     typedef bg::model::multi_point<P> mpt;
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);
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);
79 }
80 
81 template <typename P>
test_p_a()82 void test_p_a()
83 {
84     typedef bg::model::multi_point<P> mpt;
85     typedef bg::model::ring<P> ring;
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);
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);
142 }
143 
144 template <typename P>
test_all()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>
test_spherical_geographic()153 void test_spherical_geographic()
154 {
155     bg::model::polygon<Point> wrangel;
156 
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 
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);
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);
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);
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);
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);
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);
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);
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);
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
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);
265         // Points on pole
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);
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
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);
277         // Points outside but on the same level as segment
278         BOOST_CHECK_EQUAL(bg::covered_by(Point(-90, 75), poly_n2, ws), false);
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);
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);
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
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);
306         // Points on pole
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);
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);
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);
365     }
366 }
367 
test_large_integers()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 
test_tickets()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 
test_main(int,char * [])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 
453     test_tickets();
454 
455     return 0;
456 }
457