]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/intersection/areal_areal.hpp
update source to Ceph Pacific 16.2.2
[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 detail::intersection::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 detail::intersection::expect_output_pla
89 <
90 Areal1, Areal2, single_out
91 >
92 >();
93
94 typedef geometry::detail::output_geometry_access
95 <
96 single_out, polygon_tag, polygon_tag
97 > areal;
98 typedef geometry::detail::output_geometry_access
99 <
100 single_out, linestring_tag, linestring_tag
101 > linear;
102 typedef geometry::detail::output_geometry_access
103 <
104 single_out, point_tag, point_tag
105 > pointlike;
106
107 typedef typename geometry::tuples::element
108 <
109 areal::index, TupledOut
110 >::type areal_out_type;
111 typedef typename geometry::tuples::element
112 <
113 pointlike::index, TupledOut
114 >::type pointlike_out_type;
115
116 // NOTE: The same robust_policy is used in each call of
117 // intersection_insert. Is that correct?
118
119 // A * A -> A
120 call_intersection(areal1, areal2, robust_policy,
121 areal::get(geometry_out),
122 strategy);
123
124 bool const is_areal_empty = boost::empty(areal::get(geometry_out));
125 TupledOut temp_out;
126
127 // L * L -> (L, P)
128 call_intersection(geometry::detail::boundary_view<Areal1 const>(areal1),
129 geometry::detail::boundary_view<Areal2 const>(areal2),
130 robust_policy,
131 ! is_areal_empty
132 ? temp_out
133 : geometry_out,
134 strategy);
135
136 if (! is_areal_empty)
137 {
138 // NOTE: the original areal geometry could be used instead of boundary here
139 // however this results in static assert failure related to rescale policy
140 typedef geometry::detail::boundary_view
141 <
142 areal_out_type const
143 > areal_out_boundary_type;
144
145 areal_out_boundary_type areal_out_boundary(areal::get(geometry_out));
146
147 // L - L -> L
148 call_difference(linear::get(temp_out),
149 areal_out_boundary,
150 robust_policy,
151 linear::get(geometry_out),
152 strategy);
153
154 // P - L -> P
155 call_difference(pointlike::get(temp_out),
156 areal_out_boundary,
157 robust_policy,
158 pointlike::get(geometry_out),
159 strategy.template get_point_in_geometry_strategy
160 <
161 pointlike_out_type,
162 areal_out_boundary_type
163 >());
164 }
165
166 return;
167 }
168
169 private:
170 template
171 <
172 typename Geometry1,
173 typename Geometry2,
174 typename RobustPolicy,
175 typename GeometryOut,
176 typename Strategy
177 >
178 static inline void call_intersection(Geometry1 const& geometry1,
179 Geometry2 const& geometry2,
180 RobustPolicy const& robust_policy,
181 GeometryOut& geometry_out,
182 Strategy const& strategy)
183 {
184 geometry::dispatch::intersection_insert
185 <
186 Geometry1,
187 Geometry2,
188 typename geometry::detail::output_geometry_value
189 <
190 GeometryOut
191 >::type,
192 overlay_intersection
193 >::apply(geometry1,
194 geometry2,
195 robust_policy,
196 geometry::detail::output_geometry_back_inserter(geometry_out),
197 strategy);
198 }
199
200 template
201 <
202 typename Geometry1,
203 typename Geometry2,
204 typename RobustPolicy,
205 typename GeometryOut,
206 typename Strategy
207 >
208 static inline void call_difference(Geometry1 const& geometry1,
209 Geometry2 const& geometry2,
210 RobustPolicy const& robust_policy,
211 GeometryOut& geometry_out,
212 Strategy const& strategy)
213 {
214 geometry::dispatch::intersection_insert
215 <
216 Geometry1,
217 Geometry2,
218 typename boost::range_value<GeometryOut>::type,
219 overlay_difference
220 >::apply(geometry1,
221 geometry2,
222 robust_policy,
223 geometry::range::back_inserter(geometry_out),
224 strategy);
225 }
226 };
227
228
229 struct intersection_areal_areal
230 {
231 template
232 <
233 typename Areal1,
234 typename Areal2,
235 typename RobustPolicy,
236 typename GeometryOut,
237 typename Strategy
238 >
239 static inline bool apply(Areal1 const& areal1,
240 Areal2 const& areal2,
241 RobustPolicy const& robust_policy,
242 GeometryOut& geometry_out,
243 Strategy const& strategy)
244 {
245 intersection_areal_areal_
246 <
247 GeometryOut
248 >::apply(areal1, areal2, robust_policy, geometry_out, strategy);
249
250 return true;
251 }
252 };
253
254
255 }} // namespace detail::intersection
256 #endif // DOXYGEN_NO_DETAIL
257
258
259 #ifndef DOXYGEN_NO_DISPATCH
260 namespace dispatch
261 {
262
263
264 template
265 <
266 typename Polygon1, typename Polygon2
267 >
268 struct intersection
269 <
270 Polygon1, Polygon2,
271 polygon_tag, polygon_tag,
272 false
273 >
274 : detail::intersection::intersection_areal_areal
275 {};
276
277 template
278 <
279 typename Polygon, typename Ring
280 >
281 struct intersection
282 <
283 Polygon, Ring,
284 polygon_tag, ring_tag,
285 false
286 >
287 : detail::intersection::intersection_areal_areal
288 {};
289
290 template
291 <
292 typename Ring1, typename Ring2
293 >
294 struct intersection
295 <
296 Ring1, Ring2,
297 ring_tag, ring_tag,
298 false
299 >
300 : detail::intersection::intersection_areal_areal
301 {};
302
303 template
304 <
305 typename Polygon, typename MultiPolygon
306 >
307 struct intersection
308 <
309 Polygon, MultiPolygon,
310 polygon_tag, multi_polygon_tag,
311 false
312 >
313 : detail::intersection::intersection_areal_areal
314 {};
315
316 template
317 <
318 typename MultiPolygon, typename Ring
319 >
320 struct intersection
321 <
322 MultiPolygon, Ring,
323 multi_polygon_tag, ring_tag,
324 false
325 >
326 : detail::intersection::intersection_areal_areal
327 {};
328
329 template
330 <
331 typename MultiPolygon1, typename MultiPolygon2
332 >
333 struct intersection
334 <
335 MultiPolygon1, MultiPolygon2,
336 multi_polygon_tag, multi_polygon_tag,
337 false
338 >
339 : detail::intersection::intersection_areal_areal
340 {};
341
342
343 } // namespace dispatch
344 #endif // DOXYGEN_NO_DISPATCH
345
346 }} // namespace boost::geometry
347
348 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP