File indexing completed on 2025-01-18 09:35:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
0011 #define BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
0012
0013
0014 #include <type_traits>
0015
0016 #include <boost/range/begin.hpp>
0017 #include <boost/range/end.hpp>
0018
0019 #include <boost/geometry/core/exterior_ring.hpp>
0020 #include <boost/geometry/core/interior_rings.hpp>
0021 #include <boost/geometry/core/tags.hpp>
0022
0023 #include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
0024 #include <boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp>
0025
0026 #include <boost/geometry/iterators/dispatch/segment_iterator.hpp>
0027
0028
0029 namespace boost { namespace geometry
0030 {
0031
0032
0033 #ifndef DOXYGEN_NO_DISPATCH
0034 namespace dispatch
0035 {
0036
0037
0038
0039
0040
0041 template <typename Linestring>
0042 struct segments_begin<Linestring, linestring_tag>
0043 {
0044 typedef typename detail::segment_iterator::iterator_type
0045 <
0046 Linestring
0047 >::type return_type;
0048
0049 static inline return_type apply(Linestring& linestring)
0050 {
0051 return return_type(linestring);
0052 }
0053 };
0054
0055
0056 template <typename Ring>
0057 struct segments_begin<Ring, ring_tag>
0058 {
0059 typedef typename detail::segment_iterator::iterator_type
0060 <
0061 Ring
0062 >::type return_type;
0063
0064 static inline return_type apply(Ring& ring)
0065 {
0066 return return_type(ring);
0067 }
0068 };
0069
0070
0071 template <typename Polygon>
0072 struct segments_begin<Polygon, polygon_tag>
0073 {
0074 typedef typename detail::point_iterator::inner_range_type
0075 <
0076 Polygon
0077 >::type inner_range;
0078
0079 typedef typename detail::segment_iterator::iterator_type
0080 <
0081 Polygon
0082 >::type return_type;
0083
0084 static inline return_type apply(Polygon& polygon)
0085 {
0086 typedef typename return_type::second_iterator_type flatten_iterator;
0087
0088 return return_type
0089 (segments_begin
0090 <
0091 inner_range
0092 >::apply(geometry::exterior_ring(polygon)),
0093 segments_end
0094 <
0095 inner_range
0096 >::apply(geometry::exterior_ring(polygon)),
0097 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
0098 boost::end(geometry::interior_rings(polygon))
0099 ),
0100 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
0101 boost::end(geometry::interior_rings(polygon))
0102 )
0103 );
0104 }
0105 };
0106
0107
0108 template <typename MultiLinestring>
0109 struct segments_begin<MultiLinestring, multi_linestring_tag>
0110 {
0111 typedef typename detail::segment_iterator::iterator_type
0112 <
0113 MultiLinestring
0114 >::type return_type;
0115
0116 static inline return_type apply(MultiLinestring& multilinestring)
0117 {
0118 return return_type(boost::begin(multilinestring),
0119 boost::end(multilinestring));
0120 }
0121 };
0122
0123
0124 template <typename MultiPolygon>
0125 struct segments_begin<MultiPolygon, multi_polygon_tag>
0126 {
0127 typedef typename detail::segment_iterator::iterator_type
0128 <
0129 MultiPolygon
0130 >::type return_type;
0131
0132 static inline return_type apply(MultiPolygon& multipolygon)
0133 {
0134 return return_type(boost::begin(multipolygon),
0135 boost::end(multipolygon));
0136 }
0137 };
0138
0139
0140 }
0141 #endif
0142
0143
0144
0145
0146
0147 #ifndef DOXYGEN_NO_DISPATCH
0148 namespace dispatch
0149 {
0150
0151
0152
0153
0154
0155 template <typename Linestring>
0156 struct segments_end<Linestring, linestring_tag>
0157 {
0158 typedef typename detail::segment_iterator::iterator_type
0159 <
0160 Linestring
0161 >::type return_type;
0162
0163 static inline return_type apply(Linestring& linestring)
0164 {
0165 return return_type(linestring, true);
0166 }
0167 };
0168
0169
0170 template <typename Ring>
0171 struct segments_end<Ring, ring_tag>
0172 {
0173 typedef typename detail::segment_iterator::iterator_type
0174 <
0175 Ring
0176 >::type return_type;
0177
0178 static inline return_type apply(Ring& ring)
0179 {
0180 return return_type(ring, true);
0181 }
0182 };
0183
0184
0185 template <typename Polygon>
0186 struct segments_end<Polygon, polygon_tag>
0187 {
0188 typedef typename detail::point_iterator::inner_range_type
0189 <
0190 Polygon
0191 >::type inner_range;
0192
0193 typedef typename detail::segment_iterator::iterator_type
0194 <
0195 Polygon
0196 >::type return_type;
0197
0198 static inline return_type apply(Polygon& polygon)
0199 {
0200 typedef typename return_type::second_iterator_type flatten_iterator;
0201
0202 return return_type
0203 (segments_end
0204 <
0205 inner_range
0206 >::apply(geometry::exterior_ring(polygon)),
0207 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
0208 boost::end(geometry::interior_rings(polygon))
0209 ),
0210 flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
0211 );
0212 }
0213 };
0214
0215
0216 template <typename MultiLinestring>
0217 struct segments_end<MultiLinestring, multi_linestring_tag>
0218 {
0219 typedef typename detail::segment_iterator::iterator_type
0220 <
0221 MultiLinestring
0222 >::type return_type;
0223
0224 static inline return_type apply(MultiLinestring& multilinestring)
0225 {
0226 return return_type(boost::end(multilinestring));
0227 }
0228 };
0229
0230
0231 template <typename MultiPolygon>
0232 struct segments_end<MultiPolygon, multi_polygon_tag>
0233 {
0234 typedef typename detail::segment_iterator::iterator_type
0235 <
0236 MultiPolygon
0237 >::type return_type;
0238
0239 static inline return_type apply(MultiPolygon& multipolygon)
0240 {
0241 return return_type(boost::end(multipolygon));
0242 }
0243 };
0244
0245
0246 }
0247 #endif
0248
0249
0250
0251 template <typename Geometry>
0252 class segment_iterator
0253 : public detail::segment_iterator::iterator_type<Geometry>::type
0254 {
0255 private:
0256 typedef typename detail::segment_iterator::iterator_type
0257 <
0258 Geometry
0259 >::type base;
0260
0261 inline base const* base_ptr() const
0262 {
0263 return this;
0264 }
0265
0266 template <typename OtherGeometry> friend class segment_iterator;
0267
0268 template <typename G>
0269 friend inline segment_iterator<G const> segments_begin(G const&);
0270
0271 template <typename G>
0272 friend inline segment_iterator<G const> segments_end(G const&);
0273
0274 inline segment_iterator(base const& base_it) : base(base_it) {}
0275
0276 public:
0277
0278
0279
0280
0281
0282
0283
0284
0285 typedef std::bidirectional_iterator_tag iterator_category;
0286
0287 inline segment_iterator() = default;
0288
0289 template
0290 <
0291 typename OtherGeometry,
0292 std::enable_if_t
0293 <
0294 std::is_convertible
0295 <
0296 typename detail::segment_iterator::iterator_type<OtherGeometry>::type,
0297 typename detail::segment_iterator::iterator_type<Geometry>::type
0298 >::value,
0299 int
0300 > = 0
0301 >
0302 inline segment_iterator(segment_iterator<OtherGeometry> const& other)
0303 : base(*other.base_ptr())
0304 {}
0305
0306 inline segment_iterator& operator++()
0307 {
0308 base::operator++();
0309 return *this;
0310 }
0311
0312 inline segment_iterator& operator--()
0313 {
0314 base::operator--();
0315 return *this;
0316 }
0317
0318 inline segment_iterator operator++(int)
0319 {
0320 segment_iterator copy(*this);
0321 base::operator++();
0322 return copy;
0323 }
0324
0325 inline segment_iterator operator--(int)
0326 {
0327 segment_iterator copy(*this);
0328 base::operator--();
0329 return copy;
0330 }
0331 };
0332
0333
0334
0335 template <typename Geometry>
0336 inline segment_iterator<Geometry const>
0337 segments_begin(Geometry const& geometry)
0338 {
0339 return dispatch::segments_begin<Geometry const>::apply(geometry);
0340 }
0341
0342
0343
0344 template <typename Geometry>
0345 inline segment_iterator<Geometry const>
0346 segments_end(Geometry const& geometry)
0347 {
0348 return dispatch::segments_end<Geometry const>::apply(geometry);
0349 }
0350
0351
0352 }}
0353
0354 #endif