Heikkinen 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) | :: | lon |
longitude [rad] |
||
real(kind=wp), | intent(out) | :: | lat |
geodetic latitude [rad] |
pure subroutine heikkinen(rvec, a, b, h, lon, 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) :: lon !! longitude [rad] real(wp),intent(out) :: lat !! geodetic latitude [rad] real(wp) :: f,e_2,ep,r,e2,ff,g,c,s,pp,q,r0,u,v,z0,x,y,z,z2,r2,a2,b2 x = rvec(1) y = rvec(2) z = rvec(3) a2 = a*a b2 = b*b f = (a-b)/a e_2 = (2.0_wp*f-f*f) ep = sqrt(a2/b2 - 1.0_wp) z2 = z*z r = sqrt(x**2 + y**2) r2 = r*r e2 = a2 - b2 ff = 54.0_wp * b2 * z2 g = r2 + (1.0_wp - e_2)*z2 - e_2*e2 c = e_2**2 * ff * r2 / g**3 s = (1.0_wp + c + sqrt(c**2 + 2.0_wp*c))**(1.0_wp/3.0_wp) pp = ff / ( 3.0_wp*(s + 1.0_wp/s + 1.0_wp)**2 * g**2 ) q = sqrt( 1.0_wp + 2.0_wp*e_2**2 * pp ) r0 = -pp*e_2*r/(1.0_wp+q) + & sqrt( max(0.0_wp, 1.0_wp/2.0_wp * a2 * (1.0_wp + 1.0_wp/q) - & ( pp*(1.0_wp-e_2)*z2 )/(q*(1.0_wp+q)) - & 1.0_wp/2.0_wp * pp * r2) ) u = sqrt( (r - e_2*r0)**2 + z2 ) v = sqrt( (r - e_2*r0)**2 + (1.0_wp - e_2)*z2 ) z0 = b**2 * z / (a*v) h = u*(1.0_wp - b2/(a*v) ) lat = atan2( (z + ep**2*z0), r ) lon = atan2( y, x ) end subroutine heikkinen