Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2023 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 
0011 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0012 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0013 
0014 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0015 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0016 
0017 // Use, modification and distribution is subject to the Boost Software License,
0018 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0019 // http://www.boost.org/LICENSE_1_0.txt)
0020 
0021 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
0022 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
0023 
0024 
0025 #include <boost/geometry/algorithms/detail/distance/interface.hpp>
0026 
0027 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0028 #include <boost/geometry/geometries/concepts/check.hpp>
0029 
0030 #include <boost/geometry/strategies/comparable_distance_result.hpp>
0031 #include <boost/geometry/strategies/default_comparable_distance_result.hpp>
0032 #include <boost/geometry/strategies/distance.hpp>
0033 
0034 #include <boost/geometry/strategies/distance/comparable.hpp>
0035 #include <boost/geometry/strategies/distance/services.hpp>
0036 
0037 
0038 namespace boost { namespace geometry
0039 {
0040 
0041 
0042 namespace resolve_strategy
0043 {
0044 
0045 
0046 template
0047 <
0048     typename Strategies,
0049     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategies>::value
0050 >
0051 struct comparable_distance
0052 {
0053     template <typename Geometry1, typename Geometry2>
0054     static inline auto apply(Geometry1 const& geometry1,
0055                              Geometry2 const& geometry2,
0056                              Strategies const& strategies)
0057     {
0058         return dispatch::distance
0059             <
0060                 Geometry1, Geometry2,
0061                 strategies::distance::detail::comparable<Strategies>
0062             >::apply(geometry1,
0063                      geometry2,
0064                      strategies::distance::detail::comparable<Strategies>(strategies));
0065     }
0066 };
0067 
0068 template <typename Strategy>
0069 struct comparable_distance<Strategy, false>
0070 {
0071     template <typename Geometry1, typename Geometry2>
0072     static inline auto apply(Geometry1 const& geometry1,
0073                              Geometry2 const& geometry2,
0074                              Strategy const& strategy)
0075     {
0076         using strategies::distance::services::strategy_converter;
0077 
0078         using comparable_strategies_type = strategies::distance::detail::comparable
0079             <
0080                 decltype(strategy_converter<Strategy>::get(strategy))
0081             >;
0082 
0083         return dispatch::distance
0084             <
0085                 Geometry1, Geometry2,
0086                 comparable_strategies_type
0087             >::apply(geometry1,
0088                      geometry2,
0089                      comparable_strategies_type(
0090                          strategy_converter<Strategy>::get(strategy)));
0091     }
0092 };
0093 
0094 template <>
0095 struct comparable_distance<default_strategy, false>
0096 {
0097     template <typename Geometry1, typename Geometry2>
0098     static inline auto apply(Geometry1 const& geometry1,
0099                              Geometry2 const& geometry2,
0100                              default_strategy)
0101     {
0102         using comparable_strategy_type = strategies::distance::detail::comparable
0103             <
0104                 typename strategies::distance::services::default_strategy
0105                     <
0106                         Geometry1, Geometry2
0107                     >::type
0108             >;
0109 
0110         return dispatch::distance
0111             <
0112                 Geometry1, Geometry2, comparable_strategy_type
0113             >::apply(geometry1, geometry2, comparable_strategy_type());
0114     }
0115 };
0116 
0117 } // namespace resolve_strategy
0118 
0119 
0120 namespace resolve_dynamic
0121 {
0122 
0123 
0124 template
0125 <
0126     typename Geometry1, typename Geometry2,
0127     typename Tag1 = typename geometry::tag<Geometry1>::type,
0128     typename Tag2 = typename geometry::tag<Geometry2>::type
0129 >
0130 struct comparable_distance
0131 {
0132     template <typename Strategy>
0133     static inline auto apply(Geometry1 const& geometry1,
0134                              Geometry2 const& geometry2,
0135                              Strategy const& strategy)
0136     {
0137         return resolve_strategy::comparable_distance
0138             <
0139                 Strategy
0140             >::apply(geometry1, geometry2, strategy);
0141     }
0142 };
0143 
0144 
0145 template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
0146 struct comparable_distance<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
0147 {
0148     template <typename Strategy>
0149     static inline auto apply(DynamicGeometry1 const& geometry1,
0150                              Geometry2 const& geometry2,
0151                              Strategy const& strategy)
0152     {
0153         using result_t = typename geometry::comparable_distance_result
0154             <
0155                 DynamicGeometry1, Geometry2, Strategy
0156             >::type;
0157         result_t result = 0;
0158         traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
0159         {
0160             result = resolve_strategy::comparable_distance
0161                         <
0162                             Strategy
0163                         >::apply(g1, geometry2, strategy);
0164         }, geometry1);
0165         return result;
0166     }
0167 };
0168 
0169 
0170 template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
0171 struct comparable_distance<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
0172 {
0173     template <typename Strategy>
0174     static inline auto apply(Geometry1 const& geometry1,
0175                              DynamicGeometry2 const& geometry2,
0176                              Strategy const& strategy)
0177     {
0178         using result_t = typename geometry::comparable_distance_result
0179             <
0180                 Geometry1, DynamicGeometry2, Strategy
0181             >::type;
0182         result_t result = 0;
0183         traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
0184         {
0185             result = resolve_strategy::comparable_distance
0186                         <
0187                             Strategy
0188                         >::apply(geometry1, g2, strategy);
0189         }, geometry2);
0190         return result;
0191     }
0192 };
0193 
0194 
0195 template <typename DynamicGeometry1, typename DynamicGeometry2>
0196 struct comparable_distance
0197     <
0198         DynamicGeometry1, DynamicGeometry2,
0199         dynamic_geometry_tag, dynamic_geometry_tag
0200     >
0201 {
0202     template <typename Strategy>
0203     static inline auto apply(DynamicGeometry1 const& geometry1,
0204                              DynamicGeometry2 const& geometry2,
0205                              Strategy const& strategy)
0206     {
0207         using result_t = typename geometry::comparable_distance_result
0208             <
0209                 DynamicGeometry1, DynamicGeometry2, Strategy
0210             >::type;
0211         result_t result = 0;
0212         traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
0213         {
0214             result = resolve_strategy::comparable_distance
0215                         <
0216                             Strategy
0217                         >::apply(g1, g2, strategy);
0218         }, geometry1, geometry2);
0219         return result;
0220     }
0221 };
0222 
0223 } // namespace resolve_dynamic
0224 
0225 
0226 
0227 /*!
0228 \brief \brief_calc2{comparable distance measurement} \brief_strategy
0229 \ingroup distance
0230 \details The free function comparable_distance does not necessarily calculate the distance,
0231     but it calculates a distance measure such that two distances are comparable to each other.
0232     For example: for the Cartesian coordinate system, Pythagoras is used but the square root
0233     is not taken, which makes it faster and the results of two point pairs can still be
0234     compared to each other.
0235 \tparam Geometry1 first geometry type
0236 \tparam Geometry2 second geometry type
0237 \tparam Strategy \tparam_strategy{Distance}
0238 \param geometry1 \param_geometry
0239 \param geometry2 \param_geometry
0240 \param strategy \param_strategy{distance}
0241 \return \return_calc{comparable distance}
0242 
0243 \qbk{distinguish,with strategy}
0244  */
0245 template <typename Geometry1, typename Geometry2, typename Strategy>
0246 inline auto comparable_distance(Geometry1 const& geometry1,
0247                                 Geometry2 const& geometry2,
0248                                 Strategy const& strategy)
0249 {
0250     concepts::check<Geometry1 const>();
0251     concepts::check<Geometry2 const>();
0252 
0253     return resolve_dynamic::comparable_distance
0254         <
0255             Geometry1,
0256             Geometry2
0257         >::apply(geometry1, geometry2, strategy);
0258 }
0259 
0260 
0261 
0262 /*!
0263 \brief \brief_calc2{comparable distance measurement}
0264 \ingroup distance
0265 \details The free function comparable_distance does not necessarily calculate the distance,
0266     but it calculates a distance measure such that two distances are comparable to each other.
0267     For example: for the Cartesian coordinate system, Pythagoras is used but the square root
0268     is not taken, which makes it faster and the results of two point pairs can still be
0269     compared to each other.
0270 \tparam Geometry1 first geometry type
0271 \tparam Geometry2 second geometry type
0272 \param geometry1 \param_geometry
0273 \param geometry2 \param_geometry
0274 \return \return_calc{comparable distance}
0275 
0276 \qbk{[include reference/algorithms/comparable_distance.qbk]}
0277  */
0278 template <typename Geometry1, typename Geometry2>
0279 inline auto comparable_distance(Geometry1 const& geometry1,
0280                                 Geometry2 const& geometry2)
0281 {
0282     return geometry::comparable_distance(geometry1, geometry2, default_strategy());
0283 }
0284 
0285 
0286 }} // namespace boost::geometry
0287 
0288 
0289 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP