polygon_set_concept.hpp 26 KB

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