1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2014, Oracle and/or its affiliates.
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
10 #ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
11 #define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
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>
18 #include <boost/geometry/core/exterior_ring.hpp>
19 #include <boost/geometry/core/interior_rings.hpp>
20 #include <boost/geometry/core/tags.hpp>
22 #include <boost/geometry/iterators/dispatch/point_iterator.hpp>
23 #include <boost/geometry/iterators/detail/point_iterator/iterator_type.hpp>
26 namespace boost { namespace geometry
30 #ifndef DOXYGEN_NO_DISPATCH
35 // specializations for points_begin
38 template <typename Linestring>
39 struct points_begin<Linestring, linestring_tag>
41 static inline typename detail::point_iterator::iterator_type
45 apply(Linestring& linestring)
47 return boost::begin(linestring);
52 template <typename Ring>
53 struct points_begin<Ring, ring_tag>
55 static inline typename detail::point_iterator::iterator_type<Ring>::type
58 return boost::begin(ring);
63 template <typename Polygon>
64 struct points_begin<Polygon, polygon_tag>
66 typedef typename detail::point_iterator::iterator_type
71 static inline return_type apply(Polygon& polygon)
73 typedef typename return_type::second_iterator_type flatten_iterator;
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))
81 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
82 boost::end(geometry::interior_rings(polygon))
89 template <typename MultiPoint>
90 struct points_begin<MultiPoint, multi_point_tag>
92 static inline typename detail::point_iterator::iterator_type
96 apply(MultiPoint& multipoint)
98 return boost::begin(multipoint);
103 template <typename MultiLinestring>
104 struct points_begin<MultiLinestring, multi_linestring_tag>
106 typedef typename detail::point_iterator::iterator_type
111 static inline return_type apply(MultiLinestring& multilinestring)
113 return return_type(boost::begin(multilinestring),
114 boost::end(multilinestring));
119 template <typename MultiPolygon>
120 struct points_begin<MultiPolygon, multi_polygon_tag>
122 typedef typename detail::point_iterator::iterator_type
127 static inline return_type apply(MultiPolygon& multipolygon)
129 return return_type(boost::begin(multipolygon),
130 boost::end(multipolygon));
134 } // namespace dispatch
135 #endif // DOXYGEN_NO_DISPATCH
141 #ifndef DOXYGEN_NO_DISPATCH
146 // specializations for points_end
149 template <typename Linestring>
150 struct points_end<Linestring, linestring_tag>
152 static inline typename detail::point_iterator::iterator_type
156 apply(Linestring& linestring)
158 return boost::end(linestring);
163 template <typename Ring>
164 struct points_end<Ring, ring_tag>
166 static inline typename detail::point_iterator::iterator_type<Ring>::type
169 return boost::end(ring);
174 template <typename Polygon>
175 struct points_end<Polygon, polygon_tag>
177 typedef typename detail::point_iterator::iterator_type
182 static inline return_type apply(Polygon& polygon)
184 typedef typename return_type::second_iterator_type flatten_iterator;
187 (boost::end(geometry::exterior_ring(polygon)),
188 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
189 boost::end(geometry::interior_rings(polygon))
191 flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
197 template <typename MultiPoint>
198 struct points_end<MultiPoint, multi_point_tag>
200 static inline typename detail::point_iterator::iterator_type
204 apply(MultiPoint& multipoint)
206 return boost::end(multipoint);
211 template <typename MultiLinestring>
212 struct points_end<MultiLinestring, multi_linestring_tag>
214 typedef typename detail::point_iterator::iterator_type
219 static inline return_type apply(MultiLinestring& multilinestring)
221 return return_type(boost::end(multilinestring));
226 template <typename MultiPolygon>
227 struct points_end<MultiPolygon, multi_polygon_tag>
229 typedef typename detail::point_iterator::iterator_type
234 static inline return_type apply(MultiPolygon& multipolygon)
236 return return_type(boost::end(multipolygon));
241 } // namespace dispatch
242 #endif // DOXYGEN_NO_DISPATCH
245 // MK:: need to add doc here
246 template <typename Geometry>
248 : public boost::iterator_adaptor
250 point_iterator<Geometry>,
251 typename detail::point_iterator::iterator_type<Geometry>::type
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&);
259 inline point_iterator(typename point_iterator::base_type const& base_it)
260 : point_iterator::iterator_adaptor_(base_it) {}
263 inline point_iterator() {}
265 template <typename OtherGeometry>
266 inline point_iterator(point_iterator<OtherGeometry> const& other)
267 : point_iterator::iterator_adaptor_(other.base())
269 static const bool is_conv
270 = boost::is_convertible<
271 typename detail::point_iterator::iterator_type
275 typename detail::point_iterator::iterator_type
281 BOOST_MPL_ASSERT_MSG((is_conv),
283 (point_iterator<OtherGeometry>));
288 // MK:: need to add doc here
289 template <typename Geometry>
290 inline point_iterator<Geometry>
291 points_begin(Geometry& geometry)
293 return dispatch::points_begin<Geometry>::apply(geometry);
297 // MK:: need to add doc here
298 template <typename Geometry>
299 inline point_iterator<Geometry>
300 points_end(Geometry& geometry)
302 return dispatch::points_end<Geometry>::apply(geometry);
306 }} // namespace boost::geometry
308 #endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP