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