summaryrefslogtreecommitdiff
path: root/libs/geometry/test/algorithms/test_distance.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/geometry/test/algorithms/test_distance.hpp')
-rw-r--r--libs/geometry/test/algorithms/test_distance.hpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/libs/geometry/test/algorithms/test_distance.hpp b/libs/geometry/test/algorithms/test_distance.hpp
new file mode 100644
index 000000000..271bdab6e
--- /dev/null
+++ b/libs/geometry/test/algorithms/test_distance.hpp
@@ -0,0 +1,158 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_TEST_DISTANCE_HPP
+#define BOOST_GEOMETRY_TEST_DISTANCE_HPP
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/io/wkt/read.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+
+// Define a custom distance strategy
+// For this one, the "taxicab" distance,
+// see http://en.wikipedia.org/wiki/Taxicab_geometry
+
+// For a point-point-distance operation, one typename Point is enough.
+// For a point-segment-distance operation, there is some magic inside
+// using another point type and casting if necessary. Therefore,
+// two point-types are necessary.
+template <typename P1, typename P2 = P1>
+struct taxicab_distance
+{
+ static inline typename bg::coordinate_type<P1>::type apply(
+ P1 const& p1, P2 const& p2)
+ {
+ using bg::get;
+ using bg::math::abs;
+ return abs(get<0>(p1) - get<1>(p2))
+ + abs(get<1>(p1) - get<1>(p2));
+ }
+};
+
+
+
+namespace boost { namespace geometry { namespace strategy { namespace distance { namespace services
+{
+
+template <typename P1, typename P2>
+struct tag<taxicab_distance<P1, P2> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename P1, typename P2>
+struct return_type<taxicab_distance<P1, P2> >
+{
+ typedef typename coordinate_type<P1>::type type;
+};
+
+
+template<typename P1, typename P2, typename PN1, typename PN2>
+struct similar_type<taxicab_distance<P1, P2>, PN1, PN2>
+{
+ typedef taxicab_distance<PN1, PN2> type;
+};
+
+
+template<typename P1, typename P2, typename PN1, typename PN2>
+struct get_similar<taxicab_distance<P1, P2>, PN1, PN2>
+{
+ static inline typename similar_type
+ <
+ taxicab_distance<P1, P2>, PN1, PN2
+ >::type apply(taxicab_distance<P1, P2> const& )
+ {
+ return taxicab_distance<PN1, PN2>();
+ }
+};
+
+template <typename P1, typename P2>
+struct comparable_type<taxicab_distance<P1, P2> >
+{
+ typedef taxicab_distance<P1, P2> type;
+};
+
+template <typename P1, typename P2>
+struct get_comparable<taxicab_distance<P1, P2> >
+{
+ static inline taxicab_distance<P1, P2> apply(taxicab_distance<P1, P2> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename P1, typename P2>
+struct result_from_distance<taxicab_distance<P1, P2> >
+{
+ template <typename T>
+ static inline typename coordinate_type<P1>::type apply(taxicab_distance<P1, P2> const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+}}}}} // namespace bg::strategy::distance::services
+
+
+
+
+
+template <typename Geometry1, typename Geometry2>
+void test_distance(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ long double expected_distance)
+{
+ typename bg::default_distance_result<Geometry1>::type distance = bg::distance(geometry1, geometry2);
+
+#ifdef GEOMETRY_TEST_DEBUG
+ std::ostringstream out;
+ out << typeid(typename bg::coordinate_type<Geometry1>::type).name()
+ << std::endl
+ << typeid(typename bg::default_distance_result<Geometry1>::type).name()
+ << std::endl
+ << "distance : " << bg::distance(geometry1, geometry2)
+ << std::endl;
+ std::cout << out.str();
+#endif
+
+ BOOST_CHECK_CLOSE(distance, expected_distance, 0.0001);
+}
+
+
+template <typename Geometry1, typename Geometry2>
+void test_geometry(std::string const& wkt1, std::string const& wkt2, double expected_distance)
+{
+ Geometry1 geometry1;
+ bg::read_wkt(wkt1, geometry1);
+ Geometry2 geometry2;
+ bg::read_wkt(wkt2, geometry2);
+
+ test_distance(geometry1, geometry2, expected_distance);
+}
+
+template <typename Geometry1, typename Geometry2>
+void test_empty_input(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ try
+ {
+ bg::distance(geometry1, geometry2);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" );
+}
+
+
+#endif