1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. 6 7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 9 10 // This file was modified by Oracle on 2013, 2014. 11 // Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates. 12 13 // Use, modification and distribution is subject to the Boost Software License, 14 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 15 // http://www.boost.org/LICENSE_1_0.txt) 16 17 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 18 19 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP 20 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP 21 22 #include <boost/mpl/assert.hpp> 23 #include <boost/range.hpp> 24 25 #include <boost/geometry/core/access.hpp> 26 #include <boost/geometry/core/assert.hpp> 27 #include <boost/geometry/core/closure.hpp> 28 #include <boost/geometry/core/exterior_ring.hpp> 29 #include <boost/geometry/core/interior_rings.hpp> 30 #include <boost/geometry/core/ring_type.hpp> 31 #include <boost/geometry/core/tags.hpp> 32 #include <boost/geometry/geometries/concepts/check.hpp> 33 #include <boost/geometry/util/range.hpp> 34 35 36 namespace boost { namespace geometry 37 { 38 39 #ifndef DOXYGEN_NO_DETAIL 40 namespace detail { namespace section 41 { 42 43 44 template <typename Range, typename Section> 45 struct full_section_range 46 { applyboost::geometry::detail::section::full_section_range47 static inline Range const& apply(Range const& range, Section const& ) 48 { 49 return range; 50 } 51 }; 52 53 54 template <typename Polygon, typename Section> 55 struct full_section_polygon 56 { applyboost::geometry::detail::section::full_section_polygon57 static inline typename ring_return_type<Polygon const>::type apply(Polygon const& polygon, Section const& section) 58 { 59 return section.ring_id.ring_index < 0 60 ? geometry::exterior_ring(polygon) 61 : range::at(geometry::interior_rings(polygon), 62 static_cast<std::size_t>(section.ring_id.ring_index)); 63 } 64 }; 65 66 67 template 68 < 69 typename MultiGeometry, 70 typename Section, 71 typename Policy 72 > 73 struct full_section_multi 74 { applyboost::geometry::detail::section::full_section_multi75 static inline typename ring_return_type<MultiGeometry const>::type apply( 76 MultiGeometry const& multi, Section const& section) 77 { 78 typedef typename boost::range_size<MultiGeometry>::type size_type; 79 80 BOOST_GEOMETRY_ASSERT 81 ( 82 section.ring_id.multi_index >= 0 83 && size_type(section.ring_id.multi_index) < boost::size(multi) 84 ); 85 86 return Policy::apply(range::at(multi, size_type(section.ring_id.multi_index)), section); 87 } 88 }; 89 90 91 }} // namespace detail::section 92 #endif 93 94 95 #ifndef DOXYGEN_NO_DISPATCH 96 namespace dispatch 97 { 98 99 100 template 101 < 102 typename Tag, 103 typename Geometry, 104 typename Section 105 > 106 struct range_by_section 107 { 108 BOOST_MPL_ASSERT_MSG 109 ( 110 false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE 111 , (types<Geometry>) 112 ); 113 }; 114 115 116 template <typename LineString, typename Section> 117 struct range_by_section<linestring_tag, LineString, Section> 118 : detail::section::full_section_range<LineString, Section> 119 {}; 120 121 122 template <typename Ring, typename Section> 123 struct range_by_section<ring_tag, Ring, Section> 124 : detail::section::full_section_range<Ring, Section> 125 {}; 126 127 128 template <typename Polygon, typename Section> 129 struct range_by_section<polygon_tag, Polygon, Section> 130 : detail::section::full_section_polygon<Polygon, Section> 131 {}; 132 133 134 template <typename MultiPolygon, typename Section> 135 struct range_by_section<multi_polygon_tag, MultiPolygon, Section> 136 : detail::section::full_section_multi 137 < 138 MultiPolygon, 139 Section, 140 detail::section::full_section_polygon 141 < 142 typename boost::range_value<MultiPolygon>::type, 143 Section 144 > 145 > 146 {}; 147 148 template <typename MultiLinestring, typename Section> 149 struct range_by_section<multi_linestring_tag, MultiLinestring, Section> 150 : detail::section::full_section_multi 151 < 152 MultiLinestring, 153 Section, 154 detail::section::full_section_range 155 < 156 typename boost::range_value<MultiLinestring>::type, 157 Section 158 > 159 > 160 {}; 161 162 163 } // namespace dispatch 164 #endif 165 166 167 /*! 168 \brief Get full ring (exterior, one of interiors, one from multi) 169 indicated by the specified section 170 \ingroup sectionalize 171 \tparam Geometry type 172 \tparam Section type of section to get from 173 \param geometry geometry to take section of 174 \param section structure with section 175 */ 176 template <typename Geometry, typename Section> 177 inline typename ring_return_type<Geometry const>::type range_by_section(Geometry const & geometry,Section const & section)178 range_by_section(Geometry const& geometry, Section const& section) 179 { 180 concepts::check<Geometry const>(); 181 182 return dispatch::range_by_section 183 < 184 typename tag<Geometry>::type, 185 Geometry, 186 Section 187 >::apply(geometry, section); 188 } 189 190 191 }} // namespace boost::geometry 192 193 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP 194