]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/intersection/areal_areal.hpp
994c3c7daaa6abe18a0164e3eb0c8e0a92a35166
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / intersection / areal_areal.hpp
1 // Boost.Geometry
2
3 // Copyright (c) 2020, Oracle and/or its affiliates.
4 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
5
6 // Licensed under the Boost Software License version 1.0.
7 // http://www.boost.org/users/license.html
8
9 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP
10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP
11
12
13 #include <boost/core/ignore_unused.hpp>
14
15 #include <boost/geometry/algorithms/detail/intersection/interface.hpp>
16
17
18 namespace boost { namespace geometry
19 {
20
21 #ifndef DOXYGEN_NO_DETAIL
22 namespace detail { namespace intersection
23 {
24
25
26 template
27 <
28 typename GeometryOut,
29 typename OutTag = typename geometry::detail::setop_insert_output_tag
30 <
31 typename geometry::detail::output_geometry_value
32 <
33 GeometryOut
34 >::type
35 >::type
36 >
37 struct intersection_areal_areal_
38 {
39 template
40 <
41 typename Areal1,
42 typename Areal2,
43 typename RobustPolicy,
44 typename Strategy
45 >
46 static inline void apply(Areal1 const& areal1,
47 Areal2 const& areal2,
48 RobustPolicy const& robust_policy,
49 GeometryOut& geometry_out,
50 Strategy const& strategy)
51 {
52 geometry::dispatch::intersection_insert
53 <
54 Areal1, Areal2,
55 typename boost::range_value<GeometryOut>::type,
56 overlay_intersection
57 >::apply(areal1, areal2, robust_policy,
58 geometry::range::back_inserter(geometry_out),
59 strategy);
60 }
61 };
62
63 // TODO: Ideally this should be done in one call of intersection_insert
64 // just like it's done for all other combinations
65 template <typename TupledOut>
66 struct intersection_areal_areal_<TupledOut, tupled_output_tag>
67 {
68 template
69 <
70 typename Areal1,
71 typename Areal2,
72 typename RobustPolicy,
73 typename Strategy
74 >
75 static inline void apply(Areal1 const& areal1,
76 Areal2 const& areal2,
77 RobustPolicy const& robust_policy,
78 TupledOut& geometry_out,
79 Strategy const& strategy)
80 {
81 typedef typename geometry::detail::output_geometry_value
82 <
83 TupledOut
84 >::type single_out;
85
86 boost::ignore_unused
87 <
88 geometry::detail::expect_output
89 <
90 Areal1, Areal2, single_out,
91 point_tag, linestring_tag, polygon_tag
92 >
93 >();
94
95 typedef geometry::detail::output_geometry_access
96 <
97 single_out, polygon_tag, polygon_tag
98 > areal;
99 typedef geometry::detail::output_geometry_access
100 <
101 single_out, linestring_tag, linestring_tag
102 > linear;
103 typedef geometry::detail::output_geometry_access
104 <
105 single_out, point_tag, point_tag
106 > pointlike;
107
108 typedef typename geometry::tuples::element
109 <
110 areal::index, TupledOut
111 >::type areal_out_type;
112 typedef typename geometry::tuples::element
113 <
114 pointlike::index, TupledOut
115 >::type pointlike_out_type;
116
117 // NOTE: The same robust_policy is used in each call of
118 // intersection_insert. Is that correct?
119
120 // A * A -> A
121 call_intersection(areal1, areal2, robust_policy,
122 areal::get(geometry_out),
123 strategy);
124
125 bool const is_areal_empty = boost::empty(areal::get(geometry_out));
126 TupledOut temp_out;
127
128 // L * L -> (L, P)
129 call_intersection(geometry::detail::boundary_view<Areal1 const>(areal1),
130 geometry::detail::boundary_view<Areal2 const>(areal2),
131 robust_policy,
132 ! is_areal_empty
133 ? temp_out
134 : geometry_out,
135 strategy);
136
137 if (! is_areal_empty)
138 {
139 // NOTE: the original areal geometry could be used instead of boundary here
140 // however this results in static assert failure related to rescale policy
141 typedef geometry::detail::boundary_view
142 <
143 areal_out_type const
144 > areal_out_boundary_type;
145
146 areal_out_boundary_type areal_out_boundary(areal::get(geometry_out));
147
148 // L - L -> L
149 call_difference(linear::get(temp_out),
150 areal_out_boundary,
151 robust_policy,
152 linear::get(geometry_out),
153 strategy);
154
155 // P - L -> P
156 call_difference(pointlike::get(temp_out),
157 areal_out_boundary,
158 robust_policy,
159 pointlike::get(geometry_out),
160 strategy.template get_point_in_geometry_strategy
161 <
162 pointlike_out_type,
163 areal_out_boundary_type
164 >());
165 }
166
167 return;
168 }
169
170 private:
171 template
172 <
173 typename Geometry1,
174 typename Geometry2,
175 typename RobustPolicy,
176 typename GeometryOut,
177 typename Strategy
178 >
179 static inline void call_intersection(Geometry1 const& geometry1,
180 Geometry2 const& geometry2,
181 RobustPolicy const& robust_policy,
182 GeometryOut& geometry_out,
183 Strategy const& strategy)
184 {
185 geometry::dispatch::intersection_insert
186 <
187 Geometry1,
188 Geometry2,
189 typename geometry::detail::output_geometry_value
190 <
191 GeometryOut
192 >::type,
193 overlay_intersection
194 >::apply(geometry1,
195 geometry2,
196 robust_policy,
197 geometry::detail::output_geometry_back_inserter(geometry_out),
198 strategy);
199 }
200
201 template
202 <
203 typename Geometry1,
204 typename Geometry2,
205 typename RobustPolicy,
206 typename GeometryOut,
207 typename Strategy
208 >
209 static inline void call_difference(Geometry1 const& geometry1,
210 Geometry2 const& geometry2,
211 RobustPolicy const& robust_policy,
212 GeometryOut& geometry_out,
213 Strategy const& strategy)
214 {
215 geometry::dispatch::intersection_insert
216 <
217 Geometry1,
218 Geometry2,
219 typename boost::range_value<GeometryOut>::type,
220 overlay_difference
221 >::apply(geometry1,
222 geometry2,
223 robust_policy,
224 geometry::range::back_inserter(geometry_out),
225 strategy);
226 }
227 };
228
229
230 struct intersection_areal_areal
231 {
232 template
233 <
234 typename Areal1,
235 typename Areal2,
236 typename RobustPolicy,
237 typename GeometryOut,
238 typename Strategy
239 >
240 static inline bool apply(Areal1 const& areal1,
241 Areal2 const& areal2,
242 RobustPolicy const& robust_policy,
243 GeometryOut& geometry_out,
244 Strategy const& strategy)
245 {
246 intersection_areal_areal_
247 <
248 GeometryOut
249 >::apply(areal1, areal2, robust_policy, geometry_out, strategy);
250
251 return true;
252 }
253 };
254
255
256 }} // namespace detail::intersection
257 #endif // DOXYGEN_NO_DETAIL
258
259
260 #ifndef DOXYGEN_NO_DISPATCH
261 namespace dispatch
262 {
263
264
265 template
266 <
267 typename Polygon1, typename Polygon2
268 >
269 struct intersection
270 <
271 Polygon1, Polygon2,
272 polygon_tag, polygon_tag,
273 false
274 >
275 : detail::intersection::intersection_areal_areal
276 {};
277
278 template
279 <
280 typename Polygon, typename Ring
281 >
282 struct intersection
283 <
284 Polygon, Ring,
285 polygon_tag, ring_tag,
286 false
287 >
288 : detail::intersection::intersection_areal_areal
289 {};
290
291 template
292 <
293 typename Ring1, typename Ring2
294 >
295 struct intersection
296 <
297 Ring1, Ring2,
298 ring_tag, ring_tag,
299 false
300 >
301 : detail::intersection::intersection_areal_areal
302 {};
303
304 template
305 <
306 typename Polygon, typename MultiPolygon
307 >
308 struct intersection
309 <
310 Polygon, MultiPolygon,
311 polygon_tag, multi_polygon_tag,
312 false
313 >
314 : detail::intersection::intersection_areal_areal
315 {};
316
317 template
318 <
319 typename MultiPolygon, typename Ring
320 >
321 struct intersection
322 <
323 MultiPolygon, Ring,
324 multi_polygon_tag, ring_tag,
325 false
326 >
327 : detail::intersection::intersection_areal_areal
328 {};
329
330 template
331 <
332 typename MultiPolygon1, typename MultiPolygon2
333 >
334 struct intersection
335 <
336 MultiPolygon1, MultiPolygon2,
337 multi_polygon_tag, multi_polygon_tag,
338 false
339 >
340 : detail::intersection::intersection_areal_areal
341 {};
342
343
344 } // namespace dispatch
345 #endif // DOXYGEN_NO_DISPATCH
346
347 }} // namespace boost::geometry
348
349 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP