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