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