Back to home page

EIC code displayed by LXR

 
 

    


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

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) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
0007 // Copyright (c) 2014 Samuel Debionne, Grenoble, France.
0008 
0009 // This file was modified by Oracle on 2014-2021.
0010 // Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
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_DISTANCE_INTERFACE_HPP
0022 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP
0023 
0024 #include <boost/concept_check.hpp>
0025 
0026 #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
0027 #include <boost/geometry/algorithms/dispatch/distance.hpp>
0028 
0029 #include <boost/geometry/core/point_type.hpp>
0030 #include <boost/geometry/core/visit.hpp>
0031 
0032 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0033 #include <boost/geometry/geometries/concepts/check.hpp>
0034 
0035 // TODO: move these to algorithms
0036 #include <boost/geometry/strategies/default_distance_result.hpp>
0037 #include <boost/geometry/strategies/distance_result.hpp>
0038 
0039 #include <boost/geometry/strategies/default_strategy.hpp>
0040 #include <boost/geometry/strategies/detail.hpp>
0041 #include <boost/geometry/strategies/distance/services.hpp>
0042 
0043 
0044 namespace boost { namespace geometry
0045 {
0046 
0047 
0048 #ifndef DOXYGEN_NO_DISPATCH
0049 namespace dispatch
0050 {
0051 
0052 
0053 // If reversal is needed, perform it
0054 template
0055 <
0056     typename Geometry1, typename Geometry2, typename Strategy,
0057     typename Tag1, typename Tag2, typename StrategyTag
0058 >
0059 struct distance
0060 <
0061     Geometry1, Geometry2, Strategy,
0062     Tag1, Tag2, StrategyTag,
0063     true
0064 >
0065     : distance<Geometry2, Geometry1, Strategy, Tag2, Tag1, StrategyTag, false>
0066 {
0067     static inline auto apply(Geometry1 const& g1, Geometry2 const& g2,
0068                              Strategy const& strategy)
0069     {
0070         return distance
0071             <
0072                 Geometry2, Geometry1, Strategy,
0073                 Tag2, Tag1, StrategyTag,
0074                 false
0075             >::apply(g2, g1, strategy);
0076     }
0077 };
0078 
0079 
0080 } // namespace dispatch
0081 #endif // DOXYGEN_NO_DISPATCH
0082 
0083 
0084 namespace resolve_strategy
0085 {
0086 
0087 template
0088 <
0089     typename Strategy,
0090     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0091 >
0092 struct distance
0093 {
0094     template <typename Geometry1, typename Geometry2>
0095     static inline auto apply(Geometry1 const& geometry1,
0096                              Geometry2 const& geometry2,
0097                              Strategy const& strategy)
0098     {
0099         return dispatch::distance
0100             <
0101                 Geometry1, Geometry2, Strategy
0102             >::apply(geometry1, geometry2, strategy);
0103     }
0104 };
0105 
0106 template <typename Strategy>
0107 struct is_strategy_converter_specialized
0108 {
0109     typedef strategies::distance::services::strategy_converter<Strategy> converter;
0110     static const bool value = ! std::is_same
0111         <
0112             decltype(converter::get(std::declval<Strategy>())),
0113             strategies::detail::not_implemented
0114         >::value;
0115 };
0116 
0117 template <typename Strategy>
0118 struct distance<Strategy, false>
0119 {
0120     template
0121     <
0122         typename Geometry1, typename Geometry2, typename S,
0123         std::enable_if_t<is_strategy_converter_specialized<S>::value, int> = 0
0124     >
0125     static inline auto apply(Geometry1 const& geometry1,
0126                              Geometry2 const& geometry2,
0127                              S const& strategy)
0128     {
0129         typedef strategies::distance::services::strategy_converter<Strategy> converter;
0130         typedef decltype(converter::get(strategy)) strategy_type;
0131 
0132         return dispatch::distance
0133             <
0134                 Geometry1, Geometry2, strategy_type
0135             >::apply(geometry1, geometry2, converter::get(strategy));
0136     }
0137 
0138     template
0139     <
0140         typename Geometry1, typename Geometry2, typename S,
0141         std::enable_if_t<! is_strategy_converter_specialized<S>::value, int> = 0
0142     >
0143     static inline auto apply(Geometry1 const& geometry1,
0144                              Geometry2 const& geometry2,
0145                              S const& strategy)
0146     {
0147         typedef strategies::distance::services::custom_strategy_converter
0148             <
0149                 Geometry1, Geometry2, Strategy
0150             > converter;
0151         typedef decltype(converter::get(strategy)) strategy_type;
0152 
0153         return dispatch::distance
0154             <
0155                 Geometry1, Geometry2, strategy_type
0156             >::apply(geometry1, geometry2, converter::get(strategy));
0157     }
0158 };
0159 
0160 template <>
0161 struct distance<default_strategy, false>
0162 {
0163     template <typename Geometry1, typename Geometry2>
0164     static inline auto apply(Geometry1 const& geometry1,
0165                              Geometry2 const& geometry2,
0166                              default_strategy)
0167     {
0168         typedef typename strategies::distance::services::default_strategy
0169             <
0170                 Geometry1, Geometry2
0171             >::type strategy_type;
0172 
0173         return dispatch::distance
0174             <
0175                 Geometry1, Geometry2, strategy_type
0176             >::apply(geometry1, geometry2, strategy_type());
0177     }
0178 };
0179 
0180 } // namespace resolve_strategy
0181 
0182 
0183 namespace resolve_dynamic
0184 {
0185 
0186 
0187 template
0188 <
0189     typename Geometry1, typename Geometry2,
0190     typename Tag1 = typename geometry::tag<Geometry1>::type,
0191     typename Tag2 = typename geometry::tag<Geometry2>::type
0192 >
0193 struct distance
0194 {
0195     template <typename Strategy>
0196     static inline auto apply(Geometry1 const& geometry1,
0197                              Geometry2 const& geometry2,
0198                              Strategy const& strategy)
0199     {
0200         return resolve_strategy::distance
0201             <
0202                 Strategy
0203             >::apply(geometry1, geometry2, strategy);
0204     }
0205 };
0206 
0207 
0208 template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
0209 struct distance<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
0210 {
0211     template <typename Strategy>
0212     static inline auto apply(DynamicGeometry1 const& geometry1,
0213                              Geometry2 const& geometry2,
0214                              Strategy const& strategy)
0215     {
0216         using result_t = typename geometry::distance_result<DynamicGeometry1, Geometry2, Strategy>::type;
0217         result_t result = 0;
0218         traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
0219         {
0220             result = resolve_strategy::distance
0221                         <
0222                             Strategy
0223                         >::apply(g1, geometry2, strategy);
0224         }, geometry1);
0225         return result;
0226     }
0227 };
0228 
0229 
0230 template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
0231 struct distance<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
0232 {
0233     template <typename Strategy>
0234     static inline auto apply(Geometry1 const& geometry1,
0235                              DynamicGeometry2 const& geometry2,
0236                              Strategy const& strategy)
0237     {
0238         using result_t = typename geometry::distance_result<Geometry1, DynamicGeometry2, Strategy>::type;
0239         result_t result = 0;
0240         traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
0241         {
0242             result = resolve_strategy::distance
0243                         <
0244                             Strategy
0245                         >::apply(geometry1, g2, strategy);
0246         }, geometry2);
0247         return result;
0248     }
0249 };
0250 
0251 
0252 template <typename DynamicGeometry1, typename DynamicGeometry2>
0253 struct distance<DynamicGeometry1, DynamicGeometry2, dynamic_geometry_tag, dynamic_geometry_tag>
0254 {
0255     template <typename Strategy>
0256     static inline auto apply(DynamicGeometry1 const& geometry1,
0257                              DynamicGeometry2 const& geometry2,
0258                              Strategy const& strategy)
0259     {
0260         using result_t = typename geometry::distance_result<DynamicGeometry1, DynamicGeometry2, Strategy>::type;
0261         result_t result = 0;
0262         traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
0263         {
0264             result = resolve_strategy::distance
0265                         <
0266                             Strategy
0267                         >::apply(g1, g2, strategy);
0268         }, geometry1, geometry2);
0269         return result;
0270     }
0271 };
0272 
0273 } // namespace resolve_dynamic
0274 
0275 
0276 /*!
0277 \brief Calculate the distance between two geometries \brief_strategy
0278 \ingroup distance
0279 \details
0280 \details The free function distance calculates the distance between two geometries \brief_strategy. \details_strategy_reasons
0281 
0282 \tparam Geometry1 \tparam_geometry
0283 \tparam Geometry2 \tparam_geometry
0284 \tparam Strategy \tparam_strategy{Distance}
0285 \param geometry1 \param_geometry
0286 \param geometry2 \param_geometry
0287 \param strategy \param_strategy{distance}
0288 \return \return_calc{distance}
0289 \note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
0290     it may also be a point-segment strategy.
0291 
0292 \qbk{distinguish,with strategy}
0293 
0294 \qbk{
0295 [heading Available Strategies]
0296 \* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)]
0297 \* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)]
0298 \* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)]
0299 \* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)]
0300 \* more (currently extensions): Vincenty\, Andoyer (geographic)
0301 }
0302  */
0303 
0304 /*
0305 Note, in case of a Compilation Error:
0306 if you get:
0307  - "Failed to specialize function template ..."
0308  - "error: no matching function for call to ..."
0309 for distance, it is probably so that there is no specialization
0310 for return_type<...> for your strategy.
0311 */
0312 template <typename Geometry1, typename Geometry2, typename Strategy>
0313 inline auto distance(Geometry1 const& geometry1,
0314                      Geometry2 const& geometry2,
0315                      Strategy const& strategy)
0316 {
0317     concepts::check<Geometry1 const>();
0318     concepts::check<Geometry2 const>();
0319 
0320     detail::throw_on_empty_input(geometry1);
0321     detail::throw_on_empty_input(geometry2);
0322 
0323     return resolve_dynamic::distance
0324                <
0325                    Geometry1,
0326                    Geometry2
0327                >::apply(geometry1, geometry2, strategy);
0328 }
0329 
0330 
0331 /*!
0332 \brief Calculate the distance between two geometries.
0333 \ingroup distance
0334 \details The free function distance calculates the distance between two geometries. \details_default_strategy
0335 
0336 \tparam Geometry1 \tparam_geometry
0337 \tparam Geometry2 \tparam_geometry
0338 \param geometry1 \param_geometry
0339 \param geometry2 \param_geometry
0340 \return \return_calc{distance}
0341 
0342 \qbk{[include reference/algorithms/distance.qbk]}
0343  */
0344 template <typename Geometry1, typename Geometry2>
0345 inline auto distance(Geometry1 const& geometry1,
0346                      Geometry2 const& geometry2)
0347 {
0348     return geometry::distance(geometry1, geometry2, default_strategy());
0349 }
0350 
0351 }} // namespace boost::geometry
0352 
0353 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP