direct_accuracy.cpp 4.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Boost.Geometry
  2. // Unit Test
  3. // Copyright (c) 2019 Oracle and/or its affiliates.
  4. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  5. // Use, modification and distribution is subject to the Boost Software License,
  6. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. #include <geometry_test_common.hpp>
  9. #include <boost/geometry/formulas/karney_direct.hpp>
  10. #include <boost/geometry/srs/srs.hpp>
  11. #ifdef BOOST_GEOEMTRY_TEST_WITH_GEOGRAPHICLIB
  12. #include <GeographicLib/Geodesic.hpp>
  13. #include <GeographicLib/Constants.hpp>
  14. #endif // BOOST_GEOEMTRY_TEST_WITH_GEOGRAPHICLIB
  15. int test_main(int, char*[])
  16. {
  17. #ifdef BOOST_GEOEMTRY_TEST_WITH_GEOGRAPHICLIB
  18. // accuracy test from https://github.com/boostorg/geometry/issues/560
  19. using namespace GeographicLib;
  20. const long double wgs84_a = 6378137.0L;
  21. const long double wgs84_f = 1.0L / 298.257223563L;
  22. const long double one_minus_f = 1.0L - wgs84_f;
  23. const long double wgs84_b = wgs84_a * one_minus_f;
  24. const boost::geometry::srs::spheroid<long double> BoostWGS84(wgs84_a, wgs84_b);
  25. // boost karney_direct function class with azimuth output and SeriesOrder = 6
  26. typedef boost::geometry::formula::karney_direct <double, true, true, false, false, 6u>
  27. BoostKarneyDirect_6;
  28. // boost karney_direct function class with azimuth output and SeriesOrder = 8
  29. typedef boost::geometry::formula::karney_direct <double, true, true, false, false, 8u>
  30. BoostKarneyDirect_8;
  31. // boost test BOOST_CHECK_CLOSE macro takes a percentage accuracy parameter
  32. const double EPSILON = std::numeric_limits<double>::epsilon();
  33. const double CALCULATION_TOLERANCE = 100 * EPSILON;
  34. const Geodesic GeographicLibWGS84(Geodesic::WGS84());
  35. // Loop around latitudes: 0 to 89 degrees
  36. for (int i=0; i < 90; ++i)
  37. {
  38. // The latitude in degrees.
  39. double latitude(1.0 * i);
  40. // Loop around longitudes: 1 to 179 degrees
  41. for (int j=1; j < 180; ++j)
  42. {
  43. // The longitude in degrees.
  44. double longitude(1.0 * j);
  45. // The Geodesic: distance in metres, start azimuth and finish azimuth in degrees.
  46. double distance_m, azimuth, azi2;
  47. GeographicLibWGS84.Inverse(0.0, 0.0, latitude, longitude, distance_m, azimuth, azi2);
  48. // The GeographicLib position and azimuth at the distance in metres
  49. double lat2k, lon2k, azi2k;
  50. GeographicLibWGS84.Direct(0.0, 0.0, azimuth, distance_m, lat2k, lon2k, azi2k);
  51. BOOST_CHECK_CLOSE(latitude, lat2k, 140 * CALCULATION_TOLERANCE);
  52. BOOST_CHECK_CLOSE(longitude, lon2k, 120 * CALCULATION_TOLERANCE);
  53. // The boost karney_direct order 6 position at the azimuth and distance in metres.
  54. boost::geometry::formula::result_direct<double> results_6
  55. = BoostKarneyDirect_6::apply(0.0, 0.0, distance_m, azimuth, BoostWGS84);
  56. BOOST_CHECK_CLOSE(azi2, results_6.reverse_azimuth, 140 * CALCULATION_TOLERANCE);
  57. BOOST_CHECK_CLOSE(latitude, results_6.lat2, 220 * CALCULATION_TOLERANCE);
  58. /******** Test below only passes with >= 10172000 * CALCULATION_TOLERANCE !! ********/
  59. BOOST_CHECK_CLOSE(longitude, results_6.lon2, 10171000 * CALCULATION_TOLERANCE);
  60. /*****************************************************************************/
  61. // The boost karney_direct order 8 position at the azimuth and distance in metres.
  62. boost::geometry::formula::result_direct<double> results_8
  63. = BoostKarneyDirect_8::apply(0.0, 0.0, distance_m, azimuth, BoostWGS84);
  64. BOOST_CHECK_CLOSE(azi2, results_8.reverse_azimuth, 140 * CALCULATION_TOLERANCE);
  65. BOOST_CHECK_CLOSE(latitude, results_8.lat2, 220 * CALCULATION_TOLERANCE);
  66. /******** Test below only passes with >= 10174000 * CALCULATION_TOLERANCE !! ********/
  67. BOOST_CHECK_CLOSE(longitude, results_8.lon2, 10173000 * CALCULATION_TOLERANCE);
  68. /*****************************************************************************/
  69. }
  70. }
  71. #endif // BOOST_GEOEMTRY_TEST_WITH_GEOGRAPHICLIB
  72. return 0;
  73. }