XYZ2ELL.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //
  2. // Academic License - for use in teaching, academic research, and meeting
  3. // course requirements at degree granting institutions only. Not for
  4. // government, commercial, or other organizational use.
  5. // File: XYZ2ELL.cpp
  6. //
  7. // MATLAB Coder version : 5.3
  8. // C/C++ source code generated on : 04-Apr-2023 15:28:59
  9. //
  10. // Include Files
  11. #include "XYZ2ELL.h"
  12. #include "rt_nonfinite.h"
  13. #include "rt_defines.h"
  14. #include <cmath>
  15. // Function Declarations
  16. static double rt_atan2d_snf(double u0, double u1);
  17. // Function Definitions
  18. //
  19. // Arguments : double u0
  20. // double u1
  21. // Return Type : double
  22. //
  23. static double rt_atan2d_snf(double u0, double u1)
  24. {
  25. double y;
  26. if (std::isnan(u0) || std::isnan(u1)) {
  27. y = rtNaN;
  28. } else if (std::isinf(u0) && std::isinf(u1)) {
  29. int b_u0;
  30. int b_u1;
  31. if (u0 > 0.0) {
  32. b_u0 = 1;
  33. } else {
  34. b_u0 = -1;
  35. }
  36. if (u1 > 0.0) {
  37. b_u1 = 1;
  38. } else {
  39. b_u1 = -1;
  40. }
  41. y = std::atan2(static_cast<double>(b_u0), static_cast<double>(b_u1));
  42. } else if (u1 == 0.0) {
  43. if (u0 > 0.0) {
  44. y = RT_PI / 2.0;
  45. } else if (u0 < 0.0) {
  46. y = -(RT_PI / 2.0);
  47. } else {
  48. y = 0.0;
  49. }
  50. } else {
  51. y = std::atan2(u0, u1);
  52. }
  53. return y;
  54. }
  55. //
  56. // choose reference ellipsoid
  57. // 1 ...... tide free
  58. // 2 ...... GRS80
  59. // 3 ...... WGS84
  60. //
  61. // Arguments : const double pos[3]
  62. // double *lat
  63. // double *lon
  64. // double *h
  65. // Return Type : void
  66. //
  67. void XYZ2ELL(const double pos[3], double *lat, double *lon, double *h)
  68. {
  69. double N;
  70. double N_tmp;
  71. double h_tmp;
  72. double lat_tmp_im;
  73. double lat_tmp_re;
  74. // ************************************************************************
  75. // Description:
  76. // Transformation from Cartesian coordinates X,Y,Z to ellipsoidal
  77. // coordinates lam,phi,elh. based on Occam subroutine transf.
  78. //
  79. // Input:
  80. // pos = [x,y,z] [m,m,m]
  81. // can be a matrix: number of rows = number of stations
  82. //
  83. // Output:
  84. // coor_ell = [lat,lon,h] [deg,deg,m]
  85. //
  86. // External calls:
  87. // global a_... Equatorial radius of the Earth [m]
  88. // f_... Flattening factor of the Earth
  89. //
  90. // Coded for VieVS:
  91. // 17 Dec 2008 by Lucia Plank
  92. //
  93. // Revision:
  94. // 11 Nov 2022 by Haobin Luo
  95. // *************************************************************************
  96. // WGS84
  97. lat_tmp_re = pos[2] * 0.0;
  98. lat_tmp_im = pos[2];
  99. *lat = rt_atan2d_snf(pos[2], std::sqrt(pos[0] * pos[0] + pos[1] * pos[1]) +
  100. lat_tmp_re);
  101. N_tmp = pos[0];
  102. N = pos[1];
  103. h_tmp = std::sqrt(N_tmp * N_tmp + N * N);
  104. for (int j{0}; j < 10; j++) {
  105. N_tmp = std::sin(*lat);
  106. N = 6.378137E+6 / std::sqrt(1.0 - 0.0066943799902085387 * N_tmp * N_tmp);
  107. *h = h_tmp / std::cos(*lat) - N;
  108. N_tmp = N + *h;
  109. *lat = rt_atan2d_snf(lat_tmp_im * N_tmp,
  110. h_tmp * (0.9933056200097915 * N + *h) +
  111. lat_tmp_re * N_tmp);
  112. }
  113. *lat *= 57.295779513082323;
  114. *lon = 57.295779513082323 * rt_atan2d_snf(pos[1], pos[0]);
  115. // lat=cart2phigd(pos);
  116. }
  117. //
  118. // File trailer for XYZ2ELL.cpp
  119. //
  120. // [EOF]
  121. //