]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/simplify_countries.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2018 Barend Gehrels, Amsterdam, the Netherlands.
6 // This file was modified by Oracle on 2021.
7 // Modifications copyright (c) 2021, Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
17 #include <geometry_test_common.hpp>
19 #include <boost/geometry/algorithms/correct.hpp>
20 #include <boost/geometry/algorithms/simplify.hpp>
22 #include <boost/geometry/geometries/geometries.hpp>
24 #include <boost/geometry/io/wkt/read.hpp>
25 #include <boost/geometry/io/wkt/write.hpp>
27 #if defined(TEST_WITH_SVG)
28 # include <boost/geometry/io/svg/svg_mapper.hpp>
32 template <typename MultiPolygon
>
33 std::string
read_from_file(std::string
const& filename
)
36 std::ifstream
in(filename
.c_str());
40 std::getline(in
, line
);
43 typename
boost::range_value
<MultiPolygon
>::type pol
;
44 bg::read_wkt(line
, pol
);
48 std::ostringstream out
;
51 out
<< std::fixed
<< std::setprecision(19) << bg::wkt(mp
);
54 BOOST_CHECK(! out
.str().empty());
60 template <typename MultiPolygon
>
61 void test_one(std::string
const& caseid
, std::string
const& wkt
,
62 double distance_in_meters
,
63 double expected_area_ratio
, double expected_perimeter_ratio
,
64 std::size_t expected_polygon_count
= 0,
65 std::size_t expected_interior_count
= 0,
66 std::size_t expected_point_count
= 0)
68 boost::ignore_unused(caseid
);
70 MultiPolygon geometry
, simplified
;
71 bg::read_wkt(wkt
, geometry
);
72 bg::correct(geometry
);
73 bg::simplify(geometry
, simplified
, distance_in_meters
);
75 double const area_ratio
= bg::area(simplified
) / bg::area(geometry
);
76 double const perimeter_ratio
= bg::perimeter(simplified
) / bg::perimeter(geometry
);
78 BOOST_CHECK_CLOSE(perimeter_ratio
, expected_perimeter_ratio
, 0.01);
79 BOOST_CHECK_CLOSE(area_ratio
, expected_area_ratio
, 0.01);
80 BOOST_CHECK_EQUAL(expected_polygon_count
, boost::size(simplified
));
81 BOOST_CHECK_EQUAL(expected_interior_count
, bg::num_interior_rings(simplified
));
82 BOOST_CHECK_EQUAL(expected_point_count
, bg::num_points(simplified
));
84 // To add new tests, this is convenient and write the test itself:
85 // std::cout << "test_one<mp>(\"" << caseid << "\", " << caseid
86 // << ", " << distance_in_meters
87 // << std::setprecision(6)
88 // << ", " << area_ratio
89 // << ", " << perimeter_ratio
90 // << ", " << boost::size(simplified)
91 // << ", " << bg::num_interior_rings(simplified)
92 // << ", " << bg::num_points(simplified)
96 #if defined(TEST_WITH_SVG)
98 typedef typename
boost::range_value
<MultiPolygon
>::type polygon
;
100 std::ostringstream filename
;
101 filename
<< "simplify_" << caseid
<< "_" << distance_in_meters
<< ".svg";
103 std::ofstream
svg(filename
.str().c_str());
107 typename
bg::point_type
<MultiPolygon
>::type
108 > mapper(svg
, 1200, 800);
109 mapper
.add(geometry
);
110 mapper
.add(simplified
);
112 mapper
.map(geometry
, "fill-opacity:0.5;fill:rgb(153,204,0);"
113 "stroke:rgb(153,204,0);stroke-width:1");
114 for (polygon
const& pol
: simplified
)
117 bg::area(pol
) > 0 ? "fill:none;stroke:rgb(255,0,0);stroke-width:1"
118 : "fill:none;stroke:rgb(255,0,255);stroke-width:1");
125 template <bool Clockwise
, typename P
>
128 typedef bg::model::polygon
<P
, Clockwise
> polygon
;
129 typedef bg::model::multi_polygon
<polygon
> mp
;
131 // The unit test uses countries originally added for buffer unit test
132 std::string base_folder
= "buffer/data/";
134 // Verify for Greece, Italy, Netherlands, Norway and UK
135 std::string gr
= read_from_file
<mp
>(base_folder
+ "gr.wkt");
136 std::string it
= read_from_file
<mp
>(base_folder
+ "it.wkt");
137 std::string nl
= read_from_file
<mp
>(base_folder
+ "nl.wkt");
138 std::string no
= read_from_file
<mp
>(base_folder
+ "no.wkt");
139 std::string uk
= read_from_file
<mp
>(base_folder
+ "uk.wkt");
141 // Gradually simplify more aggresively.
142 // Area ratio (first) can increase or decrease
143 // Perimeter ratio (second) should decrease.
144 // Polygons, interior rings, points should decrease
145 test_one
<mp
>("gr", gr
, 100, 0.999905, 0.999758, 68, 0, 2520);
146 test_one
<mp
>("gr", gr
, 200, 0.999773, 0.998865, 68, 0, 2019);
147 test_one
<mp
>("gr", gr
, 500, 0.999026, 0.995931, 68, 0, 1468);
148 test_one
<mp
>("gr", gr
, 1000, 0.997782, 0.991475, 68, 0, 1132);
149 test_one
<mp
>("gr", gr
, 2000, 0.994448, 0.9793, 65, 0, 854);
150 test_one
<mp
>("gr", gr
, 5000, 0.979743, 0.910266, 50, 0, 471);
151 test_one
<mp
>("gr", gr
, 10000, 0.968349, 0.778863, 28, 0, 245);
152 test_one
<mp
>("gr", gr
, 20000, 0.961943, 0.607009, 10, 0, 97); // Many islands disappear
154 test_one
<mp
>("it", it
, 100, 1.00001, 0.999813, 22, 1, 1783);
155 test_one
<mp
>("it", it
, 200, 1.00009, 0.9991, 22, 1, 1406);
156 test_one
<mp
>("it", it
, 500, 1.00019, 0.996848, 22, 1, 1011);
157 test_one
<mp
>("it", it
, 1000, 1.00041, 0.99294, 22, 1, 749);
158 test_one
<mp
>("it", it
, 2000, 1.00086, 0.985144, 22, 1, 546);
159 test_one
<mp
>("it", it
, 5000, 1.00147, 0.93927, 11, 1, 283);
160 test_one
<mp
>("it", it
, 10000, 1.01089, 0.882198, 4, 1, 153);
161 test_one
<mp
>("it", it
, 20000, 1.00893, 0.828774, 4, 0, 86); // San Marino disappears
163 test_one
<mp
>("nl", nl
, 100, 0.999896, 0.999804, 8, 0, 789);
164 test_one
<mp
>("nl", nl
, 200, 0.999733, 0.999095, 8, 0, 633);
165 test_one
<mp
>("nl", nl
, 500, 0.999423, 0.996313, 8, 0, 436);
166 test_one
<mp
>("nl", nl
, 1000, 0.997893, 0.991951, 8, 0, 331);
167 test_one
<mp
>("nl", nl
, 2000, 0.996129, 0.981998, 8, 0, 234);
168 test_one
<mp
>("nl", nl
, 5000, 0.986128, 0.896, 5, 0, 132);
169 test_one
<mp
>("nl", nl
, 10000, 0.973917, 0.832522, 4, 0, 75);
170 test_one
<mp
>("nl", nl
, 20000, 0.970675, 0.739275, 3, 0, 40);
172 test_one
<mp
>("no", no
, 100, 0.999966, 0.999975, 95, 0, 7650);
173 test_one
<mp
>("no", no
, 200, 0.999812, 0.999731, 95, 0, 6518);
174 test_one
<mp
>("no", no
, 500, 0.99929, 0.998092, 95, 0, 4728);
175 test_one
<mp
>("no", no
, 1000, 0.998473, 0.994075, 95, 0, 3524);
176 test_one
<mp
>("no", no
, 2000, 0.996674, 0.985863, 92, 0, 2576);
177 test_one
<mp
>("no", no
, 5000, 0.99098, 0.965689, 87, 0, 1667);
178 test_one
<mp
>("no", no
, 10000, 0.978207, 0.906525, 69, 0, 1059);
179 test_one
<mp
>("no", no
, 20000, 0.955223, 0.786546, 38, 0, 593);
181 test_one
<mp
>("uk", uk
, 100, 0.999942, 0.999878, 48, 0, 3208);
182 test_one
<mp
>("uk", uk
, 200, 0.999843, 0.999291, 48, 0, 2615);
183 test_one
<mp
>("uk", uk
, 500, 0.999522, 0.996888, 48, 0, 1885);
184 test_one
<mp
>("uk", uk
, 1000, 0.999027, 0.992306, 48, 0, 1396);
185 test_one
<mp
>("uk", uk
, 2000, 0.998074, 0.983839, 47, 0, 1032);
186 test_one
<mp
>("uk", uk
, 5000, 0.991901, 0.943496, 35, 0, 611);
187 test_one
<mp
>("uk", uk
, 10000, 0.990039, 0.871969, 23, 0, 359);
188 test_one
<mp
>("uk", uk
, 20000, 0.979171, 0.737577, 11, 0, 193);
192 int test_main(int, char* [])
194 test_all
<true, bg::model::point
<double, 2, bg::cs::cartesian
> >();