1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 #ifndef BOOST_GEOMETRY_CORE_CLOSURE_HPP
15 #define BOOST_GEOMETRY_CORE_CLOSURE_HPP
18 #include <boost/mpl/assert.hpp>
19 #include <boost/mpl/int.hpp>
20 #include <boost/range.hpp>
21 #include <boost/type_traits/remove_const.hpp>
23 #include <boost/geometry/core/ring_type.hpp>
24 #include <boost/geometry/core/tag.hpp>
25 #include <boost/geometry/core/tags.hpp>
27 namespace boost { namespace geometry
32 \brief Enumerates options for defining if polygons are open or closed
34 \details The enumeration closure_selector describes options for if a polygon is
35 open or closed. In a closed polygon the very first point (per ring) should
36 be equal to the very last point.
37 The specific closing property of a polygon type is defined by the closure
38 metafunction. The closure metafunction defines a value, which is one of the
39 values enumerated in the closure_selector
43 [link geometry.reference.core.closure The closure metafunction]
48 /// Rings are open: first point and last point are different, algorithms
49 /// close them explicitly on the fly
51 /// Rings are closed: first point and last point must be the same
53 /// (Not yet implemented): algorithms first figure out if ring must be
55 closure_undertermined = -1
62 \brief Traits class indicating if points within a
63 ring or (multi)polygon are closed (last point == first point),
73 static const closure_selector value = closed;
80 #ifndef DOXYGEN_NO_DETAIL
81 namespace core_detail { namespace closure
86 static const closure_selector value = geometry::closed;
90 /// Metafunction to define the minimum size of a ring:
91 /// 3 for open rings, 4 for closed rings
92 template <closure_selector Closure>
93 struct minimum_ring_size {};
96 struct minimum_ring_size<geometry::closed> : boost::mpl::int_<4> {};
99 struct minimum_ring_size<geometry::open> : boost::mpl::int_<3> {};
102 }} // namespace detail::point_order
103 #endif // DOXYGEN_NO_DETAIL
107 #ifndef DOXYGEN_NO_DISPATCH
108 namespace core_dispatch
111 template <typename Tag, typename Geometry>
116 false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
121 template <typename Box>
122 struct closure<point_tag, Box> : public core_detail::closure::closed {};
124 template <typename Box>
125 struct closure<box_tag, Box> : public core_detail::closure::closed {};
127 template <typename Box>
128 struct closure<segment_tag, Box> : public core_detail::closure::closed {};
130 template <typename LineString>
131 struct closure<linestring_tag, LineString>
132 : public core_detail::closure::closed {};
135 template <typename Ring>
136 struct closure<ring_tag, Ring>
138 static const closure_selector value
139 = geometry::traits::closure<Ring>::value;
142 // Specialization for polygon: the closure is the closure of its rings
143 template <typename Polygon>
144 struct closure<polygon_tag, Polygon>
146 static const closure_selector value = core_dispatch::closure
149 typename ring_type<polygon_tag, Polygon>::type
154 } // namespace core_dispatch
155 #endif // DOXYGEN_NO_DISPATCH
159 \brief \brief_meta{value, closure (clockwise\, counterclockwise),
161 \tparam Geometry \tparam_geometry
164 \qbk{[include reference/core/closure.qbk]}
166 template <typename Geometry>
169 static const closure_selector value = core_dispatch::closure
171 typename tag<Geometry>::type,
172 typename boost::remove_const<Geometry>::type
177 }} // namespace boost::geometry
180 #endif // BOOST_GEOMETRY_CORE_CLOSURE_HPP