]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/area/area.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
8 // This file was modified by Oracle on 2015-2021.
9 // Modifications copyright (c) 2015-2021, Oracle and/or its affiliates.
11 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
12 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
22 #include <algorithms/area/test_area.hpp>
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>
33 #include <boost/geometry/strategy/cartesian/precise_area.hpp>
35 #include <test_geometries/all_custom_ring.hpp>
36 #include <test_geometries/all_custom_polygon.hpp>
37 //#define BOOST_GEOMETRY_TEST_DEBUG
39 #include <boost/multiprecision/cpp_dec_float.hpp>
41 template <typename Polygon
>
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);
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);
59 test_polygon
<bg::model::polygon
<P
> >();
60 test_polygon
<all_custom_polygon
<P
> >();
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);
66 test_geometry
<all_custom_ring
<P
> >("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0);
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);
72 test_geometry
<bg::model::polygon
<P
, false> >
73 ("POLYGON((1 0,0 1,-1 0,0 -1,1 0))", 2);
75 typedef typename
bg::coordinate_type
<P
>::type coord_type
;
76 if (BOOST_GEOMETRY_CONDITION((std::is_same
<coord_type
, double>::value
)))
78 test_geometry
<bg::model::polygon
<P
, false, false> >
79 ("POLYGON((100000001 100000000, 100000000 100000001, \
80 99999999 100000000, 100000000 99999999))", 2);
82 else if (BOOST_GEOMETRY_CONDITION((std::is_same
<coord_type
, float>::value
)))
84 test_geometry
<bg::model::polygon
<P
, false, false> >
85 ("POLYGON((100001 100000, 100000 100001, \
86 99999 100000, 100000 99999))", 2);
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))";
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);
113 template <typename P
, typename CT
>
114 void test_open(CT expected_area
)
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
121 template <typename P
, typename CT
>
122 void test_open_ccw(CT expected_area
)
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
129 template <typename P
>
130 void test_poles_ccw()
132 typedef typename
bg::coordinate_type
<P
>::type ct
;
133 bg::model::polygon
<P
, false> polygon
;
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))";
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);
152 template <typename P
>
153 void test_empty_input()
155 bg::model::polygon
<P
> poly_empty
;
156 bg::model::ring
<P
> ring_empty
;
158 test_empty_input(poly_empty
);
159 test_empty_input(ring_empty
);
162 void test_large_integers()
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
;
167 bg::model::polygon
<int_point_type
> int_poly
;
168 bg::model::polygon
<double_point_type
> double_poly
;
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,\
174 bg::read_wkt(polygon_li
, int_poly
);
175 bg::read_wkt(polygon_li
, double_poly
);
177 double int_area
= bg::area(int_poly
);
178 double double_area
= bg::area(double_poly
);
180 BOOST_CHECK_CLOSE(int_area
, double_area
, 0.0001);
183 struct precise_cartesian
: bg::strategies::detail::cartesian_base
185 template <typename Geometry
>
186 static auto area(Geometry
const&)
188 return bg::strategy::area::precise_cartesian
<>();
192 void test_accurate_sum_strategy()
194 typedef bg::model::point
<double, 2, bg::cs::cartesian
> point_type
;
195 typedef bg::model::point
197 boost::multiprecision::cpp_dec_float_50
,
202 auto const poly0_string
= "POLYGON((0 0,0 1,1 0,0 0))";
204 bg::model::polygon
<point_type
> poly0
;
205 bg::read_wkt(poly0_string
, poly0
);
207 BOOST_CHECK_CLOSE(bg::area(poly0
), 0.5, 0.0001);
208 BOOST_CHECK_CLOSE(bg::area(poly0
, precise_cartesian()), 0.5, 0.0001);
210 bg::model::polygon
<mp_point_type
> mp_poly0
;
211 bg::read_wkt(poly0_string
, mp_poly0
);
213 BOOST_CHECK_CLOSE(bg::area(mp_poly0
), 0.5, 0.0001);
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))";
221 bg::model::polygon
<point_type
> poly1
;
222 bg::read_wkt(poly1_string
, poly1
);
224 BOOST_CHECK_CLOSE(bg::area(poly1
), 0, 0.0001);
225 BOOST_CHECK_CLOSE(bg::area(poly1
, precise_cartesian()), -0.315, 0.0001);
227 bg::model::polygon
<mp_point_type
> mp_poly1
;
228 bg::read_wkt(poly1_string
, mp_poly1
);
230 BOOST_CHECK_CLOSE(bg::area(mp_poly1
), 34720783012552.6, 0.0001);
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))";
235 bg::model::polygon
<point_type
> poly2
;
236 bg::read_wkt(poly2_string
, poly2
);
238 BOOST_CHECK_CLOSE(bg::area(poly2
), 0, 0.0001);
239 BOOST_CHECK_CLOSE(bg::area(poly2
, precise_cartesian()), 0.315, 0.0001);
241 bg::model::polygon
<mp_point_type
> mp_poly2
;
242 bg::read_wkt(poly2_string
, mp_poly2
);
244 BOOST_CHECK_CLOSE(bg::area(mp_poly2
), 35000000000000, 0.0001);
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
;
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
);
258 std::string
const box_li
= "BOX(0 0,2 2)";
259 bg::read_wkt(box_li
, box
);
261 auto apoly
= bg::area(poly
);
262 auto abox
= bg::area(box
);
264 boost::variant
<polygon_type
, box_type
> v
;
266 BOOST_CHECK_CLOSE(bg::area(v
), apoly
, 0.0001);
268 BOOST_CHECK_CLOSE(bg::area(v
), abox
, 0.0001);
270 boost::variant2::variant
<polygon_type
, box_type
> v2
;
272 BOOST_CHECK_CLOSE(bg::area(v2
), apoly
, 0.0001);
274 BOOST_CHECK_CLOSE(bg::area(v2
), abox
, 0.0001);
276 bg::model::geometry_collection
<boost::variant
<polygon_type
, box_type
> > gc
;
279 BOOST_CHECK_CLOSE(bg::area(gc
), apoly
+ abox
, 0.0001);
282 int test_main(int, char* [])
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
> >();
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
;
293 // mean Earth's radius^2
294 double r2
= bg::math::sqr(bg::get_radius
<0>(bg::srs::sphere
<double>()));
300 test_open
<pt_crt
>(2.0);
301 test_open
<pt_sph
>(24726179921.523518 / r2
);
302 test_open
<pt_geo
>(24615770547.825359);
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);
308 test_poles_ccw
<pt_crt
>();
309 test_poles_ccw
<pt_sph
>();
310 test_poles_ccw
<pt_geo
>();
312 test_large_integers();
316 test_accurate_sum_strategy();
318 // test_empty_input<bg::model::d2::point_xy<int> >();