]> git.proxmox.com Git - ceph.git/blame_incremental - ceph/src/boost/libs/geometry/test/strategies/douglas_peucker.cpp
bump version to 19.2.0-pve1
[ceph.git] / ceph / src / boost / libs / geometry / test / strategies / douglas_peucker.cpp
... / ...
CommitLineData
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2// Unit Test
3
4// Copyright (c) 2015-2021, Oracle and/or its affiliates.
5// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7
8// Licensed under the Boost Software License version 1.0.
9// http://www.boost.org/users/license.html
10
11#ifndef BOOST_TEST_MODULE
12#define BOOST_TEST_MODULE test_douglas_peucker
13#endif
14
15#ifdef BOOST_GEOMETRY_TEST_DEBUG
16#ifndef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
17#define BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
18#endif
19#endif
20
21#include <iostream>
22#include <iterator>
23#include <sstream>
24#include <string>
25
26#include <boost/core/ignore_unused.hpp>
27#include <boost/test/included/unit_test.hpp>
28#include <boost/tuple/tuple.hpp>
29
30#include <boost/geometry/algorithms/comparable_distance.hpp>
31#include <boost/geometry/algorithms/equals.hpp>
32#include <boost/geometry/algorithms/simplify.hpp>
33
34#include <boost/geometry/core/point_type.hpp>
35#include <boost/geometry/core/tags.hpp>
36
37#include <boost/geometry/io/wkt/wkt.hpp>
38#include <boost/geometry/io/dsv/write.hpp>
39
40#include <boost/geometry/strategies/distance.hpp>
41#include <boost/geometry/strategies/strategies.hpp>
42
43#include <boost/geometry/geometries/geometries.hpp>
44#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
45#include <boost/geometry/geometries/register/multi_point.hpp>
46
47
48namespace bg = ::boost::geometry;
49namespace services = bg::strategy::distance::services;
50
51typedef boost::tuple<double, double> tuple_point_type;
52typedef std::vector<tuple_point_type> tuple_multi_point_type;
53
54BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
55BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type)
56BOOST_GEOMETRY_REGISTER_MULTI_POINT_TEMPLATED(std::vector)
57
58template <typename CoordinateType>
59struct simplify_default_strategy
60{
61 typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
62 typedef typename bg::strategies::simplify::services::default_strategy
63 <
64 point_type
65 >::type type;
66};
67
68template <typename CoordinateType>
69struct simplify_regular_strategy
70{
71 typedef bg::strategies::simplify::cartesian<> type;
72};
73
74template <typename CoordinateType>
75struct simplify_comparable_strategy
76{
77 typedef bg::strategies::distance::detail::comparable
78 <
79 bg::strategies::simplify::cartesian<>
80 > type;
81};
82
83
84
85template <typename Geometry>
86inline Geometry from_wkt(std::string const& wkt)
87{
88 Geometry geometry;
89 bg::read_wkt(wkt, geometry);
90 return geometry;
91}
92
93template <typename Iterator>
94inline std::ostream& print_point_range(std::ostream& os,
95 Iterator first,
96 Iterator beyond,
97 std::string const& header)
98{
99 os << header << "(";
100 for (Iterator it = first; it != beyond; ++it)
101 {
102 os << " " << bg::dsv(*it);
103 }
104 os << " )";
105 return os;
106}
107
108
109struct equals
110{
111 template <typename Iterator1, typename Iterator2>
112 static inline bool apply(Iterator1 begin1, Iterator1 end1,
113 Iterator2 begin2, Iterator2 end2)
114 {
115 std::size_t num_points1 = std::distance(begin1, end1);
116 std::size_t num_points2 = std::distance(begin2, end2);
117
118 if ( num_points1 != num_points2 )
119 {
120 return false;
121 }
122
123 Iterator1 it1 = begin1;
124 Iterator2 it2 = begin2;
125 for (; it1 != end1; ++it1, ++it2)
126 {
127 if ( !bg::equals(*it1, *it2) )
128 {
129 return false;
130 }
131 }
132 return true;
133 }
134
135 template <typename Range1, typename Range2>
136 static inline bool apply(Range1 const& range1, Range2 const& range2)
137 {
138 return apply(boost::begin(range1), boost::end(range1),
139 boost::begin(range2), boost::end(range2));
140 }
141};
142
143
144
145
146template <typename Geometry>
147struct test_one_case
148{
149 using point_type = typename bg::point_type<Geometry>::type;
150
151 template <typename Strategy>
152 static inline void apply(std::string const& case_id,
153 std::string const& wkt,
154 double max_distance,
155 Strategy const& strategy,
156 std::initializer_list<point_type> const& expected_result)
157 {
158 std::vector<point_type> result;
159
160 Geometry geometry = from_wkt<Geometry>(wkt);
161
162 std::string typeid_name
163 = typeid(typename bg::coordinate_type<point_type>::type).name();
164
165#ifdef BOOST_GEOMETRY_TEST_DEBUG
166 std::cout << case_id << " - " << typeid_name
167 << std::endl;
168 std::cout << wkt << std::endl;
169#endif
170
171 bg::detail::simplify::douglas_peucker::apply(
172 geometry, std::back_inserter(result), max_distance, strategy);
173
174#ifdef BOOST_GEOMETRY_TEST_DEBUG
175 print_point_range(std::cout, boost::begin(result), boost::end(result),
176 "output: ");
177 std::cout << std::endl << std::endl;
178#endif
179 std::stringstream stream_expected;
180 print_point_range(stream_expected, boost::begin(expected_result),
181 boost::end(expected_result),
182 "");
183 std::stringstream stream_detected;
184 print_point_range(stream_detected, boost::begin(result),
185 boost::end(result),
186 "");
187
188 BOOST_CHECK_MESSAGE(equals::apply(result, expected_result),
189 "case id: " << case_id << " - " << typeid_name
190 << ", geometry: " << wkt
191 << ", Expected: " << stream_expected.str()
192 << " - Detected: " << stream_detected.str());
193
194#ifdef BOOST_GEOMETRY_TEST_DEBUG
195 std::cout << "---------------" << std::endl;
196 std::cout << "---------------" << std::endl;
197 std::cout << std::endl << std::endl;
198#endif
199 }
200};
201
202
203template <typename CoordinateType, typename Strategy>
204inline void test_with_strategy(std::string label)
205{
206 std::cout.precision(20);
207 Strategy strategy;
208
209 typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
210 typedef bg::model::linestring<point_type> linestring_type;
211 typedef bg::model::segment<point_type> segment_type;
212 typedef test_one_case<linestring_type> tester;
213
214 label = " (" + label + ")";
215
216 {
217 point_type const p1(-6,-13), p2(0,-15);
218 segment_type const s(point_type(12,-3), point_type(-12,5));
219
220 if (bg::comparable_distance(p1, s) >= bg::comparable_distance(p2, s))
221 {
222 tester::apply("l01c1" + label,
223 "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -15,-12 5)",
224 10,
225 strategy,
226 {{12,-3},{4,8},{-6,-13},{-12,5}}
227 );
228 }
229 else
230 {
231 tester::apply("l01c2" + label,
232 "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -15,-12 5)",
233 10,
234 strategy,
235 {{12,-3},{4,8},{-6,-13},{-9,4},{0,-15},{-12,5}}
236 );
237 }
238 }
239
240 tester::apply("l02" + label,
241 "LINESTRING(-6 -13,-9 4,0 -15,-12 5)",
242 10,
243 strategy,
244 {{-6,-13},{-12,5}}
245 );
246
247 tester::apply("l03" + label,
248 "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -14,-12 5)",
249 10,
250 strategy,
251 {{12,-3},{4,8},{-6,-13},{-12,5}}
252 );
253
254 tester::apply("l04" + label,
255 "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -14,-12 5)",
256 14,
257 strategy,
258 {{12,-3},{-6,-13},{-12,5}}
259 );
260
261 {
262 segment_type const s(point_type(0,-1), point_type(5,-4));
263 point_type const p1(5,-1), p2(0,-4);
264
265#ifdef BOOST_GEOMETRY_TEST_DEBUG
266 bool d_larger_first = (bg::distance(p1, s) > bg::distance(p2, s));
267 bool d_larger_second = (bg::distance(p1, s) < bg::distance(p2, s));
268 bool cd_larger_first
269 = (bg::comparable_distance(p1, s) > bg::comparable_distance(p2, s));
270 bool cd_larger_second
271 = (bg::comparable_distance(p1, s) < bg::comparable_distance(p2, s));
272
273 std::cout << "segment: " << bg::dsv(s) << std::endl;
274 std::cout << "distance from " << bg::dsv(p1) << ": "
275 << bg::distance(p1, s) << std::endl;
276 std::cout << "comp. distance from " << bg::dsv(p1) << ": "
277 << bg::comparable_distance(p1, s) << std::endl;
278 std::cout << "distance from " << bg::dsv(p2) << ": "
279 << bg::distance(p2, s) << std::endl;
280 std::cout << "comp. distance from " << bg::dsv(p2) << ": "
281 << bg::comparable_distance(p2, s) << std::endl;
282 std::cout << "larger distance from "
283 << (d_larger_first ? "first" : (d_larger_second ? "second" : "equal"))
284 << std::endl;
285 std::cout << "larger comp. distance from "
286 << (cd_larger_first ? "first" : (cd_larger_second ? "second" : "equal"))
287 << std::endl;
288 std::cout << "difference of distances: "
289 << (bg::distance(p1, s) - bg::distance(p2, s))
290 << std::endl;
291 std::cout << "difference of comp. distances: "
292 << (bg::comparable_distance(p1, s) - bg::comparable_distance(p2, s))
293 << std::endl;
294#endif
295
296 std::string wkt =
297 "LINESTRING(0 0,5 0,0 -1,5 -1,0 -2,5 -2,0 -3,5 -3,0 -4,5 -4,0 0)";
298
299 if (bg::comparable_distance(p1, s) >= bg::comparable_distance(p2, s))
300 {
301 tester::apply("l05c1" + label,
302 wkt,
303 1,
304 strategy,
305 {{0,0},{5,0},{0,-1},{5,-1},{0,-2},{5,-2},{0,-3},{5,-4},{0,0}}
306 );
307 tester::apply("l05c1a" + label,
308 wkt,
309 2,
310 strategy,
311 {{0,0},{5,0},{0,-1},{5,-1},{0,-2},{5,-4},{0,0}}
312 );
313 }
314 else
315 {
316 tester::apply("l05c2" + label,
317 wkt,
318 1,
319 strategy,
320 {{0,0},{5,0},{0,-1},{5,-1},{0,-2},{5,-2},{0,-4},{5,-4},{0,0}}
321 );
322 tester::apply("l05c2a" + label,
323 wkt,
324 2,
325 strategy,
326 {{0,0},{5,0},{0,-1},{5,-1},{0,-4},{5,-4},{0,0}}
327 );
328 }
329 }
330
331#ifdef BOOST_GEOMETRY_TEST_DEBUG
332 std::cout << std::endl;
333 std::cout << std::endl;
334 std::cout << "*************************************************";
335 std::cout << std::endl;
336 std::cout << std::endl;
337#endif
338}
339
340
341BOOST_AUTO_TEST_CASE( test_default_strategy )
342{
343 test_with_strategy<int, simplify_default_strategy<int>::type>("i");
344 test_with_strategy<float, simplify_default_strategy<float>::type>("f");
345 test_with_strategy<double, simplify_default_strategy<double>::type>("d");
346 test_with_strategy
347 <
348 long double,
349 simplify_default_strategy<long double>::type
350 >("ld");
351}
352
353BOOST_AUTO_TEST_CASE( test_with_regular_distance_strategy )
354{
355 test_with_strategy
356 <
357 int,
358 simplify_regular_strategy<int>::type
359 >("i");
360
361 test_with_strategy
362 <
363 float,
364 simplify_regular_strategy<float>::type
365 >("f");
366
367 test_with_strategy
368 <
369 double,
370 simplify_regular_strategy<double>::type
371 >("d");
372 test_with_strategy
373 <
374 long double,
375 simplify_regular_strategy<long double>::type
376 >("ld");
377}
378
379BOOST_AUTO_TEST_CASE( test_with_comparable_distance_strategy )
380{
381 test_with_strategy
382 <
383 int,
384 simplify_comparable_strategy<int>::type
385 >("i");
386 test_with_strategy
387 <
388 float,
389 simplify_comparable_strategy<float>::type
390 >("f");
391 test_with_strategy
392 <
393 double,
394 simplify_comparable_strategy<double>::type
395 >("d");
396 test_with_strategy
397 <
398 long double,
399 simplify_comparable_strategy<long double>::type
400 >("ld");
401}