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