geometry_to_range.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2014, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  4. // Licensed under the Boost Software License version 1.0.
  5. // http://www.boost.org/users/license.html
  6. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
  7. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
  8. #include <iterator>
  9. #include <boost/geometry/core/assert.hpp>
  10. #include <boost/geometry/core/point_type.hpp>
  11. #include <boost/geometry/strategies/distance.hpp>
  12. #include <boost/geometry/util/math.hpp>
  13. #include <boost/geometry/algorithms/dispatch/distance.hpp>
  14. namespace boost { namespace geometry
  15. {
  16. #ifndef DOXYGEN_NO_DETAIL
  17. namespace detail { namespace closest_feature
  18. {
  19. // returns the range iterator the realizes the closest
  20. // distance between the geometry and the element of the range
  21. class geometry_to_range
  22. {
  23. private:
  24. template
  25. <
  26. typename Geometry,
  27. typename RangeIterator,
  28. typename Strategy,
  29. typename Distance
  30. >
  31. static inline void apply(Geometry const& geometry,
  32. RangeIterator first,
  33. RangeIterator last,
  34. Strategy const& strategy,
  35. RangeIterator& it_min,
  36. Distance& dist_min)
  37. {
  38. BOOST_GEOMETRY_ASSERT( first != last );
  39. Distance const zero = Distance(0);
  40. // start with first distance
  41. it_min = first;
  42. dist_min = dispatch::distance
  43. <
  44. Geometry,
  45. typename std::iterator_traits<RangeIterator>::value_type,
  46. Strategy
  47. >::apply(geometry, *it_min, strategy);
  48. // check if other elements in the range are closer
  49. for (RangeIterator it = ++first; it != last; ++it)
  50. {
  51. Distance dist = dispatch::distance
  52. <
  53. Geometry,
  54. typename std::iterator_traits<RangeIterator>::value_type,
  55. Strategy
  56. >::apply(geometry, *it, strategy);
  57. if (geometry::math::equals(dist, zero))
  58. {
  59. dist_min = dist;
  60. it_min = it;
  61. return;
  62. }
  63. else if (dist < dist_min)
  64. {
  65. dist_min = dist;
  66. it_min = it;
  67. }
  68. }
  69. }
  70. public:
  71. template
  72. <
  73. typename Geometry,
  74. typename RangeIterator,
  75. typename Strategy,
  76. typename Distance
  77. >
  78. static inline RangeIterator apply(Geometry const& geometry,
  79. RangeIterator first,
  80. RangeIterator last,
  81. Strategy const& strategy,
  82. Distance& dist_min)
  83. {
  84. RangeIterator it_min;
  85. apply(geometry, first, last, strategy, it_min, dist_min);
  86. return it_min;
  87. }
  88. template
  89. <
  90. typename Geometry,
  91. typename RangeIterator,
  92. typename Strategy
  93. >
  94. static inline RangeIterator apply(Geometry const& geometry,
  95. RangeIterator first,
  96. RangeIterator last,
  97. Strategy const& strategy)
  98. {
  99. typename strategy::distance::services::return_type
  100. <
  101. Strategy,
  102. typename point_type<Geometry>::type,
  103. typename point_type
  104. <
  105. typename std::iterator_traits
  106. <
  107. RangeIterator
  108. >::value_type
  109. >::type
  110. >::type dist_min;
  111. return apply(geometry, first, last, strategy, dist_min);
  112. }
  113. };
  114. }} // namespace detail::closest_feature
  115. #endif // DOXYGEN_NO_DETAIL
  116. }} // namespace boost::geometry
  117. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP