--- /dev/null
+/*******************************************************************************\r
+NAME TRANSVERSE MERCATOR\r
+\r
+PURPOSE: Transforms input longitude and latitude to Easting and\r
+ Northing for the Transverse Mercator projection. The\r
+ longitude and latitude must be in radians. The Easting\r
+ and Northing values will be returned in meters.\r
+\r
+ALGORITHM REFERENCES\r
+\r
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological\r
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United\r
+ State Government Printing Office, Washington D.C., 1987.\r
+\r
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",\r
+ U.S. Geological Survey Professional Paper 1453 , United State Government\r
+ Printing Office, Washington D.C., 1989.\r
+*******************************************************************************/\r
+\r
+\r
+/**\r
+ Initialize Transverse Mercator projection\r
+*/\r
+\r
+Proj4js.Proj.tmerc = {\r
+ init : function() {\r
+ this.e0 = Proj4js.common.e0fn(this.es);\r
+ this.e1 = Proj4js.common.e1fn(this.es);\r
+ this.e2 = Proj4js.common.e2fn(this.es);\r
+ this.e3 = Proj4js.common.e3fn(this.es);\r
+ this.ml0 = this.a * Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);\r
+ },\r
+\r
+ /**\r
+ Transverse Mercator Forward - long/lat to x/y\r
+ long/lat in radians\r
+ */\r
+ forward : function(p) {\r
+ var lon = p.x;\r
+ var lat = p.y;\r
+\r
+ var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); // Delta longitude\r
+ var con; // cone constant\r
+ var x, y;\r
+ var sin_phi=Math.sin(lat);\r
+ var cos_phi=Math.cos(lat);\r
+\r
+ if (this.sphere) { /* spherical form */\r
+ var b = cos_phi * Math.sin(delta_lon);\r
+ if ((Math.abs(Math.abs(b) - 1.0)) < .0000000001) {\r
+ Proj4js.reportError("tmerc:forward: Point projects into infinity");\r
+ return(93);\r
+ } else {\r
+ x = .5 * this.a * this.k0 * Math.log((1.0 + b)/(1.0 - b));\r
+ con = Math.acos(cos_phi * Math.cos(delta_lon)/Math.sqrt(1.0 - b*b));\r
+ if (lat < 0) con = - con;\r
+ y = this.a * this.k0 * (con - this.lat0);\r
+ }\r
+ } else {\r
+ var al = cos_phi * delta_lon;\r
+ var als = Math.pow(al,2);\r
+ var c = this.ep2 * Math.pow(cos_phi,2);\r
+ var tq = Math.tan(lat);\r
+ var t = Math.pow(tq,2);\r
+ con = 1.0 - this.es * Math.pow(sin_phi,2);\r
+ var n = this.a / Math.sqrt(con);\r
+ var ml = this.a * Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat);\r
+\r
+ x = this.k0 * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als / 20.0 * (5.0 - 18.0 * t + Math.pow(t,2) + 72.0 * c - 58.0 * this.ep2))) + this.x0;\r
+ y = this.k0 * (ml - this.ml0 + n * tq * (als * (0.5 + als / 24.0 * (5.0 - t + 9.0 * c + 4.0 * Math.pow(c,2) + als / 30.0 * (61.0 - 58.0 * t + Math.pow(t,2) + 600.0 * c - 330.0 * this.ep2))))) + this.y0;\r
+\r
+ }\r
+ p.x = x; p.y = y;\r
+ return p;\r
+ }, // tmercFwd()\r
+\r
+ /**\r
+ Transverse Mercator Inverse - x/y to long/lat\r
+ */\r
+ inverse : function(p) {\r
+ var con, phi; /* temporary angles */\r
+ var delta_phi; /* difference between longitudes */\r
+ var i;\r
+ var max_iter = 6; /* maximun number of iterations */\r
+ var lat, lon;\r
+\r
+ if (this.sphere) { /* spherical form */\r
+ var f = Math.exp(p.x/(this.a * this.k0));\r
+ var g = .5 * (f - 1/f);\r
+ var temp = this.lat0 + p.y/(this.a * this.k0);\r
+ var h = Math.cos(temp);\r
+ con = Math.sqrt((1.0 - h * h)/(1.0 + g * g));\r
+ lat = Proj4js.common.asinz(con);\r
+ if (temp < 0)\r
+ lat = -lat;\r
+ if ((g == 0) && (h == 0)) {\r
+ lon = this.long0;\r
+ } else {\r
+ lon = Proj4js.common.adjust_lon(Math.atan2(g,h) + this.long0);\r
+ }\r
+ } else { // ellipsoidal form\r
+ var x = p.x - this.x0;\r
+ var y = p.y - this.y0;\r
+\r
+ con = (this.ml0 + y / this.k0) / this.a;\r
+ phi = con;\r
+ for (i=0;true;i++) {\r
+ delta_phi=((con + this.e1 * Math.sin(2.0*phi) - this.e2 * Math.sin(4.0*phi) + this.e3 * Math.sin(6.0*phi)) / this.e0) - phi;\r
+ phi += delta_phi;\r
+ if (Math.abs(delta_phi) <= Proj4js.common.EPSLN) break;\r
+ if (i >= max_iter) {\r
+ Proj4js.reportError("tmerc:inverse: Latitude failed to converge");\r
+ return(95);\r
+ }\r
+ } // for()\r
+ if (Math.abs(phi) < Proj4js.common.HALF_PI) {\r
+ // sincos(phi, &sin_phi, &cos_phi);\r
+ var sin_phi=Math.sin(phi);\r
+ var cos_phi=Math.cos(phi);\r
+ var tan_phi = Math.tan(phi);\r
+ var c = this.ep2 * Math.pow(cos_phi,2);\r
+ var cs = Math.pow(c,2);\r
+ var t = Math.pow(tan_phi,2);\r
+ var ts = Math.pow(t,2);\r
+ con = 1.0 - this.es * Math.pow(sin_phi,2);\r
+ var n = this.a / Math.sqrt(con);\r
+ var r = n * (1.0 - this.es) / con;\r
+ var d = x / (n * this.k0);\r
+ var ds = Math.pow(d,2);\r
+ lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t + 10.0 * c - 4.0 * cs - 9.0 * this.ep2 - ds / 30.0 * (61.0 + 90.0 * t + 298.0 * c + 45.0 * ts - 252.0 * this.ep2 - 3.0 * cs)));\r
+ lon = Proj4js.common.adjust_lon(this.long0 + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t + c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * this.ep2 + 24.0 * ts))) / cos_phi));\r
+ } else {\r
+ lat = Proj4js.common.HALF_PI * Proj4js.common.sign(y);\r
+ lon = this.long0;\r
+ }\r
+ }\r
+ p.x = lon;\r
+ p.y = lat;\r
+ return p;\r
+ } // tmercInv()\r
+};
\ No newline at end of file