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