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 | } |
---|