Understand shapefiles in different projections (notably OSGB)
[potlatch2.git] / com / gradoservice / proj4as / ProjConstants.as
1 package com.gradoservice.proj4as
2 {
3         public class ProjConstants
4         {
5                 
6         static public const PI:Number=3.141592653589793238; //Math.PI,
7         static public const HALF_PI:Number=1.570796326794896619; //Math.PI*0.5,
8     static public const TWO_PI:Number=6.283185307179586477; //Math.PI*2,
9     static public const FORTPI:Number=0.78539816339744833;
10     static public const R2D:Number=57.29577951308232088;
11     static public const D2R:Number=0.01745329251994329577;
12     static public const SEC_TO_RAD:Number=4.84813681109535993589914102357e-6; /* SEC_TO_RAD = Pi/180/3600 */
13     static public const EPSLN:Number=1.0e-10;
14     static public const MAX_ITER:Number=20;
15     // following constants from geocent.c
16     static public const COS_67P5:Number=0.38268343236508977;  /* cosine of 67.5 degrees */
17     static public const AD_C:Number=1.0026000;                /* Toms region 1 constant */
18
19   /* datum_type values */
20    static public const PJD_UNKNOWN:int=0;
21    static public const PJD_3PARAM:int=1;
22    static public const PJD_7PARAM:int=2;
23    static public const PJD_GRIDSHIFT:int=3;
24    static public const PJD_WGS84:int=4;   // WGS84 or equivalent
25    static public const PJD_NODATUM:int=5;   // WGS84 or equivalent
26    static public const SRS_WGS84_SEMIMAJOR:int=6378137;  // only used in grid shift transforms
27
28   // ellipoid pj_set_ell.c
29    static public const SIXTH :Number=0.1666666666666666667; /* 1/6 */
30    static public const RA4:Number=0.04722222222222222222; /* 17/360 */
31    static public const RA6:Number=0.02215608465608465608; /* 67/3024 */
32    static public const RV4:Number=0.06944444444444444444; /* 5/72 */
33    static public const RV6:Number=0.04243827160493827160; /* 55/1296 */
34    
35    
36    
37    static public const PrimeMeridian:Object = {
38     "greenwich": 0.0,               //"0dE",
39     "lisbon":     -9.131906111111,   //"9d07'54.862\"W",
40     "paris":       2.337229166667,   //"2d20'14.025\"E",
41     "bogota":    -74.080916666667,  //"74d04'51.3\"W",
42     "madrid":     -3.687938888889,  //"3d41'16.58\"W",
43     "rome":       12.452333333333,  //"12d27'8.4\"E",
44     "bern":        7.439583333333,  //"7d26'22.5\"E",
45     "jakarta":   106.807719444444,  //"106d48'27.79\"E",
46     "ferro":     -17.666666666667,  //"17d40'W",
47     "brussels":    4.367975,        //"4d22'4.71\"E",
48     "stockholm":  18.058277777778,  //"18d3'29.8\"E",
49     "athens":     23.7163375,       //"23d42'58.815\"E",
50     "oslo":       10.722916666667   //"10d43'22.5\"E"
51         };
52
53   static public const Ellipsoid:Object = {
54   "MERIT": {a:6378137.0, rf:298.257, ellipseName:"MERIT 1983"},
55   "SGS85": {a:6378136.0, rf:298.257, ellipseName:"Soviet Geodetic System 85"},
56   "GRS80": {a:6378137.0, rf:298.257222101, ellipseName:"GRS 1980(IUGG, 1980)"},
57   "IAU76": {a:6378140.0, rf:298.257, ellipseName:"IAU 1976"},
58   "airy": {a:6377563.396, b:6356256.910, ellipseName:"Airy 1830"},
59   "APL4.": {a:6378137, rf:298.25, ellipseName:"Appl. Physics. 1965"},
60   "NWL9D": {a:6378145.0, rf:298.25, ellipseName:"Naval Weapons Lab., 1965"},
61   "mod_airy": {a:6377340.189, b:6356034.446, ellipseName:"Modified Airy"},
62   "andrae": {a:6377104.43, rf:300.0, ellipseName:"Andrae 1876 (Den., Iclnd.)"},
63   "aust_SA": {a:6378160.0, rf:298.25, ellipseName:"Australian Natl & S. Amer. 1969"},
64   "GRS67": {a:6378160.0, rf:298.2471674270, ellipseName:"GRS 67(IUGG 1967)"},
65   "bessel": {a:6377397.155, rf:299.1528128, ellipseName:"Bessel 1841"},
66   "bess_nam": {a:6377483.865, rf:299.1528128, ellipseName:"Bessel 1841 (Namibia)"},
67   "clrk66": {a:6378206.4, b:6356583.8, ellipseName:"Clarke 1866"},
68   "clrk80": {a:6378249.145, rf:293.4663, ellipseName:"Clarke 1880 mod."},
69   "CPM": {a:6375738.7, rf:334.29, ellipseName:"Comm. des Poids et Mesures 1799"},
70   "delmbr": {a:6376428.0, rf:311.5, ellipseName:"Delambre 1810 (Belgium)"},
71   "engelis": {a:6378136.05, rf:298.2566, ellipseName:"Engelis 1985"},
72   "evrst30": {a:6377276.345, rf:300.8017, ellipseName:"Everest 1830"},
73   "evrst48": {a:6377304.063, rf:300.8017, ellipseName:"Everest 1948"},
74   "evrst56": {a:6377301.243, rf:300.8017, ellipseName:"Everest 1956"},
75   "evrst69": {a:6377295.664, rf:300.8017, ellipseName:"Everest 1969"},
76   "evrstSS": {a:6377298.556, rf:300.8017, ellipseName:"Everest (Sabah & Sarawak)"},
77   "fschr60": {a:6378166.0, rf:298.3, ellipseName:"Fischer (Mercury Datum) 1960"},
78   "fschr60m": {a:6378155.0, rf:298.3, ellipseName:"Fischer 1960"},
79   "fschr68": {a:6378150.0, rf:298.3, ellipseName:"Fischer 1968"},
80   "helmert": {a:6378200.0, rf:298.3, ellipseName:"Helmert 1906"},
81   "hough": {a:6378270.0, rf:297.0, ellipseName:"Hough"},
82   "intl": {a:6378388.0, rf:297.0, ellipseName:"International 1909 (Hayford)"},
83   "kaula": {a:6378163.0, rf:298.24, ellipseName:"Kaula 1961"},
84   "lerch": {a:6378139.0, rf:298.257, ellipseName:"Lerch 1979"},
85   "mprts": {a:6397300.0, rf:191.0, ellipseName:"Maupertius 1738"},
86   "new_intl": {a:6378157.5, b:6356772.2, ellipseName:"New International 1967"},
87   "plessis": {a:6376523.0, rf:6355863.0, ellipseName:"Plessis 1817 (France)"},
88   "krass": {a:6378245.0, rf:298.3, ellipseName:"Krassovsky, 1942"},
89   "SEasia": {a:6378155.0, b:6356773.3205, ellipseName:"Southeast Asia"},
90   "walbeck": {a:6376896.0, b:6355834.8467, ellipseName:"Walbeck"},
91   "WGS60": {a:6378165.0, rf:298.3, ellipseName:"WGS 60"},
92   "WGS66": {a:6378145.0, rf:298.25, ellipseName:"WGS 66"},
93   "WGS72": {a:6378135.0, rf:298.26, ellipseName:"WGS 72"},
94   "WGS84": {a:6378137.0, rf:298.257223563, ellipseName:"WGS 84"},
95   "sphere": {a:6370997.0, b:6370997.0, ellipseName:"Normal Sphere (r=6370997)"}
96 };
97
98  static public const Datum:Object = {
99   "WGS84": {towgs84: "0,0,0", ellipse: "WGS84", datumName: "WGS84"},
100   "GGRS87": {towgs84: "-199.87,74.79,246.62", ellipse: "GRS80", datumName: "Greek_Geodetic_Reference_System_1987"},
101   "NAD83": {towgs84: "0,0,0", ellipse: "GRS80", datumName: "North_American_Datum_1983"},
102   "NAD27": {nadgrids: "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat", ellipse: "clrk66", datumName: "North_American_Datum_1927"},
103   "potsdam": {towgs84: "606.0,23.0,413.0", ellipse: "bessel", datumName: "Potsdam Rauenberg 1950 DHDN"},
104   "carthage": {towgs84: "-263.0,6.0,431.0", ellipse: "clark80", datumName: "Carthage 1934 Tunisia"},
105   "hermannskogel": {towgs84: "653.0,-212.0,449.0", ellipse: "bessel", datumName: "Hermannskogel"},
106   "ire65": {towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", ellipse: "mod_airy", datumName: "Ireland 1965"},
107   "nzgd49": {towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993", ellipse: "intl", datumName: "New Zealand Geodetic Datum 1949"},
108   "OSGB36": {towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894", ellipse: "airy", datumName: "Airy 1830"}
109 };
110    
111                 
112                 
113                 public function ProjConstants()
114                 {
115                 }
116                 
117                 
118                 // Function to compute the constant small m which is the radius of
119                 //   a parallel of latitude, phi, divided by the semimajor axis.
120                 // -----------------------------------------------------------------
121                 static public function msfnz (eccent:Number, sinphi:Number, cosphi:Number):Number 
122                 {
123         var con:Number = eccent * sinphi;
124         return cosphi/(Math.sqrt(1.0 - con * con));
125                 }
126
127                 // Function to compute the constant small t for use in the forward
128                 //   computations in the Lambert Conformal Conic and the Polar
129                 //   Stereographic projections.
130                 // -----------------------------------------------------------------
131                 static public function tsfnz(eccent:Number, phi:Number, sinphi:Number):Number 
132                 {
133         var con:Number = eccent * sinphi;
134         var com:Number = 0.5 * eccent;
135         con = Math.pow(((1.0 - con) / (1.0 + con)), com);
136         return (Math.tan(0.5 * (ProjConstants.HALF_PI - phi))/con);
137                 }
138
139                 // Function to compute the latitude angle, phi2, for the inverse of the
140                 //   Lambert Conformal Conic and Polar Stereographic projections.
141                 // ----------------------------------------------------------------
142                 static public function phi2z(eccent:Number, ts:Number):Number 
143                 {
144                     var eccnth:Number = .5 * eccent;
145                     var con:Number =0;
146                     var dphi:Number =0;
147                     var phi:Number = ProjConstants.HALF_PI - 2 * Math.atan(ts);
148                     for (var i:int = 0; i <= 15; i++) {
149                       con = eccent * Math.sin(phi);
150                       dphi = ProjConstants.HALF_PI - 2 * Math.atan(ts *(Math.pow(((1.0 - con)/(1.0 + con)),eccnth))) - phi;
151                       phi += dphi;
152                       if (Math.abs(dphi) <= .0000000001) return phi;
153                     }
154                     trace("phi2z has NoConvergence");
155                     return -9999;
156                 }
157
158                 /* Function to compute constant small q which is the radius of a 
159                    parallel of latitude, phi, divided by the semimajor axis. 
160                 ------------------------------------------------------------*/
161                   static public function qsfnz(eccent:Number,sinphi:Number,cosphi:Number):Number 
162                   {
163                     var con:Number = 0;
164                     if (eccent > 1.0e-7) {
165                       con = eccent * sinphi;
166                       return (( 1.0- eccent * eccent) * (sinphi /(1.0 - con * con) - (.5/eccent)*Math.log((1.0 - con)/(1.0 + con))));
167                     } else {
168                       return 2.0 * sinphi;
169                     }
170                   }
171
172                 /* Function to eliminate roundoff errors in asin
173                 ----------------------------------------------*/
174                   static public function asinz(x:Number):Number 
175                   {
176                     if (Math.abs(x)>1.0) {
177                       x=(x>1.0)?1.0:-1.0;
178                     }
179                     return Math.asin(x);
180                   }
181
182                 // following functions from gctpc cproj.c for transverse mercator projections
183                 static public function e0fn(x:Number):Number {return(1.0-0.25*x*(1.0+x/16.0*(3.0+1.25*x)));}
184                 static public function e1fn(x:Number):Number {return(0.375*x*(1.0+0.25*x*(1.0+0.46875*x)));}
185                 static public function e2fn(x:Number):Number {return(0.05859375*x*x*(1.0+0.75*x));}
186                 static public function e3fn(x:Number):Number {return(x*x*x*(35.0/3072.0));}
187                 static public function mlfn(e0:Number,e1:Number,e2:Number,e3:Number,phi:Number):Number {return(e0*phi-e1*Math.sin(2.0*phi)+e2*Math.sin(4.0*phi)-e3*Math.sin(6.0*phi));}
188
189                 static public function srat(esinp:Number, exp:Number):Number 
190                 {
191                 return(Math.pow((1.0-esinp)/(1.0+esinp), exp));
192                 }
193
194 // Function to return the sign of an argument
195   static public function sign(x:Number):Number { if (x < 0.0) return(-1); else return(1);}
196
197 // Function to adjust longitude to -180 to 180; input in radians
198   static public function adjust_lon(x:Number):Number {
199     x = (Math.abs(x) < ProjConstants.PI) ? x: (x - (ProjConstants.sign(x)*ProjConstants.TWO_PI) );
200     return x;
201   }
202
203 // IGNF - DGR : algorithms used by IGN France
204
205 // Function to adjust latitude to -90 to 90; input in radians
206   static public function adjust_lat(x:Number):Number {
207     x= (Math.abs(x) < ProjConstants.HALF_PI) ? x: (x - (ProjConstants.sign(x)*ProjConstants.PI) );
208     return x;
209   }
210
211 // Latitude Isometrique - close to tsfnz ...
212   static public function latiso(eccent:Number, phi:Number, sinphi:Number):Number
213   {
214     if (Math.abs(phi) > ProjConstants.HALF_PI) return +Number.NaN;
215     if (phi==ProjConstants.HALF_PI) return Number.POSITIVE_INFINITY;
216     if (phi==-1.0*ProjConstants.HALF_PI) return -1.0*Number.POSITIVE_INFINITY;
217
218     var con:Number= eccent*sinphi;
219     return Math.log(Math.tan((ProjConstants.HALF_PI+phi)/2.0))+eccent*Math.log((1.0-con)/(1.0+con))/2.0;
220   }
221
222   static public function fL(x:Number,L:Number):Number {
223     return 2.0*Math.atan(x*Math.exp(L)) - ProjConstants.HALF_PI;
224   }
225
226 // Inverse Latitude Isometrique - close to ph2z
227   static public function invlatiso(eccent:Number, ts:Number):Number {
228     var phi:Number= ProjConstants.fL(1.0,ts);
229     var Iphi:Number= 0.0;
230     var con:Number= 0.0;
231     do {
232       Iphi= phi;
233       con= eccent*Math.sin(Iphi);
234       phi= ProjConstants.fL(Math.exp(eccent*Math.log((1.0+con)/(1.0-con))/2.0),ts)
235     } while (Math.abs(phi-Iphi)>1.0e-12);
236     return phi;
237   }
238
239 // Needed for Gauss Laborde
240 // Original:  Denis Makarov (info@binarythings.com)
241 // Web Site:  http://www.binarythings.com
242   static public function sinh(x:Number):Number
243   {
244     var r:Number= Math.exp(x);
245     r= (r-1.0/r)/2.0;
246     return r;
247   }
248
249   static public function cosh(x:Number):Number
250   {
251     var r:Number= Math.exp(x);
252     r= (r+1.0/r)/2.0;
253     return r;
254   }
255
256   static public function tanh(x:Number):Number
257   {
258     var r:Number= Math.exp(x);
259     r= (r-1.0/r)/(r+1.0/r);
260     return r;
261   }
262
263  static public function  asinh(x:Number):Number
264   {
265     var s:Number= (x>= 0? 1.0:-1.0);
266     return s*(Math.log( Math.abs(x) + Math.sqrt(x*x+1.0) ));
267   }
268
269  static public function  acosh(x:Number):Number
270   {
271     return 2.0*Math.log(Math.sqrt((x+1.0)/2.0) + Math.sqrt((x-1.0)/2.0));
272   }
273
274  static public function  atanh(x:Number):Number
275   {
276     return Math.log((x-1.0)/(x+1.0))/2.0;
277   }
278
279 // Grande Normale
280  static public function  gN(a:Number,e:Number,sinphi:Number):Number
281   {
282     var temp:Number= e*sinphi;
283     return a/Math.sqrt(1.0 - temp*temp);
284   }
285                 
286
287         }
288 }