]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/test/algorithms/set_operations/test_set_ops_pointlike.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / set_operations / test_set_ops_pointlike.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
1e59de90 3// Copyright (c) 2014-2021, Oracle and/or its affiliates.
f67539c2
TL
4// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
5// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7c673cae
FG
6
7// Licensed under the Boost Software License version 1.0.
8// http://www.boost.org/users/license.html
9
7c673cae
FG
10#ifndef BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP
11#define BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP
12
13
7c673cae 14#include <from_wkt.hpp>
7c673cae
FG
15
16#include <algorithm>
17#include <fstream>
7c673cae 18
1e59de90
TL
19#include <boost/core/ignore_unused.hpp>
20#include <boost/range/begin.hpp>
21#include <boost/range/end.hpp>
22#include <boost/range/size.hpp>
7c673cae 23
1e59de90 24#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
7c673cae 25#include <boost/geometry/algorithms/difference.hpp>
1e59de90 26#include <boost/geometry/algorithms/equals.hpp>
7c673cae
FG
27#include <boost/geometry/algorithms/intersection.hpp>
28#include <boost/geometry/algorithms/sym_difference.hpp>
1e59de90
TL
29#include <boost/geometry/algorithms/union.hpp>
30#include <boost/geometry/io/wkt/write.hpp>
31#include <boost/geometry/policies/compare.hpp>
7c673cae 32
1e59de90
TL
33#if defined(TEST_WITH_SVG)
34#include <boost/geometry/io/svg/svg_mapper.hpp>
35#endif
36
37namespace bg = ::boost::geometry;
7c673cae
FG
38
39
40//==================================================================
41//==================================================================
42// svg output
43//==================================================================
44//==================================================================
45
46template <typename Output, typename G1, typename G2>
47void set_operation_output(std::string const& set_op_id,
48 std::string const& caseid,
49 G1 const& g1, G2 const& g2,
50 Output const& output)
51{
52 boost::ignore_unused(set_op_id, caseid, g1, g2, output);
53
54#if defined(TEST_WITH_SVG)
7c673cae
FG
55
56 std::ostringstream filename;
57 filename << "svgs/" << set_op_id << "_" << caseid << ".svg";
58
59 std::ofstream svg(filename.str().c_str());
60
1e59de90 61 bg::svg_mapper<typename bg::point_type<G1>::type> mapper(svg, 500, 500);
7c673cae
FG
62
63 mapper.add(g1);
64 mapper.add(g2);
65
66 mapper.map(g2, "stroke-opacity:1;stroke:rgb(153,204,0);stroke-width:4");
67 mapper.map(g1, "stroke-opacity:1;stroke:rgb(51,51,153);stroke-width:2");
68
1e59de90 69 for (auto it = output.begin(); it != output.end(); ++it)
7c673cae
FG
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
86struct 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
1e59de90
TL
105 auto it1 = boost::begin(mp1);
106 auto it2 = boost::begin(mp2);
7c673cae
FG
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
126template <bg::overlay_type OverlayType> struct set_op;
127
128
129template<>
130struct 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
144template<>
145struct 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
159template<>
160struct 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
174template
175<
176 typename Geometry,
177 typename Tag = typename bg::tag<Geometry>::type
178> struct geometry_info
179{};
180
181template <typename Point>
182struct geometry_info<Point, bg::point_tag>
183{
184 static std::size_t const topological_dimension = 0;
185
f67539c2 186 static inline char const* name() { return "Pt"; }
7c673cae
FG
187};
188
189template <typename MultiPoint>
190struct geometry_info<MultiPoint, bg::multi_point_tag>
191{
192 static std::size_t const topological_dimension = 0;
193
f67539c2 194 static inline char const* name() { return "MPt"; }
7c673cae
FG
195};
196
197template <typename Linestring>
198struct 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
205template <typename MultiLinestring>
206struct 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
213template <typename Segment>
214struct 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
f67539c2
TL
221template <typename Ring>
222struct geometry_info<Ring, bg::ring_tag>
223{
224 static std::size_t const topological_dimension = 2;
225
226 static inline char const* name() { return "R"; }
227};
228
229template <typename Polygon>
230struct geometry_info<Polygon, bg::polygon_tag>
231{
232 static std::size_t const topological_dimension = 2;
233
234 static inline char const* name() { return "Po"; }
235};
7c673cae 236
f67539c2
TL
237template <typename MultiPolygon>
238struct geometry_info<MultiPolygon, bg::multi_polygon_tag>
239{
240 static std::size_t const topological_dimension = 2;
241
242 static inline char const* name() { return "MPo"; }
243};
7c673cae
FG
244
245//==================================================================
246//==================================================================
247// test the set operation of (point-like) geometries
248//==================================================================
249//==================================================================
250
251
252template
253<
254 typename Geometry1,
255 typename Geometry2,
256 typename MultiPoint,
257 bg::overlay_type OverlayType
258>
259class test_set_op_of_pointlike_geometries
260{
261private:
262 template <bool Enable, typename Dummy = void>
263 struct base_test
264 {
265 template <typename G1, typename G2, typename MP>
266 static inline void apply(std::string const& case_id,
267 G1 const& geometry1,
268 G2 const& geometry2,
269 MP const& mp_expected)
270 {
271 MultiPoint mp_output;
272
273 set_op<OverlayType>::apply(geometry1, geometry2, mp_output);
274
275 std::string op_name = set_op<OverlayType>::name();
276
277 BOOST_CHECK_MESSAGE(equals::apply(mp_expected, mp_output),
278 "case ID: " << case_id << ", "
279 << op_name << " "
280 << geometry_info<G1>::name() << "/"
281 << geometry_info<G2>::name() << ": "
282 << bg::wkt(geometry1)
283 << " " << bg::wkt(geometry2)
284 << " -> Expected: " << bg::wkt(mp_expected)
285 << " computed: " << bg::wkt(mp_output) );
286
287 set_operation_output(op_name, case_id,
288 geometry1, geometry2, mp_output);
289
290#ifdef BOOST_GEOMETRY_TEST_DEBUG
291 std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
292 std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
293 std::cout << "expected " << op_name << " : "
294 << bg::wkt(mp_expected) << std::endl;
295 std::cout << op_name << " : " << bg::wkt(mp_output) << std::endl;
296 std::cout << std::endl;
297 std::cout << "************************************" << std::endl;
298 std::cout << std::endl;
299 std::cout << std::endl;
300#endif
301 }
302 };
303
304 template <typename Dummy>
305 struct base_test<false, Dummy>
306 {
307 template <typename G1, typename G2, typename MP>
308 static inline void apply(std::string const&, G1 const&, G2 const&,
309 MP const&)
310 {
311 }
312 };
313
314public:
315 static inline void apply(std::string const& case_id,
316 Geometry1 const& geometry1,
317 Geometry2 const& geometry2,
318 MultiPoint const& mp_expected12,
319 MultiPoint const& mp_expected21)
320 {
321#ifdef BOOST_GEOMETRY_TEST_DEBUG
322 std::cout << "test case: " << case_id << std::endl;
323#endif
324
325 base_test<true>::apply(case_id, geometry1, geometry2, mp_expected12);
326 // try the same set operation with the arguments' order
327 // reversed only if the two geometries are of the same
328 // topological dimension
329 base_test
330 <
331 (geometry_info<Geometry1>::topological_dimension
332 == geometry_info<Geometry2>::topological_dimension)
333 >::apply(case_id, geometry2, geometry1, mp_expected21);
334
335#ifdef BOOST_GEOMETRY_TEST_DEBUG
336 std::cout << std::endl;
337 std::cout << std::endl;
338#endif
339 }
340
341 static inline void apply(std::string const& case_id,
342 Geometry1 const& geometry1,
343 Geometry2 const& geometry2,
344 MultiPoint const& mp_expected)
345 {
346 apply(case_id, geometry1, geometry2, mp_expected, mp_expected);
347 }
348};
349
350
351#endif // BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP