Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:50:23

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
0007 
0008 // This file was modified by Oracle on 2013-2022.
0009 // Modifications copyright (c) 2013-2022, Oracle and/or its affiliates.
0010 
0011 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0012 
0013 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0014 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0015 
0016 // Use, modification and distribution is subject to the Boost Software License,
0017 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0018 // http://www.boost.org/LICENSE_1_0.txt)
0019 
0020 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP
0021 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP
0022 
0023 
0024 #include <deque>
0025 
0026 #include <boost/geometry/core/reverse_dispatch.hpp>
0027 #include <boost/geometry/core/tag.hpp>
0028 #include <boost/geometry/core/tag_cast.hpp>
0029 #include <boost/geometry/core/tags.hpp>
0030 #include <boost/geometry/core/visit.hpp>
0031 
0032 #include <boost/geometry/geometries/adapted/boost_variant.hpp>
0033 #include <boost/geometry/geometries/concepts/check.hpp>
0034 
0035 #include <boost/geometry/strategies/default_strategy.hpp>
0036 #include <boost/geometry/strategies/detail.hpp>
0037 #include <boost/geometry/strategies/relate/services.hpp>
0038 
0039 
0040 namespace boost { namespace geometry
0041 {
0042 
0043 #ifndef DOXYGEN_NO_DISPATCH
0044 namespace dispatch {
0045 
0046 // TODO: Since CastedTags are used is Reverse needed?
0047 
0048 template
0049 <
0050     typename Geometry1,
0051     typename Geometry2,
0052     typename Tag1 = tag_t<Geometry1>,
0053     typename Tag2 = tag_t<Geometry2>,
0054     typename CastedTag1 = tag_cast_t<Tag1, pointlike_tag, linear_tag, areal_tag>,
0055     typename CastedTag2 = tag_cast_t<Tag2, pointlike_tag, linear_tag, areal_tag>,
0056     bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
0057 >
0058 struct touches
0059     : not_implemented<Tag1, Tag2>
0060 {};
0061 
0062 // If reversal is needed, perform it
0063 template
0064 <
0065     typename Geometry1, typename Geometry2,
0066     typename Tag1, typename Tag2,
0067     typename CastedTag1, typename CastedTag2
0068 >
0069 struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
0070     : touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false>
0071 {
0072     template <typename Strategy>
0073     static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
0074     {
0075         return touches<Geometry2, Geometry1>::apply(g2, g1, strategy);
0076     }
0077 };
0078 
0079 } // namespace dispatch
0080 #endif // DOXYGEN_NO_DISPATCH
0081 
0082 
0083 namespace resolve_strategy
0084 {
0085 
0086 template
0087 <
0088     typename Strategy,
0089     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0090 >
0091 struct touches
0092 {
0093     template <typename Geometry1, typename Geometry2>
0094     static inline bool apply(Geometry1 const& geometry1,
0095                              Geometry2 const& geometry2,
0096                              Strategy const& strategy)
0097     {
0098         return dispatch::touches
0099             <
0100                 Geometry1, Geometry2
0101             >::apply(geometry1, geometry2, strategy);
0102     }
0103 };
0104 
0105 template <typename Strategy>
0106 struct touches<Strategy, false>
0107 {
0108     template <typename Geometry1, typename Geometry2>
0109     static inline bool apply(Geometry1 const& geometry1,
0110                              Geometry2 const& geometry2,
0111                              Strategy const& strategy)
0112     {
0113         using strategies::relate::services::strategy_converter;
0114 
0115         return dispatch::touches
0116             <
0117                 Geometry1, Geometry2
0118             >::apply(geometry1, geometry2,
0119                      strategy_converter<Strategy>::get(strategy));
0120     }
0121 };
0122 
0123 template <>
0124 struct touches<default_strategy, false>
0125 {
0126     template <typename Geometry1, typename Geometry2>
0127     static inline bool apply(Geometry1 const& geometry1,
0128                              Geometry2 const& geometry2,
0129                              default_strategy)
0130     {
0131         typedef typename strategies::relate::services::default_strategy
0132             <
0133                 Geometry1,
0134                 Geometry2
0135             >::type strategy_type;
0136 
0137         return dispatch::touches
0138             <
0139                 Geometry1, Geometry2
0140             >::apply(geometry1, geometry2, strategy_type());
0141     }
0142 };
0143 
0144 } // namespace resolve_strategy
0145 
0146 
0147 namespace resolve_dynamic {
0148 
0149 template
0150 <
0151     typename Geometry1, typename Geometry2,
0152     typename Tag1 = geometry::tag_t<Geometry1>,
0153     typename Tag2 = geometry::tag_t<Geometry2>
0154 >
0155 struct touches
0156 {
0157     template <typename Strategy>
0158     static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0159                       Strategy const& strategy)
0160     {
0161         concepts::check<Geometry1 const>();
0162         concepts::check<Geometry2 const>();
0163 
0164         return resolve_strategy::touches
0165                 <
0166                     Strategy
0167                 >::apply(geometry1, geometry2, strategy);
0168     }
0169 };
0170 
0171 template <typename Geometry1, typename Geometry2, typename Tag2>
0172 struct touches<Geometry1, Geometry2, dynamic_geometry_tag, Tag2>
0173 {
0174     template <typename Strategy>
0175     static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0176                       Strategy const& strategy)
0177     {
0178         bool result = false;
0179         traits::visit<Geometry1>::apply([&](auto const& g1)
0180         {
0181             result = touches
0182                 <
0183                     util::remove_cref_t<decltype(g1)>,
0184                     Geometry2
0185                 >::apply(g1, geometry2, strategy);
0186         }, geometry1);
0187         return result;
0188     }
0189 };
0190 
0191 template <typename Geometry1, typename Geometry2, typename Tag1>
0192 struct touches<Geometry1, Geometry2, Tag1, dynamic_geometry_tag>
0193 {
0194     template <typename Strategy>
0195     static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0196                       Strategy const& strategy)
0197     {
0198         bool result = false;
0199         traits::visit<Geometry2>::apply([&](auto const& g2)
0200         {
0201             result = touches
0202                 <
0203                     Geometry1,
0204                     util::remove_cref_t<decltype(g2)>
0205                 >::apply(geometry1, g2, strategy);
0206         }, geometry2);
0207         return result;
0208     }
0209 };
0210 
0211 template <typename Geometry1, typename Geometry2>
0212 struct touches<Geometry1, Geometry2, dynamic_geometry_tag, dynamic_geometry_tag>
0213 {
0214     template <typename Strategy>
0215     static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0216                       Strategy const& strategy)
0217     {
0218         bool result = false;
0219         traits::visit<Geometry1, Geometry2>::apply([&](auto const& g1, auto const& g2)
0220         {
0221             result = touches
0222                 <
0223                     util::remove_cref_t<decltype(g1)>,
0224                     util::remove_cref_t<decltype(g2)>
0225                 >::apply(g1, g2, strategy);
0226         }, geometry1, geometry2);
0227         return result;
0228     }
0229 };
0230 
0231 template <typename Geometry, typename Tag = geometry::tag_t<Geometry>>
0232 struct self_touches;
0233 
0234 template <typename Geometry>
0235 struct self_touches<Geometry, dynamic_geometry_tag>
0236 {
0237     static bool apply(Geometry const& geometry)
0238     {
0239         bool result = false;
0240         traits::visit<Geometry>::apply([&](auto const& g)
0241         {
0242             result = self_touches
0243                 <
0244                     util::remove_cref_t<decltype(g)>
0245                 >::apply(g);
0246         }, geometry);
0247         return result;
0248     }
0249 };
0250 
0251 } // namespace resolve_dynamic
0252 
0253 
0254 /*!
0255 \brief \brief_check{has at least one touching point (self-tangency)}
0256 \note This function can be called for one geometry (self-tangency) and
0257     also for two geometries (touch)
0258 \ingroup touches
0259 \tparam Geometry \tparam_geometry
0260 \param geometry \param_geometry
0261 \return \return_check{is self-touching}
0262 
0263 \qbk{distinguish,one geometry}
0264 \qbk{[def __one_parameter__]}
0265 \qbk{[include reference/algorithms/touches.qbk]}
0266 \qbk{
0267 [heading Examples]
0268 [touches_one_geometry]
0269 [touches_one_geometry_output]
0270 }
0271 */
0272 template <typename Geometry>
0273 inline bool touches(Geometry const& geometry)
0274 {
0275     return resolve_dynamic::self_touches<Geometry>::apply(geometry);
0276 }
0277 
0278 
0279 /*!
0280 \brief \brief_check2{have at least one touching point (tangent - non overlapping)}
0281 \ingroup touches
0282 \tparam Geometry1 \tparam_geometry
0283 \tparam Geometry2 \tparam_geometry
0284 \param geometry1 \param_geometry
0285 \param geometry2 \param_geometry
0286 \return \return_check2{touch each other}
0287 
0288 \qbk{distinguish,two geometries}
0289 \qbk{[include reference/algorithms/touches.qbk]}
0290 \qbk{
0291 [heading Examples]
0292 [touches_two_geometries]
0293 [touches_two_geometries_output]
0294 }
0295  */
0296 template <typename Geometry1, typename Geometry2>
0297 inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
0298 {
0299     return resolve_dynamic::touches
0300         <
0301             Geometry1, Geometry2
0302         >::apply(geometry1, geometry2, default_strategy());
0303 }
0304 
0305 /*!
0306 \brief \brief_check2{have at least one touching point (tangent - non overlapping)}
0307 \ingroup touches
0308 \tparam Geometry1 \tparam_geometry
0309 \tparam Geometry2 \tparam_geometry
0310 \tparam Strategy \tparam_strategy{Touches}
0311 \param geometry1 \param_geometry
0312 \param geometry2 \param_geometry
0313 \param strategy \param_strategy{touches}
0314 \return \return_check2{touch each other}
0315 
0316 \qbk{distinguish,with strategy}
0317 \qbk{[include reference/algorithms/touches.qbk]}
0318  */
0319 template <typename Geometry1, typename Geometry2, typename Strategy>
0320 inline bool touches(Geometry1 const& geometry1,
0321                     Geometry2 const& geometry2,
0322                     Strategy const& strategy)
0323 {
0324     return resolve_dynamic::touches
0325         <
0326             Geometry1, Geometry2
0327         >::apply(geometry1, geometry2, strategy);
0328 }
0329 
0330 
0331 }} // namespace boost::geometry
0332 
0333 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP