]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/line_interpolate.cpp
4 // Copyright (c) 2018, 2021, Oracle and/or its affiliates.
6 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9 // Licensed under the Boost Software License version 1.0.
10 // http://www.boost.org/users/license.html
13 #include <geometry_test_common.hpp>
15 #include <boost/geometry.hpp>
16 #include <boost/geometry/geometries/geometries.hpp>
18 #include <boost/geometry/algorithms/line_interpolate.hpp>
19 #include <boost/geometry/algorithms/length.hpp>
21 #include <boost/geometry/iterators/segment_iterator.hpp>
23 #include <boost/geometry/strategies/strategies.hpp>
25 #include <boost/geometry/io/wkt/wkt.hpp>
27 template <typename P
, typename Tag
= typename
bg::tag
<P
>::type
>
28 struct check_points
: bg::not_implemented
<Tag
>
32 struct check_points
<P
, bg::point_tag
>
34 static void apply(P
const& p0
, P
const& p1
)
36 double p00
= bg::get
<0>(p0
);
37 double p10
= bg::get
<0>(p1
);
39 BOOST_CHECK_CLOSE(p00
, p10
, 0.001);
41 double p01
= bg::get
<1>(p0
);
42 double p11
= bg::get
<1>(p1
);
44 BOOST_CHECK_CLOSE(p01
, p11
, 0.001);
49 struct check_points
<P
, bg::multi_point_tag
>
51 template <typename Range
>
52 static void apply(Range
const& r0
, Range
const& r1
)
55 typedef typename
boost::range_iterator
<Range
const>::type iterator_t
;
56 typedef typename
boost::range_value
<Range
const>::type point_t
;
58 std::size_t count0
= boost::size(r0
);
59 std::size_t count1
= boost::size(r1
);
61 BOOST_CHECK_MESSAGE(count0
== count1
, bg::wkt(r0
) << " != " << bg::wkt(r1
));
65 for (iterator_t it0
= boost::begin(r0
), it1
= boost::begin(r1
);
66 it0
< boost::end(r0
); it0
++, it1
++)
68 check_points
<point_t
>::apply(*it0
, *it1
);
74 template <typename G
, typename P
, typename S
>
75 inline void test(std::string
const& wkt1
,
77 std::string
const& wkt2
,
81 bg::read_wkt(wkt1
, g
);
84 bg::read_wkt(wkt2
, o
);
87 bg::line_interpolate(g
, fraction
* bg::length(g
), p1
, str
);
88 check_points
<P
>::apply(p1
, o
);
92 template <typename G
, typename P
>
93 inline void test(std::string
const& wkt1
,
95 std::string
const& wkt2
)
98 bg::read_wkt(wkt1
, g
);
101 bg::read_wkt(wkt2
, o
);
104 bg::line_interpolate(g
, fraction
* bg::length(g
), p1
);
105 check_points
<P
>::apply(p1
, o
);
108 template <typename G
, typename P
>
109 inline void test_distance(std::string
const& wkt1
,
111 std::string
const& wkt2
)
114 bg::read_wkt(wkt1
, g
);
117 bg::read_wkt(wkt2
, o
);
120 bg::line_interpolate(g
, distance
, p1
);
121 check_points
<P
>::apply(p1
, o
);
124 template <typename G
, typename P
, typename S
>
125 inline void test_distance(std::string
const& wkt1
,
127 std::string
const& wkt2
,
131 bg::read_wkt(wkt1
, g
);
134 bg::read_wkt(wkt2
, o
);
137 bg::line_interpolate(g
, distance
, p1
, str
);
138 check_points
<P
>::apply(p1
, o
);
141 std::string
const s
= "SEGMENT(1 1, 2 2)";
142 std::string
const l1
= "LINESTRING(1 1, 2 1, 2 2, 1 2, 1 3)";
143 std::string
const l2
= "LINESTRING(0 2, 5 2, 5 1, 20 1)";
144 std::string
const l00
= "LINESTRING()";
145 std::string
const l01
= "LINESTRING(1 1)";
146 std::string
const l02
= "LINESTRING(1 1, 1 1)";
148 void test_car_edge_cases()
150 typedef bg::model::point
<double, 2, bg::cs::cartesian
> P
;
151 typedef bg::model::multi_point
<P
> MP
;
152 typedef bg::model::linestring
<P
> LS
;
154 //negative input distance
155 test_distance
<LS
,P
>(l1
, -1, "POINT(1 1)");
156 test_distance
<LS
,MP
>(l1
, -1, "MULTIPOINT((1 1))");
158 //input distance longer than total length
159 test_distance
<LS
,P
>(l1
, 5, "POINT(1 3)");
160 test_distance
<LS
,MP
>(l1
, 5, "MULTIPOINT((1 3))");
162 //linestring with only one point
163 test_distance
<LS
,P
>(l01
, 1, "POINT(1 1)");
164 test_distance
<LS
,MP
>(l01
, 1, "MULTIPOINT((1 1))");
166 //linestring with two same points
167 test_distance
<LS
,P
>(l02
, 1, "POINT(1 1)");
168 test_distance
<LS
,MP
>(l02
, 1, "MULTIPOINT((1 1))");
173 test_distance
<LS
,P
>(l00
, 1, "POINT(1 1)");
175 catch(bg::empty_input_exception
const& )
179 BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" );
184 typedef bg::model::point
<double, 2, bg::cs::cartesian
> P
;
185 typedef bg::model::multi_point
<P
> MP
;
186 typedef bg::model::segment
<P
> S
;
187 typedef bg::model::linestring
<P
> LS
;
189 test
<S
,P
>(s
, 0, "POINT(1 1)");
190 test
<S
,P
>(s
, 0.5, "POINT(1.5 1.5)");
191 test
<S
,P
>(s
, 1, "POINT(2 2)");
193 test
<LS
,P
>(l1
, 0, "POINT(1 1)");
194 test
<LS
,P
>(l1
, 0.1, "POINT(1.4 1)");
195 test
<LS
,P
>(l1
, 0.2, "POINT(1.8 1)");
196 test
<LS
,P
>(l1
, 0.3, "POINT(2 1.2)");
197 test
<LS
,P
>(l1
, 0.4, "POINT(2 1.6)");
198 test
<LS
,P
>(l1
, 0.5, "POINT(2 2)");
199 test
<LS
,P
>(l1
, 0.6, "POINT(1.6 2)");
200 test
<LS
,P
>(l1
, 0.7, "POINT(1.2 2)");
201 test
<LS
,P
>(l1
, 0.8, "POINT(1 2.2)");
202 test
<LS
,P
>(l1
, 0.9, "POINT(1 2.6)");
203 test
<LS
,P
>(l1
, 1, "POINT(1 3)");
205 test
<LS
,MP
>(l1
, 0, "MULTIPOINT((1 1))");
206 // The following type of test is not robust;
207 // (1 3) could be missing due to floating point round off errors
208 //test<LS,MP>(l1, 0.1, "MULTIPOINT((1.4 1)(1.8 1)(2 1.2)(2 1.6)(2 2)(1.6 2)"
209 // "(1.2 2)(1 2.2)(1 2.6)(1 3))");
210 // Tests are more robust if you directly pass the distance
211 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)"
212 "(1.2 2)(1 2.2)(1 2.6)(1 3))");
213 test
<LS
,MP
>(l1
, 0.09, "MULTIPOINT((1.36 1)(1.72 1)(2 1.08)(2 1.44)(2 1.8)"
214 "(1.84 2)(1.48 2)(1.12 2)(1 2.24)(1 2.6)(1 2.96))");
215 test
<LS
,MP
>(l1
, 0.21, "MULTIPOINT((1.84 1)(2 1.68)(1.48 2)(1 2.36))");
216 test
<LS
,MP
>(l1
, 0.4, "MULTIPOINT((2 1.6)(1 2.2))");
217 test
<LS
,MP
>(l1
, 0.6, "MULTIPOINT((1.6 2))");
218 test
<LS
,MP
>(l1
, 1, "MULTIPOINT((1 3))");
223 typedef bg::model::point
<double, 2, bg::cs::spherical_equatorial
<bg::degree
> > P
;
224 typedef bg::model::multi_point
<P
> MP
;
225 typedef bg::model::segment
<P
> S
;
226 typedef bg::model::linestring
<P
> LS
;
228 test
<S
,P
>(s
, 0, "POINT(1 1)");
229 test
<S
,P
>(s
, 0.5, "POINT(1.4998857365615981 1.5000570914791198)");
230 test
<S
,P
>(s
, 1, "POINT(2 2)");
232 test
<LS
,P
>(l1
, 0, "POINT(1 1)");
233 test
<LS
,P
>(l1
, 0.1, "POINT(1.39998476912905323 1.0000365473536286)");
234 test
<LS
,P
>(l1
, 0.2, "POINT(1.79996953825810646 1.0000243679448551)");
235 test
<LS
,P
>(l1
, 0.3, "POINT(2 1.1999238595669637)");
236 test
<LS
,P
>(l1
, 0.4, "POINT(2 1.5998477098527744)");
237 test
<LS
,P
>(l1
, 0.5, "POINT(2 1.9997715601390484)");
238 test
<LS
,P
>(l1
, 0.6, "POINT(1.6000609543036084 2.0000730473928678)");
239 test
<LS
,P
>(l1
, 0.7, "POINT(1.1998933176222553 2.0000486811516014)");
240 test
<LS
,P
>(l1
, 0.8, "POINT(1 2.2001522994279883)");
241 test
<LS
,P
>(l1
, 0.9, "POINT(1 2.6000761497139444)");
242 test
<LS
,P
>(l1
, 1, "POINT(1 3)");
244 test
<LS
,MP
>(l1
, 0, "MULTIPOINT((1 1))");
245 test
<LS
,MP
>(l1
, 0.09, "MULTIPOINT((1.35999 1.00004)(1.71997 1.00003)"
246 "(2 1.07995)(2 1.43988)(2 1.79981)(1.84016 2.00004)"
247 "(1.48001 2.00008)(1.11986 2.00003)(1 2.24014)"
248 "(1 2.60008)(1 2.96001))");
249 test
<LS
,MP
>(l1
, 0.21, "MULTIPOINT((1.83997 1.00002)(2 1.67983)(1.48001 2.00008)(1 2.36012))");
250 test
<LS
,MP
>(l1
, 0.4, "MULTIPOINT((2 1.5998477098527744)(1 2.2001522994279883))");
251 test
<LS
,MP
>(l1
, 0.6, "MULTIPOINT((1.6000609543036084 2.0000730473928678))");
252 test
<LS
,MP
>(l1
, 1, "MULTIPOINT((1 3))");
254 test
<LS
,MP
>(l2
, 0.3, "MULTIPOINT((5.3014893312120446 1.0006787676128222)"
255 "(11.600850053156366 1.0085030143490989)"
256 "(17.9002174825842 1.0041514208039872))");
259 template <typename Strategy
>
260 void test_sph(Strategy str
)
262 typedef bg::model::point
<double, 2, bg::cs::spherical_equatorial
<bg::degree
> > P
;
263 typedef bg::model::segment
<P
> S
;
265 test_distance
<S
,P
>(s
, 0, "POINT(1 1)", str
);
266 test_distance
<S
,P
>(s
, 0.01, "POINT(1.4051065077123643 1.405268220524982)");
267 test_distance
<S
,P
>(s
, 0.01, "POINT(1.0040505023484179 1.0040529633262307)", str
);
268 test_distance
<S
,P
>(s
, 1, "POINT(1.4051065077123015 1.405268220524919)", str
);
269 test_distance
<S
,P
>(s
, 1, "POINT(2 2)");
270 test_distance
<S
,P
>(s
, 10, "POINT(2 2)");
273 template <typename Strategy
>
274 void test_geo(Strategy str
)
276 typedef bg::model::point
<double, 2, bg::cs::geographic
<bg::degree
> > P
;
277 typedef bg::model::multi_point
<P
> MP
;
278 typedef bg::model::segment
<P
> S
;
279 typedef bg::model::linestring
<P
> LS
;
281 test
<S
,P
>(s
, 0, "POINT(1 1)", str
);
282 test
<S
,P
>(s
, 0.5, "POINT(1.4998780900539985 1.5000558288006378)", str
);
283 test
<S
,P
>(s
, 1, "POINT(2 2)", str
);
285 test
<LS
,P
>(l1
, 0, "POINT(1 1)", str
);
286 test
<LS
,P
>(l1
, 0.1, "POINT(1.3986445638301882 1.0000367522730751)", str
);
287 test
<LS
,P
>(l1
, 0.2, "POINT(1.79728912766037641 1.0000247772611039)", str
);
288 test
<LS
,P
>(l1
, 0.3, "POINT(2 1.1972285554368427)", str
);
289 test
<LS
,P
>(l1
, 0.4, "POINT(2 1.598498298996567)", str
);
290 test
<LS
,P
>(l1
, 0.5, "POINT(2 1.9997664696834965)", str
);
291 test
<LS
,P
>(l1
, 0.6, "POINT(1.6013936980010324 2.0000734568388099)", str
);
292 test
<LS
,P
>(l1
, 0.7, "POINT(1.2025664628960846 2.0000494983098767)", str
);
293 test
<LS
,P
>(l1
, 0.8, "POINT(1 2.1974612279909937)", str
);
294 test
<LS
,P
>(l1
, 0.9, "POINT(1 2.5987263175375022)", str
);
295 test
<LS
,P
>(l1
, 1, "POINT(1 3)", str
);
297 test
<LS
,MP
>(l1
, 0, "MULTIPOINT((1 1))", str
);
298 test
<LS
,MP
>(l1
, 0.11, "MULTIPOINT((1.43851 1.00004)(1.87702 1.00002)(2 1.31761)"
299 "(2 1.75901)(1.80081 2.00005)(1.3621 2.00007)"
300 "(1 2.07708)(1 2.51847)(1 2.95986))", str
);
301 test
<LS
,MP
>(l1
, 0.21, "MULTIPOINT((1.83716 1.00002)(2 1.67875)(1.48176 2.00008)"
302 "(1 2.35796))", str
);
303 test
<LS
,MP
>(l1
, 0.4, "MULTIPOINT((2 1.598498298996567)(1 2.1974612279909937))", str
);
304 test
<LS
,MP
>(l1
, 0.6, "MULTIPOINT((1.6013936980010324 2.0000734568388099))", str
);
305 test
<LS
,MP
>(l1
, 1, "MULTIPOINT((1 3))", str
);
307 test
<LS
,MP
>(l2
, 0.3, "MULTIPOINT((5.306157814 1.0006937303)"
308 "(11.60351281 1.0085614548123072)"
309 "(17.90073492 1.004178475142552))", str
);
312 template <typename Strategy
>
313 void test_geo_non_standard_spheroid(Strategy str
)
315 typedef bg::model::point
<double, 2, bg::cs::geographic
<bg::degree
> > P
;
316 typedef bg::model::segment
<P
> S
;
318 test
<S
,P
>(s
, 0, "POINT(1 1)", str
);
319 test
<S
,P
>(s
, 0.5, "POINT(1.5127731436886724 1.5129021873759412)", str
);
320 test
<S
,P
>(s
, 1, "POINT(2 2)", str
);
323 int test_main(int, char* [])
326 test_car_edge_cases();
329 test_sph(bg::strategy::line_interpolate::spherical
<>(100));
331 typedef bg::srs::spheroid
<double> stype
;
333 test_geo(bg::strategy::line_interpolate::geographic
<bg::strategy::andoyer
>());
334 test_geo(bg::strategy::line_interpolate::geographic
<bg::strategy::thomas
>());
335 test_geo(bg::strategy::line_interpolate::geographic
<bg::strategy::vincenty
>());
337 test_geo_non_standard_spheroid(bg::strategy::line_interpolate::geographic
338 <bg::strategy::vincenty
>(stype(5000000,6000000)));