cross_track.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
  5. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
  6. // This file was modified by Oracle on 2014.
  7. // Modifications copyright (c) 2014, Oracle and/or its affiliates.
  8. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  9. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  10. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  11. // Use, modification and distribution is subject to the Boost Software License,
  12. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. #include <geometry_test_common.hpp>
  15. #include <boost/core/ignore_unused.hpp>
  16. #include <boost/geometry/io/wkt/read.hpp>
  17. #include <boost/geometry/algorithms/assign.hpp>
  18. #include <boost/geometry/algorithms/distance.hpp>
  19. #include <boost/geometry/strategies/spherical/distance_haversine.hpp>
  20. #include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
  21. #include <boost/geometry/strategies/concepts/distance_concept.hpp>
  22. #include <boost/geometry/geometries/point.hpp>
  23. #include <boost/geometry/geometries/segment.hpp>
  24. // This test is GIS oriented.
  25. template <typename Point, typename LatitudePolicy>
  26. void test_distance(
  27. typename bg::coordinate_type<Point>::type const& lon1,
  28. typename bg::coordinate_type<Point>::type const& lat1,
  29. typename bg::coordinate_type<Point>::type const& lon2,
  30. typename bg::coordinate_type<Point>::type const& lat2,
  31. typename bg::coordinate_type<Point>::type const& lon3,
  32. typename bg::coordinate_type<Point>::type const& lat3,
  33. typename bg::coordinate_type<Point>::type const& radius,
  34. typename bg::coordinate_type<Point>::type const& expected,
  35. typename bg::coordinate_type<Point>::type const& tolerance)
  36. {
  37. typedef bg::strategy::distance::cross_track
  38. <
  39. typename bg::coordinate_type<Point>::type
  40. > strategy_type;
  41. typedef typename bg::strategy::distance::services::return_type
  42. <
  43. strategy_type,
  44. Point,
  45. Point
  46. >::type return_type;
  47. {
  48. // compile-check if there is a strategy for this type
  49. typedef typename bg::strategy::distance::services::default_strategy
  50. <
  51. bg::point_tag, bg::segment_tag, Point, Point
  52. >::type cross_track_strategy_type;
  53. typedef typename bg::strategy::distance::services::default_strategy
  54. <
  55. bg::segment_tag, bg::point_tag, Point, Point
  56. >::type reversed_tags_cross_track_strategy_type;
  57. boost::ignore_unused<cross_track_strategy_type,
  58. reversed_tags_cross_track_strategy_type>();
  59. }
  60. BOOST_CONCEPT_ASSERT
  61. (
  62. (bg::concepts::PointSegmentDistanceStrategy<strategy_type, Point, Point>)
  63. );
  64. Point p1, p2, p3;
  65. bg::assign_values(p1, lon1, LatitudePolicy::apply(lat1));
  66. bg::assign_values(p2, lon2, LatitudePolicy::apply(lat2));
  67. bg::assign_values(p3, lon3, LatitudePolicy::apply(lat3));
  68. strategy_type strategy;
  69. return_type d = strategy.apply(p1, p2, p3);
  70. BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
  71. // The strategy should return the same result if we reverse the parameters
  72. d = strategy.apply(p1, p3, p2);
  73. BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
  74. // Test specifying radius explicitly
  75. strategy_type strategy_radius(radius);
  76. d = strategy_radius.apply(p1, p2, p3);
  77. BOOST_CHECK_CLOSE(d, expected, tolerance);
  78. // Test the "default strategy" registration
  79. bg::model::referring_segment<Point const> segment(p2, p3);
  80. d = bg::distance(p1, segment);
  81. BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
  82. }
  83. template <typename Point>
  84. void test_case_boost_geometry_list_20120625()
  85. {
  86. // This function tests the bug submitted by Karsten Ahnert
  87. // on Boost.Geometry list at 2012-06-25, and wherefore he
  88. // submitted a patch a few days later.
  89. Point p1, p2;
  90. bg::model::segment<Point> s1, s2;
  91. bg::read_wkt("POINT(1 1)", p1);
  92. bg::read_wkt("POINT(5 1)", p2);
  93. bg::read_wkt("LINESTRING(0 2,2 2)", s1);
  94. bg::read_wkt("LINESTRING(2 2,4 2)", s2);
  95. BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s1), 0.0174586, 0.0001);
  96. BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s2), 0.0246783, 0.0001);
  97. BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s1), 0.0551745, 0.0001);
  98. BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s2), 0.0246783, 0.0001);
  99. // Check degenerated segments
  100. bg::model::segment<Point> s3;
  101. bg::read_wkt("LINESTRING(2 2,2 2)", s3);
  102. BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s3), 0.0246783, 0.0001);
  103. BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s3), 0.0551745, 0.0001);
  104. // Point/Point distance should be identical:
  105. Point p3;
  106. bg::read_wkt("POINT(2 2)", p3);
  107. BOOST_CHECK_CLOSE(boost::geometry::distance(p1, p3), 0.0246783, 0.0001);
  108. BOOST_CHECK_CLOSE(boost::geometry::distance(p2, p3), 0.0551745, 0.0001);
  109. }
  110. template <typename Point, typename LatitudePolicy>
  111. void test_all()
  112. {
  113. typename bg::coordinate_type<Point>::type const average_earth_radius = 6372795.0;
  114. // distance (Paris <-> Amsterdam/Barcelona),
  115. // with coordinates rounded as below ~87 km
  116. // is equal to distance (Paris <-> Barcelona/Amsterdam)
  117. typename bg::coordinate_type<Point>::type const p_to_ab = 86.798321 * 1000.0;
  118. test_distance<Point, LatitudePolicy>(2, 48, 4, 52, 2, 41, average_earth_radius, p_to_ab, 0.1);
  119. test_distance<Point, LatitudePolicy>(2, 48, 2, 41, 4, 52, average_earth_radius, p_to_ab, 0.1);
  120. test_case_boost_geometry_list_20120625<Point>();
  121. }
  122. int test_main(int, char* [])
  123. {
  124. test_all<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> >, geographic_policy >();
  125. // NYI: haversine for mathematical spherical coordinate systems
  126. // test_all<bg::model::point<double, 2, bg::cs::spherical<bg::degree> >, mathematical_policya >();
  127. #if defined(HAVE_TTMATH)
  128. typedef ttmath::Big<1,4> tt;
  129. //test_all<bg::model::point<tt, 2, bg::cs::geographic<bg::degree> >, geographic_policy>();
  130. #endif
  131. return 0;
  132. }