]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/area/area.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / area / area.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
6 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
7
8 // This file was modified by Oracle on 2015-2021.
9 // Modifications copyright (c) 2015-2021, Oracle and/or its affiliates.
10
11 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
12 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
13
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
16
17 // Use, modification and distribution is subject to the Boost Software License,
18 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
19 // http://www.boost.org/LICENSE_1_0.txt)
20
21
22 #include <algorithms/area/test_area.hpp>
23
24 #include <boost/geometry/geometries/box.hpp>
25 #include <boost/geometry/geometries/geometry_collection.hpp>
26 #include <boost/geometry/geometries/point_xy.hpp>
27 #include <boost/geometry/geometries/point.hpp>
28 #include <boost/geometry/geometries/polygon.hpp>
29 #include <boost/geometry/geometries/ring.hpp>
30 #include <boost/geometry/geometries/adapted/boost_variant.hpp>
31 #include <boost/geometry/geometries/adapted/boost_variant2.hpp>
32
33 #include <boost/geometry/strategy/cartesian/precise_area.hpp>
34
35 #include <test_geometries/all_custom_ring.hpp>
36 #include <test_geometries/all_custom_polygon.hpp>
37 //#define BOOST_GEOMETRY_TEST_DEBUG
38
39 #include <boost/multiprecision/cpp_dec_float.hpp>
40
41 template <typename Polygon>
42 void test_polygon()
43 {
44 // Rotated square, length=sqrt(2) -> area=2
45 test_geometry<Polygon>("POLYGON((1 1,2 2,3 1,2 0,1 1))", 2.0);
46 test_geometry<Polygon>("POLYGON((1 1,2 2,3 1,2 0,1 1))", 2.0);
47 test_geometry<Polygon>("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0);
48 test_geometry<Polygon>("POLYGON((1 1,2 1,2 2,1 2,1 1))", -1.0);
49 test_geometry<Polygon>("POLYGON((0 0,0 7,4 2,2 0,0 0), (1 1,2 1,2 2,1 2,1 1))", 15.0);
50 }
51
52
53 template <typename P>
54 void test_all()
55 {
56 test_geometry<bg::model::box<P> >("POLYGON((0 0,2 2))", 4.0);
57 test_geometry<bg::model::box<P> >("POLYGON((2 2,0 0))", 4.0);
58
59 test_polygon<bg::model::polygon<P> >();
60 test_polygon<all_custom_polygon<P> >();
61
62 // clockwise rings (second is wrongly ordered)
63 test_geometry<bg::model::ring<P> >("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0);
64 test_geometry<bg::model::ring<P> >("POLYGON((0 0,2 0,4 2,0 7,0 0))", -16.0);
65
66 test_geometry<all_custom_ring<P> >("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0);
67
68 // ccw
69 test_geometry<bg::model::polygon<P, false> >
70 ("POLYGON((0 0,0 7,4 2,2 0,0 0), (1 1,2 1,2 2,1 2,1 1))", -15.0);
71
72 test_geometry<bg::model::polygon<P, false> >
73 ("POLYGON((1 0,0 1,-1 0,0 -1,1 0))", 2);
74
75 typedef typename bg::coordinate_type<P>::type coord_type;
76 if (BOOST_GEOMETRY_CONDITION((std::is_same<coord_type, double>::value)))
77 {
78 test_geometry<bg::model::polygon<P, false, false> >
79 ("POLYGON((100000001 100000000, 100000000 100000001, \
80 99999999 100000000, 100000000 99999999))", 2);
81 }
82 else if (BOOST_GEOMETRY_CONDITION((std::is_same<coord_type, float>::value)))
83 {
84 test_geometry<bg::model::polygon<P, false, false> >
85 ("POLYGON((100001 100000, 100000 100001, \
86 99999 100000, 100000 99999))", 2);
87 }
88 }
89
90 template <typename P>
91 void test_ccw()
92 {
93 typedef typename bg::coordinate_type<P>::type ct;
94 bg::model::polygon<P, false> ccw_polygon;
95 // counterclockwise rings (second is wrongly ordered)
96 std::string poly1 = "POLYGON((1 1,2 2,3 1,2 0,1 1))";
97 std::string poly2 = "POLYGON((1 1,2 0,3 1,2 2,1 1))";
98 std::string poly3 = "POLYGON((0 0,0 7,4 2,2 0,0 0))";
99 std::string poly4 = "POLYGON((0 0,2 0,4 2,0 7,0 0))";
100
101 bg::read_wkt(poly1, ccw_polygon);
102 ct area1 = bg::area(ccw_polygon);
103 bg::read_wkt(poly2, ccw_polygon);
104 ct area2 = bg::area(ccw_polygon);
105 bg::read_wkt(poly3, ccw_polygon);
106 ct area3 = bg::area(ccw_polygon);
107 bg::read_wkt(poly4, ccw_polygon);
108 ct area4 = bg::area(ccw_polygon);
109 BOOST_CHECK_CLOSE(area1, -1 * area2, 0.001);
110 BOOST_CHECK_CLOSE(area3, -1 * area4, 0.001);
111 }
112
113 template <typename P, typename CT>
114 void test_open(CT expected_area)
115 {
116 typedef bg::model::polygon<P, true, false> open_polygon;
117 test_geometry<open_polygon>("POLYGON((1 1,2 2,3 1,2 0))", expected_area);
118 // Note the triangular testcase used in CCW is not sensible for open/close
119 }
120
121 template <typename P, typename CT>
122 void test_open_ccw(CT expected_area)
123 {
124 typedef bg::model::polygon<P, false, false> open_polygon;
125 test_geometry<open_polygon>("POLYGON((1 1,2 0,3 1,2 2))", expected_area);
126 // Note the triangular testcase used in CCW is not sensible for open/close
127 }
128
129 template <typename P>
130 void test_poles_ccw()
131 {
132 typedef typename bg::coordinate_type<P>::type ct;
133 bg::model::polygon<P, false> polygon;
134
135 std::string poly1 = "POLYGON((45 45,45 95,95 45,45 45))";
136 std::string poly2 = "POLYGON((45 45,95 45,45 95,45 45))";
137 std::string poly3 = "POLYGON((45 -45,45 -95,95 -45,45 -45))";
138 std::string poly4 = "POLYGON((45 -45,95 -45,45 -95,45 -45))";
139
140 bg::read_wkt(poly1, polygon);
141 ct area1 = bg::area(polygon);
142 bg::read_wkt(poly2, polygon);
143 ct area2 = bg::area(polygon);
144 bg::read_wkt(poly3, polygon);
145 ct area3 = bg::area(polygon);
146 bg::read_wkt(poly4, polygon);
147 ct area4 = bg::area(polygon);
148 BOOST_CHECK_CLOSE(area1, -1 * area2, 0.001);
149 BOOST_CHECK_CLOSE(area3, -1 * area4, 0.001);
150 }
151
152 template <typename P>
153 void test_empty_input()
154 {
155 bg::model::polygon<P> poly_empty;
156 bg::model::ring<P> ring_empty;
157
158 test_empty_input(poly_empty);
159 test_empty_input(ring_empty);
160 }
161
162 void test_large_integers()
163 {
164 typedef bg::model::point<int, 2, bg::cs::cartesian> int_point_type;
165 typedef bg::model::point<double, 2, bg::cs::cartesian> double_point_type;
166
167 bg::model::polygon<int_point_type> int_poly;
168 bg::model::polygon<double_point_type> double_poly;
169
170 std::string const polygon_li = "POLYGON((1872000 528000,1872000 192000,\
171 1536119 192000,1536000 528000,1200000 528000,\
172 1200000 863880,1536000 863880,1872000 863880,\
173 1872000 528000))";
174 bg::read_wkt(polygon_li, int_poly);
175 bg::read_wkt(polygon_li, double_poly);
176
177 double int_area = bg::area(int_poly);
178 double double_area = bg::area(double_poly);
179
180 BOOST_CHECK_CLOSE(int_area, double_area, 0.0001);
181 }
182
183 struct precise_cartesian : bg::strategies::detail::cartesian_base
184 {
185 template <typename Geometry>
186 static auto area(Geometry const&)
187 {
188 return bg::strategy::area::precise_cartesian<>();
189 }
190 };
191
192 void test_accurate_sum_strategy()
193 {
194 typedef bg::model::point<double, 2, bg::cs::cartesian> point_type;
195 typedef bg::model::point
196 <
197 boost::multiprecision::cpp_dec_float_50,
198 2,
199 bg::cs::cartesian
200 > mp_point_type;
201
202 auto const poly0_string = "POLYGON((0 0,0 1,1 0,0 0))";
203
204 bg::model::polygon<point_type> poly0;
205 bg::read_wkt(poly0_string, poly0);
206
207 BOOST_CHECK_CLOSE(bg::area(poly0), 0.5, 0.0001);
208 BOOST_CHECK_CLOSE(bg::area(poly0, precise_cartesian()), 0.5, 0.0001);
209
210 bg::model::polygon<mp_point_type> mp_poly0;
211 bg::read_wkt(poly0_string, mp_poly0);
212
213 BOOST_CHECK_CLOSE(bg::area(mp_poly0), 0.5, 0.0001);
214
215 auto const poly1_string = "POLYGON((0.10000000000000001 0.10000000000000001,\
216 0.20000000000000001 0.20000000000000004,\
217 0.79999999999999993 0.80000000000000004,\
218 1.267650600228229e30 1.2676506002282291e30,\
219 0.10000000000000001 0.10000000000000001))";
220
221 bg::model::polygon<point_type> poly1;
222 bg::read_wkt(poly1_string, poly1);
223
224 BOOST_CHECK_CLOSE(bg::area(poly1), 0, 0.0001);
225 BOOST_CHECK_CLOSE(bg::area(poly1, precise_cartesian()), -0.315, 0.0001);
226
227 bg::model::polygon<mp_point_type> mp_poly1;
228 bg::read_wkt(poly1_string, mp_poly1);
229
230 BOOST_CHECK_CLOSE(bg::area(mp_poly1), 34720783012552.6, 0.0001);
231
232 auto const poly2_string = "POLYGON((1.267650600228229e30 1.2676506002282291e30,\
233 0.8 0.8,0.2 0.2,0.1 0.1,1.267650600228229e30 1.2676506002282291e30))";
234
235 bg::model::polygon<point_type> poly2;
236 bg::read_wkt(poly2_string, poly2);
237
238 BOOST_CHECK_CLOSE(bg::area(poly2), 0, 0.0001);
239 BOOST_CHECK_CLOSE(bg::area(poly2, precise_cartesian()), 0.315, 0.0001);
240
241 bg::model::polygon<mp_point_type> mp_poly2;
242 bg::read_wkt(poly2_string, mp_poly2);
243
244 BOOST_CHECK_CLOSE(bg::area(mp_poly2), 35000000000000, 0.0001);
245 }
246
247 void test_dynamic()
248 {
249 typedef bg::model::point<double, 2, bg::cs::cartesian> double_point_type;
250 typedef bg::model::polygon<double_point_type> polygon_type;
251 typedef bg::model::box<double_point_type> box_type;
252
253 polygon_type poly;
254 std::string const polygon_li = "POLYGON((18 5,18 1,15 1,15 5,12 5,12 8,15 8,18 8,18 5))";
255 bg::read_wkt(polygon_li, poly);
256
257 box_type box;
258 std::string const box_li = "BOX(0 0,2 2)";
259 bg::read_wkt(box_li, box);
260
261 auto apoly = bg::area(poly);
262 auto abox = bg::area(box);
263
264 boost::variant<polygon_type, box_type> v;
265 v = poly;
266 BOOST_CHECK_CLOSE(bg::area(v), apoly, 0.0001);
267 v = box;
268 BOOST_CHECK_CLOSE(bg::area(v), abox, 0.0001);
269
270 boost::variant2::variant<polygon_type, box_type> v2;
271 v2 = poly;
272 BOOST_CHECK_CLOSE(bg::area(v2), apoly, 0.0001);
273 v2 = box;
274 BOOST_CHECK_CLOSE(bg::area(v2), abox, 0.0001);
275
276 bg::model::geometry_collection<boost::variant<polygon_type, box_type> > gc;
277 gc.push_back(poly);
278 gc.push_back(box);
279 BOOST_CHECK_CLOSE(bg::area(gc), apoly + abox, 0.0001);
280 }
281
282 int test_main(int, char* [])
283 {
284
285 test_all<bg::model::point<int, 2, bg::cs::cartesian> >();
286 test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
287 test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
288
289 typedef bg::model::point<double, 2, bg::cs::cartesian> pt_crt;
290 typedef bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> > pt_sph;
291 typedef bg::model::point<double, 2, bg::cs::geographic<bg::degree> > pt_geo;
292
293 // mean Earth's radius^2
294 double r2 = bg::math::sqr(bg::get_radius<0>(bg::srs::sphere<double>()));
295
296 test_ccw<pt_crt>();
297 test_ccw<pt_sph>();
298 test_ccw<pt_geo>();
299
300 test_open<pt_crt>(2.0);
301 test_open<pt_sph>(24726179921.523518 / r2);
302 test_open<pt_geo >(24615770547.825359);
303
304 test_open_ccw<pt_crt>(2.0);
305 test_open_ccw<pt_sph>(24726179921.523518 / r2);
306 test_open_ccw<pt_geo >(24615770547.825359);
307
308 test_poles_ccw<pt_crt>();
309 test_poles_ccw<pt_sph>();
310 test_poles_ccw<pt_geo>();
311
312 test_large_integers();
313
314 test_dynamic();
315
316 test_accurate_sum_strategy();
317
318 // test_empty_input<bg::model::d2::point_xy<int> >();
319
320 return 0;
321 }