source: inundation/pyvolution/coordinate_transforms/redfearn.py @ 1812

Last change on this file since 1812 was 928, checked in by ole, 20 years ago

Incorporated variable false eastings and northings (just in case:-).

File size: 4.1 KB
Line 
1"""Implementation of Redfearn's formula to compute UTM projections from latitude and longitude
2
3"""
4
5def degminsec2decimal_degrees(dd,mm,ss):
6    assert abs(mm) == mm
7    assert abs(ss) == ss   
8
9    if dd < 0:
10        sign = -1
11    else:
12        sign = 1
13   
14    return sign * (abs(dd) + mm/60. + ss/3600.)     
15   
16def decimal_degrees2degminsec(dec):
17
18    if dec < 0:
19        sign = -1
20    else:
21        sign = 1
22
23    dec = abs(dec)   
24    dd = int(dec)
25    f = dec-dd
26
27    mm = int(f*60)
28    ss = (f*60-mm)*60
29   
30    return sign*dd, mm, ss
31
32def redfearn(lat, lon, false_easting=None, false_northing=None):
33    """Compute UTM projection using Redfearn's formula
34
35    lat, lon is latitude and longitude in decimal degrees
36
37    If false easting and northing are specified they will override
38    the standard
39    """
40
41
42    from math import pi, sqrt, sin, cos, tan
43   
44
45
46    #GDA Specifications
47    a = 6378137.0                       #Semi major axis
48    inverse_flattening = 298.257222101  #1/f
49    K0 = 0.9996                         #Central scale factor   
50    zone_width = 6                      #Degrees
51
52    longitude_of_central_meridian_zone0 = -183   
53    longitude_of_western_edge_zone0 = -186
54
55    if false_easting is None:
56        false_easting = 500000
57
58    if false_northing is None:
59        if lat < 0:
60            false_northing = 10000000  #Southern hemisphere
61        else:
62            false_northing = 0         #Northern hemisphere)
63       
64   
65    #Derived constants
66    f = 1.0/inverse_flattening
67    b = a*(1-f)       #Semi minor axis
68
69    e2 = 2*f - f*f#    = f*(2-f) = (a^2-b^2/a^2   #Eccentricity
70    e = sqrt(e2)
71    e2_ = e2/(1-e2)   # = (a^2-b^2)/b^2 #Second eccentricity
72    e_ = sqrt(e2_)
73    e4 = e2*e2
74    e6 = e2*e4
75
76    #Foot point latitude
77    n = (a-b)/(a+b) #Same as e2 - why ?
78    n2 = n*n
79    n3 = n*n2
80    n4 = n2*n2
81
82    G = a*(1-n)*(1-n2)*(1+9*n2/4+225*n4/64)*pi/180
83
84
85    phi = lat*pi/180     #Convert latitude to radians
86
87    sinphi = sin(phi)   
88    sin2phi = sin(2*phi)
89    sin4phi = sin(4*phi)
90    sin6phi = sin(6*phi)
91
92    cosphi = cos(phi)
93    cosphi2 = cosphi*cosphi
94    cosphi3 = cosphi*cosphi2
95    cosphi4 = cosphi2*cosphi2
96    cosphi5 = cosphi*cosphi4   
97    cosphi6 = cosphi2*cosphi4
98    cosphi7 = cosphi*cosphi6
99    cosphi8 = cosphi4*cosphi4       
100
101    t = tan(phi)
102    t2 = t*t
103    t4 = t2*t2
104    t6 = t2*t4
105   
106    #Radius of Curvature
107    rho = a*(1-e2)/(1-e2*sinphi*sinphi)**1.5
108    nu = a/(1-e2*sinphi*sinphi)**0.5
109    psi = nu/rho
110    psi2 = psi*psi
111    psi3 = psi*psi2
112    psi4 = psi2*psi2
113
114
115
116    #Meridian distance
117
118    A0 = 1 - e2/4 - 3*e4/64 - 5*e6/256
119    A2 = 3.0/8*(e2+e4/4+15*e6/128)
120    A4 = 15.0/256*(e4+3*e6/4)
121    A6 = 35*e6/3072
122   
123    term1 = a*A0*phi
124    term2 = -a*A2*sin2phi
125    term3 = a*A4*sin4phi
126    term4 = -a*A6*sin6phi
127
128    m = term1 + term2 + term3 + term4 #OK
129
130    #Zone
131    zone = int((lon - longitude_of_western_edge_zone0)/zone_width)
132    central_meridian = zone*zone_width+longitude_of_central_meridian_zone0
133
134    omega = (lon-central_meridian)*pi/180 #Relative longitude (radians)
135    omega2 = omega*omega
136    omega3 = omega*omega2
137    omega4 = omega2*omega2
138    omega5 = omega*omega4
139    omega6 = omega3*omega3
140    omega7 = omega*omega6
141    omega8 = omega4*omega4
142   
143   
144    #Northing
145    term1 = nu*sinphi*cosphi*omega2/2 
146    term2 = nu*sinphi*cosphi3*(4*psi2+psi-t2)*omega4/24
147    term3 = nu*sinphi*cosphi5*\
148            (8*psi4*(11-24*t2)-28*psi3*(1-6*t2)+\
149             psi2*(1-32*t2)-psi*2*t2+t4-t2)*omega6/720
150    term4 = nu*sinphi*cosphi7*(1385-3111*t2+543*t4-t6)*omega8/40320
151    northing = false_northing + K0*(m + term1 + term2 + term3 + term4)
152
153    #Easting
154    term1 = nu*omega*cosphi
155    term2 = nu*cosphi3*(psi-t2)*omega3/6
156    term3 = nu*cosphi5*(4*psi3*(1-6*t2)+psi2*(1+8*t2)-2*psi*t2+t4)*omega5/120
157    term4 = nu*cosphi7*(61-479*t2+179*t4-t6)*omega7/5040
158    easting = false_easting + K0*(term1 + term2 + term3 + term4)
159   
160    return zone, easting, northing
Note: See TracBrowser for help on using the repository browser.