• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2010-2012 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_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP
10 #define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP
11 
12 // Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
13 // boost::polygon::polygon_with_holes_data -> boost::geometry::polygon
14 //   pair{begin_holes, begin_holes} -> interior_proxy
15 
16 #include <boost/polygon/polygon.hpp>
17 
18 #include <boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp>
19 #include <boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp>
20 
21 
22 namespace boost { namespace geometry
23 {
24 
25 namespace adapt { namespace bp
26 {
27 
28 
29 // Polygon should implement the boost::polygon::polygon_with_holes_concept
30 // Specify constness in the template parameter if necessary
31 template<typename Polygon>
32 struct holes_proxy
33 {
34     typedef ring_proxy
35         <
36             typename boost::mpl::if_
37                 <
38                     typename boost::is_const<Polygon>,
39                     Polygon const,
40                     Polygon
41                 >::type
42         > proxy_type;
43     typedef hole_iterator<Polygon, proxy_type> iterator_type;
44 
45     // The next line does not work probably because coordinate_type is part of the
46     // polygon_traits, but not of the polygon_with_holes_traits
47     // typedef typename boost::polygon::polygon_traits<Polygon>::coordinate_type coordinate_type;
48 
49     // So we use:
50     typedef typename Polygon::coordinate_type coordinate_type;
51 
holes_proxyboost::geometry::adapt::bp::holes_proxy52     inline holes_proxy(Polygon& p)
53         : polygon(p)
54     {}
55 
clearboost::geometry::adapt::bp::holes_proxy56     inline void clear()
57     {
58         Polygon empty;
59         // Clear the holes
60         polygon.set_holes
61             (
62                 boost::polygon::begin_holes(empty),
63                 boost::polygon::end_holes(empty)
64             );
65     }
66 
resizeboost::geometry::adapt::bp::holes_proxy67     inline void resize(std::size_t new_size)
68     {
69         std::vector<boost::polygon::polygon_data<coordinate_type> > temporary_copy
70             (
71                 boost::polygon::begin_holes(polygon),
72                 boost::polygon::end_holes(polygon)
73             );
74         temporary_copy.resize(new_size);
75         polygon.set_holes(temporary_copy.begin(), temporary_copy.end());
76     }
77 
78     template <typename Ring>
push_backboost::geometry::adapt::bp::holes_proxy79     inline void push_back(Ring const& ring)
80     {
81         std::vector<boost::polygon::polygon_data<coordinate_type> > temporary_copy
82             (
83                 boost::polygon::begin_holes(polygon),
84                 boost::polygon::end_holes(polygon)
85             );
86         boost::polygon::polygon_data<coordinate_type> added;
87         boost::polygon::set_points(added, ring.begin(), ring.end());
88         temporary_copy.push_back(added);
89         polygon.set_holes(temporary_copy.begin(), temporary_copy.end());
90     }
91 
92 
93     Polygon& polygon;
94 };
95 
96 
97 // Support holes_proxy for Boost.Range ADP
98 
99 // Const versions
100 template<typename Polygon>
101 inline typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type
range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon const> const & proxy)102             range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon const> const& proxy)
103 {
104     typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type
105             begin(proxy.polygon, boost::polygon::begin_holes(proxy.polygon));
106     return begin;
107 }
108 
109 template<typename Polygon>
110 inline typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type
range_end(boost::geometry::adapt::bp::holes_proxy<Polygon const> const & proxy)111             range_end(boost::geometry::adapt::bp::holes_proxy<Polygon const> const& proxy)
112 {
113     typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type
114             end(proxy.polygon, boost::polygon::end_holes(proxy.polygon));
115     return end;
116 }
117 
118 // Mutable versions
119 template<typename Polygon>
120 inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type
range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon> & proxy)121             range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon>& proxy)
122 {
123     typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type
124             begin(proxy.polygon, boost::polygon::begin_holes(proxy.polygon));
125     return begin;
126 }
127 
128 template<typename Polygon>
129 inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type
range_end(boost::geometry::adapt::bp::holes_proxy<Polygon> & proxy)130             range_end(boost::geometry::adapt::bp::holes_proxy<Polygon>& proxy)
131 {
132     typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type
133             end(proxy.polygon, boost::polygon::end_holes(proxy.polygon));
134     return end;
135 }
136 
137 
138 }}
139 
140 namespace traits
141 {
142 
143 template <typename Polygon>
144 struct rvalue_type<adapt::bp::holes_proxy<Polygon> >
145 {
146     typedef adapt::bp::holes_proxy<Polygon> type;
147 };
148 
149 
150 template <typename Polygon>
151 struct clear<adapt::bp::holes_proxy<Polygon> >
152 {
applyboost::geometry::traits::clear153     static inline void apply(adapt::bp::holes_proxy<Polygon> proxy)
154     {
155         proxy.clear();
156     }
157 };
158 
159 template <typename Polygon>
160 struct resize<adapt::bp::holes_proxy<Polygon> >
161 {
applyboost::geometry::traits::resize162     static inline void apply(adapt::bp::holes_proxy<Polygon> proxy, std::size_t new_size)
163     {
164         proxy.resize(new_size);
165     }
166 };
167 
168 template <typename Polygon>
169 struct push_back<adapt::bp::holes_proxy<Polygon> >
170 {
171     template <typename Ring>
applyboost::geometry::traits::push_back172     static inline void apply(adapt::bp::holes_proxy<Polygon> proxy, Ring const& ring)
173     {
174         proxy.push_back(ring);
175     }
176 };
177 
178 
179 
180 } // namespace traits
181 
182 
183 }}
184 
185 
186 // Specialize holes_proxy for Boost.Range
187 namespace boost
188 {
189     template<typename Polygon>
190     struct range_mutable_iterator<geometry::adapt::bp::holes_proxy<Polygon> >
191     {
192         typedef typename geometry::adapt::bp::holes_proxy<Polygon>::iterator_type type;
193     };
194 
195     template<typename Polygon>
196     struct range_const_iterator<geometry::adapt::bp::holes_proxy<Polygon> >
197     {
198         typedef typename geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type type;
199     };
200 
201 } // namespace boost
202 
203 
204 #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP
205