]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/overlay/assemble.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / overlay / assemble.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
5
6 // This file was modified by Oracle on 2019-2021.
7 // Modifications copyright (c) 2019-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 <iomanip>
16 #include <string>
17
18
19 #include <geometry_test_common.hpp>
20
21 #include <boost/geometry/algorithms/correct.hpp>
22 #include <boost/geometry/algorithms/intersection.hpp>
23 #include <boost/geometry/algorithms/union.hpp>
24 #include <boost/geometry/algorithms/difference.hpp>
25 #include <boost/geometry/algorithms/intersects.hpp>
26 #include <boost/geometry/algorithms/within.hpp>
27
28 #include <boost/geometry/geometries/geometries.hpp>
29 #include <boost/geometry/geometries/point_xy.hpp>
30
31 #include <boost/geometry/io/wkt/read.hpp>
32 #include <boost/geometry/io/wkt/write.hpp>
33
34 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
35
36 #include <boost/geometry/strategies/strategies.hpp>
37
38
39 #if defined(TEST_WITH_SVG)
40 # include <boost/geometry/io/svg/svg_mapper.hpp>
41 #endif
42
43 template <typename Geometry>
44 inline void test_assemble(std::string const& id, Geometry const& p, Geometry const& q, char operation = 'i')
45 {
46 std::vector<Geometry> u, i, d1, d2;
47 bg::detail::union_::union_insert<Geometry>(p, q, std::back_inserter(u));
48 bg::detail::intersection::intersection_insert<Geometry>(p, q, std::back_inserter(i));
49 bg::detail::difference::difference_insert<Geometry>(p, q, std::back_inserter(d1));
50 bg::detail::difference::difference_insert<Geometry>(q, p, std::back_inserter(d2));
51
52 if (operation == 'i')
53 {
54 typedef typename bg::default_area_result<Geometry>::type type;
55 type area_p = bg::area(p);
56 type area_q = bg::area(q);
57
58 type area_i = 0, area_u = 0, area_d1 = 0, area_d2 = 0;
59
60 for (Geometry const& g : u)
61 {
62 area_u += bg::area(g);
63 }
64 for (Geometry const& g : i)
65 {
66 area_i += bg::area(g);
67 }
68 for (Geometry const& g : d1)
69 {
70 area_d1 += bg::area(g);
71 }
72 for (Geometry const& g : d2)
73 {
74 area_d2 += bg::area(g);
75 }
76
77 type diff = (area_p + area_q) - area_u - area_i;
78 type diff_d1 = (area_u - area_q) - area_d1;
79 type diff_d2 = (area_u - area_p) - area_d2;
80
81 bool ok = bg::math::abs(diff) < 0.001
82 && bg::math::abs(diff_d1) < 0.001
83 && bg::math::abs(diff_d2) < 0.001;
84
85 BOOST_CHECK_MESSAGE(ok,
86 id << " diff: "
87 << diff << " d1: "
88 << diff_d1 << " d2: "
89 << diff_d2);
90 }
91
92 #if defined(TEST_WITH_SVG)
93 {
94 std::ostringstream filename;
95 filename << "assemble_" << id << "_" << operation << ".svg";
96 std::ofstream svg(filename.str().c_str());
97
98 bg::svg_mapper<typename bg::point_type<Geometry>::type> mapper(svg, 500, 500);
99 mapper.add(p);
100 mapper.add(q);
101 mapper.map(p, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:3");
102 mapper.map(q, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:3");
103 std::string linestyle = "opacity:0.7;fill:none;stroke-opacity:1;stroke-miterlimit:4;";
104
105 std::vector<Geometry> const& v = operation == 'i' ? i
106 : operation == 'u' ? u
107 : operation == 'd' ? d1
108 : d2
109 ;
110
111 for (Geometry const& geometry : v)
112 {
113 mapper.map(geometry,
114 linestyle + "stroke-width:3;stroke-linejoin:round;stroke-linecap:square;stroke-dasharray:12,12;stroke:rgb(255,0,0);");
115 }
116 }
117 #endif
118 }
119
120 template <typename Polygon>
121 inline bool int_ok(Polygon const& poly)
122 {
123 typename bg::point_type<Polygon>::type const& pi =
124 bg::interior_rings(poly)[0].front();
125
126 return bg::within(pi, bg::exterior_ring(poly));
127 }
128
129
130 template <typename T>
131 void generate()
132 {
133
134 static std::string exteriors[4] = {
135 "(0 0,0 10,10 10,10 0,0 0)",
136 "(1 1,1 9,8 9,8 1,1 1)",
137 "(2 0.5, 0.5 2,0.5 8,2 9.5,6 9.5,8.5 8,8.5 2,7 0.5,2 0.5)",
138 "(3 3,3 7,6 7,6 3,3 3)"
139 };
140 static std::string interiors[4] = {
141 "(2 2,2 8,7 8,7 2,2 2)",
142 "(8.5 1,8.5 2,9.5 2,9.5 1,8.5 1)",
143 "(4 4,4 5,5 5,5 4,4 4)",
144 "(6 4,6 5,9 5,9 4,6 4)"
145 };
146 for (int pe = 0; pe < 4; pe++)
147 {
148 for (int qe = 0; qe < 4; qe++)
149 {
150 for (int pi = 0; pi < 4; pi++)
151 {
152 for (int qi = 0; qi < 4; qi++)
153 {
154 std::string ps = "POLYGON(" + exteriors[pe] + "," + interiors[pi] + ")";
155 std::string qs = "POLYGON(" + exteriors[qe] + "," + interiors[qi] + ")";
156
157 typedef bg::model::d2::point_xy<T> point_type;
158 bg::model::polygon<point_type> p, q;
159 bg::read_wkt(ps, p);
160 bg::read_wkt(qs, q);
161 bg::correct(p);
162 bg::correct(q);
163 if (! bg::intersects(p)
164 && ! bg::intersects(q)
165 && int_ok(p)
166 && int_ok(q)
167 )
168 {
169 std::ostringstream out;
170 out << pe << qe << pi << qi;
171 test_assemble(out.str(), p, q);
172
173 #if defined(TEST_WITH_SVG)
174 test_assemble(out.str(), p, q, 'u');
175 test_assemble(out.str(), p, q, 'd');
176 test_assemble(out.str(), p, q, 'r');
177 #endif
178 }
179 }
180 }
181 }
182 }
183 }
184
185
186 #if ! defined(GEOMETRY_TEST_MULTI)
187 int test_main(int, char* [])
188 {
189 generate<double>();
190 return 0;
191 }
192 #endif