1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
6 // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
7 // Copyright (c) 2014 Samuel Debionne, Grenoble, France.
9 // This file was modified by Oracle on 2014.
10 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
17 // Use, modification and distribution is subject to the Boost Software License,
18 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
19 // http://www.boost.org/LICENSE_1_0.txt)
21 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP
22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP
24 #include <boost/concept_check.hpp>
26 #include <boost/mpl/always.hpp>
27 #include <boost/mpl/bool.hpp>
28 #include <boost/mpl/vector.hpp>
30 #include <boost/geometry/core/point_type.hpp>
32 #include <boost/geometry/geometries/concepts/check.hpp>
34 #include <boost/geometry/strategies/default_strategy.hpp>
35 #include <boost/geometry/strategies/distance.hpp>
36 #include <boost/geometry/strategies/default_distance_result.hpp>
37 #include <boost/geometry/strategies/distance_result.hpp>
39 #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
40 #include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
42 #include <boost/geometry/algorithms/dispatch/distance.hpp>
45 namespace boost { namespace geometry
49 #ifndef DOXYGEN_NO_DISPATCH
54 // If reversal is needed, perform it
57 typename Geometry1, typename Geometry2, typename Strategy,
58 typename Tag1, typename Tag2, typename StrategyTag
62 Geometry1, Geometry2, Strategy,
63 Tag1, Tag2, StrategyTag,
66 : distance<Geometry2, Geometry1, Strategy, Tag2, Tag1, StrategyTag, false>
68 typedef typename strategy::distance::services::return_type
71 typename point_type<Geometry2>::type,
72 typename point_type<Geometry1>::type
75 static inline return_type apply(
78 Strategy const& strategy)
82 Geometry2, Geometry1, Strategy,
83 Tag2, Tag1, StrategyTag,
85 >::apply(g2, g1, strategy);
90 } // namespace dispatch
91 #endif // DOXYGEN_NO_DISPATCH
94 namespace resolve_strategy
99 template <typename Geometry1, typename Geometry2, typename Strategy>
100 static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
101 apply(Geometry1 const& geometry1,
102 Geometry2 const& geometry2,
103 Strategy const& strategy)
105 return dispatch::distance
107 Geometry1, Geometry2, Strategy
108 >::apply(geometry1, geometry2, strategy);
111 template <typename Geometry1, typename Geometry2>
113 typename distance_result<Geometry1, Geometry2, default_strategy>::type
114 apply(Geometry1 const& geometry1,
115 Geometry2 const& geometry2,
118 typedef typename detail::distance::default_strategy
121 >::type strategy_type;
123 return dispatch::distance
125 Geometry1, Geometry2, strategy_type
126 >::apply(geometry1, geometry2, strategy_type());
130 } // namespace resolve_strategy
133 namespace resolve_variant
137 template <typename Geometry1, typename Geometry2>
140 template <typename Strategy>
141 static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
142 apply(Geometry1 const& geometry1,
143 Geometry2 const& geometry2,
144 Strategy const& strategy)
147 resolve_strategy::distance::apply(geometry1, geometry2, strategy);
152 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
153 struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
155 template <typename Strategy>
156 struct visitor: static_visitor
158 typename distance_result
160 variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
166 Geometry2 const& m_geometry2;
167 Strategy const& m_strategy;
169 visitor(Geometry2 const& geometry2,
170 Strategy const& strategy)
171 : m_geometry2(geometry2),
175 template <typename Geometry1>
176 typename distance_result<Geometry1, Geometry2, Strategy>::type
177 operator()(Geometry1 const& geometry1) const
186 >(geometry1, m_geometry2, m_strategy);
190 template <typename Strategy>
191 static inline typename distance_result
193 variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
197 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
198 Geometry2 const& geometry2,
199 Strategy const& strategy)
201 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
206 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
207 struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
209 template <typename Strategy>
210 struct visitor: static_visitor
212 typename distance_result
215 variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
220 Geometry1 const& m_geometry1;
221 Strategy const& m_strategy;
223 visitor(Geometry1 const& geometry1,
224 Strategy const& strategy)
225 : m_geometry1(geometry1),
229 template <typename Geometry2>
230 typename distance_result<Geometry1, Geometry2, Strategy>::type
231 operator()(Geometry2 const& geometry2) const
240 >(m_geometry1, geometry2, m_strategy);
244 template <typename Strategy>
245 static inline typename distance_result
248 variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
252 Geometry1 const& geometry1,
253 const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
254 Strategy const& strategy)
256 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
263 BOOST_VARIANT_ENUM_PARAMS(typename T1),
264 BOOST_VARIANT_ENUM_PARAMS(typename T2)
268 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
269 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
272 template <typename Strategy>
273 struct visitor: static_visitor
275 typename distance_result
277 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
278 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
283 Strategy const& m_strategy;
285 visitor(Strategy const& strategy)
286 : m_strategy(strategy)
289 template <typename Geometry1, typename Geometry2>
290 typename distance_result<Geometry1, Geometry2, Strategy>::type
291 operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const
300 >(geometry1, geometry2, m_strategy);
304 template <typename Strategy>
305 static inline typename distance_result
307 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
308 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
311 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
312 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
313 Strategy const& strategy)
315 return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
319 } // namespace resolve_variant
323 \brief \brief_calc2{distance} \brief_strategy
326 \details \details_calc{area}. \brief_strategy. \details_strategy_reasons
328 \tparam Geometry1 \tparam_geometry
329 \tparam Geometry2 \tparam_geometry
330 \tparam Strategy \tparam_strategy{Distance}
331 \param geometry1 \param_geometry
332 \param geometry2 \param_geometry
333 \param strategy \param_strategy{distance}
334 \return \return_calc{distance}
335 \note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
336 it may also be a point-segment strategy.
338 \qbk{distinguish,with strategy}
341 [heading Available Strategies]
342 \* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)]
343 \* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)]
344 \* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)]
345 \* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)]
346 \* more (currently extensions): Vincenty\, Andoyer (geographic)
351 Note, in case of a Compilation Error:
353 - "Failed to specialize function template ..."
354 - "error: no matching function for call to ..."
355 for distance, it is probably so that there is no specialization
356 for return_type<...> for your strategy.
358 template <typename Geometry1, typename Geometry2, typename Strategy>
359 inline typename distance_result<Geometry1, Geometry2, Strategy>::type
360 distance(Geometry1 const& geometry1,
361 Geometry2 const& geometry2,
362 Strategy const& strategy)
364 concepts::check<Geometry1 const>();
365 concepts::check<Geometry2 const>();
367 detail::throw_on_empty_input(geometry1);
368 detail::throw_on_empty_input(geometry2);
370 return resolve_variant::distance
374 >::apply(geometry1, geometry2, strategy);
379 \brief \brief_calc2{distance}
381 \details The default strategy is used, corresponding to the coordinate system of the geometries
382 \tparam Geometry1 \tparam_geometry
383 \tparam Geometry2 \tparam_geometry
384 \param geometry1 \param_geometry
385 \param geometry2 \param_geometry
386 \return \return_calc{distance}
388 \qbk{[include reference/algorithms/distance.qbk]}
390 template <typename Geometry1, typename Geometry2>
391 inline typename default_distance_result<Geometry1, Geometry2>::type
392 distance(Geometry1 const& geometry1,
393 Geometry2 const& geometry2)
395 concepts::check<Geometry1 const>();
396 concepts::check<Geometry2 const>();
398 return geometry::distance(geometry1, geometry2, default_strategy());
401 }} // namespace boost::geometry
403 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP