]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/algorithms/sym_difference.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / algorithms / sym_difference.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4
5// This file was modified by Oracle on 2015.
6// Modifications copyright (c) 2015 Oracle and/or its affiliates.
7
8// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9
10// Use, modification and distribution is subject to the Boost Software License,
11// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12// http://www.boost.org/LICENSE_1_0.txt)
13
14#ifndef BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
15#define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
16
17#include <algorithm>
18#include <iterator>
19#include <vector>
20
21#include <boost/geometry/algorithms/intersection.hpp>
22#include <boost/geometry/algorithms/union.hpp>
23#include <boost/geometry/geometries/multi_polygon.hpp>
24
25
26namespace boost { namespace geometry
27{
28
29#ifndef DOXYGEN_NO_DETAIL
30namespace detail { namespace sym_difference
31{
32
33
34template <typename GeometryOut>
35struct compute_difference
36{
37 template
38 <
39 typename Geometry1,
40 typename Geometry2,
41 typename RobustPolicy,
42 typename OutputIterator,
43 typename Strategy
44 >
45 static inline OutputIterator apply(Geometry1 const& geometry1,
46 Geometry2 const& geometry2,
47 RobustPolicy const& robust_policy,
48 OutputIterator out,
49 Strategy const& strategy)
50 {
51 return geometry::dispatch::intersection_insert
52 <
53 Geometry1,
54 Geometry2,
55 GeometryOut,
56 overlay_difference,
57 geometry::detail::overlay::do_reverse
58 <
59 geometry::point_order<Geometry1>::value
60 >::value,
61 geometry::detail::overlay::do_reverse
62 <
63 geometry::point_order<Geometry2>::value, true
64 >::value
65 >::apply(geometry1, geometry2, robust_policy, out, strategy);
66 }
67};
68
69
70
71template <typename GeometryOut, typename Geometry1, typename Geometry2>
72struct sym_difference_generic
73{
74 template
75 <
76 typename RobustPolicy,
77 typename OutputIterator,
78 typename Strategy
79 >
80 static inline OutputIterator apply(Geometry1 const& geometry1,
81 Geometry2 const& geometry2,
82 RobustPolicy const& robust_policy,
83 OutputIterator out,
84 Strategy const& strategy)
85 {
86 out = compute_difference
87 <
88 GeometryOut
89 >::apply(geometry1, geometry2, robust_policy, out, strategy);
90
91 return compute_difference
92 <
93 GeometryOut
94 >::apply(geometry2, geometry1, robust_policy, out, strategy);
95 }
96};
97
98
99template <typename GeometryOut, typename Areal1, typename Areal2>
100struct sym_difference_areal_areal
101{
102 template
103 <
104 typename RobustPolicy,
105 typename OutputIterator,
106 typename Strategy
107 >
108 static inline OutputIterator apply(Areal1 const& areal1,
109 Areal2 const& areal2,
110 RobustPolicy const& robust_policy,
111 OutputIterator out,
112 Strategy const& strategy)
113 {
114 typedef geometry::model::multi_polygon
115 <
116 GeometryOut
117 > helper_geometry_type;
118
119 helper_geometry_type diff12, diff21;
120
121 std::back_insert_iterator<helper_geometry_type> oit12(diff12);
122 std::back_insert_iterator<helper_geometry_type> oit21(diff21);
123
124 compute_difference
125 <
126 GeometryOut
127 >::apply(areal1, areal2, robust_policy, oit12, strategy);
128
129 compute_difference
130 <
131 GeometryOut
132 >::apply(areal2, areal1, robust_policy, oit21, strategy);
133
134 return geometry::dispatch::union_insert
135 <
136 helper_geometry_type,
137 helper_geometry_type,
138 GeometryOut
139 >::apply(diff12, diff21, robust_policy, out, strategy);
140 }
141};
142
143
144}} // namespace detail::sym_difference
145#endif // DOXYGEN_NO_DETAIL
146
147
148
149#ifndef DOXYGEN_NO_DISPATCH
150namespace dispatch
151{
152
153
154template
155<
156 typename Geometry1,
157 typename Geometry2,
158 typename GeometryOut,
159 typename TagIn1 = typename geometry::tag_cast
160 <
161 typename tag<Geometry1>::type, areal_tag
162 >::type,
163 typename TagIn2 = typename geometry::tag_cast
164 <
165 typename tag<Geometry2>::type, areal_tag
166 >::type,
167 typename TagOut = typename geometry::tag<GeometryOut>::type
168>
169struct sym_difference_insert
170 : detail::sym_difference::sym_difference_generic
171 <
172 GeometryOut, Geometry1, Geometry2
173 >
174{};
175
176
177template
178<
179 typename Areal1,
180 typename Areal2,
181 typename GeometryOut,
182 typename TagOut
183>
184struct sym_difference_insert
185 <
186 Areal1, Areal2, GeometryOut,
187 areal_tag, areal_tag, TagOut
188 > : detail::sym_difference::sym_difference_areal_areal
189 <
190 GeometryOut, Areal1, Areal2
191 >
192{};
193
194
195} // namespace dispatch
196#endif // DOXYGEN_NO_DISPATCH
197
198
199
200#ifndef DOXYGEN_NO_DETAIL
201namespace detail { namespace sym_difference
202{
203
204
205
206/*!
207\brief \brief_calc2{symmetric difference} \brief_strategy
208\ingroup sym_difference
209\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
210 \brief_strategy. \details_insert{sym_difference}
211\tparam GeometryOut output geometry type, must be specified
212\tparam Geometry1 \tparam_geometry
213\tparam Geometry2 \tparam_geometry
214\tparam Strategy \tparam_strategy_overlay
215\param geometry1 \param_geometry
216\param geometry2 \param_geometry
217\param out \param_out{difference}
218\param strategy \param_strategy{difference}
219\return \return_out
220
221\qbk{distinguish,with strategy}
222*/
223template
224<
225 typename GeometryOut,
226 typename Geometry1,
227 typename Geometry2,
228 typename RobustPolicy,
229 typename OutputIterator,
230 typename Strategy
231>
232inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
233 Geometry2 const& geometry2,
234 RobustPolicy const& robust_policy,
235 OutputIterator out,
236 Strategy const& strategy)
237{
238 concepts::check<Geometry1 const>();
239 concepts::check<Geometry2 const>();
240 concepts::check<GeometryOut>();
241
242 return dispatch::sym_difference_insert
243 <
244 Geometry1, Geometry2, GeometryOut
245 >::apply(geometry1, geometry2, robust_policy, out, strategy);
246}
247
248
249/*!
250\brief \brief_calc2{symmetric difference}
251\ingroup sym_difference
252\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
253 \details_insert{sym_difference}
254\tparam GeometryOut output geometry type, must be specified
255\tparam Geometry1 \tparam_geometry
256\tparam Geometry2 \tparam_geometry
257\param geometry1 \param_geometry
258\param geometry2 \param_geometry
259\param out \param_out{difference}
260\return \return_out
261
262*/
263template
264<
265 typename GeometryOut,
266 typename Geometry1,
267 typename Geometry2,
268 typename RobustPolicy,
269 typename OutputIterator
270>
271inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
272 Geometry2 const& geometry2,
273 RobustPolicy const& robust_policy, OutputIterator out)
274{
275 concepts::check<Geometry1 const>();
276 concepts::check<Geometry2 const>();
277 concepts::check<GeometryOut>();
278
279 typedef intersection_strategies
280 <
281 typename cs_tag<GeometryOut>::type,
282 Geometry1,
283 Geometry2,
284 typename geometry::point_type<GeometryOut>::type,
285 RobustPolicy
286 > strategy_type;
287
288 return sym_difference_insert<GeometryOut>(geometry1, geometry2, robust_policy, out, strategy_type());
289}
290
291}} // namespace detail::sym_difference
292#endif // DOXYGEN_NO_DETAIL
293
294
295/*!
296\brief \brief_calc2{symmetric difference}
297\ingroup sym_difference
298\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
299\tparam Geometry1 \tparam_geometry
300\tparam Geometry2 \tparam_geometry
301\tparam Collection output collection, either a multi-geometry,
302 or a std::vector<Geometry> / std::deque<Geometry> etc
303\param geometry1 \param_geometry
304\param geometry2 \param_geometry
305\param output_collection the output collection
306
307\qbk{[include reference/algorithms/sym_difference.qbk]}
308*/
309template
310<
311 typename Geometry1,
312 typename Geometry2,
313 typename Collection
314>
315inline void sym_difference(Geometry1 const& geometry1,
316 Geometry2 const& geometry2, Collection& output_collection)
317{
318 concepts::check<Geometry1 const>();
319 concepts::check<Geometry2 const>();
320
321 typedef typename boost::range_value<Collection>::type geometry_out;
322 concepts::check<geometry_out>();
323
324 typedef typename geometry::rescale_overlay_policy_type
325 <
326 Geometry1,
327 Geometry2
328 >::type rescale_policy_type;
329
330 rescale_policy_type robust_policy
331 = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
332
333 detail::sym_difference::sym_difference_insert<geometry_out>(
334 geometry1, geometry2, robust_policy,
335 range::back_inserter(output_collection));
336}
337
338
339}} // namespace boost::geometry
340
341
342#endif // BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP