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