inverse.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Boost.Geometry
  2. // Unit Test
  3. // Copyright (c) 2016-2019 Oracle and/or its affiliates.
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan.
  6. // Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #include <sstream>
  11. #include "test_formula.hpp"
  12. #include "inverse_cases.hpp"
  13. #include <boost/geometry/formulas/vincenty_inverse.hpp>
  14. #include <boost/geometry/formulas/thomas_inverse.hpp>
  15. #include <boost/geometry/formulas/andoyer_inverse.hpp>
  16. #include <boost/geometry/srs/spheroid.hpp>
  17. template <typename Result>
  18. void check_inverse(std::string const& name,
  19. Result const& results,
  20. bg::formula::result_inverse<double> const& result,
  21. expected_result const& expected,
  22. expected_result const& reference,
  23. double reference_error)
  24. {
  25. std::stringstream ss;
  26. ss << "(" << results.p1.lon << " " << results.p1.lat << ")->(" << results.p2.lon << " " << results.p2.lat << ")";
  27. check_one(name + "_d " + ss.str(),
  28. result.distance, expected.distance, reference.distance, reference_error);
  29. check_one(name + "_a " + ss.str(),
  30. result.azimuth, expected.azimuth, reference.azimuth, reference_error, true);
  31. check_one(name + "_ra " + ss.str(),
  32. result.reverse_azimuth, expected.reverse_azimuth, reference.reverse_azimuth, reference_error, true);
  33. check_one(name + "_rl " + ss.str(),
  34. result.reduced_length, expected.reduced_length, reference.reduced_length, reference_error);
  35. check_one(name + "_gs " + ss.str(),
  36. result.geodesic_scale, expected.geodesic_scale, reference.geodesic_scale, reference_error);
  37. }
  38. void test_all(expected_results const& results)
  39. {
  40. double const d2r = bg::math::d2r<double>();
  41. double const r2d = bg::math::r2d<double>();
  42. double lon1r = results.p1.lon * d2r;
  43. double lat1r = results.p1.lat * d2r;
  44. double lon2r = results.p2.lon * d2r;
  45. double lat2r = results.p2.lat * d2r;
  46. // WGS84
  47. bg::srs::spheroid<double> spheroid(6378137.0, 6356752.3142451793);
  48. bg::formula::result_inverse<double> result_v, result_t, result_a;
  49. typedef bg::formula::vincenty_inverse<double, true, true, true, true, true> vi_t;
  50. result_v = vi_t::apply(lon1r, lat1r, lon2r, lat2r, spheroid);
  51. result_v.azimuth *= r2d;
  52. result_v.reverse_azimuth *= r2d;
  53. check_inverse("vincenty", results, result_v, results.vincenty, results.reference, 0.0000001);
  54. typedef bg::formula::thomas_inverse<double, true, true, true, true, true> th_t;
  55. result_t = th_t::apply(lon1r, lat1r, lon2r, lat2r, spheroid);
  56. result_t.azimuth *= r2d;
  57. result_t.reverse_azimuth *= r2d;
  58. check_inverse("thomas", results, result_t, results.thomas, results.reference, 0.00001);
  59. typedef bg::formula::andoyer_inverse<double, true, true, true, true, true> an_t;
  60. result_a = an_t::apply(lon1r, lat1r, lon2r, lat2r, spheroid);
  61. result_a.azimuth *= r2d;
  62. result_a.reverse_azimuth *= r2d;
  63. check_inverse("andoyer", results, result_a, results.andoyer, results.reference, 0.001);
  64. }
  65. int test_main(int, char*[])
  66. {
  67. for (size_t i = 0; i < expected_size; ++i)
  68. {
  69. test_all(expected[i]);
  70. }
  71. return 0;
  72. }