[76] | 1 | /******************************************************************************* |
---|
| 2 | NAME VAN DER GRINTEN |
---|
| 3 | |
---|
| 4 | PURPOSE: Transforms input Easting and Northing to longitude and |
---|
| 5 | latitude for the Van der Grinten projection. The |
---|
| 6 | Easting and Northing must be in meters. The longitude |
---|
| 7 | and latitude values will be returned in radians. |
---|
| 8 | |
---|
| 9 | PROGRAMMER DATE |
---|
| 10 | ---------- ---- |
---|
| 11 | T. Mittan March, 1993 |
---|
| 12 | |
---|
| 13 | This function was adapted from the Van Der Grinten projection code |
---|
| 14 | (FORTRAN) in the General Cartographic Transformation Package software |
---|
| 15 | which is available from the U.S. Geological Survey National Mapping Division. |
---|
| 16 | |
---|
| 17 | ALGORITHM REFERENCES |
---|
| 18 | |
---|
| 19 | 1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, |
---|
| 20 | The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. |
---|
| 21 | |
---|
| 22 | 2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological |
---|
| 23 | Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United |
---|
| 24 | State Government Printing Office, Washington D.C., 1987. |
---|
| 25 | |
---|
| 26 | 3. "Software Documentation for GCTP General Cartographic Transformation |
---|
| 27 | Package", U.S. Geological Survey National Mapping Division, May 1982. |
---|
| 28 | *******************************************************************************/ |
---|
| 29 | |
---|
| 30 | Proj4js.Proj.vandg = { |
---|
| 31 | |
---|
| 32 | /* Initialize the Van Der Grinten projection |
---|
| 33 | ----------------------------------------*/ |
---|
| 34 | init: function() { |
---|
| 35 | this.R = 6370997.0; //Radius of earth |
---|
| 36 | }, |
---|
| 37 | |
---|
| 38 | forward: function(p) { |
---|
| 39 | |
---|
| 40 | var lon=p.x; |
---|
| 41 | var lat=p.y; |
---|
| 42 | |
---|
| 43 | /* Forward equations |
---|
| 44 | -----------------*/ |
---|
| 45 | var dlon = Proj4js.common.adjust_lon(lon - this.long0); |
---|
| 46 | var x,y; |
---|
| 47 | |
---|
| 48 | if (Math.abs(lat) <= Proj4js.common.EPSLN) { |
---|
| 49 | x = this.x0 + this.R * dlon; |
---|
| 50 | y = this.y0; |
---|
| 51 | } |
---|
| 52 | var theta = Proj4js.common.asinz(2.0 * Math.abs(lat / Proj4js.common.PI)); |
---|
| 53 | if ((Math.abs(dlon) <= Proj4js.common.EPSLN) || (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN)) { |
---|
| 54 | x = this.x0; |
---|
| 55 | if (lat >= 0) { |
---|
| 56 | y = this.y0 + Proj4js.common.PI * this.R * Math.tan(.5 * theta); |
---|
| 57 | } else { |
---|
| 58 | y = this.y0 + Proj4js.common.PI * this.R * - Math.tan(.5 * theta); |
---|
| 59 | } |
---|
| 60 | // return(OK); |
---|
| 61 | } |
---|
| 62 | var al = .5 * Math.abs((Proj4js.common.PI / dlon) - (dlon / Proj4js.common.PI)); |
---|
| 63 | var asq = al * al; |
---|
| 64 | var sinth = Math.sin(theta); |
---|
| 65 | var costh = Math.cos(theta); |
---|
| 66 | |
---|
| 67 | var g = costh / (sinth + costh - 1.0); |
---|
| 68 | var gsq = g * g; |
---|
| 69 | var m = g * (2.0 / sinth - 1.0); |
---|
| 70 | var msq = m * m; |
---|
| 71 | var con = Proj4js.common.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq); |
---|
| 72 | if (dlon < 0) { |
---|
| 73 | con = -con; |
---|
| 74 | } |
---|
| 75 | x = this.x0 + con; |
---|
| 76 | con = Math.abs(con / (Proj4js.common.PI * this.R)); |
---|
| 77 | if (lat >= 0) { |
---|
| 78 | y = this.y0 + Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con); |
---|
| 79 | } else { |
---|
| 80 | y = this.y0 - Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con); |
---|
| 81 | } |
---|
| 82 | p.x = x; |
---|
| 83 | p.y = y; |
---|
| 84 | return p; |
---|
| 85 | }, |
---|
| 86 | |
---|
| 87 | /* Van Der Grinten inverse equations--mapping x,y to lat/long |
---|
| 88 | ---------------------------------------------------------*/ |
---|
| 89 | inverse: function(p) { |
---|
| 90 | var dlon; |
---|
| 91 | var xx,yy,xys,c1,c2,c3; |
---|
| 92 | var al,asq; |
---|
| 93 | var a1; |
---|
| 94 | var m1; |
---|
| 95 | var con; |
---|
| 96 | var th1; |
---|
| 97 | var d; |
---|
| 98 | |
---|
| 99 | /* inverse equations |
---|
| 100 | -----------------*/ |
---|
| 101 | p.x -= this.x0; |
---|
| 102 | p.y -= this.y0; |
---|
| 103 | con = Proj4js.common.PI * this.R; |
---|
| 104 | xx = p.x / con; |
---|
| 105 | yy =p.y / con; |
---|
| 106 | xys = xx * xx + yy * yy; |
---|
| 107 | c1 = -Math.abs(yy) * (1.0 + xys); |
---|
| 108 | c2 = c1 - 2.0 * yy * yy + xx * xx; |
---|
| 109 | c3 = -2.0 * c1 + 1.0 + 2.0 * yy * yy + xys * xys; |
---|
| 110 | d = yy * yy / c3 + (2.0 * c2 * c2 * c2 / c3 / c3 / c3 - 9.0 * c1 * c2 / c3 /c3) / 27.0; |
---|
| 111 | a1 = (c1 - c2 * c2 / 3.0 / c3) / c3; |
---|
| 112 | m1 = 2.0 * Math.sqrt( -a1 / 3.0); |
---|
| 113 | con = ((3.0 * d) / a1) / m1; |
---|
| 114 | if (Math.abs(con) > 1.0) { |
---|
| 115 | if (con >= 0.0) { |
---|
| 116 | con = 1.0; |
---|
| 117 | } else { |
---|
| 118 | con = -1.0; |
---|
| 119 | } |
---|
| 120 | } |
---|
| 121 | th1 = Math.acos(con) / 3.0; |
---|
| 122 | if (p.y >= 0) { |
---|
| 123 | lat = (-m1 *Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI; |
---|
| 124 | } else { |
---|
| 125 | lat = -(-m1 * Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI; |
---|
| 126 | } |
---|
| 127 | |
---|
| 128 | if (Math.abs(xx) < Proj4js.common.EPSLN) { |
---|
| 129 | lon = this.long0; |
---|
| 130 | } |
---|
| 131 | lon = Proj4js.common.adjust_lon(this.long0 + Proj4js.common.PI * (xys - 1.0 + Math.sqrt(1.0 + 2.0 * (xx * xx - yy * yy) + xys * xys)) / 2.0 / xx); |
---|
| 132 | |
---|
| 133 | p.x=lon; |
---|
| 134 | p.y=lat; |
---|
| 135 | return p; |
---|
| 136 | } |
---|
| 137 | }; |
---|