diff options
Diffstat (limited to 'libs/geometry/test/algorithms/test_distance.hpp')
-rw-r--r-- | libs/geometry/test/algorithms/test_distance.hpp | 158 |
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 |