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
7// This file was modified by Oracle on 2014.
8// Modifications copyright (c) 2014 Oracle and/or its affiliates.
9
10// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11
12// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
14
15// Use, modification and distribution is subject to the Boost Software License,
16// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17// http://www.boost.org/LICENSE_1_0.txt)
18
19#ifndef BOOST_GEOMETRY_CORE_CLOSURE_HPP
20#define BOOST_GEOMETRY_CORE_CLOSURE_HPP
21
22#include <boost/mpl/assert.hpp>
23#include <boost/mpl/size_t.hpp>
24#include <boost/range/value_type.hpp>
25#include <boost/type_traits/remove_const.hpp>
26
27#include <boost/geometry/core/ring_type.hpp>
28#include <boost/geometry/core/tag.hpp>
29#include <boost/geometry/core/tags.hpp>
30
31namespace boost { namespace geometry
32{
33
34
35/*!
36\brief Enumerates options for defining if polygons are open or closed
37\ingroup enum
38\details The enumeration closure_selector describes options for if a polygon is
39 open or closed. In a closed polygon the very first point (per ring) should
40 be equal to the very last point.
41 The specific closing property of a polygon type is defined by the closure
42 metafunction. The closure metafunction defines a value, which is one of the
43 values enumerated in the closure_selector
44
45\qbk{
46[heading See also]
47[link geometry.reference.core.closure The closure metafunction]
48}
49*/
50enum closure_selector
51{
52 /// Rings are open: first point and last point are different, algorithms
53 /// close them explicitly on the fly
54 open = 0,
55 /// Rings are closed: first point and last point must be the same
56 closed = 1,
57 /// (Not yet implemented): algorithms first figure out if ring must be
58 /// closed on the fly
59 closure_undertermined = -1
60};
61
62namespace traits
63{
64
65/*!
66 \brief Traits class indicating if points within a
67 ring or (multi)polygon are closed (last point == first point),
68 open or not known.
69 \ingroup traits
70 \par Geometries:
71 - ring
72 \tparam G geometry
73*/
74template <typename G>
75struct closure
76{
77 static const closure_selector value = closed;
78};
79
80
81} // namespace traits
82
83
84#ifndef DOXYGEN_NO_DETAIL
85namespace core_detail { namespace closure
86{
87
88struct closed
89{
90 static const closure_selector value = geometry::closed;
91};
92
93
94/// Metafunction to define the minimum size of a ring:
95/// 3 for open rings, 4 for closed rings
96template <closure_selector Closure>
97struct minimum_ring_size {};
98
99template <>
100struct minimum_ring_size<geometry::closed> : boost::mpl::size_t<4> {};
101
102template <>
103struct minimum_ring_size<geometry::open> : boost::mpl::size_t<3> {};
104
105
106}} // namespace detail::point_order
107#endif // DOXYGEN_NO_DETAIL
108
109
110
111#ifndef DOXYGEN_NO_DISPATCH
112namespace core_dispatch
113{
114
115template <typename Tag, typename Geometry>
116struct closure
117{
118 BOOST_MPL_ASSERT_MSG
119 (
120 false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
121 , (types<Geometry>)
122 );
123};
124
125template <typename Box>
126struct closure<point_tag, Box> : public core_detail::closure::closed {};
127
128template <typename Box>
129struct closure<box_tag, Box> : public core_detail::closure::closed {};
130
131template <typename Box>
132struct closure<segment_tag, Box> : public core_detail::closure::closed {};
133
134template <typename LineString>
135struct closure<linestring_tag, LineString>
136 : public core_detail::closure::closed {};
137
138
139template <typename Ring>
140struct closure<ring_tag, Ring>
141{
142 static const closure_selector value
143 = geometry::traits::closure<Ring>::value;
144};
145
146// Specialization for Polygon: the closure is the closure of its rings
147template <typename Polygon>
148struct closure<polygon_tag, Polygon>
149{
150 static const closure_selector value = core_dispatch::closure
151 <
152 ring_tag,
153 typename ring_type<polygon_tag, Polygon>::type
154 >::value ;
155};
156
157template <typename MultiPoint>
158struct closure<multi_point_tag, MultiPoint>
159 : public core_detail::closure::closed {};
160
161template <typename MultiLinestring>
162struct closure<multi_linestring_tag, MultiLinestring>
163 : public core_detail::closure::closed {};
164
165// Specialization for MultiPolygon: the closure is the closure of Polygon's rings
166template <typename MultiPolygon>
167struct closure<multi_polygon_tag, MultiPolygon>
168{
169 static const closure_selector value = core_dispatch::closure
170 <
171 polygon_tag,
172 typename boost::range_value<MultiPolygon>::type
173 >::value ;
174};
175
176} // namespace core_dispatch
177#endif // DOXYGEN_NO_DISPATCH
178
179
180/*!
181\brief \brief_meta{value, closure (clockwise\, counterclockwise),
182 \meta_geometry_type}
183\tparam Geometry \tparam_geometry
184\ingroup core
185
186\qbk{[include reference/core/closure.qbk]}
187*/
188template <typename Geometry>
189struct closure
190{
191 static const closure_selector value = core_dispatch::closure
192 <
193 typename tag<Geometry>::type,
194 typename util::bare_type<Geometry>::type
195 >::value;
196};
197
198
199}} // namespace boost::geometry
200
201
202#endif // BOOST_GEOMETRY_CORE_CLOSURE_HPP
203

source code of boost/boost/geometry/core/closure.hpp