File indexing completed on 2025-01-18 09:35:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
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
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
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 }
0081 #endif
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 }
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 }
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
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
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
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 }}
0352
0353 #endif