Understand shapefiles in different projections (notably OSGB)
authorRichard Fairhurst <richard@systemeD.net>
Fri, 10 Jun 2011 08:18:44 +0000 (09:18 +0100)
committerRichard Fairhurst <richard@systemeD.net>
Fri, 10 Jun 2011 08:18:44 +0000 (09:18 +0100)
34 files changed:
com/gradoservice/proj4as/Datum.as [new file with mode: 0755]
com/gradoservice/proj4as/LICENCE.txt [new file with mode: 0755]
com/gradoservice/proj4as/Proj4as.as [new file with mode: 0755]
com/gradoservice/proj4as/ProjConstants.as [new file with mode: 0755]
com/gradoservice/proj4as/ProjPoint.as [new file with mode: 0755]
com/gradoservice/proj4as/ProjProjection.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/AbstractProjProjection.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/IProjection.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjAea.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjAeqd.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjEqc.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjEqdc.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjEqui.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjGauss.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjGstmerc.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjLaea.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjLcc.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjLonglat.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjMerc.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjMill.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjMoll.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjNzmg.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjOmerc.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjOrtho.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjParams.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjSinu.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjSoMerc.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjStere.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjSterea.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjTmerc.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjUtm.as [new file with mode: 0755]
com/gradoservice/proj4as/proj/ProjVandg.as [new file with mode: 0755]
net/systemeD/potlatch2/VectorSourceDialog.mxml
net/systemeD/potlatch2/utils/ShpImporter.as

diff --git a/com/gradoservice/proj4as/Datum.as b/com/gradoservice/proj4as/Datum.as
new file mode 100755 (executable)
index 0000000..0632a67
--- /dev/null
@@ -0,0 +1,413 @@
+package com.gradoservice.proj4as\r
+{\r
+       import com.gradoservice.proj4as.proj.AbstractProjProjection;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       \r
+       public class Datum\r
+       {\r
+               public var datum_type:int;\r
+               public var a:Number;\r
+               public var b:Number;                            \r
+               public var es:Number;           \r
+               public var ep2:Number;\r
+               public var datum_params:Array;\r
+               public var params:Array;                \r
+               \r
+               public function Datum(proj:ProjProjection)\r
+               {\r
+               this.datum_type = ProjConstants.PJD_WGS84;   //default setting\r
+       if (proj.datumCode && proj.datumCode == 'none') \r
+               {\r
+               this.datum_type = ProjConstants.PJD_NODATUM;\r
+               }\r
+       if (proj && proj.datum_params) \r
+               {\r
+               for (var i:int=0; i<proj.datum_params.length; i++) \r
+                       {\r
+                       proj.datum_params[i]=parseFloat(proj.datum_params[i]);\r
+                       }\r
+               if (proj.datum_params[0] != 0 || proj.datum_params[1] != 0 || proj.datum_params[2] != 0 ) \r
+                       {\r
+                       this.datum_type = ProjConstants.PJD_3PARAM;\r
+                       }\r
+               if (proj.datum_params.length > 3) \r
+                       {\r
+                       if (proj.datum_params[3] != 0 || proj.datum_params[4] != 0 ||\r
+                       proj.datum_params[5] != 0 || proj.datum_params[6] != 0 ) \r
+                       {\r
+                               this.datum_type = ProjConstants.PJD_7PARAM;\r
+                               proj.datum_params[3] *= ProjConstants.SEC_TO_RAD;\r
+                               proj.datum_params[4] *= ProjConstants.SEC_TO_RAD;\r
+                               proj.datum_params[5] *= ProjConstants.SEC_TO_RAD;\r
+                               proj.datum_params[6] = (proj.datum_params[6]/1000000.0) + 1.0;\r
+                               }\r
+                       }\r
+               }\r
+       if (proj) \r
+               {\r
+               this.a = proj.a;    //datum object also uses these values\r
+               this.b = proj.b;\r
+               this.es = proj.es;\r
+               this.ep2 = proj.ep2;\r
+               this.datum_params = proj.datum_params;\r
+               }                       \r
+               }\r
+               \r
+        /****************************************************************/\r
+        // cs_compare_datums()\r
+        //   Returns 1 (TRUE) if the two datums match, otherwise 0 (FALSE).\r
+       public function compare_datums( dest:Datum ):Boolean \r
+               {\r
+       if( this.datum_type != dest.datum_type ) \r
+       {\r
+       return false; // false, datums are not equal\r
+       } \r
+       else if( this.a != dest.a || Math.abs(this.es-dest.es) > 0.000000000050 ) \r
+               {\r
+               // the tolerence for es is to ensure that GRS80 and WGS84\r
+               // are considered identical\r
+               return false;\r
+               } \r
+               else if( this.datum_type == ProjConstants.PJD_3PARAM ) \r
+               {\r
+               return (this.datum_params[0] == dest.datum_params[0]\r
+              && this.datum_params[1] == dest.datum_params[1]\r
+              && this.datum_params[2] == dest.datum_params[2]);\r
+                 } else if( this.datum_type == ProjConstants.PJD_7PARAM ) \r
+                               {\r
+                               return (this.datum_params[0] == dest.datum_params[0]\r
+                               && this.datum_params[1] == dest.datum_params[1]\r
+                               && this.datum_params[2] == dest.datum_params[2]\r
+                               && this.datum_params[3] == dest.datum_params[3]\r
+                               && this.datum_params[4] == dest.datum_params[4]\r
+                               && this.datum_params[5] == dest.datum_params[5]\r
+                               && this.datum_params[6] == dest.datum_params[6]);\r
+                               } \r
+                               else if( this.datum_type == ProjConstants.PJD_GRIDSHIFT ) \r
+                                       {\r
+                                       /*return strcmp( pj_param(this.params,"snadgrids").s,\r
+                                       pj_param(dest.params,"snadgrids").s ) == 0; */\r
+                                       return false;\r
+                                       } else \r
+                                       {\r
+                                       return true; // datums are equal\r
+                                       }\r
+       } // cs_compare_datums()\r
+               \r
+\r
+       public function geodetic_to_geocentric(p:ProjPoint):int \r
+               {\r
+       var Longitude:Number = p.x;\r
+       var Latitude:Number = p.y;\r
+       var Height:Number = p.z ? p.z : 0;   //Z value not always supplied\r
+       var X:Number;  // output\r
+       var Y:Number;\r
+       var Z:Number;\r
+\r
+       var Error_Code:int=0;  //  GEOCENT_NO_ERROR;\r
+       var Rn:Number;            /*  Earth radius at location  */\r
+               var Sin_Lat:Number;       /*  Math.sin(Latitude)  */\r
+       var Sin2_Lat:Number;      /*  Square of Math.sin(Latitude)  */\r
+       var Cos_Lat:Number;       /*  Math.cos(Latitude)  */\r
+\r
+           /*\r
+           ** Don't blow up if Latitude is just a little out of the value\r
+           ** range as it may just be a rounding issue.  Also removed longitude\r
+           ** test, it should be wrapped by Math.cos() and Math.sin().  NFW for PROJ.4, Sep/2001.\r
+           */\r
+    if( Latitude < -ProjConstants.HALF_PI && Latitude > -1.001 *ProjConstants.HALF_PI ) {\r
+        Latitude = -ProjConstants.HALF_PI;\r
+    } else if( Latitude > ProjConstants.HALF_PI && Latitude < 1.001 * ProjConstants.HALF_PI ) {\r
+        Latitude = ProjConstants.HALF_PI;\r
+    } else if ((Latitude < -ProjConstants.HALF_PI) || (Latitude > ProjConstants.HALF_PI)) {\r
+      /* Latitude out of range */\r
+      trace('geocent:lat out of range:'+Latitude);\r
+      return 0;\r
+    }\r
+\r
+    if (Longitude > ProjConstants.PI) {Longitude -= (2*ProjConstants.PI);}\r
+    Sin_Lat = Math.sin(Latitude);\r
+    Cos_Lat = Math.cos(Latitude);\r
+    Sin2_Lat = Sin_Lat * Sin_Lat;\r
+    Rn = this.a / (Math.sqrt(1.0e0 - this.es * Sin2_Lat));\r
+    X = (Rn + Height) * Cos_Lat * Math.cos(Longitude);\r
+    Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude);\r
+    Z = ((Rn * (1 - this.es)) + Height) * Sin_Lat;\r
+\r
+    p.x = X;\r
+    p.y = Y;\r
+    p.z = Z;\r
+    return Error_Code;\r
+       } // cs_geodetic_to_geocentric()\r
+\r
+\r
+  public function geocentric_to_geodetic(p:ProjPoint):ProjPoint\r
+  {\r
+       /* local defintions and variables */\r
+       /* end-criterium of loop, accuracy of sin(Latitude) */\r
+       var genau:Number = 1.E-12;\r
+       var genau2:Number = (genau*genau);\r
+       var maxiter:int = 30;\r
+\r
+    var P:Number;        /* distance between semi-minor axis and location */\r
+    var RR:Number;       /* distance between center and location */\r
+    var CT:Number;       /* sin of geocentric latitude */\r
+    var ST:Number;       /* cos of geocentric latitude */\r
+    var RX:Number;\r
+    var RK:Number;\r
+    var RN:Number;       /* Earth radius at location */\r
+    var CPHI0:Number;    /* cos of start or old geodetic latitude in iterations */\r
+    var SPHI0:Number;    /* sin of start or old geodetic latitude in iterations */\r
+    var CPHI:Number;     /* cos of searched geodetic latitude */\r
+    var SPHI:Number;     /* sin of searched geodetic latitude */\r
+    var SDPHI:Number;    /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */\r
+    var At_Pole:Boolean;     /* indicates location is in polar region */\r
+    var iter:Number;        /* # of continous iteration, max. 30 is always enough (s.a.) */\r
+\r
+    var X:Number = p.x;\r
+    var Y:Number = p.y;\r
+    var Z:Number = p.z ? p.z : 0.0;   //Z value not always supplied\r
+    var Longitude:Number;\r
+    var Latitude:Number;\r
+    var Height:Number;\r
+\r
+    At_Pole = false;\r
+    P = Math.sqrt(X*X+Y*Y);\r
+    RR = Math.sqrt(X*X+Y*Y+Z*Z);\r
+\r
+/*      special cases for latitude and longitude */\r
+    if (P/this.a < genau) \r
+       {\r
+               /*  special case, if P=0. (X=0., Y=0.) */\r
+        At_Pole = true;\r
+        Longitude = 0.0;\r
+/*  if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis\r
+ *  of ellipsoid (=center of mass), Latitude becomes PI/2 */\r
+        if (RR/this.a < genau) {\r
+            Latitude = ProjConstants.HALF_PI;\r
+            Height   = -this.b;\r
+            return null;\r
+        }\r
+    } else {\r
+/*  ellipsoidal (geodetic) longitude\r
+ *  interval: -PI < Longitude <= +PI */\r
+        Longitude=Math.atan2(Y,X);\r
+    }\r
+\r
+/* --------------------------------------------------------------\r
+ * Following iterative algorithm was developped by\r
+ * "Institut fьr Erdmessung", University of Hannover, July 1988.\r
+ * Internet: www.ife.uni-hannover.de\r
+ * Iterative computation of CPHI,SPHI and Height.\r
+ * Iteration of CPHI and SPHI to 10**-12 radian resp.\r
+ * 2*10**-7 arcsec.\r
+ * --------------------------------------------------------------\r
+ */\r
+    CT = Z/RR;\r
+    ST = P/RR;\r
+    RX = 1.0/Math.sqrt(1.0-this.es*(2.0-this.es)*ST*ST);\r
+    CPHI0 = ST*(1.0-this.es)*RX;\r
+    SPHI0 = CT*RX;\r
+    iter = 0;\r
+\r
+/* loop to find sin(Latitude) resp. Latitude\r
+ * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */\r
+    do\r
+    {\r
+        iter++;\r
+        RN = this.a/Math.sqrt(1.0-this.es*SPHI0*SPHI0);\r
+\r
+/*  ellipsoidal (geodetic) height */\r
+        Height = P*CPHI0+Z*SPHI0-RN*(1.0-this.es*SPHI0*SPHI0);\r
+\r
+        RK = this.es*RN/(RN+Height);\r
+        RX = 1.0/Math.sqrt(1.0-RK*(2.0-RK)*ST*ST);\r
+        CPHI = ST*(1.0-RK)*RX;\r
+        SPHI = CT*RX;\r
+        SDPHI = SPHI*CPHI0-CPHI*SPHI0;\r
+        CPHI0 = CPHI;\r
+        SPHI0 = SPHI;\r
+    }\r
+    while (SDPHI*SDPHI > genau2 && iter < maxiter);\r
+\r
+/*      ellipsoidal (geodetic) latitude */\r
+    Latitude=Math.atan(SPHI/Math.abs(CPHI));\r
+\r
+    p.x = Longitude;\r
+    p.y = Latitude;\r
+    p.z = Height;\r
+    return p;\r
+  } // cs_geocentric_to_geodetic()\r
+  \r
+  \r
+  public function geocentric_to_geodetic_noniter(p:ProjPoint):ProjPoint \r
+  {\r
+    var X:Number = p.x;\r
+    var Y:Number = p.y;\r
+    var Z:Number = p.z ? p.z : 0;   //Z value not always supplied\r
+    var Longitude:Number;\r
+    var Latitude:Number;\r
+    var Height:Number;\r
+\r
+    var W:Number;        /* distance from Z axis */\r
+    var W2:Number;       /* square of distance from Z axis */\r
+    var T0:Number;       /* initial estimate of vertical component */\r
+    var T1:Number;       /* corrected estimate of vertical component */\r
+    var S0:Number;       /* initial estimate of horizontal component */\r
+    var S1:Number;       /* corrected estimate of horizontal component */\r
+    var Sin_B0:Number;   /* Math.sin(B0), B0 is estimate of Bowring aux variable */\r
+    var Sin3_B0:Number;  /* cube of Math.sin(B0) */\r
+    var Cos_B0:Number;   /* Math.cos(B0) */\r
+    var Sin_p1:Number;   /* Math.sin(phi1), phi1 is estimated latitude */\r
+    var Cos_p1:Number;   /* Math.cos(phi1) */\r
+    var Rn:Number;       /* Earth radius at location */\r
+    var Sum:Number;      /* numerator of Math.cos(phi1) */\r
+    var At_Pole:Boolean;  /* indicates location is in polar region */\r
+\r
+    At_Pole = false;\r
+    if (X != 0.0)\r
+    {\r
+        Longitude = Math.atan2(Y,X);\r
+    }\r
+    else\r
+    {\r
+        if (Y > 0)\r
+        {\r
+            Longitude = ProjConstants.HALF_PI;\r
+        }\r
+        else if (Y < 0)\r
+        {\r
+            Longitude = -ProjConstants.HALF_PI;\r
+        }\r
+        else\r
+        {\r
+            At_Pole = true;\r
+            Longitude = 0.0;\r
+            if (Z > 0.0)\r
+            {  /* north pole */\r
+                Latitude = ProjConstants.HALF_PI;\r
+            }\r
+            else if (Z < 0.0)\r
+            {  /* south pole */\r
+                Latitude = -ProjConstants.HALF_PI;\r
+            }\r
+            else\r
+            {  /* center of earth */\r
+                Latitude = ProjConstants.HALF_PI;\r
+                Height = -this.b;\r
+                return null;\r
+            }\r
+        }\r
+    }\r
+    W2 = X*X + Y*Y;\r
+    W = Math.sqrt(W2);\r
+    T0 = Z * ProjConstants.AD_C;\r
+    S0 = Math.sqrt(T0 * T0 + W2);\r
+    Sin_B0 = T0 / S0;\r
+    Cos_B0 = W / S0;\r
+    Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0;\r
+    T1 = Z + this.b * this.ep2 * Sin3_B0;\r
+    Sum = W - this.a * this.es * Cos_B0 * Cos_B0 * Cos_B0;\r
+    S1 = Math.sqrt(T1*T1 + Sum * Sum);\r
+    Sin_p1 = T1 / S1;\r
+    Cos_p1 = Sum / S1;\r
+    Rn = this.a / Math.sqrt(1.0 - this.es * Sin_p1 * Sin_p1);\r
+    if (Cos_p1 >= ProjConstants.COS_67P5)\r
+    {\r
+        Height = W / Cos_p1 - Rn;\r
+    }\r
+    else if (Cos_p1 <= -ProjConstants.COS_67P5)\r
+    {\r
+        Height = W / -Cos_p1 - Rn;\r
+    }\r
+    else\r
+    {\r
+        Height = Z / Sin_p1 + Rn * (this.es - 1.0);\r
+    }\r
+    if (At_Pole == false)\r
+    {\r
+        Latitude = Math.atan(Sin_p1 / Cos_p1);\r
+    }\r
+\r
+    p.x = Longitude;\r
+    p.y = Latitude;\r
+    p.z = Height;\r
+    return p;\r
+  } // geocentric_to_geodetic_noniter()\r
+\r
+  /****************************************************************/\r
+  // pj_geocentic_to_wgs84( p )\r
+  //  p = point to transform in geocentric coordinates (x,y,z)\r
+  public function geocentric_to_wgs84( p:ProjPoint ):void\r
+   {\r
+\r
+    if( this.datum_type == ProjConstants.PJD_3PARAM )\r
+    {\r
+      // if( x[io] == HUGE_VAL )\r
+      //    continue;\r
+      p.x += this.datum_params[0];\r
+      p.y += this.datum_params[1];\r
+      p.z += this.datum_params[2];\r
+\r
+    }\r
+    else if (this.datum_type == ProjConstants.PJD_7PARAM)\r
+    {\r
+      var Dx_BF:Number =this.datum_params[0];\r
+      var Dy_BF:Number =this.datum_params[1];\r
+      var Dz_BF:Number =this.datum_params[2];\r
+      var Rx_BF:Number =this.datum_params[3];\r
+      var Ry_BF:Number =this.datum_params[4];\r
+      var Rz_BF:Number =this.datum_params[5];\r
+      var M_BF:Number  =this.datum_params[6];\r
+      // if( x[io] == HUGE_VAL )\r
+      //    continue;\r
+      var x_out:Number = M_BF*(       p.x - Rz_BF*p.y + Ry_BF*p.z) + Dx_BF;\r
+      var y_out:Number = M_BF*( Rz_BF*p.x +       p.y - Rx_BF*p.z) + Dy_BF;\r
+      var z_out:Number = M_BF*(-Ry_BF*p.x + Rx_BF*p.y +       p.z) + Dz_BF;\r
+      p.x = x_out;\r
+      p.y = y_out;\r
+      p.z = z_out;\r
+    }\r
+  } // cs_geocentric_to_wgs84\r
+\r
+  /****************************************************************/\r
+  // pj_geocentic_from_wgs84()\r
+  //  coordinate system definition,\r
+  //  point to transform in geocentric coordinates (x,y,z)\r
+  public function geocentric_from_wgs84( p:ProjPoint ):void\r
+  {\r
+\r
+    if( this.datum_type == ProjConstants.PJD_3PARAM )\r
+    {\r
+      //if( x[io] == HUGE_VAL )\r
+      //    continue;\r
+      p.x -= this.datum_params[0];\r
+      p.y -= this.datum_params[1];\r
+      p.z -= this.datum_params[2];\r
+\r
+    }\r
+    else if (this.datum_type == ProjConstants.PJD_7PARAM)\r
+    {\r
+      var Dx_BF:Number =this.datum_params[0];\r
+      var Dy_BF:Number =this.datum_params[1];\r
+      var Dz_BF:Number =this.datum_params[2];\r
+      var Rx_BF:Number =this.datum_params[3];\r
+      var Ry_BF:Number =this.datum_params[4];\r
+      var Rz_BF:Number =this.datum_params[5];\r
+      var M_BF:Number  =this.datum_params[6];\r
+      var x_tmp:Number = (p.x - Dx_BF) / M_BF;\r
+      var y_tmp:Number = (p.y - Dy_BF) / M_BF;\r
+      var z_tmp:Number = (p.z - Dz_BF) / M_BF;\r
+      //if( x[io] == HUGE_VAL )\r
+      //    continue;\r
+\r
+      p.x =        x_tmp + Rz_BF*y_tmp - Ry_BF*z_tmp;\r
+      p.y = -Rz_BF*x_tmp +       y_tmp + Rx_BF*z_tmp;\r
+      p.z =  Ry_BF*x_tmp - Rx_BF*y_tmp +       z_tmp;\r
+    } //cs_geocentric_from_wgs84()\r
+  }\r
+  \r
+\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/LICENCE.txt b/com/gradoservice/proj4as/LICENCE.txt
new file mode 100755 (executable)
index 0000000..3ce7c3e
--- /dev/null
@@ -0,0 +1,10 @@
+Copyright (c) German Osin, 2009
+All rights reserved.
+[see http://groups.google.com/group/openscales-dev/msg/425f736fd9d07884 for licence declaration]
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/com/gradoservice/proj4as/Proj4as.as b/com/gradoservice/proj4as/Proj4as.as
new file mode 100755 (executable)
index 0000000..745e314
--- /dev/null
@@ -0,0 +1,157 @@
+package com.gradoservice.proj4as
+{
+       import com.gradoservice.proj4as.proj.AbstractProjProjection;
+       
+       public class Proj4as
+       {
+               
+               static public const defaultDatum:String = 'WGS84';
+               static public const WGS84:ProjProjection = new ProjProjection('WGS84');
+
+               
+               public function Proj4as()
+               {
+               }
+               
+               public function transform(source:ProjProjection, dest:ProjProjection, point:ProjPoint):ProjPoint
+               {
+               
+               if (source==null || dest==null || point==null)
+               {
+                       trace("Parametrs not created!");
+                       return null;  
+               }
+               
+               if (!source.readyToUse || !dest.readyToUse) 
+               {
+            trace("Proj4js initialization for "+source.srsCode+" not yet complete");
+               return point;
+               }
+        
+        // Workaround for Spherical Mercator
+        if ((source.srsProjNumber =="900913" && dest.datumCode != "WGS84") ||
+            (dest.srsProjNumber == "900913" && source.datumCode != "WGS84")) {
+            var wgs84:ProjProjection = WGS84;
+            this.transform(source, wgs84, point);
+            source = wgs84;
+        }
+
+        // Transform source points to long/lat, if they aren't already.
+        if ( source.projName=="longlat") {
+            point.x *= ProjConstants.D2R;  // convert degrees to radians
+            point.y *= ProjConstants.D2R;
+        } else {
+            if (source.to_meter) {
+                point.x *= source.to_meter;
+                point.y *= source.to_meter;
+            }
+            source.inverse(point); // Convert Cartesian to longlat
+        }
+
+        // Adjust for the prime meridian if necessary
+        if (source.from_greenwich) { 
+            point.x += source.from_greenwich; 
+        }
+
+        // Convert datums if needed, and if possible.
+        point = this.datum_transform( source.datum, dest.datum, point );
+
+        // Adjust for the prime meridian if necessary
+        if (dest.from_greenwich) {
+            point.x -= dest.from_greenwich;
+        }
+
+        if( dest.projName=="longlat" ) {             
+            // convert radians to decimal degrees
+            point.x *= ProjConstants.R2D;
+            point.y *= ProjConstants.R2D;
+        } else  {               // else project
+            dest.forward(point);
+            if (dest.to_meter) {
+                point.x /= dest.to_meter;
+                point.y /= dest.to_meter;
+            }
+        }
+        return point;                  
+               }
+               
+               
+    public function datum_transform( source:Datum, dest:Datum, point:ProjPoint ):ProjPoint 
+    {
+
+      // Short cut if the datums are identical.
+      if( source.compare_datums( dest ) ) {
+          return point; // in this case, zero is sucess,
+                    // whereas cs_compare_datums returns 1 to indicate TRUE
+                    // confusing, should fix this
+      }
+
+      // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest
+      if( source.datum_type == ProjConstants.PJD_NODATUM
+          || dest.datum_type == ProjConstants.PJD_NODATUM) {
+          return point;
+      }
+
+      // If this datum requires grid shifts, then apply it to geodetic coordinates.
+      if( source.datum_type == ProjConstants.PJD_GRIDSHIFT )
+      {
+       trace("ERROR: Grid shift transformations are not implemented yet.");
+        /*
+          pj_apply_gridshift( pj_param(source.params,"snadgrids").s, 0,
+                              point_count, point_offset, x, y, z );
+          CHECK_RETURN;
+
+          src_a = SRS_WGS84_SEMIMAJOR;
+          src_es = 0.006694379990;
+        */
+      }
+
+      if( dest.datum_type == ProjConstants.PJD_GRIDSHIFT )
+      {
+        trace("ERROR: Grid shift transformations are not implemented yet.");
+        /*
+          dst_a = ;
+          dst_es = 0.006694379990;
+        */
+      }
+
+      // Do we need to go through geocentric coordinates?
+      if( source.es != dest.es || source.a != dest.a
+          || source.datum_type == ProjConstants.PJD_3PARAM
+          || source.datum_type == ProjConstants.PJD_7PARAM
+          || dest.datum_type == ProjConstants.PJD_3PARAM
+          || dest.datum_type == ProjConstants.PJD_7PARAM)
+      {
+
+        // Convert to geocentric coordinates.
+        source.geodetic_to_geocentric( point );
+        // CHECK_RETURN;
+
+        // Convert between datums
+        if( source.datum_type == ProjConstants.PJD_3PARAM || source.datum_type == ProjConstants.PJD_7PARAM ) {
+          source.geocentric_to_wgs84(point);
+          // CHECK_RETURN;
+        }
+
+        if( dest.datum_type == ProjConstants.PJD_3PARAM || dest.datum_type == ProjConstants.PJD_7PARAM ) {
+          dest.geocentric_from_wgs84(point);
+          // CHECK_RETURN;
+        }
+
+        // Convert back to geodetic coordinates
+        dest.geocentric_to_geodetic( point );
+          // CHECK_RETURN;
+      }
+
+      // Apply grid shift to destination if required
+      if( dest.datum_type == ProjConstants.PJD_GRIDSHIFT )
+      {
+        trace("ERROR: Grid shift transformations are not implemented yet.");
+        // pj_apply_gridshift( pj_param(dest.params,"snadgrids").s, 1, point);
+        // CHECK_RETURN;
+      }
+      return point;
+    }          
+
+       }
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/ProjConstants.as b/com/gradoservice/proj4as/ProjConstants.as
new file mode 100755 (executable)
index 0000000..d4be076
--- /dev/null
@@ -0,0 +1,288 @@
+package com.gradoservice.proj4as
+{
+       public class ProjConstants
+       {
+               
+       static public const PI:Number=3.141592653589793238; //Math.PI,
+       static public const HALF_PI:Number=1.570796326794896619; //Math.PI*0.5,
+    static public const TWO_PI:Number=6.283185307179586477; //Math.PI*2,
+    static public const FORTPI:Number=0.78539816339744833;
+    static public const R2D:Number=57.29577951308232088;
+    static public const D2R:Number=0.01745329251994329577;
+    static public const SEC_TO_RAD:Number=4.84813681109535993589914102357e-6; /* SEC_TO_RAD = Pi/180/3600 */
+    static public const EPSLN:Number=1.0e-10;
+    static public const MAX_ITER:Number=20;
+    // following constants from geocent.c
+    static public const COS_67P5:Number=0.38268343236508977;  /* cosine of 67.5 degrees */
+    static public const AD_C:Number=1.0026000;                /* Toms region 1 constant */
+
+  /* datum_type values */
+   static public const PJD_UNKNOWN:int=0;
+   static public const PJD_3PARAM:int=1;
+   static public const PJD_7PARAM:int=2;
+   static public const PJD_GRIDSHIFT:int=3;
+   static public const PJD_WGS84:int=4;   // WGS84 or equivalent
+   static public const PJD_NODATUM:int=5;   // WGS84 or equivalent
+   static public const SRS_WGS84_SEMIMAJOR:int=6378137;  // only used in grid shift transforms
+
+  // ellipoid pj_set_ell.c
+   static public const SIXTH :Number=0.1666666666666666667; /* 1/6 */
+   static public const RA4:Number=0.04722222222222222222; /* 17/360 */
+   static public const RA6:Number=0.02215608465608465608; /* 67/3024 */
+   static public const RV4:Number=0.06944444444444444444; /* 5/72 */
+   static public const RV6:Number=0.04243827160493827160; /* 55/1296 */
+   
+   
+   
+   static public const PrimeMeridian:Object = {
+    "greenwich": 0.0,               //"0dE",
+    "lisbon":     -9.131906111111,   //"9d07'54.862\"W",
+    "paris":       2.337229166667,   //"2d20'14.025\"E",
+    "bogota":    -74.080916666667,  //"74d04'51.3\"W",
+    "madrid":     -3.687938888889,  //"3d41'16.58\"W",
+    "rome":       12.452333333333,  //"12d27'8.4\"E",
+    "bern":        7.439583333333,  //"7d26'22.5\"E",
+    "jakarta":   106.807719444444,  //"106d48'27.79\"E",
+    "ferro":     -17.666666666667,  //"17d40'W",
+    "brussels":    4.367975,        //"4d22'4.71\"E",
+    "stockholm":  18.058277777778,  //"18d3'29.8\"E",
+    "athens":     23.7163375,       //"23d42'58.815\"E",
+    "oslo":       10.722916666667   //"10d43'22.5\"E"
+       };
+
+  static public const Ellipsoid:Object = {
+  "MERIT": {a:6378137.0, rf:298.257, ellipseName:"MERIT 1983"},
+  "SGS85": {a:6378136.0, rf:298.257, ellipseName:"Soviet Geodetic System 85"},
+  "GRS80": {a:6378137.0, rf:298.257222101, ellipseName:"GRS 1980(IUGG, 1980)"},
+  "IAU76": {a:6378140.0, rf:298.257, ellipseName:"IAU 1976"},
+  "airy": {a:6377563.396, b:6356256.910, ellipseName:"Airy 1830"},
+  "APL4.": {a:6378137, rf:298.25, ellipseName:"Appl. Physics. 1965"},
+  "NWL9D": {a:6378145.0, rf:298.25, ellipseName:"Naval Weapons Lab., 1965"},
+  "mod_airy": {a:6377340.189, b:6356034.446, ellipseName:"Modified Airy"},
+  "andrae": {a:6377104.43, rf:300.0, ellipseName:"Andrae 1876 (Den., Iclnd.)"},
+  "aust_SA": {a:6378160.0, rf:298.25, ellipseName:"Australian Natl & S. Amer. 1969"},
+  "GRS67": {a:6378160.0, rf:298.2471674270, ellipseName:"GRS 67(IUGG 1967)"},
+  "bessel": {a:6377397.155, rf:299.1528128, ellipseName:"Bessel 1841"},
+  "bess_nam": {a:6377483.865, rf:299.1528128, ellipseName:"Bessel 1841 (Namibia)"},
+  "clrk66": {a:6378206.4, b:6356583.8, ellipseName:"Clarke 1866"},
+  "clrk80": {a:6378249.145, rf:293.4663, ellipseName:"Clarke 1880 mod."},
+  "CPM": {a:6375738.7, rf:334.29, ellipseName:"Comm. des Poids et Mesures 1799"},
+  "delmbr": {a:6376428.0, rf:311.5, ellipseName:"Delambre 1810 (Belgium)"},
+  "engelis": {a:6378136.05, rf:298.2566, ellipseName:"Engelis 1985"},
+  "evrst30": {a:6377276.345, rf:300.8017, ellipseName:"Everest 1830"},
+  "evrst48": {a:6377304.063, rf:300.8017, ellipseName:"Everest 1948"},
+  "evrst56": {a:6377301.243, rf:300.8017, ellipseName:"Everest 1956"},
+  "evrst69": {a:6377295.664, rf:300.8017, ellipseName:"Everest 1969"},
+  "evrstSS": {a:6377298.556, rf:300.8017, ellipseName:"Everest (Sabah & Sarawak)"},
+  "fschr60": {a:6378166.0, rf:298.3, ellipseName:"Fischer (Mercury Datum) 1960"},
+  "fschr60m": {a:6378155.0, rf:298.3, ellipseName:"Fischer 1960"},
+  "fschr68": {a:6378150.0, rf:298.3, ellipseName:"Fischer 1968"},
+  "helmert": {a:6378200.0, rf:298.3, ellipseName:"Helmert 1906"},
+  "hough": {a:6378270.0, rf:297.0, ellipseName:"Hough"},
+  "intl": {a:6378388.0, rf:297.0, ellipseName:"International 1909 (Hayford)"},
+  "kaula": {a:6378163.0, rf:298.24, ellipseName:"Kaula 1961"},
+  "lerch": {a:6378139.0, rf:298.257, ellipseName:"Lerch 1979"},
+  "mprts": {a:6397300.0, rf:191.0, ellipseName:"Maupertius 1738"},
+  "new_intl": {a:6378157.5, b:6356772.2, ellipseName:"New International 1967"},
+  "plessis": {a:6376523.0, rf:6355863.0, ellipseName:"Plessis 1817 (France)"},
+  "krass": {a:6378245.0, rf:298.3, ellipseName:"Krassovsky, 1942"},
+  "SEasia": {a:6378155.0, b:6356773.3205, ellipseName:"Southeast Asia"},
+  "walbeck": {a:6376896.0, b:6355834.8467, ellipseName:"Walbeck"},
+  "WGS60": {a:6378165.0, rf:298.3, ellipseName:"WGS 60"},
+  "WGS66": {a:6378145.0, rf:298.25, ellipseName:"WGS 66"},
+  "WGS72": {a:6378135.0, rf:298.26, ellipseName:"WGS 72"},
+  "WGS84": {a:6378137.0, rf:298.257223563, ellipseName:"WGS 84"},
+  "sphere": {a:6370997.0, b:6370997.0, ellipseName:"Normal Sphere (r=6370997)"}
+};
+
+ static public const Datum:Object = {
+  "WGS84": {towgs84: "0,0,0", ellipse: "WGS84", datumName: "WGS84"},
+  "GGRS87": {towgs84: "-199.87,74.79,246.62", ellipse: "GRS80", datumName: "Greek_Geodetic_Reference_System_1987"},
+  "NAD83": {towgs84: "0,0,0", ellipse: "GRS80", datumName: "North_American_Datum_1983"},
+  "NAD27": {nadgrids: "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat", ellipse: "clrk66", datumName: "North_American_Datum_1927"},
+  "potsdam": {towgs84: "606.0,23.0,413.0", ellipse: "bessel", datumName: "Potsdam Rauenberg 1950 DHDN"},
+  "carthage": {towgs84: "-263.0,6.0,431.0", ellipse: "clark80", datumName: "Carthage 1934 Tunisia"},
+  "hermannskogel": {towgs84: "653.0,-212.0,449.0", ellipse: "bessel", datumName: "Hermannskogel"},
+  "ire65": {towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", ellipse: "mod_airy", datumName: "Ireland 1965"},
+  "nzgd49": {towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993", ellipse: "intl", datumName: "New Zealand Geodetic Datum 1949"},
+  "OSGB36": {towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894", ellipse: "airy", datumName: "Airy 1830"}
+};
+   
+               
+               
+               public function ProjConstants()
+               {
+               }
+               
+               
+               // Function to compute the constant small m which is the radius of
+               //   a parallel of latitude, phi, divided by the semimajor axis.
+               // -----------------------------------------------------------------
+               static public function msfnz (eccent:Number, sinphi:Number, cosphi:Number):Number 
+               {
+       var con:Number = eccent * sinphi;
+       return cosphi/(Math.sqrt(1.0 - con * con));
+               }
+
+               // Function to compute the constant small t for use in the forward
+               //   computations in the Lambert Conformal Conic and the Polar
+               //   Stereographic projections.
+               // -----------------------------------------------------------------
+               static public function tsfnz(eccent:Number, phi:Number, sinphi:Number):Number 
+               {
+       var con:Number = eccent * sinphi;
+       var com:Number = 0.5 * eccent;
+       con = Math.pow(((1.0 - con) / (1.0 + con)), com);
+       return (Math.tan(0.5 * (ProjConstants.HALF_PI - phi))/con);
+               }
+
+               // Function to compute the latitude angle, phi2, for the inverse of the
+               //   Lambert Conformal Conic and Polar Stereographic projections.
+               // ----------------------------------------------------------------
+               static public function phi2z(eccent:Number, ts:Number):Number 
+               {
+                   var eccnth:Number = .5 * eccent;
+                   var con:Number =0;
+                   var dphi:Number =0;
+                   var phi:Number = ProjConstants.HALF_PI - 2 * Math.atan(ts);
+                   for (var i:int = 0; i <= 15; i++) {
+                     con = eccent * Math.sin(phi);
+                     dphi = ProjConstants.HALF_PI - 2 * Math.atan(ts *(Math.pow(((1.0 - con)/(1.0 + con)),eccnth))) - phi;
+                     phi += dphi;
+                     if (Math.abs(dphi) <= .0000000001) return phi;
+                   }
+                   trace("phi2z has NoConvergence");
+                   return -9999;
+               }
+
+               /* Function to compute constant small q which is the radius of a 
+                  parallel of latitude, phi, divided by the semimajor axis. 
+               ------------------------------------------------------------*/
+                 static public function qsfnz(eccent:Number,sinphi:Number,cosphi:Number):Number 
+                 {
+                   var con:Number = 0;
+                   if (eccent > 1.0e-7) {
+                     con = eccent * sinphi;
+                     return (( 1.0- eccent * eccent) * (sinphi /(1.0 - con * con) - (.5/eccent)*Math.log((1.0 - con)/(1.0 + con))));
+                   } else {
+                     return 2.0 * sinphi;
+                   }
+                 }
+
+               /* Function to eliminate roundoff errors in asin
+               ----------------------------------------------*/
+                 static public function asinz(x:Number):Number 
+                 {
+                   if (Math.abs(x)>1.0) {
+                     x=(x>1.0)?1.0:-1.0;
+                   }
+                   return Math.asin(x);
+                 }
+
+               // following functions from gctpc cproj.c for transverse mercator projections
+               static public function e0fn(x:Number):Number {return(1.0-0.25*x*(1.0+x/16.0*(3.0+1.25*x)));}
+               static public function e1fn(x:Number):Number {return(0.375*x*(1.0+0.25*x*(1.0+0.46875*x)));}
+               static public function e2fn(x:Number):Number {return(0.05859375*x*x*(1.0+0.75*x));}
+               static public function e3fn(x:Number):Number {return(x*x*x*(35.0/3072.0));}
+               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));}
+
+               static public function srat(esinp:Number, exp:Number):Number 
+               {
+               return(Math.pow((1.0-esinp)/(1.0+esinp), exp));
+               }
+
+// Function to return the sign of an argument
+  static public function sign(x:Number):Number { if (x < 0.0) return(-1); else return(1);}
+
+// Function to adjust longitude to -180 to 180; input in radians
+  static public function adjust_lon(x:Number):Number {
+    x = (Math.abs(x) < ProjConstants.PI) ? x: (x - (ProjConstants.sign(x)*ProjConstants.TWO_PI) );
+    return x;
+  }
+
+// IGNF - DGR : algorithms used by IGN France
+
+// Function to adjust latitude to -90 to 90; input in radians
+  static public function adjust_lat(x:Number):Number {
+    x= (Math.abs(x) < ProjConstants.HALF_PI) ? x: (x - (ProjConstants.sign(x)*ProjConstants.PI) );
+    return x;
+  }
+
+// Latitude Isometrique - close to tsfnz ...
+  static public function latiso(eccent:Number, phi:Number, sinphi:Number):Number
+  {
+    if (Math.abs(phi) > ProjConstants.HALF_PI) return +Number.NaN;
+    if (phi==ProjConstants.HALF_PI) return Number.POSITIVE_INFINITY;
+    if (phi==-1.0*ProjConstants.HALF_PI) return -1.0*Number.POSITIVE_INFINITY;
+
+    var con:Number= eccent*sinphi;
+    return Math.log(Math.tan((ProjConstants.HALF_PI+phi)/2.0))+eccent*Math.log((1.0-con)/(1.0+con))/2.0;
+  }
+
+  static public function fL(x:Number,L:Number):Number {
+    return 2.0*Math.atan(x*Math.exp(L)) - ProjConstants.HALF_PI;
+  }
+
+// Inverse Latitude Isometrique - close to ph2z
+  static public function invlatiso(eccent:Number, ts:Number):Number {
+    var phi:Number= ProjConstants.fL(1.0,ts);
+    var Iphi:Number= 0.0;
+    var con:Number= 0.0;
+    do {
+      Iphi= phi;
+      con= eccent*Math.sin(Iphi);
+      phi= ProjConstants.fL(Math.exp(eccent*Math.log((1.0+con)/(1.0-con))/2.0),ts)
+    } while (Math.abs(phi-Iphi)>1.0e-12);
+    return phi;
+  }
+
+// Needed for Gauss Laborde
+// Original:  Denis Makarov (info@binarythings.com)
+// Web Site:  http://www.binarythings.com
+  static public function sinh(x:Number):Number
+  {
+    var r:Number= Math.exp(x);
+    r= (r-1.0/r)/2.0;
+    return r;
+  }
+
+  static public function cosh(x:Number):Number
+  {
+    var r:Number= Math.exp(x);
+    r= (r+1.0/r)/2.0;
+    return r;
+  }
+
+  static public function tanh(x:Number):Number
+  {
+    var r:Number= Math.exp(x);
+    r= (r-1.0/r)/(r+1.0/r);
+    return r;
+  }
+
+ static public function  asinh(x:Number):Number
+  {
+    var s:Number= (x>= 0? 1.0:-1.0);
+    return s*(Math.log( Math.abs(x) + Math.sqrt(x*x+1.0) ));
+  }
+
+ static public function  acosh(x:Number):Number
+  {
+    return 2.0*Math.log(Math.sqrt((x+1.0)/2.0) + Math.sqrt((x-1.0)/2.0));
+  }
+
+ static public function  atanh(x:Number):Number
+  {
+    return Math.log((x-1.0)/(x+1.0))/2.0;
+  }
+
+// Grande Normale
+ static public function  gN(a:Number,e:Number,sinphi:Number):Number
+  {
+    var temp:Number= e*sinphi;
+    return a/Math.sqrt(1.0 - temp*temp);
+  }
+               
+
+       }
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/ProjPoint.as b/com/gradoservice/proj4as/ProjPoint.as
new file mode 100755 (executable)
index 0000000..f56dc1b
--- /dev/null
@@ -0,0 +1,50 @@
+package com.gradoservice.proj4as\r
+{\r
+       public class ProjPoint\r
+       {\r
+               public var x:Number;\r
+               public var y:Number;\r
+               public var z:Number;\r
+               \r
+               public function ProjPoint(x:Number,y:Number,z:Number)\r
+               {\r
+                       this.x = x;\r
+                       this.y = y;\r
+                       this.z = z;                                             \r
+               }\r
+\r
+       public function clone():ProjPoint \r
+       {\r
+      return new ProjPoint(this.x, this.y, this.z);\r
+    }\r
+\r
+    /**\r
+     * APIMethod: toString\r
+     * Return a readable string version of the point\r
+     *\r
+     * Return:\r
+     * {String} String representation of Proj4js.Point object. \r
+     *           (ex. <i>"x=5,y=42"</i>)\r
+     */\r
+    public function toString():String \r
+    {\r
+        return ("x=" + this.x + ",y=" + this.y);\r
+    }\r
+\r
+    /** \r
+     * APIMethod: toShortString\r
+     * Return a short string version of the point.\r
+     *\r
+     * Return:\r
+     * {String} Shortened String representation of Proj4js.Point object. \r
+     *         (ex. <i>"5, 42"</i>)\r
+     */\r
+    public function toShortString ():String \r
+    {\r
+        return (this.x + ", " + this.y);\r
+    }\r
+\r
+\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/ProjProjection.as b/com/gradoservice/proj4as/ProjProjection.as
new file mode 100755 (executable)
index 0000000..9b0a290
--- /dev/null
@@ -0,0 +1,282 @@
+package com.gradoservice.proj4as
+{
+       import com.gradoservice.proj4as.proj.*;
+       
+       public class ProjProjection
+       {
+       /**
+          * Property: readyToUse
+          * Flag to indicate if initialization is complete for this Proj object
+          */
+         public var readyToUse:Boolean = false;   
+         
+         /**
+          * Property: title
+          * The title to describe the projection
+          */
+        protected var projParams:ProjParams = new ProjParams();
+         
+        static public const defs:Object = {
+                       'EPSG:900913': "+title=Google Mercator EPSG:900913 +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs",
+                       'WGS84': "+title=long/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees",
+                       'EPSG:4326': "+title=long/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees",
+                       'EPSG:4269': "+title=long/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees",                   
+                       'EPSG:32639': "+title=WGS 84 / UTM zone 39N +proj=utm +zone=39 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
+                       'EPSG:27700': "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs"
+               }
+                        
+
+         
+         protected var proj:IProjection;       
+         
+               public function get srsCode():String
+               {
+                       return projParams.srsCode;
+               }
+               
+               public function get srsProjNumber():String
+               {
+                       return projParams.srsProjNumber;
+               }
+               
+               public function get projName():String
+               {
+                       return projParams.projName;
+               }               
+               
+               public function get datum():Datum
+               {
+                       return projParams.datum;                
+               }
+               
+               public function get datumCode():String
+               {
+                       return projParams.datumCode;            
+               }       
+               
+               public function get from_greenwich():Number
+               {
+                       return projParams.from_greenwich;               
+               }
+               
+               public function get to_meter():Number
+               {
+                       return projParams.to_meter;             
+               }
+               
+               public function get a():Number
+               {
+                       return projParams.a;            
+               }
+               
+               public function get b():Number
+               {
+                       return projParams.b;            
+               }
+               
+               public function get ep2():Number
+               {
+                       return projParams.ep2;                  
+               }
+               
+               public function get es():Number
+               {
+                       return projParams.es;           
+               }                               
+               
+               public function get datum_params():Array
+               {
+                       return projParams.datum_params;                 
+               }                                                                                       
+               
+               public function ProjProjection(srsCode:String)
+               {
+                       this.projParams.srsCode = srsCode.toUpperCase();
+                       
+                     if (this.projParams.srsCode.indexOf("EPSG") == 0) {
+                         this.projParams.srsAuth = 'epsg';
+                         this.projParams.srsProjNumber = this.projParams.srsCode.substring(5);
+                     // DGR 2007-11-20 : authority IGNF
+                     } else if (this.projParams.srsCode.indexOf("IGNF") == 0) {
+                         this.projParams.srsAuth = 'IGNF';
+                         this.projParams.srsProjNumber = this.projParams.srsCode.substring(5);
+                     // DGR 2008-06-19 : pseudo-authority CRS for WMS
+                     } else if (this.projParams.srsCode.indexOf("CRS") == 0) {
+                         this.projParams.srsAuth = 'CRS';
+                         this.projParams.srsProjNumber = this.projParams.srsCode.substring(4);
+                     } else {
+                         this.projParams.srsAuth = '';
+                         this.projParams.srsProjNumber = this.projParams.srsCode;
+                     }
+                     this.loadProjDefinition();                                
+               }
+               
+               private function loadProjDefinition():void
+               {                       
+                       if (this.srsCode!=null && ProjProjection.defs[this.srsCode]!=null)
+                       {
+                               this.parseDef(ProjProjection.defs[this.projParams.srsCode]);
+                               this.initTransforms();
+                       }
+               }
+               
+               protected function initTransforms():void 
+                       {
+                       switch (this.projParams.projName)
+                       {
+                               case "aea": this.proj = new ProjAea(this.projParams); break;
+                               case "aeqd": this.proj = new ProjAeqd(this.projParams); break;                          
+                               case "eqc": this.proj = new ProjEqc(this.projParams); break;                            
+                               case "eqdc": this.proj = new ProjEqdc(this.projParams); break;                          
+                               case "equi": this.proj = new ProjEqui(this.projParams); break;                          
+                               case "gauss": this.proj = new ProjGauss(this.projParams); break;                                
+                               case "gstmerc": this.proj = new ProjGstmerc(this.projParams); break;                            
+                               case "laea": this.proj = new ProjLaea(this.projParams); break;                          
+                               case "lcc": this.proj = new ProjLcc(this.projParams); break;                            
+                               case "longlat": this.proj = new ProjLonglat(this.projParams); break;                            
+                               case "merc": this.proj = new ProjMerc(this.projParams); break;                          
+                               case "mill": this.proj = new ProjMill(this.projParams); break;                          
+                               case "moll": this.proj = new ProjMoll(this.projParams); break;                          
+                               case "nzmg": this.proj = new ProjNzmg(this.projParams); break;                          
+                               case "omerc": this.proj = new ProjOmerc(this.projParams); break;                                
+                               case "ortho": this.proj = new ProjOrtho(this.projParams); break;                                
+                               case "sinu": this.proj = new ProjSinu(this.projParams); break;                          
+                               case "omerc": this.proj = new ProjOmerc(this.projParams); break;                                
+                               case "stere": this.proj = new ProjStere(this.projParams); break;                                
+                               case "sterea": this.proj = new ProjSterea(this.projParams); break;                              
+                               case "tmerc": this.proj = new ProjTmerc(this.projParams); break;                                
+                               case "utm": this.proj = new ProjUtm(this.projParams); break;
+                               case "vandg": this.proj = new ProjVandg(this.projParams); break;                                
+                       }
+                       if (this.proj!=null) {
+                               this.proj.init();
+                               this.readyToUse = true;                         
+                       }
+                       }
+                               
+               private function parseDef(definition:String):void
+               {
+               var paramName:String = '';
+               var paramVal:String = '';
+               var paramArray:Array=definition.split("+");
+                       for (var prop:int=0; prop<paramArray.length; prop++) {
+                                 var property:Array = paramArray[prop].split("=");
+                                 paramName = property[0].toLowerCase();
+                                 paramVal = property[1];
+                       
+                                 switch (paramName.replace(/\s/gi,"")) {  // trim out spaces
+                                     case "": break;   // throw away nameless parameter
+                                     case "title":  this.projParams.title = paramVal; break;
+                                     case "proj":   this.projParams.projName =  paramVal.replace(/\s/gi,""); break;
+                                     case "units":  this.projParams.units = paramVal.replace(/\s/gi,""); break;
+                                     case "datum":  this.projParams.datumCode = paramVal.replace(/\s/gi,""); break;
+                                     case "nadgrids": this.projParams.nagrids = paramVal.replace(/\s/gi,""); break;
+                                     case "ellps":  this.projParams.ellps = paramVal.replace(/\s/gi,""); break;
+                                     case "a":      this.projParams.a =  parseFloat(paramVal); break;  // semi-major radius
+                                     case "b":      this.projParams.b =  parseFloat(paramVal); break;  // semi-minor radius
+                                     // DGR 2007-11-20
+                                     case "rf":     this.projParams.rf = parseFloat(paramVal); break; // inverse flattening rf= a/(a-b)
+                                     case "lat_0":  this.projParams.lat0 = parseFloat(paramVal)*ProjConstants.D2R; break;        // phi0, central latitude
+                                     case "lat_1":  this.projParams.lat1 = parseFloat(paramVal)*ProjConstants.D2R; break;        //standard parallel 1
+                                     case "lat_2":  this.projParams.lat2 = parseFloat(paramVal)*ProjConstants.D2R; break;        //standard parallel 2
+                                     case "lat_ts": this.projParams.lat_ts = parseFloat(paramVal)*ProjConstants.D2R; break;      // used in merc and eqc
+                                     case "lon_0":  this.projParams.long0 = parseFloat(paramVal)*ProjConstants.D2R; break;       // lam0, central longitude
+                                     case "alpha":  this.projParams.alpha =  parseFloat(paramVal)*ProjConstants.D2R; break;  //for somerc projection
+                                     case "lonc":   this.projParams.longc = parseFloat(paramVal)*ProjConstants.D2R; break;       //for somerc projection
+                                     case "x_0":    this.projParams.x0 = parseFloat(paramVal); break;  // false easting
+                                     case "y_0":    this.projParams.y0 = parseFloat(paramVal); break;  // false northing
+                                     case "k_0":    this.projParams.k0 = parseFloat(paramVal); break;  // projection scale factor
+                                     case "k":      this.projParams.k0 = parseFloat(paramVal); break;  // both forms returned
+                                     case "R_A":    this.projParams.R_A = true; break;   //Spheroid radius 
+                                     case "zone":   this.projParams.zone = parseInt(paramVal); break;  // UTM Zone
+                                     case "south":   this.projParams.utmSouth = true; break;  // UTM north/south
+                                     case "towgs84":this.projParams.datum_params = paramVal.split(","); break;
+                                     case "to_meter": this.projParams.to_meter = parseFloat(paramVal); break; // cartesian scaling
+                                     case "from_greenwich": this.projParams.from_greenwich = parseFloat(paramVal)*ProjConstants.D2R; break;
+                                     // DGR 2008-07-09 : if pm is not a well-known prime meridian take
+                                     // the value instead of 0.0, then convert to radians
+                                     case "pm":     paramVal = paramVal.replace(/\s/gi,"");
+                                                    this.projParams.from_greenwich = ProjConstants.PrimeMeridian[paramVal] ?
+                                                       ProjConstants.PrimeMeridian[paramVal] : parseFloat(paramVal);
+                                                    this.projParams.from_greenwich *= ProjConstants.D2R; 
+                                                    break;
+                                     case "no_defs": break; 
+                                     default: trace("Unrecognized parameter: " + paramName); break;
+                                 } // switch()
+                             } // for paramArray
+                             this.deriveConstants();
+
+               }
+               
+               private function deriveConstants():void 
+               {
+               if (this.projParams.nagrids == '@null') this.projParams.datumCode = 'none';
+               if (this.projParams.datumCode && this.projParams.datumCode != 'none') 
+               {
+               var datumDef:Object = ProjConstants.Datum[this.projParams.datumCode];
+               if (datumDef) 
+                       {
+                       this.projParams.datum_params = datumDef.towgs84.split(',');
+                       this.projParams.ellps = datumDef.ellipse;
+                       this.projParams.datumName = datumDef.datumName ? datumDef.datumName : this.projParams.datumCode;
+                       }
+               }
+      
+             if (!this.projParams.a) {    // do we have an ellipsoid?
+                 var ellipse:Object = ProjConstants.Ellipsoid[this.projParams.ellps] ? ProjConstants.Ellipsoid[this.projParams.ellps] : ProjConstants.Ellipsoid['WGS84'];
+                 extend(this.projParams, ellipse);
+             }
+             if (this.projParams.rf && !this.projParams.b) this.projParams.b = (1.0 - 1.0/this.projParams.rf) * this.projParams.a;
+             if (Math.abs(this.projParams.a - this.projParams.b)<ProjConstants.EPSLN) {
+               this.projParams.sphere = true;
+               this.projParams.b= this.projParams.a;
+             }
+             this.projParams.a2 = this.projParams.a * this.projParams.a;          // used in geocentric
+             this.projParams.b2 = this.projParams.b * this.projParams.b;          // used in geocentric
+             this.projParams.es = (this.projParams.a2-this.projParams.b2)/this.projParams.a2;  // e ^ 2
+             this.projParams.e = Math.sqrt(this.projParams.es);        // eccentricity
+             if (this.projParams.R_A) {
+               this.projParams.a *= 1. - this.projParams.es * (ProjConstants.SIXTH + this.projParams.es * (ProjConstants.RA4 + this.projParams.es * ProjConstants.RA6));
+               this.projParams.a2 = this.projParams.a * this.projParams.a;
+               this.projParams.b2 = this.projParams.b * this.projParams.b;
+               this.projParams.es = 0.;
+             }
+             this.projParams.ep2=(this.projParams.a2-this.projParams.b2)/this.projParams.b2; // used in geocentric
+             if (!this.projParams.k0) this.projParams.k0 = 1.0;    //default value
+       
+             this.projParams.datum = new Datum(this);
+               }
+
+               private function extend(destination:Object, source:Object):void 
+               {
+             destination = destination || {};
+             if(source) {
+                 for(var property:String in source) {
+                     var value:Object = source[property];
+                     if(value != null) {
+                         destination[property] = value;
+                     }
+                 }
+             }
+           }
+           
+               public function forward(p:ProjPoint):ProjPoint
+                       {
+                       if (this.proj!=null)
+                               {                                       
+                               return this.proj.forward(p);
+                               }
+                       return p;
+                       }
+               
+               public function inverse(p:ProjPoint):ProjPoint
+                       {
+                       if (this.proj!=null)
+                               {                                       
+                               return this.proj.inverse(p);
+                               }
+                       return p;
+                       }                       
+
+       }
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/AbstractProjProjection.as b/com/gradoservice/proj4as/proj/AbstractProjProjection.as
new file mode 100755 (executable)
index 0000000..591144a
--- /dev/null
@@ -0,0 +1,113 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       \r
+       public class AbstractProjProjection extends ProjParams implements IProjection\r
+       {         \r
+         protected var sinphi:Number;\r
+         protected var cosphi:Number;\r
+         protected var temp:Number;\r
+         protected var e0:Number;        \r
+         protected var e1:Number;        \r
+         protected var e2:Number;        \r
+         protected var e3:Number;\r
+         protected var sin_po:Number;\r
+         protected var cos_po:Number;\r
+         protected var t1:Number;\r
+         protected var t2:Number;        \r
+         protected var t3:Number;        \r
+         protected var con:Number;\r
+         protected var ms1:Number;\r
+         protected var ms2:Number;\r
+         protected var ns:Number;        \r
+         protected var ns0:Number;       \r
+         protected var qs0:Number;\r
+         protected var qs1:Number;\r
+         protected var qs2:Number;\r
+         protected var c:Number;                 \r
+         protected var rh:Number;\r
+         protected var cos_phi:Number;\r
+         protected var sin_phi:Number; \r
+         protected var g:Number;\r
+         protected var ml:Number;        \r
+         protected var ml0:Number;\r
+         protected var ml1:Number;\r
+         protected var ml2:Number;\r
+         protected var mode:int;\r
+\r
+         protected var cos_p12:Number;\r
+         protected var sin_p12:Number;\r
+         \r
+         protected var rc:Number;               \r
+               \r
+               \r
+               public function AbstractProjProjection(data:ProjParams)\r
+                       {\r
+                         this.extend(data);                    \r
+                       }               \r
+               \r
+               public function init():void\r
+                       {\r
+                                   \r
+                       }\r
+       \r
+               public function forward(p:ProjPoint):ProjPoint\r
+                       {\r
+                       return p;\r
+                       }\r
+               \r
+               public function inverse(p:ProjPoint):ProjPoint\r
+                       {\r
+                       return p;\r
+                       } \r
+                       \r
+               protected function extend(source:ProjParams):void \r
+               {\r
+\r
+                       this.title = source.title;        \r
+                       this.projName= source.projName;\r
+                   this.units= source.units;\r
+                       this.datum = source.datum;        \r
+                       this.datumCode=source.datumCode;\r
+                       this.datumName=source.datumName;\r
+                       this.nagrids=source.nagrids;\r
+                       this.ellps=source.ellps;\r
+                       this.a=source.a;\r
+                       this.b=source.b;\r
+                       this.a2=source.a2;\r
+                       this.b2=source.b2;\r
+                       this.e=source.e;\r
+                       this.es=source.es;        \r
+                       this.ep2=source.ep2;      \r
+                       this.rf=source.rf;\r
+                       this.long0=source.long0;\r
+                       this.lat0=source.lat0;\r
+                       this.lat1=source.lat1;\r
+                       this.lat2=source.lat2;\r
+                       this.lat_ts=source.lat_ts;\r
+                       this.alpha=source.alpha;\r
+                       this.longc=source.longc;\r
+                       this.x0=source.x0;\r
+                       this.y0=source.y0;\r
+                       this.k0=source.k0;\r
+                       this.k=source.k;\r
+                       this.R_A=source.R_A;\r
+                       this.zone=source.zone;\r
+                       this.utmSouth=source.utmSouth;\r
+                       this.to_meter=source.to_meter;\r
+                       this.from_greenwich=source.from_greenwich;\r
+                       this.datum_params=source.datum_params;\r
+                       this.sphere=source.sphere;\r
+                       this.ellipseName=source.ellipseName;    \r
+\r
+                       this.srsCode=source.srsCode;\r
+                       this.srsAuth=source.srsAuth;\r
+                       this.srsProjNumber=source.srsProjNumber;                      \r
+\r
+           }                           \r
+\r
+       }\r
+               \r
+\r
+\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/IProjection.as b/com/gradoservice/proj4as/proj/IProjection.as
new file mode 100755 (executable)
index 0000000..c9cd88d
--- /dev/null
@@ -0,0 +1,14 @@
+package com.gradoservice.proj4as.proj
+{
+       import com.gradoservice.proj4as.ProjPoint;
+       
+       public interface IProjection
+       {
+               function init():void
+               
+               function forward(p:ProjPoint):ProjPoint
+               
+               function inverse(p:ProjPoint):ProjPoint
+               
+       }
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjAea.as b/com/gradoservice/proj4as/proj/ProjAea.as
new file mode 100755 (executable)
index 0000000..f0fd549
--- /dev/null
@@ -0,0 +1,145 @@
+package com.gradoservice.proj4as.proj
+{
+       import com.gradoservice.proj4as.ProjConstants;
+       import com.gradoservice.proj4as.ProjPoint;
+       import com.gradoservice.proj4as.Datum;
+       
+       public class ProjAea extends AbstractProjProjection
+       {
+               public function ProjAea(data:ProjParams)
+               {
+                       super(data);
+               }
+               
+  override public function init():void 
+       {
+    if (Math.abs(this.lat1 + this.lat2) <ProjConstants.EPSLN) {
+       trace("aeaInitEqualLatitudes");
+       return;
+    }
+    this.temp = this.b / this.a;
+    this.es = 1.0 - Math.pow(this.temp,2);
+    this.e3 = Math.sqrt(this.es);
+
+    this.sin_po=Math.sin(this.lat1);
+    this.cos_po=Math.cos(this.lat1);
+    this.t1=this.sin_po
+    this.con = this.sin_po;
+    this.ms1 = ProjConstants.msfnz(this.e3,this.sin_po,this.cos_po);
+    this.qs1 = ProjConstants.qsfnz(this.e3,this.sin_po,this.cos_po);
+
+    this.sin_po=Math.sin(this.lat2);
+    this.cos_po=Math.cos(this.lat2);
+    this.t2=this.sin_po;
+    this.ms2 = ProjConstants.msfnz(this.e3,this.sin_po,this.cos_po);
+    this.qs2 = ProjConstants.qsfnz(this.e3,this.sin_po,this.cos_po);
+
+    this.sin_po=Math.sin(this.lat0);
+    this.cos_po=Math.cos(this.lat0);
+    this.t3=this.sin_po;
+    this.qs0 = ProjConstants.qsfnz(this.e3,this.sin_po,this.cos_po);
+
+    if (Math.abs(this.lat1 - this.lat2) > ProjConstants.EPSLN) {
+      this.ns0 = (this.ms1 * this.ms1 - this.ms2 *this.ms2)/ (this.qs2 - this.qs1);
+    } else {
+      this.ns0 = this.con;
+    }
+    this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1;
+    this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0)/this.ns0;
+  }
+
+/* Albers Conical Equal Area forward equations--mapping lat,long to x,y
+  -------------------------------------------------------------------*/
+  override public function forward(p:ProjPoint):ProjPoint
+  {
+    var lon:Number=p.x;
+    var lat:Number=p.y;
+
+    this.sin_phi=Math.sin(lat);
+    this.cos_phi=Math.cos(lat);
+
+    var qs:Number = ProjConstants.qsfnz(this.e3,this.sin_phi,this.cos_phi);
+    var rh1:Number =this.a * Math.sqrt(this.c - this.ns0 * qs)/this.ns0;
+    var theta:Number = this.ns0 * ProjConstants.adjust_lon(lon - this.long0); 
+    var x:Number = rh1 * Math.sin(theta) + this.x0;
+    var y:Number = this.rh - rh1 * Math.cos(theta) + this.y0;
+
+    p.x = x; 
+    p.y = y;
+    return p;
+  }
+
+
+  override public function inverse(p:ProjPoint):ProjPoint 
+  {
+    var rh1:Number;
+    var qs:Number;
+    var con:Number;
+    var theta:Number
+    var lon:Number;
+    var lat:Number;
+
+    p.x -= this.x0;
+    p.y = this.rh - p.y + this.y0;
+    if (this.ns0 >= 0) {
+      rh1 = Math.sqrt(p.x *p.x + p.y * p.y);
+      con = 1.0;
+    } else {
+      rh1 = -Math.sqrt(p.x * p.x + p.y *p.y);
+      con = -1.0;
+    }
+    theta = 0.0;
+    if (rh1 != 0.0) {
+      theta = Math.atan2(con * p.x, con * p.y);
+    }
+    con = rh1 * this.ns0 / this.a;
+    qs = (this.c - con * con) / this.ns0;
+    if (this.e3 >= 1e-10) {
+      con = 1 - .5 * (1.0 -this.es) * Math.log((1.0 - this.e3) / (1.0 + this.e3))/this.e3;
+      if (Math.abs(Math.abs(con) - Math.abs(qs)) > .0000000001 ) {
+          lat = this.phi1z(this.e3,qs);
+      } else {
+          if (qs >= 0) {
+             lat = .5 * Math.PI;
+          } else {
+             lat = -.5 * Math.PI;
+          }
+      }
+    } else {
+      lat = this.phi1z(e3,qs);
+    }
+
+    lon = ProjConstants.adjust_lon(theta/this.ns0 + this.long0);
+    p.x = lon;
+    p.y = lat;
+    return p;
+  }
+  
+/* Function to compute phi1, the latitude for the inverse of the
+   Albers Conical Equal-Area projection.
+-------------------------------------------*/
+   private function phi1z (eccent:Number,qs:Number):Number 
+   {
+    var con:Number;
+    var com:Number
+    var dphi:Number;
+    var phi:Number = ProjConstants.asinz(.5 * qs);
+    if (eccent < ProjConstants.EPSLN) return phi;
+    
+    var eccnts:Number = eccent * eccent; 
+    for (var i:int = 1; i <= 25; i++) {
+        sinphi = Math.sin(phi);
+        cosphi = Math.cos(phi);
+        con = eccent * sinphi; 
+        com = 1.0 - con * con;
+        dphi = .5 * com * com / cosphi * (qs / (1.0 - eccnts) - sinphi / com + .5 / eccent * Math.log((1.0 - con) / (1.0 + con)));
+        phi = phi + dphi;
+        if (Math.abs(dphi) <= 1e-7) return phi;
+    }
+    trace("aea:phi1z:Convergence error");
+    return 0;
+  }
+               
+               
+       }
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjAeqd.as b/com/gradoservice/proj4as/proj/ProjAeqd.as
new file mode 100755 (executable)
index 0000000..408470a
--- /dev/null
@@ -0,0 +1,93 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjAeqd extends AbstractProjProjection\r
+       {\r
+               public function ProjAeqd(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+               override public function init():void \r
+               {\r
+       this.sin_p12=Math.sin(this.lat0)\r
+       this.cos_p12=Math.cos(this.lat0)\r
+               }\r
+\r
+               override public function forward(p:ProjPoint):ProjPoint\r
+               {\r
+       var lon:Number=p.x;\r
+       var lat:Number=p.y;\r
+       var ksp:Number;\r
+\r
+       var sinphi:Number=Math.sin(p.y);\r
+       var cosphi:Number=Math.cos(p.y); \r
+       var dlon:Number = ProjConstants.adjust_lon(lon - this.long0);\r
+       var coslon:Number = Math.cos(dlon);\r
+       var g:Number = this.sin_p12 * sinphi + this.cos_p12 * cosphi * coslon;\r
+       if (Math.abs(Math.abs(g) - 1.0) < ProjConstants.EPSLN) {\r
+                       ksp = 1.0;\r
+                       if (g < 0.0) {\r
+               trace("aeqd:Fwd:PointError");\r
+               return null;\r
+                       }\r
+       } else {\r
+               var z:Number = Math.acos(g);\r
+               ksp = z/Math.sin(z);\r
+       }\r
+       p.x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon);\r
+       p.y = this.y0 + this.a * ksp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * coslon);\r
+       return p;\r
+               }\r
+\r
+               override public function inverse(p:ProjPoint):ProjPoint \r
+               {\r
+       p.x -= this.x0;\r
+       p.y -= this.y0;\r
+       \r
+       var rh:Number = Math.sqrt(p.x * p.x + p.y *p.y);\r
+       if (rh > (2.0 * ProjConstants.HALF_PI * this.a)) \r
+       {\r
+                       trace("aeqdInvDataError");\r
+                       return null;\r
+       }\r
+       var z:Number = rh / this.a;\r
+\r
+    var sinz:Number=Math.sin(z)\r
+    var cosz:Number=Math.cos(z)\r
+\r
+    var lon:Number = this.long0;\r
+    var lat:Number;\r
+    if (Math.abs(rh) <= ProjConstants.EPSLN) {\r
+      lat = this.lat0;\r
+    } else {\r
+      lat = ProjConstants.asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh);\r
+      var con:Number = Math.abs(this.lat0) - ProjConstants.HALF_PI;\r
+      if (Math.abs(con) <= ProjConstants.EPSLN) {\r
+        if (lat0 >= 0.0) {\r
+          lon = ProjConstants.adjust_lon(this.long0 + Math.atan2(p.x , -p.y));\r
+        } else {\r
+          lon = ProjConstants.adjust_lon(this.long0 - Math.atan2(-p.x , p.y));\r
+        }\r
+      } else {\r
+        con = cosz - this.sin_p12 * Math.sin(lat);\r
+        if ((Math.abs(con) < ProjConstants.EPSLN) && (Math.abs(p.x) < ProjConstants.EPSLN)) {\r
+           //no-op, just keep the lon value as is\r
+        } else {\r
+          var temp:Number = Math.atan2((p.x * sinz * this.cos_p12), (con * rh));\r
+          lon = ProjConstants.adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh)));\r
+        }\r
+      }\r
+    }\r
+\r
+    p.x = lon;\r
+    p.y = lat;\r
+    return p;\r
+  } \r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjEqc.as b/com/gradoservice/proj4as/proj/ProjEqc.as
new file mode 100755 (executable)
index 0000000..18e8315
--- /dev/null
@@ -0,0 +1,55 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjEqc extends AbstractProjProjection\r
+       {\r
+               public function ProjEqc(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+               override public function init():void \r
+               {\r
+               if(!this.x0) this.x0=0;\r
+               if(!this.y0) this.y0=0;\r
+               if(!this.lat0) this.lat0=0;\r
+               if(!this.long0) this.long0=0;\r
+               if(!this.lat_ts) this.lat_ts=0;\r
+               if (!this.title) this.title = "Equidistant Cylindrical (Plate Carre)";\r
+               this.rc= Math.cos(this.lat_ts);\r
+       }\r
+\r
+\r
+    // forward equations--mapping lat,long to x,y\r
+    // -----------------------------------------------------------------\r
+       override public function forward(p:ProjPoint):ProjPoint \r
+       {\r
+       var lon:Number= p.x;\r
+       var lat:Number= p.y;\r
+       \r
+       var dlon:Number = ProjConstants.adjust_lon(lon - this.long0);\r
+       var dlat:Number = ProjConstants.adjust_lat(lat - this.lat0 );\r
+       p.x= this.x0 + (this.a*dlon*this.rc);\r
+       p.y= this.y0 + (this.a*dlat        );\r
+       return p;\r
+       }\r
+\r
+  // inverse equations--mapping x,y to lat/long\r
+  // -----------------------------------------------------------------\r
+               override public function inverse(p:ProjPoint):ProjPoint \r
+               {\r
+       var x:Number= p.x;\r
+       var y:Number= p.y;\r
+\r
+       p.x= ProjConstants.adjust_lon(this.long0 + ((x - this.x0)/(this.a*this.rc)));\r
+       p.y= ProjConstants.adjust_lat(this.lat0  + ((y - this.y0)/(this.a        )));\r
+               return p;\r
+               }\r
+\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjEqdc.as b/com/gradoservice/proj4as/proj/ProjEqdc.as
new file mode 100755 (executable)
index 0000000..0d7a6a3
--- /dev/null
@@ -0,0 +1,156 @@
+/*******************************************************************************\r
+NAME                            EQUIDISTANT CONIC \r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and Northing\r
+               for the Equidistant Conic projection.  The longitude and\r
+               latitude must be in radians.  The Easting and Northing values\r
+               will be returned in meters.\r
+\r
+PROGRAMMER              DATE\r
+----------              ----\r
+T. Mittan              Mar, 1993\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
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjEqdc extends AbstractProjProjection\r
+       {\r
+               public function ProjEqdc(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+\r
+/* Variables common to all subroutines in this code file\r
+  -----------------------------------------------------*/\r
+\r
+/* Initialize the Equidistant Conic projection\r
+  ------------------------------------------*/\r
+       override public function init():void\r
+       { \r
+    /* Place parameters in static storage for common use\r
+      -------------------------------------------------*/\r
+    if(!this.mode) this.mode=0;//chosen default mode\r
+    this.temp = this.b / this.a;\r
+    this.es = 1.0 - Math.pow(this.temp,2);\r
+    this.e = Math.sqrt(this.es);\r
+    this.e0 = ProjConstants.e0fn(this.es);\r
+    this.e1 = ProjConstants.e1fn(this.es);\r
+    this.e2 = ProjConstants.e2fn(this.es);\r
+    this.e3 = ProjConstants.e3fn(this.es);\r
+\r
+    this.sinphi=Math.sin(this.lat1);\r
+    this.cosphi=Math.cos(this.lat1);\r
+\r
+    this.ms1 = ProjConstants.msfnz(this.e,this.sinphi,this.cosphi);\r
+    this.ml1 = ProjConstants.mlfn(this.e0, this.e1, this.e2,this.e3, this.lat1);\r
+\r
+    /* format B\r
+    ---------*/\r
+    if (this.mode != 0) {\r
+      if (Math.abs(this.lat1 + this.lat2) < ProjConstants.EPSLN) {\r
+            trace("eqdc:Init:EqualLatitudes");\r
+            //return(81);\r
+       }\r
+       this.sinphi=Math.sin(this.lat2);\r
+       this.cosphi=Math.cos(this.lat2);   \r
+\r
+       this.ms2 = ProjConstants.msfnz(this.e,this.sinphi,this.cosphi);\r
+       this.ml2 = ProjConstants.mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2);\r
+       if (Math.abs(this.lat1 - this.lat2) >= ProjConstants.EPSLN) {\r
+         this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1);\r
+       } else {\r
+          this.ns = this.sinphi;\r
+       }\r
+    } else {\r
+      this.ns = this.sinphi;\r
+    }\r
+    this.g = this.ml1 + this.ms1/this.ns;\r
+    this.ml0 = ProjConstants.mlfn(this.e0, this.e1,this. e2, this.e3, this.lat0);\r
+    this.rh = this.a * (this.g - this.ml0);\r
+  }\r
+\r
+\r
+/* Equidistant Conic forward equations--mapping lat,long to x,y\r
+  -----------------------------------------------------------*/\r
+       override public function forward(p:ProjPoint):ProjPoint \r
+       {\r
+           var lon:Number=p.x;\r
+           var lat:Number=p.y;\r
+       \r
+           /* Forward equations\r
+             -----------------*/\r
+           var ml:Number = ProjConstants.mlfn(this.e0, this.e1, this.e2, this.e3, lat);\r
+           var rh1:Number = this.a * (this.g - ml);\r
+           var theta:Number = this.ns * ProjConstants.adjust_lon(lon - this.long0);\r
+       \r
+           var x:Number = this.x0  + rh1 * Math.sin(theta);\r
+           var y:Number = this.y0 + this.rh - rh1 * Math.cos(theta);\r
+           p.x=x;\r
+           p.y=y;\r
+           return p;\r
+               }\r
+\r
+/* Inverse equations\r
+  -----------------*/\r
+         override public function inverse(p:ProjPoint):ProjPoint\r
+         {\r
+           p.x -= this.x0;\r
+           p.y  = this.rh - p.y + this.y0;\r
+           var con:Number;\r
+           var rh1:Number;\r
+           if (this.ns >= 0) {\r
+              rh1 = Math.sqrt(p.x *p.x + p.y * p.y); \r
+              con = 1.0;\r
+           } else {\r
+              rh1 = -Math.sqrt(p.x *p. x +p. y * p.y); \r
+              con = -1.0;\r
+           }\r
+           var theta:Number = 0.0;\r
+           if (rh1 != 0.0) theta = Math.atan2(con *p.x, con *p.y);\r
+           var ml:Number = this.g - rh1 /this.a;\r
+           var lat:Number = this.phi3z(this.ml,this.e0,this.e1,this.e2,this.e3);\r
+           var lon:Number = ProjConstants.adjust_lon(this.long0 + theta / this.ns);\r
+       \r
+            p.x=lon;\r
+            p.y=lat;  \r
+            return p;\r
+          }\r
+    \r
+/* Function to compute latitude, phi3, for the inverse of the Equidistant\r
+   Conic projection.\r
+-----------------------------------------------------------------*/\r
+       private function phi3z(ml:Number,e0:Number,e1:Number,e2:Number,e3:Number):Number \r
+       {\r
+    var phi:Number;\r
+    var dphi:Number;\r
+\r
+    phi = ml;\r
+    for (var i:int = 0; i < 15; i++) {\r
+      dphi = (ml + e1 * Math.sin(2.0 * phi) - e2 * Math.sin(4.0 * phi) + e3 * Math.sin(6.0 * phi))/ e0 - phi;\r
+      phi += dphi;\r
+      if (Math.abs(dphi) <= .0000000001) {\r
+        return phi;\r
+      }\r
+    }\r
+    trace("PHI3Z-CONV:Latitude failed to converge after 15 iterations");\r
+    return 0;\r
+       }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjEqui.as b/com/gradoservice/proj4as/proj/ProjEqui.as
new file mode 100755 (executable)
index 0000000..f0bd98f
--- /dev/null
@@ -0,0 +1,90 @@
+/*******************************************************************************\r
+NAME                             EQUIRECTANGULAR \r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the Equirectangular projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+PROGRAMMER              DATE\r
+----------              ----\r
+T. Mittan              Mar, 1993\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
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.Datum;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       \r
+       public class ProjEqui extends AbstractProjProjection\r
+       {\r
+               public function ProjEqui(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+\r
+\r
+  override public function init():void\r
+  {\r
+    if(!this.x0) this.x0=0;\r
+    if(!this.y0) this.y0=0;\r
+    if(!this.lat0) this.lat0=0;\r
+    if(!this.long0) this.long0=0;\r
+    ///this.t2;\r
+  }\r
+\r
+\r
+\r
+/* Equirectangular forward equations--mapping lat,long to x,y\r
+  ---------------------------------------------------------*/\r
+  override public function forward(p:ProjPoint):ProjPoint \r
+  {\r
+\r
+    var lon:Number=p.x;                                \r
+    var lat:Number=p.y;                        \r
+\r
+    var dlon:Number = ProjConstants.adjust_lon(lon - this.long0);\r
+    var x:Number = this.x0 +this. a * dlon *Math.cos(this.lat0);\r
+    var y:Number = this.y0 + this.a * lat;\r
+\r
+    this.t1=x;\r
+    this.t2=Math.cos(this.lat0);\r
+    p.x=x;\r
+    p.y=y;\r
+    return p;\r
+  }  //equiFwd()\r
+\r
+\r
+\r
+/* Equirectangular inverse equations--mapping x,y to lat/long\r
+  ---------------------------------------------------------*/\r
+   override public function inverse(p:ProjPoint):ProjPoint\r
+   {\r
+\r
+    p.x -= this.x0;\r
+    p.y -= this.y0;\r
+    var lat:Number = p.y /this. a;\r
+\r
+    if ( Math.abs(lat) > ProjConstants.HALF_PI) {\r
+        trace("equi:Inv:DataError");\r
+    }\r
+    var lon:Number = ProjConstants.adjust_lon(this.long0 + p.x / (this.a * Math.cos(this.lat0)));\r
+    p.x=lon;\r
+    p.y=lat;\r
+    \r
+    return p;\r
+  }//equiInv()\r
+                               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjGauss.as b/com/gradoservice/proj4as/proj/ProjGauss.as
new file mode 100755 (executable)
index 0000000..621912b
--- /dev/null
@@ -0,0 +1,62 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjGauss extends AbstractProjProjection\r
+       {\r
+\r
+       protected var phic0:Number;\r
+       protected var ratexp:Number;\r
+\r
+               public function ProjGauss(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+  override public function init():void\r
+       {\r
+    var sphi:Number = Math.sin(this.lat0);\r
+    var cphi:Number = Math.cos(this.lat0);  \r
+    cphi *= cphi;\r
+    this.rc = Math.sqrt(1.0 - this.es) / (1.0 - this.es * sphi * sphi);\r
+    this.c = Math.sqrt(1.0 + this.es * cphi * cphi / (1.0 - this.es));\r
+    this.phic0 = Math.asin(sphi / this.c);\r
+    this.ratexp = 0.5 * this.c * this.e;\r
+    this.k = Math.tan(0.5 * this.phic0 + ProjConstants.FORTPI) / (Math.pow(Math.tan(0.5*this.lat0 + ProjConstants.FORTPI), this.c) * ProjConstants.srat(this.e*sphi, this.ratexp));\r
+       }\r
+\r
+  override public function forward(p:ProjPoint):ProjPoint \r
+       {\r
+    var lon:Number = p.x;\r
+    var lat:Number = p.y;\r
+\r
+    p.y = 2.0 * Math.atan( this.k * Math.pow(Math.tan(0.5 * lat + ProjConstants.FORTPI), this.c) * ProjConstants.srat(this.e * Math.sin(lat), this.ratexp) ) - ProjConstants.HALF_PI;\r
+    p.x = this.c * lon;\r
+    return p;\r
+       }\r
+\r
+   override public function inverse(p:ProjPoint):ProjPoint\r
+   {\r
+    var DEL_TOL:Number = 1e-14;\r
+    var lon:Number = p.x / this.c;\r
+    var lat:Number = p.y;\r
+    var num:Number = Math.pow(Math.tan(0.5 * lat + ProjConstants.FORTPI)/this.k, 1./this.c);\r
+    for (var i:int = ProjConstants.MAX_ITER; i>0; --i) {\r
+      lat = 2.0 * Math.atan(num * ProjConstants.srat(this.e * Math.sin(p.y), -0.5 * this.e)) - ProjConstants.HALF_PI;\r
+      if (Math.abs(lat - p.y) < DEL_TOL) break;\r
+      p.y = lat;\r
+    }  \r
+    /* convergence failed */\r
+    if (!i) {\r
+      trace("gauss:inverse:convergence failed");\r
+      return null;\r
+    }\r
+    p.x = lon;\r
+    p.y = lat;\r
+    return p;\r
+  }            \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjGstmerc.as b/com/gradoservice/proj4as/proj/ProjGstmerc.as
new file mode 100755 (executable)
index 0000000..c7325b5
--- /dev/null
@@ -0,0 +1,74 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjGstmerc extends AbstractProjProjection\r
+       {\r
+               \r
+               private var cp:Number;\r
+               private var lc:Number;\r
+               private var n2:Number;\r
+               private var rs:Number;\r
+               private var xs:Number;\r
+               private var ys:Number;           \r
+               \r
+               public function ProjGstmerc(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+  override public function init():void\r
+       {\r
+    // array of:  a, b, lon0, lat0, k0, x0, y0\r
+      var temp:Number = this.b / this.a;\r
+      this.e = Math.sqrt(1.0 - temp*temp);\r
+      this.lc= this.long0;\r
+      this.rs= Math.sqrt(1.0+this.e*this.e*Math.pow(Math.cos(this.lat0),4.0)/(1.0-this.e*this.e));\r
+      var sinz:Number= Math.sin(this.lat0);\r
+      var pc:Number= Math.asin(sinz/this.rs);\r
+      var sinzpc:Number= Math.sin(pc);\r
+      this.cp= ProjConstants.latiso(0.0,pc,sinzpc)-this.rs*ProjConstants.latiso(this.e,this.lat0,sinz);\r
+      this.n2= this.k0*this.a*Math.sqrt(1.0-this.e*this.e)/(1.0-this.e*this.e*sinz*sinz);\r
+      this.xs= this.x0;\r
+      this.ys= this.y0-this.n2*pc;\r
+\r
+      if (!this.title) this.title = "Gauss Schreiber transverse mercator";\r
+    }\r
+\r
+\r
+    // forward equations--mapping lat,long to x,y\r
+    // -----------------------------------------------------------------\r
+  override public function forward(p:ProjPoint):ProjPoint \r
+       {\r
+      var lon:Number= p.x;\r
+      var lat:Number= p.y;\r
+\r
+      var L:Number= this.rs*(lon-this.lc);\r
+      var Ls:Number= this.cp+(this.rs*ProjConstants.latiso(this.e,lat,Math.sin(lat)));\r
+      var lat1:Number= Math.asin(Math.sin(L)/ProjConstants.cosh(Ls));\r
+      var Ls1:Number= ProjConstants.latiso(0.0,lat1,Math.sin(lat1));\r
+      p.x= this.xs+(this.n2*Ls1);\r
+      p.y= this.ys+(this.n2*Math.atan(ProjConstants.sinh(Ls)/Math.cos(L)));\r
+      return p;\r
+    }\r
+\r
+  // inverse equations--mapping x,y to lat/long\r
+  // -----------------------------------------------------------------\r
+   override public function inverse(p:ProjPoint):ProjPoint\r
+   {\r
+    var x:Number= p.x;\r
+    var y:Number= p.y;\r
+\r
+    var L:Number= Math.atan(ProjConstants.sinh((x-this.xs)/this.n2)/Math.cos((y-this.ys)/this.n2));\r
+    var lat1:Number= Math.asin(Math.sin((y-this.ys)/this.n2)/ProjConstants.cosh((x-this.xs)/this.n2));\r
+    var LC:Number= ProjConstants.latiso(0.0,lat1,Math.sin(lat1));\r
+    p.x= this.lc+L/this.rs;\r
+    p.y= ProjConstants.invlatiso(this.e,(LC-this.cp)/this.rs);\r
+    return p;\r
+  }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjLaea.as b/com/gradoservice/proj4as/proj/ProjLaea.as
new file mode 100755 (executable)
index 0000000..9af7a6b
--- /dev/null
@@ -0,0 +1,127 @@
+/*******************************************************************************\r
+NAME                  LAMBERT AZIMUTHAL EQUAL-AREA\r
\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the Lambert Azimuthal Equal-Area projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+PROGRAMMER              DATE            \r
+----------              ----           \r
+D. Steinwand, EROS      March, 1991   \r
+\r
+This function was adapted from the Lambert Azimuthal Equal Area projection\r
+code (FORTRAN) in the General Cartographic Transformation Package software\r
+which is available from the U.S. Geological Survey National Mapping Division.\r
\r
+ALGORITHM REFERENCES\r
+\r
+1.  "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,\r
+    The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.\r
+\r
+2.  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
+3.  "Software Documentation for GCTP General Cartographic Transformation\r
+    Package", U.S. Geological Survey National Mapping Division, May 1982.\r
+*******************************************************************************/\r
+\r
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjLaea extends AbstractProjProjection\r
+       {\r
+               private var sin_lat_o:Number;\r
+               private var cos_lat_o:Number;\r
+               \r
+               public function ProjLaea(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+               /* Initialize the Lambert Azimuthal Equal Area projection\r
+                 ------------------------------------------------------*/\r
+                 override public function init():void\r
+                 {\r
+                   this.sin_lat_o=Math.sin(this.lat0);\r
+                   this.cos_lat_o=Math.cos(this.lat0);\r
+                 }\r
+               \r
+               /* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y\r
+                 -----------------------------------------------------------------------*/\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+               \r
+                   /* Forward equations\r
+                     -----------------*/\r
+                   var lon:Number=p.x;\r
+                   var lat:Number=p.y;\r
+                   var delta_lon:Number = ProjConstants.adjust_lon(lon - this.long0);\r
+               \r
+                   //v 1.0\r
+                   var sin_lat:Number=Math.sin(lat);\r
+                   var cos_lat:Number=Math.cos(lat);\r
+               \r
+                   var sin_delta_lon:Number=Math.sin(delta_lon);\r
+                   var cos_delta_lon:Number=Math.cos(delta_lon);\r
+               \r
+                   var g:Number =this.sin_lat_o * sin_lat +this.cos_lat_o * cos_lat * cos_delta_lon;\r
+                   if (g == -1.0) {\r
+                     trace("laea:fwd:Point projects to a circle of radius ");\r
+                     return null;\r
+                   }\r
+                   var ksp:Number = this.a * Math.sqrt(2.0 / (1.0 + g));\r
+                   var x:Number = ksp * cos_lat * sin_delta_lon + this.x0;\r
+                   var y:Number = ksp * (this.cos_lat_o * sin_lat - this.sin_lat_o * cos_lat * cos_delta_lon) + this.y0;\r
+                   p.x = x;\r
+                   p.y = y\r
+                   return p;\r
+                 }//lamazFwd()\r
+               \r
+               /* Inverse equations\r
+                 -----------------*/\r
+                 override public function inverse(p:ProjPoint):ProjPoint\r
+                 {\r
+                   p.x -= this.x0;\r
+                   p.y -= this.y0;\r
+               \r
+                   var Rh:Number = Math.sqrt(p.x *p.x +p.y * p.y);\r
+                   var temp:Number = Rh / (2.0 * this.a);\r
+               \r
+                   if (temp > 1) {\r
+                     trace("laea:Inv:DataError");\r
+                     return null;\r
+                   }\r
+               \r
+                   var z:Number = 2.0 * ProjConstants.asinz(temp);\r
+                   var sin_z:Number=Math.sin(z);\r
+                   var cos_z:Number=Math.cos(z);\r
+               \r
+                   var lon:Number =this.long0;\r
+                   if (Math.abs(Rh) > ProjConstants.EPSLN) {\r
+                      var lat:Number = ProjConstants.asinz(this.sin_lat_o * cos_z +this. cos_lat_o * sin_z *p.y / Rh);\r
+                      temp =Math.abs(this.lat0) - ProjConstants.HALF_PI;\r
+                      if (Math.abs(temp) > ProjConstants.EPSLN) {\r
+                         temp = cos_z -this.sin_lat_o * Math.sin(lat);\r
+                         if(temp!=0.0) lon=ProjConstants.adjust_lon(this.long0+Math.atan2(p.x*sin_z*this.cos_lat_o,temp*Rh));\r
+                      } else if (this.lat0 < 0.0) {\r
+                         lon = ProjConstants.adjust_lon(this.long0 - Math.atan2(-p.x,p.y));\r
+                      } else {\r
+                         lon = ProjConstants.adjust_lon(this.long0 + Math.atan2(p.x, -p.y));\r
+                      }\r
+                   } else {\r
+                     lat = this.lat0;\r
+                   }\r
+                   //return(OK);\r
+                   p.x = lon;\r
+                   p.y = lat;\r
+                   return p;\r
+                 }//lamazInv()\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjLcc.as b/com/gradoservice/proj4as/proj/ProjLcc.as
new file mode 100755 (executable)
index 0000000..6e043ab
--- /dev/null
@@ -0,0 +1,161 @@
+/*******************************************************************************\r
+NAME                            LAMBERT CONFORMAL CONIC\r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the Lambert Conformal Conic projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\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
+*******************************************************************************/\r
+\r
+\r
+//<2104> +proj=lcc +lat_1=10.16666666666667 +lat_0=10.16666666666667 +lon_0=-71.60561777777777 +k_0=1 +x0=-17044 +x0=-23139.97 +ellps=intl +units=m +no_defs  no_defs\r
+\r
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjLcc extends AbstractProjProjection\r
+       {\r
+               private var f0:Number;\r
+               \r
+               public function ProjLcc(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+                 override public function init():void\r
+                 {\r
+                   // array of:  r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north\r
+                   //double c_lat;                   /* center latitude                      */\r
+                   //double c_lon;                   /* center longitude                     */\r
+                   //double lat1;                    /* first standard parallel              */\r
+                   //double lat2;                    /* second standard parallel             */\r
+                   //double r_maj;                   /* major axis                           */\r
+                   //double r_min;                   /* minor axis                           */\r
+                   //double false_east;              /* x offset in meters                   */\r
+                   //double false_north;             /* y offset in meters                   */\r
+               \r
+                     if (!this.lat2){this.lat2=this.lat0;}//if lat2 is not defined\r
+                     if (!this.k0) this.k0 = 1.0;\r
+               \r
+                   // Standard Parallels cannot be equal and on opposite sides of the equator\r
+                     if (Math.abs(this.lat1+this.lat2) < ProjConstants.EPSLN) {\r
+                       trace("lcc:init: Equal Latitudes");\r
+                       return;\r
+                     }\r
+               \r
+                     var temp:Number = this.b / this.a;\r
+                     this.e = Math.sqrt(1.0 - temp*temp);\r
+               \r
+                     var sin1:Number = Math.sin(this.lat1);\r
+                     var cos1:Number = Math.cos(this.lat1);\r
+                     var ms1:Number= ProjConstants.msfnz(this.e, sin1, cos1);\r
+                     var ts1:Number = ProjConstants.tsfnz(this.e, this.lat1, sin1);\r
+               \r
+                     var sin2:Number = Math.sin(this.lat2);\r
+                     var cos2:Number = Math.cos(this.lat2);\r
+                     var ms2:Number = ProjConstants.msfnz(this.e, sin2, cos2);\r
+                     var ts2:Number = ProjConstants.tsfnz(this.e, this.lat2, sin2);\r
+               \r
+                     var ts0:Number = ProjConstants.tsfnz(this.e, this.lat0, Math.sin(this.lat0));\r
+               \r
+                     if (Math.abs(this.lat1 - this.lat2) > ProjConstants.EPSLN) {\r
+                       this.ns = Math.log(ms1/ms2)/Math.log(ts1/ts2);\r
+                     } else {\r
+                       this.ns = sin1;\r
+                     }\r
+                     this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns));\r
+                     this.rh = this.a * this.f0 * Math.pow(ts0, this.ns);\r
+                     if (!this.title) this.title = "Lambert Conformal Conic";\r
+                   }\r
+               \r
+               \r
+                   // Lambert Conformal conic forward equations--mapping lat,long to x,y\r
+                   // -----------------------------------------------------------------\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                     var lon:Number = p.x;\r
+                     var lat:Number = p.y;\r
+               \r
+                   // convert to radians\r
+                     if ( lat <= 90.0 && lat >= -90.0 && lon <= 180.0 && lon >= -180.0) {\r
+                       //lon = lon * Proj4js.common.D2R;\r
+                       //lat = lat * Proj4js.common.D2R;\r
+                     } else {\r
+                       trace("lcc:forward: llInputOutOfRange: "+ lon +" : " + lat);\r
+                       return null;\r
+                     }\r
+               \r
+                     var con:Number  = Math.abs( Math.abs(lat) - ProjConstants.HALF_PI);\r
+                     var ts:Number;\r
+                     var rh1:Number;\r
+                     if (con > ProjConstants.EPSLN) {\r
+                       ts = ProjConstants.tsfnz(this.e, lat, Math.sin(lat) );\r
+                       rh1 = this.a * this.f0 * Math.pow(ts, this.ns);\r
+                     } else {\r
+                       con = lat * this.ns;\r
+                       if (con <= 0) {\r
+                         trace("lcc:forward: No Projection");\r
+                         return null;\r
+                       }\r
+                       rh1 = 0;\r
+                     }\r
+                     var theta:Number = this.ns * ProjConstants.adjust_lon(lon - this.long0);\r
+                     p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0;\r
+                     p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0;\r
+               \r
+                     return p;\r
+                   }\r
+               \r
+                 // Lambert Conformal Conic inverse equations--mapping x,y to lat/long\r
+                 // -----------------------------------------------------------------\r
+                 override public function inverse(p:ProjPoint):ProjPoint\r
+                 {\r
+                   var rh1:Number;\r
+                   var con:Number;\r
+                   var ts:Number;\r
+                   var lat:Number;\r
+                   var lon:Number;                 \r
+                   var x:Number = (p.x - this.x0)/this.k0;\r
+                   var y:Number  = (this.rh - (p.y - this.y0)/this.k0);\r
+                   if (this.ns > 0) {\r
+                     rh1 = Math.sqrt (x * x + y * y);\r
+                     con = 1.0;\r
+                   } else {\r
+                     rh1 = -Math.sqrt (x * x + y * y);\r
+                     con = -1.0;\r
+                   }\r
+                   var theta:Number = 0.0;\r
+                   if (rh1 != 0) {\r
+                     theta = Math.atan2((con * x),(con * y));\r
+                   }\r
+                   if ((rh1 != 0) || (this.ns > 0.0)) {\r
+                     con = 1.0/this.ns;\r
+                     ts = Math.pow((rh1/(this.a * this.f0)), con);\r
+                     lat = ProjConstants.phi2z(this.e, ts);\r
+                     if (lat == -9999) return null;\r
+                   } else {\r
+                     lat = -ProjConstants.HALF_PI;\r
+                   }\r
+                   lon = ProjConstants.adjust_lon(theta/this.ns + this.long0);\r
+               \r
+                   p.x = lon;\r
+                   p.y = lat;\r
+                   return p;\r
+                 }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjLonglat.as b/com/gradoservice/proj4as/proj/ProjLonglat.as
new file mode 100755 (executable)
index 0000000..e907593
--- /dev/null
@@ -0,0 +1,13 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.Datum;\r
+                       \r
+       public class ProjLonglat extends AbstractProjProjection\r
+       {\r
+               public function ProjLonglat(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjMerc.as b/com/gradoservice/proj4as/proj/ProjMerc.as
new file mode 100755 (executable)
index 0000000..8854359
--- /dev/null
@@ -0,0 +1,120 @@
+/*******************************************************************************\r
+NAME                            MERCATOR\r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the Mercator projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+PROGRAMMER              DATE\r
+----------              ----\r
+D. Steinwand, EROS      Nov, 1991\r
+T. Mittan              Mar, 1993\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
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjMerc extends AbstractProjProjection\r
+       {\r
+               public function ProjMerc(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+                 override public function init():void\r
+                 {\r
+                       //?this.temp = this.r_minor / this.r_major;\r
+                       //this.temp = this.b / this.a;\r
+                       //this.es = 1.0 - Math.sqrt(this.temp);\r
+                       //this.e = Math.sqrt( this.es );\r
+                       //?this.m1 = Math.cos(this.lat_origin) / (Math.sqrt( 1.0 - this.es * Math.sin(this.lat_origin) * Math.sin(this.lat_origin)));\r
+                       //this.m1 = Math.cos(0.0) / (Math.sqrt( 1.0 - this.es * Math.sin(0.0) * Math.sin(0.0)));\r
+                   if (this.lat_ts) {\r
+                     if (this.sphere) {\r
+                       this.k0 = Math.cos(this.lat_ts);\r
+                     } else {\r
+                       this.k0 = ProjConstants.msfnz(this.es, Math.sin(this.lat_ts), Math.cos(this.lat_ts));\r
+                     }\r
+                   }\r
+                 }\r
+               \r
+               /* Mercator forward equations--mapping lat,long to x,y\r
+                 --------------------------------------------------*/\r
+               \r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {     \r
+                   //alert("ll2m coords : "+coords);\r
+                   var lon:Number = p.x;\r
+                   var lat:Number = p.y;\r
+                   // convert to radians\r
+                   if ( lat*ProjConstants.R2D > 90.0 && \r
+                         lat*ProjConstants.R2D < -90.0 && \r
+                         lon*ProjConstants.R2D > 180.0 && \r
+                         lon*ProjConstants.R2D < -180.0) {\r
+                               trace("merc:forward: llInputOutOfRange: "+ lon +" : " + lat);\r
+                     return null;\r
+                   }\r
+               \r
+                   var x:Number,y:Number;\r
+                   if(Math.abs( Math.abs(lat) - ProjConstants.HALF_PI)  <= ProjConstants.EPSLN) {\r
+                     trace("merc:forward: ll2mAtPoles");\r
+                     return null;\r
+                   } else {\r
+                     if (this.sphere) {\r
+                       x = this.x0 + this.a * this.k0 * ProjConstants.adjust_lon(lon - this.long0);\r
+                       y = this.y0 + this.a * this.k0 * Math.log(Math.tan(ProjConstants.FORTPI + 0.5*lat));\r
+                     } else {\r
+                       var sinphi:Number = Math.sin(lat);\r
+                       var ts:Number = ProjConstants.tsfnz(this.e,lat,sinphi);\r
+                       x = this.x0 + this.a * this.k0 * ProjConstants.adjust_lon(lon - this.long0);\r
+                       y = this.y0 - this.a * this.k0 * Math.log(ts);\r
+                     }\r
+                     p.x = x; \r
+                     p.y = y;\r
+                     return p;\r
+                   }\r
+                 }\r
+               \r
+               \r
+                 /* Mercator inverse equations--mapping x,y to lat/long\r
+                 --------------------------------------------------*/\r
+                 override public function inverse(p:ProjPoint):ProjPoint\r
+                 {\r
+                   var x:Number = p.x - this.x0;\r
+                   var y:Number = p.y - this.y0;\r
+                   var lon:Number,lat:Number;\r
+               \r
+                   if (this.sphere) {\r
+                     lat = ProjConstants.HALF_PI - 2.0 * Math.atan(Math.exp(-y / this.a * this.k0));\r
+                   } else {\r
+                     var ts:Number = Math.exp(-y / (this.a * this.k0));\r
+                     lat = ProjConstants.phi2z(this.e,ts);\r
+                     if(lat == -9999) {\r
+                       trace("merc:inverse: lat = -9999");\r
+                       return null;\r
+                     }\r
+                   }\r
+                   lon = ProjConstants.adjust_lon(this.long0+ x / (this.a * this.k0));\r
+               \r
+                   p.x = lon;\r
+                   p.y = lat;\r
+                   return p;\r
+                 }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjMill.as b/com/gradoservice/proj4as/proj/ProjMill.as
new file mode 100755 (executable)
index 0000000..36ebb4d
--- /dev/null
@@ -0,0 +1,83 @@
+/*******************************************************************************\r
+NAME                    MILLER CYLINDRICAL \r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the Miller Cylindrical projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+PROGRAMMER              DATE            \r
+----------              ----           \r
+T. Mittan              March, 1993\r
+\r
+This function was adapted from the Lambert Azimuthal Equal Area projection\r
+code (FORTRAN) in the General Cartographic Transformation Package software\r
+which is available from the U.S. Geological Survey National Mapping Division.\r
\r
+ALGORITHM REFERENCES\r
+\r
+1.  "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,\r
+    The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.\r
+\r
+2.  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
+3.  "Software Documentation for GCTP General Cartographic Transformation\r
+    Package", U.S. Geological Survey National Mapping Division, May 1982.\r
+*******************************************************************************/\r
+\r
+\r
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjMill extends AbstractProjProjection\r
+       {\r
+               public function ProjMill(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+                 override public function init():void\r
+                 {\r
+               //no-op\r
+                 }\r
+\r
+\r
+                 /* Miller Cylindrical forward equations--mapping lat,long to x,y\r
+                   ------------------------------------------------------------*/\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                   var lon:Number=p.x;\r
+                   var lat:Number=p.y;\r
+                   /* Forward equations\r
+                     -----------------*/\r
+                   var dlon:Number = ProjConstants.adjust_lon(lon -this.long0);\r
+                   var x:Number = this.x0 + this.a * dlon;\r
+                   var y:Number = this.y0 + this.a * Math.log(Math.tan((ProjConstants.PI / 4.0) + (lat / 2.5))) * 1.25;\r
+               \r
+                   p.x=x;\r
+                   p.y=y;\r
+                   return p;\r
+                 }//millFwd()\r
+               \r
+                 /* Miller Cylindrical inverse equations--mapping x,y to lat/long\r
+                   ------------------------------------------------------------*/\r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                   p.x -= this.x0;\r
+                   p.y -= this.y0;\r
+               \r
+                   var lon:Number = ProjConstants.adjust_lon(this.long0 + p.x /this.a);\r
+                   var lat:Number = 2.5 * (Math.atan(Math.exp(0.8*p.y/this.a)) - ProjConstants.PI / 4.0);\r
+               \r
+                   p.x=lon;\r
+                   p.y=lat;\r
+                   return p;\r
+                 }//millInv()          \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjMoll.as b/com/gradoservice/proj4as/proj/ProjMoll.as
new file mode 100755 (executable)
index 0000000..5e29222
--- /dev/null
@@ -0,0 +1,113 @@
+/*******************************************************************************\r
+NAME                            MOLLWEIDE\r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the MOllweide projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+PROGRAMMER              DATE\r
+----------              ----\r
+D. Steinwand, EROS      May, 1991;  Updated Sept, 1992; Updated Feb, 1993\r
+S. Nelson, EDC         Jun, 2993;      Made corrections in precision and\r
+                                       number of iterations.\r
+\r
+ALGORITHM REFERENCES\r
+\r
+1.  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
+2.  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
+\r
+\r
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjMoll extends AbstractProjProjection\r
+       {\r
+               public function ProjMoll(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+                 override public function init():void\r
+                 {\r
+               //no-op\r
+                 }\r
+\r
+  /* Mollweide forward equations--mapping lat,long to x,y\r
+    ----------------------------------------------------*/\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                   /* Forward equations\r
+                     -----------------*/\r
+                   var lon:Number=p.x;\r
+                   var lat:Number=p.y;\r
+               \r
+                   var delta_lon:Number = ProjConstants.adjust_lon(lon - this.long0);\r
+                   var theta:Number = lat;\r
+                   var con:Number = ProjConstants.PI * Math.sin(lat);\r
+               \r
+                   /* Iterate using the Newton-Raphson method to find theta\r
+                     -----------------------------------------------------*/\r
+                   for (var i:int=0;;i++) {\r
+                      var delta_theta:Number = -(theta + Math.sin(theta) - con)/ (1.0 + Math.cos(theta));\r
+                      theta += delta_theta;\r
+                      if (Math.abs(delta_theta) < ProjConstants.EPSLN) break;\r
+                      if (i >= 50) {\r
+                         trace("moll:Fwd:IterationError");\r
+                        //return(241);\r
+                      }\r
+                   }\r
+                   theta /= 2.0;\r
+               \r
+                   /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting"\r
+                      this is done here because of precision problems with "cos(theta)"\r
+                      --------------------------------------------------------------------------*/\r
+                   if (ProjConstants.PI/2 - Math.abs(lat) < ProjConstants.EPSLN) delta_lon =0;\r
+                   var x:Number = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0;\r
+                   var y:Number = 1.4142135623731 * this.a * Math.sin(theta) + this.y0;\r
+               \r
+                   p.x=x;\r
+                   p.y=y;\r
+                   return p;\r
+                 }\r
+               \r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                   var theta:Number;\r
+                   var arg:Number;\r
+               \r
+                   /* Inverse equations\r
+                     -----------------*/\r
+                   p.x-= this.x0;\r
+                   //~ p.y -= this.y0;\r
+                   arg = p.y /  (1.4142135623731 * this.a);\r
+               \r
+                   /* Because of division by zero problems, 'arg' can not be 1.0.  Therefore\r
+                      a number very close to one is used instead.\r
+                      -------------------------------------------------------------------*/\r
+                   if(Math.abs(arg) > 0.999999999999) arg=0.999999999999;\r
+                   theta =Math.asin(arg);\r
+                   var lon:Number = ProjConstants.adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta))));\r
+                   if(lon < (-ProjConstants.PI)) lon= -ProjConstants.PI;\r
+                   if(lon > ProjConstants.PI) lon= ProjConstants.PI;\r
+                   arg = (2.0 * theta + Math.sin(2.0 * theta)) / ProjConstants.PI;\r
+                   if(Math.abs(arg) > 1.0)arg=1.0;\r
+                   var lat:Number = Math.asin(arg);\r
+                   //return(OK);\r
+               \r
+                   p.x=lon;\r
+                   p.y=lat;\r
+                   return p;\r
+                 }             \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjNzmg.as b/com/gradoservice/proj4as/proj/ProjNzmg.as
new file mode 100755 (executable)
index 0000000..d34eeba
--- /dev/null
@@ -0,0 +1,292 @@
+/*******************************************************************************\r
+NAME                            NEW ZEALAND MAP GRID\r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the New Zealand Map Grid projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+\r
+ALGORITHM REFERENCES\r
+\r
+1.  Department of Land and Survey Technical Circular 1973/32\r
+      http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf\r
+\r
+2.  OSG Technical Report 4.1\r
+      http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf\r
+\r
+\r
+IMPLEMENTATION NOTES\r
+\r
+The two references use different symbols for the calculated values. This\r
+implementation uses the variable names similar to the symbols in reference [1].\r
+\r
+The alogrithm uses different units for delta latitude and delta longitude.\r
+The delta latitude is assumed to be in units of seconds of arc x 10^-5.\r
+The delta longitude is the usual radians. Look out for these conversions.\r
+\r
+The algorithm is described using complex arithmetic. There were three\r
+options:\r
+   * find and use a Javascript library for complex arithmetic\r
+   * write my own complex library\r
+   * expand the complex arithmetic by hand to simple arithmetic\r
+\r
+This implementation has expanded the complex multiplication operations\r
+into parallel simple arithmetic operations for the real and imaginary parts.\r
+The imaginary part is way over to the right of the display; this probably\r
+violates every coding standard in the world, but, to me, it makes it much\r
+more obvious what is going on.\r
+\r
+The following complex operations are used:\r
+   - addition\r
+   - multiplication\r
+   - division\r
+   - complex number raised to integer power\r
+   - summation\r
+\r
+A summary of complex arithmetic operations:\r
+   (from http://en.wikipedia.org/wiki/Complex_arithmetic)\r
+   addition:       (a + bi) + (c + di) = (a + c) + (b + d)i\r
+   subtraction:    (a + bi) - (c + di) = (a - c) + (b - d)i\r
+   multiplication: (a + bi) x (c + di) = (ac - bd) + (bc + ad)i\r
+   division:       (a + bi) / (c + di) = [(ac + bd)/(cc + dd)] + [(bc - ad)/(cc + dd)]i\r
+\r
+The algorithm needs to calculate summations of simple and complex numbers. This is\r
+implemented using a for-loop, pre-loading the summed value to zero.\r
+\r
+The algorithm needs to calculate theta^2, theta^3, etc while doing a summation.\r
+There are three possible implementations:\r
+   - use Math.pow in the summation loop - except for complex numbers\r
+   - precalculate the values before running the loop\r
+   - calculate theta^n = theta^(n-1) * theta during the loop\r
+This implementation uses the third option for both real and complex arithmetic.\r
+\r
+For example\r
+   psi_n = 1;\r
+   sum = 0;\r
+   for (n = 1; n <=6; n++) {\r
+      psi_n1 = psi_n * psi;       // calculate psi^(n+1)\r
+      psi_n = psi_n1;\r
+      sum = sum + A[n] * psi_n;\r
+   }\r
+\r
+\r
+TEST VECTORS\r
+\r
+NZMG E, N:         2487100.638      6751049.719     metres\r
+NZGD49 long, lat:      172.739194       -34.444066  degrees\r
+\r
+NZMG E, N:         2486533.395      6077263.661     metres\r
+NZGD49 long, lat:      172.723106       -40.512409  degrees\r
+\r
+NZMG E, N:         2216746.425      5388508.765     metres\r
+NZGD49 long, lat:      169.172062       -46.651295  degrees\r
+\r
+Note that these test vectors convert from NZMG metres to lat/long referenced\r
+to NZGD49, not the more usual WGS84. The difference is about 70m N/S and about\r
+10m E/W.\r
+\r
+These test vectors are provided in reference [1]. Many more test\r
+vectors are available in\r
+   http://www.linz.govt.nz/docs/topography/topographicdata/placenamesdatabase/nznamesmar08.zip\r
+which is a catalog of names on the 260-series maps.\r
+\r
+\r
+EPSG CODES\r
+\r
+NZMG     EPSG:27200\r
+NZGD49   EPSG:4272\r
+\r
+http://spatialreference.org/ defines these as\r
+  Proj4js.defs["EPSG:4272"] = "+proj=longlat +ellps=intl +datum=nzgd49 +no_defs ";\r
+  Proj4js.defs["EPSG:27200"] = "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 +ellps=intl +datum=nzgd49 +units=m +no_defs ";\r
+\r
+\r
+LICENSE\r
+  Copyright: Stephen Irons 2008\r
+  Released under terms of the LGPL as per: http://www.gnu.org/copyleft/lesser.html\r
+\r
+*******************************************************************************/\r
+\r
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjNzmg extends AbstractProjProjection\r
+       {\r
+               private var A:Array = [];\r
+               private var B_re:Array = [];\r
+               private var B_im:Array = [];\r
+               private var C_re:Array = [];\r
+               private var C_im:Array = [];\r
+               private var D:Array = [];\r
+               private var iterations:int = 1;                                         \r
+               \r
+               public function ProjNzmg(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+                 override public function init():void\r
+                 {\r
+                   this.A[1]  = +0.6399175073;\r
+                   this.A[2]  = -0.1358797613;\r
+                   this.A[3]  = +0.063294409;\r
+                   this.A[4]  = -0.02526853;\r
+                   this.A[5]  = +0.0117879;\r
+                   this.A[6]  = -0.0055161;\r
+                   this.A[7]  = +0.0026906;\r
+                   this.A[8]  = -0.001333;\r
+                   this.A[9]  = +0.00067;\r
+                   this.A[10] = -0.00034;\r
+               \r
+                   this.B_re[1] = +0.7557853228;   this.B_im[1] =  0.0;\r
+                   this.B_re[2] = +0.249204646;    this.B_im[2] = +0.003371507;\r
+                   this.B_re[3] = -0.001541739;    this.B_im[3] = +0.041058560;\r
+                   this.B_re[4] = -0.10162907;     this.B_im[4] = +0.01727609;\r
+                   this.B_re[5] = -0.26623489;     this.B_im[5] = -0.36249218;\r
+                   this.B_re[6] = -0.6870983;      this.B_im[6] = -1.1651967;\r
+               \r
+                   this.C_re[1] = +1.3231270439;   this.C_im[1] =  0.0;\r
+                   this.C_re[2] = -0.577245789;    this.C_im[2] = -0.007809598;\r
+                   this.C_re[3] = +0.508307513;    this.C_im[3] = -0.112208952;\r
+                   this.C_re[4] = -0.15094762;     this.C_im[4] = +0.18200602;\r
+                   this.C_re[5] = +1.01418179;     this.C_im[5] = +1.64497696;\r
+                   this.C_re[6] = +1.9660549;      this.C_im[6] = +2.5127645;\r
+               \r
+                   this.D[1] = +1.5627014243;\r
+                   this.D[2] = +0.5185406398;\r
+                   this.D[3] = -0.03333098;\r
+                   this.D[4] = -0.1052906;\r
+                   this.D[5] = -0.0368594;\r
+                   this.D[6] = +0.007317;\r
+                   this.D[7] = +0.01220;\r
+                   this.D[8] = +0.00394;\r
+                   this.D[9] = -0.0013;\r
+                 }\r
+               \r
+                 /**\r
+                   New Zealand Map Grid Forward  - long/lat to x/y\r
+                   long/lat in radians\r
+                 */\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                   var lon:Number = p.x;\r
+                   var lat:Number = p.y;\r
+               \r
+                   var delta_lat:Number = lat - this.lat0;\r
+                   var delta_lon:Number = lon - this.long0;\r
+               \r
+                   // 1. Calculate d_phi and d_psi    ...                          // and d_lambda\r
+                   // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians.\r
+                   var d_phi:Number = delta_lat / ProjConstants.SEC_TO_RAD * 1E-5;       var d_lambda:Number = delta_lon;\r
+                   var d_phi_n:Number = 1;  // d_phi^0\r
+               \r
+                   var d_psi:Number = 0;\r
+                   for (var n:int = 1; n <= 10; n++) {\r
+                     d_phi_n = d_phi_n * d_phi;\r
+                     d_psi = d_psi + this.A[n] * d_phi_n;\r
+                   }\r
+               \r
+                   // 2. Calculate theta\r
+                   var th_re:Number = d_psi;                                              var th_im:Number = d_lambda;\r
+               \r
+                   // 3. Calculate z\r
+                   var th_n_re:Number = 1;                                                var th_n_im:Number = 0;  // theta^0\r
+                   var th_n_re1:Number;                                                   var th_n_im1:Number;\r
+               \r
+                   var z_re:Number = 0;                                                   var z_im:Number = 0;\r
+                   for (n = 1; n <= 6; n++) {\r
+                     th_n_re1 = th_n_re*th_re - th_n_im*th_im;                     th_n_im1 = th_n_im*th_re + th_n_re*th_im;\r
+                     th_n_re = th_n_re1;                                           th_n_im = th_n_im1;\r
+                     z_re = z_re + this.B_re[n]*th_n_re - this.B_im[n]*th_n_im;    z_im = z_im + this.B_im[n]*th_n_re + this.B_re[n]*th_n_im;\r
+                   }\r
+               \r
+                   // 4. Calculate easting and northing\r
+                   var x:Number = (z_im * this.a) + this.x0;\r
+                   var y:Number = (z_re * this.a) + this.y0;\r
+               \r
+                   p.x = x; p.y = y;\r
+               \r
+                   return p;\r
+                 }\r
+               \r
+               \r
+                 /**\r
+                   New Zealand Map Grid Inverse  -  x/y to long/lat\r
+                 */\r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                   var x:Number = p.x;\r
+                   var y:Number = p.y;\r
+               \r
+                   var delta_x:Number = x - this.x0;\r
+                   var delta_y:Number = y - this.y0;\r
+               \r
+                   // 1. Calculate z\r
+                   var z_re:Number = delta_y / this.a;                                              var z_im:Number = delta_x / this.a;\r
+               \r
+                   // 2a. Calculate theta - first approximation gives km accuracy\r
+                   var z_n_re:Number = 1;                                                           var z_n_im:Number = 0;  // z^0\r
+                   var z_n_re1:Number;                                                              var z_n_im1:Number;\r
+               \r
+                   var th_re:Number = 0;                                                            var th_im:Number = 0;\r
+                   for (var n:int = 1; n <= 6; n++) {\r
+                     z_n_re1 = z_n_re*z_re - z_n_im*z_im;                                    z_n_im1 = z_n_im*z_re + z_n_re*z_im;\r
+                     z_n_re = z_n_re1;                                                       z_n_im = z_n_im1;\r
+                     th_re = th_re + this.C_re[n]*z_n_re - this.C_im[n]*z_n_im;              th_im = th_im + this.C_im[n]*z_n_re + this.C_re[n]*z_n_im;\r
+                   }\r
+               \r
+                   // 2b. Iterate to refine the accuracy of the calculation\r
+                   //        0 iterations gives km accuracy\r
+                   //        1 iteration gives m accuracy -- good enough for most mapping applications\r
+                   //        2 iterations bives mm accuracy\r
+                   for (var i:int = 0; i < this.iterations; i++) {\r
+                      var th_n_re:Number = th_re;                                                      var th_n_im:Number = th_im;\r
+                      var th_n_re1:Number;                                                             var th_n_im1:Number;\r
+               \r
+                      var num_re:Number = z_re;                                                        var num_im:Number = z_im;\r
+                      for (n = 2; n <= 6; n++) {\r
+                        th_n_re1 = th_n_re*th_re - th_n_im*th_im;                               th_n_im1 = th_n_im*th_re + th_n_re*th_im;\r
+                        th_n_re = th_n_re1;                                                     th_n_im = th_n_im1;\r
+                        num_re = num_re + (n-1)*(this.B_re[n]*th_n_re - this.B_im[n]*th_n_im);  num_im = num_im + (n-1)*(this.B_im[n]*th_n_re + this.B_re[n]*th_n_im);\r
+                      }\r
+               \r
+                      th_n_re = 1;                                                              th_n_im = 0;\r
+                      var den_re:Number = this.B_re[1];                                                var den_im:Number = this.B_im[1];\r
+                      for (n = 2; n <= 6; n++) {\r
+                        th_n_re1 = th_n_re*th_re - th_n_im*th_im;                               th_n_im1 = th_n_im*th_re + th_n_re*th_im;\r
+                        th_n_re = th_n_re1;                                                     th_n_im = th_n_im1;\r
+                        den_re = den_re + n * (this.B_re[n]*th_n_re - this.B_im[n]*th_n_im);    den_im = den_im + n * (this.B_im[n]*th_n_re + this.B_re[n]*th_n_im);\r
+                      }\r
+               \r
+                      // Complex division\r
+                      var den2:Number = den_re*den_re + den_im*den_im;\r
+                      th_re = (num_re*den_re + num_im*den_im) / den2;                           th_im = (num_im*den_re - num_re*den_im) / den2;\r
+                   }\r
+               \r
+                   // 3. Calculate d_phi              ...                                    // and d_lambda\r
+                   var d_psi:Number = th_re;                                                        var d_lambda:Number = th_im;\r
+                   var d_psi_n:Number = 1;  // d_psi^0\r
+               \r
+                   var d_phi:Number = 0;\r
+                   for (n = 1; n <= 9; n++) {\r
+                      d_psi_n = d_psi_n * d_psi;\r
+                      d_phi = d_phi + this.D[n] * d_psi_n;\r
+                   }\r
+               \r
+                   // 4. Calculate latitude and longitude\r
+                   // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians.\r
+                   var lat:Number = this.lat0 + (d_phi * ProjConstants.SEC_TO_RAD * 1E5);\r
+                   var lon:Number = this.long0 +  d_lambda;\r
+               \r
+                   p.x = lon;\r
+                   p.y = lat;\r
+               \r
+                   return p;\r
+                 }             \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjOmerc.as b/com/gradoservice/proj4as/proj/ProjOmerc.as
new file mode 100755 (executable)
index 0000000..1a262f5
--- /dev/null
@@ -0,0 +1,299 @@
+/*******************************************************************************\r
+NAME                       OBLIQUE MERCATOR (HOTINE) \r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the Oblique Mercator projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+PROGRAMMER              DATE\r
+----------              ----\r
+T. Mittan              Mar, 1993\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
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjOmerc extends AbstractProjProjection\r
+       {\r
+               private var d:Number;           \r
+               private var f:Number;           \r
+               private var h:Number;           \r
+               private var j:Number;           \r
+               private var l:Number;   \r
+               private var p:Number;   \r
+               private var u:Number;           \r
+               private var dlon:Number;                \r
+               private var al:Number;\r
+               private var bl:Number;          \r
+               private var el:Number;          \r
+               private var com:Number;         \r
+               private var cos_p20:Number;             \r
+               private var cosaz:Number;               \r
+               private var cosgam:Number;              \r
+               private var at1:Number;         \r
+               private var gam:Number;         \r
+               private var gama:Number;\r
+               private var lon1:Number;\r
+               private var lon2:Number;\r
+               private var sin_p20:Number;                                             \r
+               private var sinaz:Number;       \r
+               private var singam:Number;              \r
+               private var ts:Number;          \r
+               private var ts1:Number;         \r
+               private var ts2:Number;         \r
+               \r
+               public function ProjOmerc(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+               \r
+                 override public function init():void\r
+                 {\r
+                   if (!this.mode) this.mode=0;\r
+                   if (!this.lon1)   {this.lon1=0;this.mode=1;}\r
+                   if (!this.lon2)   this.lon2=0;\r
+                   if (!this.lat2)    this.lat2=0;\r
+               \r
+                   /* Place parameters in static storage for common use\r
+                     -------------------------------------------------*/\r
+                   var temp:Number = this.b/ this.a;\r
+                   var es:Number = 1.0 - Math.pow(temp,2);\r
+                   var e:Number = Math.sqrt(es);\r
+               \r
+                   this.sin_p20=Math.sin(this.lat0);\r
+                   this.cos_p20=Math.cos(this.lat0);\r
+               \r
+                   this.con = 1.0 - this.es * this.sin_p20 * this.sin_p20;\r
+                   this.com = Math.sqrt(1.0 - es);\r
+                   this.bl = Math.sqrt(1.0 + this.es * Math.pow(this.cos_p20,4.0)/(1.0 - es));\r
+                   this.al = this.a * this.bl * this.k0 * this.com / this.con;\r
+                   if (Math.abs(this.lat0) < ProjConstants.EPSLN) {\r
+                      this.ts = 1.0;\r
+                      this.d = 1.0;\r
+                      this.el = 1.0;\r
+                   } else {\r
+                      this.ts = ProjConstants.tsfnz(this.e,this.lat0,this.sin_p20);\r
+                      this.con = Math.sqrt(this.con);\r
+                      this.d = this.bl * this.com / (this.cos_p20 * this.con);\r
+                      if ((this.d * this.d - 1.0) > 0.0) {\r
+                         if (this.lat0 >= 0.0) {\r
+                            this.f = this.d + Math.sqrt(this.d * this.d - 1.0);\r
+                         } else {\r
+                            this.f = this.d - Math.sqrt(this.d * this.d - 1.0);\r
+                         }\r
+                      } else {\r
+                        this.f = this.d;\r
+                      }\r
+                      this.el = this.f * Math.pow(this.ts,this.bl);\r
+                   }\r
+               \r
+                   //this.longc=52.60353916666667;\r
+               \r
+                   if (this.mode != 0) {\r
+                      this.g = .5 * (this.f - 1.0/this.f);\r
+                      this.gama = ProjConstants.asinz(Math.sin(this.alpha) / this.d);\r
+                      this.longc= this.longc - ProjConstants.asinz(this.g * Math.tan(this.gama))/this.bl;\r
+               \r
+                      /* Report parameters common to format B\r
+                      -------------------------------------*/\r
+                      //genrpt(azimuth * R2D,"Azimuth of Central Line:    ");\r
+                      //cenlon(lon_origin);\r
+                     // cenlat(lat_origin);\r
+               \r
+                      this.con = Math.abs(this.lat0);\r
+                      if ((this.con > ProjConstants.EPSLN) && (Math.abs(this.con - ProjConstants.HALF_PI) > ProjConstants.EPSLN)) {\r
+                           this.singam=Math.sin(this.gama);\r
+                           this.cosgam=Math.cos(this.gama);\r
+               \r
+                           this.sinaz=Math.sin(this.alpha);\r
+                           this.cosaz=Math.cos(this.alpha);\r
+               \r
+                           if (this.lat0>= 0) {\r
+                              this.u =  (this.al / this.bl) * Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz);\r
+                           } else {\r
+                              this.u =  -(this.al / this.bl) *Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz);\r
+                           }\r
+                         } else {\r
+                           trace("omerc:Init:DataError");\r
+                         }\r
+                      } else {\r
+                      this.sinphi =Math. sin(this.at1);\r
+                      this.ts1 = ProjConstants.tsfnz(this.e,this.lat1,this.sinphi);\r
+                      this.sinphi = Math.sin(this.lat2);\r
+                      this.ts2 = ProjConstants.tsfnz(this.e,this.lat2,this.sinphi);\r
+                      this.h = Math.pow(this.ts1,this.bl);\r
+                      this.l = Math.pow(this.ts2,this.bl);\r
+                      this.f = this.el/this.h;\r
+                      this.g = .5 * (this.f - 1.0/this.f);\r
+                      this.j = (this.el * this.el - this.l * this.h)/(this.el * this.el + this.l * this.h);\r
+                      this.p = (this.l - this.h) / (this.l + this.h);\r
+                      this.dlon = this.lon1 - this.lon2;\r
+                      if (this.dlon < -ProjConstants.PI) this.lon2 = this.lon2 - 2.0 * ProjConstants.PI;\r
+                      if (this.dlon > ProjConstants.PI) this.lon2 = this.lon2 + 2.0 * ProjConstants.PI;\r
+                      this.dlon = this.lon1 - this.lon2;\r
+                      this.longc = .5 * (this.lon1 + this.lon2) -Math.atan(this.j * Math.tan(.5 * this.bl * this.dlon)/this.p)/this.bl;\r
+                      this.dlon  = ProjConstants.adjust_lon(this.lon1 - this.longc);\r
+                      this.gama = Math.atan(Math.sin(this.bl * this.dlon)/this.g);\r
+                      this.alpha = ProjConstants.asinz(this.d * Math.sin(this.gama));\r
+               \r
+                      /* Report parameters common to format A\r
+                      -------------------------------------*/\r
+               \r
+                      if (Math.abs(this.lat1 - this.lat2) <= ProjConstants.EPSLN) {\r
+                         trace("omercInitDataError");\r
+                         //return(202);\r
+                      } else {\r
+                         this.con = Math.abs(this.lat1);\r
+                      }\r
+                      if ((this.con <= ProjConstants.EPSLN) || (Math.abs(this.con - ProjConstants.HALF_PI) <= ProjConstants.EPSLN)) {\r
+                          trace("omercInitDataError");\r
+                               //return(202);\r
+                      } else {\r
+                        if (Math.abs(Math.abs(this.lat0) - ProjConstants.HALF_PI) <= ProjConstants.EPSLN) {\r
+                           trace("omercInitDataError");\r
+                           //return(202);\r
+                        }\r
+                      }\r
+               \r
+                      this.singam=Math.sin(this.gam);\r
+                      this.cosgam=Math.cos(this.gam);\r
+               \r
+                      this.sinaz=Math.sin(this.alpha);\r
+                      this.cosaz=Math.cos(this.alpha);  \r
+               \r
+               \r
+                      if (this.lat0 >= 0) {\r
+                         this.u =  (this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz);\r
+                      } else {\r
+                         this.u = -(this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz);\r
+                      }\r
+                    }\r
+                 }\r
+               \r
+               \r
+                 /* Oblique Mercator forward equations--mapping lat,long to x,y\r
+                   ----------------------------------------------------------*/\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                   var theta:Number;           /* angle                                        */\r
+                   var sin_phi:Number, cos_phi:Number;/* sin and cos value                             */\r
+                   var b:Number;               /* temporary values                             */\r
+                   var c:Number, t:Number, tq:Number;  /* temporary values                             */\r
+                   var con:Number, n:Number, ml:Number;        /* cone constant, small m                       */\r
+                   var q:Number,us:Number,vl:Number;\r
+                   var ul:Number,vs:Number;\r
+                   var s:Number;\r
+                   var dlon:Number;\r
+                   var ts1:Number;\r
+               \r
+                   var lon:Number=p.x;\r
+                   var lat:Number=p.y;\r
+                   /* Forward equations\r
+                     -----------------*/\r
+                   sin_phi = Math.sin(lat);\r
+                   dlon = ProjConstants.adjust_lon(lon - this.longc);\r
+                   vl = Math.sin(this.bl * dlon);\r
+                   if (Math.abs(Math.abs(lat) - ProjConstants.HALF_PI) > ProjConstants.EPSLN) {\r
+                      ts1 = ProjConstants.tsfnz(this.e,lat,sin_phi);\r
+                      q = this.el / (Math.pow(ts1,this.bl));\r
+                      s = .5 * (q - 1.0 / q);\r
+                      t = .5 * (q + 1.0/ q);\r
+                      ul = (s * this.singam - vl * this.cosgam) / t;\r
+                      con = Math.cos(this.bl * dlon);\r
+                      if (Math.abs(con) < .0000001) {\r
+                         us = this.al * this.bl * dlon;\r
+                      } else {\r
+                         us = this.al * Math.atan((s * this.cosgam + vl * this.singam) / con)/this.bl;\r
+                         if (con < 0) us = us + ProjConstants.PI * this.al / this.bl;\r
+                      }\r
+                   } else {\r
+                      if (lat >= 0) {\r
+                         ul = this.singam;\r
+                      } else {\r
+                         ul = -this.singam;\r
+                      }\r
+                      us = this.al * lat / this.bl;\r
+                   }\r
+                   if (Math.abs(Math.abs(ul) - 1.0) <= ProjConstants.EPSLN) {\r
+                      //alert("Point projects into infinity","omer-for");\r
+                      trace("omercFwdInfinity");\r
+                      //return(205);\r
+                   }\r
+                   vs = .5 * this.al * Math.log((1.0 - ul)/(1.0 + ul)) / this.bl;\r
+                   us = us - this.u;\r
+                   var x:Number = this.x0 + vs * this.cosaz + us * this.sinaz;\r
+                   var y:Number = this.y0 + us * this.cosaz - vs * this.sinaz;\r
+               \r
+                   p.x=x;\r
+                   p.y=y;\r
+                   return p;\r
+                 }\r
+               \r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                   var delta_lon:Number;       /* Delta longitude (Given longitude - center    */\r
+                   var theta:Number;           /* angle                                        */\r
+                   var delta_theta:Number;     /* adjusted longitude                           */\r
+                   var sin_phi:Number, cos_phi:Number;/* sin and cos value                             */\r
+                   var b:Number;               /* temporary values                             */\r
+                   var c:Number, t:Number, tq:Number;  /* temporary values                             */\r
+                   var con:Number, n:Number, ml:Number;        /* cone constant, small m                       */\r
+                   var vs:Number,us:Number,q:Number,s:Number,ts1:Number;\r
+                   var vl:Number,ul:Number,bs:Number;\r
+                   var dlon:Number;\r
+                   var  flag:Number;\r
+               \r
+                   /* Inverse equations\r
+                     -----------------*/\r
+                   p.x -= this.x0;\r
+                   p.y -= this.y0;\r
+                   flag = 0;\r
+                   vs = p.x * this.cosaz - p.y * this.sinaz;\r
+                   us = p.y * this.cosaz + p.x * this.sinaz;\r
+                   us = us + this.u;\r
+                   q = Math.exp(-this.bl * vs / this.al);\r
+                   s = .5 * (q - 1.0/q);\r
+                   t = .5 * (q + 1.0/q);\r
+                   vl = Math.sin(this.bl * us / this.al);\r
+                   ul = (vl * this.cosgam + s * this.singam)/t;\r
+                   if (Math.abs(Math.abs(ul) - 1.0) <= ProjConstants.EPSLN)\r
+                      {\r
+                      var lon:Number = this.longc;\r
+                      if (ul >= 0.0) {\r
+                         var lat:Number = ProjConstants.HALF_PI;\r
+                      } else {\r
+                        lat = -ProjConstants.HALF_PI;\r
+                      }\r
+                   } else {\r
+                      con = 1.0 / this.bl;\r
+                      ts1 =Math.pow((this.el / Math.sqrt((1.0 + ul) / (1.0 - ul))),con);\r
+                      lat = ProjConstants.phi2z(this.e,ts1);\r
+                      //if (flag != 0)\r
+                         //return(flag);\r
+                      //~ con = Math.cos(this.bl * us /al);\r
+                      theta = this.longc - Math.atan2((s * this.cosgam - vl * this.singam) , con)/this.bl;\r
+                      lon = ProjConstants.adjust_lon(theta);\r
+                   }\r
+                   p.x=lon;\r
+                   p.y=lat;\r
+                   return p;\r
+                 }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjOrtho.as b/com/gradoservice/proj4as/proj/ProjOrtho.as
new file mode 100755 (executable)
index 0000000..2f38a6c
--- /dev/null
@@ -0,0 +1,131 @@
+/*******************************************************************************\r
+NAME                             ORTHOGRAPHIC \r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the Orthographic projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+PROGRAMMER              DATE\r
+----------              ----\r
+T. Mittan              Mar, 1993\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
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+                       \r
+       public class ProjOrtho extends AbstractProjProjection\r
+       {\r
+               \r
+               private var cos_p14:Number;\r
+               private var sin_p14:Number;\r
+               \r
+               public function ProjOrtho(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+                 override public function init():void\r
+                 {\r
+                   //double temp;                      /* temporary variable           */\r
+               \r
+                   /* Place parameters in static storage for common use\r
+                     -------------------------------------------------*/;\r
+                   this.sin_p14=Math.sin(this.lat0);\r
+                   this.cos_p14=Math.cos(this.lat0);   \r
+                 }\r
+               \r
+               \r
+                 /* Orthographic forward equations--mapping lat,long to x,y\r
+                   ---------------------------------------------------*/\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                   var sinphi:Number, cosphi:Number;   /* sin and cos value                            */\r
+                   var dlon:Number;            /* delta longitude value                        */\r
+                   var coslon:Number;          /* cos of longitude                             */\r
+                   var ksp:Number;             /* scale factor                                 */\r
+                   var g:Number;               \r
+                   var lon:Number=p.x;\r
+                   var lat:Number=p.y; \r
+                   var x:Number,y:Number;\r
+                   /* Forward equations\r
+                     -----------------*/\r
+                   dlon = ProjConstants.adjust_lon(lon - this.long0);\r
+               \r
+                   sinphi=Math.sin(lat);\r
+                   cosphi=Math.cos(lat);       \r
+               \r
+                   coslon = Math.cos(dlon);\r
+                   g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;\r
+                   ksp = 1.0;\r
+                   if ((g > 0) || (Math.abs(g) <= ProjConstants.EPSLN)) {\r
+                     x = this.a * ksp * cosphi * Math.sin(dlon);\r
+                     y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);\r
+                   } else {\r
+                     trace("orthoFwdPointError");\r
+                   }\r
+                   p.x=x;\r
+                   p.y=y;\r
+                   return p;\r
+                 }\r
+               \r
+               \r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                   var rh:Number;              /* height above ellipsoid                       */\r
+                   var x:Number,y:Number,z:Number;             /* angle                                        */\r
+                   var sinz:Number,cosz:Number,cosi:Number;    /* sin of z and cos of z                        */\r
+                   var temp:Number;\r
+                   var con:Number;\r
+                   var lon:Number , lat:Number;\r
+                   /* Inverse equations\r
+                     -----------------*/\r
+                   p.x -= this.x0;\r
+                   p.y -= this.y0;\r
+                   rh = Math.sqrt(p.x * p.x + p.y * p.y);\r
+                   if (rh > this.a + .0000001) {\r
+                     trace("orthoInvDataError");\r
+                   }\r
+                   z = ProjConstants.asinz(rh / this.a);\r
+               \r
+                   sinz=Math.sin(z);\r
+                   cosi=Math.cos(z);\r
+               \r
+                   lon = this.long0;\r
+                   if (Math.abs(rh) <= ProjConstants.EPSLN) {\r
+                     lat = this.lat0; \r
+                   }\r
+                   lat = ProjConstants.asinz(cosz * this.sin_p14 + (y * sinz * this.cos_p14)/rh);\r
+                   con = Math.abs(lat0) - ProjConstants.HALF_PI;\r
+                   if (Math.abs(con) <= ProjConstants.EPSLN) {\r
+                      if (this.lat0 >= 0) {\r
+                         lon = ProjConstants.adjust_lon(this.long0 + Math.atan2(p.x, -p.y));\r
+                      } else {\r
+                         lon = ProjConstants.adjust_lon(this.long0 -Math.atan2(-p.x, p.y));\r
+                      }\r
+                   }\r
+                   con = cosz - this.sin_p14 * Math.sin(lat);\r
+                   if ((Math.abs(con) >= ProjConstants.EPSLN) || (Math.abs(x) >= ProjConstants.EPSLN)) {\r
+                      lon = ProjConstants.adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p14), (con * rh)));\r
+                   }\r
+                   p.x=lon;\r
+                   p.y=lat;\r
+                   return p;\r
+                 }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjParams.as b/com/gradoservice/proj4as/proj/ProjParams.as
new file mode 100755 (executable)
index 0000000..782f5a8
--- /dev/null
@@ -0,0 +1,71 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.Datum;\r
+       \r
+       public class ProjParams\r
+       {\r
+                 \r
+         public var title:Object;  \r
+         \r
+         /**\r
+          * Property: projName\r
+          * The projection class for this projection, e.g. lcc (lambert conformal conic,\r
+          * or merc for mercator.  These are exactly equicvalent to their Proj4 \r
+          * counterparts.\r
+          */\r
+         public var projName:String;\r
+         /**\r
+          * Property: units\r
+          * The units of the projection.  Values include 'm' and 'degrees'\r
+         /**\r
+          * Property: units\r
+          * The units of the projection.  Values include 'm' and 'degrees'\r
+          */\r
+         public var units:String;\r
+         /**\r
+          * Property: datum\r
+          * The datum specified for the projection\r
+          */\r
+         public var datum:Datum;         \r
+         public var datumCode:String;\r
+         public var datumName:String;\r
+         public var nagrids:String;\r
+         public var ellps:String;\r
+         public var a:Number;\r
+         public var b:Number;\r
+         public var a2:Number;\r
+         public var b2:Number;\r
+         public var e:Number;\r
+         public var es:Number;   \r
+         public var ep2:Number;          \r
+         public var rf:Number;\r
+         public var long0:Number;\r
+         public var lat0:Number;\r
+         public var lat1:Number;\r
+         public var lat2:Number;\r
+         public var lat_ts:Number;\r
+         public var alpha:Number;\r
+         public var longc:Number;\r
+         public var x0:Number;\r
+         public var y0:Number;\r
+         public var k0:Number;\r
+         public var k:Number;\r
+         public var R_A:Boolean = false;\r
+         public var zone:int;\r
+         public var utmSouth:Boolean = false;\r
+         public var to_meter:Number;\r
+         public var from_greenwich:Number;\r
+         public var datum_params:Array;\r
+         public var sphere:Boolean = false;\r
+         public var ellipseName:String;        \r
+         \r
+         public var srsCode:String;\r
+         public var srsAuth:String;\r
+         public var srsProjNumber:String;              \r
+               \r
+               public function ProjParams()\r
+               {\r
+               }\r
+\r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjSinu.as b/com/gradoservice/proj4as/proj/ProjSinu.as
new file mode 100755 (executable)
index 0000000..c5e7d33
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************\r
+NAME                           SINUSOIDAL\r
+\r
+PURPOSE:       Transforms input longitude and latitude to Easting and\r
+               Northing for the Sinusoidal projection.  The\r
+               longitude and latitude must be in radians.  The Easting\r
+               and Northing values will be returned in meters.\r
+\r
+PROGRAMMER              DATE            \r
+----------              ----           \r
+D. Steinwand, EROS      May, 1991     \r
+\r
+This function was adapted from the Sinusoidal projection code (FORTRAN) in the \r
+General Cartographic Transformation Package software which is available from \r
+the U.S. Geological Survey National Mapping Division.\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.  "Software Documentation for GCTP General Cartographic Transformation\r
+    Package", U.S. Geological Survey National Mapping Division, May 1982.\r
+*******************************************************************************/\r
+\r
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjSinu extends AbstractProjProjection\r
+       {\r
+               private var R:Number;\r
+               public function ProjSinu(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+       /* Initialize the Sinusoidal projection\r
+         ------------------------------------*/\r
+                 override public function init():void\r
+                 {\r
+                       /* Place parameters in static storage for common use\r
+                 -------------------------------------------------*/\r
+                       this.R = 6370997.0; //Radius of earth\r
+                 }\r
+\r
+                       /* Sinusoidal forward equations--mapping lat,long to x,y\r
+                       -----------------------------------------------------*/\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                               var x:Number,y:Number,delta_lon:Number; \r
+                               var lon:Number=p.x;\r
+                               var lat:Number=p.y;     \r
+                               /* Forward equations\r
+                               -----------------*/\r
+                               delta_lon = ProjConstants.adjust_lon(lon - this.long0);\r
+                               x = this.R * delta_lon * Math.cos(lat) + this.x0;\r
+                               y = this.R * lat + this.y0;\r
+               \r
+                               p.x=x;\r
+                               p.y=y;  \r
+                               return p;\r
+                       }\r
+               \r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                               var lat:Number,temp:Number,lon:Number;  \r
+               \r
+                               /* Inverse equations\r
+                                 -----------------*/\r
+                               p.x -= this.x0;\r
+                               p.y -= this.y0;\r
+                               lat = p.y / this.R;\r
+                               if (Math.abs(lat) > ProjConstants.HALF_PI) {\r
+                                  trace("sinu:Inv:DataError");\r
+                               }\r
+                               temp = Math.abs(lat) - ProjConstants.HALF_PI;\r
+                               if (Math.abs(temp) > ProjConstants.EPSLN) {\r
+                                       temp = this.long0+ p.x / (this.R *Math.cos(lat));\r
+                                       lon = ProjConstants.adjust_lon(temp);\r
+                               } else {\r
+                                       lon = this.long0;\r
+                               }\r
+                                 \r
+                               p.x=lon;\r
+                               p.y=lat;\r
+                               return p;\r
+                       }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjSoMerc.as b/com/gradoservice/proj4as/proj/ProjSoMerc.as
new file mode 100755 (executable)
index 0000000..ccaaa68
--- /dev/null
@@ -0,0 +1,135 @@
+/*******************************************************************************\r
+NAME                       SWISS OBLIQUE MERCATOR\r
+\r
+PURPOSE:       Swiss projection.\r
+WARNING:  X and Y are inverted (weird) in the swiss coordinate system. Not\r
+   here, since we want X to be horizontal and Y vertical.\r
+\r
+ALGORITHM REFERENCES\r
+1. "Formules et constantes pour le Calcul pour la\r
+ projection cylindrique conforme Г  axe oblique et pour la transformation entre\r
+ des systГЁmes de rГ©fГ©rence".\r
+ http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf\r
+\r
+*******************************************************************************/\r
+\r
+\r
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjSoMerc extends AbstractProjProjection\r
+       {\r
+               private var lambda0:Number;\r
+               private var R:Number;\r
+               private var b0:Number;\r
+               private var K:Number;\r
+               \r
+               \r
+               public function ProjSoMerc(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+               \r
+                 override public function init():void\r
+                 {\r
+                   var phy0:Number = this.lat0;\r
+                   this.lambda0 = this.long0;\r
+                   var sinPhy0:Number = Math.sin(phy0);\r
+                   var semiMajorAxis:Number = this.a;\r
+                   var invF:Number = this.rf;\r
+                   var flattening:Number = 1 / invF;\r
+                   var e2:Number = 2 * flattening - Math.pow(flattening, 2);\r
+                   var e:Number = this.e = Math.sqrt(e2);\r
+                   this.R = semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2.0));\r
+                   this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4.0));\r
+                   this.b0 = Math.asin(sinPhy0 / this.alpha);\r
+                   this.K = Math.log(Math.tan(Math.PI / 4.0 + this.b0 / 2.0))\r
+                           - this.alpha\r
+                           * Math.log(Math.tan(Math.PI / 4.0 + phy0 / 2.0))\r
+                           + this.alpha\r
+                           * e / 2\r
+                           * Math.log((1 + e * sinPhy0)\r
+                           / (1 - e * sinPhy0));\r
+                 }\r
+               \r
+               \r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                   var Sa1:Number = Math.log(Math.tan(Math.PI / 4.0 - p.y / 2.0));\r
+                   var Sa2:Number = this.e / 2.0\r
+                           * Math.log((1 + this.e * Math.sin(p.y))\r
+                           / (1 - this.e * Math.sin(p.y)));\r
+                   var S:Number = -this.alpha * (Sa1 + Sa2) + this.K;\r
+               \r
+                       // spheric latitude\r
+                   var b:Number = 2.0 * (Math.atan(Math.exp(S)) - Math.PI / 4.0);\r
+               \r
+                       // spheric longitude\r
+                   var I:Number = this.alpha * (p.x - this.lambda0);\r
+               \r
+                       // psoeudo equatorial rotation\r
+                   var rotI:Number = Math.atan(Math.sin(I)\r
+                           / (Math.sin(this.b0) * Math.tan(b) +\r
+                              Math.cos(this.b0) * Math.cos(I)));\r
+               \r
+                   var rotB:Number = Math.asin(Math.cos(this.b0) * Math.sin(b) -\r
+                                        Math.sin(this.b0) * Math.cos(b) * Math.cos(I));\r
+               \r
+                   p.y = this.R / 2.0\r
+                           * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB)))\r
+                           + this.y0;\r
+                   p.x = this.R * rotI + this.x0;\r
+                   return p;\r
+                 }\r
+               \r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                   var Y:Number = p.x - this.x0;\r
+                   var X:Number = p.y - this.y0;\r
+               \r
+                   var rotI:Number = Y / this.R;\r
+                   var rotB:Number = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4.0);\r
+               \r
+                   var b:Number = Math.asin(Math.cos(this.b0) * Math.sin(rotB)\r
+                           + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI));\r
+                   var I:Number = Math.atan(Math.sin(rotI)\r
+                           / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0)\r
+                           * Math.tan(rotB)));\r
+               \r
+                   var lambda:Number = this.lambda0 + I / this.alpha;\r
+               \r
+                   var S:Number = 0.0;\r
+                   var phy:Number = b;\r
+                   var prevPhy:Number = -1000.0;\r
+                   var iteration:Number = 0;\r
+                   while (Math.abs(phy - prevPhy) > 0.0000001)\r
+                   {\r
+                     if (++iteration > 20)\r
+                     {\r
+                       trace("omercFwdInfinity");\r
+                       return null;\r
+                     }\r
+                     //S = Math.log(Math.tan(Math.PI / 4.0 + phy / 2.0));\r
+                     S = 1.0\r
+                             / this.alpha\r
+                             * (Math.log(Math.tan(Math.PI / 4.0 + b / 2.0)) - this.K)\r
+                             + this.e\r
+                             * Math.log(Math.tan(Math.PI / 4.0\r
+                             + Math.asin(this.e * Math.sin(phy))\r
+                             / 2.0));\r
+                     prevPhy = phy;\r
+                     phy = 2.0 * Math.atan(Math.exp(S)) - Math.PI / 2.0;\r
+                   }\r
+               \r
+                   p.x = lambda;\r
+                   p.y = phy;\r
+                   return p;\r
+                 }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjStere.as b/com/gradoservice/proj4as/proj/ProjStere.as
new file mode 100755 (executable)
index 0000000..e03c85d
--- /dev/null
@@ -0,0 +1,278 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+               \r
+       public class ProjStere extends AbstractProjProjection\r
+       {\r
+               private const TOL:Number=1.e-8;\r
+               private const NITER:Number=8;\r
+               private const CONV:Number=1.e-10;\r
+               private const S_POLE:Number=0;\r
+               private const N_POLE:Number=1;\r
+               private const OBLIQ:Number=2;\r
+               private const EQUIT:Number=3;\r
+               \r
+               private var akm1:Number;\r
+               private var cosph0:Number;\r
+               private var cosX1:Number;\r
+               private var sinX1:Number;               \r
+               private var phi0:Number;\r
+               private var phits:Number;\r
+               private var sinph0:Number;\r
+               \r
+               public function ProjStere(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+               private function ssfn_(phit:Number, sinphi:Number, eccen:Number):Number \r
+               {\r
+                       sinphi *= eccen;\r
+                       return (Math.tan (.5 * (ProjConstants.HALF_PI + phit)) * Math.pow((1. - sinphi) / (1. + sinphi), .5 * eccen));\r
+               }\r
+               \r
+               \r
+                 override public function init():void\r
+                 {\r
+                       this.phits = this.lat_ts ? this.lat_ts : ProjConstants.HALF_PI;\r
+                   var t:Number = Math.abs(this.lat0);\r
+                       if ((Math.abs(t) - ProjConstants.HALF_PI) < ProjConstants.EPSLN) {\r
+                               this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE;\r
+                       } else {\r
+                               this.mode = t > ProjConstants.EPSLN ? this.OBLIQ : this.EQUIT;\r
+                   }\r
+                       this.phits = Math.abs(this.phits);\r
+                       if (this.es) {\r
+                               var X:Number;\r
+               \r
+                               switch (this.mode) {\r
+                               case this.N_POLE:\r
+                               case this.S_POLE:\r
+                                       if (Math.abs(this.phits - ProjConstants.HALF_PI) < ProjConstants.EPSLN) {\r
+                                               this.akm1 = 2. * this.k0 / Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e));\r
+                                       } else {\r
+                         t = Math.sin(this.phits);\r
+                                               this.akm1 = Math.cos(this.phits) / ProjConstants.tsfnz(this.e, this.phits, t);\r
+                                               t *= this.e;\r
+                                               this.akm1 /= Math.sqrt(1. - t * t);\r
+                                       }\r
+                                       break;\r
+                               case this.EQUIT:\r
+                                       this.akm1 = 2. * this.k0;\r
+                                       break;\r
+                               case this.OBLIQ:\r
+                                       t = Math.sin(this.lat0);\r
+                                       X = 2. * Math.atan(this.ssfn_(this.lat0, t, this.e)) - ProjConstants.HALF_PI;\r
+                                       t *= this.e;\r
+                                       this.akm1 = 2. * this.k0 * Math.cos(this.lat0) / Math.sqrt(1. - t * t);\r
+                                       this.sinX1 = Math.sin(X);\r
+                                       this.cosX1 = Math.cos(X);\r
+                                       break;\r
+                               }\r
+                       } else {\r
+                               switch (this.mode) {\r
+                               case this.OBLIQ:\r
+                                       this.sinph0 = Math.sin(this.lat0);\r
+                                       this.cosph0 = Math.cos(this.lat0);\r
+                               case this.EQUIT:\r
+                                       this.akm1 = 2. * this.k0;\r
+                                       break;\r
+                               case this.S_POLE:\r
+                               case this.N_POLE:\r
+                                       this.akm1 = Math.abs(this.phits - ProjConstants.HALF_PI) >= ProjConstants.EPSLN ?\r
+                                          Math.cos(this.phits) / Math.tan(ProjConstants.FORTPI - .5 * this.phits) :\r
+                                          2. * this.k0 ;\r
+                                       break;\r
+                               }\r
+                       }\r
+                 } \r
+               \r
+               // Stereographic forward equations--mapping lat,long to x,y\r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                   var lon:Number = p.x;\r
+                   var lat:Number = p.y;\r
+                   var x:Number, y:Number, A:Number, X:Number;\r
+                   var sinX:Number,cosX:Number;\r
+                   \r
+                   if (this.sphere) {\r
+                       var  sinphi:Number, cosphi:Number, coslam:Number, sinlam:Number;\r
+               \r
+                       sinphi = Math.sin(lat);\r
+                       cosphi = Math.cos(lat);\r
+                       coslam = Math.cos(lon);\r
+                       sinlam = Math.sin(lon);\r
+                       switch (this.mode) {\r
+                       case this.EQUIT:\r
+                               y = 1. + cosphi * coslam;\r
+                               if (y <= ProjConstants.EPSLN) {\r
+                         trace('ERROR');\r
+                         //F_ERROR;\r
+                       }\r
+                       y = this.akm1 / y;\r
+                               x = y * cosphi * sinlam;\r
+                       y *= sinphi;\r
+                               break;\r
+                       case this.OBLIQ:\r
+                               y = 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;\r
+                               if (y <= ProjConstants.EPSLN) {\r
+                         trace('ERROR');\r
+                         //F_ERROR;\r
+                       }\r
+                       y = this.akm1 / y;\r
+                               x = y * cosphi * sinlam;\r
+                               y *= this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;\r
+                               break;\r
+                       case this.N_POLE:\r
+                               coslam = -coslam;\r
+                               lat = -lat;\r
+                       //Note  no break here so it conitnues through S_POLE\r
+                       case this.S_POLE:\r
+                               if (Math.abs(lat - ProjConstants.HALF_PI) < this.TOL) {\r
+                         trace('ERROR');\r
+                         //F_ERROR;\r
+                       }\r
+                       y = this.akm1 * Math.tan(ProjConstants.FORTPI + .5 * lat)\r
+                               x = sinlam * y;\r
+                               y *= coslam;\r
+                               break;\r
+                       }\r
+                   } else {\r
+                       coslam = Math.cos(lon);\r
+                       sinlam = Math.sin(lon);\r
+                       sinphi = Math.sin(lat);\r
+                       if (this.mode == this.OBLIQ || this.mode == this.EQUIT) {\r
+                       X = 2. * Math.atan(this.ssfn_(lat, sinphi, this.e));\r
+                               sinX = Math.sin(X - ProjConstants.HALF_PI);\r
+                               cosX = Math.cos(X);\r
+                       }\r
+                       switch (this.mode) {\r
+                       case this.OBLIQ:\r
+                               A = this.akm1 / (this.cosX1 * (1. + this.sinX1 * sinX + this.cosX1 * cosX * coslam));\r
+                               y = A * (this.cosX1 * sinX - this.sinX1 * cosX * coslam);\r
+                               x = A * cosX;\r
+                               break;\r
+                       case this.EQUIT:\r
+                               A = 2. * this.akm1 / (1. + cosX * coslam);\r
+                               y = A * sinX;\r
+                               x = A * cosX;\r
+                               break;\r
+                       case this.S_POLE:\r
+                               lat = -lat;\r
+                               coslam = - coslam;\r
+                               sinphi = -sinphi;\r
+                       case this.N_POLE:\r
+                               x = this.akm1 * ProjConstants.tsfnz(this.e, lat, sinphi);\r
+                               y = - x * coslam;\r
+                               break;\r
+                       }\r
+                       x = x * sinlam;\r
+                   }\r
+                   p.x = x*this.a + this.x0;\r
+                   p.y = y*this.a + this.y0;\r
+                   return p;\r
+                 }\r
+               \r
+               \r
+               //* Stereographic inverse equations--mapping x,y to lat/long\r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                   var x:Number = (p.x - this.x0)/this.a;   /* descale and de-offset */\r
+                   var y:Number = (p.y - this.y0)/this.a;\r
+                   var lon:Number, lat:Number;\r
+               \r
+                   var cosphi:Number, sinphi:Number, tp:Number=0.0, phi_l:Number=0.0, rho:Number, halfe:Number=0.0, pi2:Number=0.0;\r
+                   var i:int;\r
+               \r
+                   if (this.sphere) {\r
+                       var  c:Number, rh:Number, sinc:Number, cosc:Number;\r
+               \r
+                     rh = Math.sqrt(x*x + y*y);\r
+                     c = 2. * Math.atan(rh / this.akm1);\r
+                       sinc = Math.sin(c);\r
+                       cosc = Math.cos(c);\r
+                       lon = 0.;\r
+                       switch (this.mode) {\r
+                       case this.EQUIT:\r
+                               if (Math.abs(rh) <= ProjConstants.EPSLN) {\r
+                                       lat = 0.;\r
+                               } else {\r
+                                       lat = Math.asin(y * sinc / rh);\r
+                       }\r
+                               if (cosc != 0. || x != 0.) lon = Math.atan2(x * sinc, cosc * rh);\r
+                               break;\r
+                       case this.OBLIQ:\r
+                               if (Math.abs(rh) <= ProjConstants.EPSLN) {\r
+                                       lat = this.phi0;\r
+                               } else {\r
+                                       lat = Math.asin(cosc * sinph0 + y * sinc * cosph0 / rh);\r
+                       }\r
+                       c = cosc - sinph0 * Math.sin(lat);\r
+                               if (c != 0. || x != 0.) {\r
+                                       lon = Math.atan2(x * sinc * cosph0, c * rh);\r
+                       }\r
+                               break;\r
+                       case this.N_POLE:\r
+                               y = -y;\r
+                       case this.S_POLE:\r
+                               if (Math.abs(rh) <= ProjConstants.EPSLN) {\r
+                                       lat = this.phi0;\r
+                               } else {\r
+                                       lat = Math.asin(this.mode == this.S_POLE ? -cosc : cosc);\r
+                       }\r
+                               lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y);\r
+                               break;\r
+                       }\r
+                   } else {\r
+                       rho = Math.sqrt(x*x + y*y);\r
+                       switch (this.mode) {\r
+                       case this.OBLIQ:\r
+                       case this.EQUIT:\r
+                       tp = 2. * Math.atan2(rho * this.cosX1 , this.akm1);\r
+                               cosphi = Math.cos(tp);\r
+                               sinphi = Math.sin(tp);\r
+                       if( rho == 0.0 ) {\r
+                                 phi_l = Math.asin(cosphi * this.sinX1);\r
+                       } else {\r
+                                 phi_l = Math.asin(cosphi * this.sinX1 + (y * sinphi * this.cosX1 / rho));\r
+                       }\r
+               \r
+                               tp = Math.tan(.5 * (ProjConstants.HALF_PI + phi_l));\r
+                               x *= sinphi;\r
+                               y = rho * this.cosX1 * cosphi - y * this.sinX1* sinphi;\r
+                               pi2 = ProjConstants.HALF_PI;\r
+                               halfe = .5 * this.e;\r
+                               break;\r
+                       case this.N_POLE:\r
+                               y = -y;\r
+                       case this.S_POLE:\r
+                       tp = - rho / this.akm1\r
+                               phi_l = ProjConstants.HALF_PI - 2. * Math.atan(tp);\r
+                               pi2 = -ProjConstants.HALF_PI;\r
+                               halfe = -.5 * this.e;\r
+                               break;\r
+                       }\r
+                       for (i = this.NITER; i--; phi_l = lat) \r
+                               { //check this\r
+                               sinphi = this.e * Math.sin(phi_l);\r
+                               lat = 2. * Math.atan(tp * Math.pow((1.+sinphi)/(1.-sinphi), halfe)) - pi2;\r
+                               if (Math.abs(phi_l - lat) < this.CONV) \r
+                                       {\r
+                                       if (this.mode == this.S_POLE) lat = -lat;\r
+                                       lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y);\r
+                                       p.x = lon;\r
+                                       p.y = lat\r
+                                       return p;\r
+                                       }\r
+                               }\r
+                       }\r
+                   return null;\r
+                       }\r
+               \r
+\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjSterea.as b/com/gradoservice/proj4as/proj/ProjSterea.as
new file mode 100755 (executable)
index 0000000..49b3459
--- /dev/null
@@ -0,0 +1,74 @@
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+                       \r
+       public class ProjSterea extends ProjGauss\r
+       {\r
+               \r
+               protected var sinc0:Number;\r
+               protected var cosc0:Number;\r
+               protected var R2:Number;                \r
+               \r
+               public function ProjSterea(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+                 override public function init():void\r
+                 {\r
+                   super.init();\r
+                   if (!this.rc) {\r
+                     trace("sterea:init:E_ERROR_0");\r
+                     return;\r
+                   }\r
+                   this.sinc0 = Math.sin(this.phic0);\r
+                   this.cosc0 = Math.cos(this.phic0);\r
+                   this.R2 = 2.0 * this.rc;\r
+                   if (!this.title) this.title = "Oblique Stereographic Alternative";\r
+                 }\r
+               \r
+                 override public function forward(p:ProjPoint):ProjPoint\r
+                 {\r
+                   p.x = ProjConstants.adjust_lon(p.x-this.long0); /* adjust del longitude */\r
+                   super.forward(p);\r
+                   var sinc:Number = Math.sin(p.y);\r
+                   var cosc:Number = Math.cos(p.y);\r
+                   var cosl:Number = Math.cos(p.x);\r
+                   k = this.k0 * this.R2 / (1.0 + this.sinc0 * sinc + this.cosc0 * cosc * cosl);\r
+                   p.x = k * cosc * Math.sin(p.x);\r
+                   p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl);\r
+                   p.x = this.a * p.x + this.x0;\r
+                   p.y = this.a * p.y + this.y0;\r
+                   return p;\r
+                 }\r
+               \r
+                override public function inverse(p:ProjPoint):ProjPoint\r
+                {\r
+                   var lon:Number,lat:Number,rho:Number,sinc:Number,cosc:Number;\r
+                   p.x = (p.x - this.x0) / this.a; /* descale and de-offset */\r
+                   p.y = (p.y - this.y0) / this.a;\r
+               \r
+                   p.x /= this.k0;\r
+                   p.y /= this.k0;\r
+                   if ( (rho = Math.sqrt(p.x*p.x + p.y*p.y)) ) {\r
+                     c = 2.0 * Math.atan2(rho, this.R2);\r
+                     sinc = Math.sin(c);\r
+                     cosc = Math.cos(c);\r
+                     lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho);\r
+                     lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc);\r
+                   } else {\r
+                     lat = this.phic0;\r
+                     lon = 0.;\r
+                   }\r
+               \r
+                   p.x = lon;\r
+                   p.y = lat;\r
+                   super.inverse(p);\r
+                   p.x = ProjConstants.adjust_lon(p.x + this.long0); /* adjust longitude to CM */\r
+                   return p;\r
+                 }             \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjTmerc.as b/com/gradoservice/proj4as/proj/ProjTmerc.as
new file mode 100755 (executable)
index 0000000..b6d083a
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************\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
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+                       \r
+       public class ProjTmerc extends AbstractProjProjection\r
+       {\r
+               public function ProjTmerc(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+  override public function init():void\r
+       {\r
+    this.e0 = ProjConstants.e0fn(this.es);\r
+    this.e1 = ProjConstants.e1fn(this.es);\r
+    this.e2 = ProjConstants.e2fn(this.es);\r
+    this.e3 = ProjConstants.e3fn(this.es);\r
+    this.ml0 = this.a * ProjConstants.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
+  override public function forward(p:ProjPoint):ProjPoint \r
+       {\r
+    var lon:Number = p.x;\r
+    var lat:Number = p.y;\r
+\r
+    var delta_lon:Number = ProjConstants.adjust_lon(lon - this.long0); // Delta longitude\r
+    var con:Number;    // cone constant\r
+    var x:Number, y:Number;\r
+    var sin_phi:Number=Math.sin(lat);\r
+    var cos_phi:Number=Math.cos(lat);\r
+\r
+    if (this.sphere) {  /* spherical form */\r
+      var b:Number = cos_phi * Math.sin(delta_lon);\r
+      if ((Math.abs(Math.abs(b) - 1.0)) < .0000000001)  {\r
+        trace("tmerc:forward: Point projects into infinity");\r
+        return null;\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:Number  = cos_phi * delta_lon;\r
+      var als:Number = Math.pow(al,2);\r
+      var c:Number   = this.ep2 * Math.pow(cos_phi,2);\r
+      var tq:Number  = Math.tan(lat);\r
+      var t:Number   = Math.pow(tq,2);\r
+      con = 1.0 - this.es * Math.pow(sin_phi,2);\r
+      var n:Number   = this.a / Math.sqrt(con);\r
+      var ml:Number  = this.a * ProjConstants.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
+   override public function inverse(p:ProjPoint):ProjPoint\r
+   {\r
+    var con:Number, phi:Number;  /* temporary angles       */\r
+    var delta_phi:Number; /* difference between longitudes    */\r
+    var i:Number;\r
+    var max_iter:Number = 6;      /* maximun number of iterations */\r
+    var lat:Number, lon:Number;\r
+\r
+    if (this.sphere) {   /* spherical form */\r
+      var f:Number = Math.exp(p.x/(this.a * this.k0));\r
+      var g:Number = .5 * (f - 1/f);\r
+      var temp:Number = this.lat0 + p.y/(this.a * this.k0);\r
+      var h:Number = Math.cos(temp);\r
+      con = Math.sqrt((1.0 - h * h)/(1.0 + g * g));      \r
+      lat = ProjConstants.asinz(con);\r
+      if (temp < 0)\r
+        lat = -lat;\r
+      if ((g == 0) && (h == 0)) {\r
+        lon = this.long0;\r
+      } else {\r
+        lon = ProjConstants.adjust_lon(Math.atan2(g,h) + this.long0);\r
+      }\r
+    } else {    // ellipsoidal form\r
+      var x:Number= p.x - this.x0;\r
+      var y:Number = p.y - this.y0;\r
+\r
+      con = (this.ml0 + y / this.k0) / this.a;\r
+      phi = con;\r
+      for (i=0;;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) <= ProjConstants.EPSLN) break;\r
+        if (i >= max_iter) {\r
+          trace("tmerc:inverse: Latitude failed to converge");\r
+          return null;\r
+        }\r
+      } // for()\r
+      if (Math.abs(phi) < ProjConstants.HALF_PI) {\r
+        // sincos(phi, &sin_phi, &cos_phi);\r
+        var sin_phi:Number=Math.sin(phi);\r
+        var cos_phi:Number=Math.cos(phi);\r
+        var tan_phi:Number = Math.tan(phi);\r
+        var c:Number = this.ep2 * Math.pow(cos_phi,2);\r
+        var cs:Number = Math.pow(c,2);\r
+        var t:Number = Math.pow(tan_phi,2);\r
+        var ts :Number= Math.pow(t,2);\r
+        con = 1.0 - this.es * Math.pow(sin_phi,2);\r
+        var n:Number = this.a / Math.sqrt(con);\r
+        var r:Number = n * (1.0 - this.es) / con;\r
+        var d:Number = x / (n * this.k0);\r
+        var ds:Number = 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 = ProjConstants.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 = ProjConstants.HALF_PI * ProjConstants.sign(y);\r
+        lon = this.long0;\r
+      }\r
+    }\r
+    p.x = lon;\r
+    p.y = lat;\r
+    return p;\r
+  } // tmercInv()\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjUtm.as b/com/gradoservice/proj4as/proj/ProjUtm.as
new file mode 100755 (executable)
index 0000000..5e07f73
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************\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
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+       \r
+       public class ProjUtm extends ProjTmerc\r
+       {\r
+               public function ProjUtm(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+  override public function init():void\r
+       {\r
+           if (!this.zone) {\r
+             trace("utm:init: zone must be specified for UTM");\r
+             return;\r
+           }\r
+           this.lat0 = 0.0;\r
+           this.long0 = ((6 * Math.abs(this.zone)) - 183) * ProjConstants.D2R;\r
+           this.x0 = 500000.0;\r
+           this.y0 = this.utmSouth ? 10000000.0 : 0.0;\r
+           this.k0 = 0.9996;\r
+       \r
+           super.init();\r
+    }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
diff --git a/com/gradoservice/proj4as/proj/ProjVandg.as b/com/gradoservice/proj4as/proj/ProjVandg.as
new file mode 100755 (executable)
index 0000000..0a0cdbd
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************\r
+NAME                    VAN DER GRINTEN \r
+\r
+PURPOSE:       Transforms input Easting and Northing to longitude and\r
+               latitude for the Van der Grinten projection.  The\r
+               Easting and Northing must be in meters.  The longitude\r
+               and latitude values will be returned in radians.\r
+\r
+PROGRAMMER              DATE            \r
+----------              ----           \r
+T. Mittan              March, 1993\r
+\r
+This function was adapted from the Van Der Grinten projection code\r
+(FORTRAN) in the General Cartographic Transformation Package software\r
+which is available from the U.S. Geological Survey National Mapping Division.\r
\r
+ALGORITHM REFERENCES\r
+\r
+1.  "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,\r
+    The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.\r
+\r
+2.  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
+3.  "Software Documentation for GCTP General Cartographic Transformation\r
+    Package", U.S. Geological Survey National Mapping Division, May 1982.\r
+*******************************************************************************/\r
+\r
+package com.gradoservice.proj4as.proj\r
+{\r
+       import com.gradoservice.proj4as.ProjPoint;\r
+       import com.gradoservice.proj4as.ProjConstants;\r
+       import com.gradoservice.proj4as.Datum;\r
+                       \r
+       public class ProjVandg extends AbstractProjProjection\r
+       {\r
+\r
+               protected var R:Number;                 \r
+               \r
+               public function ProjVandg(data:ProjParams)\r
+               {\r
+                       super(data);\r
+               }\r
+               \r
+  override public function init():void\r
+       {\r
+               this.R = 6370997.0; //Radius of earth\r
+       }\r
+\r
+  override public function forward(p:ProjPoint):ProjPoint \r
+       {\r
+               var lon:Number=p.x;\r
+               var lat:Number=p.y;     \r
+\r
+               /* Forward equations\r
+               -----------------*/\r
+               var dlon:Number = ProjConstants.adjust_lon(lon - this.long0);\r
+               var x:Number,y:Number;\r
+\r
+               if (Math.abs(lat) <= ProjConstants.EPSLN) {\r
+                       x = this.x0  + this.R * dlon;\r
+                       y = this.y0;\r
+               }\r
+               var theta:Number = ProjConstants.asinz(2.0 * Math.abs(lat / ProjConstants.PI));\r
+               if ((Math.abs(dlon) <= ProjConstants.EPSLN) || (Math.abs(Math.abs(lat) - ProjConstants.HALF_PI) <= ProjConstants.EPSLN)) {\r
+                       x = this.x0;\r
+                       if (lat >= 0) {\r
+                               y = this.y0 + ProjConstants.PI * this.R * Math.tan(.5 * theta);\r
+                       } else {\r
+                               y = this.y0 + ProjConstants.PI * this.R * - Math.tan(.5 * theta);\r
+                       }\r
+                       //  return(OK);\r
+               }\r
+               var al:Number = .5 * Math.abs((ProjConstants.PI / dlon) - (dlon / ProjConstants.PI));\r
+               var asq:Number = al * al;\r
+               var sinth:Number = Math.sin(theta);\r
+               var costh:Number = Math.cos(theta);\r
+\r
+               var g :Number= costh / (sinth + costh - 1.0);\r
+               var gsq:Number = g * g;\r
+               var m:Number = g * (2.0 / sinth - 1.0);\r
+               var msq:Number = m * m;\r
+               var con:Number = ProjConstants.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq);\r
+               if (dlon < 0) {\r
+                con = -con;\r
+               }\r
+               x = this.x0 + con;\r
+               con = Math.abs(con / (ProjConstants.PI * this.R));\r
+               if (lat >= 0) {\r
+                y = this.y0 + ProjConstants.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con);\r
+               } else {\r
+                y = this.y0 - ProjConstants.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con);\r
+               }\r
+               p.x = x;\r
+               p.y = y;\r
+               return p;\r
+       }\r
+\r
+/* Van Der Grinten inverse equations--mapping x,y to lat/long\r
+  ---------------------------------------------------------*/\r
+   override public function inverse(p:ProjPoint):ProjPoint\r
+   {\r
+               var dlon:Number,lat:Number,lon:Number;\r
+               var xx:Number,yy:Number,xys:Number,c1:Number,c2:Number,c3:Number;\r
+               var al:Number,asq:Number;\r
+               var a1:Number;\r
+               var m1:Number;\r
+               var con:Number;\r
+               var th1:Number;\r
+               var d:Number;\r
+\r
+               /* inverse equations\r
+               -----------------*/\r
+               p.x -= this.x0;\r
+               p.y -= this.y0;\r
+               con = ProjConstants.PI * this.R;\r
+               xx = p.x / con;\r
+               yy =p.y / con;\r
+               xys = xx * xx + yy * yy;\r
+               c1 = -Math.abs(yy) * (1.0 + xys);\r
+               c2 = c1 - 2.0 * yy * yy + xx * xx;\r
+               c3 = -2.0 * c1 + 1.0 + 2.0 * yy * yy + xys * xys;\r
+               d = yy * yy / c3 + (2.0 * c2 * c2 * c2 / c3 / c3 / c3 - 9.0 * c1 * c2 / c3 /c3) / 27.0;\r
+               a1 = (c1 - c2 * c2 / 3.0 / c3) / c3;\r
+               m1 = 2.0 * Math.sqrt( -a1 / 3.0);\r
+               con = ((3.0 * d) / a1) / m1;\r
+               if (Math.abs(con) > 1.0) {\r
+                       if (con >= 0.0) {\r
+                               con = 1.0;\r
+                       } else {\r
+                               con = -1.0;\r
+                       }\r
+               }\r
+               th1 = Math.acos(con) / 3.0;\r
+               if (p.y >= 0) {\r
+                       lat = (-m1 *Math.cos(th1 + ProjConstants.PI / 3.0) - c2 / 3.0 / c3) * ProjConstants.PI;\r
+               } else {\r
+                       lat = -(-m1 * Math.cos(th1 + Math.PI / 3.0) - c2 / 3.0 / c3) * ProjConstants.PI;\r
+               }\r
+\r
+               if (Math.abs(xx) < ProjConstants.EPSLN) {\r
+                       lon = this.long0;\r
+               }\r
+               lon = ProjConstants.adjust_lon(this.long0 + ProjConstants.PI * (xys - 1.0 + Math.sqrt(1.0 + 2.0 * (xx * xx - yy * yy) + xys * xys)) / 2.0 / xx);\r
+\r
+               p.x=lon;\r
+               p.y=lat;\r
+               return p;\r
+       }\r
+               \r
+               \r
+       }\r
+}
\ No newline at end of file
index 754d19c..f2ee64c 100644 (file)
@@ -33,7 +33,7 @@
            </mx:columns>
        </mx:DataGrid>
        <mx:HBox horizontalAlign="right" width="100%">
-               <mx:LinkButton label="Delete" click="removeLayer()" enabled="{dataGrid.selectedItem != null? true : false}"/>
+               <mx:LinkButton label="Delete" click="removeLayer()" enabled="{dataGrid.selectedItem != null &amp;&amp; dataGrid.selectedItem.isBackground}"/>
        </mx:HBox>
 
        <mx:VBox width="100%" paddingTop="10">
                        <mx:RadioButton width="100%" groupName="filetype" value="kml" id="kml" label="KML" />
                        <mx:RadioButton width="100%" groupName="filetype" value="osm" id="osm" label="OSM" />
                        <mx:RadioButton width="100%" groupName="filetype" value="shp" id="shp" label="Shapefile" />
+               </mx:HBox>
+               <mx:HBox>
+                       <mx:Label text="Shapefile projection:" />
+                       <mx:ComboBox id="projection"> 
+                               <mx:ArrayCollection>
+                                       <mx:Object label="Lat/long" data="" />
+                                       <mx:Object label="Ordnance Survey GB" data="EPSG:27700" />
+                                       <mx:Object label="NAD83" data="EPSG:4269" />
+                               </mx:ArrayCollection>
+                       </mx:ComboBox>
                        <mx:CheckBox width="100%" label="Simplify paths" selected="true" id="simplify" />
                </mx:HBox>
                <mx:HBox>
                        <mx:Text text="URL:"/>
                        <mx:TextInput width="100%" id="src" text="" />
-                       <mx:Button label="Load" click="loadFiles(src.text, filetype.selectedValue.toString(), simplify.selected);" enabled="{src.text == '' ? false : true}"/>
+                       <mx:Button label="Load" click="loadFiles(src.text, filetype.selectedValue.toString(), simplify.selected, projection.selectedItem.data);" enabled="{src.text == '' ? false : true}"/>
                </mx:HBox>
        </mx:VBox>
 
        private function get vectorLayers():Array {
         var v:Array=[];
         for each (var a:MapPaint in map.getLayers() ) {
-            if (a.isBackground) {
-                v.push( { name:a.connection.name, visible:a.visible, url:a.connection.apiBase, style:a.style } );
-            }
+            v.push( { name:a.connection.name, visible:a.visible, url:a.connection.apiBase, style:a.style, isBackground:a.isBackground } );
         }
                return v;
        }
         PopUpManager.removePopUp(this);
     }
 
-       private function loadFiles(url:String,type:String,simplify:Boolean):void {
+       private function loadFiles(url:String,type:String,simplify:Boolean,projection:String=""):void {
                var names:Array=url.split('/'); var name:String=names[names.length-1];
                var stylesheet:String="stylesheets/potlatch.css";
                if (type=='gpx') { stylesheet="stylesheets/gpx.css"; }
                } else if (type=='osm') {
                        var osm:OsmImporter=new OsmImporter(connection, map, [url], filesLoaded, simplify);
                } else {
+                       /* FIXME: 
+                          we're currently hardcoding the projection values. We could populate this directly from 
+                          proj4as, or better still, parse the WKT in the .PRJ file:
+                                       http://trac.osgeo.org/proj4js/ticket/47
+                                       http://trac.osgeo.org/proj4js/changeset/1873
+                       */
                        var re:RegExp=/.shp$/i; url=url.replace(re,'');
                        var shp:ShpImporter=new ShpImporter(connection,
                                                            map,
-                                                           [url+".shp",url+".shx",url+".dbf"], filesLoaded, simplify);
+                                                           [url+".shp",url+".shx",url+".dbf"], filesLoaded, simplify, projection);
                }
        }
 
index 9f5cd9c..70ded7e 100644 (file)
@@ -2,6 +2,7 @@ package net.systemeD.potlatch2.utils {
 
        import org.vanrijkom.shp.*;
        import org.vanrijkom.dbf.*;
+       import com.gradoservice.proj4as.*;
        import net.systemeD.halcyon.Map;
        import net.systemeD.halcyon.connection.Connection;
        import net.systemeD.halcyon.connection.Node;
@@ -10,7 +11,10 @@ package net.systemeD.potlatch2.utils {
 
        public class ShpImporter extends Importer {
 
-               public function ShpImporter(connection:Connection, map:Map, filenames:Array, callback:Function=null, simplify:Boolean=false) {
+               private var projection:String;
+
+               public function ShpImporter(connection:Connection, map:Map, filenames:Array, callback:Function=null, simplify:Boolean=false, projection:String="") {
+                       if (projection!='') this.projection=projection;
                        super(connection,map,filenames,callback,simplify);
                }
 
@@ -19,6 +23,14 @@ package net.systemeD.potlatch2.utils {
                        var shp:ShpHeader=new ShpHeader(files[0]);
                        var dbf:DbfHeader=new DbfHeader(files[2]);
 
+                       if (projection) {
+                               var proj:Proj4as=new Proj4as();
+                               var toProj:ProjProjection=new ProjProjection('EPSG:4326');
+                               var fromProj:ProjProjection=new ProjProjection('EPSG:27700');
+                       }
+
+                       var nodemap:Object={};
+
                        if (shp.shapeType==ShpType.SHAPE_POLYGON || shp.shapeType==ShpType.SHAPE_POLYLINE) {
 
                                // Loop through all polylines in the shape
@@ -30,14 +42,28 @@ package net.systemeD.potlatch2.utils {
                                        //              var xsID:String = dr.values[idFieldName];
 
                                        // Do each ring in turn, then each point in the ring
+                                       var way:Way;
+                                       var node:Node;
+                                       var x:Number, y:Number;
                                        for (var j:int=0; j < polyArray[i].shape.rings.length; j++) {
-                                               var way:Way;
                                                var nodestring:Array=[];
                                                var points:Array = polyArray[i].shape.rings[j];
                                                if (points!=null) {
                                                        for (var k:int=0; k < points.length; k++) {
                                                                var p:ShpPoint = ShpPoint(points[k]);
-                                                               nodestring.push(connection.createNode({}, p.y, p.x, push));
+                                                               
+                                                               if (projection) {
+                                                                       var r:ProjPoint = new ProjPoint(p.x,p.y,0);
+                                                                       r=proj.transform(fromProj,toProj,r);
+                                                                       x=r.x; y=r.y;
+                                                               } else {
+                                                                       x=p.x; x=p.y;
+                                                               }
+
+                                                               var key:String=x+","+y;
+                                                               if (nodemap[key]) { node=nodemap[key]; }
+                                                               else { node=connection.createNode({}, y, x, push); nodemap[key]=node; }
+                                                               nodestring.push(node);
                                                        }
                                                }
                                                if (nodestring.length>0) {