1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
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)
9 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
15 #include <boost/range.hpp>
17 #include <boost/geometry/core/assert.hpp>
18 #include <boost/geometry/core/coordinate_type.hpp>
19 #include <boost/geometry/core/closure.hpp>
20 #include <boost/geometry/core/point_order.hpp>
21 #include <boost/geometry/core/point_type.hpp>
23 #include <boost/geometry/strategies/buffer.hpp>
25 #include <boost/geometry/algorithms/within.hpp>
27 #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
28 #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
29 #include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
30 #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
31 #include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
32 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
35 namespace boost { namespace geometry
38 #ifndef DOXYGEN_NO_DETAIL
39 namespace detail { namespace buffer
42 struct buffered_ring_collection_tag : polygonal_tag, multi_tag
46 template <typename Ring>
47 struct buffered_ring : public Ring
50 bool has_accepted_intersections;
51 bool has_discarded_intersections;
52 bool is_untouched_outside_original;
54 inline buffered_ring()
56 , has_accepted_intersections(false)
57 , has_discarded_intersections(false)
58 , is_untouched_outside_original(false)
61 inline bool discarded() const
63 return has_discarded_intersections && ! has_accepted_intersections;
65 inline bool has_intersections() const
67 return has_discarded_intersections || has_accepted_intersections;
71 // This is a collection now special for overlay (needs vector of rings)
72 template <typename Ring>
73 struct buffered_ring_collection : public std::vector<Ring>
77 }} // namespace detail::buffer
80 // Turn off concept checking (for now)
83 template <typename Geometry, bool IsConst>
84 struct check<Geometry, detail::buffer::buffered_ring_collection_tag, IsConst>
91 #endif // DOXYGEN_NO_DETAIL
100 template <typename Ring>
101 struct tag<geometry::detail::buffer::buffered_ring<Ring> >
103 typedef ring_tag type;
107 template <typename Ring>
108 struct point_order<geometry::detail::buffer::buffered_ring<Ring> >
110 static const order_selector value = geometry::point_order<Ring>::value;
114 template <typename Ring>
115 struct closure<geometry::detail::buffer::buffered_ring<Ring> >
117 static const closure_selector value = geometry::closure<Ring>::value;
121 template <typename Ring>
122 struct point_type<geometry::detail::buffer::buffered_ring_collection<Ring> >
124 typedef typename geometry::point_type<Ring>::type type;
127 template <typename Ring>
128 struct tag<geometry::detail::buffer::buffered_ring_collection<Ring> >
130 typedef geometry::detail::buffer::buffered_ring_collection_tag type;
134 } // namespace traits
139 namespace core_dispatch
142 template <typename Ring>
145 detail::buffer::buffered_ring_collection_tag,
146 detail::buffer::buffered_ring_collection<Ring>
153 // There is a specific tag, so this specialization cannot be placed in traits
154 template <typename Ring>
155 struct point_order<detail::buffer::buffered_ring_collection_tag,
156 geometry::detail::buffer::buffered_ring_collection
158 geometry::detail::buffer::buffered_ring<Ring>
161 static const order_selector value
162 = core_dispatch::point_order<ring_tag, Ring>::value;
170 struct single_tag_of<detail::buffer::buffered_ring_collection_tag>
172 typedef ring_tag type;
183 typename SegmentIdentifier,
186 struct copy_segment_point
188 detail::buffer::buffered_ring_collection_tag,
194 : detail::copy_segments::copy_segment_point_multi
199 detail::copy_segments::copy_segment_point_range
201 typename boost::range_value<MultiRing>::type,
210 template<bool Reverse>
213 detail::buffer::buffered_ring_collection_tag,
216 : detail::copy_segments::copy_segments_multi
218 detail::copy_segments::copy_segments_ring<Reverse>
222 template <typename Point, typename MultiGeometry>
228 detail::buffer::buffered_ring_collection_tag
231 template <typename Strategy>
232 static inline bool apply(Point const& point,
233 MultiGeometry const& multi, Strategy const& strategy)
235 return detail::within::point_in_geometry(point, multi, strategy) == 1;
240 template <typename Geometry>
241 struct is_empty<Geometry, detail::buffer::buffered_ring_collection_tag>
242 : detail::is_empty::multi_is_empty<detail::is_empty::range_is_empty>
246 template <typename Geometry>
247 struct envelope<Geometry, detail::buffer::buffered_ring_collection_tag>
248 : detail::envelope::envelope_multi_range
250 detail::envelope::envelope_range
255 } // namespace dispatch
257 namespace detail { namespace overlay
261 struct get_ring<detail::buffer::buffered_ring_collection_tag>
263 template<typename MultiGeometry>
264 static inline typename ring_type<MultiGeometry>::type const& apply(
265 ring_identifier const& id,
266 MultiGeometry const& multi_ring)
268 BOOST_GEOMETRY_ASSERT
271 && id.multi_index < int(boost::size(multi_ring))
273 return get_ring<ring_tag>::apply(id, multi_ring[id.multi_index]);
280 }} // namespace boost::geometry
282 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING