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