]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/densify.cpp
4 // Copyright (c) 2017-2021, Oracle and/or its affiliates.
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
12 #include <boost/variant/variant.hpp>
14 #include <geometry_test_common.hpp>
16 #include <boost/geometry/geometries/geometries.hpp>
18 #include <boost/geometry/algorithms/densify.hpp>
19 #include <boost/geometry/algorithms/length.hpp>
20 #include <boost/geometry/algorithms/num_points.hpp>
21 #include <boost/geometry/algorithms/perimeter.hpp>
23 #include <boost/geometry/iterators/segment_iterator.hpp>
25 #include <boost/geometry/strategies/cartesian/densify.hpp>
26 #include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
27 #include <boost/geometry/strategies/geographic/densify.hpp>
28 #include <boost/geometry/strategies/geographic/distance.hpp>
29 #include <boost/geometry/strategies/spherical/densify.hpp>
30 #include <boost/geometry/strategies/spherical/distance_haversine.hpp>
32 #include <boost/geometry/io/wkt/wkt.hpp>
37 template <typename G
, typename S
>
38 void operator()(G
const& g
, G
const& o
, S
const& s
) const
40 double d1
= bg::length(g
, s
);
41 double d2
= bg::length(o
, s
);
43 BOOST_CHECK_CLOSE(d1
, d2
, 0.0001);
47 struct check_perimeters
49 template <typename G
, typename S
>
50 void operator()(G
const& g
, G
const& o
, S
const& s
) const
52 double d1
= bg::perimeter(g
, s
);
53 double d2
= bg::perimeter(o
, s
);
55 BOOST_CHECK_CLOSE(d1
, d2
, 0.0001);
59 template <typename G
, typename DistS
>
60 double inline shortest_length(G
const& g
, DistS
const& dist_s
)
62 double min_len
= (std::numeric_limits
<double>::max
)();
63 for (bg::segment_iterator
<G
const> it
= bg::segments_begin(g
);
64 it
!= bg::segments_end(g
); ++it
)
66 double len
= bg::length(*it
, dist_s
);
67 min_len
= (std::min
)(min_len
, len
);
72 template <typename G
, typename DistS
>
73 double inline greatest_length(G
const& o
, DistS
const& dist_s
)
76 for (bg::segment_iterator
<G
const> it
= bg::segments_begin(o
);
77 it
!= bg::segments_end(o
); ++it
)
79 double len
= bg::length(*it
, dist_s
);
80 max_len
= (std::max
)(max_len
, len
);
85 template <typename G
, typename CSTag
= typename
bg::cs_tag
<G
>::type
>
90 struct cs_data
<G
, bg::cartesian_tag
>
92 bg::strategy::densify::cartesian
<> compl_s
;
93 bg::strategy::distance::pythagoras
<> dist_s
;
97 struct cs_data
<G
, bg::spherical_equatorial_tag
>
105 bg::srs::sphere
<double> model
;
106 bg::strategy::densify::spherical
<> compl_s
;
107 bg::strategy::distance::haversine
<double> dist_s
;
110 template <typename G
>
111 struct cs_data
<G
, bg::geographic_tag
>
114 : model(6378137.0, 6356752.3142451793)
119 bg::srs::spheroid
<double> model
;
120 bg::strategy::densify::geographic
<> compl_s
;
121 bg::strategy::distance::geographic
<> dist_s
;
124 template <typename G
, typename DistS
, typename Check
>
125 inline void check_result(G
const& g
, G
const& o
, double max_distance
,
126 DistS
const& dist_s
, Check
const& check
)
128 // geometry was indeed densified
129 std::size_t g_count
= bg::num_points(g
);
130 std::size_t o_count
= bg::num_points(o
);
131 BOOST_CHECK(g_count
< o_count
);
133 // all segments have lengths smaller or equal to max_distance
134 double gr_len
= greatest_length(o
, dist_s
);
135 // NOTE: Currently geographic strategies can generate segments that have
136 // lengths slightly greater than max_distance. In order to change
137 // this the generation of new points should e.g. be recursive with
138 // stop condition comparing the current distance calculated by
140 // NOTE: Closeness value tweaked for Andoyer
141 bool is_close
= (gr_len
- max_distance
) / (std::max
)(gr_len
, max_distance
) < 0.0001;
142 BOOST_CHECK(gr_len
<= max_distance
|| is_close
);
144 // the overall length or perimeter didn't change
148 template <typename G
, typename Check
>
149 inline void test_geometry(std::string
const& wkt
, Check
const& check
)
154 bg::read_wkt(wkt
, g
);
157 bg::default_strategy def_s
;
158 double max_distance
= shortest_length(g
, def_s
) / 3.0;
161 bg::densify(g
, o
, max_distance
);
163 check_result(g
, o
, max_distance
, def_s
, check
);
165 using variant_t
= boost::variant
<G
, typename
bg::point_type
<G
>::type
>;
167 bg::densify(v
, vo
, max_distance
);
171 bg::model::geometry_collection
<variant_t
> gc
{v
}, gco
;
172 bg::densify(gc
, gco
, max_distance
);
174 check(gc
, gco
, def_s
);
178 double max_distance
= shortest_length(g
, d
.dist_s
) / 3.0;
181 bg::densify(g
, o
, max_distance
, d
.compl_s
);
183 check_result(g
, o
, max_distance
, d
.dist_s
, check
);
187 template <typename G
>
188 inline void test_linear(std::string
const& wkt
)
190 test_geometry
<G
>(wkt
, check_lengths());
193 template <typename G
>
194 inline void test_areal(std::string
const& wkt
)
196 test_geometry
<G
>(wkt
, check_perimeters());
199 template <typename P
>
202 typedef bg::model::linestring
<P
> ls_t
;
203 typedef bg::model::multi_linestring
<ls_t
> mls_t
;
205 typedef bg::model::ring
<P
> ring_t
;
206 typedef bg::model::polygon
<P
> poly_t
;
207 typedef bg::model::multi_polygon
<poly_t
> mpoly_t
;
209 typedef bg::model::ring
<P
, true, false> oring_t
;
210 typedef bg::model::polygon
<P
, true, false> opoly_t
;
211 typedef bg::model::multi_polygon
<opoly_t
> ompoly_t
;
213 test_linear
<ls_t
>("LINESTRING(4 -4, 4 -1)");
214 test_linear
<ls_t
>("LINESTRING(4 4, 4 1)");
215 test_linear
<ls_t
>("LINESTRING(0 0, 180 0)");
216 test_linear
<ls_t
>("LINESTRING(1 1, -179 -1)");
218 test_linear
<ls_t
>("LINESTRING(1 1, 2 2, 4 2)");
219 test_linear
<mls_t
>("MULTILINESTRING((1 1, 2 2),(2 2, 4 2))");
221 test_areal
<ring_t
>("POLYGON((1 1, 1 2, 2 2, 1 1))");
222 test_areal
<poly_t
>("POLYGON((1 1, 1 4, 4 4, 4 1, 1 1),(1 1, 2 2, 2 3, 1 1))");
223 test_areal
<mpoly_t
>("MULTIPOLYGON(((1 1, 1 4, 4 4, 4 1, 1 1),(1 1, 2 2, 2 3, 1 1)),((4 4, 5 5, 5 4, 4 4)))");
225 test_areal
<oring_t
>("POLYGON((1 1, 1 2, 2 2))");
226 test_areal
<opoly_t
>("POLYGON((1 1, 1 4, 4 4, 4 1),(1 1, 2 2, 2 3))");
227 test_areal
<ompoly_t
>("MULTIPOLYGON(((1 1, 1 4, 4 4, 4 1),(1 1, 2 2, 2 3)),((4 4, 5 5, 5 4)))");
229 test_areal
<ring_t
>("POLYGON((0 0,0 40,40 40,40 0,0 0))");
230 test_areal
<oring_t
>("POLYGON((0 0,0 40,40 40,40 0))");
233 int test_main(int, char* [])
235 test_all
< bg::model::point
<double, 2, bg::cs::cartesian
> >();
236 test_all
< bg::model::point
<double, 2, bg::cs::spherical_equatorial
<bg::degree
> > >();
237 test_all
< bg::model::point
<double, 2, bg::cs::geographic
<bg::degree
> > >();