Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-16 08:28:57

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2024 Adam Wulkiewicz, Lodz, Poland.
0007 // 
0008 // This file was modified by Oracle on 2014-2021.
0009 // Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
0010 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0011 
0012 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0013 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0014 
0015 // Use, modification and distribution is subject to the Boost Software License,
0016 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0017 // http://www.boost.org/LICENSE_1_0.txt)
0018 
0019 #ifndef BOOST_GEOMETRY_CORE_CLOSURE_HPP
0020 #define BOOST_GEOMETRY_CORE_CLOSURE_HPP
0021 
0022 #include <boost/range/value_type.hpp>
0023 
0024 #include <boost/geometry/core/ring_type.hpp>
0025 #include <boost/geometry/core/static_assert.hpp>
0026 #include <boost/geometry/core/tag.hpp>
0027 #include <boost/geometry/core/tags.hpp>
0028 #include <boost/geometry/util/type_traits_std.hpp>
0029 
0030 namespace boost { namespace geometry
0031 {
0032 
0033 
0034 /*!
0035 \brief Enumerates options for defining if polygons are open or closed
0036 \ingroup enum
0037 \details The enumeration closure_selector describes options for if a polygon is
0038     open or closed. In a closed polygon the very first point (per ring) should
0039     be equal to the very last point.
0040     The specific closing property of a polygon type is defined by the closure
0041     metafunction. The closure metafunction defines a value, which is one of the
0042     values enumerated in the closure_selector
0043 
0044 \qbk{
0045 [heading See also]
0046 [link geometry.reference.core.closure The closure metafunction]
0047 }
0048 */
0049 enum closure_selector
0050 {
0051     /// Rings are open: first point and last point are different, algorithms
0052     /// close them explicitly on the fly
0053     open = 0,
0054     /// Rings are closed: first point and last point must be the same
0055     closed = 1,
0056     /// (Not yet implemented): algorithms first figure out if ring must be
0057     /// closed on the fly
0058     closure_undertermined = -1
0059 };
0060 
0061 namespace traits
0062 {
0063 
0064 /*!
0065     \brief Traits class indicating if points within a
0066         ring or (multi)polygon are closed (last point == first point),
0067         open or not known.
0068     \ingroup traits
0069     \par Geometries:
0070         - ring
0071     \tparam G geometry
0072 */
0073 template <typename G>
0074 struct closure
0075 {
0076     static const closure_selector value = closed;
0077 };
0078 
0079 
0080 } // namespace traits
0081 
0082 
0083 #ifndef DOXYGEN_NO_DETAIL
0084 namespace core_detail { namespace closure
0085 {
0086 
0087 struct closed
0088 {
0089     static const closure_selector value = geometry::closed;
0090 };
0091 
0092 
0093 /// Metafunction to define the minimum size of a ring:
0094 /// 3 for open rings, 4 for closed rings
0095 template <closure_selector Closure>
0096 struct minimum_ring_size {};
0097 
0098 template <>
0099 struct minimum_ring_size<geometry::closed>
0100     : std::integral_constant<std::size_t, 4>
0101 {};
0102 
0103 template <>
0104 struct minimum_ring_size<geometry::open>
0105     : std::integral_constant<std::size_t, 3>
0106 {};
0107 
0108 
0109 }} // namespace core_detail::closure
0110 #endif // DOXYGEN_NO_DETAIL
0111 
0112 
0113 
0114 #ifndef DOXYGEN_NO_DISPATCH
0115 namespace core_dispatch
0116 {
0117 
0118 template <typename Tag, typename Geometry>
0119 struct closure
0120 {
0121     BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0122         "Not implemented for this Geometry type.",
0123         Geometry);
0124 };
0125 
0126 template <typename Box>
0127 struct closure<point_tag, Box> : public core_detail::closure::closed {};
0128 
0129 template <typename Box>
0130 struct closure<box_tag, Box> : public core_detail::closure::closed {};
0131 
0132 template <typename Box>
0133 struct closure<segment_tag, Box> : public core_detail::closure::closed {};
0134 
0135 template <typename LineString>
0136 struct closure<linestring_tag, LineString>
0137     : public core_detail::closure::closed {};
0138 
0139 
0140 template <typename Ring>
0141 struct closure<ring_tag, Ring>
0142 {
0143     static const closure_selector value
0144         = geometry::traits::closure<Ring>::value;
0145 };
0146 
0147 // Specialization for Polygon: the closure is the closure of its rings
0148 template <typename Polygon>
0149 struct closure<polygon_tag, Polygon>
0150 {
0151     static const closure_selector value = core_dispatch::closure
0152         <
0153             ring_tag,
0154             typename ring_type<polygon_tag, Polygon>::type
0155         >::value ;
0156 };
0157 
0158 template <typename MultiPoint>
0159 struct closure<multi_point_tag, MultiPoint>
0160     : public core_detail::closure::closed {};
0161 
0162 template <typename MultiLinestring>
0163 struct closure<multi_linestring_tag, MultiLinestring>
0164     : public core_detail::closure::closed {};
0165 
0166 // Specialization for MultiPolygon: the closure is the closure of Polygon's rings
0167 template <typename MultiPolygon>
0168 struct closure<multi_polygon_tag, MultiPolygon>
0169 {
0170     static const closure_selector value = core_dispatch::closure
0171         <
0172             polygon_tag,
0173             typename boost::range_value<MultiPolygon>::type
0174         >::value ;
0175 };
0176 
0177 } // namespace core_dispatch
0178 #endif // DOXYGEN_NO_DISPATCH
0179 
0180 
0181 /*!
0182 \brief \brief_meta{value, closure (clockwise\, counterclockwise),
0183     \meta_geometry_type}
0184 \tparam Geometry \tparam_geometry
0185 \ingroup core
0186 
0187 \qbk{[include reference/core/closure.qbk]}
0188 */
0189 template <typename Geometry>
0190 struct closure
0191     : std::integral_constant
0192         <
0193             closure_selector,
0194             core_dispatch::closure
0195                 <
0196                     tag_t<Geometry>,
0197                     util::remove_cptrref_t<Geometry>
0198                 >::value
0199         >
0200 {};
0201 
0202 #ifndef BOOST_NO_CXX17_INLINE_VARIABLES
0203 template <typename Geometry>
0204 inline constexpr closure_selector closure_v = closure<Geometry>::value;
0205 #endif
0206 
0207 
0208 #ifndef DOXYGEN_NO_DETAIL
0209 namespace detail
0210 {
0211 
0212 template <typename Geometry>
0213 using minimum_ring_size = core_detail::closure::minimum_ring_size
0214                             <
0215                                 geometry::closure<Geometry>::value
0216                             >;
0217 
0218 
0219 } // namespace detail
0220 #endif // DOXYGEN_NO_DETAIL
0221 
0222 
0223 }} // namespace boost::geometry
0224 
0225 
0226 #endif // BOOST_GEOMETRY_CORE_CLOSURE_HPP