]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / overlay / copy_segment_point.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4
5 // This file was modified by Oracle on 2020.
6 // Modifications copyright (c) 2020, Oracle and/or its affiliates.
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8
9 // Use, modification and distribution is subject to the Boost Software License,
10 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12
13 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
14 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
15
16
17 #include <boost/array.hpp>
18 #include <boost/range/begin.hpp>
19 #include <boost/range/end.hpp>
20 #include <boost/range/size.hpp>
21 #include <boost/range/value_type.hpp>
22
23 #include <boost/geometry/algorithms/convert.hpp>
24 #include <boost/geometry/algorithms/detail/signed_size_type.hpp>
25 #include <boost/geometry/core/assert.hpp>
26 #include <boost/geometry/core/exterior_ring.hpp>
27 #include <boost/geometry/core/interior_rings.hpp>
28 #include <boost/geometry/core/ring_type.hpp>
29 #include <boost/geometry/core/static_assert.hpp>
30 #include <boost/geometry/core/tags.hpp>
31 #include <boost/geometry/geometries/concepts/check.hpp>
32 #include <boost/geometry/iterators/ever_circling_iterator.hpp>
33 #include <boost/geometry/util/range.hpp>
34 #include <boost/geometry/views/closeable_view.hpp>
35 #include <boost/geometry/views/reversible_view.hpp>
36
37
38 namespace boost { namespace geometry
39 {
40
41
42 #ifndef DOXYGEN_NO_DETAIL
43 namespace detail { namespace copy_segments
44 {
45
46
47 template <typename Range, bool Reverse, typename SegmentIdentifier, typename PointOut>
48 struct copy_segment_point_range
49 {
50 static inline bool apply(Range const& range,
51 SegmentIdentifier const& seg_id, int offset,
52 PointOut& point)
53 {
54 typedef typename closeable_view
55 <
56 Range const,
57 closure<Range>::value
58 >::type cview_type;
59
60 typedef typename reversible_view
61 <
62 cview_type const,
63 Reverse ? iterate_reverse : iterate_forward
64 >::type rview_type;
65
66 cview_type cview(range);
67 rview_type view(cview);
68
69 typedef typename boost::range_iterator<rview_type>::type iterator;
70 geometry::ever_circling_iterator<iterator> it(boost::begin(view), boost::end(view),
71 boost::begin(view) + seg_id.segment_index, true);
72
73 for (signed_size_type i = 0; i < offset; ++i, ++it)
74 {
75 }
76
77 geometry::convert(*it, point);
78 return true;
79 }
80 };
81
82
83 template <typename Polygon, bool Reverse, typename SegmentIdentifier, typename PointOut>
84 struct copy_segment_point_polygon
85 {
86 static inline bool apply(Polygon const& polygon,
87 SegmentIdentifier const& seg_id, int offset,
88 PointOut& point)
89 {
90 // Call ring-version with the right ring
91 return copy_segment_point_range
92 <
93 typename geometry::ring_type<Polygon>::type,
94 Reverse,
95 SegmentIdentifier,
96 PointOut
97 >::apply
98 (
99 seg_id.ring_index < 0
100 ? geometry::exterior_ring(polygon)
101 : range::at(geometry::interior_rings(polygon), seg_id.ring_index),
102 seg_id, offset,
103 point
104 );
105 }
106 };
107
108
109 template <typename Box, bool Reverse, typename SegmentIdentifier, typename PointOut>
110 struct copy_segment_point_box
111 {
112 static inline bool apply(Box const& box,
113 SegmentIdentifier const& seg_id, int offset,
114 PointOut& point)
115 {
116 signed_size_type index = seg_id.segment_index;
117 for (int i = 0; i < offset; i++)
118 {
119 index++;
120 }
121
122 boost::array<typename point_type<Box>::type, 4> bp;
123 assign_box_corners_oriented<Reverse>(box, bp);
124 point = bp[index % 4];
125 return true;
126 }
127 };
128
129
130 template
131 <
132 typename MultiGeometry,
133 typename SegmentIdentifier,
134 typename PointOut,
135 typename Policy
136 >
137 struct copy_segment_point_multi
138 {
139 static inline bool apply(MultiGeometry const& multi,
140 SegmentIdentifier const& seg_id, int offset,
141 PointOut& point)
142 {
143
144 BOOST_GEOMETRY_ASSERT
145 (
146 seg_id.multi_index >= 0
147 && seg_id.multi_index < int(boost::size(multi))
148 );
149
150 // Call the single-version
151 return Policy::apply(range::at(multi, seg_id.multi_index), seg_id, offset, point);
152 }
153 };
154
155
156 }} // namespace detail::copy_segments
157 #endif // DOXYGEN_NO_DETAIL
158
159
160 #ifndef DOXYGEN_NO_DISPATCH
161 namespace dispatch
162 {
163
164
165 template
166 <
167 typename Tag,
168 typename GeometryIn,
169 bool Reverse,
170 typename SegmentIdentifier,
171 typename PointOut
172 >
173 struct copy_segment_point
174 {
175 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
176 "Not or not yet implemented for this Geometry type.",
177 Tag, GeometryIn);
178 };
179
180
181 template <typename LineString, bool Reverse, typename SegmentIdentifier, typename PointOut>
182 struct copy_segment_point<linestring_tag, LineString, Reverse, SegmentIdentifier, PointOut>
183 : detail::copy_segments::copy_segment_point_range
184 <
185 LineString, Reverse, SegmentIdentifier, PointOut
186 >
187 {};
188
189
190 template <typename Ring, bool Reverse, typename SegmentIdentifier, typename PointOut>
191 struct copy_segment_point<ring_tag, Ring, Reverse, SegmentIdentifier, PointOut>
192 : detail::copy_segments::copy_segment_point_range
193 <
194 Ring, Reverse, SegmentIdentifier, PointOut
195 >
196 {};
197
198 template <typename Polygon, bool Reverse, typename SegmentIdentifier, typename PointOut>
199 struct copy_segment_point<polygon_tag, Polygon, Reverse, SegmentIdentifier, PointOut>
200 : detail::copy_segments::copy_segment_point_polygon
201 <
202 Polygon, Reverse, SegmentIdentifier, PointOut
203 >
204 {};
205
206
207 template <typename Box, bool Reverse, typename SegmentIdentifier, typename PointOut>
208 struct copy_segment_point<box_tag, Box, Reverse, SegmentIdentifier, PointOut>
209 : detail::copy_segments::copy_segment_point_box
210 <
211 Box, Reverse, SegmentIdentifier, PointOut
212 >
213 {};
214
215
216 template
217 <
218 typename MultiGeometry,
219 bool Reverse,
220 typename SegmentIdentifier,
221 typename PointOut
222 >
223 struct copy_segment_point
224 <
225 multi_polygon_tag,
226 MultiGeometry,
227 Reverse,
228 SegmentIdentifier,
229 PointOut
230 >
231 : detail::copy_segments::copy_segment_point_multi
232 <
233 MultiGeometry,
234 SegmentIdentifier,
235 PointOut,
236 detail::copy_segments::copy_segment_point_polygon
237 <
238 typename boost::range_value<MultiGeometry>::type,
239 Reverse,
240 SegmentIdentifier,
241 PointOut
242 >
243 >
244 {};
245
246 template
247 <
248 typename MultiGeometry,
249 bool Reverse,
250 typename SegmentIdentifier,
251 typename PointOut
252 >
253 struct copy_segment_point
254 <
255 multi_linestring_tag,
256 MultiGeometry,
257 Reverse,
258 SegmentIdentifier,
259 PointOut
260 >
261 : detail::copy_segments::copy_segment_point_multi
262 <
263 MultiGeometry,
264 SegmentIdentifier,
265 PointOut,
266 detail::copy_segments::copy_segment_point_range
267 <
268 typename boost::range_value<MultiGeometry>::type,
269 Reverse,
270 SegmentIdentifier,
271 PointOut
272 >
273 >
274 {};
275
276
277 } // namespace dispatch
278 #endif // DOXYGEN_NO_DISPATCH
279
280
281
282
283
284 /*!
285 \brief Helper function, copies a point from a segment
286 \ingroup overlay
287 */
288 template<bool Reverse, typename Geometry, typename SegmentIdentifier, typename PointOut>
289 inline bool copy_segment_point(Geometry const& geometry,
290 SegmentIdentifier const& seg_id, int offset,
291 PointOut& point_out)
292 {
293 concepts::check<Geometry const>();
294
295 return dispatch::copy_segment_point
296 <
297 typename tag<Geometry>::type,
298 Geometry,
299 Reverse,
300 SegmentIdentifier,
301 PointOut
302 >::apply(geometry, seg_id, offset, point_out);
303 }
304
305
306 /*!
307 \brief Helper function, to avoid the same construct several times,
308 copies a point, based on a source-index and two geometries
309 \ingroup overlay
310 */
311 template
312 <
313 bool Reverse1, bool Reverse2,
314 typename Geometry1, typename Geometry2,
315 typename SegmentIdentifier,
316 typename PointOut
317 >
318 inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geometry2,
319 SegmentIdentifier const& seg_id, int offset,
320 PointOut& point_out)
321 {
322 concepts::check<Geometry1 const>();
323 concepts::check<Geometry2 const>();
324
325 BOOST_GEOMETRY_ASSERT(seg_id.source_index == 0 || seg_id.source_index == 1);
326
327 if (seg_id.source_index == 0)
328 {
329 return dispatch::copy_segment_point
330 <
331 typename tag<Geometry1>::type,
332 Geometry1,
333 Reverse1,
334 SegmentIdentifier,
335 PointOut
336 >::apply(geometry1, seg_id, offset, point_out);
337 }
338 else if (seg_id.source_index == 1)
339 {
340 return dispatch::copy_segment_point
341 <
342 typename tag<Geometry2>::type,
343 Geometry2,
344 Reverse2,
345 SegmentIdentifier,
346 PointOut
347 >::apply(geometry2, seg_id, offset, point_out);
348 }
349 // Exception?
350 return false;
351 }
352
353
354 /*!
355 \brief Helper function, to avoid the same construct several times,
356 copies a point, based on a source-index and two geometries
357 \ingroup overlay
358 */
359 template
360 <
361 bool Reverse1, bool Reverse2,
362 typename Geometry1, typename Geometry2,
363 typename SegmentIdentifier,
364 typename PointOut
365 >
366 inline bool copy_segment_points(Geometry1 const& geometry1, Geometry2 const& geometry2,
367 SegmentIdentifier const& seg_id,
368 PointOut& point1, PointOut& point2)
369 {
370 concepts::check<Geometry1 const>();
371 concepts::check<Geometry2 const>();
372
373 return copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, 0, point1)
374 && copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, 1, point2);
375 }
376
377 /*!
378 \brief Helper function, copies three points: two from the specified segment
379 (from, to) and the next one
380 \ingroup overlay
381 */
382 template
383 <
384 bool Reverse1, bool Reverse2,
385 typename Geometry1, typename Geometry2,
386 typename SegmentIdentifier,
387 typename PointOut
388 >
389 inline bool copy_segment_points(Geometry1 const& geometry1, Geometry2 const& geometry2,
390 SegmentIdentifier const& seg_id,
391 PointOut& point1, PointOut& point2, PointOut& point3)
392 {
393 concepts::check<Geometry1 const>();
394 concepts::check<Geometry2 const>();
395
396 return copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, 0, point1)
397 && copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, 1, point2)
398 && copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, 2, point3);
399 }
400
401
402
403 }} // namespace boost::geometry
404
405 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP