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