summaryrefslogtreecommitdiff
path: root/libs/geometry/test/algorithms/distance/distance_brute_force.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/geometry/test/algorithms/distance/distance_brute_force.hpp')
-rw-r--r--libs/geometry/test/algorithms/distance/distance_brute_force.hpp493
1 files changed, 493 insertions, 0 deletions
diff --git a/libs/geometry/test/algorithms/distance/distance_brute_force.hpp b/libs/geometry/test/algorithms/distance/distance_brute_force.hpp
new file mode 100644
index 0000000000..e645ec5245
--- /dev/null
+++ b/libs/geometry/test/algorithms/distance/distance_brute_force.hpp
@@ -0,0 +1,493 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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_TEST_DISTANCE_BRUTE_FORCE_HPP
+#define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
+
+#include <iterator>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/reverse_dispatch.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace unit_test
+{
+
+namespace detail { namespace distance_brute_force
+{
+
+struct distance_from_bg
+{
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline
+ typename distance_result<Geometry1, Geometry2, Strategy>::type
+ apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ BOOST_MPL_ASSERT
+ ((typename boost::mpl::or_
+ <
+ boost::is_same<typename tag<Geometry1>::type, point_tag>,
+ boost::is_same<typename tag<Geometry1>::type, segment_tag>
+ >::type));
+
+ BOOST_MPL_ASSERT
+ ((typename boost::mpl::or_
+ <
+ boost::is_same<typename tag<Geometry2>::type, point_tag>,
+ boost::is_same<typename tag<Geometry2>::type, segment_tag>
+ >::type));
+
+ return geometry::distance(geometry1, geometry2, strategy);
+ }
+};
+
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline
+typename distance_result<Geometry1, Geometry2, Strategy>::type
+bg_distance(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return distance_from_bg::apply(geometry1, geometry2, strategy);
+}
+
+
+template <typename Policy>
+struct one_to_many
+{
+ template <typename Geometry, typename Iterator, typename Strategy>
+ static inline typename distance_result
+ <
+ Geometry,
+ typename std::iterator_traits<Iterator>::value_type,
+ Strategy
+ >::type
+ apply(Geometry const& geometry, Iterator begin, Iterator end,
+ Strategy const& strategy)
+ {
+ typedef typename distance_result
+ <
+ Geometry,
+ typename std::iterator_traits<Iterator>::value_type,
+ Strategy
+ >::type distance_type;
+
+ bool first = true;
+ distance_type d_min(0);
+ for (Iterator it = begin; it != end; ++it, first = false)
+ {
+ distance_type d = Policy::apply(geometry, *it, strategy);
+
+ if ( first || d < d_min )
+ {
+ d_min = d;
+ }
+ }
+ return d_min;
+ }
+};
+
+
+
+}} // namespace detail::distance_brute_force
+
+
+namespace dispatch
+{
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Strategy,
+ typename Tag1 = typename tag_cast
+ <
+ typename tag<Geometry1>::type,
+ segment_tag,
+ linear_tag
+ >::type,
+ typename Tag2 = typename tag_cast
+ <
+ typename tag<Geometry2>::type,
+ segment_tag,
+ linear_tag
+ >::type,
+ bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
+>
+struct distance_brute_force
+ : not_implemented<Geometry1, Geometry2>
+{};
+
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Strategy,
+ typename Tag1,
+ typename Tag2
+>
+struct distance_brute_force<Geometry1, Geometry2, Strategy, Tag1, Tag2, true>
+{
+ static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
+ apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ return distance_brute_force
+ <
+ Geometry2, Geometry1, Strategy
+ >::apply(geometry2, geometry1, strategy);
+ }
+};
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point1, Point2, Strategy,
+ point_tag, point_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+
+template
+<
+ typename Point,
+ typename Segment,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, Segment, Strategy,
+ point_tag, segment_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+
+template
+<
+ typename Segment1,
+ typename Segment2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Segment1, Segment2, Strategy,
+ segment_tag, segment_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+
+template
+<
+ typename Point,
+ typename Linear,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, Linear, Strategy,
+ point_tag, linear_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Point, Linear, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Point const& point,
+ Linear const& linear,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(point,
+ geometry::segments_begin(linear),
+ geometry::segments_end(linear),
+ strategy);
+ }
+};
+
+
+template
+<
+ typename Point,
+ typename MultiPoint,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, MultiPoint, Strategy,
+ point_tag, multi_point_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Point, MultiPoint, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Point const& p,
+ MultiPoint const& mp,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(p, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+template
+<
+ typename MultiPoint1,
+ typename MultiPoint2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint1, MultiPoint2, Strategy,
+ multi_point_tag, multi_point_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint1, MultiPoint2, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint1 const& mp1,
+ MultiPoint2 const& mp2,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ MultiPoint1,
+ typename boost::range_value<MultiPoint2>::type,
+ Strategy
+ >
+ >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
+ }
+};
+
+
+template
+<
+ typename MultiPoint,
+ typename Linear,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint, Linear, Strategy,
+ multi_point_tag, linear_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint, Linear, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint const& mp,
+ Linear const& linear,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Linear,
+ typename boost::range_value<MultiPoint>::type,
+ Strategy
+ >
+ >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+
+template
+<
+ typename Linear,
+ typename MultiPoint,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear, MultiPoint, Strategy,
+ linear_tag, multi_point_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear, MultiPoint, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear const& linear,
+ MultiPoint const& multipoint,
+ Strategy const& strategy)
+ {
+ return distance_brute_force
+ <
+ MultiPoint, Linear, Strategy,
+ multi_point_tag, linear_tag, false
+ >::apply(multipoint, linear, strategy);
+ }
+};
+
+
+template
+<
+ typename MultiPoint,
+ typename Segment,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint, Segment, Strategy,
+ multi_point_tag, segment_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint, Segment, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint const& mp,
+ Segment const& segment,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+
+template
+<
+ typename Linear,
+ typename Segment,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear, Segment, Strategy,
+ linear_tag, segment_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear, Segment, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear const& linear,
+ Segment const& segment,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(segment,
+ geometry::segments_begin(linear),
+ geometry::segments_end(linear),
+ strategy);
+ }
+};
+
+
+template
+<
+ typename Linear1,
+ typename Linear2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear1, Linear2, Strategy,
+ linear_tag, linear_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear1, Linear2, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear1 const& linear1,
+ Linear2 const& linear2,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Linear1,
+ typename std::iterator_traits
+ <
+ segment_iterator<Linear2 const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(linear1,
+ geometry::segments_begin(linear2),
+ geometry::segments_end(linear2),
+ strategy);
+ }
+};
+
+} // namespace dispatch
+
+
+
+
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline typename distance_result<Geometry1, Geometry2, Strategy>::type
+distance_brute_force(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return dispatch::distance_brute_force
+ <
+ Geometry1, Geometry2, Strategy
+ >::apply(geometry1, geometry2, strategy);
+}
+
+} // namespace unit_test
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP