Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:20

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2017 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2020-2023.
0006 // Modifications copyright (c) 2020-2023 Oracle and/or its affiliates.
0007 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0008 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0009 
0010 // Use, modification and distribution is subject to the Boost Software License,
0011 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0012 // http://www.boost.org/LICENSE_1_0.txt)
0013 
0014 #ifndef BOOST_GEOMETRY_ALGORITHMS_CORRECT_CLOSURE_HPP
0015 #define BOOST_GEOMETRY_ALGORITHMS_CORRECT_CLOSURE_HPP
0016 
0017 #include <boost/geometry/algorithms/detail/multi_modify.hpp>
0018 #include <boost/geometry/algorithms/disjoint.hpp>
0019 
0020 #include <boost/geometry/core/closure.hpp>
0021 #include <boost/geometry/core/exterior_ring.hpp>
0022 #include <boost/geometry/core/interior_rings.hpp>
0023 #include <boost/geometry/core/tags.hpp>
0024 
0025 #include <boost/geometry/geometries/adapted/boost_variant.hpp>
0026 #include <boost/geometry/geometries/concepts/check.hpp>
0027 
0028 #include <boost/geometry/util/range.hpp>
0029 #include <boost/range/size.hpp>
0030 
0031 namespace boost { namespace geometry
0032 {
0033 
0034 // Silence warning C4127: conditional expression is constant
0035 #if defined(_MSC_VER)
0036 #pragma warning(push)
0037 #pragma warning(disable : 4127)
0038 #endif
0039 
0040 #ifndef DOXYGEN_NO_DETAIL
0041 namespace detail { namespace correct_closure
0042 {
0043 
0044 struct nop
0045 {
0046     template <typename Geometry>
0047     static inline void apply(Geometry& )
0048     {}
0049 };
0050 
0051 // Close a ring, if not closed, or open it
0052 struct close_or_open_ring
0053 {
0054     template <typename Ring>
0055     static inline void apply(Ring& r)
0056     {
0057         auto size = boost::size(r);
0058         if (size <= 2)
0059         {
0060             return;
0061         }
0062 
0063         // TODO: This requires relate(pt, pt) strategy
0064         bool const disjoint = geometry::disjoint(*boost::begin(r), *(boost::end(r) - 1));
0065         closure_selector const closure = geometry::closure<Ring>::value;
0066 
0067         if (disjoint && closure == closed)
0068         {
0069             // Close it by adding first point
0070             geometry::append(r, *boost::begin(r));
0071         }
0072         else if (! disjoint && closure == open)
0073         {
0074             // Open it by removing last point
0075             range::resize(r, size - 1);
0076         }
0077     }
0078 };
0079 
0080 // Close/open exterior ring and all its interior rings
0081 struct close_or_open_polygon
0082 {
0083     template <typename Polygon>
0084     static inline void apply(Polygon& poly)
0085     {
0086         close_or_open_ring::apply(exterior_ring(poly));
0087 
0088         auto&& rings = interior_rings(poly);
0089         auto const end = boost::end(rings);
0090         for (auto it = boost::begin(rings); it != end; ++it)
0091         {
0092             close_or_open_ring::apply(*it);
0093         }
0094     }
0095 };
0096 
0097 }} // namespace detail::correct_closure
0098 #endif // DOXYGEN_NO_DETAIL
0099 
0100 
0101 #ifndef DOXYGEN_NO_DISPATCH
0102 namespace dispatch
0103 {
0104 
0105 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0106 struct correct_closure: not_implemented<Tag>
0107 {};
0108 
0109 template <typename Point>
0110 struct correct_closure<Point, point_tag>
0111     : detail::correct_closure::nop
0112 {};
0113 
0114 template <typename LineString>
0115 struct correct_closure<LineString, linestring_tag>
0116     : detail::correct_closure::nop
0117 {};
0118 
0119 template <typename Segment>
0120 struct correct_closure<Segment, segment_tag>
0121     : detail::correct_closure::nop
0122 {};
0123 
0124 
0125 template <typename Box>
0126 struct correct_closure<Box, box_tag>
0127     : detail::correct_closure::nop
0128 {};
0129 
0130 template <typename Ring>
0131 struct correct_closure<Ring, ring_tag>
0132     : detail::correct_closure::close_or_open_ring
0133 {};
0134 
0135 template <typename Polygon>
0136 struct correct_closure<Polygon, polygon_tag>
0137     : detail::correct_closure::close_or_open_polygon
0138 {};
0139 
0140 
0141 template <typename MultiPoint>
0142 struct correct_closure<MultiPoint, multi_point_tag>
0143     : detail::correct_closure::nop
0144 {};
0145 
0146 
0147 template <typename MultiLineString>
0148 struct correct_closure<MultiLineString, multi_linestring_tag>
0149     : detail::correct_closure::nop
0150 {};
0151 
0152 
0153 template <typename Geometry>
0154 struct correct_closure<Geometry, multi_polygon_tag>
0155     : detail::multi_modify
0156         <
0157             detail::correct_closure::close_or_open_polygon
0158         >
0159 {};
0160 
0161 
0162 } // namespace dispatch
0163 #endif // DOXYGEN_NO_DISPATCH
0164 
0165 
0166 namespace resolve_variant
0167 {
0168 
0169 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0170 struct correct_closure
0171 {
0172     static inline void apply(Geometry& geometry)
0173     {
0174         concepts::check<Geometry const>();
0175         dispatch::correct_closure<Geometry>::apply(geometry);
0176     }
0177 };
0178 
0179 template <typename Geometry>
0180 struct correct_closure<Geometry, dynamic_geometry_tag>
0181 {
0182     static void apply(Geometry& geometry)
0183     {
0184         traits::visit<Geometry>::apply([](auto & g)
0185         {
0186             correct_closure<util::remove_cref_t<decltype(g)>>::apply(g);
0187         }, geometry);
0188     }
0189 };
0190 
0191 template <typename Geometry>
0192 struct correct_closure<Geometry, geometry_collection_tag>
0193 {
0194     static void apply(Geometry& geometry)
0195     {
0196         detail::visit_breadth_first([](auto & g)
0197         {
0198             correct_closure<util::remove_cref_t<decltype(g)>>::apply(g);
0199             return true;
0200         }, geometry);
0201     }
0202 };
0203 
0204 } // namespace resolve_variant
0205 
0206 
0207 // TODO: This algorithm should use relate(pt, pt) strategy
0208 
0209 
0210 /*!
0211 \brief Closes or opens a geometry, according to its type
0212 \details Corrects a geometry w.r.t. closure points to all rings which do not
0213     have a closing point and are typed as they should have one, the first point
0214     is appended.
0215 \ingroup correct_closure
0216 \tparam Geometry \tparam_geometry
0217 \param geometry \param_geometry which will be corrected if necessary
0218 */
0219 template <typename Geometry>
0220 inline void correct_closure(Geometry& geometry)
0221 {
0222     resolve_variant::correct_closure<Geometry>::apply(geometry);
0223 }
0224 
0225 
0226 #if defined(_MSC_VER)
0227 #pragma warning(pop)
0228 #endif
0229 
0230 }} // namespace boost::geometry
0231 
0232 
0233 #endif // BOOST_GEOMETRY_ALGORITHMS_CORRECT_CLOSURE_HPP