]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/set_operations/test_set_ops_pointlike.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / set_operations / test_set_ops_pointlike.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2014-2015, Oracle and/or its affiliates.
4
5 // Licensed under the Boost Software License version 1.0.
6 // http://www.boost.org/users/license.html
7
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9
10 #ifndef BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP
11 #define BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP
12
13
14 #include <boost/geometry/geometry.hpp>
15
16 namespace bg = ::boost::geometry;
17
18 #include <from_wkt.hpp>
19 #include <to_svg.hpp>
20
21 #include <algorithm>
22 #include <fstream>
23 #include <boost/core/ignore_unused.hpp>
24 #include <boost/typeof/typeof.hpp>
25
26 #include <boost/geometry/policies/compare.hpp>
27 #include <boost/geometry/algorithms/equals.hpp>
28
29 #include <boost/geometry/algorithms/union.hpp>
30 #include <boost/geometry/algorithms/difference.hpp>
31 #include <boost/geometry/algorithms/intersection.hpp>
32 #include <boost/geometry/algorithms/sym_difference.hpp>
33
34 #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
35
36
37 //==================================================================
38 //==================================================================
39 // svg output
40 //==================================================================
41 //==================================================================
42
43 template <typename Output, typename G1, typename G2>
44 void set_operation_output(std::string const& set_op_id,
45 std::string const& caseid,
46 G1 const& g1, G2 const& g2,
47 Output const& output)
48 {
49 boost::ignore_unused(set_op_id, caseid, g1, g2, output);
50
51 #if defined(TEST_WITH_SVG)
52 typedef typename bg::coordinate_type<G1>::type coordinate_type;
53 typedef typename bg::point_type<G1>::type point_type;
54
55 std::ostringstream filename;
56 filename << "svgs/" << set_op_id << "_" << caseid << ".svg";
57
58 std::ofstream svg(filename.str().c_str());
59
60 bg::svg_mapper<point_type> mapper(svg, 500, 500);
61
62 mapper.add(g1);
63 mapper.add(g2);
64
65 mapper.map(g2, "stroke-opacity:1;stroke:rgb(153,204,0);stroke-width:4");
66 mapper.map(g1, "stroke-opacity:1;stroke:rgb(51,51,153);stroke-width:2");
67
68 BOOST_AUTO_TPL(it, output.begin());
69 for (; it != output.end(); ++it)
70 {
71 mapper.map(*it,
72 "fill:rgb(255,0,255);stroke:rgb(0,0,0);stroke-width:1",
73 4);
74 }
75 #endif
76 }
77
78
79 //==================================================================
80 //==================================================================
81 // testing equality of multi-points
82 //==================================================================
83 //==================================================================
84
85
86 struct equals
87 {
88 template <typename MultiPoint1, typename MultiPoint2>
89 static inline bool apply(MultiPoint1 const& multipoint1,
90 MultiPoint2 const& multipoint2)
91 {
92 MultiPoint1 mp1(multipoint1);
93 MultiPoint2 mp2(multipoint2);
94
95 std::sort(mp1.begin(), mp1.end(),
96 bg::less<typename bg::point_type<MultiPoint1>::type>());
97 std::sort(mp2.begin(), mp2.end(),
98 bg::less<typename bg::point_type<MultiPoint2>::type>());
99
100 if ( boost::size(mp1) != boost::size(mp2) )
101 {
102 return false;
103 }
104
105 BOOST_AUTO_TPL(it1, boost::begin(mp1));
106 BOOST_AUTO_TPL(it2, boost::begin(mp2));
107 for (; it1 != boost::end(mp1); ++it1, ++it2)
108 {
109 if ( !bg::equals(*it1, *it2) )
110 {
111 return false;
112 }
113 }
114 return true;
115 }
116 };
117
118
119
120 //==================================================================
121 //==================================================================
122 // struct for calling the appropriate set op function
123 //==================================================================
124 //==================================================================
125
126 template <bg::overlay_type OverlayType> struct set_op;
127
128
129 template<>
130 struct set_op<bg::overlay_difference>
131 {
132 static inline std::string name() { return "difference"; }
133
134 template <typename Geometry1, typename Geometry2, typename GeometryOut>
135 static inline void apply(Geometry1 const& g1,
136 Geometry2 const& g2,
137 GeometryOut& gout)
138 {
139 bg::difference(g1, g2, gout);
140 }
141 };
142
143
144 template<>
145 struct set_op<bg::overlay_union>
146 {
147 static inline std::string name() { return "union"; }
148
149 template <typename Geometry1, typename Geometry2, typename GeometryOut>
150 static inline void apply(Geometry1 const& g1,
151 Geometry2 const& g2,
152 GeometryOut& gout)
153 {
154 bg::union_(g1, g2, gout);
155 }
156 };
157
158
159 template<>
160 struct set_op<bg::overlay_intersection>
161 {
162 static inline std::string name() { return "intersection"; }
163
164 template <typename Geometry1, typename Geometry2, typename GeometryOut>
165 static inline void apply(Geometry1 const& g1,
166 Geometry2 const& g2,
167 GeometryOut& gout)
168 {
169 bg::intersection(g1, g2, gout);
170 }
171 };
172
173
174 template
175 <
176 typename Geometry,
177 typename Tag = typename bg::tag<Geometry>::type
178 > struct geometry_info
179 {};
180
181 template <typename Point>
182 struct geometry_info<Point, bg::point_tag>
183 {
184 static std::size_t const topological_dimension = 0;
185
186 static inline char const* name() { return "P"; }
187 };
188
189 template <typename MultiPoint>
190 struct geometry_info<MultiPoint, bg::multi_point_tag>
191 {
192 static std::size_t const topological_dimension = 0;
193
194 static inline char const* name() { return "MP"; }
195 };
196
197 template <typename Linestring>
198 struct geometry_info<Linestring, bg::linestring_tag>
199 {
200 static std::size_t const topological_dimension = 1;
201
202 static inline char const* name() { return "L"; }
203 };
204
205 template <typename MultiLinestring>
206 struct geometry_info<MultiLinestring, bg::multi_linestring_tag>
207 {
208 static std::size_t const topological_dimension = 1;
209
210 static inline char const* name() { return "ML"; }
211 };
212
213 template <typename Segment>
214 struct geometry_info<Segment, bg::segment_tag>
215 {
216 static std::size_t const topological_dimension = 1;
217
218 static inline char const* name() { return "S"; }
219 };
220
221
222
223 //==================================================================
224 //==================================================================
225 // test the set operation of (point-like) geometries
226 //==================================================================
227 //==================================================================
228
229
230 template
231 <
232 typename Geometry1,
233 typename Geometry2,
234 typename MultiPoint,
235 bg::overlay_type OverlayType
236 >
237 class test_set_op_of_pointlike_geometries
238 {
239 private:
240 template <bool Enable, typename Dummy = void>
241 struct base_test
242 {
243 template <typename G1, typename G2, typename MP>
244 static inline void apply(std::string const& case_id,
245 G1 const& geometry1,
246 G2 const& geometry2,
247 MP const& mp_expected)
248 {
249 MultiPoint mp_output;
250
251 set_op<OverlayType>::apply(geometry1, geometry2, mp_output);
252
253 std::string op_name = set_op<OverlayType>::name();
254
255 BOOST_CHECK_MESSAGE(equals::apply(mp_expected, mp_output),
256 "case ID: " << case_id << ", "
257 << op_name << " "
258 << geometry_info<G1>::name() << "/"
259 << geometry_info<G2>::name() << ": "
260 << bg::wkt(geometry1)
261 << " " << bg::wkt(geometry2)
262 << " -> Expected: " << bg::wkt(mp_expected)
263 << " computed: " << bg::wkt(mp_output) );
264
265 set_operation_output(op_name, case_id,
266 geometry1, geometry2, mp_output);
267
268 #ifdef BOOST_GEOMETRY_TEST_DEBUG
269 std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
270 std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
271 std::cout << "expected " << op_name << " : "
272 << bg::wkt(mp_expected) << std::endl;
273 std::cout << op_name << " : " << bg::wkt(mp_output) << std::endl;
274 std::cout << std::endl;
275 std::cout << "************************************" << std::endl;
276 std::cout << std::endl;
277 std::cout << std::endl;
278 #endif
279 }
280 };
281
282 template <typename Dummy>
283 struct base_test<false, Dummy>
284 {
285 template <typename G1, typename G2, typename MP>
286 static inline void apply(std::string const&, G1 const&, G2 const&,
287 MP const&)
288 {
289 }
290 };
291
292 public:
293 static inline void apply(std::string const& case_id,
294 Geometry1 const& geometry1,
295 Geometry2 const& geometry2,
296 MultiPoint const& mp_expected12,
297 MultiPoint const& mp_expected21)
298 {
299 #ifdef BOOST_GEOMETRY_TEST_DEBUG
300 std::cout << "test case: " << case_id << std::endl;
301 #endif
302
303 base_test<true>::apply(case_id, geometry1, geometry2, mp_expected12);
304 // try the same set operation with the arguments' order
305 // reversed only if the two geometries are of the same
306 // topological dimension
307 base_test
308 <
309 (geometry_info<Geometry1>::topological_dimension
310 == geometry_info<Geometry2>::topological_dimension)
311 >::apply(case_id, geometry2, geometry1, mp_expected21);
312
313 #ifdef BOOST_GEOMETRY_TEST_DEBUG
314 std::cout << std::endl;
315 std::cout << std::endl;
316 #endif
317 }
318
319 static inline void apply(std::string const& case_id,
320 Geometry1 const& geometry1,
321 Geometry2 const& geometry2,
322 MultiPoint const& mp_expected)
323 {
324 apply(case_id, geometry1, geometry2, mp_expected, mp_expected);
325 }
326 };
327
328
329 #endif // BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP