1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
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)
9 #ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
10 #define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
12 // Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
13 // boost::polygon::polygon_with_holes_data -> boost::geometry::polygon
14 // pair{begin_points, end_points} -> ring_proxy
16 #include <boost/polygon/polygon.hpp>
17 #include <boost/range.hpp>
21 namespace boost { namespace geometry
24 namespace adapt { namespace bp
30 template <bool Mutable>
37 template <typename Ring, typename Point>
38 static inline void push_back(Ring& ring, Point const& point)
40 // Boost.Polygon's polygons are not appendable. So create a temporary vector,
41 // add a record and set it to the original. Of course: this is not efficient.
42 // But there seems no other way (without using a wrapper)
43 std::vector<Point> temporary_vector
45 boost::polygon::begin_points(ring),
46 boost::polygon::end_points(ring)
48 temporary_vector.push_back(point);
49 boost::polygon::set_points(ring, temporary_vector.begin(), temporary_vector.end());
57 template <typename Ring, typename Point>
58 static inline void push_back(Ring& /*ring*/, Point const& /*point*/)
68 // Polygon should implement the boost::polygon::polygon_with_holes_concept
69 // Specify constness in the template parameter if necessary
70 template<typename Polygon>
74 typedef typename boost::polygon::polygon_traits
76 typename boost::remove_const<Polygon>::type
77 >::iterator_type iterator_type;
79 typedef typename boost::polygon::polygon_with_holes_traits
81 typename boost::remove_const<Polygon>::type
82 >::iterator_holes_type hole_iterator_type;
84 static const bool is_mutable = !boost::is_const<Polygon>::type::value;
86 inline ring_proxy(Polygon& p)
87 : m_polygon_pointer(&p)
91 // Constructor used from hole_iterator
92 inline ring_proxy(Polygon& p, hole_iterator_type hole_it)
93 : m_polygon_pointer(&p)
98 // Default constructor, for mutable polygons / appending (interior) rings
100 : m_polygon_pointer(&m_polygon_for_default_constructor)
105 iterator_type begin() const
108 ? boost::polygon::begin_points(*m_hole_it)
109 : boost::polygon::begin_points(*m_polygon_pointer)
113 iterator_type begin()
116 ? boost::polygon::begin_points(*m_hole_it)
117 : boost::polygon::begin_points(*m_polygon_pointer)
121 iterator_type end() const
124 ? boost::polygon::end_points(*m_hole_it)
125 : boost::polygon::end_points(*m_polygon_pointer)
132 ? boost::polygon::end_points(*m_hole_it)
133 : boost::polygon::end_points(*m_polygon_pointer)
143 // Does NOT work see comment above
147 boost::polygon::set_points(*m_polygon_pointer,
148 boost::polygon::begin_points(p),
149 boost::polygon::end_points(p));
153 void resize(std::size_t /*new_size*/)
157 // Does NOT work see comment above
161 // TODO: implement this by resizing the container
167 template <typename Point>
168 void push_back(Point const& point)
172 //detail::modify<is_mutable>::push_back(*m_hole_it, point);
173 //std::cout << "HOLE: " << typeid(*m_hole_it).name() << std::endl;
174 //std::cout << "HOLE: " << typeid(m_hole_it).name() << std::endl;
175 //std::cout << "HOLE: " << typeid(hole_iterator_type).name() << std::endl;
177 // Note, ths does NOT work because hole_iterator_type is defined
178 // as a const_iterator by Boost.Polygon
183 detail::modify<is_mutable>::push_back(*m_polygon_pointer, point);
188 Polygon* m_polygon_pointer;
190 hole_iterator_type m_hole_it;
192 Polygon m_polygon_for_default_constructor;
198 // Support geometry::adapt::bp::ring_proxy for Boost.Range ADP
199 template<typename Polygon>
200 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
201 range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
203 return proxy.begin();
206 template<typename Polygon>
207 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
208 range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
210 return proxy.begin();
213 template<typename Polygon>
214 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
215 range_end(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
220 template<typename Polygon>
221 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
222 range_end(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
230 }} // namespace adapt::bp
236 template <typename Polygon>
237 struct tag<adapt::bp::ring_proxy<Polygon> >
239 typedef ring_tag type;
243 template <typename Polygon>
244 struct rvalue_type<adapt::bp::ring_proxy<Polygon> >
246 typedef adapt::bp::ring_proxy<Polygon> type;
249 template <typename Polygon>
250 struct clear<adapt::bp::ring_proxy<Polygon> >
252 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy)
259 template <typename Polygon>
260 struct resize<adapt::bp::ring_proxy<Polygon> >
262 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy, std::size_t new_size)
264 proxy.resize(new_size);
268 template <typename Polygon>
269 struct push_back<adapt::bp::ring_proxy<Polygon> >
271 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy,
272 typename boost::polygon::polygon_traits<Polygon>::point_type const& point)
274 proxy.push_back(point);
279 } // namespace traits
281 }} // namespace boost::geometry
283 // Specialize ring_proxy for Boost.Range
286 template<typename Polygon>
287 struct range_mutable_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
289 typedef typename geometry::adapt::bp::ring_proxy<Polygon>::iterator_type type;
292 template<typename Polygon>
293 struct range_const_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
295 typedef typename geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type type;
301 #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP