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-2018 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
32#include <initializer_list>
33
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::deque
51\tparam RingList container type for inner rings,
52 for example std::vector, 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( (concepts::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 // default constructor definition is required only
94 // if the constructor taking std::initializer_list is defined
95
96 /// \constructor_default{polygon}
97 inline polygon()
98 : m_outer()
99 , m_inners()
100 {}
101
102 /// \constructor_initializer_list{polygon}
103 inline polygon(std::initializer_list<ring_type> l)
104 : m_outer(l.size() > 0 ? *l.begin() : ring_type())
105 , m_inners(l.size() > 0 ? l.begin() + 1 : l.begin(), l.end())
106 {}
107
108// Commented out for now in order to support Boost.Assign
109// Without this assignment operator first the object should be created
110// from initializer list, then it shoudl be moved.
111//// Without this workaround in MSVC the assignment operator is ambiguous
112//#ifndef BOOST_MSVC
113// /// \assignment_initializer_list{polygon}
114// inline polygon & operator=(std::initializer_list<ring_type> l)
115// {
116// if ( l.size() > 0 )
117// {
118// m_outer = *l.begin();
119// m_inners.assign(l.begin() + 1, l.end());
120// }
121// else
122// {
123// m_outer.clear();
124// m_inners.clear();
125// }
126// return *this;
127// }
128//#endif
129
130 /// Utility method, clears outer and inner rings
131 inline void clear()
132 {
133 m_outer.clear();
134 m_inners.clear();
135 }
136
137private:
138
139 ring_type m_outer;
140 inner_container_type m_inners;
141};
142
143
144} // namespace model
145
146
147#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
148namespace traits
149{
150
151template
152<
153 typename Point,
154 bool ClockWise, bool Closed,
155 template<typename, typename> class PointList,
156 template<typename, typename> class RingList,
157 template<typename> class PointAlloc,
158 template<typename> class RingAlloc
159>
160struct tag
161<
162 model::polygon
163 <
164 Point, ClockWise, Closed,
165 PointList, RingList, PointAlloc, RingAlloc
166 >
167>
168{
169 typedef polygon_tag type;
170};
171
172template
173<
174 typename Point,
175 bool ClockWise, bool Closed,
176 template<typename, typename> class PointList,
177 template<typename, typename> class RingList,
178 template<typename> class PointAlloc,
179 template<typename> class RingAlloc
180>
181struct ring_const_type
182<
183 model::polygon
184 <
185 Point, ClockWise, Closed,
186 PointList, RingList, PointAlloc, RingAlloc
187 >
188>
189{
190 typedef typename model::polygon
191 <
192 Point, ClockWise, Closed,
193 PointList, RingList,
194 PointAlloc, RingAlloc
195 >::ring_type const& type;
196};
197
198
199template
200<
201 typename Point,
202 bool ClockWise, bool Closed,
203 template<typename, typename> class PointList,
204 template<typename, typename> class RingList,
205 template<typename> class PointAlloc,
206 template<typename> class RingAlloc
207>
208struct ring_mutable_type
209<
210 model::polygon
211 <
212 Point, ClockWise, Closed,
213 PointList, RingList, PointAlloc, RingAlloc
214 >
215>
216{
217 typedef typename model::polygon
218 <
219 Point, ClockWise, Closed,
220 PointList, RingList,
221 PointAlloc, RingAlloc
222 >::ring_type& type;
223};
224
225template
226<
227 typename Point,
228 bool ClockWise, bool Closed,
229 template<typename, typename> class PointList,
230 template<typename, typename> class RingList,
231 template<typename> class PointAlloc,
232 template<typename> class RingAlloc
233>
234struct interior_const_type
235<
236 model::polygon
237 <
238 Point, ClockWise, Closed,
239 PointList, RingList,
240 PointAlloc, RingAlloc
241 >
242>
243{
244 typedef typename model::polygon
245 <
246 Point, ClockWise, Closed,
247 PointList, RingList,
248 PointAlloc, RingAlloc
249 >::inner_container_type const& type;
250};
251
252
253template
254<
255 typename Point,
256 bool ClockWise, bool Closed,
257 template<typename, typename> class PointList,
258 template<typename, typename> class RingList,
259 template<typename> class PointAlloc,
260 template<typename> class RingAlloc
261>
262struct interior_mutable_type
263<
264 model::polygon
265 <
266 Point, ClockWise, Closed,
267 PointList, RingList,
268 PointAlloc, RingAlloc
269 >
270>
271{
272 typedef typename model::polygon
273 <
274 Point, ClockWise, Closed,
275 PointList, RingList,
276 PointAlloc, RingAlloc
277 >::inner_container_type& type;
278};
279
280
281template
282<
283 typename Point,
284 bool ClockWise, bool Closed,
285 template<typename, typename> class PointList,
286 template<typename, typename> class RingList,
287 template<typename> class PointAlloc,
288 template<typename> class RingAlloc
289>
290struct exterior_ring
291<
292 model::polygon
293 <
294 Point, ClockWise, Closed,
295 PointList, RingList, PointAlloc, RingAlloc
296 >
297>
298{
299 typedef model::polygon
300 <
301 Point, ClockWise, Closed,
302 PointList, RingList,
303 PointAlloc, RingAlloc
304 > polygon_type;
305
306 static inline typename polygon_type::ring_type& get(polygon_type& p)
307 {
308 return p.outer();
309 }
310
311 static inline typename polygon_type::ring_type const& get(
312 polygon_type const& p)
313 {
314 return p.outer();
315 }
316};
317
318template
319<
320 typename Point,
321 bool ClockWise, bool Closed,
322 template<typename, typename> class PointList,
323 template<typename, typename> class RingList,
324 template<typename> class PointAlloc,
325 template<typename> class RingAlloc
326>
327struct interior_rings
328<
329 model::polygon
330 <
331 Point, ClockWise, Closed,
332 PointList, RingList,
333 PointAlloc, RingAlloc
334 >
335>
336{
337 typedef model::polygon
338 <
339 Point, ClockWise, Closed, PointList, RingList,
340 PointAlloc, RingAlloc
341 > polygon_type;
342
343 static inline typename polygon_type::inner_container_type& get(
344 polygon_type& p)
345 {
346 return p.inners();
347 }
348
349 static inline typename polygon_type::inner_container_type const& get(
350 polygon_type const& p)
351 {
352 return p.inners();
353 }
354};
355
356} // namespace traits
357#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
358
359
360
361}} // namespace boost::geometry
362
363#endif // BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP
364

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