distance.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP
  11. #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP
  12. #include <boost/numeric/conversion/bounds.hpp>
  13. #include <boost/range.hpp>
  14. #include <boost/geometry/multi/core/tags.hpp>
  15. #include <boost/geometry/multi/core/geometry_id.hpp>
  16. #include <boost/geometry/multi/core/point_type.hpp>
  17. #include <boost/geometry/multi/geometries/concepts/check.hpp>
  18. #include <boost/geometry/algorithms/distance.hpp>
  19. #include <boost/geometry/multi/algorithms/num_points.hpp>
  20. #include <boost/geometry/util/select_coordinate_type.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. #ifndef DOXYGEN_NO_DETAIL
  24. namespace detail { namespace distance
  25. {
  26. template<typename Geometry, typename MultiGeometry, typename Strategy>
  27. struct distance_single_to_multi
  28. : private dispatch::distance
  29. <
  30. Geometry,
  31. typename range_value<MultiGeometry>::type,
  32. Strategy
  33. >
  34. {
  35. typedef typename strategy::distance::services::return_type
  36. <
  37. Strategy,
  38. typename point_type<Geometry>::type,
  39. typename point_type<MultiGeometry>::type
  40. >::type return_type;
  41. static inline return_type apply(Geometry const& geometry,
  42. MultiGeometry const& multi,
  43. Strategy const& strategy)
  44. {
  45. return_type mindist = return_type();
  46. bool first = true;
  47. for(typename range_iterator<MultiGeometry const>::type it = boost::begin(multi);
  48. it != boost::end(multi);
  49. ++it, first = false)
  50. {
  51. return_type dist = dispatch::distance
  52. <
  53. Geometry,
  54. typename range_value<MultiGeometry>::type,
  55. Strategy
  56. >::apply(geometry, *it, strategy);
  57. if (first || dist < mindist)
  58. {
  59. mindist = dist;
  60. }
  61. }
  62. return mindist;
  63. }
  64. };
  65. template<typename Multi1, typename Multi2, typename Strategy>
  66. struct distance_multi_to_multi
  67. : private distance_single_to_multi
  68. <
  69. typename range_value<Multi1>::type,
  70. Multi2,
  71. Strategy
  72. >
  73. {
  74. typedef typename strategy::distance::services::return_type
  75. <
  76. Strategy,
  77. typename point_type<Multi1>::type,
  78. typename point_type<Multi2>::type
  79. >::type return_type;
  80. static inline return_type apply(Multi1 const& multi1,
  81. Multi2 const& multi2, Strategy const& strategy)
  82. {
  83. return_type mindist = return_type();
  84. bool first = true;
  85. for(typename range_iterator<Multi1 const>::type it = boost::begin(multi1);
  86. it != boost::end(multi1);
  87. ++it, first = false)
  88. {
  89. return_type dist = distance_single_to_multi
  90. <
  91. typename range_value<Multi1>::type,
  92. Multi2,
  93. Strategy
  94. >::apply(*it, multi2, strategy);
  95. if (first || dist < mindist)
  96. {
  97. mindist = dist;
  98. }
  99. }
  100. return mindist;
  101. }
  102. };
  103. }} // namespace detail::distance
  104. #endif
  105. #ifndef DOXYGEN_NO_DISPATCH
  106. namespace dispatch
  107. {
  108. template
  109. <
  110. typename G1,
  111. typename G2,
  112. typename Strategy,
  113. typename SingleGeometryTag
  114. >
  115. struct distance
  116. <
  117. G1, G2, Strategy,
  118. SingleGeometryTag, multi_tag, strategy_tag_distance_point_point,
  119. false
  120. >
  121. : detail::distance::distance_single_to_multi<G1, G2, Strategy>
  122. {};
  123. template <typename G1, typename G2, typename Strategy>
  124. struct distance
  125. <
  126. G1, G2, Strategy,
  127. multi_tag, multi_tag, strategy_tag_distance_point_point,
  128. false
  129. >
  130. : detail::distance::distance_multi_to_multi<G1, G2, Strategy>
  131. {};
  132. } // namespace dispatch
  133. #endif
  134. }} // namespace boost::geometry
  135. #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP