Source code for gavo.stc.geo
"""
Coordinate systems for positions on earth.
"""
#c Copyright 2008-2023, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL. See the
#c COPYING file in the source distribution.
import math
from gavo.utils import DEG
[docs]class WGS84(object):
"""the WGS84 reference system.
"""
a = 6378137.
f = 1/298.257223563
GM = 3.986005e14 # m3s-1
J2 = 0.00108263
omega = 7.292115e-5 # rad s-1
def _getC_S(phi, refSys):
"""returns the values of the auxiliary functions C and S.
phi must be in rad.
See Astron. Almanac, Appendix K.
"""
B = (1-refSys.f)**2
C = 1/math.sqrt(
math.cos(phi)**2
+B*math.sin(phi)**2)
S = C*B
return C, S
[docs]def geocToGeod(long, phip, rho=1, refSys=WGS84):
"""returns geodetic coordinates long, phi for geocentric coordinates.
refSys defaults is the reference system the geodetic coordinates are
expressed in.
This will not work at the poles -- patches welcome.
See Astron. Almanac, Appendix K; we go for the iterative solution
discussed there.
"""
long, phip = long*DEG, phip*DEG
x = refSys.a*rho*math.cos(phip)*math.cos(long)
y = refSys.a*rho*math.cos(phip)*math.sin(long)
z = refSys.a*rho*math.sin(phip)
e2 = 2*refSys.f-refSys.f**2
r = math.sqrt(x**2+y**2)
phi = math.atan2(z, r)
while True:
phi1 = phi
C = 1/math.sqrt((1-e2*math.sin(phi1)**2))
phi = math.atan2(z+refSys.a*C*e2*math.sin(phi1), r)
if abs(phi1-phi)<1e-14: # phi is always of order 1
break
return long/DEG, phi/DEG, r/math.cos(phi)-refSys.a*C
[docs]def geodToGeoc(long, phi, height, refSys=WGS84):
"""returns geocentric coordinates lambda, phi', rho for geodetic coordinates.
refSys defaults is the reference system the geodetic coordinates are
expressed in.
height is in meter, long, phi in degrees.
See Astron. Almanac, Appendix K.
"""
long, phi = long*DEG, phi*DEG
C, S = _getC_S(phi, refSys)
rcp = (C+height/refSys.a)*math.cos(phi)
rsp = (S+height/refSys.a)*math.sin(phi)
rho = math.sqrt(rcp**2+rsp**2)
phip = math.atan2(rsp, rcp)
return long/DEG, phip/DEG, rho