1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2014-2018, Oracle and/or its affiliates.
5 
6 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
7 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9 
10 // Licensed under the Boost Software License version 1.0.
11 // http://www.boost.org/users/license.html
12 
13 #include <iostream>
14 
15 #ifndef BOOST_TEST_MODULE
16 #define BOOST_TEST_MODULE test_distance_spherical_equatorial_pointlike_pointlike
17 #endif
18 
19 #include <boost/range.hpp>
20 
21 #include <boost/test/included/unit_test.hpp>
22 #include <boost/geometry/strategies/strategies.hpp>
23 
24 #include "test_distance_se_common.hpp"
25 #include "test_empty_geometry.hpp"
26 
27 typedef bg::cs::spherical_equatorial<bg::degree> cs_type;
28 typedef bg::model::point<double, 2, cs_type> point_type;
29 typedef bg::model::multi_point<point_type> multi_point_type;
30 
31 namespace distance = bg::strategy::distance;
32 namespace services = distance::services;
33 typedef bg::default_distance_result<point_type>::type return_type;
34 
35 typedef distance::haversine<double> point_point_strategy;
36 typedef distance::comparable::haversine<double> comparable_point_point_strategy;
37 
38 //===========================================================================
39 
40 template <typename Strategy>
41 inline typename bg::distance_result<point_type, point_type, Strategy>::type
distance_from_wkt(std::string const & wkt1,std::string const & wkt2,Strategy const & strategy)42 distance_from_wkt(std::string const& wkt1,
43                   std::string const& wkt2,
44                   Strategy const& strategy)
45 {
46     point_type p1, p2;
47     bg::read_wkt(wkt1, p1);
48     bg::read_wkt(wkt2, p2);
49     return bg::distance(p1, p2, strategy);
50 }
51 
52 inline bg::default_comparable_distance_result<point_type>::type
comparable_distance_from_wkt(std::string const & wkt1,std::string const & wkt2)53 comparable_distance_from_wkt(std::string const& wkt1,
54                              std::string const& wkt2)
55 {
56     point_type p1, p2;
57     bg::read_wkt(wkt1, p1);
58     bg::read_wkt(wkt2, p2);
59     return bg::comparable_distance(p1, p2);
60 }
61 
62 //===========================================================================
63 
64 template <typename Strategy>
test_distance_point_point(Strategy const & strategy,bool is_comparable_strategy=false)65 void test_distance_point_point(Strategy const& strategy,
66                                bool is_comparable_strategy = false)
67 {
68     double pi = bg::math::pi<double>();
69     double r = strategy.radius();
70 
71 #ifdef BOOST_GEOMETRY_TEST_DEBUG
72     std::cout << std::endl;
73     std::cout << "point/point distance tests" << std::endl;
74 #endif
75     typedef test_distance_of_geometries<point_type, point_type> tester;
76 
77     tester::apply("p-p-01",
78                   "POINT(10 10)",
79                   "POINT(0 0)",
80                   (is_comparable_strategy
81                    ? 0.0150768448035229
82                    : (0.24619691677893202 * r)),
83                   0.0150768448035229,
84                   strategy);
85     tester::apply("p-p-02",
86                   "POINT(10 10)",
87                   "POINT(10 10)",
88                   0,
89                   strategy);
90 
91     // antipodal points
92     tester::apply("p-p-03",
93                   "POINT(0 10)",
94                   "POINT(180 -10)",
95                   (is_comparable_strategy
96                    ? 1.0
97                    : (pi * r)),
98                   1.0,
99                   strategy);
100     tester::apply("p-p-04",
101                   "POINT(0 0)",
102                   "POINT(180 0)",
103                   (is_comparable_strategy
104                    ? 1.0
105                    : (pi * r)),
106                   1.0,
107                   strategy);
108 
109     // https://svn.boost.org/trac/boost/ticket/11982
110     tester::apply("p-p-05",
111                   "POINT(10.521812 59.887214)",
112                   "POINT(10.4 63.43)",
113                   (is_comparable_strategy
114                    ? 0.00095578716185788
115                    : (0.06184146915711819 * r)),
116                   0.00095578716185788,
117                   strategy);
118     tester::apply("p-p-06",
119                   "POINT(10.733557 59.911923)",
120                   "POINT(10.4 63.43)",
121                   (is_comparable_strategy
122                    ? 0.0009441561071329
123                    : (0.0614639773975828 * r)),
124                   0.000944156107132969,
125                   strategy);
126 }
127 
128 //===========================================================================
129 
130 template <typename Strategy>
test_distance_point_multipoint(Strategy const & strategy)131 void test_distance_point_multipoint(Strategy const& strategy)
132 {
133 #ifdef BOOST_GEOMETRY_TEST_DEBUG
134     std::cout << std::endl;
135     std::cout << "point/multipoint distance tests" << std::endl;
136 #endif
137     typedef test_distance_of_geometries<point_type, multi_point_type> tester;
138 
139     tester::apply("p-mp-01",
140                   "POINT(10 10)",
141                   "MULTIPOINT(10 10,20 10,20 20,10 20)",
142                   0,
143                   strategy);
144     tester::apply("p-mp-02",
145                   "POINT(10 10)",
146                   "MULTIPOINT(20 20,20 30,30 20,30 30)",
147                   distance_from_wkt("POINT(10 10)", "POINT(20 20)", strategy),
148                   comparable_distance_from_wkt("POINT(10 10)", "POINT(20 20)"),
149                   strategy);
150     tester::apply("p-mp-03",
151                   "POINT(3 0)",
152                   "MULTIPOINT(20 20,20 40,40 20,40 40)",
153                   distance_from_wkt("POINT(3 0)", "POINT(20 20)", strategy),
154                   comparable_distance_from_wkt("POINT(3 0)", "POINT(20 20)"),
155                   strategy);
156 
157     // almost antipodal points
158     tester::apply("p-mp-04",
159                   "POINT(179 2)",
160                   "MULTIPOINT(3 3,4 3,4 4,3 4)",
161                   distance_from_wkt("POINT(179 2)", "POINT(4 4)", strategy),
162                   comparable_distance_from_wkt("POINT(179 2)", "POINT(4 4)"),
163                   strategy);
164 
165     // minimum distance across the dateline
166     tester::apply("p-mp-05",
167                   "POINT(355 5)",
168                   "MULTIPOINT(10 10,20 10,20 20,10 20)",
169                   distance_from_wkt("POINT(355 5)", "POINT(10 10)", strategy),
170                   comparable_distance_from_wkt("POINT(355 5)", "POINT(10 10)"),
171                   strategy);
172     tester::apply("p-mp-06",
173                   "POINT(-5 5)",
174                   "MULTIPOINT(10 10,20 10,20 20,10 20)",
175                   distance_from_wkt("POINT(-5 5)", "POINT(10 10)", strategy),
176                   comparable_distance_from_wkt("POINT(-5 5)", "POINT(10 10)"),
177                   strategy);
178 }
179 
180 //===========================================================================
181 
182 template <typename Strategy>
test_distance_multipoint_multipoint(Strategy const & strategy)183 void test_distance_multipoint_multipoint(Strategy const& strategy)
184 {
185 #ifdef BOOST_GEOMETRY_TEST_DEBUG
186     std::cout << std::endl;
187     std::cout << "multipoint/multipoint distance tests" << std::endl;
188 #endif
189     typedef test_distance_of_geometries
190         <
191             multi_point_type, multi_point_type
192         > tester;
193 
194     tester::apply("mp-mp-01",
195                   "MULTIPOINT(10 10,11 10,10 11,11 11)",
196                   "MULTIPOINT(11 11,12 11,12 12,11 12)",
197                   0,
198                   strategy);
199     tester::apply("mp-mp-02",
200                   "MULTIPOINT(10 10,11 10,10 11,11 11)",
201                   "MULTIPOINT(12 12,12 13,13 12,13 13)",
202                   distance_from_wkt("POINT(11 11)", "POINT(12 12)", strategy),
203                   comparable_distance_from_wkt("POINT(11 11)", "POINT(12 12)"),
204                   strategy);
205 
206     // example with many points in each multi-point so that the r-tree
207     // does some splitting.
208     tester::apply("mp-mp-03",
209                   "MULTIPOINT(1 1,1 2,1 3,1 4,1 5,1 6,1 7,1 8,1 9,1 10,\
210                   2 1,2 2,2 3,2 4,2 5,2 6,2 7,2 8,2 9,2 10,\
211                   3 1,3 2,3 3,3 4,3 5,3 6,3 7,3 8,3 9,3 10,\
212                   10 1,10 10)",
213                   "MULTIPOINT(11 11,11 12,11 13,11 14,11 15,\
214                   11 16,11 17,11 18,11 19,11 20,\
215                   12 11,12 12,12 13,12 24,12 15,\
216                   12 16,12 17,12 18,12 29,12 20,\
217                   13 11,13 12,13 13,13 24,13 15,\
218                   13 16,13 17,13 18,13 29,13 20,\
219                   20 11,20 20)",
220                   distance_from_wkt("POINT(10 10)", "POINT(11 11)", strategy),
221                   comparable_distance_from_wkt("POINT(10 10)", "POINT(11 11)"),
222                   strategy);
223 
224 }
225 
226 //===========================================================================
227 
BOOST_AUTO_TEST_CASE(test_all_pointlike_pointlike)228 BOOST_AUTO_TEST_CASE( test_all_pointlike_pointlike )
229 {
230     test_distance_point_point(point_point_strategy());
231     test_distance_point_point(point_point_strategy(earth_radius_km));
232     test_distance_point_point(point_point_strategy(earth_radius_miles));
233 
234     test_distance_point_point(comparable_point_point_strategy(), true);
235     test_distance_point_point
236         (comparable_point_point_strategy(earth_radius_km), true);
237     test_distance_point_point
238         (comparable_point_point_strategy(earth_radius_miles), true);
239 }
240 
BOOST_AUTO_TEST_CASE(test_all_point_multipoint)241 BOOST_AUTO_TEST_CASE( test_all_point_multipoint )
242 {
243     test_distance_point_multipoint(point_point_strategy());
244     test_distance_point_multipoint(point_point_strategy(earth_radius_km));
245     test_distance_point_multipoint(point_point_strategy(earth_radius_miles));
246 
247     test_distance_point_multipoint(comparable_point_point_strategy());
248     test_distance_point_multipoint
249         (comparable_point_point_strategy(earth_radius_km));
250     test_distance_point_multipoint
251         (comparable_point_point_strategy(earth_radius_miles));
252 }
253 
BOOST_AUTO_TEST_CASE(test_all_multipoint_multipoint)254 BOOST_AUTO_TEST_CASE( test_all_multipoint_multipoint )
255 {
256     test_distance_multipoint_multipoint(point_point_strategy());
257     test_distance_multipoint_multipoint(point_point_strategy(earth_radius_km));
258     test_distance_multipoint_multipoint
259         (point_point_strategy(earth_radius_miles));
260 
261     test_distance_multipoint_multipoint(comparable_point_point_strategy());
262     test_distance_multipoint_multipoint
263         (comparable_point_point_strategy(earth_radius_km));
264     test_distance_multipoint_multipoint
265         (comparable_point_point_strategy(earth_radius_miles));
266 }
267 
BOOST_AUTO_TEST_CASE(test_all_empty_input_pointlike_pointlike)268 BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_pointlike )
269 {
270     test_more_empty_input_pointlike_pointlike
271         <
272             point_type
273         >(point_point_strategy());
274 
275     test_more_empty_input_pointlike_pointlike
276         <
277             point_type
278         >(point_point_strategy(earth_radius_km));
279 
280     test_more_empty_input_pointlike_pointlike
281         <
282             point_type
283         >(point_point_strategy(earth_radius_miles));
284 
285     test_more_empty_input_pointlike_pointlike
286         <
287             point_type
288         >(comparable_point_point_strategy());
289 
290     test_more_empty_input_pointlike_pointlike
291         <
292             point_type
293         >(comparable_point_point_strategy(earth_radius_km));
294 
295     test_more_empty_input_pointlike_pointlike
296         <
297             point_type
298         >(comparable_point_point_strategy(earth_radius_miles));
299 }
300