1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2014-2020, Oracle and/or its affiliates.
4 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
5 // Contributed and/or modified by Adam Wulkiewicz, 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
14 #include <type_traits>
16 #include <boost/iterator/iterator_adaptor.hpp>
17 #include <boost/range/begin.hpp>
18 #include <boost/range/end.hpp>
20 #include <boost/geometry/core/exterior_ring.hpp>
21 #include <boost/geometry/core/interior_rings.hpp>
22 #include <boost/geometry/core/static_assert.hpp>
23 #include <boost/geometry/core/tags.hpp>
25 #include <boost/geometry/iterators/dispatch/point_iterator.hpp>
26 #include <boost/geometry/iterators/detail/point_iterator/iterator_type.hpp>
29 namespace boost { namespace geometry
33 #ifndef DOXYGEN_NO_DISPATCH
38 // specializations for points_begin
41 template <typename Linestring>
42 struct points_begin<Linestring, linestring_tag>
44 static inline typename detail::point_iterator::iterator_type
48 apply(Linestring& linestring)
50 return boost::begin(linestring);
55 template <typename Ring>
56 struct points_begin<Ring, ring_tag>
58 static inline typename detail::point_iterator::iterator_type<Ring>::type
61 return boost::begin(ring);
66 template <typename Polygon>
67 struct points_begin<Polygon, polygon_tag>
69 typedef typename detail::point_iterator::iterator_type
74 static inline return_type apply(Polygon& polygon)
76 typedef typename return_type::second_iterator_type flatten_iterator;
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))
84 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
85 boost::end(geometry::interior_rings(polygon))
92 template <typename MultiPoint>
93 struct points_begin<MultiPoint, multi_point_tag>
95 static inline typename detail::point_iterator::iterator_type
99 apply(MultiPoint& multipoint)
101 return boost::begin(multipoint);
106 template <typename MultiLinestring>
107 struct points_begin<MultiLinestring, multi_linestring_tag>
109 typedef typename detail::point_iterator::iterator_type
114 static inline return_type apply(MultiLinestring& multilinestring)
116 return return_type(boost::begin(multilinestring),
117 boost::end(multilinestring));
122 template <typename MultiPolygon>
123 struct points_begin<MultiPolygon, multi_polygon_tag>
125 typedef typename detail::point_iterator::iterator_type
130 static inline return_type apply(MultiPolygon& multipolygon)
132 return return_type(boost::begin(multipolygon),
133 boost::end(multipolygon));
137 } // namespace dispatch
138 #endif // DOXYGEN_NO_DISPATCH
144 #ifndef DOXYGEN_NO_DISPATCH
149 // specializations for points_end
152 template <typename Linestring>
153 struct points_end<Linestring, linestring_tag>
155 static inline typename detail::point_iterator::iterator_type
159 apply(Linestring& linestring)
161 return boost::end(linestring);
166 template <typename Ring>
167 struct points_end<Ring, ring_tag>
169 static inline typename detail::point_iterator::iterator_type<Ring>::type
172 return boost::end(ring);
177 template <typename Polygon>
178 struct points_end<Polygon, polygon_tag>
180 typedef typename detail::point_iterator::iterator_type
185 static inline return_type apply(Polygon& polygon)
187 typedef typename return_type::second_iterator_type flatten_iterator;
190 (boost::end(geometry::exterior_ring(polygon)),
191 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
192 boost::end(geometry::interior_rings(polygon))
194 flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
200 template <typename MultiPoint>
201 struct points_end<MultiPoint, multi_point_tag>
203 static inline typename detail::point_iterator::iterator_type
207 apply(MultiPoint& multipoint)
209 return boost::end(multipoint);
214 template <typename MultiLinestring>
215 struct points_end<MultiLinestring, multi_linestring_tag>
217 typedef typename detail::point_iterator::iterator_type
222 static inline return_type apply(MultiLinestring& multilinestring)
224 return return_type(boost::end(multilinestring));
229 template <typename MultiPolygon>
230 struct points_end<MultiPolygon, multi_polygon_tag>
232 typedef typename detail::point_iterator::iterator_type
237 static inline return_type apply(MultiPolygon& multipolygon)
239 return return_type(boost::end(multipolygon));
244 } // namespace dispatch
245 #endif // DOXYGEN_NO_DISPATCH
248 // MK:: need to add doc here
249 template <typename Geometry>
251 : public boost::iterator_adaptor
253 point_iterator<Geometry>,
254 typename detail::point_iterator::iterator_type<Geometry>::type
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&);
262 inline point_iterator(typename point_iterator::base_type const& base_it)
263 : point_iterator::iterator_adaptor_(base_it) {}
266 inline point_iterator() {}
268 template <typename OtherGeometry>
269 inline point_iterator(point_iterator<OtherGeometry> const& other)
270 : point_iterator::iterator_adaptor_(other.base())
272 static const bool is_conv
273 = std::is_convertible<
274 typename detail::point_iterator::iterator_type
278 typename detail::point_iterator::iterator_type
284 BOOST_GEOMETRY_STATIC_ASSERT((is_conv),
285 "Other iterator has to be convertible to member iterator.",
286 point_iterator<OtherGeometry>);
291 // MK:: need to add doc here
292 template <typename Geometry>
293 inline point_iterator<Geometry>
294 points_begin(Geometry& geometry)
296 return dispatch::points_begin<Geometry>::apply(geometry);
300 // MK:: need to add doc here
301 template <typename Geometry>
302 inline point_iterator<Geometry>
303 points_end(Geometry& geometry)
305 return dispatch::points_end<Geometry>::apply(geometry);
309 }} // namespace boost::geometry
311 #endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP