diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp b/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp new file mode 100644 index 0000000000..c7558b4ff1 --- /dev/null +++ b/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp @@ -0,0 +1,147 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP + +#include <iterator> + +#include <boost/assert.hpp> + +#include <boost/geometry/core/point_type.hpp> +#include <boost/geometry/strategies/distance.hpp> +#include <boost/geometry/util/math.hpp> + +#include <boost/geometry/algorithms/dispatch/distance.hpp> + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace closest_feature +{ + + + +// returns the range iterator the realizes the closest +// distance between the geometry and the element of the range +class geometry_to_range +{ +private: + template + < + typename Geometry, + typename RangeIterator, + typename Strategy, + typename Distance + > + static inline void apply(Geometry const& geometry, + RangeIterator first, + RangeIterator last, + Strategy const& strategy, + RangeIterator& it_min, + Distance& dist_min) + { + BOOST_ASSERT( first != last ); + + Distance const zero = Distance(0); + + // start with first distance + it_min = first; + dist_min = dispatch::distance + < + Geometry, + typename std::iterator_traits<RangeIterator>::value_type, + Strategy + >::apply(geometry, *it_min, strategy); + + // check if other elements in the range are closer + RangeIterator it = first; + for (++it; it != last; ++it) + { + Distance dist = dispatch::distance + < + Geometry, + typename std::iterator_traits<RangeIterator>::value_type, + Strategy + >::apply(geometry, *it, strategy); + + if (geometry::math::equals(dist, zero)) + { + dist_min = dist; + it_min = it; + return; + } + else if (dist < dist_min) + { + dist_min = dist; + it_min = it; + } + } + } + +public: + template + < + typename Geometry, + typename RangeIterator, + typename Strategy, + typename Distance + > + static inline RangeIterator apply(Geometry const& geometry, + RangeIterator first, + RangeIterator last, + Strategy const& strategy, + Distance& dist_min) + { + RangeIterator it_min; + apply(geometry, first, last, strategy, it_min, dist_min); + + return it_min; + } + + + template + < + typename Geometry, + typename RangeIterator, + typename Strategy + > + static inline RangeIterator apply(Geometry const& geometry, + RangeIterator first, + RangeIterator last, + Strategy const& strategy) + { + typename strategy::distance::services::return_type + < + Strategy, + typename point_type<Geometry>::type, + typename point_type + < + typename std::iterator_traits + < + RangeIterator + >::value_type + >::type + >::type dist_min; + + return apply(geometry, first, last, strategy, dist_min); + } +}; + + + +}} // namespace detail::closest_feature +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP |