1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2012-2015 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_BUFFER_BUFFERED_RING 10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING 11 12 13 #include <cstddef> 14 15 #include <boost/range.hpp> 16 17 #include <boost/geometry/core/assert.hpp> 18 #include <boost/geometry/core/coordinate_type.hpp> 19 #include <boost/geometry/core/point_type.hpp> 20 21 #include <boost/geometry/strategies/buffer.hpp> 22 23 #include <boost/geometry/algorithms/within.hpp> 24 25 #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp> 26 #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp> 27 #include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp> 28 #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp> 29 #include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp> 30 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp> 31 32 33 namespace boost { namespace geometry 34 { 35 36 #ifndef DOXYGEN_NO_DETAIL 37 namespace detail { namespace buffer 38 { 39 40 struct buffered_ring_collection_tag : polygonal_tag, multi_tag 41 {}; 42 43 44 template <typename Ring> 45 struct buffered_ring : public Ring 46 { 47 bool has_concave; 48 bool has_accepted_intersections; 49 bool has_discarded_intersections; 50 bool is_untouched_outside_original; 51 buffered_ringboost::geometry::detail::buffer::buffered_ring52 inline buffered_ring() 53 : has_concave(false) 54 , has_accepted_intersections(false) 55 , has_discarded_intersections(false) 56 , is_untouched_outside_original(false) 57 {} 58 discardedboost::geometry::detail::buffer::buffered_ring59 inline bool discarded() const 60 { 61 return has_discarded_intersections && ! has_accepted_intersections; 62 } has_intersectionsboost::geometry::detail::buffer::buffered_ring63 inline bool has_intersections() const 64 { 65 return has_discarded_intersections || has_accepted_intersections; 66 } 67 }; 68 69 // This is a collection now special for overlay (needs vector of rings) 70 template <typename Ring> 71 struct buffered_ring_collection : public std::vector<Ring> 72 { 73 }; 74 75 }} // namespace detail::buffer 76 77 78 // Turn off concept checking (for now) 79 namespace dispatch 80 { 81 template <typename Geometry, bool IsConst> 82 struct check<Geometry, detail::buffer::buffered_ring_collection_tag, IsConst> 83 { 84 }; 85 86 } 87 88 89 #endif // DOXYGEN_NO_DETAIL 90 91 92 93 // Register the types 94 namespace traits 95 { 96 97 98 template <typename Ring> 99 struct tag<detail::buffer::buffered_ring<Ring> > 100 { 101 typedef ring_tag type; 102 }; 103 104 105 template <typename Ring> 106 struct point_order<detail::buffer::buffered_ring<Ring> > 107 { 108 static const order_selector value = geometry::point_order<Ring>::value; 109 }; 110 111 112 template <typename Ring> 113 struct closure<detail::buffer::buffered_ring<Ring> > 114 { 115 static const closure_selector value = geometry::closure<Ring>::value; 116 }; 117 118 119 template <typename Ring> 120 struct point_type<detail::buffer::buffered_ring_collection<Ring> > 121 { 122 typedef typename geometry::point_type<Ring>::type type; 123 }; 124 125 template <typename Ring> 126 struct tag<detail::buffer::buffered_ring_collection<Ring> > 127 { 128 typedef detail::buffer::buffered_ring_collection_tag type; 129 }; 130 131 132 } // namespace traits 133 134 135 136 137 namespace core_dispatch 138 { 139 140 template <typename Ring> 141 struct ring_type 142 < 143 detail::buffer::buffered_ring_collection_tag, 144 detail::buffer::buffered_ring_collection<Ring> 145 > 146 { 147 typedef Ring type; 148 }; 149 150 } 151 152 namespace dispatch 153 { 154 155 template 156 < 157 typename MultiRing, 158 bool Reverse, 159 typename SegmentIdentifier, 160 typename PointOut 161 > 162 struct copy_segment_point 163 < 164 detail::buffer::buffered_ring_collection_tag, 165 MultiRing, 166 Reverse, 167 SegmentIdentifier, 168 PointOut 169 > 170 : detail::copy_segments::copy_segment_point_multi 171 < 172 MultiRing, 173 SegmentIdentifier, 174 PointOut, 175 detail::copy_segments::copy_segment_point_range 176 < 177 typename boost::range_value<MultiRing>::type, 178 Reverse, 179 SegmentIdentifier, 180 PointOut 181 > 182 > 183 {}; 184 185 186 template<bool Reverse> 187 struct copy_segments 188 < 189 detail::buffer::buffered_ring_collection_tag, 190 Reverse 191 > 192 : detail::copy_segments::copy_segments_multi 193 < 194 detail::copy_segments::copy_segments_ring<Reverse> 195 > 196 {}; 197 198 template <typename Point, typename MultiGeometry> 199 struct within 200 < 201 Point, 202 MultiGeometry, 203 point_tag, 204 detail::buffer::buffered_ring_collection_tag 205 > 206 { 207 template <typename Strategy> applyboost::geometry::dispatch::within208 static inline bool apply(Point const& point, 209 MultiGeometry const& multi, Strategy const& strategy) 210 { 211 return detail::within::point_in_geometry(point, multi, strategy) == 1; 212 } 213 }; 214 215 216 } // namespace dispatch 217 218 namespace detail { namespace overlay 219 { 220 221 template<> 222 struct get_ring<detail::buffer::buffered_ring_collection_tag> 223 { 224 template<typename MultiGeometry> applyboost::geometry::detail::overlay::get_ring225 static inline typename ring_type<MultiGeometry>::type const& apply( 226 ring_identifier const& id, 227 MultiGeometry const& multi_ring) 228 { 229 BOOST_GEOMETRY_ASSERT 230 ( 231 id.multi_index >= 0 232 && id.multi_index < int(boost::size(multi_ring)) 233 ); 234 return get_ring<ring_tag>::apply(id, multi_ring[id.multi_index]); 235 } 236 }; 237 238 }} 239 240 241 }} // namespace boost::geometry 242 243 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING 244