00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 from math import pi, sin, cos, tan, sqrt
00045
00046
00047
00048
00049
00050 _deg2rad = pi / 180.0
00051 _rad2deg = 180.0 / pi
00052
00053 _EquatorialRadius = 2
00054 _eccentricitySquared = 3
00055
00056 _ellipsoid = [
00057
00058
00059 [ -1, "Placeholder", 0, 0],
00060 [ 1, "Airy", 6377563, 0.00667054],
00061 [ 2, "Australian National", 6378160, 0.006694542],
00062 [ 3, "Bessel 1841", 6377397, 0.006674372],
00063 [ 4, "Bessel 1841 (Nambia] ", 6377484, 0.006674372],
00064 [ 5, "Clarke 1866", 6378206, 0.006768658],
00065 [ 6, "Clarke 1880", 6378249, 0.006803511],
00066 [ 7, "Everest", 6377276, 0.006637847],
00067 [ 8, "Fischer 1960 (Mercury] ", 6378166, 0.006693422],
00068 [ 9, "Fischer 1968", 6378150, 0.006693422],
00069 [ 10, "GRS 1967", 6378160, 0.006694605],
00070 [ 11, "GRS 1980", 6378137, 0.00669438],
00071 [ 12, "Helmert 1906", 6378200, 0.006693422],
00072 [ 13, "Hough", 6378270, 0.00672267],
00073 [ 14, "International", 6378388, 0.00672267],
00074 [ 15, "Krassovsky", 6378245, 0.006693422],
00075 [ 16, "Modified Airy", 6377340, 0.00667054],
00076 [ 17, "Modified Everest", 6377304, 0.006637847],
00077 [ 18, "Modified Fischer 1960", 6378155, 0.006693422],
00078 [ 19, "South American 1969", 6378160, 0.006694542],
00079 [ 20, "WGS 60", 6378165, 0.006693422],
00080 [ 21, "WGS 66", 6378145, 0.006694542],
00081 [ 22, "WGS-72", 6378135, 0.006694318],
00082 [ 23, "WGS-84", 6378137, 0.00669438]
00083 ]
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 def LLtoUTM(ReferenceEllipsoid, Lat, Long, zone = None):
00099 a = _ellipsoid[ReferenceEllipsoid][_EquatorialRadius]
00100 eccSquared = _ellipsoid[ReferenceEllipsoid][_eccentricitySquared]
00101 k0 = 0.9996
00102
00103
00104 LongTemp = (Long+180)-int((Long+180)/360)*360-180
00105
00106 LatRad = Lat*_deg2rad
00107 LongRad = LongTemp*_deg2rad
00108
00109 if zone is None:
00110 ZoneNumber = int((LongTemp + 180)/6) + 1
00111 else:
00112 ZoneNumber = zone
00113
00114 if Lat >= 56.0 and Lat < 64.0 and LongTemp >= 3.0 and LongTemp < 12.0:
00115 ZoneNumber = 32
00116
00117
00118 if Lat >= 72.0 and Lat < 84.0:
00119 if LongTemp >= 0.0 and LongTemp < 9.0:ZoneNumber = 31
00120 elif LongTemp >= 9.0 and LongTemp < 21.0: ZoneNumber = 33
00121 elif LongTemp >= 21.0 and LongTemp < 33.0: ZoneNumber = 35
00122 elif LongTemp >= 33.0 and LongTemp < 42.0: ZoneNumber = 37
00123
00124 LongOrigin = (ZoneNumber - 1)*6 - 180 + 3
00125 LongOriginRad = LongOrigin * _deg2rad
00126
00127
00128 UTMZone = "%d%c" % (ZoneNumber, _UTMLetterDesignator(Lat))
00129
00130 eccPrimeSquared = (eccSquared)/(1-eccSquared)
00131 N = a/sqrt(1-eccSquared*sin(LatRad)*sin(LatRad))
00132 T = tan(LatRad)*tan(LatRad)
00133 C = eccPrimeSquared*cos(LatRad)*cos(LatRad)
00134 A = cos(LatRad)*(LongRad-LongOriginRad)
00135
00136 M = a*((1
00137 - eccSquared/4
00138 - 3*eccSquared*eccSquared/64
00139 - 5*eccSquared*eccSquared*eccSquared/256)*LatRad
00140 - (3*eccSquared/8
00141 + 3*eccSquared*eccSquared/32
00142 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(2*LatRad)
00143 + (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(4*LatRad)
00144 - (35*eccSquared*eccSquared*eccSquared/3072)*sin(6*LatRad))
00145
00146 UTMEasting = (k0*N*(A+(1-T+C)*A*A*A/6
00147 + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120)
00148 + 500000.0)
00149
00150 UTMNorthing = (k0*(M+N*tan(LatRad)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
00151 + (61
00152 -58*T
00153 +T*T
00154 +600*C
00155 -330*eccPrimeSquared)*A*A*A*A*A*A/720)))
00156
00157 if Lat < 0:
00158 UTMNorthing = UTMNorthing + 10000000.0;
00159 return (UTMZone, UTMEasting, UTMNorthing)
00160
00161
00162 def _UTMLetterDesignator(Lat):
00163 if 84 >= Lat >= 72: return 'X'
00164 elif 72 > Lat >= 64: return 'W'
00165 elif 64 > Lat >= 56: return 'V'
00166 elif 56 > Lat >= 48: return 'U'
00167 elif 48 > Lat >= 40: return 'T'
00168 elif 40 > Lat >= 32: return 'S'
00169 elif 32 > Lat >= 24: return 'R'
00170 elif 24 > Lat >= 16: return 'Q'
00171 elif 16 > Lat >= 8: return 'P'
00172 elif 8 > Lat >= 0: return 'N'
00173 elif 0 > Lat >= -8: return 'M'
00174 elif -8> Lat >= -16: return 'L'
00175 elif -16 > Lat >= -24: return 'K'
00176 elif -24 > Lat >= -32: return 'J'
00177 elif -32 > Lat >= -40: return 'H'
00178 elif -40 > Lat >= -48: return 'G'
00179 elif -48 > Lat >= -56: return 'F'
00180 elif -56 > Lat >= -64: return 'E'
00181 elif -64 > Lat >= -72: return 'D'
00182 elif -72 > Lat >= -80: return 'C'
00183 else: return 'Z'
00184
00185
00186
00187
00188 def UTMtoLL(ReferenceEllipsoid, northing, easting, zone):
00189 k0 = 0.9996
00190 a = _ellipsoid[ReferenceEllipsoid][_EquatorialRadius]
00191 eccSquared = _ellipsoid[ReferenceEllipsoid][_eccentricitySquared]
00192 e1 = (1-sqrt(1-eccSquared))/(1+sqrt(1-eccSquared))
00193
00194
00195 x = easting - 500000.0
00196 y = northing
00197
00198 ZoneLetter = zone[-1]
00199 ZoneNumber = int(zone[:-1])
00200 if ZoneLetter >= 'N':
00201 NorthernHemisphere = 1
00202 else:
00203 NorthernHemisphere = 0
00204 y -= 10000000.0
00205
00206 LongOrigin = (ZoneNumber - 1)*6 - 180 + 3
00207
00208 eccPrimeSquared = (eccSquared)/(1-eccSquared)
00209
00210 M = y / k0
00211 mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256))
00212
00213 phi1Rad = (mu + (3*e1/2-27*e1*e1*e1/32)*sin(2*mu)
00214 + (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu)
00215 +(151*e1*e1*e1/96)*sin(6*mu))
00216 phi1 = phi1Rad*_rad2deg;
00217
00218 N1 = a/sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad))
00219 T1 = tan(phi1Rad)*tan(phi1Rad)
00220 C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad)
00221 R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5)
00222 D = x/(N1*k0)
00223
00224 Lat = phi1Rad - (N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24
00225 +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720)
00226 Lat = Lat * _rad2deg
00227
00228 Long = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)
00229 *D*D*D*D*D/120)/cos(phi1Rad)
00230 Long = LongOrigin + Long * _rad2deg
00231 return (Lat, Long)
00232
00233 if __name__ == '__main__':
00234 (z, e, n) = LLtoUTM(23, 45.00, -75.00)
00235 print z, e, n
00236 print UTMtoLL(23, e, n, z)
00237