123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- // 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.
- struct taxicab_distance
- {
- template <typename P1, typename P2>
- 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 <>
- struct tag<taxicab_distance>
- {
- 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 <>
- struct comparable_type<taxicab_distance>
- {
- typedef taxicab_distance type;
- };
- template <>
- struct get_comparable<taxicab_distance>
- {
- static inline taxicab_distance apply(taxicab_distance 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 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 BOOST_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
|