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 begin_polygon_set_data(const polygon_set_type & polygon_set)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 end_polygon_set_data(const polygon_set_type & polygon_set)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 clean(const polygon_set_type & polygon_set)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 & assign(polygon_set_type_1 & lvalue,const polygon_set_type_2 & rvalue)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 get_trapezoids(output_container_type & output,const polygon_set_type & polygon_set)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 get_trapezoids(output_container_type & output,const polygon_set_type & polygon_set,orientation_2d orient)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 equivalence(const polygon_set_type_1 & lvalue,const polygon_set_type_2 & rvalue)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 clear(polygon_set_type & polygon_set)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 empty(const polygon_set_type & polygon_set)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 extents(rectangle_type & extents_rectangle,const polygon_set_type & polygon_set)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 area(const polygon_set_type & polygon_set)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 simplify(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::coordinate_distance threshold)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 & resize(polygon_set_type & polygon_set,coord_type resizing,bool corner_fill_arcs=false,int num_circle_segments=0)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 & bloat(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating)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 & shrink(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking)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& interact(polygon_set_type_1 & polygon_set_1,const polygon_set_type_2 & polygon_set_2)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 & scale_up(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor)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 & scale_down(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor)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 & transform(polygon_set_type & polygon_set,const transformation_type & transformation)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 & keep(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type min_area,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type max_area,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height)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 operator |(const geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 operator +(const geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 operator *(const geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 operator &(const geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 operator ^(const geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 operator -(const geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 & operator +=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 & operator |=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 & operator *=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 & operator &=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 & operator ^=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 & operator -=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)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 & operator +=(geometry_type_1 & lvalue,coordinate_type_1 rvalue)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 & operator -=(geometry_type_1 & lvalue,coordinate_type_1 rvalue)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 operator +(const geometry_type_1 & lvalue,coordinate_type_1 rvalue)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 operator -(const geometry_type_1 & lvalue,coordinate_type_1 rvalue)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; view_ofboost::polygon::view_of500 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 } view_ofboost::polygon::view_of509 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 beginboost::polygon::view_of522 inline iterator_type begin() const { 523 return polys.begin(); 524 } 525 endboost::polygon::view_of526 inline iterator_type end() const { 527 return polys.end(); 528 } 529 orientboost::polygon::view_of530 inline orientation_2d orient() const { return HORIZONTAL; } 531 cleanboost::polygon::view_of532 inline bool clean() const { return false; } 533 sortedboost::polygon::view_of534 inline bool sorted() const { return false; } 535 getboost::polygon::view_of536 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 beginboost::polygon::polygon_45_set_traits545 static inline iterator_type begin(const view_of<polygon_45_set_concept, T>& polygon_set) { 546 return polygon_set.begin(); 547 } 548 endboost::polygon::polygon_45_set_traits549 static inline iterator_type end(const view_of<polygon_45_set_concept, T>& polygon_set) { 550 return polygon_set.end(); 551 } 552 orientboost::polygon::polygon_45_set_traits553 static inline orientation_2d orient(const view_of<polygon_45_set_concept, T>& polygon_set) { 554 return polygon_set.orient(); } 555 cleanboost::polygon::polygon_45_set_traits556 static inline bool clean(const view_of<polygon_45_set_concept, T>& polygon_set) { 557 return polygon_set.clean(); } 558 sortedboost::polygon::polygon_45_set_traits559 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; beginboost::polygon::get_iterator_type_2576 static type begin(const view_of<polygon_45_set_concept, T>& t) { return t.begin(); } endboost::polygon::get_iterator_type_2577 static type end(const view_of<polygon_45_set_concept, T>& t) { return t.end(); } 578 }; 579 } 580 } 581 #endif 582