direct_meridian.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Boost.Geometry
  2. // Unit Test
  3. // Copyright (c) 2018 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. #define BOOST_GEOMETRY_NORMALIZE_LATITUDE
  9. #include <sstream>
  10. #include "test_formula.hpp"
  11. #include "direct_meridian_cases.hpp"
  12. #include <boost/geometry/srs/srs.hpp>
  13. #include <boost/geometry/formulas/vincenty_direct.hpp>
  14. #include <boost/geometry/formulas/meridian_direct.hpp>
  15. template <typename Result, typename Expected, typename Reference>
  16. void check_meridian_direct(Result& result,
  17. Expected const& expected,
  18. Reference& reference,
  19. double reference_error)
  20. {
  21. boost::geometry::math::normalize_spheroidal_coordinates
  22. <
  23. boost::geometry::radian,
  24. double
  25. >(result.lon2, result.lat2);
  26. boost::geometry::math::normalize_spheroidal_coordinates
  27. <
  28. boost::geometry::radian,
  29. double
  30. >(reference.lon2, reference.lat2);
  31. std::stringstream ss;
  32. ss << "(" << result.lon2 * bg::math::r2d<double>()
  33. << " " << result.lat2 * bg::math::r2d<double>() << ")";
  34. check_one("lon:" + ss.str(), result.lon2, expected.lon, reference.lon2,
  35. reference_error);
  36. check_one("lat:" + ss.str(), result.lat2, expected.lat, reference.lat2,
  37. reference_error);
  38. check_one("rev_az:" + ss.str(), result.reverse_azimuth,
  39. result.reverse_azimuth, reference.reverse_azimuth, reference_error);
  40. check_one("red len:" + ss.str(), result.reduced_length, result.reduced_length,
  41. reference.reduced_length, 0.01);
  42. check_one("geo scale:" + ss.str(), result.geodesic_scale, result.geodesic_scale,
  43. reference.geodesic_scale, 0.01);
  44. }
  45. void test_all(expected_results const& results)
  46. {
  47. double const d2r = bg::math::d2r<double>();
  48. double lon1_rad = results.p1.lon * d2r;
  49. double lat1_rad = results.p1.lat * d2r;
  50. coordinates expected_point;
  51. expected_point.lon = results.p2.lon * d2r;
  52. expected_point.lat = results.p2.lat * d2r;
  53. double distance = results.distance;
  54. bool direction = results.direction;
  55. // WGS84
  56. bg::srs::spheroid<double> spheroid(6378137.0, 6356752.3142451793);
  57. bg::formula::result_direct<double> vincenty_result;
  58. bg::formula::result_direct<double> meridian_result;
  59. typedef bg::formula::vincenty_direct<double, true, true, true, true> vi_t;
  60. double vincenty_azimuth = direction ? 0.0 : bg::math::pi<double>();
  61. vincenty_result = vi_t::apply(lon1_rad, lat1_rad, distance, vincenty_azimuth, spheroid);
  62. {
  63. typedef bg::formula::meridian_direct<double, true, true, true, true, 1> eli;
  64. meridian_result = eli::apply(lon1_rad, lat1_rad, distance, direction, spheroid);
  65. check_meridian_direct(meridian_result, expected_point, vincenty_result, 0.001);
  66. }
  67. {
  68. typedef bg::formula::meridian_direct<double, true, true, true, true, 2> eli;
  69. meridian_result = eli::apply(lon1_rad, lat1_rad, distance, direction, spheroid);
  70. check_meridian_direct(meridian_result, expected_point, vincenty_result, 0.00001);
  71. }
  72. {
  73. typedef bg::formula::meridian_direct<double, true, true, true, true, 3> eli;
  74. meridian_result = eli::apply(lon1_rad, lat1_rad, distance, direction, spheroid);
  75. check_meridian_direct(meridian_result, expected_point, vincenty_result, 0.00000001);
  76. }
  77. {
  78. typedef bg::formula::meridian_direct<double, true, true, true, true, 4> eli;
  79. meridian_result = eli::apply(lon1_rad, lat1_rad, distance, direction, spheroid);
  80. check_meridian_direct(meridian_result, expected_point, vincenty_result, 0.00000001);
  81. }
  82. {
  83. typedef bg::formula::meridian_direct<double, true, true, true, true, 5> eli;
  84. meridian_result = eli::apply(lon1_rad, lat1_rad, distance, direction, spheroid);
  85. check_meridian_direct(meridian_result, expected_point, vincenty_result, 0.00000000001);
  86. }
  87. }
  88. int test_main(int, char*[])
  89. {
  90. for (size_t i = 0; i < expected_size; ++i)
  91. {
  92. test_all(expected[i]);
  93. }
  94. return 0;
  95. }