Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:50:16

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2020.
0006 // Modifications copyright (c) 2020 Oracle and/or its affiliates.
0007 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0008 
0009 // Use, modification and distribution is subject to the Boost Software License,
0010 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0011 // http://www.boost.org/LICENSE_1_0.txt)
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 // A range of rings (multi-ring but that does not exist)
0046 // gets the "void" tag and is dispatched here.
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 // Returns the number of segments on a ring (regardless whether the ring is open or closed)
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     // A closed polygon, a triangle of 4 points, including starting point,
0128     // contains 3 segments. So handle as if it is closed, and subtract one.
0129     return geometry::num_points(detail::overlay::get_ring<tag>::apply(ring_id, geometry), true) - 1;
0130 }
0131 
0132 // Returns the number of segments on a ring (regardless whether the ring is open or closed)
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 // Returns the distance between the second and the first segment identifier (second-first)
0142 // It supports circular behavior and for this it is necessary to pass the geometry.
0143 // It will not report negative values
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     // It is an internal function, make sure the preconditions are met
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     // Take wrap into account, counting segments on the ring (passing any of the ids is fine).
0159     // Suppose point_count=10 (10 points, 9 segments), first.seg_id=7, second.seg_id=2,
0160     // then distance=9-7+2=4, being segments 7,8,0,1
0161     return segment_count_on_ring(geometry, first) + result;
0162 }
0163 
0164 }} // namespace detail::overlay
0165 #endif // DOXYGEN_NO_DETAIL
0166 
0167 
0168 }} // namespace boost::geometry
0169 
0170 
0171 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP