]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/line_interpolate.cpp
4 // Copyright (c) 2018, Oracle and/or its affiliates.
6 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
12 #include <geometry_test_common.hpp>
14 #include <boost/geometry.hpp>
15 #include <boost/geometry/geometries/geometries.hpp>
17 #include <boost/geometry/algorithms/line_interpolate.hpp>
18 #include <boost/geometry/algorithms/length.hpp>
20 #include <boost/geometry/iterators/segment_iterator.hpp>
22 #include <boost/geometry/strategies/strategies.hpp>
24 #include <boost/geometry/io/wkt/wkt.hpp>
26 template <typename P
, typename Tag
= typename
bg::tag
<P
>::type
>
27 struct check_points
: bg::not_implemented
<Tag
>
31 struct check_points
<P
, bg::point_tag
>
33 static void apply(P
const& p0
, P
const& p1
)
35 double p00
= bg::get
<0>(p0
);
36 double p10
= bg::get
<0>(p1
);
38 BOOST_CHECK_CLOSE(p00
, p10
, 0.001);
40 double p01
= bg::get
<1>(p0
);
41 double p11
= bg::get
<1>(p1
);
43 BOOST_CHECK_CLOSE(p01
, p11
, 0.001);
48 struct check_points
<P
, bg::multi_point_tag
>
50 template <typename Range
>
51 static void apply(Range
const& r0
, Range
const& r1
)
54 typedef typename
boost::range_iterator
<Range
const>::type iterator_t
;
55 typedef typename
boost::range_value
<Range
const>::type point_t
;
57 std::size_t count0
= boost::size(r0
);
58 std::size_t count1
= boost::size(r1
);
60 BOOST_CHECK_MESSAGE(count0
== count1
, bg::wkt(r0
) << " != " << bg::wkt(r1
));
64 for (iterator_t it0
= boost::begin(r0
), it1
= boost::begin(r1
);
65 it0
< boost::end(r0
); it0
++, it1
++)
67 check_points
<point_t
>::apply(*it0
, *it1
);
73 template <typename G
, typename P
, typename S
>
74 inline void test(std::string
const& wkt1
,
76 std::string
const& wkt2
,
80 bg::read_wkt(wkt1
, g
);
83 bg::read_wkt(wkt2
, o
);
86 bg::line_interpolate(g
, fraction
* bg::length(g
), p1
, str
);
87 check_points
<P
>::apply(p1
, o
);
91 template <typename G
, typename P
>
92 inline void test(std::string
const& wkt1
,
94 std::string
const& wkt2
)
97 bg::read_wkt(wkt1
, g
);
100 bg::read_wkt(wkt2
, o
);
103 bg::line_interpolate(g
, fraction
* bg::length(g
), p1
);
104 check_points
<P
>::apply(p1
, o
);
107 template <typename G
, typename P
>
108 inline void test_distance(std::string
const& wkt1
,
110 std::string
const& wkt2
)
113 bg::read_wkt(wkt1
, g
);
116 bg::read_wkt(wkt2
, o
);
119 bg::line_interpolate(g
, distance
, p1
);
120 check_points
<P
>::apply(p1
, o
);
123 template <typename G
, typename P
, typename S
>
124 inline void test_distance(std::string
const& wkt1
,
126 std::string
const& wkt2
,
130 bg::read_wkt(wkt1
, g
);
133 bg::read_wkt(wkt2
, o
);
136 bg::line_interpolate(g
, distance
, p1
, str
);
137 check_points
<P
>::apply(p1
, o
);
140 std::string
const s
= "SEGMENT(1 1, 2 2)";
141 std::string
const l1
= "LINESTRING(1 1, 2 1, 2 2, 1 2, 1 3)";
142 std::string
const l2
= "LINESTRING(0 2, 5 2, 5 1, 20 1)";
143 std::string
const l00
= "LINESTRING()";
144 std::string
const l01
= "LINESTRING(1 1)";
145 std::string
const l02
= "LINESTRING(1 1, 1 1)";
147 void test_car_edge_cases()
149 typedef bg::model::point
<double, 2, bg::cs::cartesian
> P
;
150 typedef bg::model::multi_point
<P
> MP
;
151 typedef bg::model::linestring
<P
> LS
;
153 //negative input distance
154 test_distance
<LS
,P
>(l1
, -1, "POINT(1 1)");
155 test_distance
<LS
,MP
>(l1
, -1, "MULTIPOINT((1 1))");
157 //input distance longer than total length
158 test_distance
<LS
,P
>(l1
, 5, "POINT(1 3)");
159 test_distance
<LS
,MP
>(l1
, 5, "MULTIPOINT((1 3))");
161 //linestring with only one point
162 test_distance
<LS
,P
>(l01
, 1, "POINT(1 1)");
163 test_distance
<LS
,MP
>(l01
, 1, "MULTIPOINT((1 1))");
165 //linestring with two same points
166 test_distance
<LS
,P
>(l02
, 1, "POINT(1 1)");
167 test_distance
<LS
,MP
>(l02
, 1, "MULTIPOINT((1 1))");
172 test_distance
<LS
,P
>(l00
, 1, "POINT(1 1)");
174 catch(bg::empty_input_exception
const& )
178 BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" );
183 typedef bg::model::point
<double, 2, bg::cs::cartesian
> P
;
184 typedef bg::model::multi_point
<P
> MP
;
185 typedef bg::model::segment
<P
> S
;
186 typedef bg::model::linestring
<P
> LS
;
188 test
<S
,P
>(s
, 0, "POINT(1 1)");
189 test
<S
,P
>(s
, 0.5, "POINT(1.5 1.5)");
190 test
<S
,P
>(s
, 1, "POINT(2 2)");
192 test
<LS
,P
>(l1
, 0, "POINT(1 1)");
193 test
<LS
,P
>(l1
, 0.1, "POINT(1.4 1)");
194 test
<LS
,P
>(l1
, 0.2, "POINT(1.8 1)");
195 test
<LS
,P
>(l1
, 0.3, "POINT(2 1.2)");
196 test
<LS
,P
>(l1
, 0.4, "POINT(2 1.6)");
197 test
<LS
,P
>(l1
, 0.5, "POINT(2 2)");
198 test
<LS
,P
>(l1
, 0.6, "POINT(1.6 2)");
199 test
<LS
,P
>(l1
, 0.7, "POINT(1.2 2)");
200 test
<LS
,P
>(l1
, 0.8, "POINT(1 2.2)");
201 test
<LS
,P
>(l1
, 0.9, "POINT(1 2.6)");
202 test
<LS
,P
>(l1
, 1, "POINT(1 3)");
204 test
<LS
,MP
>(l1
, 0, "MULTIPOINT((1 1))");
205 //(1 3) missing due to floating point round off errors
206 test
<LS
,MP
>(l1
, 0.1, "MULTIPOINT((1.4 1)(1.8 1)(2 1.2)(2 1.6)(2 2)(1.6 2)\
207 (1.2 2)(1 2.2)(1 2.6))");
208 //(1 3) is not missing if you directly pass the distance
209 test_distance
<LS
,MP
>(l1
, 0.4, "MULTIPOINT((1.4 1)(1.8 1)(2 1.2)(2 1.6)(2 2)(1.6 2)\
210 (1.2 2)(1 2.2)(1 2.6)(1 3))");
211 test
<LS
,MP
>(l1
, 0.2, "MULTIPOINT((1.8 1)(2 1.6)(1.6 2)(1 2.2))");//(1 3) missing
212 test
<LS
,MP
>(l1
, 0.4, "MULTIPOINT((2 1.6)(1 2.2))");
213 test
<LS
,MP
>(l1
, 0.5, "MULTIPOINT((2 2)(1 3))");
214 test
<LS
,MP
>(l1
, 0.6, "MULTIPOINT((1.6 2))");
215 test
<LS
,MP
>(l1
, 1, "MULTIPOINT((1 3))");
220 typedef bg::model::point
<double, 2, bg::cs::spherical_equatorial
<bg::degree
> > P
;
221 typedef bg::model::multi_point
<P
> MP
;
222 typedef bg::model::segment
<P
> S
;
223 typedef bg::model::linestring
<P
> LS
;
225 test
<S
,P
>(s
, 0, "POINT(1 1)");
226 test
<S
,P
>(s
, 0.5, "POINT(1.4998857365615981 1.5000570914791198)");
227 test
<S
,P
>(s
, 1, "POINT(2 2)");
229 test
<LS
,P
>(l1
, 0, "POINT(1 1)");
230 test
<LS
,P
>(l1
, 0.1, "POINT(1.39998476912905323 1.0000365473536286)");
231 test
<LS
,P
>(l1
, 0.2, "POINT(1.79996953825810646 1.0000243679448551)");
232 test
<LS
,P
>(l1
, 0.3, "POINT(2 1.1999238595669637)");
233 test
<LS
,P
>(l1
, 0.4, "POINT(2 1.5998477098527744)");
234 test
<LS
,P
>(l1
, 0.5, "POINT(2 1.9997715601390484)");
235 test
<LS
,P
>(l1
, 0.6, "POINT(1.6000609543036084 2.0000730473928678)");
236 test
<LS
,P
>(l1
, 0.7, "POINT(1.1998933176222553 2.0000486811516014)");
237 test
<LS
,P
>(l1
, 0.8, "POINT(1 2.2001522994279883)");
238 test
<LS
,P
>(l1
, 0.9, "POINT(1 2.6000761497139444)");
239 test
<LS
,P
>(l1
, 1, "POINT(1 3)");
241 test
<LS
,MP
>(l1
, 0, "MULTIPOINT((1 1))");
242 test
<LS
,MP
>(l1
, 0.1, "MULTIPOINT((1.39998476912905323 1.0000365473536286)\
243 (1.79996953825810646 1.0000243679448551)\
244 (2 1.1999238595669637)\
245 (2 1.5998477098527744)\
246 (2 1.9997715601385837)\
247 (1.6000609543036084 2.0000730473928678)\
248 (1.1998933176222553 2.0000486811516014)\
249 (1 2.2001522994279883)\
250 (1 2.6000761497139444)\
252 test
<LS
,MP
>(l1
, 0.2, "MULTIPOINT((1.79996953825810646 1.0000243679448551)\
253 (2 1.5998477098527744)\
254 (1.6000609543036084 2.0000730473928678)\
255 (1 2.2001522994279883)\
257 test
<LS
,MP
>(l1
, 0.4, "MULTIPOINT((2 1.5998477098527744)(1 2.2001522994279883))");
258 test
<LS
,MP
>(l1
, 0.5, "MULTIPOINT((2 1.9997715601385837)(1 3))");
259 test
<LS
,MP
>(l1
, 0.6, "MULTIPOINT((1.6000609543036084 2.0000730473928678))");
260 test
<LS
,MP
>(l1
, 1, "MULTIPOINT((1 3))");
262 test
<LS
,MP
>(l2
, 0.3, "MULTIPOINT((5.3014893312120446 1.0006787676128222)\
263 (11.600850053156366 1.0085030143490989)\
264 (17.9002174825842 1.0041514208039872))");
268 template <typename Strategy
>
269 void test_sph(Strategy str
)
271 typedef bg::model::point
<double, 2, bg::cs::spherical_equatorial
<bg::degree
> > P
;
272 typedef bg::model::segment
<P
> S
;
274 test_distance
<S
,P
>(s
, 0, "POINT(1 1)", str
);
275 test_distance
<S
,P
>(s
, 0.01, "POINT(1.4051065077123643 1.405268220524982)");
276 test_distance
<S
,P
>(s
, 0.01, "POINT(1.0040505023484179 1.0040529633262307)", str
);
277 test_distance
<S
,P
>(s
, 1, "POINT(1.4051065077123015 1.405268220524919)", str
);
278 test_distance
<S
,P
>(s
, 1, "POINT(2 2)");
279 test_distance
<S
,P
>(s
, 10, "POINT(2 2)");
282 template <typename Strategy
>
283 void test_geo(Strategy str
)
285 typedef bg::model::point
<double, 2, bg::cs::geographic
<bg::degree
> > P
;
286 typedef bg::model::multi_point
<P
> MP
;
287 typedef bg::model::segment
<P
> S
;
288 typedef bg::model::linestring
<P
> LS
;
290 test
<S
,P
>(s
, 0, "POINT(1 1)", str
);
291 test
<S
,P
>(s
, 0.5, "POINT(1.4998780900539985 1.5000558288006378)", str
);
292 test
<S
,P
>(s
, 1, "POINT(2 2)", str
);
294 test
<LS
,P
>(l1
, 0, "POINT(1 1)", str
);
295 test
<LS
,P
>(l1
, 0.1, "POINT(1.3986445638301882 1.0000367522730751)", str
);
296 test
<LS
,P
>(l1
, 0.2, "POINT(1.79728912766037641 1.0000247772611039)", str
);
297 test
<LS
,P
>(l1
, 0.3, "POINT(2 1.1972285554368427)", str
);
298 test
<LS
,P
>(l1
, 0.4, "POINT(2 1.598498298996567)", str
);
299 test
<LS
,P
>(l1
, 0.5, "POINT(2 1.9997664696834965)", str
);
300 test
<LS
,P
>(l1
, 0.6, "POINT(1.6013936980010324 2.0000734568388099)", str
);
301 test
<LS
,P
>(l1
, 0.7, "POINT(1.2025664628960846 2.0000494983098767)", str
);
302 test
<LS
,P
>(l1
, 0.8, "POINT(1 2.1974612279909937)", str
);
303 test
<LS
,P
>(l1
, 0.9, "POINT(1 2.5987263175375022)", str
);
304 test
<LS
,P
>(l1
, 1, "POINT(1 3)", str
);
306 test
<LS
,MP
>(l1
, 0, "MULTIPOINT((1 1))", str
);
308 //adnoyer is missing the last point in the following cases
309 // of linestrings due to inaccuracy
310 if (!boost::is_same
<Strategy
, bg::strategy::line_interpolate::geographic
311 <bg::strategy::andoyer
> >::value
)
313 test
<LS
,MP
>(l1
, 0.1, "MULTIPOINT((1.3986445638301882 1.0000367522730751)\
314 (1.79728912766037641 1.0000247772582571)\
315 (2 1.1972285554368427)\
316 (2 1.598498298996567)\
317 (2 1.9997664696834965)\
318 (1.6013936980010324 2.0000734568388099)\
319 (1.2025664628960846 2.0000495003440779)\
320 (1 2.1974612279909937)\
321 (1 2.5987263175375022)\
324 test
<LS
,MP
>(l1
, 0.2, "MULTIPOINT((1.79728912766037641 1.0000247772613331)\
325 (2 1.598498298996567)\
326 (1.6013936980010324 2.0000734568388099)\
327 (1 2.1974612279909937)\
330 test
<LS
,MP
>(l1
, 0.4, "MULTIPOINT((2 1.598498298996567)(1 2.1974612279909937))", str
);
331 test
<LS
,MP
>(l1
, 0.5, "MULTIPOINT((2 1.9997664696834965)(1 3))", str
);
332 test
<LS
,MP
>(l1
, 0.6, "MULTIPOINT((1.6013936980010324 2.0000734568388099))", str
);
333 test
<LS
,MP
>(l1
, 1, "MULTIPOINT((1 3))", str
);
335 test
<LS
,MP
>(l2
, 0.3, "MULTIPOINT((5.306157814 1.0006937303)\
336 (11.60351281 1.0085614548123072)\
337 (17.90073492 1.004178475142552))", str
);
340 template <typename Strategy
>
341 void test_geo_non_standard_spheroid(Strategy str
)
343 typedef bg::model::point
<double, 2, bg::cs::geographic
<bg::degree
> > P
;
344 typedef bg::model::segment
<P
> S
;
346 test
<S
,P
>(s
, 0, "POINT(1 1)", str
);
347 test
<S
,P
>(s
, 0.5, "POINT(1.5127731436886724 1.5129021873759412)", str
);
348 test
<S
,P
>(s
, 1, "POINT(2 2)", str
);
351 int test_main(int, char* [])
354 test_car_edge_cases();
357 test_sph(bg::strategy::line_interpolate::spherical
<>(100));
359 typedef bg::srs::spheroid
<double> stype
;
361 test_geo(bg::strategy::line_interpolate::geographic
<bg::strategy::andoyer
>());
362 test_geo(bg::strategy::line_interpolate::geographic
<bg::strategy::thomas
>());
363 test_geo(bg::strategy::line_interpolate::geographic
<bg::strategy::vincenty
>());
365 test_geo_non_standard_spheroid(bg::strategy::line_interpolate::geographic
366 <bg::strategy::vincenty
>(stype(5000000,6000000)));