1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. 6 // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. 7 8 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 9 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 10 11 // Use, modification and distribution is subject to the Boost Software License, 12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 13 // http://www.boost.org/LICENSE_1_0.txt) 14 15 #ifndef BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP 16 #define BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP 17 18 #include <memory> 19 #include <vector> 20 21 #include <boost/concept/assert.hpp> 22 23 #include <boost/geometry/core/exterior_ring.hpp> 24 #include <boost/geometry/core/interior_rings.hpp> 25 #include <boost/geometry/core/point_type.hpp> 26 #include <boost/geometry/core/ring_type.hpp> 27 #include <boost/geometry/geometries/concepts/point_concept.hpp> 28 #include <boost/geometry/geometries/ring.hpp> 29 30 #include <boost/config.hpp> 31 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST 32 #include <initializer_list> 33 #endif 34 35 namespace boost { namespace geometry 36 { 37 38 namespace model 39 { 40 41 /*! 42 \brief The polygon contains an outer ring and zero or more inner rings. 43 \ingroup geometries 44 \tparam Point point type 45 \tparam ClockWise true for clockwise direction, 46 false for CounterClockWise direction 47 \tparam Closed true for closed polygons (last point == first point), 48 false open points 49 \tparam PointList container type for points, 50 for example std::vector, std::list, std::deque 51 \tparam RingList container type for inner rings, 52 for example std::vector, std::list, std::deque 53 \tparam PointAlloc container-allocator-type, for the points 54 \tparam RingAlloc container-allocator-type, for the rings 55 \note The container collecting the points in the rings can be different 56 from the container collecting the inner rings. They all default to vector. 57 58 \qbk{[include reference/geometries/polygon.qbk]} 59 \qbk{before.synopsis, 60 [heading Model of] 61 [link geometry.reference.concepts.concept_polygon Polygon Concept] 62 } 63 64 65 */ 66 template 67 < 68 typename Point, 69 bool ClockWise = true, 70 bool Closed = true, 71 template<typename, typename> class PointList = std::vector, 72 template<typename, typename> class RingList = std::vector, 73 template<typename> class PointAlloc = std::allocator, 74 template<typename> class RingAlloc = std::allocator 75 > 76 class polygon 77 { 78 BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) ); 79 80 public: 81 82 // Member types 83 typedef Point point_type; 84 typedef ring<Point, ClockWise, Closed, PointList, PointAlloc> ring_type; 85 typedef RingList<ring_type , RingAlloc<ring_type > > inner_container_type; 86 outer() const87 inline ring_type const& outer() const { return m_outer; } inners() const88 inline inner_container_type const& inners() const { return m_inners; } 89 outer()90 inline ring_type& outer() { return m_outer; } inners()91 inline inner_container_type & inners() { return m_inners; } 92 93 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST 94 95 // default constructor definition is required only 96 // if the constructor taking std::initializer_list is defined 97 98 /// \constructor_default{polygon} polygon()99 inline polygon() 100 : m_outer() 101 , m_inners() 102 {} 103 104 /// \constructor_initializer_list{polygon} polygon(std::initializer_list<ring_type> l)105 inline polygon(std::initializer_list<ring_type> l) 106 : m_outer(l.size() > 0 ? *l.begin() : ring_type()) 107 , m_inners(l.size() > 0 ? l.begin() + 1 : l.begin(), l.end()) 108 {} 109 110 // Commented out for now in order to support Boost.Assign 111 // Without this assignment operator first the object should be created 112 // from initializer list, then it shoudl be moved. 113 //// Without this workaround in MSVC the assignment operator is ambiguous 114 //#ifndef BOOST_MSVC 115 // /// \assignment_initializer_list{polygon} 116 // inline polygon & operator=(std::initializer_list<ring_type> l) 117 // { 118 // if ( l.size() > 0 ) 119 // { 120 // m_outer = *l.begin(); 121 // m_inners.assign(l.begin() + 1, l.end()); 122 // } 123 // else 124 // { 125 // m_outer.clear(); 126 // m_inners.clear(); 127 // } 128 // return *this; 129 // } 130 //#endif 131 132 #endif 133 134 /// Utility method, clears outer and inner rings clear()135 inline void clear() 136 { 137 m_outer.clear(); 138 m_inners.clear(); 139 } 140 141 private: 142 143 ring_type m_outer; 144 inner_container_type m_inners; 145 }; 146 147 148 } // namespace model 149 150 151 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS 152 namespace traits 153 { 154 155 template 156 < 157 typename Point, 158 bool ClockWise, bool Closed, 159 template<typename, typename> class PointList, 160 template<typename, typename> class RingList, 161 template<typename> class PointAlloc, 162 template<typename> class RingAlloc 163 > 164 struct tag 165 < 166 model::polygon 167 < 168 Point, ClockWise, Closed, 169 PointList, RingList, PointAlloc, RingAlloc 170 > 171 > 172 { 173 typedef polygon_tag type; 174 }; 175 176 template 177 < 178 typename Point, 179 bool ClockWise, bool Closed, 180 template<typename, typename> class PointList, 181 template<typename, typename> class RingList, 182 template<typename> class PointAlloc, 183 template<typename> class RingAlloc 184 > 185 struct ring_const_type 186 < 187 model::polygon 188 < 189 Point, ClockWise, Closed, 190 PointList, RingList, PointAlloc, RingAlloc 191 > 192 > 193 { 194 typedef typename model::polygon 195 < 196 Point, ClockWise, Closed, 197 PointList, RingList, 198 PointAlloc, RingAlloc 199 >::ring_type const& type; 200 }; 201 202 203 template 204 < 205 typename Point, 206 bool ClockWise, bool Closed, 207 template<typename, typename> class PointList, 208 template<typename, typename> class RingList, 209 template<typename> class PointAlloc, 210 template<typename> class RingAlloc 211 > 212 struct ring_mutable_type 213 < 214 model::polygon 215 < 216 Point, ClockWise, Closed, 217 PointList, RingList, PointAlloc, RingAlloc 218 > 219 > 220 { 221 typedef typename model::polygon 222 < 223 Point, ClockWise, Closed, 224 PointList, RingList, 225 PointAlloc, RingAlloc 226 >::ring_type& type; 227 }; 228 229 template 230 < 231 typename Point, 232 bool ClockWise, bool Closed, 233 template<typename, typename> class PointList, 234 template<typename, typename> class RingList, 235 template<typename> class PointAlloc, 236 template<typename> class RingAlloc 237 > 238 struct interior_const_type 239 < 240 model::polygon 241 < 242 Point, ClockWise, Closed, 243 PointList, RingList, 244 PointAlloc, RingAlloc 245 > 246 > 247 { 248 typedef typename model::polygon 249 < 250 Point, ClockWise, Closed, 251 PointList, RingList, 252 PointAlloc, RingAlloc 253 >::inner_container_type const& type; 254 }; 255 256 257 template 258 < 259 typename Point, 260 bool ClockWise, bool Closed, 261 template<typename, typename> class PointList, 262 template<typename, typename> class RingList, 263 template<typename> class PointAlloc, 264 template<typename> class RingAlloc 265 > 266 struct interior_mutable_type 267 < 268 model::polygon 269 < 270 Point, ClockWise, Closed, 271 PointList, RingList, 272 PointAlloc, RingAlloc 273 > 274 > 275 { 276 typedef typename model::polygon 277 < 278 Point, ClockWise, Closed, 279 PointList, RingList, 280 PointAlloc, RingAlloc 281 >::inner_container_type& type; 282 }; 283 284 285 template 286 < 287 typename Point, 288 bool ClockWise, bool Closed, 289 template<typename, typename> class PointList, 290 template<typename, typename> class RingList, 291 template<typename> class PointAlloc, 292 template<typename> class RingAlloc 293 > 294 struct exterior_ring 295 < 296 model::polygon 297 < 298 Point, ClockWise, Closed, 299 PointList, RingList, PointAlloc, RingAlloc 300 > 301 > 302 { 303 typedef model::polygon 304 < 305 Point, ClockWise, Closed, 306 PointList, RingList, 307 PointAlloc, RingAlloc 308 > polygon_type; 309 getboost::geometry::traits::exterior_ring310 static inline typename polygon_type::ring_type& get(polygon_type& p) 311 { 312 return p.outer(); 313 } 314 getboost::geometry::traits::exterior_ring315 static inline typename polygon_type::ring_type const& get( 316 polygon_type const& p) 317 { 318 return p.outer(); 319 } 320 }; 321 322 template 323 < 324 typename Point, 325 bool ClockWise, bool Closed, 326 template<typename, typename> class PointList, 327 template<typename, typename> class RingList, 328 template<typename> class PointAlloc, 329 template<typename> class RingAlloc 330 > 331 struct interior_rings 332 < 333 model::polygon 334 < 335 Point, ClockWise, Closed, 336 PointList, RingList, 337 PointAlloc, RingAlloc 338 > 339 > 340 { 341 typedef model::polygon 342 < 343 Point, ClockWise, Closed, PointList, RingList, 344 PointAlloc, RingAlloc 345 > polygon_type; 346 getboost::geometry::traits::interior_rings347 static inline typename polygon_type::inner_container_type& get( 348 polygon_type& p) 349 { 350 return p.inners(); 351 } 352 getboost::geometry::traits::interior_rings353 static inline typename polygon_type::inner_container_type const& get( 354 polygon_type const& p) 355 { 356 return p.inners(); 357 } 358 }; 359 360 } // namespace traits 361 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS 362 363 364 365 }} // namespace boost::geometry 366 367 #endif // BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP 368