1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2020.
6 // Modifications copyright (c) 2020 Oracle and/or its affiliates.
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9 // Use, modification and distribution is subject to the Boost Software License,
10 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
13 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
14 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
19 #include <boost/range/size.hpp>
20 #include <boost/range/value_type.hpp>
22 #include <boost/geometry/core/assert.hpp>
23 #include <boost/geometry/core/coordinate_type.hpp>
24 #include <boost/geometry/core/closure.hpp>
25 #include <boost/geometry/core/point_order.hpp>
26 #include <boost/geometry/core/point_type.hpp>
28 #include <boost/geometry/strategies/buffer.hpp>
30 #include <boost/geometry/algorithms/within.hpp>
32 #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
33 #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
34 #include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
35 #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
36 #include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
37 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
40 namespace boost { namespace geometry
43 #ifndef DOXYGEN_NO_DETAIL
44 namespace detail { namespace buffer
47 struct buffered_ring_collection_tag : polygonal_tag, multi_tag
51 template <typename Ring>
52 struct buffered_ring : public Ring
55 bool has_accepted_intersections;
56 bool has_discarded_intersections;
57 bool is_untouched_outside_original;
59 inline buffered_ring()
61 , has_accepted_intersections(false)
62 , has_discarded_intersections(false)
63 , is_untouched_outside_original(false)
66 inline bool discarded() const
68 return has_discarded_intersections && ! has_accepted_intersections;
70 inline bool has_intersections() const
72 return has_discarded_intersections || has_accepted_intersections;
76 // This is a collection now special for overlay (needs vector of rings)
77 template <typename Ring>
78 struct buffered_ring_collection : public std::vector<Ring>
82 }} // namespace detail::buffer
85 // Turn off concept checking (for now)
88 template <typename Geometry, bool IsConst>
89 struct check<Geometry, detail::buffer::buffered_ring_collection_tag, IsConst>
96 #endif // DOXYGEN_NO_DETAIL
100 // Register the types
105 template <typename Ring>
106 struct tag<geometry::detail::buffer::buffered_ring<Ring> >
108 typedef ring_tag type;
112 template <typename Ring>
113 struct point_order<geometry::detail::buffer::buffered_ring<Ring> >
115 static const order_selector value = geometry::point_order<Ring>::value;
119 template <typename Ring>
120 struct closure<geometry::detail::buffer::buffered_ring<Ring> >
122 static const closure_selector value = geometry::closure<Ring>::value;
126 template <typename Ring>
127 struct point_type<geometry::detail::buffer::buffered_ring_collection<Ring> >
129 typedef typename geometry::point_type<Ring>::type type;
132 template <typename Ring>
133 struct tag<geometry::detail::buffer::buffered_ring_collection<Ring> >
135 typedef geometry::detail::buffer::buffered_ring_collection_tag type;
139 } // namespace traits
144 namespace core_dispatch
147 template <typename Ring>
150 detail::buffer::buffered_ring_collection_tag,
151 detail::buffer::buffered_ring_collection<Ring>
158 // There is a specific tag, so this specialization cannot be placed in traits
159 template <typename Ring>
160 struct point_order<detail::buffer::buffered_ring_collection_tag,
161 geometry::detail::buffer::buffered_ring_collection
163 geometry::detail::buffer::buffered_ring<Ring>
166 static const order_selector value
167 = core_dispatch::point_order<ring_tag, Ring>::value;
175 struct single_tag_of<detail::buffer::buffered_ring_collection_tag>
177 typedef ring_tag type;
188 typename SegmentIdentifier,
191 struct copy_segment_point
193 detail::buffer::buffered_ring_collection_tag,
199 : detail::copy_segments::copy_segment_point_multi
204 detail::copy_segments::copy_segment_point_range
206 typename boost::range_value<MultiRing>::type,
215 template<bool Reverse>
218 detail::buffer::buffered_ring_collection_tag,
221 : detail::copy_segments::copy_segments_multi
223 detail::copy_segments::copy_segments_ring<Reverse>
227 template <typename Point, typename MultiGeometry>
233 detail::buffer::buffered_ring_collection_tag
236 template <typename Strategy>
237 static inline bool apply(Point const& point,
238 MultiGeometry const& multi, Strategy const& strategy)
240 return detail::within::point_in_geometry(point, multi, strategy) == 1;
245 template <typename Geometry>
246 struct is_empty<Geometry, detail::buffer::buffered_ring_collection_tag>
247 : detail::is_empty::multi_is_empty<detail::is_empty::range_is_empty>
251 template <typename Geometry>
252 struct envelope<Geometry, detail::buffer::buffered_ring_collection_tag>
253 : detail::envelope::envelope_multi_range
255 detail::envelope::envelope_range
260 } // namespace dispatch
262 namespace detail { namespace overlay
266 struct get_ring<detail::buffer::buffered_ring_collection_tag>
268 template<typename MultiGeometry>
269 static inline typename ring_type<MultiGeometry>::type const& apply(
270 ring_identifier const& id,
271 MultiGeometry const& multi_ring)
273 BOOST_GEOMETRY_ASSERT
276 && id.multi_index < int(boost::size(multi_ring))
278 return get_ring<ring_tag>::apply(id, multi_ring[id.multi_index]);
285 }} // namespace boost::geometry
287 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING