1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 5 // Use, modification and distribution is subject to the Boost Software License, 6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP 10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP 11 12 13 #include <boost/range.hpp> 14 15 #include <boost/geometry/core/assert.hpp> 16 #include <boost/geometry/core/exterior_ring.hpp> 17 #include <boost/geometry/core/interior_rings.hpp> 18 #include <boost/geometry/core/ring_type.hpp> 19 #include <boost/geometry/core/tags.hpp> 20 #include <boost/geometry/algorithms/detail/ring_identifier.hpp> 21 #include <boost/geometry/geometries/concepts/check.hpp> 22 #include <boost/geometry/util/range.hpp> 23 24 25 namespace boost { namespace geometry 26 { 27 28 29 #ifndef DOXYGEN_NO_DETAIL 30 namespace detail { namespace overlay 31 { 32 33 34 template<typename Tag> 35 struct get_ring 36 {}; 37 38 // A range of rings (multi-ring but that does not exist) 39 // gets the "void" tag and is dispatched here. 40 template<> 41 struct get_ring<void> 42 { 43 template<typename Range> 44 static inline typename boost::range_value<Range>::type const& applyboost::geometry::detail::overlay::get_ring45 apply(ring_identifier const& id, Range const& container) 46 { 47 return range::at(container, id.multi_index); 48 } 49 }; 50 51 52 53 54 template<> 55 struct get_ring<ring_tag> 56 { 57 template<typename Ring> applyboost::geometry::detail::overlay::get_ring58 static inline Ring const& apply(ring_identifier const& , Ring const& ring) 59 { 60 return ring; 61 } 62 }; 63 64 65 template<> 66 struct get_ring<box_tag> 67 { 68 template<typename Box> applyboost::geometry::detail::overlay::get_ring69 static inline Box const& apply(ring_identifier const& , 70 Box const& box) 71 { 72 return box; 73 } 74 }; 75 76 77 template<> 78 struct get_ring<polygon_tag> 79 { 80 template<typename Polygon> applyboost::geometry::detail::overlay::get_ring81 static inline typename ring_return_type<Polygon const>::type const apply( 82 ring_identifier const& id, 83 Polygon const& polygon) 84 { 85 BOOST_GEOMETRY_ASSERT 86 ( 87 id.ring_index >= -1 88 && id.ring_index < int(boost::size(interior_rings(polygon))) 89 ); 90 return id.ring_index < 0 91 ? exterior_ring(polygon) 92 : range::at(interior_rings(polygon), id.ring_index); 93 } 94 }; 95 96 97 template<> 98 struct get_ring<multi_polygon_tag> 99 { 100 template<typename MultiPolygon> applyboost::geometry::detail::overlay::get_ring101 static inline typename ring_type<MultiPolygon>::type const& apply( 102 ring_identifier const& id, 103 MultiPolygon const& multi_polygon) 104 { 105 BOOST_GEOMETRY_ASSERT 106 ( 107 id.multi_index >= 0 108 && id.multi_index < int(boost::size(multi_polygon)) 109 ); 110 return get_ring<polygon_tag>::apply(id, 111 range::at(multi_polygon, id.multi_index)); 112 } 113 }; 114 115 116 }} // namespace detail::overlay 117 #endif // DOXYGEN_NO_DETAIL 118 119 120 }} // namespace boost::geometry 121 122 123 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP 124