test_distance.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Use, modification and distribution is subject to the Boost Software License,
  5. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_GEOMETRY_TEST_DISTANCE_HPP
  8. #define BOOST_GEOMETRY_TEST_DISTANCE_HPP
  9. #include <geometry_test_common.hpp>
  10. #include <boost/geometry/algorithms/distance.hpp>
  11. #include <boost/geometry/io/wkt/read.hpp>
  12. #include <boost/geometry/strategies/strategies.hpp>
  13. // Define a custom distance strategy
  14. // For this one, the "taxicab" distance,
  15. // see http://en.wikipedia.org/wiki/Taxicab_geometry
  16. // For a point-point-distance operation, one typename Point is enough.
  17. // For a point-segment-distance operation, there is some magic inside
  18. // using another point type and casting if necessary. Therefore,
  19. // two point-types are necessary.
  20. struct taxicab_distance
  21. {
  22. template <typename P1, typename P2>
  23. static inline typename bg::coordinate_type<P1>::type apply(
  24. P1 const& p1, P2 const& p2)
  25. {
  26. using bg::get;
  27. using bg::math::abs;
  28. return abs(get<0>(p1) - get<1>(p2))
  29. + abs(get<1>(p1) - get<1>(p2));
  30. }
  31. };
  32. namespace boost { namespace geometry { namespace strategy { namespace distance { namespace services
  33. {
  34. template <>
  35. struct tag<taxicab_distance>
  36. {
  37. typedef strategy_tag_distance_point_point type;
  38. };
  39. template <typename P1, typename P2>
  40. struct return_type<taxicab_distance, P1, P2>
  41. {
  42. typedef typename coordinate_type<P1>::type type;
  43. };
  44. template <>
  45. struct comparable_type<taxicab_distance>
  46. {
  47. typedef taxicab_distance type;
  48. };
  49. template <>
  50. struct get_comparable<taxicab_distance>
  51. {
  52. static inline taxicab_distance apply(taxicab_distance const& input)
  53. {
  54. return input;
  55. }
  56. };
  57. template <typename P1, typename P2>
  58. struct result_from_distance<taxicab_distance, P1, P2>
  59. {
  60. template <typename T>
  61. static inline typename coordinate_type<P1>::type apply(taxicab_distance const& , T const& value)
  62. {
  63. return value;
  64. }
  65. };
  66. }}}}} // namespace bg::strategy::distance::services
  67. template <typename Geometry1, typename Geometry2>
  68. void test_distance(Geometry1 const& geometry1,
  69. Geometry2 const& geometry2,
  70. long double expected_distance)
  71. {
  72. typename bg::default_distance_result<Geometry1>::type distance = bg::distance(geometry1, geometry2);
  73. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  74. std::ostringstream out;
  75. out << typeid(typename bg::coordinate_type<Geometry1>::type).name()
  76. << std::endl
  77. << typeid(typename bg::default_distance_result<Geometry1>::type).name()
  78. << std::endl
  79. << "distance : " << bg::distance(geometry1, geometry2)
  80. << std::endl;
  81. std::cout << out.str();
  82. #endif
  83. BOOST_CHECK_CLOSE(distance, expected_distance, 0.0001);
  84. }
  85. template <typename Geometry1, typename Geometry2>
  86. void test_geometry(std::string const& wkt1, std::string const& wkt2, double expected_distance)
  87. {
  88. Geometry1 geometry1;
  89. bg::read_wkt(wkt1, geometry1);
  90. Geometry2 geometry2;
  91. bg::read_wkt(wkt2, geometry2);
  92. test_distance(geometry1, geometry2, expected_distance);
  93. }
  94. template <typename Geometry1, typename Geometry2>
  95. void test_empty_input(Geometry1 const& geometry1, Geometry2 const& geometry2)
  96. {
  97. try
  98. {
  99. bg::distance(geometry1, geometry2);
  100. }
  101. catch(bg::empty_input_exception const& )
  102. {
  103. return;
  104. }
  105. BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" );
  106. }
  107. #endif