]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/overlay/dissolver.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / overlay / dissolver.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands.
5
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
9
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)
13
14 #include <iostream>
15 #include <string>
16
17
18 #include <geometry_test_common.hpp>
19
20 #include <boost/geometry/algorithms/detail/overlay/dissolver.hpp>
21
22 #include <boost/geometry/strategies/strategies.hpp>
23 #include <boost/geometry/geometries/point_xy.hpp>
24 #include <boost/geometry/geometries/multi_polygon.hpp>
25 #include <boost/geometry/io/wkt/read.hpp>
26
27
28 #include <test_common/test_point.hpp>
29
30
31 #if defined(TEST_WITH_SVG)
32 # include <boost/geometry/io/svg/svg_mapper.hpp>
33 # include <boost/geometry/io/svg/write_svg_multi.hpp>
34 #endif
35
36 // Collection might be a multi-geometry, or std::vector<ring>
37 template <typename GeometryOut, typename Collection, typename T>
38 void test_dissolve_plusmin(std::string const& caseid, Collection const& input,
39 T const& expected_positive_area,
40 T const& expected_negative_area)
41 {
42 typedef typename boost::range_value<GeometryOut>::type geometry_type;
43 typedef typename bg::point_type<geometry_type>::type point_type;
44
45
46 GeometryOut output;
47 bg::dissolver(input, output);
48
49 T zero = T();
50 T positive_area = T();
51 T negative_area = T();
52
53 for (geometry_type const& geometry : output)
54 {
55 T a = bg::area(geometry);
56 if (a > zero)
57 {
58 positive_area += a;
59 }
60 else
61 {
62 negative_area += a;
63 }
64 }
65
66 BOOST_CHECK_CLOSE(positive_area, expected_positive_area, 0.001);
67 BOOST_CHECK_CLOSE(negative_area, expected_negative_area, 0.001);
68
69
70 #if defined(TEST_WITH_SVG)
71 {
72 std::ostringstream filename;
73 filename << "dissolve_plusmin_"
74 << caseid << ".svg";
75
76 std::ofstream svg(filename.str().c_str());
77
78 bg::svg_mapper<point_type> mapper(svg, 500, 500);
79
80 typedef typename boost::range_value<Collection>::type value_type;
81 for (value_type const& geometry : input)
82 {
83 mapper.add(geometry);
84 }
85
86 for (value_type const& geometry : input)
87 {
88 mapper.map(geometry,
89 "opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:0.5");
90 }
91 for (geometry_type const& geometry : output)
92 {
93 mapper.map(geometry,
94 bg::area(geometry) > 0
95 ? "opacity:0.5;fill:none;stroke:rgb(255,0,0);stroke-width:5"
96 : "opacity:0.5;fill:none;stroke:rgb(0,0,255);stroke-width:5"
97 );
98 }
99 }
100 #endif
101
102 }
103
104 template <typename MultiPolygon, typename T>
105 void test_geometry(std::string const& caseid, std::string const& wkt,
106 T const& expected_positive_area,
107 T const& expected_negative_area = T())
108 {
109
110 MultiPolygon multi_polygon;
111 bg::read_wkt(wkt, multi_polygon);
112
113 // Test std::vector<Polygon> (= multi_polygon)
114 test_dissolve_plusmin<MultiPolygon>(caseid, multi_polygon,
115 expected_positive_area,
116 expected_negative_area);
117
118 // Test std::vector<ring>
119 {
120 typedef typename boost::range_value<MultiPolygon>::type polygon_type;
121 typedef typename bg::ring_type<MultiPolygon>::type ring_type;
122 std::vector<ring_type> rings;
123 for (polygon_type const& polygon : multi_polygon)
124 {
125 rings.push_back(bg::exterior_ring(polygon));
126 }
127
128 test_dissolve_plusmin<MultiPolygon>(caseid + "_rings", rings,
129 expected_positive_area,
130 expected_negative_area);
131 }
132
133 // Test different combinations
134 #define BOOST_GEOMETRY_TEST_PERMUTATIONS
135 #ifdef BOOST_GEOMETRY_TEST_PERMUTATIONS
136
137 int n = multi_polygon.size();
138
139 // test them in all orders
140 std::vector<int> indices;
141 for (int i = 0; i < n; i++)
142 {
143 indices.push_back(i);
144 }
145 int permutation = 0;
146 do
147 {
148 std::ostringstream out;
149 out << caseid;
150 MultiPolygon multi_polygon2;
151 for (int i = 0; i < n; i++)
152 {
153 int index = indices[i];
154 out << "_" << index;
155 multi_polygon2.push_back(multi_polygon[index]);
156 }
157 test_dissolve_plusmin<MultiPolygon>(out.str(), multi_polygon2, expected_positive_area,
158 expected_negative_area);
159 } while (std::next_permutation(indices.begin(), indices.end()));
160 #endif
161 }
162
163 template <typename Point>
164 void test_all()
165 {
166 typedef bg::model::polygon<Point> polygon;
167 typedef bg::model::multi_polygon<polygon> multi_polygon;
168
169 test_geometry<multi_polygon>("simplex_one",
170 "MULTIPOLYGON(((0 0,1 4,4 1,0 0)))",
171 7.5);
172
173 test_geometry<multi_polygon>("simplex_two",
174 "MULTIPOLYGON(((0 0,1 4,4 1,0 0)),((2 2,3 6,6 3,2 2)))",
175 14.7);
176 test_geometry<multi_polygon>("simplex_three",
177 "MULTIPOLYGON(((0 0,1 4,4 1,0 0)),((2 2,3 6,6 3,2 2)),((3 4,5 6,6 2,3 4)))",
178 16.7945);
179 test_geometry<multi_polygon>("simplex_four",
180 "MULTIPOLYGON(((0 0,1 4,4 1,0 0)),((2 2,3 6,6 3,2 2)),((3 4,5 6,6 2,3 4)),((5 5,7 7,8 4,5 5)))",
181 20.7581);
182
183 // disjoint
184 test_geometry<multi_polygon>("simplex_disjoint",
185 "MULTIPOLYGON(((0 0,1 4,4 1,0 0)),((1 6,2 10,5 7,1 6)),((3 4,5 6,6 2,3 4)),((6 5,8 7,9 4,6 5)))",
186 24.0);
187
188 // new hole of four
189 test_geometry<multi_polygon>("new_hole",
190 "MULTIPOLYGON(((0 0,1 4,4 1,0 0)),((2 2,3 6,6 3,2 2)),((3 4,5 6,6 2,3 4)),((3 1,5 4,8 4,3 1)))",
191 19.5206);
192
193 // intersection of positive/negative ring
194 test_geometry<multi_polygon>("plus_min_one",
195 "MULTIPOLYGON(((0 0,1 4,4 1,0 0)),((2 2,6 3,3 6,2 2)))",
196 7.5, -7.2);
197
198 // negative ring within a positive ring
199 test_geometry<multi_polygon>("plus_min_one_within",
200 "MULTIPOLYGON(((0 0,1 7,7 3,0 0)),((1 2,4 4,2 5,1 2)))",
201 23.0, -3.5);
202
203 // from buffer
204 test_geometry<multi_polygon>("from_buffer_1",
205 "MULTIPOLYGON(((2.4 3.03431,1.71716 3.71716,2.4 4,2.4 3.03431))"
206 ",((2.4 1.96569,2.4 1,1.71716 1.28284,2.4 1.96569))"
207 ",((2.93431 2.5,2.4 3.03431,2.4 1.96569,2.93431 2.5))"
208 ",((3.06569 2.5,3 2.43431,2.93431 2.5,3 2.56569,3.06569 2.5))"
209 ",((-0.4 5.4,4.4 5.4,4.4 3.83431,3.06569 2.5,4.4 1.16569,4.4 -0.4,-0.4 -0.4,-0.4 5.4)))"
210 ,
211 26.0596168239, -0.2854871761);
212
213 }
214
215 int test_main(int, char* [])
216 {
217 test_all<bg::model::d2::point_xy<double> >();
218 return 0;
219 }
220
221