21 #ifndef otbGeocentricTransform_hxx
22 #define otbGeocentricTransform_hxx
30 template <TransformDirection TDirectionOfMapping,
class TScalarType>
49 template <
class TScalarType,
class TEllipso
id>
50 itk::Point<TScalarType, 3>
WorldToEcef(
const itk::Point<TScalarType, 3> & worldPoint)
52 itk::Point<TScalarType, 3> ecefPoint;
56 const auto height = worldPoint[2];
58 auto sin_latitude = std::sin(lat);
59 auto cos_latitude = std::cos(lat);
60 auto N = TEllipsoid::a / sqrt( 1.0 - TEllipsoid::es * sin_latitude * sin_latitude);
62 ecefPoint[0] = (N + height) * cos_latitude * cos(lon);
63 ecefPoint[1] = (N + height) * cos_latitude * sin(lon);
64 ecefPoint[2] = (N * (1 - TEllipsoid::es) + height) * sin_latitude;
69 template <
class TScalarType,
class TEllipso
id>
70 itk::Point<TScalarType, 3>
EcefToWorld(
const itk::Point<TScalarType, 3> & ecefPoint)
72 itk::Point<TScalarType, 3> worldPoint;
74 const auto x = ecefPoint[0];
75 const auto y = ecefPoint[1];
76 const auto z = ecefPoint[2];
78 const TScalarType tol = 1e-15;
79 const TScalarType d2 = x*x + y*y;
80 const TScalarType d = sqrt(d2);
81 const int MAX_ITER = 10;
83 constexpr TScalarType a2 = TEllipsoid::a * TEllipsoid::a;
84 constexpr TScalarType b2 = TEllipsoid::b * TEllipsoid::b;
85 const TScalarType pa2 = d2 * a2;
86 const TScalarType qb2 = z * z * b2;
87 constexpr TScalarType ae2 = a2 * TEllipsoid::es;
88 constexpr TScalarType ae4 = ae2 * ae2;
90 const TScalarType c3 = -( ae4/2 + pa2 + qb2 );
91 const TScalarType c4 = ae2*( pa2 - qb2 );
92 const TScalarType c5 = ae4/4 * ( ae4/4 - pa2 - qb2 );
94 TScalarType s0 = 0.5 * (a2 + b2) * std::sqrt(d/TEllipsoid::a * d/TEllipsoid::a + z/TEllipsoid::b * z/TEllipsoid::b);
96 for (
int iterIdx = 0; iterIdx < MAX_ITER; ++iterIdx)
98 const TScalarType pol = c5 + s0 * ( c4 + s0 * ( c3 + s0 * s0 ) );
99 const TScalarType der = c4 + s0 * ( 2 * c3 + 4 * s0 * s0 );
101 const TScalarType ds = - pol / der;
104 if (std::abs(ds) < tol * s0)
106 constexpr TScalarType half = 0.5;
107 constexpr TScalarType one = 1.0;
109 const auto t = s0 - half * (a2 + b2);
110 const auto x_ell = d / (one + t/a2);
111 const auto y_ell = z / (one + t/b2);
113 auto const xea2 = x_ell / a2;
114 auto const yeb2 = y_ell / b2;
116 auto height = (d - x_ell) * xea2 + (z - y_ell) * yeb2;
117 height /= std::sqrt(xea2 * xea2 + yeb2 * yeb2);
124 worldPoint[2] = height;