• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/closure.hpp>
20 #include <boost/geometry/core/point_order.hpp>
21 #include <boost/geometry/core/point_type.hpp>
22 
23 #include <boost/geometry/strategies/buffer.hpp>
24 
25 #include <boost/geometry/algorithms/within.hpp>
26 
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>
33 
34 
35 namespace boost { namespace geometry
36 {
37 
38 #ifndef DOXYGEN_NO_DETAIL
39 namespace detail { namespace buffer
40 {
41 
42 struct buffered_ring_collection_tag : polygonal_tag, multi_tag
43 {};
44 
45 
46 template <typename Ring>
47 struct buffered_ring : public Ring
48 {
49     bool has_concave;
50     bool has_accepted_intersections;
51     bool has_discarded_intersections;
52     bool is_untouched_outside_original;
53 
buffered_ringboost::geometry::detail::buffer::buffered_ring54     inline buffered_ring()
55         : has_concave(false)
56         , has_accepted_intersections(false)
57         , has_discarded_intersections(false)
58         , is_untouched_outside_original(false)
59     {}
60 
discardedboost::geometry::detail::buffer::buffered_ring61     inline bool discarded() const
62     {
63         return has_discarded_intersections && ! has_accepted_intersections;
64     }
has_intersectionsboost::geometry::detail::buffer::buffered_ring65     inline bool has_intersections() const
66     {
67         return has_discarded_intersections || has_accepted_intersections;
68     }
69 };
70 
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>
74 {
75 };
76 
77 }} // namespace detail::buffer
78 
79 
80 // Turn off concept checking (for now)
81 namespace dispatch
82 {
83 template <typename Geometry, bool IsConst>
84 struct check<Geometry, detail::buffer::buffered_ring_collection_tag, IsConst>
85 {
86 };
87 
88 }
89 
90 
91 #endif // DOXYGEN_NO_DETAIL
92 
93 
94 
95 // Register the types
96 namespace traits
97 {
98 
99 
100 template <typename Ring>
101 struct tag<geometry::detail::buffer::buffered_ring<Ring> >
102 {
103     typedef ring_tag type;
104 };
105 
106 
107 template <typename Ring>
108 struct point_order<geometry::detail::buffer::buffered_ring<Ring> >
109 {
110     static const order_selector value = geometry::point_order<Ring>::value;
111 };
112 
113 
114 template <typename Ring>
115 struct closure<geometry::detail::buffer::buffered_ring<Ring> >
116 {
117     static const closure_selector value = geometry::closure<Ring>::value;
118 };
119 
120 
121 template <typename Ring>
122 struct point_type<geometry::detail::buffer::buffered_ring_collection<Ring> >
123 {
124     typedef typename geometry::point_type<Ring>::type type;
125 };
126 
127 template <typename Ring>
128 struct tag<geometry::detail::buffer::buffered_ring_collection<Ring> >
129 {
130     typedef geometry::detail::buffer::buffered_ring_collection_tag type;
131 };
132 
133 
134 } // namespace traits
135 
136 
137 
138 
139 namespace core_dispatch
140 {
141 
142 template <typename Ring>
143 struct ring_type
144 <
145     detail::buffer::buffered_ring_collection_tag,
146     detail::buffer::buffered_ring_collection<Ring>
147 >
148 {
149     typedef Ring type;
150 };
151 
152 
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
157         <
158             geometry::detail::buffer::buffered_ring<Ring>
159         > >
160 {
161     static const order_selector value
162         = core_dispatch::point_order<ring_tag, Ring>::value;
163 };
164 
165 
166 }
167 
168 
169 template <>
170 struct single_tag_of<detail::buffer::buffered_ring_collection_tag>
171 {
172     typedef ring_tag type;
173 };
174 
175 
176 namespace dispatch
177 {
178 
179 template
180 <
181     typename MultiRing,
182     bool Reverse,
183     typename SegmentIdentifier,
184     typename PointOut
185 >
186 struct copy_segment_point
187     <
188         detail::buffer::buffered_ring_collection_tag,
189         MultiRing,
190         Reverse,
191         SegmentIdentifier,
192         PointOut
193     >
194     : detail::copy_segments::copy_segment_point_multi
195         <
196             MultiRing,
197             SegmentIdentifier,
198             PointOut,
199             detail::copy_segments::copy_segment_point_range
200                 <
201                     typename boost::range_value<MultiRing>::type,
202                     Reverse,
203                     SegmentIdentifier,
204                     PointOut
205                 >
206         >
207 {};
208 
209 
210 template<bool Reverse>
211 struct copy_segments
212     <
213         detail::buffer::buffered_ring_collection_tag,
214         Reverse
215     >
216     : detail::copy_segments::copy_segments_multi
217         <
218             detail::copy_segments::copy_segments_ring<Reverse>
219         >
220 {};
221 
222 template <typename Point, typename MultiGeometry>
223 struct within
224 <
225     Point,
226     MultiGeometry,
227     point_tag,
228     detail::buffer::buffered_ring_collection_tag
229 >
230 {
231     template <typename Strategy>
applyboost::geometry::dispatch::within232     static inline bool apply(Point const& point,
233                 MultiGeometry const& multi, Strategy const& strategy)
234     {
235         return detail::within::point_in_geometry(point, multi, strategy) == 1;
236     }
237 };
238 
239 
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>
243 {};
244 
245 
246 template <typename Geometry>
247 struct envelope<Geometry, detail::buffer::buffered_ring_collection_tag>
248     : detail::envelope::envelope_multi_range
249         <
250             detail::envelope::envelope_range
251         >
252 {};
253 
254 
255 } // namespace dispatch
256 
257 namespace detail { namespace overlay
258 {
259 
260 template<>
261 struct get_ring<detail::buffer::buffered_ring_collection_tag>
262 {
263     template<typename MultiGeometry>
applyboost::geometry::detail::overlay::get_ring264     static inline typename ring_type<MultiGeometry>::type const& apply(
265                 ring_identifier const& id,
266                 MultiGeometry const& multi_ring)
267     {
268         BOOST_GEOMETRY_ASSERT
269             (
270                 id.multi_index >= 0
271                 && id.multi_index < int(boost::size(multi_ring))
272             );
273         return get_ring<ring_tag>::apply(id, multi_ring[id.multi_index]);
274     }
275 };
276 
277 }}
278 
279 
280 }} // namespace boost::geometry
281 
282 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
283