1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2014-2017, Oracle and/or its affiliates.
5 
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7 
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10 
11 #ifndef BOOST_TEST_MODULE
12 #define BOOST_TEST_MODULE test_is_simple_geo
13 #endif
14 
15 #include "test_is_simple.hpp"
16 
17 
sph(double a,double rf)18 inline bg::srs::spheroid<double> sph(double a, double rf)
19 {
20     double b = a - a / rf;
21     return bg::srs::spheroid<double>(a, b);
22 }
23 
24 typedef bg::model::point<double, 2, bg::cs::geographic<bg::degree> >  point_type;
25 typedef bg::model::segment<point_type>                  segment_type;
26 typedef bg::model::linestring<point_type>               linestring_type;
27 typedef bg::model::multi_linestring<linestring_type>    multi_linestring_type;
28 // ccw open and closed polygons
29 typedef bg::model::polygon<point_type,false,false>      open_ccw_polygon_type;
30 typedef bg::model::polygon<point_type,false,true>       closed_ccw_polygon_type;
31 // multi-geometries
32 typedef bg::model::multi_point<point_type>              multi_point_type;
33 typedef bg::model::multi_polygon<open_ccw_polygon_type> multi_polygon_type;
34 // box
35 typedef bg::model::box<point_type>                      box_type;
36 
37 
BOOST_AUTO_TEST_CASE(test_is_simple_geo_multipoint)38 BOOST_AUTO_TEST_CASE( test_is_simple_geo_multipoint )
39 {
40     typedef multi_point_type G;
41 
42     bg::strategy::intersection::geographic_segments<> s;
43 
44     test_simple_s(from_wkt<G>("MULTIPOINT(0 90, 0 90)"), s, false);
45     test_simple_s(from_wkt<G>("MULTIPOINT(0 90, 1 90)"), s, false);
46     test_simple_s(from_wkt<G>("MULTIPOINT(0 -90, 0 -90)"), s, false);
47     test_simple_s(from_wkt<G>("MULTIPOINT(0 -90, 1 -90)"), s, false);
48     test_simple_s(from_wkt<G>("MULTIPOINT(0 80, 1 80)"), s, true);
49 }
50 
BOOST_AUTO_TEST_CASE(test_is_simple_geo_linestring)51 BOOST_AUTO_TEST_CASE( test_is_simple_geo_linestring )
52 {
53     typedef linestring_type G;
54 
55     bg::srs::spheroid<double> sph_wgs84;
56     bg::srs::spheroid<double> sph_4053(6371228, 6371228);
57     bg::srs::spheroid<double> sph_near_4053(6371228, 6371227);
58 
59     bg::strategy::intersection::geographic_segments<> s(sph_wgs84);
60     bg::strategy::intersection::geographic_segments<> s_4053(sph_4053);
61     bg::strategy::intersection::geographic_segments<> s_near_4053(sph_near_4053);
62 
63     // Two cases which in Cartesian would be a spike, but in Geographic
64     // they go over the equator (first segment) and then over the pole
65     // (second segment)
66     test_simple_s(from_wkt<G>("LINESTRING(0 0, -90 0, 90 0)"), s, true);
67     test_simple_s(from_wkt<G>("LINESTRING(0 0, 90 0, -90 0)"), s, true);
68 
69     // Two similar cases, but these do not go over the pole back, but
70     // over the equator, and therefore make a spike
71     test_simple_s(from_wkt<G>("LINESTRING(0 0, -80 0, 80 0)"), s, false);
72     test_simple_s(from_wkt<G>("LINESTRING(0 0, 80 0, -80 0)"), s, false);
73 
74     // Going over the equator in a normal way, eastwards and westwards
75     test_simple_s(from_wkt<G>("LINESTRING(-90 0, 0 0, 90 0)"), s, true);
76     test_simple_s(from_wkt<G>("LINESTRING(90 0, 0 0, -90 0)"), s, true);
77 
78     test_simple_s(from_wkt<G>("LINESTRING(0 90, -90 0, 90 0)"), s, false);
79     test_simple_s(from_wkt<G>("LINESTRING(0 90, -90 50, 90 0)"), s, false);
80     test_simple_s(from_wkt<G>("LINESTRING(0 90, -90 -50, 90 0)"), s, true);
81 
82     // invalid linestrings
83     test_simple_s(from_wkt<G>("LINESTRING(0 90, 0 90)"), s, false, false);
84     test_simple_s(from_wkt<G>("LINESTRING(0 -90, 0 -90)"), s, false, false);
85     test_simple_s(from_wkt<G>("LINESTRING(0 90, 1 90)"), s, false, false);
86     test_simple_s(from_wkt<G>("LINESTRING(0 -90, 1 -90)"), s, false, false);
87 
88     // FAILING
89     //test_simple_s(from_wkt<G>("LINESTRING(0 90, 0 80, 1 80, 0 90)"), s, false);
90     //test_simple_s(from_wkt<G>("LINESTRING(0 -90, 0 -80, 1 -80, 0 -90)"), s, false);
91     //test_simple_s(from_wkt<G>("LINESTRING(0 90, 0 80, 1 80, 1 90)"), s, false);
92     //test_simple_s(from_wkt<G>("LINESTRING(0 -90, 0 -80, 1 -80, 1 -90)"), s, false);
93 
94     test_simple_s(from_wkt<G>("LINESTRING(35 0, 110 36, 159 0, 82 30)"), s, false);
95     test_simple_s(from_wkt<G>("LINESTRING(135 0, -150 36, -101 0, -178 30)"), s, false);
96     test_simple_s(from_wkt<G>("LINESTRING(45 0, 120 36, 169 0, 92 30)"), s, false);
97     test_simple_s(from_wkt<G>("LINESTRING(179 0, -179 1, -179 0, 179 1)"), s, false);
98 
99     test_simple_s(from_wkt<G>("LINESTRING(-121 -19,37 8,-19 -15,-104 -58)"), s, false);
100     test_simple_s(from_wkt<G>("LINESTRING(-121 -19,37 8,-19 -15,-104 -58)"), s_4053, false);
101     test_simple_s(from_wkt<G>("LINESTRING(-121 -19,37 8,-19 -15,-104 -58)"), s_near_4053, false);
102 
103     // The segments are very close to each other, in WGS84 they cross,
104     // in spherical or nearly spherical they don't cross
105     test_simple_s(from_wkt<G>("LINESTRING(106 22,21 39,40 -12,-91 68)"), s, false);
106     test_simple_s(from_wkt<G>("LINESTRING(106 22,21 39,40 -12,-91 68)"), s_4053, true);
107     test_simple_s(from_wkt<G>("LINESTRING(106 22,21 39,40 -12,-91 68)"), s_near_4053, true);
108 }
109 
BOOST_AUTO_TEST_CASE(test_is_simple_geo_multilinestring)110 BOOST_AUTO_TEST_CASE( test_is_simple_geo_multilinestring )
111 {
112     typedef multi_linestring_type G;
113 
114     bg::strategy::intersection::geographic_segments<> s_wgs84; // EPSG 4326
115     bg::strategy::intersection::geographic_segments<> s_bessel((sph(6377397.155,299.1528128))); // EPSG 4804, 4813, 4820
116 
117     // FAILING
118     //test_simple_s(from_wkt<G>("MULTILINESTRING((0 90, 0 80),(1 90, 1 80))"), s_wgs84, false);
119     //test_simple_s(from_wkt<G>("MULTILINESTRING((0 -90, 0 -80),(1 -90, 1 -80))"), s_wgs84, false);
120 
121     test_simple_s(from_wkt<G>("MULTILINESTRING((35 0, 110 36),(159 0, 82 30))"), s_wgs84, false);
122     test_simple_s(from_wkt<G>("MULTILINESTRING((135 0, -150 36),(-101 0, -178 30))"), s_wgs84, false);
123     test_simple_s(from_wkt<G>("MULTILINESTRING((45 0, 120 36),(169 0, 92 30))"), s_wgs84, false);
124     test_simple_s(from_wkt<G>("MULTILINESTRING((179 0, -179 1),(-179 0, 179 1))"), s_wgs84, false);
125 
126     test_simple_s(from_wkt<G>("MULTILINESTRING((35 2,110 36),(72 51,67 28,16 53,159 3,82 30))"), s_wgs84, false);
127     test_simple_s(from_wkt<G>("MULTILINESTRING((35 2,110 36),(72 51,67 28,16 53,159 3,82 30))"), s_bessel, false);
128 }
129