[76] | 1 | /******************************************************************************* |
---|
| 2 | NAME CASSINI |
---|
| 3 | |
---|
| 4 | PURPOSE: Transforms input longitude and latitude to Easting and |
---|
| 5 | Northing for the Cassini projection. The |
---|
| 6 | longitude and latitude must be in radians. The Easting |
---|
| 7 | and Northing values will be returned in meters. |
---|
| 8 | Ported from PROJ.4. |
---|
| 9 | |
---|
| 10 | |
---|
| 11 | ALGORITHM REFERENCES |
---|
| 12 | |
---|
| 13 | 1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological |
---|
| 14 | Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United |
---|
| 15 | State Government Printing Office, Washington D.C., 1987. |
---|
| 16 | |
---|
| 17 | 2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", |
---|
| 18 | U.S. Geological Survey Professional Paper 1453 , United State Government |
---|
| 19 | *******************************************************************************/ |
---|
| 20 | |
---|
| 21 | |
---|
| 22 | //Proj4js.defs["EPSG:28191"] = "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m +no_defs"; |
---|
| 23 | |
---|
| 24 | // Initialize the Cassini projection |
---|
| 25 | // ----------------------------------------------------------------- |
---|
| 26 | |
---|
| 27 | Proj4js.Proj.cass = { |
---|
| 28 | init : function() { |
---|
| 29 | if (!this.sphere) { |
---|
| 30 | this.en = this.pj_enfn(this.es) |
---|
| 31 | this.m0 = this.pj_mlfn(this.lat0, Math.sin(this.lat0), Math.cos(this.lat0), this.en); |
---|
| 32 | } |
---|
| 33 | }, |
---|
| 34 | |
---|
| 35 | C1: .16666666666666666666, |
---|
| 36 | C2: .00833333333333333333, |
---|
| 37 | C3: .04166666666666666666, |
---|
| 38 | C4: .33333333333333333333, |
---|
| 39 | C5: .06666666666666666666, |
---|
| 40 | |
---|
| 41 | |
---|
| 42 | /* Cassini forward equations--mapping lat,long to x,y |
---|
| 43 | -----------------------------------------------------------------------*/ |
---|
| 44 | forward: function(p) { |
---|
| 45 | |
---|
| 46 | /* Forward equations |
---|
| 47 | -----------------*/ |
---|
| 48 | var x,y; |
---|
| 49 | var lam=p.x; |
---|
| 50 | var phi=p.y; |
---|
| 51 | lam = Proj4js.common.adjust_lon(lam - this.long0); |
---|
| 52 | |
---|
| 53 | if (this.sphere) { |
---|
| 54 | x = Math.asin(Math.cos(phi) * Math.sin(lam)); |
---|
| 55 | y = Math.atan2(Math.tan(phi) , Math.cos(lam)) - this.phi0; |
---|
| 56 | } else { |
---|
| 57 | //ellipsoid |
---|
| 58 | this.n = Math.sin(phi); |
---|
| 59 | this.c = Math.cos(phi); |
---|
| 60 | y = this.pj_mlfn(phi, this.n, this.c, this.en); |
---|
| 61 | this.n = 1./Math.sqrt(1. - this.es * this.n * this.n); |
---|
| 62 | this.tn = Math.tan(phi); |
---|
| 63 | this.t = this.tn * this.tn; |
---|
| 64 | this.a1 = lam * this.c; |
---|
| 65 | this.c *= this.es * this.c / (1 - this.es); |
---|
| 66 | this.a2 = this.a1 * this.a1; |
---|
| 67 | x = this.n * this.a1 * (1. - this.a2 * this.t * (this.C1 - (8. - this.t + 8. * this.c) * this.a2 * this.C2)); |
---|
| 68 | y -= this.m0 - this.n * this.tn * this.a2 * (.5 + (5. - this.t + 6. * this.c) * this.a2 * this.C3); |
---|
| 69 | } |
---|
| 70 | |
---|
| 71 | p.x = this.a*x + this.x0; |
---|
| 72 | p.y = this.a*y + this.y0; |
---|
| 73 | return p; |
---|
| 74 | },//cassFwd() |
---|
| 75 | |
---|
| 76 | /* Inverse equations |
---|
| 77 | -----------------*/ |
---|
| 78 | inverse: function(p) { |
---|
| 79 | p.x -= this.x0; |
---|
| 80 | p.y -= this.y0; |
---|
| 81 | var x = p.x/this.a; |
---|
| 82 | var y = p.y/this.a; |
---|
| 83 | |
---|
| 84 | if (this.sphere) { |
---|
| 85 | this.dd = y + this.lat0; |
---|
| 86 | phi = Math.asin(Math.sin(this.dd) * Math.cos(x)); |
---|
| 87 | lam = Math.atan2(Math.tan(x), Math.cos(this.dd)); |
---|
| 88 | } else { |
---|
| 89 | /* ellipsoid */ |
---|
| 90 | ph1 = this.pj_inv_mlfn(this.m0 + y, this.es, this.en); |
---|
| 91 | this.tn = Math.tan(ph1); |
---|
| 92 | this.t = this.tn * this.tn; |
---|
| 93 | this.n = Math.sin(ph1); |
---|
| 94 | this.r = 1. / (1. - this.es * this.n * this.n); |
---|
| 95 | this.n = Math.sqrt(this.r); |
---|
| 96 | this.r *= (1. - this.es) * this.n; |
---|
| 97 | this.dd = x / this.n; |
---|
| 98 | this.d2 = this.dd * this.dd; |
---|
| 99 | phi = ph1 - (this.n * this.tn / this.r) * this.d2 * (.5 - (1. + 3. * this.t) * this.d2 * this.C3); |
---|
| 100 | lam = this.dd * (1. + this.t * this.d2 * (-this.C4 + (1. + 3. * this.t) * this.d2 * this.C5)) / Math.cos(ph1); |
---|
| 101 | } |
---|
| 102 | p.x = Proj4js.common.adjust_lon(this.long0+lam); |
---|
| 103 | p.y = phi; |
---|
| 104 | return p; |
---|
| 105 | },//lamazInv() |
---|
| 106 | |
---|
| 107 | |
---|
| 108 | //code from the PROJ.4 pj_mlfn.c file; this may be useful for other projections |
---|
| 109 | pj_enfn: function(es) { |
---|
| 110 | en = new Array(); |
---|
| 111 | en[0] = this.C00 - es * (this.C02 + es * (this.C04 + es * (this.C06 + es * this.C08))); |
---|
| 112 | en[1] = es * (this.C22 - es * (this.C04 + es * (this.C06 + es * this.C08))); |
---|
| 113 | var t = es * es; |
---|
| 114 | en[2] = t * (this.C44 - es * (this.C46 + es * this.C48)); |
---|
| 115 | t *= es; |
---|
| 116 | en[3] = t * (this.C66 - es * this.C68); |
---|
| 117 | en[4] = t * es * this.C88; |
---|
| 118 | return en; |
---|
| 119 | }, |
---|
| 120 | |
---|
| 121 | pj_mlfn: function(phi, sphi, cphi, en) { |
---|
| 122 | cphi *= sphi; |
---|
| 123 | sphi *= sphi; |
---|
| 124 | return(en[0] * phi - cphi * (en[1] + sphi*(en[2]+ sphi*(en[3] + sphi*en[4])))); |
---|
| 125 | }, |
---|
| 126 | |
---|
| 127 | pj_inv_mlfn: function(arg, es, en) { |
---|
| 128 | k = 1./(1.-es); |
---|
| 129 | phi = arg; |
---|
| 130 | for (i = Proj4js.common.MAX_ITER; i ; --i) { /* rarely goes over 2 iterations */ |
---|
| 131 | s = Math.sin(phi); |
---|
| 132 | t = 1. - es * s * s; |
---|
| 133 | //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg; |
---|
| 134 | //phi -= t * (t * Math.sqrt(t)) * k; |
---|
| 135 | t = (this.pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k; |
---|
| 136 | phi -= t; |
---|
| 137 | if (Math.abs(t) < Proj4js.common.EPSLN) |
---|
| 138 | return phi; |
---|
| 139 | } |
---|
| 140 | Proj4js.reportError("cass:pj_inv_mlfn: Convergence error"); |
---|
| 141 | return phi; |
---|
| 142 | }, |
---|
| 143 | |
---|
| 144 | /* meridinal distance for ellipsoid and inverse |
---|
| 145 | ** 8th degree - accurate to < 1e-5 meters when used in conjuction |
---|
| 146 | ** with typical major axis values. |
---|
| 147 | ** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds. |
---|
| 148 | */ |
---|
| 149 | C00: 1.0, |
---|
| 150 | C02: .25, |
---|
| 151 | C04: .046875, |
---|
| 152 | C06: .01953125, |
---|
| 153 | C08: .01068115234375, |
---|
| 154 | C22: .75, |
---|
| 155 | C44: .46875, |
---|
| 156 | C46: .01302083333333333333, |
---|
| 157 | C48: .00712076822916666666, |
---|
| 158 | C66: .36458333333333333333, |
---|
| 159 | C68: .00569661458333333333, |
---|
| 160 | C88: .3076171875 |
---|
| 161 | |
---|
| 162 | } |
---|