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_linear_linear
16 #endif
17 
18 #include <boost/test/included/unit_test.hpp>
19 
20 #include "test_distance_common.hpp"
21 
22 
23 typedef bg::model::point<double,2,bg::cs::cartesian>  point_type;
24 typedef bg::model::segment<point_type>                segment_type;
25 typedef bg::model::linestring<point_type>             linestring_type;
26 typedef bg::model::multi_linestring<linestring_type>  multi_linestring_type;
27 
28 namespace services = bg::strategy::distance::services;
29 typedef bg::default_distance_result<point_type>::type return_type;
30 
31 typedef bg::strategy::distance::projected_point<> point_segment_strategy;
32 
33 //===========================================================================
34 
35 template <typename Strategy>
test_distance_segment_segment(Strategy const & strategy)36 void test_distance_segment_segment(Strategy const& strategy)
37 {
38 #ifdef BOOST_GEOMETRY_TEST_DEBUG
39     std::cout << std::endl;
40     std::cout << "segment/segment distance tests" << std::endl;
41 #endif
42     typedef test_distance_of_geometries<segment_type, segment_type> tester;
43 
44     tester::apply("segment(0 0,10 0)",
45                   "segment(4 2,4 0.5)",
46                   return_type(0.5), return_type(0.25), strategy);
47 
48     tester::apply("segment(0 0,10 0)",
49                   "segment(4 2,4 -0.5)",
50                   return_type(0), return_type(0), strategy);
51 
52     tester::apply("segment(0 0,10 0)",
53                   "segment(4 2,0 0)",
54                   return_type(0), return_type(0), strategy);
55 
56     tester::apply("segment(0 0,10 0)",
57                   "segment(-2 3,1 2)",
58                   return_type(2), return_type(4), strategy);
59 }
60 
61 //===========================================================================
62 
63 template <typename Strategy>
test_distance_segment_linestring(Strategy const & strategy)64 void test_distance_segment_linestring(Strategy const& strategy)
65 {
66 #ifdef BOOST_GEOMETRY_TEST_DEBUG
67     std::cout << std::endl;
68     std::cout << "segment/linestring distance tests" << std::endl;
69 #endif
70     typedef test_distance_of_geometries<segment_type, linestring_type> tester;
71 
72     tester::apply("segment(-1 -1,-2 -2)",
73                   "linestring(2 1,1 2,4 0)",
74                   sqrt(12.5), 12.5, strategy);
75 
76     tester::apply("segment(1 1,2 2)",
77                   "linestring(2 1,1 2,4 0)",
78                   0, 0, strategy);
79 
80     tester::apply("segment(1 1,2 2)",
81                   "linestring(3 3,3 3)",
82                   sqrt(2.0), 2, strategy);
83 
84     tester::apply("segment(1 1,2 2)",
85                   "linestring(3 3)",
86                   sqrt(2.0), 2, strategy);
87 }
88 
89 //===========================================================================
90 
91 template <typename Strategy>
test_distance_linestring_linestring(Strategy const & strategy)92 void test_distance_linestring_linestring(Strategy const& strategy)
93 {
94 #ifdef BOOST_GEOMETRY_TEST_DEBUG
95     std::cout << std::endl;
96     std::cout << "linestring/linestring distance tests" << std::endl;
97 #endif
98     typedef test_distance_of_geometries
99         <
100             linestring_type, linestring_type
101         > tester;
102 
103     // It is not obvious that linestrings with only one point are valid
104     tester::apply("linestring(1 1)", "linestring(2 1)",
105                   1, 1, strategy);
106 
107     tester::apply("linestring(1 1,3 1)", "linestring(2 1)",
108                   0, 0, strategy);
109 
110     tester::apply("linestring(1 1)", "linestring(0 0,-2 0,2 -2,2 0)",
111                   sqrt(2.0), 2, strategy);
112 
113     tester::apply("linestring(1 1,1 1)", "linestring(2 1,2 1)",
114                   1, 1, strategy);
115 
116     tester::apply("linestring(1 1,1 1,1 1)", "linestring(2 1,2 1,2 1,2 1)",
117                   1, 1, strategy);
118 
119     tester::apply("linestring(1 1,3 1)", "linestring(2 1,2 1)",
120                   0, 0, strategy);
121 
122     tester::apply("linestring(1 1,1 1)", "linestring(0 0,-2 0,2 -2,2 0)",
123                   sqrt(2.0), 2, strategy);
124 
125     tester::apply("linestring(1 1,3 1)", "linestring(2 1, 4 1)",
126                   0, 0, strategy);
127 
128     tester::apply("linestring(1 1,2 2,3 3)", "linestring(2 1,1 2,4 0)",
129                   0, 0, strategy);
130 
131     tester::apply("linestring(1 1,2 2,3 3)", "linestring(1 0,2 -1,4 0)",
132                   1, 1, strategy);
133 
134     tester::apply("linestring(1 1,2 2,3 3)",
135                   "linestring(1 -10,2 0,2.1 -10,4 0)",
136                   sqrt(2.0), 2, strategy);
137 
138     tester::apply("linestring(1 1,2 2,3 3)",
139                   "linestring(1 -10,2 1.9,2.1 -10,4 0)",
140                   sqrt(0.005), 0.005, strategy);
141 
142     tester::apply("linestring(1 1,1 2)", "linestring(0 0,-2 0,2 -2,2 0)",
143                   sqrt(2.0), 2, strategy);
144 }
145 
146 //===========================================================================
147 
148 template <typename Strategy>
test_distance_segment_multilinestring(Strategy const & strategy)149 void test_distance_segment_multilinestring(Strategy const& strategy)
150 {
151 #ifdef BOOST_GEOMETRY_TEST_DEBUG
152     std::cout << std::endl;
153     std::cout << "segment/multilinestring distance tests" << std::endl;
154 #endif
155     typedef test_distance_of_geometries
156         <
157             segment_type, multi_linestring_type
158         > tester;
159 
160     tester::apply("segment(-1 -1,-2 -2)",
161                   "multilinestring((2 1,1 2),(4 0,4 10))",
162                   sqrt(12.5), 12.5, strategy);
163 
164     tester::apply("segment(1 1,2 2)",
165                   "multilinestring((2 1,1 2),(4 0,4 10))",
166                   0, 0, strategy);
167 
168     tester::apply("segment(1 1,2 2)",
169                   "multilinestring((2.5 0,4 0,5 0),(3 3,3 3))",
170                    sqrt(2.0), 2, strategy);
171 
172     tester::apply("segment(1 1,2 2)",
173                   "multilinestring((2.5 0),(3 3,3 3))",
174                    sqrt(2.0), 2, strategy);
175 
176     tester::apply("segment(1 1,2 2)",
177                   "multilinestring((2.5 0,4 0,5 0),(3 3))",
178                    sqrt(2.0), 2, strategy);
179 }
180 
181 //===========================================================================
182 
183 template <typename Strategy>
test_distance_linestring_multilinestring(Strategy const & strategy)184 void test_distance_linestring_multilinestring(Strategy const& strategy)
185 {
186 #ifdef BOOST_GEOMETRY_TEST_DEBUG
187     std::cout << std::endl;
188     std::cout << "linestring/multilinestring distance tests" << std::endl;
189 #endif
190 
191     typedef test_distance_of_geometries
192         <
193             linestring_type, multi_linestring_type
194         > tester;
195 
196     tester::apply("linestring(1 1,2 2,3 3)",
197                   "multilinestring((2 1,1 2,4 0),(1 -10,2 1.9,2.1 -10,4 0))",
198                   0, 0, strategy);
199 
200     tester::apply("linestring(1 1,2 2,3 3)",
201                   "multilinestring((1 -10,2 0,2.1 -10,4 0),(1 -10,2 1.9,2.1 -10,4 0))",
202                   sqrt(0.005), 0.005, strategy);
203 
204     tester::apply("linestring(1 1,2 2)",
205                   "multilinestring((2.5 0,4 0,5 0),(3 3,3 3))",
206                    sqrt(2.0), 2, strategy);
207 
208     tester::apply("linestring(2 2)",
209                   "multilinestring((2.5 0,4 0,5 0),(3 3,3 3))",
210                    sqrt(2.0), 2, strategy);
211 
212     tester::apply("linestring(1 1,2 2)",
213                   "multilinestring((2.5 0,4 0,5 0),(3 3))",
214                    sqrt(2.0), 2, strategy);
215 
216     tester::apply("linestring(1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9)",
217                   "multilinestring((2.5 0,4 0,5 0),(10 10,10 10))",
218                    sqrt(2.0), 2, strategy);
219 }
220 
221 //===========================================================================
222 
223 template <typename Strategy>
test_distance_multilinestring_multilinestring(Strategy const & strategy)224 void test_distance_multilinestring_multilinestring(Strategy const& strategy)
225 {
226 #ifdef BOOST_GEOMETRY_TEST_DEBUG
227     std::cout << std::endl;
228     std::cout << "multilinestring/multilinestring distance tests" << std::endl;
229 #endif
230 
231     typedef test_distance_of_geometries
232         <
233             multi_linestring_type, multi_linestring_type
234         > tester;
235 
236     tester::apply("multilinestring((0 0,0 1,1 1),(10 0,11 1,12 2))",
237                   "multilinestring((0.5 0.5,0.75 0.75),(11 0,11 7))",
238                   0, 0, strategy);
239 
240     tester::apply("multilinestring((0 0,0 1,1 1),(10 0,11 1,12 2))",
241                   "multilinestring((0.5 0.5,0.75 0.75),(11 0,11 0.9))",
242                   sqrt(0.005), 0.005, strategy);
243 
244     tester::apply("multilinestring((0 0,0 1,1 1),(10 0,11 1,12 2))",
245                   "multilinestring((0.5 0.5,0.75 0.75),(11.1 0,11.1 0.9))",
246                   sqrt(0.02), 0.02, strategy);
247 
248     tester::apply("multilinestring((0 0),(1 1))",
249                   "multilinestring((2 2),(3 3))",
250                   sqrt(2.0), 2, strategy);
251 }
252 
253 //===========================================================================
254 
255 template <typename Point, typename Strategy>
test_more_empty_input_linear_linear(Strategy const & strategy)256 void test_more_empty_input_linear_linear(Strategy const& strategy)
257 {
258 #ifdef BOOST_GEOMETRY_TEST_DEBUG
259     std::cout << std::endl;
260     std::cout << "testing on empty inputs... " << std::flush;
261 #endif
262     bg::model::linestring<Point> line_empty;
263     bg::model::multi_linestring<bg::model::linestring<Point> > multiline_empty;
264 
265     bg::model::linestring<Point> line =
266         from_wkt<bg::model::linestring<Point> >("linestring(0 0,1 1)");
267 
268     // 1st geometry is empty
269     test_empty_input(line_empty, line, strategy);
270     test_empty_input(multiline_empty, line, strategy);
271 
272     // 2nd geometry is empty
273     test_empty_input(line, line_empty, strategy);
274     test_empty_input(line, multiline_empty, strategy);
275 
276     // both geometries are empty
277     test_empty_input(line_empty, line_empty, strategy);
278     test_empty_input(line_empty, multiline_empty, strategy);
279     test_empty_input(multiline_empty, multiline_empty, strategy);
280 
281 #ifdef BOOST_GEOMETRY_TEST_DEBUG
282     std::cout << "done!" << std::endl;
283 #endif
284 }
285 
286 //===========================================================================
287 
BOOST_AUTO_TEST_CASE(test_all_segment_segment)288 BOOST_AUTO_TEST_CASE( test_all_segment_segment )
289 {
290     test_distance_segment_segment(point_segment_strategy());
291 }
292 
BOOST_AUTO_TEST_CASE(test_all_segment_linestring)293 BOOST_AUTO_TEST_CASE( test_all_segment_linestring )
294 {
295     test_distance_segment_linestring(point_segment_strategy());
296 }
297 
BOOST_AUTO_TEST_CASE(test_all_linestring_linestring)298 BOOST_AUTO_TEST_CASE( test_all_linestring_linestring )
299 {
300     test_distance_linestring_linestring(point_segment_strategy());
301 }
302 
BOOST_AUTO_TEST_CASE(test_all_segment_multilinestring)303 BOOST_AUTO_TEST_CASE( test_all_segment_multilinestring )
304 {
305     test_distance_segment_multilinestring(point_segment_strategy());
306 }
307 
BOOST_AUTO_TEST_CASE(test_all_linestring_multilinestring)308 BOOST_AUTO_TEST_CASE( test_all_linestring_multilinestring )
309 {
310     test_distance_linestring_multilinestring(point_segment_strategy());
311 }
312 
BOOST_AUTO_TEST_CASE(test_all_multilinestring_multilinestring)313 BOOST_AUTO_TEST_CASE( test_all_multilinestring_multilinestring )
314 {
315     test_distance_multilinestring_multilinestring(point_segment_strategy());
316 }
317 
BOOST_AUTO_TEST_CASE(test_all_empty_input_linear_linear)318 BOOST_AUTO_TEST_CASE( test_all_empty_input_linear_linear )
319 {
320     test_more_empty_input_linear_linear<point_type>(point_segment_strategy());
321 }
322