]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
20effc67 | 3 | // Copyright (c) 2014-2020, Oracle and/or its affiliates. |
7c673cae | 4 | // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle |
20effc67 | 5 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle |
7c673cae FG |
6 | |
7 | // Licensed under the Boost Software License version 1.0. | |
8 | // http://www.boost.org/users/license.html | |
9 | ||
10 | #ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP | |
11 | #define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP | |
12 | ||
20effc67 TL |
13 | |
14 | #include <type_traits> | |
15 | ||
7c673cae | 16 | #include <boost/iterator/iterator_adaptor.hpp> |
20effc67 TL |
17 | #include <boost/range/begin.hpp> |
18 | #include <boost/range/end.hpp> | |
7c673cae FG |
19 | |
20 | #include <boost/geometry/core/exterior_ring.hpp> | |
21 | #include <boost/geometry/core/interior_rings.hpp> | |
20effc67 | 22 | #include <boost/geometry/core/static_assert.hpp> |
7c673cae FG |
23 | #include <boost/geometry/core/tags.hpp> |
24 | ||
25 | #include <boost/geometry/iterators/dispatch/point_iterator.hpp> | |
26 | #include <boost/geometry/iterators/detail/point_iterator/iterator_type.hpp> | |
27 | ||
28 | ||
29 | namespace boost { namespace geometry | |
30 | { | |
31 | ||
32 | ||
33 | #ifndef DOXYGEN_NO_DISPATCH | |
34 | namespace dispatch | |
35 | { | |
36 | ||
37 | ||
38 | // specializations for points_begin | |
39 | ||
40 | ||
41 | template <typename Linestring> | |
42 | struct points_begin<Linestring, linestring_tag> | |
43 | { | |
44 | static inline typename detail::point_iterator::iterator_type | |
45 | < | |
46 | Linestring | |
47 | >::type | |
48 | apply(Linestring& linestring) | |
49 | { | |
50 | return boost::begin(linestring); | |
51 | } | |
52 | }; | |
53 | ||
54 | ||
55 | template <typename Ring> | |
56 | struct points_begin<Ring, ring_tag> | |
57 | { | |
58 | static inline typename detail::point_iterator::iterator_type<Ring>::type | |
59 | apply(Ring& ring) | |
60 | { | |
61 | return boost::begin(ring); | |
62 | } | |
63 | }; | |
64 | ||
65 | ||
66 | template <typename Polygon> | |
67 | struct points_begin<Polygon, polygon_tag> | |
68 | { | |
69 | typedef typename detail::point_iterator::iterator_type | |
70 | < | |
71 | Polygon | |
72 | >::type return_type; | |
73 | ||
74 | static inline return_type apply(Polygon& polygon) | |
75 | { | |
76 | typedef typename return_type::second_iterator_type flatten_iterator; | |
77 | ||
78 | return return_type | |
79 | (boost::begin(geometry::exterior_ring(polygon)), | |
80 | boost::end(geometry::exterior_ring(polygon)), | |
81 | flatten_iterator(boost::begin(geometry::interior_rings(polygon)), | |
82 | boost::end(geometry::interior_rings(polygon)) | |
83 | ), | |
84 | flatten_iterator(boost::begin(geometry::interior_rings(polygon)), | |
85 | boost::end(geometry::interior_rings(polygon)) | |
86 | ) | |
87 | ); | |
88 | } | |
89 | }; | |
90 | ||
91 | ||
92 | template <typename MultiPoint> | |
93 | struct points_begin<MultiPoint, multi_point_tag> | |
94 | { | |
95 | static inline typename detail::point_iterator::iterator_type | |
96 | < | |
97 | MultiPoint | |
98 | >::type | |
99 | apply(MultiPoint& multipoint) | |
100 | { | |
101 | return boost::begin(multipoint); | |
102 | } | |
103 | }; | |
104 | ||
105 | ||
106 | template <typename MultiLinestring> | |
107 | struct points_begin<MultiLinestring, multi_linestring_tag> | |
108 | { | |
109 | typedef typename detail::point_iterator::iterator_type | |
110 | < | |
111 | MultiLinestring | |
112 | >::type return_type; | |
113 | ||
114 | static inline return_type apply(MultiLinestring& multilinestring) | |
115 | { | |
116 | return return_type(boost::begin(multilinestring), | |
117 | boost::end(multilinestring)); | |
118 | } | |
119 | }; | |
120 | ||
121 | ||
122 | template <typename MultiPolygon> | |
123 | struct points_begin<MultiPolygon, multi_polygon_tag> | |
124 | { | |
125 | typedef typename detail::point_iterator::iterator_type | |
126 | < | |
127 | MultiPolygon | |
128 | >::type return_type; | |
129 | ||
130 | static inline return_type apply(MultiPolygon& multipolygon) | |
131 | { | |
132 | return return_type(boost::begin(multipolygon), | |
133 | boost::end(multipolygon)); | |
134 | } | |
135 | }; | |
136 | ||
137 | } // namespace dispatch | |
138 | #endif // DOXYGEN_NO_DISPATCH | |
139 | ||
140 | ||
141 | ||
142 | ||
143 | ||
144 | #ifndef DOXYGEN_NO_DISPATCH | |
145 | namespace dispatch | |
146 | { | |
147 | ||
148 | ||
149 | // specializations for points_end | |
150 | ||
151 | ||
152 | template <typename Linestring> | |
153 | struct points_end<Linestring, linestring_tag> | |
154 | { | |
155 | static inline typename detail::point_iterator::iterator_type | |
156 | < | |
157 | Linestring | |
158 | >::type | |
159 | apply(Linestring& linestring) | |
160 | { | |
161 | return boost::end(linestring); | |
162 | } | |
163 | }; | |
164 | ||
165 | ||
166 | template <typename Ring> | |
167 | struct points_end<Ring, ring_tag> | |
168 | { | |
169 | static inline typename detail::point_iterator::iterator_type<Ring>::type | |
170 | apply(Ring& ring) | |
171 | { | |
172 | return boost::end(ring); | |
173 | } | |
174 | }; | |
175 | ||
176 | ||
177 | template <typename Polygon> | |
178 | struct points_end<Polygon, polygon_tag> | |
179 | { | |
180 | typedef typename detail::point_iterator::iterator_type | |
181 | < | |
182 | Polygon | |
183 | >::type return_type; | |
184 | ||
185 | static inline return_type apply(Polygon& polygon) | |
186 | { | |
187 | typedef typename return_type::second_iterator_type flatten_iterator; | |
188 | ||
189 | return return_type | |
190 | (boost::end(geometry::exterior_ring(polygon)), | |
191 | flatten_iterator(boost::begin(geometry::interior_rings(polygon)), | |
192 | boost::end(geometry::interior_rings(polygon)) | |
193 | ), | |
194 | flatten_iterator( boost::end(geometry::interior_rings(polygon)) ) | |
195 | ); | |
196 | } | |
197 | }; | |
198 | ||
199 | ||
200 | template <typename MultiPoint> | |
201 | struct points_end<MultiPoint, multi_point_tag> | |
202 | { | |
203 | static inline typename detail::point_iterator::iterator_type | |
204 | < | |
205 | MultiPoint | |
206 | >::type | |
207 | apply(MultiPoint& multipoint) | |
208 | { | |
209 | return boost::end(multipoint); | |
210 | } | |
211 | }; | |
212 | ||
213 | ||
214 | template <typename MultiLinestring> | |
215 | struct points_end<MultiLinestring, multi_linestring_tag> | |
216 | { | |
217 | typedef typename detail::point_iterator::iterator_type | |
218 | < | |
219 | MultiLinestring | |
220 | >::type return_type; | |
221 | ||
222 | static inline return_type apply(MultiLinestring& multilinestring) | |
223 | { | |
224 | return return_type(boost::end(multilinestring)); | |
225 | } | |
226 | }; | |
227 | ||
228 | ||
229 | template <typename MultiPolygon> | |
230 | struct points_end<MultiPolygon, multi_polygon_tag> | |
231 | { | |
232 | typedef typename detail::point_iterator::iterator_type | |
233 | < | |
234 | MultiPolygon | |
235 | >::type return_type; | |
236 | ||
237 | static inline return_type apply(MultiPolygon& multipolygon) | |
238 | { | |
239 | return return_type(boost::end(multipolygon)); | |
240 | } | |
241 | }; | |
242 | ||
243 | ||
244 | } // namespace dispatch | |
245 | #endif // DOXYGEN_NO_DISPATCH | |
246 | ||
247 | ||
248 | // MK:: need to add doc here | |
249 | template <typename Geometry> | |
250 | class point_iterator | |
251 | : public boost::iterator_adaptor | |
252 | < | |
253 | point_iterator<Geometry>, | |
254 | typename detail::point_iterator::iterator_type<Geometry>::type | |
255 | > | |
256 | { | |
257 | private: | |
258 | template <typename OtherGeometry> friend class point_iterator; | |
259 | template <typename G> friend inline point_iterator<G> points_begin(G&); | |
260 | template <typename G> friend inline point_iterator<G> points_end(G&); | |
261 | ||
262 | inline point_iterator(typename point_iterator::base_type const& base_it) | |
263 | : point_iterator::iterator_adaptor_(base_it) {} | |
264 | ||
265 | public: | |
266 | inline point_iterator() {} | |
267 | ||
268 | template <typename OtherGeometry> | |
269 | inline point_iterator(point_iterator<OtherGeometry> const& other) | |
270 | : point_iterator::iterator_adaptor_(other.base()) | |
271 | { | |
272 | static const bool is_conv | |
20effc67 | 273 | = std::is_convertible< |
7c673cae FG |
274 | typename detail::point_iterator::iterator_type |
275 | < | |
276 | OtherGeometry | |
277 | >::type, | |
278 | typename detail::point_iterator::iterator_type | |
279 | < | |
280 | Geometry | |
281 | >::type | |
282 | >::value; | |
283 | ||
20effc67 TL |
284 | BOOST_GEOMETRY_STATIC_ASSERT((is_conv), |
285 | "Other iterator has to be convertible to member iterator.", | |
286 | point_iterator<OtherGeometry>); | |
7c673cae FG |
287 | } |
288 | }; | |
289 | ||
290 | ||
291 | // MK:: need to add doc here | |
292 | template <typename Geometry> | |
293 | inline point_iterator<Geometry> | |
294 | points_begin(Geometry& geometry) | |
295 | { | |
296 | return dispatch::points_begin<Geometry>::apply(geometry); | |
297 | } | |
298 | ||
299 | ||
300 | // MK:: need to add doc here | |
301 | template <typename Geometry> | |
302 | inline point_iterator<Geometry> | |
303 | points_end(Geometry& geometry) | |
304 | { | |
305 | return dispatch::points_end<Geometry>::apply(geometry); | |
306 | } | |
307 | ||
308 | ||
309 | }} // namespace boost::geometry | |
310 | ||
311 | #endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP |