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
35namespace boost { namespace geometry
36{
37
38namespace 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*/
66template
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>
76class polygon
77{
78 BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
79
80public:
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
87 inline ring_type const& outer() const { return m_outer; }
88 inline inner_container_type const& inners() const { return m_inners; }
89
90 inline ring_type& outer() { return m_outer; }
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}
99 inline polygon()
100 : m_outer()
101 , m_inners()
102 {}
103
104 /// \constructor_initializer_list{polygon}
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
135 inline void clear()
136 {
137 m_outer.clear();
138 m_inners.clear();
139 }
140
141private:
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
152namespace traits
153{
154
155template
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>
164struct 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
176template
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>
185struct 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
203template
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>
212struct 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
229template
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>
238struct 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
257template
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>
266struct 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
285template
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>
294struct 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
310 static inline typename polygon_type::ring_type& get(polygon_type& p)
311 {
312 return p.outer();
313 }
314
315 static inline typename polygon_type::ring_type const& get(
316 polygon_type const& p)
317 {
318 return p.outer();
319 }
320};
321
322template
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>
331struct 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
347 static inline typename polygon_type::inner_container_type& get(
348 polygon_type& p)
349 {
350 return p.inners();
351 }
352
353 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

source code of boost/boost/geometry/geometries/polygon.hpp