]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
54 | 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 | ||
61 | inline bool discarded() const | |
62 | { | |
63 | return has_discarded_intersections && ! has_accepted_intersections; | |
64 | } | |
65 | 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> | |
232 | 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> | |
264 | 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 |