]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | Copyright 2008 Intel Corporation | |
3 | ||
4 | Use, modification and distribution are subject to the Boost Software License, | |
5 | Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
6 | http://www.boost.org/LICENSE_1_0.txt). | |
7 | */ | |
8 | #ifndef BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP | |
9 | #define BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP | |
10 | #include "polygon_set_data.hpp" | |
11 | #include "detail/polygon_simplify.hpp" | |
12 | namespace boost { namespace polygon{ | |
13 | ||
14 | template <typename T, typename T2> | |
15 | struct is_either_polygon_set_type { | |
16 | typedef typename gtl_or<typename is_polygon_set_type<T>::type, typename is_polygon_set_type<T2>::type >::type type; | |
17 | }; | |
18 | ||
19 | template <typename T> | |
20 | struct is_any_polygon_set_type { | |
21 | typedef typename gtl_or<typename is_polygon_45_or_90_set_type<T>::type, typename is_polygon_set_type<T>::type >::type type; | |
22 | }; | |
23 | ||
24 | template <typename polygon_set_type> | |
25 | typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type, | |
26 | typename polygon_set_traits<polygon_set_type>::iterator_type>::type | |
27 | begin_polygon_set_data(const polygon_set_type& polygon_set) { | |
28 | return polygon_set_traits<polygon_set_type>::begin(polygon_set); | |
29 | } | |
30 | ||
31 | template <typename polygon_set_type> | |
32 | typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type, | |
33 | typename polygon_set_traits<polygon_set_type>::iterator_type>::type | |
34 | end_polygon_set_data(const polygon_set_type& polygon_set) { | |
35 | return polygon_set_traits<polygon_set_type>::end(polygon_set); | |
36 | } | |
37 | ||
38 | template <typename polygon_set_type> | |
39 | typename enable_if< typename is_polygon_set_type<polygon_set_type>::type, | |
40 | bool>::type | |
41 | clean(const polygon_set_type& polygon_set) { | |
42 | return polygon_set_traits<polygon_set_type>::clean(polygon_set); | |
43 | } | |
44 | ||
45 | //assign | |
46 | template <typename polygon_set_type_1, typename polygon_set_type_2> | |
47 | typename enable_if< typename gtl_and< | |
48 | typename is_mutable_polygon_set_type<polygon_set_type_1>::type, | |
49 | typename is_any_polygon_set_type<polygon_set_type_2>::type>::type, | |
50 | polygon_set_type_1>::type & | |
51 | assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) { | |
52 | if(clean(rvalue)) | |
53 | polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue)); | |
54 | else { | |
55 | polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps; | |
56 | ps.insert(begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue)); | |
57 | ps.clean(); | |
58 | polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, ps.begin(), ps.end()); | |
59 | } | |
60 | return lvalue; | |
61 | } | |
62 | ||
63 | //get trapezoids | |
64 | template <typename output_container_type, typename polygon_set_type> | |
65 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
66 | void>::type | |
67 | get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) { | |
68 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; | |
69 | assign(ps, polygon_set); | |
70 | ps.get_trapezoids(output); | |
71 | } | |
72 | ||
73 | //get trapezoids | |
74 | template <typename output_container_type, typename polygon_set_type> | |
75 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
76 | void>::type | |
77 | get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set, | |
78 | orientation_2d orient) { | |
79 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; | |
80 | assign(ps, polygon_set); | |
81 | ps.get_trapezoids(output, orient); | |
82 | } | |
83 | ||
84 | //equivalence | |
85 | template <typename polygon_set_type_1, typename polygon_set_type_2> | |
86 | typename enable_if< typename gtl_and_3 < | |
87 | typename is_any_polygon_set_type<polygon_set_type_1>::type, | |
88 | typename is_any_polygon_set_type<polygon_set_type_2>::type, | |
89 | typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type, | |
90 | bool>::type | |
91 | equivalence(const polygon_set_type_1& lvalue, | |
92 | const polygon_set_type_2& rvalue) { | |
93 | polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1; | |
94 | assign(ps1, lvalue); | |
95 | polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2; | |
96 | assign(ps2, rvalue); | |
97 | return ps1 == ps2; | |
98 | } | |
99 | ||
100 | //clear | |
101 | template <typename polygon_set_type> | |
102 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
103 | void>::type | |
104 | clear(polygon_set_type& polygon_set) { | |
105 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; | |
106 | assign(polygon_set, ps); | |
107 | } | |
108 | ||
109 | //empty | |
110 | template <typename polygon_set_type> | |
111 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
112 | bool>::type | |
113 | empty(const polygon_set_type& polygon_set) { | |
114 | if(clean(polygon_set)) return begin_polygon_set_data(polygon_set) == end_polygon_set_data(polygon_set); | |
115 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; | |
116 | assign(ps, polygon_set); | |
117 | ps.clean(); | |
118 | return ps.empty(); | |
119 | } | |
120 | ||
121 | //extents | |
122 | template <typename polygon_set_type, typename rectangle_type> | |
123 | typename enable_if< typename gtl_and< | |
124 | typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
125 | typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, | |
126 | bool>::type | |
127 | extents(rectangle_type& extents_rectangle, | |
128 | const polygon_set_type& polygon_set) { | |
129 | clean(polygon_set); | |
130 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; | |
131 | assign(ps, polygon_set); | |
132 | return ps.extents(extents_rectangle); | |
133 | } | |
134 | ||
135 | //area | |
136 | template <typename polygon_set_type> | |
137 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
138 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type>::type | |
139 | area(const polygon_set_type& polygon_set) { | |
140 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; | |
141 | typedef polygon_with_holes_data<Unit> p_type; | |
142 | typedef typename coordinate_traits<Unit>::area_type area_type; | |
143 | std::vector<p_type> polys; | |
144 | assign(polys, polygon_set); | |
145 | area_type retval = (area_type)0; | |
146 | for(std::size_t i = 0; i < polys.size(); ++i) { | |
147 | retval += area(polys[i]); | |
148 | } | |
149 | return retval; | |
150 | } | |
151 | ||
152 | template <typename polygon_set_type> | |
153 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
154 | std::size_t>::type | |
155 | simplify(polygon_set_type& polygon_set, typename coordinate_traits< | |
156 | typename polygon_set_traits<polygon_set_type>::coordinate_type | |
157 | >::coordinate_distance threshold) { | |
158 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; | |
159 | typedef polygon_with_holes_data<Unit> p_type; | |
160 | std::vector<p_type> polys; | |
161 | assign(polys, polygon_set); | |
162 | std::size_t retval = 0; | |
163 | for(std::size_t i = 0; i < polys.size(); ++i) { | |
164 | retval += detail::simplify_detail::simplify(polys[i].self_.coords_, | |
165 | polys[i].self_.coords_, threshold); | |
166 | for(typename std::list<polygon_data<Unit> >::iterator itrh = | |
167 | polys[i].holes_.begin(); itrh != (polys[i].holes_.end()); ++itrh) { | |
168 | retval += detail::simplify_detail::simplify((*itrh).coords_, | |
169 | (*itrh).coords_, threshold); | |
170 | } | |
171 | } | |
172 | assign(polygon_set, polys); | |
173 | return retval; | |
174 | } | |
175 | ||
176 | template <typename polygon_set_type, typename coord_type> | |
177 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
178 | polygon_set_type>::type & | |
179 | resize(polygon_set_type& polygon_set, coord_type resizing, bool corner_fill_arcs = false, int num_circle_segments = 0) { | |
180 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; | |
181 | clean(polygon_set); | |
182 | polygon_set_data<Unit> ps; | |
183 | assign(ps, polygon_set); | |
184 | ps.resize(resizing, corner_fill_arcs,num_circle_segments); | |
185 | assign(polygon_set, ps); | |
186 | return polygon_set; | |
187 | } | |
188 | ||
189 | template <typename polygon_set_type> | |
190 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
191 | polygon_set_type>::type & | |
192 | bloat(polygon_set_type& polygon_set, | |
193 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { | |
194 | return resize(polygon_set, bloating); | |
195 | } | |
196 | ||
197 | template <typename polygon_set_type> | |
198 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
199 | polygon_set_type>::type & | |
200 | shrink(polygon_set_type& polygon_set, | |
201 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { | |
202 | return resize(polygon_set, -(typename polygon_set_traits<polygon_set_type>::coordinate_type)shrinking); | |
203 | } | |
204 | ||
205 | //interact | |
206 | template <typename polygon_set_type_1, typename polygon_set_type_2> | |
207 | typename enable_if< typename gtl_and_3 < | |
208 | typename is_any_polygon_set_type<polygon_set_type_1>::type, | |
209 | typename is_any_polygon_set_type<polygon_set_type_2>::type, | |
210 | typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type, | |
211 | polygon_set_type_1>::type& | |
212 | interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) { | |
213 | polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1; | |
214 | assign(ps1, polygon_set_1); | |
215 | polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2; | |
216 | assign(ps2, polygon_set_2); | |
217 | ps1.interact(ps2); | |
218 | assign(polygon_set_1, ps1); | |
219 | return polygon_set_1; | |
220 | } | |
221 | ||
222 | template <typename polygon_set_type> | |
223 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
224 | polygon_set_type>::type & | |
225 | scale_up(polygon_set_type& polygon_set, | |
226 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) { | |
227 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; | |
228 | clean(polygon_set); | |
229 | polygon_set_data<Unit> ps; | |
230 | assign(ps, polygon_set); | |
231 | ps.scale_up(factor); | |
232 | assign(polygon_set, ps); | |
233 | return polygon_set; | |
234 | } | |
235 | ||
236 | template <typename polygon_set_type> | |
237 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
238 | polygon_set_type>::type & | |
239 | scale_down(polygon_set_type& polygon_set, | |
240 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) { | |
241 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; | |
242 | clean(polygon_set); | |
243 | polygon_set_data<Unit> ps; | |
244 | assign(ps, polygon_set); | |
245 | ps.scale_down(factor); | |
246 | assign(polygon_set, ps); | |
247 | return polygon_set; | |
248 | } | |
249 | ||
250 | //transform | |
251 | template <typename polygon_set_type, typename transformation_type> | |
252 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
253 | polygon_set_type>::type & | |
254 | transform(polygon_set_type& polygon_set, | |
255 | const transformation_type& transformation) { | |
256 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; | |
257 | clean(polygon_set); | |
258 | polygon_set_data<Unit> ps; | |
259 | assign(ps, polygon_set); | |
260 | ps.transform(transformation); | |
261 | assign(polygon_set, ps); | |
262 | return polygon_set; | |
263 | } | |
264 | ||
265 | //keep | |
266 | template <typename polygon_set_type> | |
267 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, | |
268 | polygon_set_type>::type & | |
269 | keep(polygon_set_type& polygon_set, | |
270 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type min_area, | |
271 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type max_area, | |
272 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width, | |
273 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width, | |
274 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height, | |
275 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) { | |
276 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; | |
277 | typedef typename coordinate_traits<Unit>::unsigned_area_type uat; | |
278 | std::list<polygon_with_holes_data<Unit> > polys; | |
279 | assign(polys, polygon_set); | |
280 | typename std::list<polygon_with_holes_data<Unit> >::iterator itr_nxt; | |
281 | for(typename std::list<polygon_with_holes_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){ | |
282 | itr_nxt = itr; | |
283 | ++itr_nxt; | |
284 | rectangle_data<Unit> bbox; | |
285 | extents(bbox, *itr); | |
286 | uat pwidth = delta(bbox, HORIZONTAL); | |
287 | if(pwidth > min_width && pwidth <= max_width){ | |
288 | uat pheight = delta(bbox, VERTICAL); | |
289 | if(pheight > min_height && pheight <= max_height){ | |
290 | typename coordinate_traits<Unit>::area_type parea = area(*itr); | |
291 | if(parea <= max_area && parea >= min_area) { | |
292 | continue; | |
293 | } | |
294 | } | |
295 | } | |
296 | polys.erase(itr); | |
297 | } | |
298 | assign(polygon_set, polys); | |
299 | return polygon_set; | |
300 | } | |
301 | ||
302 | namespace operators { | |
303 | ||
304 | struct yes_ps_ob : gtl_yes {}; | |
305 | ||
306 | template <typename geometry_type_1, typename geometry_type_2> | |
307 | typename enable_if< typename gtl_and_4 < yes_ps_ob, typename is_any_polygon_set_type<geometry_type_1>::type, | |
308 | typename is_any_polygon_set_type<geometry_type_2>::type, | |
309 | typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, | |
310 | polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type | |
311 | operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
312 | return polygon_set_view<geometry_type_1, geometry_type_2, 0> | |
313 | (lvalue, rvalue); | |
314 | } | |
315 | ||
316 | struct yes_ps_op : gtl_yes {}; | |
317 | ||
318 | template <typename geometry_type_1, typename geometry_type_2> | |
319 | typename enable_if< typename gtl_and_4 < yes_ps_op, | |
320 | typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type, | |
321 | typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type, | |
322 | typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type> | |
323 | ::type, polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type | |
324 | operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
325 | return polygon_set_view<geometry_type_1, geometry_type_2, 0> | |
326 | (lvalue, rvalue); | |
327 | } | |
328 | ||
329 | struct yes_ps_os : gtl_yes {}; | |
330 | ||
331 | template <typename geometry_type_1, typename geometry_type_2> | |
332 | typename enable_if< typename gtl_and_4 < yes_ps_os, | |
333 | typename is_any_polygon_set_type<geometry_type_1>::type, | |
334 | typename is_any_polygon_set_type<geometry_type_2>::type, | |
335 | typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, | |
336 | polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type | |
337 | operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
338 | return polygon_set_view<geometry_type_1, geometry_type_2, 1> | |
339 | (lvalue, rvalue); | |
340 | } | |
341 | ||
342 | struct yes_ps_oa : gtl_yes {}; | |
343 | ||
344 | template <typename geometry_type_1, typename geometry_type_2> | |
345 | typename enable_if< typename gtl_and_4 < yes_ps_oa, | |
346 | typename is_any_polygon_set_type<geometry_type_1>::type, | |
347 | typename is_any_polygon_set_type<geometry_type_2>::type, | |
348 | typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, | |
349 | polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type | |
350 | operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
351 | return polygon_set_view<geometry_type_1, geometry_type_2, 1> | |
352 | (lvalue, rvalue); | |
353 | } | |
354 | ||
355 | struct yes_ps_ox : gtl_yes {}; | |
356 | ||
357 | template <typename geometry_type_1, typename geometry_type_2> | |
358 | typename enable_if< typename gtl_and_4 < yes_ps_ox, | |
359 | typename is_any_polygon_set_type<geometry_type_1>::type, | |
360 | typename is_any_polygon_set_type<geometry_type_2>::type, | |
361 | typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, | |
362 | polygon_set_view<geometry_type_1, geometry_type_2, 2> >::type | |
363 | operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
364 | return polygon_set_view<geometry_type_1, geometry_type_2, 2> | |
365 | (lvalue, rvalue); | |
366 | } | |
367 | ||
368 | struct yes_ps_om : gtl_yes {}; | |
369 | ||
370 | template <typename geometry_type_1, typename geometry_type_2> | |
371 | typename enable_if< typename gtl_and_4 < yes_ps_om, | |
372 | typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type, | |
373 | typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type, | |
374 | typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type> | |
375 | ::type, polygon_set_view<geometry_type_1, geometry_type_2, 3> >::type | |
376 | operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
377 | return polygon_set_view<geometry_type_1, geometry_type_2, 3> | |
378 | (lvalue, rvalue); | |
379 | } | |
380 | ||
381 | struct yes_ps_ope : gtl_yes {}; | |
382 | ||
383 | template <typename geometry_type_1, typename geometry_type_2> | |
384 | typename enable_if< typename gtl_and_4< yes_ps_ope, gtl_yes, typename is_mutable_polygon_set_type<geometry_type_1>::type, | |
385 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, | |
386 | geometry_type_1>::type & | |
387 | operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
388 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue); | |
389 | } | |
390 | ||
391 | struct yes_ps_obe : gtl_yes {}; | |
392 | ||
393 | template <typename geometry_type_1, typename geometry_type_2> | |
394 | typename enable_if< typename gtl_and_3< yes_ps_obe, typename is_mutable_polygon_set_type<geometry_type_1>::type, | |
395 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, | |
396 | geometry_type_1>::type & | |
397 | operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
398 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue); | |
399 | } | |
400 | ||
401 | struct yes_ps_ose : gtl_yes {}; | |
402 | ||
403 | template <typename geometry_type_1, typename geometry_type_2> | |
404 | typename enable_if< typename gtl_and_3< yes_ps_ose, typename is_mutable_polygon_set_type<geometry_type_1>::type, | |
405 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, | |
406 | geometry_type_1>::type & | |
407 | operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
408 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue); | |
409 | } | |
410 | ||
411 | struct yes_ps_oae : gtl_yes {}; | |
412 | ||
413 | template <typename geometry_type_1, typename geometry_type_2> | |
414 | typename enable_if< | |
415 | typename gtl_and_3< yes_ps_oae, typename is_mutable_polygon_set_type<geometry_type_1>::type, | |
416 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, | |
417 | geometry_type_1>::type & | |
418 | operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
419 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue); | |
420 | } | |
421 | ||
422 | struct yes_ps_oxe : gtl_yes {}; | |
423 | ||
424 | template <typename geometry_type_1, typename geometry_type_2> | |
425 | typename enable_if< typename gtl_and_3< yes_ps_oxe, typename is_mutable_polygon_set_type<geometry_type_1>::type, | |
426 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, | |
427 | geometry_type_1>::type & | |
428 | operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
429 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 2>(lvalue, rvalue); | |
430 | } | |
431 | ||
432 | struct yes_ps_ome : gtl_yes {}; | |
433 | ||
434 | template <typename geometry_type_1, typename geometry_type_2> | |
435 | typename enable_if< | |
436 | typename gtl_and_3< yes_ps_ome, typename is_mutable_polygon_set_type<geometry_type_1>::type, | |
437 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, | |
438 | geometry_type_1>::type & | |
439 | operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { | |
440 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 3>(lvalue, rvalue); | |
441 | } | |
442 | ||
443 | // TODO: Dafna, test these four resizing operators | |
444 | struct y_ps_rpe : gtl_yes {}; | |
445 | ||
446 | template <typename geometry_type_1, typename coordinate_type_1> | |
447 | typename enable_if< typename gtl_and_3< y_ps_rpe, typename is_mutable_polygon_set_type<geometry_type_1>::type, | |
448 | typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, | |
449 | coordinate_concept>::type>::type, | |
450 | geometry_type_1>::type & | |
451 | operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { | |
452 | return resize(lvalue, rvalue); | |
453 | } | |
454 | ||
455 | struct y_ps_rme : gtl_yes {}; | |
456 | ||
457 | template <typename geometry_type_1, typename coordinate_type_1> | |
458 | typename enable_if< typename gtl_and_3<y_ps_rme, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, | |
459 | typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, | |
460 | coordinate_concept>::type>::type, | |
461 | geometry_type_1>::type & | |
462 | operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { | |
463 | return resize(lvalue, -rvalue); | |
464 | } | |
465 | ||
466 | struct y_ps_rp : gtl_yes {}; | |
467 | ||
468 | template <typename geometry_type_1, typename coordinate_type_1> | |
469 | typename enable_if< typename gtl_and_3<y_ps_rp, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, | |
470 | typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, | |
471 | coordinate_concept>::type> | |
472 | ::type, geometry_type_1>::type | |
473 | operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { | |
474 | geometry_type_1 retval(lvalue); | |
475 | retval += rvalue; | |
476 | return retval; | |
477 | } | |
478 | ||
479 | struct y_ps_rm : gtl_yes {}; | |
480 | ||
481 | template <typename geometry_type_1, typename coordinate_type_1> | |
482 | typename enable_if< typename gtl_and_3<y_ps_rm, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, | |
483 | typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, | |
484 | coordinate_concept>::type> | |
485 | ::type, geometry_type_1>::type | |
486 | operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { | |
487 | geometry_type_1 retval(lvalue); | |
488 | retval -= rvalue; | |
489 | return retval; | |
490 | } | |
491 | ||
492 | ||
493 | } //end operators namespace | |
494 | ||
495 | template <typename T> | |
496 | struct view_of<polygon_45_set_concept, T> { | |
497 | typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type; | |
498 | T* tp; | |
499 | std::vector<polygon_45_with_holes_data<coordinate_type> > polys; | |
500 | view_of(const T& obj) : tp(), polys() { | |
501 | std::vector<polygon_with_holes_data<coordinate_type> > gpolys; | |
502 | assign(gpolys, obj); | |
503 | for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin(); | |
504 | itr != gpolys.end(); ++itr) { | |
505 | polys.push_back(polygon_45_with_holes_data<coordinate_type>()); | |
506 | assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr)); | |
507 | } | |
508 | } | |
509 | view_of(T& obj) : tp(&obj), polys() { | |
510 | std::vector<polygon_with_holes_data<coordinate_type> > gpolys; | |
511 | assign(gpolys, obj); | |
512 | for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin(); | |
513 | itr != gpolys.end(); ++itr) { | |
514 | polys.push_back(polygon_45_with_holes_data<coordinate_type>()); | |
515 | assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr)); | |
516 | } | |
517 | } | |
518 | ||
519 | typedef typename std::vector<polygon_45_with_holes_data<coordinate_type> >::const_iterator iterator_type; | |
520 | typedef view_of operator_arg_type; | |
521 | ||
522 | inline iterator_type begin() const { | |
523 | return polys.begin(); | |
524 | } | |
525 | ||
526 | inline iterator_type end() const { | |
527 | return polys.end(); | |
528 | } | |
529 | ||
530 | inline orientation_2d orient() const { return HORIZONTAL; } | |
531 | ||
532 | inline bool clean() const { return false; } | |
533 | ||
534 | inline bool sorted() const { return false; } | |
535 | ||
536 | inline T& get() { return *tp; } | |
537 | }; | |
538 | ||
539 | template <typename T> | |
540 | struct polygon_45_set_traits<view_of<polygon_45_set_concept, T> > { | |
541 | typedef typename view_of<polygon_45_set_concept, T>::coordinate_type coordinate_type; | |
542 | typedef typename view_of<polygon_45_set_concept, T>::iterator_type iterator_type; | |
543 | typedef view_of<polygon_45_set_concept, T> operator_arg_type; | |
544 | ||
545 | static inline iterator_type begin(const view_of<polygon_45_set_concept, T>& polygon_set) { | |
546 | return polygon_set.begin(); | |
547 | } | |
548 | ||
549 | static inline iterator_type end(const view_of<polygon_45_set_concept, T>& polygon_set) { | |
550 | return polygon_set.end(); | |
551 | } | |
552 | ||
553 | static inline orientation_2d orient(const view_of<polygon_45_set_concept, T>& polygon_set) { | |
554 | return polygon_set.orient(); } | |
555 | ||
556 | static inline bool clean(const view_of<polygon_45_set_concept, T>& polygon_set) { | |
557 | return polygon_set.clean(); } | |
558 | ||
559 | static inline bool sorted(const view_of<polygon_45_set_concept, T>& polygon_set) { | |
560 | return polygon_set.sorted(); } | |
561 | ||
562 | }; | |
563 | ||
564 | template <typename T> | |
565 | struct geometry_concept<view_of<polygon_45_set_concept, T> > { | |
566 | typedef polygon_45_set_concept type; | |
567 | }; | |
568 | ||
569 | template <typename T> | |
570 | struct get_coordinate_type<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> { | |
571 | typedef typename view_of<polygon_45_set_concept, T>::coordinate_type type; | |
572 | }; | |
573 | template <typename T> | |
574 | struct get_iterator_type_2<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> { | |
575 | typedef typename view_of<polygon_45_set_concept, T>::iterator_type type; | |
576 | static type begin(const view_of<polygon_45_set_concept, T>& t) { return t.begin(); } | |
577 | static type end(const view_of<polygon_45_set_concept, T>& t) { return t.end(); } | |
578 | }; | |
579 | } | |
580 | } | |
581 | #endif |