Olson routine for cartesian to geodetic transformation.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in), | dimension(3) | :: | rvec |
position vector [km] |
|
real(kind=wp), | intent(in) | :: | a |
geoid semimajor axis [km] |
||
real(kind=wp), | intent(in) | :: | b |
geoid semiminor axis [km] |
||
real(kind=wp), | intent(out) | :: | h |
geodetic altitude [km] |
||
real(kind=wp), | intent(out) | :: | long |
longitude [rad] |
||
real(kind=wp), | intent(out) | :: | lat |
geodetic latitude [rad] |
pure subroutine olson(rvec, a, b, h, long, lat) implicit none real(wp),dimension(3),intent(in) :: rvec !!position vector [km] real(wp),intent(in) :: a !!geoid semimajor axis [km] real(wp),intent(in) :: b !!geoid semiminor axis [km] real(wp),intent(out) :: h !!geodetic altitude [km] real(wp),intent(out) :: long !!longitude [rad] real(wp),intent(out) :: lat !!geodetic latitude [rad] real(wp) :: f,x,y,z,e2,a1,a2,a3,a4,a5,a6,w,zp,& w2,r2,r,s2,c2,u,v,s,ss,c,g,rg,rf,m,p,z2 x = rvec(1) y = rvec(2) z = rvec(3) f = (a-b)/a e2 = f * (2.0_wp - f) a1 = a * e2 a2 = a1 * a1 a3 = a1 * e2 / 2.0_wp a4 = 2.5_wp * a2 a5 = a1 + a3 a6 = 1.0_wp - e2 zp = abs(z) w2 = x*x + y*y w = sqrt(w2) z2 = z * z r2 = z2 + w2 r = sqrt(r2) if (r < 100.0_wp) then lat = 0.0_wp long = 0.0_wp h = -1.0e7_wp else s2 = z2 / r2 c2 = w2 / r2 u = a2 / r v = a3 - a4 / r if (c2 > 0.3_wp) then s = (zp / r) * (1.0_wp + c2 * (a1 + u + s2 * v) / r) lat = asin(s) ss = s * s c = sqrt(1.0_wp - ss) else c = (w / r) * (1.0_wp - s2 * (a5 - u - c2 * v) / r) lat = acos(c) ss = 1.0_wp - c * c s = sqrt(ss) end if g = 1.0_wp - e2 * ss rg = a / sqrt(g) rf = a6 * rg u = w - rg * c v = zp - rf * s f = c * u + s * v m = c * v - s * u p = m / (rf / g + f) lat = lat + p if (z < 0.0_wp) lat = -lat h = f + m * p / 2.0_wp long = atan2( y, x ) end if end subroutine olson