1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2010-2015 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)
18 #include <geometry_test_common.hpp>
20 #include <boost/geometry/algorithms/detail/overlay/dissolver.hpp>
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>
28 #include <test_common/test_point.hpp>
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>
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
)
42 typedef typename
boost::range_value
<GeometryOut
>::type geometry_type
;
43 typedef typename
bg::point_type
<geometry_type
>::type point_type
;
47 bg::dissolver(input
, output
);
50 T positive_area
= T();
51 T negative_area
= T();
53 for (geometry_type
const& geometry
: output
)
55 T a
= bg::area(geometry
);
66 BOOST_CHECK_CLOSE(positive_area
, expected_positive_area
, 0.001);
67 BOOST_CHECK_CLOSE(negative_area
, expected_negative_area
, 0.001);
70 #if defined(TEST_WITH_SVG)
72 std::ostringstream filename
;
73 filename
<< "dissolve_plusmin_"
76 std::ofstream
svg(filename
.str().c_str());
78 bg::svg_mapper
<point_type
> mapper(svg
, 500, 500);
80 typedef typename
boost::range_value
<Collection
>::type value_type
;
81 for (value_type
const& geometry
: input
)
86 for (value_type
const& geometry
: input
)
89 "opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:0.5");
91 for (geometry_type
const& geometry
: output
)
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"
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())
110 MultiPolygon multi_polygon
;
111 bg::read_wkt(wkt
, multi_polygon
);
113 // Test std::vector<Polygon> (= multi_polygon)
114 test_dissolve_plusmin
<MultiPolygon
>(caseid
, multi_polygon
,
115 expected_positive_area
,
116 expected_negative_area
);
118 // Test std::vector<ring>
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
)
125 rings
.push_back(bg::exterior_ring(polygon
));
128 test_dissolve_plusmin
<MultiPolygon
>(caseid
+ "_rings", rings
,
129 expected_positive_area
,
130 expected_negative_area
);
133 // Test different combinations
134 #define BOOST_GEOMETRY_TEST_PERMUTATIONS
135 #ifdef BOOST_GEOMETRY_TEST_PERMUTATIONS
137 int n
= multi_polygon
.size();
139 // test them in all orders
140 std::vector
<int> indices
;
141 for (int i
= 0; i
< n
; i
++)
143 indices
.push_back(i
);
148 std::ostringstream out
;
150 MultiPolygon multi_polygon2
;
151 for (int i
= 0; i
< n
; i
++)
153 int index
= indices
[i
];
155 multi_polygon2
.push_back(multi_polygon
[index
]);
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()));
163 template <typename Point
>
166 typedef bg::model::polygon
<Point
> polygon
;
167 typedef bg::model::multi_polygon
<polygon
> multi_polygon
;
169 test_geometry
<multi_polygon
>("simplex_one",
170 "MULTIPOLYGON(((0 0,1 4,4 1,0 0)))",
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)))",
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)))",
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)))",
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)))",
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)))",
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)))",
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)))",
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)))"
211 26.0596168239, -0.2854871761);
215 int test_main(int, char* [])
217 test_all
<bg::model::d2::point_xy
<double> >();