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 
9 // Licensed under the Boost Software License version 1.0.
10 // http://www.boost.org/users/license.html
11 
12 #include <iostream>
13 
14 #ifndef BOOST_TEST_MODULE
15 #define BOOST_TEST_MODULE test_distance_cartesian_pointlike_linear
16 #endif
17 
18 #include <boost/test/included/unit_test.hpp>
19 
20 #include "test_distance_common.hpp"
21 #include "test_empty_geometry.hpp"
22 
23 typedef bg::model::point<double,2,bg::cs::cartesian>  point_type;
24 typedef bg::model::multi_point<point_type>            multi_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 
29 namespace services = bg::strategy::distance::services;
30 typedef bg::default_distance_result<point_type>::type return_type;
31 
32 typedef bg::strategy::distance::pythagoras<> point_point_strategy;
33 typedef bg::strategy::distance::projected_point<> point_segment_strategy;
34 
35 
36 //===========================================================================
37 
38 
39 template <typename Strategy>
test_distance_point_segment(Strategy const & strategy)40 void test_distance_point_segment(Strategy const& strategy)
41 {
42 #ifdef BOOST_GEOMETRY_TEST_DEBUG
43     std::cout << std::endl;
44     std::cout << "point/segment distance tests" << std::endl;
45 #endif
46     typedef test_distance_of_geometries<point_type, segment_type> tester;
47 
48     tester::apply("point(0 0)", "segment(2 0,3 0)", 2, 4, strategy);
49     tester::apply("point(2.5 3)", "segment(2 0,3 0)", 3, 9, strategy);
50     tester::apply("point(2 0)", "segment(2 0,3 0)", 0, 0, strategy);
51     tester::apply("point(3 0)", "segment(2 0,3 0)", 0, 0, strategy);
52     tester::apply("point(2.5 0)", "segment(2 0,3 0)", 0, 0, strategy);
53 
54     // distance is a NaN
55     tester::apply("POINT(4.297374e+307 8.433875e+307)",
56                   "SEGMENT(26 87,13 95)",
57                   0, 0, strategy, false);
58 }
59 
60 //===========================================================================
61 
62 template <typename Strategy>
test_distance_point_linestring(Strategy const & strategy)63 void test_distance_point_linestring(Strategy const& strategy)
64 {
65 #ifdef BOOST_GEOMETRY_TEST_DEBUG
66     std::cout << std::endl;
67     std::cout << "point/linestring distance tests" << std::endl;
68 #endif
69     typedef test_distance_of_geometries<point_type, linestring_type> tester;
70 
71     tester::apply("point(0 0)", "linestring(2 0,3 0)", 2, 4, strategy);
72     tester::apply("point(2.5 3)", "linestring(2 0,3 0)", 3, 9, strategy);
73     tester::apply("point(2 0)", "linestring(2 0,3 0)", 0, 0, strategy);
74     tester::apply("point(3 0)", "linestring(2 0,3 0)", 0, 0, strategy);
75     tester::apply("point(2.5 0)", "linestring(2 0,3 0)", 0, 0, strategy);
76 
77     // linestring with a single point
78     tester::apply("point(0 0)", "linestring(2 0)", 2, 4, strategy);
79 
80     // distance is a NaN
81     tester::apply("POINT(4.297374e+307 8.433875e+307)",
82                   "LINESTRING(26 87,13 95)",
83                   0, 0, strategy, false);
84 }
85 
86 //===========================================================================
87 
88 template <typename Strategy>
test_distance_point_multilinestring(Strategy const & strategy)89 void test_distance_point_multilinestring(Strategy const& strategy)
90 {
91 #ifdef BOOST_GEOMETRY_TEST_DEBUG
92     std::cout << std::endl;
93     std::cout << "point/multilinestring distance tests" << std::endl;
94 #endif
95     typedef test_distance_of_geometries
96         <
97             point_type, multi_linestring_type
98         > tester;
99 
100     tester::apply("point(0 0)",
101                   "multilinestring((-5 0,-3 0),(2 0,3 0))",
102                   2, 4, strategy);
103     tester::apply("point(2.5 3)",
104                   "multilinestring((-5 0,-3 0),(2 0,3 0))",
105                   3, 9, strategy);
106     tester::apply("point(2 0)",
107                   "multilinestring((-5 0,-3 0),(2 0,3 0))",
108                   0, 0, strategy);
109     tester::apply("point(3 0)",
110                   "multilinestring((-5 0,-3 0),(2 0,3 0))",
111                   0, 0, strategy);
112     tester::apply("point(2.5 0)",
113                   "multilinestring((-5 0,-3 0),(2 0,3 0))",
114                   0, 0, strategy);
115     tester::apply("POINT(0 0)",
116                   "MULTILINESTRING((10 10,10 0),(0.0 -0.0,0.0 -0.0))",
117                   0, 0, strategy);
118     tester::apply("POINT(0 0)",
119                   "MULTILINESTRING((10 10,10 0),(1 1,1 1))",
120                   sqrt(2.0), 2, strategy);
121     tester::apply("POINT(0 0)",
122                   "MULTILINESTRING((10 10,10 0),(1 1,2 2))",
123                   sqrt(2.0), 2, strategy);
124     tester::apply("POINT(0 0)",
125                   "MULTILINESTRING((10 10,10 0),(20 20,20 20))",
126                   10, 100, strategy);
127 
128     // multilinestrings containing an empty linestring
129     tester::apply("POINT(0 0)",
130                   "MULTILINESTRING((),(10 0),(20 20,20 20))",
131                   10, 100, strategy);
132     tester::apply("POINT(0 0)",
133                   "MULTILINESTRING((),(10 0),(),(20 20,20 20))",
134                   10, 100, strategy);
135 
136     // multilinestrings containing a linestring with a single point
137     tester::apply("POINT(0 0)",
138                   "MULTILINESTRING((10 0),(20 20,20 20))",
139                   10, 100, strategy);
140     tester::apply("POINT(0 0)",
141                   "MULTILINESTRING((20 20,20 20),(10 0))",
142                   10, 100, strategy);
143 
144     // multilinestring with a single-point linestring and empty linestrings
145     tester::apply("POINT(0 0)",
146                   "MULTILINESTRING((),(20 20,20 20),(),(10 0))",
147                   10, 100, strategy);
148 }
149 
150 //===========================================================================
151 
152 template <typename Strategy>
test_distance_linestring_multipoint(Strategy const & strategy)153 void test_distance_linestring_multipoint(Strategy const& strategy)
154 {
155 #ifdef BOOST_GEOMETRY_TEST_DEBUG
156     std::cout << std::endl;
157     std::cout << "linestring/multipoint distance tests" << std::endl;
158 #endif
159     typedef test_distance_of_geometries
160         <
161             linestring_type, multi_point_type
162         > tester;
163 
164     tester::apply("linestring(2 0,0 2,100 100)",
165                   "multipoint(0 0,1 0,0 1,1 1)",
166                   0, 0, strategy);
167     tester::apply("linestring(4 0,0 4,100 100)",
168                   "multipoint(0 0,1 0,0 1,1 1)",
169                   sqrt(2.0), 2, strategy);
170     tester::apply("linestring(1 1,2 2,100 100)",
171                   "multipoint(0 0,1 0,0 1,1 1)",
172                   0, 0, strategy);
173     tester::apply("linestring(3 3,4 4,100 100)",
174                   "multipoint(0 0,1 0,0 1,1 1)",
175                   sqrt(8.0), 8, strategy);
176 
177     // linestring with a single point
178     tester::apply("linestring(1 8)",
179                   "multipoint(0 0,3 0,4 -7,10 100)",
180                   sqrt(65.0), 65, strategy);
181 }
182 
183 //===========================================================================
184 
185 template <typename Strategy>
test_distance_multipoint_multilinestring(Strategy const & strategy)186 void test_distance_multipoint_multilinestring(Strategy const& strategy)
187 {
188 #ifdef BOOST_GEOMETRY_TEST_DEBUG
189     std::cout << std::endl;
190     std::cout << "multipoint/multilinestring distance tests" << std::endl;
191 #endif
192     typedef test_distance_of_geometries
193         <
194             multi_point_type, multi_linestring_type
195         > tester;
196 
197     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
198                   "multilinestring((2 0,0 2),(2 2,3 3))",
199                   0, 0, strategy);
200     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
201                   "multilinestring((3 0,0 3),(4 4,5 5))",
202                   0.5 * sqrt(2.0), 0.5, strategy);
203     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
204                   "multilinestring((4 4,5 5),(1 1,2 2))",
205                   0, 0, strategy);
206     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
207                   "multilinestring((3 3,4 4),(4 4,5 5))",
208                   sqrt(8.0), 8, strategy);
209 
210     // multilinestring with empty linestring
211     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
212                   "multilinestring((),(3 3,4 4),(4 4,5 5))",
213                   sqrt(8.0), 8, strategy);
214     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
215                   "multilinestring((3 3,4 4),(),(4 4,5 5))",
216                   sqrt(8.0), 8, strategy);
217 
218     // multilinestrings with a single-point linestrings
219     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
220                   "multilinestring((3 3),(4 4,5 5))",
221                   sqrt(8.0), 8, strategy);
222     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
223                   "multilinestring((4 4,5 5),(3 3))",
224                   sqrt(8.0), 8, strategy);
225 
226     // multilinestring with a single-point linestring and empty linestring
227     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
228                   "multilinestring((4 4,5 5),(),(3 3))",
229                   sqrt(8.0), 8, strategy);
230 
231     // 21890717 - assertion failure in distance(Pt, Box)
232     {
233         multi_point_type mpt;
234         bg::read_wkt("multipoint(1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1)", mpt);
235         multi_linestring_type mls;
236         linestring_type ls;
237         point_type pt(std::numeric_limits<double>::quiet_NaN(), 1.0);
238         ls.push_back(pt);
239         ls.push_back(pt);
240         mls.push_back(ls);
241         bg::distance(mpt, mls);
242     }
243 }
244 
245 //===========================================================================
246 
247 template <typename Strategy>
test_distance_multipoint_segment(Strategy const & strategy)248 void test_distance_multipoint_segment(Strategy const& strategy)
249 {
250 #ifdef BOOST_GEOMETRY_TEST_DEBUG
251     std::cout << std::endl;
252     std::cout << "multipoint/segment distance tests" << std::endl;
253 #endif
254     typedef test_distance_of_geometries<multi_point_type, segment_type> tester;
255 
256     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
257                   "segment(2 0,0 2)",
258                   0, 0, strategy);
259     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
260                   "segment(4 0,0 4)",
261                   sqrt(2.0), 2, strategy);
262     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
263                   "segment(1 1,2 2)",
264                   0, 0, strategy);
265     tester::apply("multipoint(0 0,1 0,0 1,1 1)",
266                   "segment(3 3,4 4)",
267                   sqrt(8.0), 8, strategy);
268     tester::apply("multipoint(4 4,5 5,2 2,3 3)",
269                   "segment(0 0,1 1)",
270                   sqrt(2.0), 2, strategy);
271 }
272 
273 //===========================================================================
274 //===========================================================================
275 //===========================================================================
276 
BOOST_AUTO_TEST_CASE(test_all_point_segment)277 BOOST_AUTO_TEST_CASE( test_all_point_segment )
278 {
279     test_distance_point_segment(point_point_strategy()); // back-compatibility
280     test_distance_point_segment(point_segment_strategy());
281 }
282 
BOOST_AUTO_TEST_CASE(test_all_point_linestring)283 BOOST_AUTO_TEST_CASE( test_all_point_linestring )
284 {
285     test_distance_point_linestring(point_point_strategy()); // back-compatibility
286     test_distance_point_linestring(point_segment_strategy());
287 }
288 
BOOST_AUTO_TEST_CASE(test_all_point_multilinestring)289 BOOST_AUTO_TEST_CASE( test_all_point_multilinestring )
290 {
291     test_distance_point_multilinestring(point_point_strategy()); // back-compatibility
292     test_distance_point_multilinestring(point_segment_strategy());
293 }
294 
BOOST_AUTO_TEST_CASE(test_all_linestring_multipoint)295 BOOST_AUTO_TEST_CASE( test_all_linestring_multipoint )
296 {
297     test_distance_linestring_multipoint(point_point_strategy()); // back-compatibility
298     test_distance_linestring_multipoint(point_segment_strategy());
299 }
300 
BOOST_AUTO_TEST_CASE(test_all_multipoint_multilinestring)301 BOOST_AUTO_TEST_CASE( test_all_multipoint_multilinestring )
302 {
303     test_distance_multipoint_multilinestring(point_point_strategy()); // back-compatibility
304     test_distance_multipoint_multilinestring(point_segment_strategy());
305 }
306 
BOOST_AUTO_TEST_CASE(test_all_multipoint_segment)307 BOOST_AUTO_TEST_CASE( test_all_multipoint_segment )
308 {
309     test_distance_multipoint_segment(point_segment_strategy());
310 }
311 
BOOST_AUTO_TEST_CASE(test_all_empty_input_pointlike_linear)312 BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_linear )
313 {
314     test_more_empty_input_pointlike_linear
315         <
316             point_type
317         >(point_segment_strategy());
318 }
319