• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
26 #include <boost/geometry/core/ring_type.hpp>
27 #include <boost/geometry/core/tag.hpp>
28 #include <boost/geometry/core/tags.hpp>
29 #include <boost/geometry/util/bare_type.hpp>
30 
31 namespace 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 */
50 enum 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 
62 namespace 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 */
74 template <typename G>
75 struct closure
76 {
77     static const closure_selector value = closed;
78 };
79 
80 
81 } // namespace traits
82 
83 
84 #ifndef DOXYGEN_NO_DETAIL
85 namespace core_detail { namespace closure
86 {
87 
88 struct 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
96 template <closure_selector Closure>
97 struct minimum_ring_size {};
98 
99 template <>
100 struct minimum_ring_size<geometry::closed> : boost::mpl::size_t<4> {};
101 
102 template <>
103 struct 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
112 namespace core_dispatch
113 {
114 
115 template <typename Tag, typename Geometry>
116 struct closure
117 {
118     BOOST_MPL_ASSERT_MSG
119         (
120             false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
121             , (types<Geometry>)
122         );
123 };
124 
125 template <typename Box>
126 struct closure<point_tag, Box> : public core_detail::closure::closed {};
127 
128 template <typename Box>
129 struct closure<box_tag, Box> : public core_detail::closure::closed {};
130 
131 template <typename Box>
132 struct closure<segment_tag, Box> : public core_detail::closure::closed {};
133 
134 template <typename LineString>
135 struct closure<linestring_tag, LineString>
136     : public core_detail::closure::closed {};
137 
138 
139 template <typename Ring>
140 struct 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
147 template <typename Polygon>
148 struct 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 
157 template <typename MultiPoint>
158 struct closure<multi_point_tag, MultiPoint>
159     : public core_detail::closure::closed {};
160 
161 template <typename MultiLinestring>
162 struct 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
166 template <typename MultiPolygon>
167 struct 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 */
188 template <typename Geometry>
189 struct 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