File indexing completed on 2025-12-15 09:50:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
0014 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
0015
0016
0017 #include <boost/range/size.hpp>
0018 #include <boost/range/value_type.hpp>
0019
0020 #include <boost/geometry/core/assert.hpp>
0021 #include <boost/geometry/core/exterior_ring.hpp>
0022 #include <boost/geometry/core/interior_rings.hpp>
0023 #include <boost/geometry/core/ring_type.hpp>
0024 #include <boost/geometry/core/tags.hpp>
0025 #include <boost/geometry/algorithms/detail/ring_identifier.hpp>
0026 #include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
0027 #include <boost/geometry/algorithms/num_points.hpp>
0028 #include <boost/geometry/geometries/concepts/check.hpp>
0029 #include <boost/geometry/util/range.hpp>
0030
0031
0032 namespace boost { namespace geometry
0033 {
0034
0035
0036 #ifndef DOXYGEN_NO_DETAIL
0037 namespace detail { namespace overlay
0038 {
0039
0040
0041 template<typename Tag>
0042 struct get_ring
0043 {};
0044
0045
0046
0047 template<>
0048 struct get_ring<void>
0049 {
0050 template<typename Range>
0051 static inline typename boost::range_value<Range>::type const&
0052 apply(ring_identifier const& id, Range const& container)
0053 {
0054 return range::at(container, id.multi_index);
0055 }
0056 };
0057
0058
0059 template<>
0060 struct get_ring<ring_tag>
0061 {
0062 template<typename Ring>
0063 static inline Ring const& apply(ring_identifier const& , Ring const& ring)
0064 {
0065 return ring;
0066 }
0067 };
0068
0069
0070 template<>
0071 struct get_ring<box_tag>
0072 {
0073 template<typename Box>
0074 static inline Box const& apply(ring_identifier const& ,
0075 Box const& box)
0076 {
0077 return box;
0078 }
0079 };
0080
0081
0082 template<>
0083 struct get_ring<polygon_tag>
0084 {
0085 template<typename Polygon>
0086 static inline ring_return_type_t<Polygon const> const apply(
0087 ring_identifier const& id,
0088 Polygon const& polygon)
0089 {
0090 BOOST_GEOMETRY_ASSERT
0091 (
0092 id.ring_index >= -1
0093 && id.ring_index < int(boost::size(interior_rings(polygon)))
0094 );
0095 return id.ring_index < 0
0096 ? exterior_ring(polygon)
0097 : range::at(interior_rings(polygon), id.ring_index);
0098 }
0099 };
0100
0101
0102 template<>
0103 struct get_ring<multi_polygon_tag>
0104 {
0105 template<typename MultiPolygon>
0106 static inline ring_type_t<MultiPolygon> const& apply(
0107 ring_identifier const& id,
0108 MultiPolygon const& multi_polygon)
0109 {
0110 BOOST_GEOMETRY_ASSERT
0111 (
0112 id.multi_index >= 0
0113 && id.multi_index < int(boost::size(multi_polygon))
0114 );
0115 return get_ring<polygon_tag>::apply(id,
0116 range::at(multi_polygon, id.multi_index));
0117 }
0118 };
0119
0120
0121 template <typename Geometry>
0122 inline signed_size_type segment_count_on_ring(Geometry const& geometry,
0123 ring_identifier const& ring_id)
0124 {
0125 using tag = geometry::tag_t<Geometry>;
0126
0127
0128
0129 return geometry::num_points(detail::overlay::get_ring<tag>::apply(ring_id, geometry), true) - 1;
0130 }
0131
0132
0133 template <typename Geometry>
0134 inline signed_size_type segment_count_on_ring(Geometry const& geometry,
0135 segment_identifier const& seg_id)
0136 {
0137 return segment_count_on_ring(geometry, ring_identifier(0, seg_id.multi_index, seg_id.ring_index));
0138 }
0139
0140
0141
0142
0143
0144 template <typename Geometry>
0145 inline signed_size_type segment_distance(Geometry const& geometry,
0146 segment_identifier const& first, segment_identifier const& second)
0147 {
0148
0149 BOOST_ASSERT(second.source_index == first.source_index);
0150 BOOST_ASSERT(second.multi_index == first.multi_index);
0151 BOOST_ASSERT(second.ring_index == first.ring_index);
0152
0153 signed_size_type const result = second.segment_index - first.segment_index;
0154 if (second.segment_index >= first.segment_index)
0155 {
0156 return result;
0157 }
0158
0159
0160
0161 return segment_count_on_ring(geometry, first) + result;
0162 }
0163
0164 }}
0165 #endif
0166
0167
0168 }}
0169
0170
0171 #endif