;+ ; NAME: ; GEO2GEODETIC ; ; PURPOSE: ; Convert from geographic/planetographic to geodetic coordinates ; EXPLANATION: ; Converts from geographic (latitude, longitude, altitude) to geodetic ; (latitude, longitude, altitude). In geographic coordinates, the ; Earth is assumed a perfect sphere with a radius equal to its equatorial ; radius. The geodetic (or ellipsoidal) coordinate system takes into ; account the Earth's oblateness. ; ; Geographic and geodetic longitudes are identical. ; Geodetic latitude is the angle between local zenith and the equatorial plane. ; Geographic and geodetic altitudes are both the closest distance between ; the satellite and the ground. ; ; The PLANET keyword allows a similar transformation for the other ; planets (planetographic to planetodetic coordinates). ; ; The EQUATORIAL_RADIUS and POLAR_RADIUS keywords allow the ; transformation for any ellipsoid. ; ; Latitudes and longitudes are expressed in degrees, altitudes in km. ; ; REF: Stephen P. Keeler and Yves Nievergelt, "Computing geodetic ; coordinates", SIAM Rev. Vol. 40, No. 2, pp. 300-309, June 1998 ; ; Planterary constants from "Allen's Astrophysical Quantities", ; Fourth Ed., (2000) ; ; CALLING SEQUENCE: ; ecoord=geo2geodetic(gcoord,[ PLANET=,EQUATORIAL_RADIUS=, POLAR_RADIUS=]) ; ; INPUT: ; gcoord = a 3-element array of geographic [latitude,longitude,altitude], ; or an array [3,n] of n such coordinates. ; ; ; OPTIONAL KEYWORD INPUT: ; PLANET = keyword specifying planet (default is Earth). The planet ; may be specified either as an integer (1-9) or as one of the ; (case-independent) strings 'mercury','venus','earth','mars', ; 'jupiter','saturn','uranus','neptune', or 'pluto' ; ; EQUATORIAL_RADIUS : Self-explanatory. In km. If not set, PLANET's ; value is used. ; POLAR_RADIUS : Self-explanatory. In km. If not set, PLANET's value is ; used. ; ; OUTPUT: ; a 3-element array of geodetic/planetodetic [latitude,longitude,altitude], ; or an array [3,n] of n such coordinates, double precision. ; ; COMMON BLOCKS: ; None ; ; RESTRICTIONS: ; ; Whereas the conversion from geodetic to geographic coordinates is given ; by an exact, analytical formula, the conversion from geographic to ; geodetic isn't. Approximative iterations (as used here) exist, but tend ; to become less good with increasing eccentricity and altitude. ; The formula used in this routine should give correct results within ; six digits for all spatial locations, for an ellipsoid (planet) with ; an eccentricity similar to or less than Earth's. ; More accurate results can be obtained via calculus, needing a ; non-determined amount of iterations. ; In any case, ; IDL> PRINT,geodetic2geo(geo2geodetic(gcoord)) - gcoord ; is a pretty good way to evaluate the accuracy of geo2geodetic.pro. ; ; EXAMPLES: ; ; Locate the geographic North pole, altitude 0., in geodetic coordinates ; IDL> geo=[90.d0,0.d0,0.d0] ; IDL> geod=geo2geodetic(geo); convert to equivalent geodetic coordinates ; IDL> PRINT,geod ; 90.000000 0.0000000 21.385000 ; ; As above, but for the case of Mars ; IDL> geod=geo2geodetic(geo,PLANET='Mars') ; IDL> PRINT,geod ; 90.000000 0.0000000 18.235500 ; ; MODIFICATION HISTORY: ; Written by Pascal Saint-Hilaire (shilaire@astro.phys.ethz.ch), May 2002 ; Generalized for all solar system planets by Robert L. Marcialis ; (umpire@lpl.arizona.edu), May 2002 ; Modified 2002/05/18, PSH: added keywords EQUATORIAL_RADIUS and ; POLAR_RADIUS ;- ;================================================================================ FUNCTION geo2geodetic,gcoord,PLANET=planet, $ EQUATORIAL_RADIUS=equatorial_radius, POLAR_RADIUS=polar_radius sz_gcoord = size(gcoord,/DIMEN) if sz_gcoord[0] LT 3 then message, $ 'ERROR - 3 coordinates (latitude,longitude,altitude) must be specified' if N_elements(PLANET) GT 0 then begin if size(planet,/tname) EQ 'STRING' then begin choose_planet=['mercury','venus','earth','mars','jupiter','saturn', $ 'uranus','neptune','pluto'] index=where(choose_planet eq strlowcase(planet)) index=index[0] ; make it a scalar if index eq -1 then index = 2 ; default is Earth endif else index = planet-1 endif else index=2 Requator = [2439.7d0,6051.8d0,6378.137D, 3397.62d0, 71492d0, $ 60268.d0, 25559.d0, 24764.d0, 1195.d0] Rpole = [2439.7d0, 6051.8d0, 6356.752d0, 3379.3845d0, 67136.5562d0, $ 54890.7686d0, 24986.1354d0, 24347.6551d0, 1195.d0] Re = Requator(index) ; equatorial radius Rp = Rpole(index) ; polar radius IF KEYWORD_SET(EQUATORIAL_RADIUS) THEN Re=DOUBLE(equatorial_radius[0]) IF KEYWORD_SET(POLAR_RADIUS) THEN Rp=DOUBLE(polar_radius[0]) e = sqrt(Re^2 - Rp^2)/Re ;f=1/298.257D ; flattening = (Re-Rp)/Re [not needed, here] glat=DOUBLE(gcoord[0,*])*!DPI/180. glon=DOUBLE(gcoord[1,*]) galt=DOUBLE(gcoord[2,*]) x= (Re+galt) * cos(glat) * cos(glon) y= (Re+galt) * cos(glat) * sin(glon) z= (Re+galt) * sin(glat) r=sqrt(x^2+y^2) s=(r^2 + z ^2)^0.5 * (1 - Re*((1-e^2)/((1-e^2)*r^2 + z^2))^0.5) t0=1+s*(1- (e*z)^2/(r^2 + z^2) )^0.5 /Re dzeta1=z * t0 xi1=r*(t0 - e^2) rho1= (xi1^2 + dzeta1^2)^0.5 c1=xi1/rho1 s1=dzeta1/rho1 b1=Re/(1- (e*s1)^2)^0.5 u1= b1*c1 w1= b1*s1*(1- e^2) ealt= ((r - u1)^2 + (z - w1)^2)^0.5 elat= atan(s1,c1) elat=elat*180./!DPI elon=glon RETURN,[elat,elon,ealt] END ;===============================================================================