Added proj4js 1.1.0 closes #933

This commit is contained in:
Ryan Kirkman
2013-02-20 14:35:15 +10:00
parent ff5c71d1ce
commit 960d5ddc75
49 changed files with 11994 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:102067"] = "+title=Krovak +proj=krovak +lat_0=49.5 +lon_0=42.5 +alpha=30.28813972222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m +towgs84=570.8,85.7,462.8,4.998,1.587,5.261,3.56 +czech +no_defs";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:102757"] = "+title=NAD 1983 StatePlane Wyoming West Central FIPS 4903 Feet +proj=tmerc +lat_0=40.5 +lon_0=-108.75 +x_0=600000.0 +y_0=0 +k=0.999938 +a=6378137.0 +b=6356752.3141403 +to_meter=0.3048006096012192";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:102758"] = "+title=NAD 1983 StatePlane Wyoming West FIPS 4904 Feet +proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +x_0=800000 +y_0=100000 +k=0.999938 +a=6378137.0 +b=6356752.3141403 +to_meter=0.3048006096012192";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:21781"] = "+title=CH1903 / LV03 +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +x_0=600000 +y_0=200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:26591"] = "+title= Monte Mario (Rome) / Italy zone 1 EPSG:26591 +proj=tmerc +lat_0=0 +lon_0=-3.45233333333333 +from_greenwich=12.45233333333333 +k=0.999600 +x_0=1500000 +y_0=0 +a=6378388.0, +b=6356911.94612795 +units=m";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG26912"] = "+title=NAD83 / UTM zone 12N +proj=utm +zone=12 +a=6378137.0 +b=6356752.3141403";
+5
View File
@@ -0,0 +1,5 @@
Proj4js.defs["EPSG:27200"] = "+title=New Zealand Map Grid\
+proj=nzmg \
+lat_0=-41 +lon_0=173 \
+x_0=2510000 +y_0=6023150 \
+ellps=intl +datum=nzgd49 +units=m +no_defs"
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:27563"]="+title=NTF (Paris)/Lambert Sud France +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:41001"] = "+title=simple mercator EPSG:41001 +proj=merc +lat_ts=0 +lon_0=0 +k=1.000000 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:4139"] = "+title=Puerto Rico EPSG:4139 (3 param datum shift) +proj=longlat +towgs84 = 11,72,-101,0,0,0,0 +a=6378206.4 +b=6356583.8";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:4181"] = "+title=Luxembourg 1930 EPSG:4181 (7 param datum shift) +proj=longlat +towgs84=-193,13.7,-39.3,-0.41,-2.933,2.688,0.43 +a=6378388.0, +b=6356911.94612795";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:42304"]="+title=Atlas of Canada, LCC +proj=lcc +lat_1=49 +lat_2=77 +lat_0=49 +lon_0=-95 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs";
+1
View File
@@ -0,0 +1 @@
Proj4js.defs["EPSG:4272"] = "+title=NZGD49 +proj=longlat +ellps=intl +datum=nzgd49 +no_defs ";
+2
View File
@@ -0,0 +1,2 @@
Proj4js.defs["EPSG:4302"] = "+title=Trinidad 1903 EPSG:4302 (7 param datum shift) +proj=longlat +a=6378293.63683822 +b=6356617.979337744 +towgs84=-61.702,284.488,472.052,0,0,0,0";
+5
View File
@@ -0,0 +1,5 @@
// Google Mercator projection
// Used in combination with GoogleMercator layer type in OpenLayers
//+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
Proj4js.defs["EPSG:900913"]= "+title=GoogleMercator +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";
+11
View File
@@ -0,0 +1,11 @@
// Google Mercator projection
// Used in combination with GoogleMercator layer type in OpenLayers
//+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
csList.EPSG900913= "\
+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 \
";
+2
View File
@@ -0,0 +1,2 @@
Proj4js.defs["GOOGLE"]="+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";
Proj4js.defs["EPSG:900913"]=Proj4js.defs["GOOGLE"];
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+1816
View File
File diff suppressed because it is too large Load Diff
+149
View File
@@ -0,0 +1,149 @@
/*******************************************************************************
NAME ALBERS CONICAL EQUAL AREA
PURPOSE: Transforms input longitude and latitude to Easting and Northing
for the Albers Conical Equal Area projection. The longitude
and latitude must be in radians. The Easting and Northing
values will be returned in meters.
PROGRAMMER DATE
---------- ----
T. Mittan, Feb, 1992
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
Proj4js.Proj.aea = {
init : function() {
if (Math.abs(this.lat1 + this.lat2) < Proj4js.common.EPSLN) {
Proj4js.reportError("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 = Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po);
this.qs1 = Proj4js.common.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 = Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po);
this.qs2 = Proj4js.common.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 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);
if (Math.abs(this.lat1 - this.lat2) > Proj4js.common.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
-------------------------------------------------------------------*/
forward: function(p){
var lon=p.x;
var lat=p.y;
this.sin_phi=Math.sin(lat);
this.cos_phi=Math.cos(lat);
var qs = Proj4js.common.qsfnz(this.e3,this.sin_phi,this.cos_phi);
var rh1 =this.a * Math.sqrt(this.c - this.ns0 * qs)/this.ns0;
var theta = this.ns0 * Proj4js.common.adjust_lon(lon - this.long0);
var x = rh1 * Math.sin(theta) + this.x0;
var y = this.rh - rh1 * Math.cos(theta) + this.y0;
p.x = x;
p.y = y;
return p;
},
inverse: function(p) {
var rh1,qs,con,theta,lon,lat;
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 * Proj4js.common.PI;
} else {
lat = -.5 * Proj4js.common.PI;
}
}
} else {
lat = this.phi1z(this.e3,qs);
}
lon = Proj4js.common.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.
-------------------------------------------*/
phi1z: function (eccent,qs) {
var sinphi, cosphi, con, com, dphi;
var phi = Proj4js.common.asinz(.5 * qs);
if (eccent < Proj4js.common.EPSLN) return phi;
var eccnts = eccent * eccent;
for (var i = 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;
}
Proj4js.reportError("aea:phi1z:Convergence error");
return null;
}
};
+75
View File
@@ -0,0 +1,75 @@
Proj4js.Proj.aeqd = {
init : function() {
this.sin_p12=Math.sin(this.lat0);
this.cos_p12=Math.cos(this.lat0);
},
forward: function(p) {
var lon=p.x;
var lat=p.y;
var ksp;
var sinphi=Math.sin(p.y);
var cosphi=Math.cos(p.y);
var dlon = Proj4js.common.adjust_lon(lon - this.long0);
var coslon = Math.cos(dlon);
var g = this.sin_p12 * sinphi + this.cos_p12 * cosphi * coslon;
if (Math.abs(Math.abs(g) - 1.0) < Proj4js.common.EPSLN) {
ksp = 1.0;
if (g < 0.0) {
Proj4js.reportError("aeqd:Fwd:PointError");
return;
}
} else {
var z = Math.acos(g);
ksp = z/Math.sin(z);
}
p.x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon);
p.y = this.y0 + this.a * ksp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * coslon);
return p;
},
inverse: function(p){
p.x -= this.x0;
p.y -= this.y0;
var rh = Math.sqrt(p.x * p.x + p.y *p.y);
if (rh > (2.0 * Proj4js.common.HALF_PI * this.a)) {
Proj4js.reportError("aeqdInvDataError");
return;
}
var z = rh / this.a;
var sinz=Math.sin(z);
var cosz=Math.cos(z);
var lon = this.long0;
var lat;
if (Math.abs(rh) <= Proj4js.common.EPSLN) {
lat = this.lat0;
} else {
lat = Proj4js.common.asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh);
var con = Math.abs(this.lat0) - Proj4js.common.HALF_PI;
if (Math.abs(con) <= Proj4js.common.EPSLN) {
if (this.lat0 >= 0.0) {
lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x , -p.y));
} else {
lon = Proj4js.common.adjust_lon(this.long0 - Math.atan2(-p.x , p.y));
}
} else {
con = cosz - this.sin_p12 * Math.sin(lat);
if ((Math.abs(con) < Proj4js.common.EPSLN) && (Math.abs(p.x) < Proj4js.common.EPSLN)) {
//no-op, just keep the lon value as is
} else {
var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh));
lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh)));
}
}
}
p.x = lon;
p.y = lat;
return p;
}
};
+108
View File
@@ -0,0 +1,108 @@
/*******************************************************************************
NAME CASSINI
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Cassini projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
Ported from PROJ.4.
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
*******************************************************************************/
//Proj4js.defs["EPSG:28191"] = "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m +no_defs";
// Initialize the Cassini projection
// -----------------------------------------------------------------
Proj4js.Proj.cass = {
init : function() {
if (!this.sphere) {
this.en = Proj4js.common.pj_enfn(this.es)
this.m0 = Proj4js.common.pj_mlfn(this.lat0, Math.sin(this.lat0), Math.cos(this.lat0), this.en);
}
},
C1: .16666666666666666666,
C2: .00833333333333333333,
C3: .04166666666666666666,
C4: .33333333333333333333,
C5: .06666666666666666666,
/* Cassini forward equations--mapping lat,long to x,y
-----------------------------------------------------------------------*/
forward: function(p) {
/* Forward equations
-----------------*/
var x,y;
var lam=p.x;
var phi=p.y;
lam = Proj4js.common.adjust_lon(lam - this.long0);
if (this.sphere) {
x = Math.asin(Math.cos(phi) * Math.sin(lam));
y = Math.atan2(Math.tan(phi) , Math.cos(lam)) - this.phi0;
} else {
//ellipsoid
this.n = Math.sin(phi);
this.c = Math.cos(phi);
y = Proj4js.common.pj_mlfn(phi, this.n, this.c, this.en);
this.n = 1./Math.sqrt(1. - this.es * this.n * this.n);
this.tn = Math.tan(phi);
this.t = this.tn * this.tn;
this.a1 = lam * this.c;
this.c *= this.es * this.c / (1 - this.es);
this.a2 = this.a1 * this.a1;
x = this.n * this.a1 * (1. - this.a2 * this.t * (this.C1 - (8. - this.t + 8. * this.c) * this.a2 * this.C2));
y -= this.m0 - this.n * this.tn * this.a2 * (.5 + (5. - this.t + 6. * this.c) * this.a2 * this.C3);
}
p.x = this.a*x + this.x0;
p.y = this.a*y + this.y0;
return p;
},//cassFwd()
/* Inverse equations
-----------------*/
inverse: function(p) {
p.x -= this.x0;
p.y -= this.y0;
var x = p.x/this.a;
var y = p.y/this.a;
var phi, lam;
if (this.sphere) {
this.dd = y + this.lat0;
phi = Math.asin(Math.sin(this.dd) * Math.cos(x));
lam = Math.atan2(Math.tan(x), Math.cos(this.dd));
} else {
/* ellipsoid */
var ph1 = Proj4js.common.pj_inv_mlfn(this.m0 + y, this.es, this.en);
this.tn = Math.tan(ph1);
this.t = this.tn * this.tn;
this.n = Math.sin(ph1);
this.r = 1. / (1. - this.es * this.n * this.n);
this.n = Math.sqrt(this.r);
this.r *= (1. - this.es) * this.n;
this.dd = x / this.n;
this.d2 = this.dd * this.dd;
phi = ph1 - (this.n * this.tn / this.r) * this.d2 * (.5 - (1. + 3. * this.t) * this.d2 * this.C3);
lam = this.dd * (1. + this.t * this.d2 * (-this.C4 + (1. + 3. * this.t) * this.d2 * this.C5)) / Math.cos(ph1);
}
p.x = Proj4js.common.adjust_lon(this.long0+lam);
p.y = phi;
return p;
}//cassInv()
}
+85
View File
@@ -0,0 +1,85 @@
/*******************************************************************************
NAME LAMBERT CYLINDRICAL EQUAL AREA
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Lambert Cylindrical Equal Area projection.
This class of projection includes the Behrmann and
Gall-Peters Projections. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
R. Marsden August 2009
Winwaed Software Tech LLC, http://www.winwaed.com
This function was adapted from the Miller Cylindrical Projection in the Proj4JS
library.
Note: This implementation assumes a Spherical Earth. The (commented) code
has been included for the ellipsoidal forward transform, but derivation of
the ellispoidal inverse transform is beyond me. Note that most of the
Proj4JS implementations do NOT currently support ellipsoidal figures.
Therefore this is not seen as a problem - especially this lack of support
is explicitly stated here.
ALGORITHM REFERENCES
1. "Cartographic Projection Procedures for the UNIX Environment -
A User's Manual" by Gerald I. Evenden, USGS Open File Report 90-284
and Release 4 Interim Reports (2003)
2. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map
Projections", Univ. Chicago Press, 1993
*******************************************************************************/
Proj4js.Proj.cea = {
/* Initialize the Cylindrical Equal Area projection
-------------------------------------------*/
init: function() {
//no-op
},
/* Cylindrical Equal Area forward equations--mapping lat,long to x,y
------------------------------------------------------------*/
forward: function(p) {
var lon=p.x;
var lat=p.y;
/* Forward equations
-----------------*/
var dlon = Proj4js.common.adjust_lon(lon -this.long0);
var x = this.x0 + this.a * dlon * Math.cos(this.lat_ts);
var y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts);
/* Elliptical Forward Transform
Not implemented due to a lack of a matchign inverse function
{
var Sin_Lat = Math.sin(lat);
var Rn = this.a * (Math.sqrt(1.0e0 - this.es * Sin_Lat * Sin_Lat ));
x = this.x0 + this.a * dlon * Math.cos(this.lat_ts);
y = this.y0 + Rn * Math.sin(lat) / Math.cos(this.lat_ts);
}
*/
p.x=x;
p.y=y;
return p;
},//ceaFwd()
/* Cylindrical Equal Area inverse equations--mapping x,y to lat/long
------------------------------------------------------------*/
inverse: function(p) {
p.x -= this.x0;
p.y -= this.y0;
var lon = Proj4js.common.adjust_lon( this.long0 + (p.x / this.a) / Math.cos(this.lat_ts) );
var lat = Math.asin( (p.y/this.a) * Math.cos(this.lat_ts) );
p.x=lon;
p.y=lat;
return p;
}//ceaInv()
};
+42
View File
@@ -0,0 +1,42 @@
/* similar to equi.js FIXME proj4 uses eqc */
Proj4js.Proj.eqc = {
init : function() {
if(!this.x0) this.x0=0;
if(!this.y0) this.y0=0;
if(!this.lat0) this.lat0=0;
if(!this.long0) this.long0=0;
if(!this.lat_ts) this.lat_ts=0;
if (!this.title) this.title = "Equidistant Cylindrical (Plate Carre)";
this.rc= Math.cos(this.lat_ts);
},
// forward equations--mapping lat,long to x,y
// -----------------------------------------------------------------
forward : function(p) {
var lon= p.x;
var lat= p.y;
var dlon = Proj4js.common.adjust_lon(lon - this.long0);
var dlat = Proj4js.common.adjust_lat(lat - this.lat0 );
p.x= this.x0 + (this.a*dlon*this.rc);
p.y= this.y0 + (this.a*dlat );
return p;
},
// inverse equations--mapping x,y to lat/long
// -----------------------------------------------------------------
inverse : function(p) {
var x= p.x;
var y= p.y;
p.x= Proj4js.common.adjust_lon(this.long0 + ((x - this.x0)/(this.a*this.rc)));
p.y= Proj4js.common.adjust_lat(this.lat0 + ((y - this.y0)/(this.a )));
return p;
}
};
+140
View File
@@ -0,0 +1,140 @@
/*******************************************************************************
NAME EQUIDISTANT CONIC
PURPOSE: Transforms input longitude and latitude to Easting and Northing
for the Equidistant Conic projection. The longitude and
latitude must be in radians. The Easting and Northing values
will be returned in meters.
PROGRAMMER DATE
---------- ----
T. Mittan Mar, 1993
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
/* Variables common to all subroutines in this code file
-----------------------------------------------------*/
Proj4js.Proj.eqdc = {
/* Initialize the Equidistant Conic projection
------------------------------------------*/
init: function() {
/* Place parameters in static storage for common use
-------------------------------------------------*/
if(!this.mode) this.mode=0;//chosen default mode
this.temp = this.b / this.a;
this.es = 1.0 - Math.pow(this.temp,2);
this.e = Math.sqrt(this.es);
this.e0 = Proj4js.common.e0fn(this.es);
this.e1 = Proj4js.common.e1fn(this.es);
this.e2 = Proj4js.common.e2fn(this.es);
this.e3 = Proj4js.common.e3fn(this.es);
this.sinphi=Math.sin(this.lat1);
this.cosphi=Math.cos(this.lat1);
this.ms1 = Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);
this.ml1 = Proj4js.common.mlfn(this.e0, this.e1, this.e2,this.e3, this.lat1);
/* format B
---------*/
if (this.mode != 0) {
if (Math.abs(this.lat1 + this.lat2) < Proj4js.common.EPSLN) {
Proj4js.reportError("eqdc:Init:EqualLatitudes");
//return(81);
}
this.sinphi=Math.sin(this.lat2);
this.cosphi=Math.cos(this.lat2);
this.ms2 = Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);
this.ml2 = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2);
if (Math.abs(this.lat1 - this.lat2) >= Proj4js.common.EPSLN) {
this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1);
} else {
this.ns = this.sinphi;
}
} else {
this.ns = this.sinphi;
}
this.g = this.ml1 + this.ms1/this.ns;
this.ml0 = Proj4js.common.mlfn(this.e0, this.e1,this. e2, this.e3, this.lat0);
this.rh = this.a * (this.g - this.ml0);
},
/* Equidistant Conic forward equations--mapping lat,long to x,y
-----------------------------------------------------------*/
forward: function(p) {
var lon=p.x;
var lat=p.y;
/* Forward equations
-----------------*/
var ml = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat);
var rh1 = this.a * (this.g - ml);
var theta = this.ns * Proj4js.common.adjust_lon(lon - this.long0);
var x = this.x0 + rh1 * Math.sin(theta);
var y = this.y0 + this.rh - rh1 * Math.cos(theta);
p.x=x;
p.y=y;
return p;
},
/* Inverse equations
-----------------*/
inverse: function(p) {
p.x -= this.x0;
p.y = this.rh - p.y + this.y0;
var con, rh1;
if (this.ns >= 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;
}
var theta = 0.0;
if (rh1 != 0.0) theta = Math.atan2(con *p.x, con *p.y);
var ml = this.g - rh1 /this.a;
var lat = this.phi3z(ml,this.e0,this.e1,this.e2,this.e3);
var lon = Proj4js.common.adjust_lon(this.long0 + theta / this.ns);
p.x=lon;
p.y=lat;
return p;
},
/* Function to compute latitude, phi3, for the inverse of the Equidistant
Conic projection.
-----------------------------------------------------------------*/
phi3z: function(ml,e0,e1,e2,e3) {
var phi;
var dphi;
phi = ml;
for (var i = 0; i < 15; i++) {
dphi = (ml + e1 * Math.sin(2.0 * phi) - e2 * Math.sin(4.0 * phi) + e3 * Math.sin(6.0 * phi))/ e0 - phi;
phi += dphi;
if (Math.abs(dphi) <= .0000000001) {
return phi;
}
}
Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations");
return null;
}
};
+72
View File
@@ -0,0 +1,72 @@
/*******************************************************************************
NAME EQUIRECTANGULAR
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Equirectangular projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
T. Mittan Mar, 1993
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
Proj4js.Proj.equi = {
init: function() {
if(!this.x0) this.x0=0;
if(!this.y0) this.y0=0;
if(!this.lat0) this.lat0=0;
if(!this.long0) this.long0=0;
///this.t2;
},
/* Equirectangular forward equations--mapping lat,long to x,y
---------------------------------------------------------*/
forward: function(p) {
var lon=p.x;
var lat=p.y;
var dlon = Proj4js.common.adjust_lon(lon - this.long0);
var x = this.x0 +this. a * dlon *Math.cos(this.lat0);
var y = this.y0 + this.a * lat;
this.t1=x;
this.t2=Math.cos(this.lat0);
p.x=x;
p.y=y;
return p;
}, //equiFwd()
/* Equirectangular inverse equations--mapping x,y to lat/long
---------------------------------------------------------*/
inverse: function(p) {
p.x -= this.x0;
p.y -= this.y0;
var lat = p.y /this. a;
if ( Math.abs(lat) > Proj4js.common.HALF_PI) {
Proj4js.reportError("equi:Inv:DataError");
}
var lon = Proj4js.common.adjust_lon(this.long0 + p.x / (this.a * Math.cos(this.lat0)));
p.x=lon;
p.y=lat;
}//equiInv()
};
+44
View File
@@ -0,0 +1,44 @@
Proj4js.Proj.gauss = {
init : function() {
var sphi = Math.sin(this.lat0);
var cphi = Math.cos(this.lat0);
cphi *= cphi;
this.rc = Math.sqrt(1.0 - this.es) / (1.0 - this.es * sphi * sphi);
this.C = Math.sqrt(1.0 + this.es * cphi * cphi / (1.0 - this.es));
this.phic0 = Math.asin(sphi / this.C);
this.ratexp = 0.5 * this.C * this.e;
this.K = Math.tan(0.5 * this.phic0 + Proj4js.common.FORTPI) / (Math.pow(Math.tan(0.5*this.lat0 + Proj4js.common.FORTPI), this.C) * Proj4js.common.srat(this.e*sphi, this.ratexp));
},
forward : function(p) {
var lon = p.x;
var lat = p.y;
p.y = 2.0 * Math.atan( this.K * Math.pow(Math.tan(0.5 * lat + Proj4js.common.FORTPI), this.C) * Proj4js.common.srat(this.e * Math.sin(lat), this.ratexp) ) - Proj4js.common.HALF_PI;
p.x = this.C * lon;
return p;
},
inverse : function(p) {
var DEL_TOL = 1e-14;
var lon = p.x / this.C;
var lat = p.y;
var num = Math.pow(Math.tan(0.5 * lat + Proj4js.common.FORTPI)/this.K, 1./this.C);
for (var i = Proj4js.common.MAX_ITER; i>0; --i) {
lat = 2.0 * Math.atan(num * Proj4js.common.srat(this.e * Math.sin(p.y), -0.5 * this.e)) - Proj4js.common.HALF_PI;
if (Math.abs(lat - p.y) < DEL_TOL) break;
p.y = lat;
}
/* convergence failed */
if (!i) {
Proj4js.reportError("gauss:inverse:convergence failed");
return null;
}
p.x = lon;
p.y = lat;
return p;
}
};
+117
View File
@@ -0,0 +1,117 @@
/*****************************************************************************
NAME GNOMONIC
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Gnomonic Projection.
Implementation based on the existing sterea and ortho
implementations.
PROGRAMMER DATE
---------- ----
Richard Marsden November 2009
ALGORITHM REFERENCES
1. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map
Projections", University of Chicago Press 1993
2. Wolfram Mathworld "Gnomonic Projection"
http://mathworld.wolfram.com/GnomonicProjection.html
Accessed: 12th November 2009
******************************************************************************/
Proj4js.Proj.gnom = {
/* Initialize the Gnomonic projection
-------------------------------------*/
init: function(def) {
/* Place parameters in static storage for common use
-------------------------------------------------*/
this.sin_p14=Math.sin(this.lat0);
this.cos_p14=Math.cos(this.lat0);
// Approximation for projecting points to the horizon (infinity)
this.infinity_dist = 1000 * this.a;
this.rc = 1;
},
/* Gnomonic forward equations--mapping lat,long to x,y
---------------------------------------------------*/
forward: function(p) {
var sinphi, cosphi; /* sin and cos value */
var dlon; /* delta longitude value */
var coslon; /* cos of longitude */
var ksp; /* scale factor */
var g;
var x, y;
var lon=p.x;
var lat=p.y;
/* Forward equations
-----------------*/
dlon = Proj4js.common.adjust_lon(lon - this.long0);
sinphi=Math.sin(lat);
cosphi=Math.cos(lat);
coslon = Math.cos(dlon);
g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;
ksp = 1.0;
if ((g > 0) || (Math.abs(g) <= Proj4js.common.EPSLN)) {
x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g;
y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g;
} else {
Proj4js.reportError("orthoFwdPointError");
// Point is in the opposing hemisphere and is unprojectable
// We still need to return a reasonable point, so we project
// to infinity, on a bearing
// equivalent to the northern hemisphere equivalent
// This is a reasonable approximation for short shapes and lines that
// straddle the horizon.
x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon);
y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
}
p.x=x;
p.y=y;
return p;
},
inverse: function(p) {
var rh; /* Rho */
var z; /* angle */
var sinc, cosc;
var c;
var lon , lat;
/* Inverse equations
-----------------*/
p.x = (p.x - this.x0) / this.a;
p.y = (p.y - this.y0) / this.a;
p.x /= this.k0;
p.y /= this.k0;
if ( (rh = Math.sqrt(p.x * p.x + p.y * p.y)) ) {
c = Math.atan2(rh, this.rc);
sinc = Math.sin(c);
cosc = Math.cos(c);
lat = Proj4js.common.asinz(cosc*this.sin_p14 + (p.y*sinc*this.cos_p14) / rh);
lon = Math.atan2(p.x*sinc, rh*this.cos_p14*cosc - p.y*this.sin_p14*sinc);
lon = Proj4js.common.adjust_lon(this.long0+lon);
} else {
lat = this.phic0;
lon = 0.0;
}
p.x=lon;
p.y=lat;
return p;
}
};
+52
View File
@@ -0,0 +1,52 @@
Proj4js.Proj.gstmerc = {
init : function() {
// array of: a, b, lon0, lat0, k0, x0, y0
var temp= this.b / this.a;
this.e= Math.sqrt(1.0 - temp*temp);
this.lc= this.long0;
this.rs= Math.sqrt(1.0+this.e*this.e*Math.pow(Math.cos(this.lat0),4.0)/(1.0-this.e*this.e));
var sinz= Math.sin(this.lat0);
var pc= Math.asin(sinz/this.rs);
var sinzpc= Math.sin(pc);
this.cp= Proj4js.common.latiso(0.0,pc,sinzpc)-this.rs*Proj4js.common.latiso(this.e,this.lat0,sinz);
this.n2= this.k0*this.a*Math.sqrt(1.0-this.e*this.e)/(1.0-this.e*this.e*sinz*sinz);
this.xs= this.x0;
this.ys= this.y0-this.n2*pc;
if (!this.title) this.title = "Gauss Schreiber transverse mercator";
},
// forward equations--mapping lat,long to x,y
// -----------------------------------------------------------------
forward : function(p) {
var lon= p.x;
var lat= p.y;
var L= this.rs*(lon-this.lc);
var Ls= this.cp+(this.rs*Proj4js.common.latiso(this.e,lat,Math.sin(lat)));
var lat1= Math.asin(Math.sin(L)/Proj4js.common.cosh(Ls));
var Ls1= Proj4js.common.latiso(0.0,lat1,Math.sin(lat1));
p.x= this.xs+(this.n2*Ls1);
p.y= this.ys+(this.n2*Math.atan(Proj4js.common.sinh(Ls)/Math.cos(L)));
return p;
},
// inverse equations--mapping x,y to lat/long
// -----------------------------------------------------------------
inverse : function(p) {
var x= p.x;
var y= p.y;
var L= Math.atan(Proj4js.common.sinh((x-this.xs)/this.n2)/Math.cos((y-this.ys)/this.n2));
var lat1= Math.asin(Math.sin((y-this.ys)/this.n2)/Proj4js.common.cosh((x-this.xs)/this.n2));
var LC= Proj4js.common.latiso(0.0,lat1,Math.sin(lat1));
p.x= this.lc+L/this.rs;
p.y= Proj4js.common.invlatiso(this.e,(LC-this.cp)/this.rs);
return p;
}
};
+135
View File
@@ -0,0 +1,135 @@
/**
NOTES: According to EPSG the full Krovak projection method should have
the following parameters. Within PROJ.4 the azimuth, and pseudo
standard parallel are hardcoded in the algorithm and can't be
altered from outside. The others all have defaults to match the
common usage with Krovak projection.
lat_0 = latitude of centre of the projection
lon_0 = longitude of centre of the projection
** = azimuth (true) of the centre line passing through the centre of the projection
** = latitude of pseudo standard parallel
k = scale factor on the pseudo standard parallel
x_0 = False Easting of the centre of the projection at the apex of the cone
y_0 = False Northing of the centre of the projection at the apex of the cone
**/
Proj4js.Proj.krovak = {
init: function() {
/* we want Bessel as fixed ellipsoid */
this.a = 6377397.155;
this.es = 0.006674372230614;
this.e = Math.sqrt(this.es);
/* if latitude of projection center is not set, use 49d30'N */
if (!this.lat0) {
this.lat0 = 0.863937979737193;
}
if (!this.long0) {
this.long0 = 0.7417649320975901 - 0.308341501185665;
}
/* if scale not set default to 0.9999 */
if (!this.k0) {
this.k0 = 0.9999;
}
this.s45 = 0.785398163397448; /* 45° */
this.s90 = 2 * this.s45;
this.fi0 = this.lat0; /* Latitude of projection centre 49° 30' */
/* Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128,
e2=0.006674372230614;
*/
this.e2 = this.es; /* 0.006674372230614; */
this.e = Math.sqrt(this.e2);
this.alfa = Math.sqrt(1. + (this.e2 * Math.pow(Math.cos(this.fi0), 4)) / (1. - this.e2));
this.uq = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */
this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa);
this.g = Math.pow( (1. + this.e * Math.sin(this.fi0)) / (1. - this.e * Math.sin(this.fi0)) , this.alfa * this.e / 2. );
this.k = Math.tan( this.u0 / 2. + this.s45) / Math.pow (Math.tan(this.fi0 / 2. + this.s45) , this.alfa) * this.g;
this.k1 = this.k0;
this.n0 = this.a * Math.sqrt(1. - this.e2) / (1. - this.e2 * Math.pow(Math.sin(this.fi0), 2));
this.s0 = 1.37008346281555; /* Latitude of pseudo standard parallel 78° 30'00" N */
this.n = Math.sin(this.s0);
this.ro0 = this.k1 * this.n0 / Math.tan(this.s0);
this.ad = this.s90 - this.uq;
},
/* ellipsoid */
/* calculate xy from lat/lon */
/* Constants, identical to inverse transform function */
forward: function(p) {
var gfi, u, deltav, s, d, eps, ro;
var lon = p.x;
var lat = p.y;
var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); // Delta longitude
/* Transformation */
gfi = Math.pow ( ((1. + this.e * Math.sin(lat)) / (1. - this.e * Math.sin(lat))) , (this.alfa * this.e / 2.));
u= 2. * (Math.atan(this.k * Math.pow( Math.tan(lat / 2. + this.s45), this.alfa) / gfi)-this.s45);
deltav = - delta_lon * this.alfa;
s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav));
d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s));
eps = this.n * d;
ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2. + this.s45) , this.n) / Math.pow(Math.tan(s / 2. + this.s45) , this.n);
/* x and y are reverted! */
//p.y = ro * Math.cos(eps) / a;
//p.x = ro * Math.sin(eps) / a;
p.y = ro * Math.cos(eps) / 1.0;
p.x = ro * Math.sin(eps) / 1.0;
if(this.czech) {
p.y *= -1.0;
p.x *= -1.0;
}
return (p);
},
/* calculate lat/lon from xy */
inverse: function(p) {
/* Constants, identisch wie in der Umkehrfunktion */
var u, deltav, s, d, eps, ro, fi1;
var ok;
/* Transformation */
/* revert y, x*/
var tmp = p.x;
p.x=p.y;
p.y=tmp;
if(this.czech) {
p.y *= -1.0;
p.x *= -1.0;
}
ro = Math.sqrt(p.x * p.x + p.y * p.y);
eps = Math.atan2(p.y, p.x);
d = eps / Math.sin(this.s0);
s = 2. * (Math.atan( Math.pow(this.ro0 / ro, 1. / this.n) * Math.tan(this.s0 / 2. + this.s45)) - this.s45);
u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d));
deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u));
p.x = this.long0 - deltav / this.alfa;
/* ITERATION FOR lat */
fi1 = u;
ok = 0;
var iter = 0;
do {
p.y = 2. * ( Math.atan( Math.pow( this.k, -1. / this.alfa) *
Math.pow( Math.tan(u / 2. + this.s45) , 1. / this.alfa) *
Math.pow( (1. + this.e * Math.sin(fi1)) / (1. - this.e * Math.sin(fi1)) , this.e / 2.)
) - this.s45);
if (Math.abs(fi1 - p.y) < 0.0000000001) ok=1;
fi1 = p.y;
iter += 1;
} while (ok==0 && iter < 15);
if (iter >= 15) {
Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations");
//console.log('iter:', iter);
return null;
}
return (p);
}
};
+358
View File
@@ -0,0 +1,358 @@
/*******************************************************************************
NAME LAMBERT AZIMUTHAL EQUAL-AREA
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Lambert Azimuthal Equal-Area projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
D. Steinwand, EROS March, 1991
This function was adapted from the Lambert Azimuthal Equal Area projection
code (FORTRAN) in the General Cartographic Transformation Package software
which is available from the U.S. Geological Survey National Mapping Division.
ALGORITHM REFERENCES
1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
3. "Software Documentation for GCTP General Cartographic Transformation
Package", U.S. Geological Survey National Mapping Division, May 1982.
*******************************************************************************/
Proj4js.Proj.laea = {
S_POLE: 1,
N_POLE: 2,
EQUIT: 3,
OBLIQ: 4,
/* Initialize the Lambert Azimuthal Equal Area projection
------------------------------------------------------*/
init: function() {
var t = Math.abs(this.lat0);
if (Math.abs(t - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) {
this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE;
} else if (Math.abs(t) < Proj4js.common.EPSLN) {
this.mode = this.EQUIT;
} else {
this.mode = this.OBLIQ;
}
if (this.es > 0) {
var sinphi;
this.qp = Proj4js.common.qsfnz(this.e, 1.0);
this.mmf = .5 / (1. - this.es);
this.apa = this.authset(this.es);
switch (this.mode) {
case this.N_POLE:
case this.S_POLE:
this.dd = 1.;
break;
case this.EQUIT:
this.rq = Math.sqrt(.5 * this.qp);
this.dd = 1. / this.rq;
this.xmf = 1.;
this.ymf = .5 * this.qp;
break;
case this.OBLIQ:
this.rq = Math.sqrt(.5 * this.qp);
sinphi = Math.sin(this.lat0);
this.sinb1 = Proj4js.common.qsfnz(this.e, sinphi) / this.qp;
this.cosb1 = Math.sqrt(1. - this.sinb1 * this.sinb1);
this.dd = Math.cos(this.lat0) / (Math.sqrt(1. - this.es * sinphi * sinphi) * this.rq * this.cosb1);
this.ymf = (this.xmf = this.rq) / this.dd;
this.xmf *= this.dd;
break;
}
} else {
if (this.mode == this.OBLIQ) {
this.sinph0 = Math.sin(this.lat0);
this.cosph0 = Math.cos(this.lat0);
}
}
},
/* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y
-----------------------------------------------------------------------*/
forward: function(p) {
/* Forward equations
-----------------*/
var x,y;
var lam=p.x;
var phi=p.y;
lam = Proj4js.common.adjust_lon(lam - this.long0);
if (this.sphere) {
var coslam, cosphi, sinphi;
sinphi = Math.sin(phi);
cosphi = Math.cos(phi);
coslam = Math.cos(lam);
switch (this.mode) {
case this.OBLIQ:
case this.EQUIT:
y = (this.mode == this.EQUIT) ? 1. + cosphi * coslam : 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;
if (y <= Proj4js.common.EPSLN) {
Proj4js.reportError("laea:fwd:y less than eps");
return null;
}
y = Math.sqrt(2. / y);
x = y * cosphi * Math.sin(lam);
y *= (this.mode == this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;
break;
case this.N_POLE:
coslam = -coslam;
case this.S_POLE:
if (Math.abs(phi + this.phi0) < Proj4js.common.EPSLN) {
Proj4js.reportError("laea:fwd:phi < eps");
return null;
}
y = Proj4js.common.FORTPI - phi * .5;
y = 2. * ((this.mode == this.S_POLE) ? Math.cos(y) : Math.sin(y));
x = y * Math.sin(lam);
y *= coslam;
break;
}
} else {
var coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0;
coslam = Math.cos(lam);
sinlam = Math.sin(lam);
sinphi = Math.sin(phi);
q = Proj4js.common.qsfnz(this.e, sinphi);
if (this.mode == this.OBLIQ || this.mode == this.EQUIT) {
sinb = q / this.qp;
cosb = Math.sqrt(1. - sinb * sinb);
}
switch (this.mode) {
case this.OBLIQ:
b = 1. + this.sinb1 * sinb + this.cosb1 * cosb * coslam;
break;
case this.EQUIT:
b = 1. + cosb * coslam;
break;
case this.N_POLE:
b = Proj4js.common.HALF_PI + phi;
q = this.qp - q;
break;
case this.S_POLE:
b = phi - Proj4js.common.HALF_PI;
q = this.qp + q;
break;
}
if (Math.abs(b) < Proj4js.common.EPSLN) {
Proj4js.reportError("laea:fwd:b < eps");
return null;
}
switch (this.mode) {
case this.OBLIQ:
case this.EQUIT:
b = Math.sqrt(2. / b);
if (this.mode == this.OBLIQ) {
y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam);
} else {
y = (b = Math.sqrt(2. / (1. + cosb * coslam))) * sinb * this.ymf;
}
x = this.xmf * b * cosb * sinlam;
break;
case this.N_POLE:
case this.S_POLE:
if (q >= 0.) {
x = (b = Math.sqrt(q)) * sinlam;
y = coslam * ((this.mode == this.S_POLE) ? b : -b);
} else {
x = y = 0.;
}
break;
}
}
//v 1.0
/*
var sin_lat=Math.sin(lat);
var cos_lat=Math.cos(lat);
var sin_delta_lon=Math.sin(delta_lon);
var cos_delta_lon=Math.cos(delta_lon);
var g =this.sin_lat_o * sin_lat +this.cos_lat_o * cos_lat * cos_delta_lon;
if (g == -1.0) {
Proj4js.reportError("laea:fwd:Point projects to a circle of radius "+ 2.0 * R);
return null;
}
var ksp = this.a * Math.sqrt(2.0 / (1.0 + g));
var x = ksp * cos_lat * sin_delta_lon + this.x0;
var y = ksp * (this.cos_lat_o * sin_lat - this.sin_lat_o * cos_lat * cos_delta_lon) + this.y0;
*/
p.x = this.a*x + this.x0;
p.y = this.a*y + this.y0;
return p;
},//lamazFwd()
/* Inverse equations
-----------------*/
inverse: function(p) {
p.x -= this.x0;
p.y -= this.y0;
var x = p.x/this.a;
var y = p.y/this.a;
var lam, phi;
if (this.sphere) {
var cosz=0.0, rh, sinz=0.0;
rh = Math.sqrt(x*x + y*y);
phi = rh * .5;
if (phi > 1.) {
Proj4js.reportError("laea:Inv:DataError");
return null;
}
phi = 2. * Math.asin(phi);
if (this.mode == this.OBLIQ || this.mode == this.EQUIT) {
sinz = Math.sin(phi);
cosz = Math.cos(phi);
}
switch (this.mode) {
case this.EQUIT:
phi = (Math.abs(rh) <= Proj4js.common.EPSLN) ? 0. : Math.asin(y * sinz / rh);
x *= sinz;
y = cosz * rh;
break;
case this.OBLIQ:
phi = (Math.abs(rh) <= Proj4js.common.EPSLN) ? this.phi0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh);
x *= sinz * this.cosph0;
y = (cosz - Math.sin(phi) * this.sinph0) * rh;
break;
case this.N_POLE:
y = -y;
phi = Proj4js.common.HALF_PI - phi;
break;
case this.S_POLE:
phi -= Proj4js.common.HALF_PI;
break;
}
lam = (y == 0. && (this.mode == this.EQUIT || this.mode == this.OBLIQ)) ? 0. : Math.atan2(x, y);
} else {
var cCe, sCe, q, rho, ab=0.0;
switch (this.mode) {
case this.EQUIT:
case this.OBLIQ:
x /= this.dd;
y *= this.dd;
rho = Math.sqrt(x*x + y*y);
if (rho < Proj4js.common.EPSLN) {
p.x = 0.;
p.y = this.phi0;
return p;
}
sCe = 2. * Math.asin(.5 * rho / this.rq);
cCe = Math.cos(sCe);
x *= (sCe = Math.sin(sCe));
if (this.mode == this.OBLIQ) {
ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho
q = this.qp * ab;
y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe;
} else {
ab = y * sCe / rho;
q = this.qp * ab;
y = rho * cCe;
}
break;
case this.N_POLE:
y = -y;
case this.S_POLE:
q = (x * x + y * y);
if (!q ) {
p.x = 0.;
p.y = this.phi0;
return p;
}
/*
q = this.qp - q;
*/
ab = 1. - q / this.qp;
if (this.mode == this.S_POLE) {
ab = - ab;
}
break;
}
lam = Math.atan2(x, y);
phi = this.authlat(Math.asin(ab), this.apa);
}
/*
var Rh = Math.Math.sqrt(p.x *p.x +p.y * p.y);
var temp = Rh / (2.0 * this.a);
if (temp > 1) {
Proj4js.reportError("laea:Inv:DataError");
return null;
}
var z = 2.0 * Proj4js.common.asinz(temp);
var sin_z=Math.sin(z);
var cos_z=Math.cos(z);
var lon =this.long0;
if (Math.abs(Rh) > Proj4js.common.EPSLN) {
var lat = Proj4js.common.asinz(this.sin_lat_o * cos_z +this. cos_lat_o * sin_z *p.y / Rh);
var temp =Math.abs(this.lat0) - Proj4js.common.HALF_PI;
if (Math.abs(temp) > Proj4js.common.EPSLN) {
temp = cos_z -this.sin_lat_o * Math.sin(lat);
if(temp!=0.0) lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x*sin_z*this.cos_lat_o,temp*Rh));
} else if (this.lat0 < 0.0) {
lon = Proj4js.common.adjust_lon(this.long0 - Math.atan2(-p.x,p.y));
} else {
lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x, -p.y));
}
} else {
lat = this.lat0;
}
*/
//return(OK);
p.x = Proj4js.common.adjust_lon(this.long0+lam);
p.y = phi;
return p;
},//lamazInv()
/* determine latitude from authalic latitude */
P00: .33333333333333333333,
P01: .17222222222222222222,
P02: .10257936507936507936,
P10: .06388888888888888888,
P11: .06640211640211640211,
P20: .01641501294219154443,
authset: function(es) {
var t;
var APA = new Array();
APA[0] = es * this.P00;
t = es * es;
APA[0] += t * this.P01;
APA[1] = t * this.P10;
t *= es;
APA[0] += t * this.P02;
APA[1] += t * this.P11;
APA[2] = t * this.P20;
return APA;
},
authlat: function(beta, APA) {
var t = beta+beta;
return(beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t+t) + APA[2] * Math.sin(t+t+t));
}
};
+148
View File
@@ -0,0 +1,148 @@
/*******************************************************************************
NAME LAMBERT CONFORMAL CONIC
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Lambert Conformal Conic projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
*******************************************************************************/
//<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
// Initialize the Lambert Conformal conic projection
// -----------------------------------------------------------------
//Proj4js.Proj.lcc = Class.create();
Proj4js.Proj.lcc = {
init : function() {
// array of: r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north
//double c_lat; /* center latitude */
//double c_lon; /* center longitude */
//double lat1; /* first standard parallel */
//double lat2; /* second standard parallel */
//double r_maj; /* major axis */
//double r_min; /* minor axis */
//double false_east; /* x offset in meters */
//double false_north; /* y offset in meters */
if (!this.lat2){this.lat2=this.lat0;}//if lat2 is not defined
if (!this.k0) this.k0 = 1.0;
// Standard Parallels cannot be equal and on opposite sides of the equator
if (Math.abs(this.lat1+this.lat2) < Proj4js.common.EPSLN) {
Proj4js.reportError("lcc:init: Equal Latitudes");
return;
}
var temp = this.b / this.a;
this.e = Math.sqrt(1.0 - temp*temp);
var sin1 = Math.sin(this.lat1);
var cos1 = Math.cos(this.lat1);
var ms1 = Proj4js.common.msfnz(this.e, sin1, cos1);
var ts1 = Proj4js.common.tsfnz(this.e, this.lat1, sin1);
var sin2 = Math.sin(this.lat2);
var cos2 = Math.cos(this.lat2);
var ms2 = Proj4js.common.msfnz(this.e, sin2, cos2);
var ts2 = Proj4js.common.tsfnz(this.e, this.lat2, sin2);
var ts0 = Proj4js.common.tsfnz(this.e, this.lat0, Math.sin(this.lat0));
if (Math.abs(this.lat1 - this.lat2) > Proj4js.common.EPSLN) {
this.ns = Math.log(ms1/ms2)/Math.log(ts1/ts2);
} else {
this.ns = sin1;
}
this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns));
this.rh = this.a * this.f0 * Math.pow(ts0, this.ns);
if (!this.title) this.title = "Lambert Conformal Conic";
},
// Lambert Conformal conic forward equations--mapping lat,long to x,y
// -----------------------------------------------------------------
forward : function(p) {
var lon = p.x;
var lat = p.y;
// convert to radians
if ( lat <= 90.0 && lat >= -90.0 && lon <= 180.0 && lon >= -180.0) {
//lon = lon * Proj4js.common.D2R;
//lat = lat * Proj4js.common.D2R;
} else {
Proj4js.reportError("lcc:forward: llInputOutOfRange: "+ lon +" : " + lat);
return null;
}
var con = Math.abs( Math.abs(lat) - Proj4js.common.HALF_PI);
var ts, rh1;
if (con > Proj4js.common.EPSLN) {
ts = Proj4js.common.tsfnz(this.e, lat, Math.sin(lat) );
rh1 = this.a * this.f0 * Math.pow(ts, this.ns);
} else {
con = lat * this.ns;
if (con <= 0) {
Proj4js.reportError("lcc:forward: No Projection");
return null;
}
rh1 = 0;
}
var theta = this.ns * Proj4js.common.adjust_lon(lon - this.long0);
p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0;
p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0;
return p;
},
// Lambert Conformal Conic inverse equations--mapping x,y to lat/long
// -----------------------------------------------------------------
inverse : function(p) {
var rh1, con, ts;
var lat, lon;
var x = (p.x - this.x0)/this.k0;
var y = (this.rh - (p.y - this.y0)/this.k0);
if (this.ns > 0) {
rh1 = Math.sqrt (x * x + y * y);
con = 1.0;
} else {
rh1 = -Math.sqrt (x * x + y * y);
con = -1.0;
}
var theta = 0.0;
if (rh1 != 0) {
theta = Math.atan2((con * x),(con * y));
}
if ((rh1 != 0) || (this.ns > 0.0)) {
con = 1.0/this.ns;
ts = Math.pow((rh1/(this.a * this.f0)), con);
lat = Proj4js.common.phi2z(this.e, ts);
if (lat == -9999) return null;
} else {
lat = -Proj4js.common.HALF_PI;
}
lon = Proj4js.common.adjust_lon(theta/this.ns + this.long0);
p.x = lon;
p.y = lat;
return p;
}
};
+115
View File
@@ -0,0 +1,115 @@
/*******************************************************************************
NAME MERCATOR
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Mercator projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
D. Steinwand, EROS Nov, 1991
T. Mittan Mar, 1993
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
//static double r_major = a; /* major axis */
//static double r_minor = b; /* minor axis */
//static double lon_center = long0; /* Center longitude (projection center) */
//static double lat_origin = lat0; /* center latitude */
//static double e,es; /* eccentricity constants */
//static double m1; /* small value m */
//static double false_northing = y0; /* y offset in meters */
//static double false_easting = x0; /* x offset in meters */
//scale_fact = k0
Proj4js.Proj.merc = {
init : function() {
//?this.temp = this.r_minor / this.r_major;
//this.temp = this.b / this.a;
//this.es = 1.0 - Math.sqrt(this.temp);
//this.e = Math.sqrt( this.es );
//?this.m1 = Math.cos(this.lat_origin) / (Math.sqrt( 1.0 - this.es * Math.sin(this.lat_origin) * Math.sin(this.lat_origin)));
//this.m1 = Math.cos(0.0) / (Math.sqrt( 1.0 - this.es * Math.sin(0.0) * Math.sin(0.0)));
if (this.lat_ts) {
if (this.sphere) {
this.k0 = Math.cos(this.lat_ts);
} else {
this.k0 = Proj4js.common.msfnz(this.es, Math.sin(this.lat_ts), Math.cos(this.lat_ts));
}
}
},
/* Mercator forward equations--mapping lat,long to x,y
--------------------------------------------------*/
forward : function(p) {
//alert("ll2m coords : "+coords);
var lon = p.x;
var lat = p.y;
// convert to radians
if ( lat*Proj4js.common.R2D > 90.0 &&
lat*Proj4js.common.R2D < -90.0 &&
lon*Proj4js.common.R2D > 180.0 &&
lon*Proj4js.common.R2D < -180.0) {
Proj4js.reportError("merc:forward: llInputOutOfRange: "+ lon +" : " + lat);
return null;
}
var x,y;
if(Math.abs( Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN) {
Proj4js.reportError("merc:forward: ll2mAtPoles");
return null;
} else {
if (this.sphere) {
x = this.x0 + this.a * this.k0 * Proj4js.common.adjust_lon(lon - this.long0);
y = this.y0 + this.a * this.k0 * Math.log(Math.tan(Proj4js.common.FORTPI + 0.5*lat));
} else {
var sinphi = Math.sin(lat);
var ts = Proj4js.common.tsfnz(this.e,lat,sinphi);
x = this.x0 + this.a * this.k0 * Proj4js.common.adjust_lon(lon - this.long0);
y = this.y0 - this.a * this.k0 * Math.log(ts);
}
p.x = x;
p.y = y;
return p;
}
},
/* Mercator inverse equations--mapping x,y to lat/long
--------------------------------------------------*/
inverse : function(p) {
var x = p.x - this.x0;
var y = p.y - this.y0;
var lon,lat;
if (this.sphere) {
lat = Proj4js.common.HALF_PI - 2.0 * Math.atan(Math.exp(-y / this.a * this.k0));
} else {
var ts = Math.exp(-y / (this.a * this.k0));
lat = Proj4js.common.phi2z(this.e,ts);
if(lat == -9999) {
Proj4js.reportError("merc:inverse: lat = -9999");
return null;
}
}
lon = Proj4js.common.adjust_lon(this.long0+ x / (this.a * this.k0));
p.x = lon;
p.y = lat;
return p;
}
};
+68
View File
@@ -0,0 +1,68 @@
/*******************************************************************************
NAME MILLER CYLINDRICAL
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Miller Cylindrical projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
T. Mittan March, 1993
This function was adapted from the Lambert Azimuthal Equal Area projection
code (FORTRAN) in the General Cartographic Transformation Package software
which is available from the U.S. Geological Survey National Mapping Division.
ALGORITHM REFERENCES
1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
3. "Software Documentation for GCTP General Cartographic Transformation
Package", U.S. Geological Survey National Mapping Division, May 1982.
*******************************************************************************/
Proj4js.Proj.mill = {
/* Initialize the Miller Cylindrical projection
-------------------------------------------*/
init: function() {
//no-op
},
/* Miller Cylindrical forward equations--mapping lat,long to x,y
------------------------------------------------------------*/
forward: function(p) {
var lon=p.x;
var lat=p.y;
/* Forward equations
-----------------*/
var dlon = Proj4js.common.adjust_lon(lon -this.long0);
var x = this.x0 + this.a * dlon;
var y = this.y0 + this.a * Math.log(Math.tan((Proj4js.common.PI / 4.0) + (lat / 2.5))) * 1.25;
p.x=x;
p.y=y;
return p;
},//millFwd()
/* Miller Cylindrical inverse equations--mapping x,y to lat/long
------------------------------------------------------------*/
inverse: function(p) {
p.x -= this.x0;
p.y -= this.y0;
var lon = Proj4js.common.adjust_lon(this.long0 + p.x /this.a);
var lat = 2.5 * (Math.atan(Math.exp(0.8*p.y/this.a)) - Proj4js.common.PI / 4.0);
p.x=lon;
p.y=lat;
return p;
}//millInv()
};
+100
View File
@@ -0,0 +1,100 @@
/*******************************************************************************
NAME MOLLWEIDE
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the MOllweide projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
D. Steinwand, EROS May, 1991; Updated Sept, 1992; Updated Feb, 1993
S. Nelson, EDC Jun, 2993; Made corrections in precision and
number of iterations.
ALGORITHM REFERENCES
1. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
*******************************************************************************/
Proj4js.Proj.moll = {
/* Initialize the Mollweide projection
------------------------------------*/
init: function(){
//no-op
},
/* Mollweide forward equations--mapping lat,long to x,y
----------------------------------------------------*/
forward: function(p) {
/* Forward equations
-----------------*/
var lon=p.x;
var lat=p.y;
var delta_lon = Proj4js.common.adjust_lon(lon - this.long0);
var theta = lat;
var con = Proj4js.common.PI * Math.sin(lat);
/* Iterate using the Newton-Raphson method to find theta
-----------------------------------------------------*/
for (var i=0;true;i++) {
var delta_theta = -(theta + Math.sin(theta) - con)/ (1.0 + Math.cos(theta));
theta += delta_theta;
if (Math.abs(delta_theta) < Proj4js.common.EPSLN) break;
if (i >= 50) {
Proj4js.reportError("moll:Fwd:IterationError");
//return(241);
}
}
theta /= 2.0;
/* If the latitude is 90 deg, force the x coordinate to be "0 + false easting"
this is done here because of precision problems with "cos(theta)"
--------------------------------------------------------------------------*/
if (Proj4js.common.PI/2 - Math.abs(lat) < Proj4js.common.EPSLN) delta_lon =0;
var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0;
var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0;
p.x=x;
p.y=y;
return p;
},
inverse: function(p){
var theta;
var arg;
/* Inverse equations
-----------------*/
p.x-= this.x0;
//~ p.y -= this.y0;
var arg = p.y / (1.4142135623731 * this.a);
/* Because of division by zero problems, 'arg' can not be 1.0. Therefore
a number very close to one is used instead.
-------------------------------------------------------------------*/
if(Math.abs(arg) > 0.999999999999) arg=0.999999999999;
var theta =Math.asin(arg);
var lon = Proj4js.common.adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta))));
if(lon < (-Proj4js.common.PI)) lon= -Proj4js.common.PI;
if(lon > Proj4js.common.PI) lon= Proj4js.common.PI;
arg = (2.0 * theta + Math.sin(2.0 * theta)) / Proj4js.common.PI;
if(Math.abs(arg) > 1.0)arg=1.0;
var lat = Math.asin(arg);
//return(OK);
p.x=lon;
p.y=lat;
return p;
}
};
+284
View File
@@ -0,0 +1,284 @@
/*******************************************************************************
NAME NEW ZEALAND MAP GRID
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the New Zealand Map Grid projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
ALGORITHM REFERENCES
1. Department of Land and Survey Technical Circular 1973/32
http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf
2. OSG Technical Report 4.1
http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf
IMPLEMENTATION NOTES
The two references use different symbols for the calculated values. This
implementation uses the variable names similar to the symbols in reference [1].
The alogrithm uses different units for delta latitude and delta longitude.
The delta latitude is assumed to be in units of seconds of arc x 10^-5.
The delta longitude is the usual radians. Look out for these conversions.
The algorithm is described using complex arithmetic. There were three
options:
* find and use a Javascript library for complex arithmetic
* write my own complex library
* expand the complex arithmetic by hand to simple arithmetic
This implementation has expanded the complex multiplication operations
into parallel simple arithmetic operations for the real and imaginary parts.
The imaginary part is way over to the right of the display; this probably
violates every coding standard in the world, but, to me, it makes it much
more obvious what is going on.
The following complex operations are used:
- addition
- multiplication
- division
- complex number raised to integer power
- summation
A summary of complex arithmetic operations:
(from http://en.wikipedia.org/wiki/Complex_arithmetic)
addition: (a + bi) + (c + di) = (a + c) + (b + d)i
subtraction: (a + bi) - (c + di) = (a - c) + (b - d)i
multiplication: (a + bi) x (c + di) = (ac - bd) + (bc + ad)i
division: (a + bi) / (c + di) = [(ac + bd)/(cc + dd)] + [(bc - ad)/(cc + dd)]i
The algorithm needs to calculate summations of simple and complex numbers. This is
implemented using a for-loop, pre-loading the summed value to zero.
The algorithm needs to calculate theta^2, theta^3, etc while doing a summation.
There are three possible implementations:
- use Math.pow in the summation loop - except for complex numbers
- precalculate the values before running the loop
- calculate theta^n = theta^(n-1) * theta during the loop
This implementation uses the third option for both real and complex arithmetic.
For example
psi_n = 1;
sum = 0;
for (n = 1; n <=6; n++) {
psi_n1 = psi_n * psi; // calculate psi^(n+1)
psi_n = psi_n1;
sum = sum + A[n] * psi_n;
}
TEST VECTORS
NZMG E, N: 2487100.638 6751049.719 metres
NZGD49 long, lat: 172.739194 -34.444066 degrees
NZMG E, N: 2486533.395 6077263.661 metres
NZGD49 long, lat: 172.723106 -40.512409 degrees
NZMG E, N: 2216746.425 5388508.765 metres
NZGD49 long, lat: 169.172062 -46.651295 degrees
Note that these test vectors convert from NZMG metres to lat/long referenced
to NZGD49, not the more usual WGS84. The difference is about 70m N/S and about
10m E/W.
These test vectors are provided in reference [1]. Many more test
vectors are available in
http://www.linz.govt.nz/docs/topography/topographicdata/placenamesdatabase/nznamesmar08.zip
which is a catalog of names on the 260-series maps.
EPSG CODES
NZMG EPSG:27200
NZGD49 EPSG:4272
http://spatialreference.org/ defines these as
Proj4js.defs["EPSG:4272"] = "+proj=longlat +ellps=intl +datum=nzgd49 +no_defs ";
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 ";
LICENSE
Copyright: Stephen Irons 2008
Released under terms of the LGPL as per: http://www.gnu.org/copyleft/lesser.html
*******************************************************************************/
/**
Initialize New Zealand Map Grip projection
*/
Proj4js.Proj.nzmg = {
/**
* iterations: Number of iterations to refine inverse transform.
* 0 -> km accuracy
* 1 -> m accuracy -- suitable for most mapping applications
* 2 -> mm accuracy
*/
iterations: 1,
init : function() {
this.A = new Array();
this.A[1] = +0.6399175073;
this.A[2] = -0.1358797613;
this.A[3] = +0.063294409;
this.A[4] = -0.02526853;
this.A[5] = +0.0117879;
this.A[6] = -0.0055161;
this.A[7] = +0.0026906;
this.A[8] = -0.001333;
this.A[9] = +0.00067;
this.A[10] = -0.00034;
this.B_re = new Array(); this.B_im = new Array();
this.B_re[1] = +0.7557853228; this.B_im[1] = 0.0;
this.B_re[2] = +0.249204646; this.B_im[2] = +0.003371507;
this.B_re[3] = -0.001541739; this.B_im[3] = +0.041058560;
this.B_re[4] = -0.10162907; this.B_im[4] = +0.01727609;
this.B_re[5] = -0.26623489; this.B_im[5] = -0.36249218;
this.B_re[6] = -0.6870983; this.B_im[6] = -1.1651967;
this.C_re = new Array(); this.C_im = new Array();
this.C_re[1] = +1.3231270439; this.C_im[1] = 0.0;
this.C_re[2] = -0.577245789; this.C_im[2] = -0.007809598;
this.C_re[3] = +0.508307513; this.C_im[3] = -0.112208952;
this.C_re[4] = -0.15094762; this.C_im[4] = +0.18200602;
this.C_re[5] = +1.01418179; this.C_im[5] = +1.64497696;
this.C_re[6] = +1.9660549; this.C_im[6] = +2.5127645;
this.D = new Array();
this.D[1] = +1.5627014243;
this.D[2] = +0.5185406398;
this.D[3] = -0.03333098;
this.D[4] = -0.1052906;
this.D[5] = -0.0368594;
this.D[6] = +0.007317;
this.D[7] = +0.01220;
this.D[8] = +0.00394;
this.D[9] = -0.0013;
},
/**
New Zealand Map Grid Forward - long/lat to x/y
long/lat in radians
*/
forward : function(p) {
var lon = p.x;
var lat = p.y;
var delta_lat = lat - this.lat0;
var delta_lon = lon - this.long0;
// 1. Calculate d_phi and d_psi ... // and d_lambda
// For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians.
var d_phi = delta_lat / Proj4js.common.SEC_TO_RAD * 1E-5; var d_lambda = delta_lon;
var d_phi_n = 1; // d_phi^0
var d_psi = 0;
for (var n = 1; n <= 10; n++) {
d_phi_n = d_phi_n * d_phi;
d_psi = d_psi + this.A[n] * d_phi_n;
}
// 2. Calculate theta
var th_re = d_psi; var th_im = d_lambda;
// 3. Calculate z
var th_n_re = 1; var th_n_im = 0; // theta^0
var th_n_re1; var th_n_im1;
var z_re = 0; var z_im = 0;
for (var n = 1; n <= 6; n++) {
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;
th_n_re = th_n_re1; th_n_im = th_n_im1;
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;
}
// 4. Calculate easting and northing
p.x = (z_im * this.a) + this.x0;
p.y = (z_re * this.a) + this.y0;
return p;
},
/**
New Zealand Map Grid Inverse - x/y to long/lat
*/
inverse : function(p) {
var x = p.x;
var y = p.y;
var delta_x = x - this.x0;
var delta_y = y - this.y0;
// 1. Calculate z
var z_re = delta_y / this.a; var z_im = delta_x / this.a;
// 2a. Calculate theta - first approximation gives km accuracy
var z_n_re = 1; var z_n_im = 0; // z^0
var z_n_re1; var z_n_im1;
var th_re = 0; var th_im = 0;
for (var n = 1; n <= 6; n++) {
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;
z_n_re = z_n_re1; z_n_im = z_n_im1;
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;
}
// 2b. Iterate to refine the accuracy of the calculation
// 0 iterations gives km accuracy
// 1 iteration gives m accuracy -- good enough for most mapping applications
// 2 iterations bives mm accuracy
for (var i = 0; i < this.iterations; i++) {
var th_n_re = th_re; var th_n_im = th_im;
var th_n_re1; var th_n_im1;
var num_re = z_re; var num_im = z_im;
for (var n = 2; n <= 6; n++) {
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;
th_n_re = th_n_re1; th_n_im = th_n_im1;
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);
}
th_n_re = 1; th_n_im = 0;
var den_re = this.B_re[1]; var den_im = this.B_im[1];
for (var n = 2; n <= 6; n++) {
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;
th_n_re = th_n_re1; th_n_im = th_n_im1;
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);
}
// Complex division
var den2 = den_re*den_re + den_im*den_im;
th_re = (num_re*den_re + num_im*den_im) / den2; th_im = (num_im*den_re - num_re*den_im) / den2;
}
// 3. Calculate d_phi ... // and d_lambda
var d_psi = th_re; var d_lambda = th_im;
var d_psi_n = 1; // d_psi^0
var d_phi = 0;
for (var n = 1; n <= 9; n++) {
d_psi_n = d_psi_n * d_psi;
d_phi = d_phi + this.D[n] * d_psi_n;
}
// 4. Calculate latitude and longitude
// d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians.
var lat = this.lat0 + (d_phi * Proj4js.common.SEC_TO_RAD * 1E5);
var lon = this.long0 + d_lambda;
p.x = lon;
p.y = lat;
return p;
}
};
+256
View File
@@ -0,0 +1,256 @@
/*******************************************************************************
NAME OBLIQUE MERCATOR (HOTINE)
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Oblique Mercator projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
T. Mittan Mar, 1993
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
Proj4js.Proj.omerc = {
/* Initialize the Oblique Mercator projection
------------------------------------------*/
init: function() {
if (!this.mode) this.mode=0;
if (!this.lon1) {this.lon1=0;this.mode=1;}
if (!this.lon2) this.lon2=0;
if (!this.lat2) this.lat2=0;
/* Place parameters in static storage for common use
-------------------------------------------------*/
var temp = this.b/ this.a;
var es = 1.0 - Math.pow(temp,2);
var e = Math.sqrt(es);
this.sin_p20=Math.sin(this.lat0);
this.cos_p20=Math.cos(this.lat0);
this.con = 1.0 - this.es * this.sin_p20 * this.sin_p20;
this.com = Math.sqrt(1.0 - es);
this.bl = Math.sqrt(1.0 + this.es * Math.pow(this.cos_p20,4.0)/(1.0 - es));
this.al = this.a * this.bl * this.k0 * this.com / this.con;
if (Math.abs(this.lat0) < Proj4js.common.EPSLN) {
this.ts = 1.0;
this.d = 1.0;
this.el = 1.0;
} else {
this.ts = Proj4js.common.tsfnz(this.e,this.lat0,this.sin_p20);
this.con = Math.sqrt(this.con);
this.d = this.bl * this.com / (this.cos_p20 * this.con);
if ((this.d * this.d - 1.0) > 0.0) {
if (this.lat0 >= 0.0) {
this.f = this.d + Math.sqrt(this.d * this.d - 1.0);
} else {
this.f = this.d - Math.sqrt(this.d * this.d - 1.0);
}
} else {
this.f = this.d;
}
this.el = this.f * Math.pow(this.ts,this.bl);
}
//this.longc=52.60353916666667;
if (this.mode != 0) {
this.g = .5 * (this.f - 1.0/this.f);
this.gama = Proj4js.common.asinz(Math.sin(this.alpha) / this.d);
this.longc= this.longc - Proj4js.common.asinz(this.g * Math.tan(this.gama))/this.bl;
/* Report parameters common to format B
-------------------------------------*/
//genrpt(azimuth * R2D,"Azimuth of Central Line: ");
//cenlon(lon_origin);
// cenlat(lat_origin);
this.con = Math.abs(this.lat0);
if ((this.con > Proj4js.common.EPSLN) && (Math.abs(this.con - Proj4js.common.HALF_PI) > Proj4js.common.EPSLN)) {
this.singam=Math.sin(this.gama);
this.cosgam=Math.cos(this.gama);
this.sinaz=Math.sin(this.alpha);
this.cosaz=Math.cos(this.alpha);
if (this.lat0>= 0) {
this.u = (this.al / this.bl) * Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz);
} else {
this.u = -(this.al / this.bl) *Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz);
}
} else {
Proj4js.reportError("omerc:Init:DataError");
}
} else {
this.sinphi =Math. sin(this.at1);
this.ts1 = Proj4js.common.tsfnz(this.e,this.lat1,this.sinphi);
this.sinphi = Math.sin(this.lat2);
this.ts2 = Proj4js.common.tsfnz(this.e,this.lat2,this.sinphi);
this.h = Math.pow(this.ts1,this.bl);
this.l = Math.pow(this.ts2,this.bl);
this.f = this.el/this.h;
this.g = .5 * (this.f - 1.0/this.f);
this.j = (this.el * this.el - this.l * this.h)/(this.el * this.el + this.l * this.h);
this.p = (this.l - this.h) / (this.l + this.h);
this.dlon = this.lon1 - this.lon2;
if (this.dlon < -Proj4js.common.PI) this.lon2 = this.lon2 - 2.0 * Proj4js.common.PI;
if (this.dlon > Proj4js.common.PI) this.lon2 = this.lon2 + 2.0 * Proj4js.common.PI;
this.dlon = this.lon1 - this.lon2;
this.longc = .5 * (this.lon1 + this.lon2) -Math.atan(this.j * Math.tan(.5 * this.bl * this.dlon)/this.p)/this.bl;
this.dlon = Proj4js.common.adjust_lon(this.lon1 - this.longc);
this.gama = Math.atan(Math.sin(this.bl * this.dlon)/this.g);
this.alpha = Proj4js.common.asinz(this.d * Math.sin(this.gama));
/* Report parameters common to format A
-------------------------------------*/
if (Math.abs(this.lat1 - this.lat2) <= Proj4js.common.EPSLN) {
Proj4js.reportError("omercInitDataError");
//return(202);
} else {
this.con = Math.abs(this.lat1);
}
if ((this.con <= Proj4js.common.EPSLN) || (Math.abs(this.con - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN)) {
Proj4js.reportError("omercInitDataError");
//return(202);
} else {
if (Math.abs(Math.abs(this.lat0) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN) {
Proj4js.reportError("omercInitDataError");
//return(202);
}
}
this.singam=Math.sin(this.gam);
this.cosgam=Math.cos(this.gam);
this.sinaz=Math.sin(this.alpha);
this.cosaz=Math.cos(this.alpha);
if (this.lat0 >= 0) {
this.u = (this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz);
} else {
this.u = -(this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz);
}
}
},
/* Oblique Mercator forward equations--mapping lat,long to x,y
----------------------------------------------------------*/
forward: function(p) {
var theta; /* angle */
var sin_phi, cos_phi;/* sin and cos value */
var b; /* temporary values */
var c, t, tq; /* temporary values */
var con, n, ml; /* cone constant, small m */
var q,us,vl;
var ul,vs;
var s;
var dlon;
var ts1;
var lon=p.x;
var lat=p.y;
/* Forward equations
-----------------*/
sin_phi = Math.sin(lat);
dlon = Proj4js.common.adjust_lon(lon - this.longc);
vl = Math.sin(this.bl * dlon);
if (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) > Proj4js.common.EPSLN) {
ts1 = Proj4js.common.tsfnz(this.e,lat,sin_phi);
q = this.el / (Math.pow(ts1,this.bl));
s = .5 * (q - 1.0 / q);
t = .5 * (q + 1.0/ q);
ul = (s * this.singam - vl * this.cosgam) / t;
con = Math.cos(this.bl * dlon);
if (Math.abs(con) < .0000001) {
us = this.al * this.bl * dlon;
} else {
us = this.al * Math.atan((s * this.cosgam + vl * this.singam) / con)/this.bl;
if (con < 0) us = us + Proj4js.common.PI * this.al / this.bl;
}
} else {
if (lat >= 0) {
ul = this.singam;
} else {
ul = -this.singam;
}
us = this.al * lat / this.bl;
}
if (Math.abs(Math.abs(ul) - 1.0) <= Proj4js.common.EPSLN) {
//alert("Point projects into infinity","omer-for");
Proj4js.reportError("omercFwdInfinity");
//return(205);
}
vs = .5 * this.al * Math.log((1.0 - ul)/(1.0 + ul)) / this.bl;
us = us - this.u;
var x = this.x0 + vs * this.cosaz + us * this.sinaz;
var y = this.y0 + us * this.cosaz - vs * this.sinaz;
p.x=x;
p.y=y;
return p;
},
inverse: function(p) {
var delta_lon; /* Delta longitude (Given longitude - center */
var theta; /* angle */
var delta_theta; /* adjusted longitude */
var sin_phi, cos_phi;/* sin and cos value */
var b; /* temporary values */
var c, t, tq; /* temporary values */
var con, n, ml; /* cone constant, small m */
var vs,us,q,s,ts1;
var vl,ul,bs;
var lon, lat;
var flag;
/* Inverse equations
-----------------*/
p.x -= this.x0;
p.y -= this.y0;
flag = 0;
vs = p.x * this.cosaz - p.y * this.sinaz;
us = p.y * this.cosaz + p.x * this.sinaz;
us = us + this.u;
q = Math.exp(-this.bl * vs / this.al);
s = .5 * (q - 1.0/q);
t = .5 * (q + 1.0/q);
vl = Math.sin(this.bl * us / this.al);
ul = (vl * this.cosgam + s * this.singam)/t;
if (Math.abs(Math.abs(ul) - 1.0) <= Proj4js.common.EPSLN)
{
lon = this.longc;
if (ul >= 0.0) {
lat = Proj4js.common.HALF_PI;
} else {
lat = -Proj4js.common.HALF_PI;
}
} else {
con = 1.0 / this.bl;
ts1 =Math.pow((this.el / Math.sqrt((1.0 + ul) / (1.0 - ul))),con);
lat = Proj4js.common.phi2z(this.e,ts1);
//if (flag != 0)
//return(flag);
//~ con = Math.cos(this.bl * us /al);
theta = this.longc - Math.atan2((s * this.cosgam - vl * this.singam) , con)/this.bl;
lon = Proj4js.common.adjust_lon(theta);
}
p.x=lon;
p.y=lat;
return p;
}
};
+110
View File
@@ -0,0 +1,110 @@
/*******************************************************************************
NAME ORTHOGRAPHIC
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Orthographic projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
T. Mittan Mar, 1993
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
Proj4js.Proj.ortho = {
/* Initialize the Orthographic projection
-------------------------------------*/
init: function(def) {
//double temp; /* temporary variable */
/* Place parameters in static storage for common use
-------------------------------------------------*/;
this.sin_p14=Math.sin(this.lat0);
this.cos_p14=Math.cos(this.lat0);
},
/* Orthographic forward equations--mapping lat,long to x,y
---------------------------------------------------*/
forward: function(p) {
var sinphi, cosphi; /* sin and cos value */
var dlon; /* delta longitude value */
var coslon; /* cos of longitude */
var ksp; /* scale factor */
var g;
var lon=p.x;
var lat=p.y;
/* Forward equations
-----------------*/
dlon = Proj4js.common.adjust_lon(lon - this.long0);
sinphi=Math.sin(lat);
cosphi=Math.cos(lat);
coslon = Math.cos(dlon);
g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;
ksp = 1.0;
if ((g > 0) || (Math.abs(g) <= Proj4js.common.EPSLN)) {
var x = this.a * ksp * cosphi * Math.sin(dlon);
var y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
} else {
Proj4js.reportError("orthoFwdPointError");
}
p.x=x;
p.y=y;
return p;
},
inverse: function(p) {
var rh; /* height above ellipsoid */
var z; /* angle */
var sinz,cosz; /* sin of z and cos of z */
var temp;
var con;
var lon , lat;
/* Inverse equations
-----------------*/
p.x -= this.x0;
p.y -= this.y0;
rh = Math.sqrt(p.x * p.x + p.y * p.y);
if (rh > this.a + .0000001) {
Proj4js.reportError("orthoInvDataError");
}
z = Proj4js.common.asinz(rh / this.a);
sinz=Math.sin(z);
cosz=Math.cos(z);
lon = this.long0;
if (Math.abs(rh) <= Proj4js.common.EPSLN) {
lat = this.lat0;
}
lat = Proj4js.common.asinz(cosz * this.sin_p14 + (p.y * sinz * this.cos_p14)/rh);
con = Math.abs(this.lat0) - Proj4js.common.HALF_PI;
if (Math.abs(con) <= Proj4js.common.EPSLN) {
if (this.lat0 >= 0) {
lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x, -p.y));
} else {
lon = Proj4js.common.adjust_lon(this.long0 -Math.atan2(-p.x, p.y));
}
}
con = cosz - this.sin_p14 * Math.sin(lat);
p.x=lon;
p.y=lat;
return p;
}
};
+157
View File
@@ -0,0 +1,157 @@
/* Function to compute, phi4, the latitude for the inverse of the
Polyconic projection.
------------------------------------------------------------*/
function phi4z (eccent,e0,e1,e2,e3,a,b,c,phi) {
var sinphi, sin2ph, tanphi, ml, mlp, con1, con2, con3, dphi, i;
phi = a;
for (i = 1; i <= 15; i++) {
sinphi = Math.sin(phi);
tanphi = Math.tan(phi);
c = tanphi * Math.sqrt (1.0 - eccent * sinphi * sinphi);
sin2ph = Math.sin (2.0 * phi);
/*
ml = e0 * *phi - e1 * sin2ph + e2 * sin (4.0 * *phi);
mlp = e0 - 2.0 * e1 * cos (2.0 * *phi) + 4.0 * e2 * cos (4.0 * *phi);
*/
ml = e0 * phi - e1 * sin2ph + e2 * Math.sin (4.0 * phi) - e3 * Math.sin (6.0 * phi);
mlp = e0 - 2.0 * e1 * Math.cos (2.0 * phi) + 4.0 * e2 * Math.cos (4.0 * phi) - 6.0 * e3 * Math.cos (6.0 * phi);
con1 = 2.0 * ml + c * (ml * ml + b) - 2.0 * a * (c * ml + 1.0);
con2 = eccent * sin2ph * (ml * ml + b - 2.0 * a * ml) / (2.0 *c);
con3 = 2.0 * (a - ml) * (c * mlp - 2.0 / sin2ph) - 2.0 * mlp;
dphi = con1 / (con2 + con3);
phi += dphi;
if (Math.abs(dphi) <= .0000000001 ) return(phi);
}
Proj4js.reportError("phi4z: No convergence");
return null;
}
/* Function to compute the constant e4 from the input of the eccentricity
of the spheroid, x. This constant is used in the Polar Stereographic
projection.
--------------------------------------------------------------------*/
function e4fn(x) {
var con, com;
con = 1.0 + x;
com = 1.0 - x;
return (Math.sqrt((Math.pow(con,con))*(Math.pow(com,com))));
}
/*******************************************************************************
NAME POLYCONIC
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Polyconic projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
T. Mittan Mar, 1993
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
Proj4js.Proj.poly = {
/* Initialize the POLYCONIC projection
----------------------------------*/
init: function() {
var temp; /* temporary variable */
if (this.lat0 == 0) this.lat0 = 90;//this.lat0 ca
/* Place parameters in static storage for common use
-------------------------------------------------*/
this.temp = this.b / this.a;
this.es = 1.0 - Math.pow(this.temp,2);// devait etre dans tmerc.js mais n y est pas donc je commente sinon retour de valeurs nulles
this.e = Math.sqrt(this.es);
this.e0 = Proj4js.common.e0fn(this.es);
this.e1 = Proj4js.common.e1fn(this.es);
this.e2 = Proj4js.common.e2fn(this.es);
this.e3 = Proj4js.common.e3fn(this.es);
this.ml0 = Proj4js.common.mlfn(this.e0, this.e1,this.e2, this.e3, this.lat0);//si que des zeros le calcul ne se fait pas
//if (!this.ml0) {this.ml0=0;}
},
/* Polyconic forward equations--mapping lat,long to x,y
---------------------------------------------------*/
forward: function(p) {
var sinphi, cosphi; /* sin and cos value */
var al; /* temporary values */
var c; /* temporary values */
var con, ml; /* cone constant, small m */
var ms; /* small m */
var x,y;
var lon=p.x;
var lat=p.y;
con = Proj4js.common.adjust_lon(lon - this.long0);
if (Math.abs(lat) <= .0000001) {
x = this.x0 + this.a * con;
y = this.y0 - this.a * this.ml0;
} else {
sinphi = Math.sin(lat);
cosphi = Math.cos(lat);
ml = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat);
ms = Proj4js.common.msfnz(this.e,sinphi,cosphi);
con = sinphi;
x = this.x0 + this.a * ms * Math.sin(con)/sinphi;
y = this.y0 + this.a * (ml - this.ml0 + ms * (1.0 - Math.cos(con))/sinphi);
}
p.x=x;
p.y=y;
return p;
},
/* Inverse equations
-----------------*/
inverse: function(p) {
var sin_phi, cos_phi; /* sin and cos value */
var al; /* temporary values */
var b; /* temporary values */
var c; /* temporary values */
var con, ml; /* cone constant, small m */
var iflg; /* error flag */
var lon,lat;
p.x -= this.x0;
p.y -= this.y0;
al = this.ml0 + p.y/this.a;
iflg = 0;
if (Math.abs(al) <= .0000001) {
lon = p.x/this.a + this.long0;
lat = 0.0;
} else {
b = al * al + (p.x/this.a) * (p.x/this.a);
iflg = phi4z(this.es,this.e0,this.e1,this.e2,this.e3,this.al,b,c,lat);
if (iflg != 1) return(iflg);
lon = Proj4js.common.adjust_lon((Proj4js.common.asinz(p.x * c / this.a) / Math.sin(lat)) + this.long0);
}
p.x=lon;
p.y=lat;
return p;
}
};
+121
View File
@@ -0,0 +1,121 @@
/*******************************************************************************
NAME SINUSOIDAL
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Sinusoidal projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
PROGRAMMER DATE
---------- ----
D. Steinwand, EROS May, 1991
This function was adapted from the Sinusoidal projection code (FORTRAN) in the
General Cartographic Transformation Package software which is available from
the U.S. Geological Survey National Mapping Division.
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. "Software Documentation for GCTP General Cartographic Transformation
Package", U.S. Geological Survey National Mapping Division, May 1982.
*******************************************************************************/
Proj4js.Proj.sinu = {
/* Initialize the Sinusoidal projection
------------------------------------*/
init: function() {
/* Place parameters in static storage for common use
-------------------------------------------------*/
if (!this.sphere) {
this.en = Proj4js.common.pj_enfn(this.es);
} else {
this.n = 1.;
this.m = 0.;
this.es = 0;
this.C_y = Math.sqrt((this.m + 1.) / this.n);
this.C_x = this.C_y/(this.m + 1.);
}
},
/* Sinusoidal forward equations--mapping lat,long to x,y
-----------------------------------------------------*/
forward: function(p) {
var x,y,delta_lon;
var lon=p.x;
var lat=p.y;
/* Forward equations
-----------------*/
lon = Proj4js.common.adjust_lon(lon - this.long0);
if (this.sphere) {
if (!this.m) {
lat = this.n != 1. ? Math.asin(this.n * Math.sin(lat)): lat;
} else {
var k = this.n * Math.sin(lat);
for (var i = Proj4js.common.MAX_ITER; i ; --i) {
var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat));
lat -= V;
if (Math.abs(V) < Proj4js.common.EPSLN) break;
}
}
x = this.a * this.C_x * lon * (this.m + Math.cos(lat));
y = this.a * this.C_y * lat;
} else {
var s = Math.sin(lat);
var c = Math.cos(lat);
y = this.a * Proj4js.common.pj_mlfn(lat, s, c, this.en);
x = this.a * lon * c / Math.sqrt(1. - this.es * s * s);
}
p.x=x;
p.y=y;
return p;
},
inverse: function(p) {
var lat,temp,lon;
/* Inverse equations
-----------------*/
p.x -= this.x0;
p.y -= this.y0;
lat = p.y / this.a;
if (this.sphere) {
p.y /= this.C_y;
lat = this.m ? Math.asin((this.m * p.y + Math.sin(p.y)) / this.n) :
( this.n != 1. ? Math.asin(Math.sin(p.y) / this.n) : p.y );
lon = p.x / (this.C_x * (this.m + Math.cos(p.y)));
} else {
lat = Proj4js.common.pj_inv_mlfn(p.y/this.a, this.es, this.en)
var s = Math.abs(lat);
if (s < Proj4js.common.HALF_PI) {
s = Math.sin(lat);
temp = this.long0 + p.x * Math.sqrt(1. - this.es * s * s) /(this.a * Math.cos(lat));
//temp = this.long0 + p.x / (this.a * Math.cos(lat));
lon = Proj4js.common.adjust_lon(temp);
} else if ((s - Proj4js.common.EPSLN) < Proj4js.common.HALF_PI) {
lon = this.long0;
}
}
p.x=lon;
p.y=lat;
return p;
}
};
+110
View File
@@ -0,0 +1,110 @@
/*******************************************************************************
NAME SWISS OBLIQUE MERCATOR
PURPOSE: Swiss projection.
WARNING: X and Y are inverted (weird) in the swiss coordinate system. Not
here, since we want X to be horizontal and Y vertical.
ALGORITHM REFERENCES
1. "Formules et constantes pour le Calcul pour la
projection cylindrique conforme à axe oblique et pour la transformation entre
des systèmes de référence".
http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf
*******************************************************************************/
Proj4js.Proj.somerc = {
init: function() {
var phy0 = this.lat0;
this.lambda0 = this.long0;
var sinPhy0 = Math.sin(phy0);
var semiMajorAxis = this.a;
var invF = this.rf;
var flattening = 1 / invF;
var e2 = 2 * flattening - Math.pow(flattening, 2);
var e = this.e = Math.sqrt(e2);
this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2.0));
this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4.0));
this.b0 = Math.asin(sinPhy0 / this.alpha);
this.K = Math.log(Math.tan(Math.PI / 4.0 + this.b0 / 2.0))
- this.alpha
* Math.log(Math.tan(Math.PI / 4.0 + phy0 / 2.0))
+ this.alpha
* e / 2
* Math.log((1 + e * sinPhy0)
/ (1 - e * sinPhy0));
},
forward: function(p) {
var Sa1 = Math.log(Math.tan(Math.PI / 4.0 - p.y / 2.0));
var Sa2 = this.e / 2.0
* Math.log((1 + this.e * Math.sin(p.y))
/ (1 - this.e * Math.sin(p.y)));
var S = -this.alpha * (Sa1 + Sa2) + this.K;
// spheric latitude
var b = 2.0 * (Math.atan(Math.exp(S)) - Math.PI / 4.0);
// spheric longitude
var I = this.alpha * (p.x - this.lambda0);
// psoeudo equatorial rotation
var rotI = Math.atan(Math.sin(I)
/ (Math.sin(this.b0) * Math.tan(b) +
Math.cos(this.b0) * Math.cos(I)));
var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) -
Math.sin(this.b0) * Math.cos(b) * Math.cos(I));
p.y = this.R / 2.0
* Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB)))
+ this.y0;
p.x = this.R * rotI + this.x0;
return p;
},
inverse: function(p) {
var Y = p.x - this.x0;
var X = p.y - this.y0;
var rotI = Y / this.R;
var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4.0);
var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB)
+ Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI));
var I = Math.atan(Math.sin(rotI)
/ (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0)
* Math.tan(rotB)));
var lambda = this.lambda0 + I / this.alpha;
var S = 0.0;
var phy = b;
var prevPhy = -1000.0;
var iteration = 0;
while (Math.abs(phy - prevPhy) > 0.0000001)
{
if (++iteration > 20)
{
Proj4js.reportError("omercFwdInfinity");
return;
}
//S = Math.log(Math.tan(Math.PI / 4.0 + phy / 2.0));
S = 1.0
/ this.alpha
* (Math.log(Math.tan(Math.PI / 4.0 + b / 2.0)) - this.K)
+ this.e
* Math.log(Math.tan(Math.PI / 4.0
+ Math.asin(this.e * Math.sin(phy))
/ 2.0));
prevPhy = phy;
phy = 2.0 * Math.atan(Math.exp(S)) - Math.PI / 2.0;
}
p.x = lambda;
p.y = phy;
return p;
}
};
+247
View File
@@ -0,0 +1,247 @@
// Initialize the Stereographic projection
Proj4js.Proj.stere = {
ssfn_: function(phit, sinphi, eccen) {
sinphi *= eccen;
return (Math.tan (.5 * (Proj4js.common.HALF_PI + phit)) * Math.pow((1. - sinphi) / (1. + sinphi), .5 * eccen));
},
TOL: 1.e-8,
NITER: 8,
CONV: 1.e-10,
S_POLE: 0,
N_POLE: 1,
OBLIQ: 2,
EQUIT: 3,
init: function() {
this.phits = this.lat_ts ? this.lat_ts : Proj4js.common.HALF_PI;
var t = Math.abs(this.lat0);
if ((Math.abs(t) - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) {
this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE;
} else {
this.mode = t > Proj4js.common.EPSLN ? this.OBLIQ : this.EQUIT;
}
this.phits = Math.abs(this.phits);
if (this.es) {
var X;
switch (this.mode) {
case this.N_POLE:
case this.S_POLE:
if (Math.abs(this.phits - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) {
this.akm1 = 2. * this.k0 / Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e));
} else {
t = Math.sin(this.phits);
this.akm1 = Math.cos(this.phits) / Proj4js.common.tsfnz(this.e, this.phits, t);
t *= this.e;
this.akm1 /= Math.sqrt(1. - t * t);
}
break;
case this.EQUIT:
this.akm1 = 2. * this.k0;
break;
case this.OBLIQ:
t = Math.sin(this.lat0);
X = 2. * Math.atan(this.ssfn_(this.lat0, t, this.e)) - Proj4js.common.HALF_PI;
t *= this.e;
this.akm1 = 2. * this.k0 * Math.cos(this.lat0) / Math.sqrt(1. - t * t);
this.sinX1 = Math.sin(X);
this.cosX1 = Math.cos(X);
break;
}
} else {
switch (this.mode) {
case this.OBLIQ:
this.sinph0 = Math.sin(this.lat0);
this.cosph0 = Math.cos(this.lat0);
case this.EQUIT:
this.akm1 = 2. * this.k0;
break;
case this.S_POLE:
case this.N_POLE:
this.akm1 = Math.abs(this.phits - Proj4js.common.HALF_PI) >= Proj4js.common.EPSLN ?
Math.cos(this.phits) / Math.tan(Proj4js.common.FORTPI - .5 * this.phits) :
2. * this.k0 ;
break;
}
}
},
// Stereographic forward equations--mapping lat,long to x,y
forward: function(p) {
var lon = p.x;
lon = Proj4js.common.adjust_lon(lon - this.long0);
var lat = p.y;
var x, y;
if (this.sphere) {
var sinphi, cosphi, coslam, sinlam;
sinphi = Math.sin(lat);
cosphi = Math.cos(lat);
coslam = Math.cos(lon);
sinlam = Math.sin(lon);
switch (this.mode) {
case this.EQUIT:
y = 1. + cosphi * coslam;
if (y <= Proj4js.common.EPSLN) {
Proj4js.reportError("stere:forward:Equit");
}
y = this.akm1 / y;
x = y * cosphi * sinlam;
y *= sinphi;
break;
case this.OBLIQ:
y = 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;
if (y <= Proj4js.common.EPSLN) {
Proj4js.reportError("stere:forward:Obliq");
}
y = this.akm1 / y;
x = y * cosphi * sinlam;
y *= this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;
break;
case this.N_POLE:
coslam = -coslam;
lat = -lat;
//Note no break here so it conitnues through S_POLE
case this.S_POLE:
if (Math.abs(lat - Proj4js.common.HALF_PI) < this.TOL) {
Proj4js.reportError("stere:forward:S_POLE");
}
y = this.akm1 * Math.tan(Proj4js.common.FORTPI + .5 * lat);
x = sinlam * y;
y *= coslam;
break;
}
} else {
coslam = Math.cos(lon);
sinlam = Math.sin(lon);
sinphi = Math.sin(lat);
var sinX, cosX;
if (this.mode == this.OBLIQ || this.mode == this.EQUIT) {
var Xt = 2. * Math.atan(this.ssfn_(lat, sinphi, this.e));
sinX = Math.sin(Xt - Proj4js.common.HALF_PI);
cosX = Math.cos(Xt);
}
switch (this.mode) {
case this.OBLIQ:
var A = this.akm1 / (this.cosX1 * (1. + this.sinX1 * sinX + this.cosX1 * cosX * coslam));
y = A * (this.cosX1 * sinX - this.sinX1 * cosX * coslam);
x = A * cosX;
break;
case this.EQUIT:
var A = 2. * this.akm1 / (1. + cosX * coslam);
y = A * sinX;
x = A * cosX;
break;
case this.S_POLE:
lat = -lat;
coslam = - coslam;
sinphi = -sinphi;
case this.N_POLE:
x = this.akm1 * Proj4js.common.tsfnz(this.e, lat, sinphi);
y = - x * coslam;
break;
}
x = x * sinlam;
}
p.x = x*this.a + this.x0;
p.y = y*this.a + this.y0;
return p;
},
//* Stereographic inverse equations--mapping x,y to lat/long
inverse: function(p) {
var x = (p.x - this.x0)/this.a; /* descale and de-offset */
var y = (p.y - this.y0)/this.a;
var lon, lat;
var cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, pi2=0.0;
var i;
if (this.sphere) {
var c, rh, sinc, cosc;
rh = Math.sqrt(x*x + y*y);
c = 2. * Math.atan(rh / this.akm1);
sinc = Math.sin(c);
cosc = Math.cos(c);
lon = 0.;
switch (this.mode) {
case this.EQUIT:
if (Math.abs(rh) <= Proj4js.common.EPSLN) {
lat = 0.;
} else {
lat = Math.asin(y * sinc / rh);
}
if (cosc != 0. || x != 0.) lon = Math.atan2(x * sinc, cosc * rh);
break;
case this.OBLIQ:
if (Math.abs(rh) <= Proj4js.common.EPSLN) {
lat = this.phi0;
} else {
lat = Math.asin(cosc * this.sinph0 + y * sinc * this.cosph0 / rh);
}
c = cosc - this.sinph0 * Math.sin(lat);
if (c != 0. || x != 0.) {
lon = Math.atan2(x * sinc * this.cosph0, c * rh);
}
break;
case this.N_POLE:
y = -y;
case this.S_POLE:
if (Math.abs(rh) <= Proj4js.common.EPSLN) {
lat = this.phi0;
} else {
lat = Math.asin(this.mode == this.S_POLE ? -cosc : cosc);
}
lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y);
break;
}
p.x = Proj4js.common.adjust_lon(lon + this.long0);
p.y = lat;
} else {
rho = Math.sqrt(x*x + y*y);
switch (this.mode) {
case this.OBLIQ:
case this.EQUIT:
tp = 2. * Math.atan2(rho * this.cosX1 , this.akm1);
cosphi = Math.cos(tp);
sinphi = Math.sin(tp);
if( rho == 0.0 ) {
phi_l = Math.asin(cosphi * this.sinX1);
} else {
phi_l = Math.asin(cosphi * this.sinX1 + (y * sinphi * this.cosX1 / rho));
}
tp = Math.tan(.5 * (Proj4js.common.HALF_PI + phi_l));
x *= sinphi;
y = rho * this.cosX1 * cosphi - y * this.sinX1* sinphi;
pi2 = Proj4js.common.HALF_PI;
halfe = .5 * this.e;
break;
case this.N_POLE:
y = -y;
case this.S_POLE:
tp = - rho / this.akm1;
phi_l = Proj4js.common.HALF_PI - 2. * Math.atan(tp);
pi2 = -Proj4js.common.HALF_PI;
halfe = -.5 * this.e;
break;
}
for (i = this.NITER; i--; phi_l = lat) { //check this
sinphi = this.e * Math.sin(phi_l);
lat = 2. * Math.atan(tp * Math.pow((1.+sinphi)/(1.-sinphi), halfe)) - pi2;
if (Math.abs(phi_l - lat) < this.CONV) {
if (this.mode == this.S_POLE) lat = -lat;
lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y);
p.x = Proj4js.common.adjust_lon(lon + this.long0);
p.y = lat;
return p;
}
}
}
}
};
+57
View File
@@ -0,0 +1,57 @@
Proj4js.Proj.sterea = {
dependsOn : 'gauss',
init : function() {
Proj4js.Proj['gauss'].init.apply(this);
if (!this.rc) {
Proj4js.reportError("sterea:init:E_ERROR_0");
return;
}
this.sinc0 = Math.sin(this.phic0);
this.cosc0 = Math.cos(this.phic0);
this.R2 = 2.0 * this.rc;
if (!this.title) this.title = "Oblique Stereographic Alternative";
},
forward : function(p) {
var sinc, cosc, cosl, k;
p.x = Proj4js.common.adjust_lon(p.x-this.long0); /* adjust del longitude */
Proj4js.Proj['gauss'].forward.apply(this, [p]);
sinc = Math.sin(p.y);
cosc = Math.cos(p.y);
cosl = Math.cos(p.x);
k = this.k0 * this.R2 / (1.0 + this.sinc0 * sinc + this.cosc0 * cosc * cosl);
p.x = k * cosc * Math.sin(p.x);
p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl);
p.x = this.a * p.x + this.x0;
p.y = this.a * p.y + this.y0;
return p;
},
inverse : function(p) {
var sinc, cosc, lon, lat, rho;
p.x = (p.x - this.x0) / this.a; /* descale and de-offset */
p.y = (p.y - this.y0) / this.a;
p.x /= this.k0;
p.y /= this.k0;
if ( (rho = Math.sqrt(p.x*p.x + p.y*p.y)) ) {
var c = 2.0 * Math.atan2(rho, this.R2);
sinc = Math.sin(c);
cosc = Math.cos(c);
lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho);
lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc);
} else {
lat = this.phic0;
lon = 0.;
}
p.x = lon;
p.y = lat;
Proj4js.Proj['gauss'].inverse.apply(this,[p]);
p.x = Proj4js.common.adjust_lon(p.x + this.long0); /* adjust longitude to CM */
return p;
}
};
+141
View File
@@ -0,0 +1,141 @@
/*******************************************************************************
NAME TRANSVERSE MERCATOR
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Transverse Mercator projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
/**
Initialize Transverse Mercator projection
*/
Proj4js.Proj.tmerc = {
init : function() {
this.e0 = Proj4js.common.e0fn(this.es);
this.e1 = Proj4js.common.e1fn(this.es);
this.e2 = Proj4js.common.e2fn(this.es);
this.e3 = Proj4js.common.e3fn(this.es);
this.ml0 = this.a * Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
},
/**
Transverse Mercator Forward - long/lat to x/y
long/lat in radians
*/
forward : function(p) {
var lon = p.x;
var lat = p.y;
var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); // Delta longitude
var con; // cone constant
var x, y;
var sin_phi=Math.sin(lat);
var cos_phi=Math.cos(lat);
if (this.sphere) { /* spherical form */
var b = cos_phi * Math.sin(delta_lon);
if ((Math.abs(Math.abs(b) - 1.0)) < .0000000001) {
Proj4js.reportError("tmerc:forward: Point projects into infinity");
return(93);
} else {
x = .5 * this.a * this.k0 * Math.log((1.0 + b)/(1.0 - b));
con = Math.acos(cos_phi * Math.cos(delta_lon)/Math.sqrt(1.0 - b*b));
if (lat < 0) con = - con;
y = this.a * this.k0 * (con - this.lat0);
}
} else {
var al = cos_phi * delta_lon;
var als = Math.pow(al,2);
var c = this.ep2 * Math.pow(cos_phi,2);
var tq = Math.tan(lat);
var t = Math.pow(tq,2);
con = 1.0 - this.es * Math.pow(sin_phi,2);
var n = this.a / Math.sqrt(con);
var ml = this.a * Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat);
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;
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;
}
p.x = x; p.y = y;
return p;
}, // tmercFwd()
/**
Transverse Mercator Inverse - x/y to long/lat
*/
inverse : function(p) {
var con, phi; /* temporary angles */
var delta_phi; /* difference between longitudes */
var i;
var max_iter = 6; /* maximun number of iterations */
var lat, lon;
if (this.sphere) { /* spherical form */
var f = Math.exp(p.x/(this.a * this.k0));
var g = .5 * (f - 1/f);
var temp = this.lat0 + p.y/(this.a * this.k0);
var h = Math.cos(temp);
con = Math.sqrt((1.0 - h * h)/(1.0 + g * g));
lat = Proj4js.common.asinz(con);
if (temp < 0)
lat = -lat;
if ((g == 0) && (h == 0)) {
lon = this.long0;
} else {
lon = Proj4js.common.adjust_lon(Math.atan2(g,h) + this.long0);
}
} else { // ellipsoidal form
var x = p.x - this.x0;
var y = p.y - this.y0;
con = (this.ml0 + y / this.k0) / this.a;
phi = con;
for (i=0;true;i++) {
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;
phi += delta_phi;
if (Math.abs(delta_phi) <= Proj4js.common.EPSLN) break;
if (i >= max_iter) {
Proj4js.reportError("tmerc:inverse: Latitude failed to converge");
return(95);
}
} // for()
if (Math.abs(phi) < Proj4js.common.HALF_PI) {
// sincos(phi, &sin_phi, &cos_phi);
var sin_phi=Math.sin(phi);
var cos_phi=Math.cos(phi);
var tan_phi = Math.tan(phi);
var c = this.ep2 * Math.pow(cos_phi,2);
var cs = Math.pow(c,2);
var t = Math.pow(tan_phi,2);
var ts = Math.pow(t,2);
con = 1.0 - this.es * Math.pow(sin_phi,2);
var n = this.a / Math.sqrt(con);
var r = n * (1.0 - this.es) / con;
var d = x / (n * this.k0);
var ds = Math.pow(d,2);
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)));
lon = Proj4js.common.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));
} else {
lat = Proj4js.common.HALF_PI * Proj4js.common.sign(y);
lon = this.long0;
}
}
p.x = lon;
p.y = lat;
return p;
} // tmercInv()
};
+43
View File
@@ -0,0 +1,43 @@
/*******************************************************************************
NAME TRANSVERSE MERCATOR
PURPOSE: Transforms input longitude and latitude to Easting and
Northing for the Transverse Mercator projection. The
longitude and latitude must be in radians. The Easting
and Northing values will be returned in meters.
ALGORITHM REFERENCES
1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
U.S. Geological Survey Professional Paper 1453 , United State Government
Printing Office, Washington D.C., 1989.
*******************************************************************************/
/**
Initialize Transverse Mercator projection
*/
Proj4js.Proj.utm = {
dependsOn : 'tmerc',
init : function() {
if (!this.zone) {
Proj4js.reportError("utm:init: zone must be specified for UTM");
return;
}
this.lat0 = 0.0;
this.long0 = ((6 * Math.abs(this.zone)) - 183) * Proj4js.common.D2R;
this.x0 = 500000.0;
this.y0 = this.utmSouth ? 10000000.0 : 0.0;
this.k0 = 0.9996;
Proj4js.Proj['tmerc'].init.apply(this);
this.forward = Proj4js.Proj['tmerc'].forward;
this.inverse = Proj4js.Proj['tmerc'].inverse;
}
};
+137
View File
@@ -0,0 +1,137 @@
/*******************************************************************************
NAME VAN DER GRINTEN
PURPOSE: Transforms input Easting and Northing to longitude and
latitude for the Van der Grinten projection. The
Easting and Northing must be in meters. The longitude
and latitude values will be returned in radians.
PROGRAMMER DATE
---------- ----
T. Mittan March, 1993
This function was adapted from the Van Der Grinten projection code
(FORTRAN) in the General Cartographic Transformation Package software
which is available from the U.S. Geological Survey National Mapping Division.
ALGORITHM REFERENCES
1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
State Government Printing Office, Washington D.C., 1987.
3. "Software Documentation for GCTP General Cartographic Transformation
Package", U.S. Geological Survey National Mapping Division, May 1982.
*******************************************************************************/
Proj4js.Proj.vandg = {
/* Initialize the Van Der Grinten projection
----------------------------------------*/
init: function() {
this.R = 6370997.0; //Radius of earth
},
forward: function(p) {
var lon=p.x;
var lat=p.y;
/* Forward equations
-----------------*/
var dlon = Proj4js.common.adjust_lon(lon - this.long0);
var x,y;
if (Math.abs(lat) <= Proj4js.common.EPSLN) {
x = this.x0 + this.R * dlon;
y = this.y0;
}
var theta = Proj4js.common.asinz(2.0 * Math.abs(lat / Proj4js.common.PI));
if ((Math.abs(dlon) <= Proj4js.common.EPSLN) || (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN)) {
x = this.x0;
if (lat >= 0) {
y = this.y0 + Proj4js.common.PI * this.R * Math.tan(.5 * theta);
} else {
y = this.y0 + Proj4js.common.PI * this.R * - Math.tan(.5 * theta);
}
// return(OK);
}
var al = .5 * Math.abs((Proj4js.common.PI / dlon) - (dlon / Proj4js.common.PI));
var asq = al * al;
var sinth = Math.sin(theta);
var costh = Math.cos(theta);
var g = costh / (sinth + costh - 1.0);
var gsq = g * g;
var m = g * (2.0 / sinth - 1.0);
var msq = m * m;
var con = Proj4js.common.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq);
if (dlon < 0) {
con = -con;
}
x = this.x0 + con;
con = Math.abs(con / (Proj4js.common.PI * this.R));
if (lat >= 0) {
y = this.y0 + Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con);
} else {
y = this.y0 - Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con);
}
p.x = x;
p.y = y;
return p;
},
/* Van Der Grinten inverse equations--mapping x,y to lat/long
---------------------------------------------------------*/
inverse: function(p) {
var lon, lat;
var xx,yy,xys,c1,c2,c3;
var al,asq;
var a1;
var m1;
var con;
var th1;
var d;
/* inverse equations
-----------------*/
p.x -= this.x0;
p.y -= this.y0;
con = Proj4js.common.PI * this.R;
xx = p.x / con;
yy =p.y / con;
xys = xx * xx + yy * yy;
c1 = -Math.abs(yy) * (1.0 + xys);
c2 = c1 - 2.0 * yy * yy + xx * xx;
c3 = -2.0 * c1 + 1.0 + 2.0 * yy * yy + xys * xys;
d = yy * yy / c3 + (2.0 * c2 * c2 * c2 / c3 / c3 / c3 - 9.0 * c1 * c2 / c3 /c3) / 27.0;
a1 = (c1 - c2 * c2 / 3.0 / c3) / c3;
m1 = 2.0 * Math.sqrt( -a1 / 3.0);
con = ((3.0 * d) / a1) / m1;
if (Math.abs(con) > 1.0) {
if (con >= 0.0) {
con = 1.0;
} else {
con = -1.0;
}
}
th1 = Math.acos(con) / 3.0;
if (p.y >= 0) {
lat = (-m1 *Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI;
} else {
lat = -(-m1 * Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI;
}
if (Math.abs(xx) < Proj4js.common.EPSLN) {
lon = this.long0;
}
lon = Proj4js.common.adjust_lon(this.long0 + Proj4js.common.PI * (xys - 1.0 + Math.sqrt(1.0 + 2.0 * (xx * xx - yy * yy) + xys * xys)) / 2.0 / xx);
p.x=lon;
p.y=lat;
return p;
}
};
+950
View File
@@ -0,0 +1,950 @@
/*
Portions of this software are based on a port of components from the OpenMap
com.bbn.openmap.proj.coords Java package. An initial port was initially created
by Patrice G. Cappelaere and included in Community Mapbuilder
(http://svn.codehaus.org/mapbuilder/), which is licensed under the LGPL license
as per http://www.gnu.org/copyleft/lesser.html. OpenMap is licensed under the
following license agreement:
OpenMap Software License Agreement
----------------------------------
This Agreement sets forth the terms and conditions under which
the software known as OpenMap(tm) will be licensed by BBN
Technologies ("BBN") to you ("Licensee"), and by which Derivative
Works (as hereafter defined) of OpenMap will be licensed by you to BBN.
Definitions:
"Derivative Work(s)" shall mean any revision, enhancement,
modification, translation, abridgement, condensation or
expansion created by Licensee or BBN that is based upon the
Software or a portion thereof that would be a copyright
infringement if prepared without the authorization of the
copyright owners of the Software or portion thereof.
"OpenMap" shall mean a programmer's toolkit for building map
based applications as originally created by BBN, and any
Derivative Works thereof as created by either BBN or Licensee,
but shall include only those Derivative Works BBN has approved
for inclusion into, and BBN has integrated into OpenMap.
"Standard Version" shall mean OpenMap, as originally created by
BBN.
"Software" shall mean OpenMap and the Derivative Works created
by Licensee and the collection of files distributed by the
Licensee with OpenMap, and the collection of files created
through textual modifications.
"Copyright Holder" is whoever is named in the copyright or
copyrights for the Derivative Works.
"Licensee" is you, only if you agree to be bound by the terms
and conditions set forth in this Agreement.
"Reasonable copying fee" is whatever you can justify on the
basis of media cost, duplication charges, time of people
involved.
"Freely Available" means that no fee is charged for the item
itself, though there may be fees involved in handling the item.
It also means that recipients of the item may redistribute it
under the same conditions that they received it.
1. BBN maintains all rights, title and interest in and to
OpenMap, including all applicable copyrights, trade secrets,
patents and other intellectual rights therein. Licensee hereby
grants to BBN all right, title and interest into the compilation
of OpenMap. Licensee shall own all rights, title and interest
into the Derivative Works created by Licensee (subject to the
compilation ownership by BBN).
2. BBN hereby grants to Licensee a royalty free, worldwide right
and license to use, copy, distribute and make Derivative Works of
OpenMap, and sublicensing rights of any of the foregoing in
accordance with the terms and conditions of this Agreement,
provided that you duplicate all of the original copyright notices
and associated disclaimers.
3. Licensee hereby grants to BBN a royalty free, worldwide right
and license to use, copy, distribute and make Derivative Works of
Derivative Works created by Licensee and sublicensing rights of
any of the foregoing.
4. Licensee's right to create Derivative Works in the Software is
subject to Licensee agreement to insert a prominent notice in
each changed file stating how and when you changed that file, and
provided that you do at least ONE of the following:
a) place your modifications in the Public Domain or otherwise
make them Freely Available, such as by posting said
modifications to Usenet or an equivalent medium, or
placing the modifications on a major archive site and by
providing your modifications to the Copyright Holder.
b) use the modified Package only within your corporation or
organization.
c) rename any non-standard executables so the names do not
conflict with standard executables, which must also be
provided, and provide a separate manual page for each
non-standard executable that clearly documents how it
differs from OpenMap.
d) make other distribution arrangements with the Copyright
Holder.
5. Licensee may distribute the programs of this Software in
object code or executable form, provided that you do at least ONE
of the following:
a) distribute an OpenMap version of the executables and
library files, together with instructions (in the manual
page or equivalent) on where to get OpenMap.
b) accompany the distribution with the machine-readable
source code with your modifications.
c) accompany any non-standard executables with their
corresponding OpenMap executables, giving the non-standard
executables non-standard names, and clearly documenting
the differences in manual pages (or equivalent), together
with instructions on where to get OpenMap.
d) make other distribution arrangements with the Copyright
Holder.
6. You may charge a reasonable copying fee for any distribution
of this Software. You may charge any fee you choose for support
of this Software. You may not charge a fee for this Software
itself. However, you may distribute this Software in aggregate
with other (possibly commercial) programs as part of a larger
(possibly commercial) software distribution provided that you do
not advertise this Software as a product of your own.
7. The data and images supplied as input to or produced as output
from the Software do not automatically fall under the copyright
of this Software, but belong to whomever generated them, and may
be sold commercially, and may be aggregated with this Software.
8. BBN makes no representation about the suitability of OpenMap
for any purposes. BBN shall have no duty or requirement to
include any Derivative Works into OpenMap.
9. Each party hereto represents and warrants that they have the
full unrestricted right to grant all rights and licenses granted
to the other party herein.
10. THIS PACKAGE IS PROVIDED "AS IS" WITHOUT WARRANTIES OF ANY
KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING (BUT NOT LIMITED TO)
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND
WITHOUT ANY WARRANTIES AS TO NONINFRINGEMENT.
11. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER RESULTING
FROM LOSS OF USE OF DATA OR PROFITS, WHETHER IN AN ACTION OF
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS CONDUCT, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PACKAGE.
12. Without limitation of the foregoing, You agree to commit no
act which, directly or indirectly, would violate any U.S. law,
regulation, or treaty, or any other international treaty or
agreement to which the United States adheres or with which the
United States complies, relating to the export or re-export of
any commodities, software, or technical data.
*/
if (window.Proj4js && !Proj4js.util) { Proj4js.util = {}; }
/**
* Converts between lat/lon and MGRS coordinates. Note that this static class
* is restricted to the WGS84 ellipsoid and does not support MGRS notations
* for polar regions (i.e. above 84° North and below 80° South).
*
* If Proj4js is loaded, this will be referenced as Proj4js.util.MGRS. If used
* standalone, it will be referenced as window.MGRS.
*
* @static
*/
(window.Proj4js ? Proj4js.util : window)["MGRS"] = (function() {
/**
* UTM zones are grouped, and assigned to one of a group of 6
* sets.
*
* {int} @private
*/
var NUM_100K_SETS = 6;
/**
* The column letters (for easting) of the lower left value, per
* set.
*
* {string} @private
*/
var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS';
/**
* The row letters (for northing) of the lower left value, per
* set.
*
* {string} @private
*/
var SET_ORIGIN_ROW_LETTERS = 'AFAFAF';
var A = 65; // A
var I = 73; // I
var O = 79; // O
var V = 86; // V
var Z = 90; // Z
/**
* Conversion of lat/lon to MGRS.
*
* @param {object} ll Object literal with lat and lon properties on a
* WGS84 ellipsoid.
* @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for
* 100 m, 4 for 1000 m or 5 for 10000 m). Optional, default is 5.
* @return {string} the MGRS string for the given location and accuracy.
*/
function forward(ll, accuracy) {
accuracy = accuracy || 5; // default accuracy 1m
return encode(LLtoUTM({lat: ll.lat, lon: ll.lon}), accuracy);
}
/**
* Conversion of MGRS to lat/lon.
*
* @param {string} mgrs MGRS string.
* @return {array} An array with left (longitude), bottom (latitude), right
* (longitude) and top (latitude) values in WGS84, representing the
* bounding box for the provided MGRS reference.
*/
function inverse(mgrs) {
var bbox = UTMtoLL(decode(mgrs.toUpperCase()));
return [bbox.left, bbox.bottom, bbox.right, bbox.top];
}
/**
* Conversion from degrees to radians.
*
* @private
* @param {number} deg the angle in degrees.
* @return {number} the angle in radians.
*/
function degToRad(deg) {
return (deg * (Math.PI / 180.0));
}
/**
* Conversion from radians to degrees.
*
* @private
* @param {number} rad the angle in radians.
* @return {number} the angle in degrees.
*/
function radToDeg(rad) {
return (180.0 * (rad / Math.PI));
}
/**
* Converts a set of Longitude and Latitude co-ordinates to UTM
* using the WGS84 ellipsoid.
*
* @private
* @param {object} ll Object literal with lat and lon properties
* representing the WGS84 coordinate to be converted.
* @return {object} Object literal containing the UTM value with easting,
* northing, zoneNumber and zoneLetter properties, and an optional
* accuracy property in digits. Returns null if the conversion failed.
*/
function LLtoUTM(ll) {
var Lat = ll.lat;
var Long = ll.lon;
var a = 6378137.0; //ellip.radius;
var eccSquared = 0.00669438; //ellip.eccsq;
var k0 = 0.9996;
var LongOrigin;
var eccPrimeSquared;
var N, T, C, A, M;
var LatRad = degToRad(Lat);
var LongRad = degToRad(Long);
var LongOriginRad;
var ZoneNumber;
// (int)
ZoneNumber = Math.floor((Long + 180) / 6) + 1;
//Make sure the longitude 180.00 is in Zone 60
if (Long == 180) {
ZoneNumber = 60;
}
// Special zone for Norway
if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) {
ZoneNumber = 32;
}
// Special zones for Svalbard
if (Lat >= 72.0 && Lat < 84.0) {
if (Long >= 0.0 && Long < 9.0)
ZoneNumber = 31;
else if (Long >= 9.0 && Long < 21.0)
ZoneNumber = 33;
else if (Long >= 21.0 && Long < 33.0)
ZoneNumber = 35;
else if (Long >= 33.0 && Long < 42.0)
ZoneNumber = 37;
}
LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin
// in middle of
// zone
LongOriginRad = degToRad(LongOrigin);
eccPrimeSquared = (eccSquared) / (1 - eccSquared);
N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad));
T = Math.tan(LatRad) * Math.tan(LatRad);
C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad);
A = Math.cos(LatRad) * (LongRad - LongOriginRad);
M = a
* ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5
* eccSquared * eccSquared * eccSquared / 256)
* LatRad
- (3 * eccSquared / 8 + 3 * eccSquared * eccSquared
/ 32 + 45 * eccSquared * eccSquared
* eccSquared / 1024)
* Math.sin(2 * LatRad)
+ (15 * eccSquared * eccSquared / 256 + 45 * eccSquared
* eccSquared * eccSquared / 1024)
* Math.sin(4 * LatRad) - (35 * eccSquared * eccSquared
* eccSquared / 3072)
* Math.sin(6 * LatRad));
var UTMEasting = (k0
* N
* (A + (1 - T + C) * A * A * A / 6.0 + (5 - 18 * T + T * T
+ 72 * C - 58 * eccPrimeSquared)
* A * A * A * A * A / 120.0) + 500000.0);
var UTMNorthing = (k0 * (M + N
* Math.tan(LatRad)
* (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A
/ 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared)
* A * A * A * A * A * A / 720.0)));
if (Lat < 0.0) {
UTMNorthing += 10000000.0; //10000000 meter offset for
// southern hemisphere
}
return {
northing: Math.round(UTMNorthing),
easting: Math.round(UTMEasting),
zoneNumber: ZoneNumber,
zoneLetter: getLetterDesignator(Lat)
};
}
/**
* Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience
* class where the Zone can be specified as a single string eg."60N" which
* is then broken down into the ZoneNumber and ZoneLetter.
*
* @private
* @param {object} utm An object literal with northing, easting, zoneNumber
* and zoneLetter properties. If an optional accuracy property is
* provided (in meters), a bounding box will be returned instead of
* latitude and longitude.
* @return {object} An object literal containing either lat and lon values
* (if no accuracy was provided), or top, right, bottom and left values
* for the bounding box calculated according to the provided accuracy.
* Returns null if the conversion failed.
*/
function UTMtoLL(utm) {
var UTMNorthing = utm.northing;
var UTMEasting = utm.easting;
var zoneLetter = utm.zoneLetter;
var zoneNumber = utm.zoneNumber;
// check the ZoneNummber is valid
if (zoneNumber < 0 || zoneNumber > 60) {
return null;
}
var k0 = 0.9996;
var a = 6378137.0; //ellip.radius;
var eccSquared = 0.00669438; //ellip.eccsq;
var eccPrimeSquared;
var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared));
var N1, T1, C1, R1, D, M;
var LongOrigin;
var mu, phi1Rad;
// remove 500,000 meter offset for longitude
var x = UTMEasting - 500000.0;
var y = UTMNorthing;
// We must know somehow if we are in the Northern or Southern
// hemisphere, this is the only time we use the letter So even
// if the Zone letter isn't exactly correct it should indicate
// the hemisphere correctly
if (zoneLetter == 'S') {
y -= 10000000.0;// remove 10,000,000 meter offset used
// for southern hemisphere
}
// There are 60 zones with zone 1 being at West -180 to -174
LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin
// in middle of
// zone
eccPrimeSquared = (eccSquared) / (1 - eccSquared);
M = y / k0;
mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256));
phi1Rad =
mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32)
* Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu);
// double phi1 = ProjMath.radToDeg(phi1Rad);
N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad));
T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad);
C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad);
R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5);
D = x / (N1 * k0);
var lat =
phi1Rad
- (N1 * Math.tan(phi1Rad) / R1)
* (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90
* T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1)
* D * D * D * D * D * D / 720);
lat = radToDeg(lat);
var lon =
(D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1)
* D * D * D * D * D / 120) / Math.cos(phi1Rad);
lon = LongOrigin + radToDeg(lon);
var result;
if (utm.accuracy) {
var topRight = UTMtoLL({
northing: utm.northing + utm.accuracy,
easting: utm.easting + utm.accuracy,
zoneLetter: utm.zoneLetter,
zoneNumber: utm.zoneNumber
});
result = {
top: topRight.lat,
right: topRight.lon,
bottom: lat,
left: lon
};
} else {
result = {
lat: lat,
lon: lon
};
}
return result;
}
/**
* Calculates the MGRS letter designator for the given latitude.
*
* @private
* @param {number} lat The latitude in WGS84 to get the letter designator
* for.
* @return {char} The letter designator.
*/
function getLetterDesignator(lat) {
//This is here as an error flag to show that the Latitude is
//outside MGRS limits
var LetterDesignator = 'Z';
if ((84 >= lat) && (lat >= 72))
LetterDesignator = 'X';
else if ((72 > lat) && (lat >= 64))
LetterDesignator = 'W';
else if ((64 > lat) && (lat >= 56))
LetterDesignator = 'V';
else if ((56 > lat) && (lat >= 48))
LetterDesignator = 'U';
else if ((48 > lat) && (lat >= 40))
LetterDesignator = 'T';
else if ((40 > lat) && (lat >= 32))
LetterDesignator = 'S';
else if ((32 > lat) && (lat >= 24))
LetterDesignator = 'R';
else if ((24 > lat) && (lat >= 16))
LetterDesignator = 'Q';
else if ((16 > lat) && (lat >= 8))
LetterDesignator = 'P';
else if ((8 > lat) && (lat >= 0))
LetterDesignator = 'N';
else if ((0 > lat) && (lat >= -8))
LetterDesignator = 'M';
else if ((-8 > lat) && (lat >= -16))
LetterDesignator = 'L';
else if ((-16 > lat) && (lat >= -24))
LetterDesignator = 'K';
else if ((-24 > lat) && (lat >= -32))
LetterDesignator = 'J';
else if ((-32 > lat) && (lat >= -40))
LetterDesignator = 'H';
else if ((-40 > lat) && (lat >= -48))
LetterDesignator = 'G';
else if ((-48 > lat) && (lat >= -56))
LetterDesignator = 'F';
else if ((-56 > lat) && (lat >= -64))
LetterDesignator = 'E';
else if ((-64 > lat) && (lat >= -72))
LetterDesignator = 'D';
else if ((-72 > lat) && (lat >= -80))
LetterDesignator = 'C';
return LetterDesignator;
}
/**
* Encodes a UTM location as MGRS string.
*
* @private
* @param {object} utm An object literal with easting, northing,
* zoneLetter, zoneNumber
* @param {number} accuracy Accuracy in digits (1-5).
* @return {string} MGRS string for the given UTM location.
*/
function encode(utm, accuracy) {
var seasting = "" + utm.easting,
snorthing = "" + utm.northing;
return utm.zoneNumber + utm.zoneLetter +
get100kID(utm.easting, utm.northing, utm.zoneNumber) +
seasting.substr(seasting.length - 5, accuracy) +
snorthing.substr(snorthing.length - 5, accuracy);
}
/**
* Get the two letter 100k designator for a given UTM easting,
* northing and zone number value.
*
* @private
* @param {number} easting
* @param {number} northing
* @param {number} zoneNumber
* @return the two letter 100k designator for the given UTM location.
*/
function get100kID(easting, northing, zoneNumber) {
var setParm = get100kSetForZone(zoneNumber);
var setColumn = Math.floor(easting / 100000);
var setRow = Math.floor(northing / 100000) % 20;
return getLetter100kID(setColumn, setRow, setParm);
}
/**
* Given a UTM zone number, figure out the MGRS 100K set it is in.
*
* @private
* @param {number} i An UTM zone number.
* @return {number} the 100k set the UTM zone is in.
*/
function get100kSetForZone(i) {
var setParm = i % NUM_100K_SETS;
if (setParm == 0)
setParm = NUM_100K_SETS;
return setParm;
}
/**
* Get the two-letter MGRS 100k designator given information
* translated from the UTM northing, easting and zone number.
*
* @private
* @param {number} column the column index as it relates to the MGRS
* 100k set spreadsheet, created from the UTM easting.
* Values are 1-8.
* @param {number} row the row index as it relates to the MGRS 100k set
* spreadsheet, created from the UTM northing value. Values
* are from 0-19.
* @param {number} parm the set block, as it relates to the MGRS 100k set
* spreadsheet, created from the UTM zone. Values are from
* 1-60.
* @return two letter MGRS 100k code.
*/
function getLetter100kID(column, row, parm) {
// colOrigin and rowOrigin are the letters at the origin of the set
var index = parm-1;
var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index);
var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index);
// colInt and rowInt are the letters to build to return
var colInt = colOrigin + column - 1;
var rowInt = rowOrigin + row;
var rollover = false;
if ( colInt > Z ) {
colInt = colInt - Z + A - 1;
rollover = true;
}
if (colInt == I || (colOrigin < I && colInt > I)
|| ((colInt > I || colOrigin < I) && rollover)) {
colInt++;
}
if (colInt == O || (colOrigin < O && colInt > O)
|| ((colInt > O || colOrigin < O) && rollover)) {
colInt++;
if (colInt == I) {
colInt++;
}
}
if (colInt > Z) {
colInt = colInt - Z + A - 1;
}
if (rowInt > V) {
rowInt = rowInt - V + A - 1;
rollover = true;
} else {
rollover = false;
}
if( ((rowInt == I) || ((rowOrigin < I) && (rowInt > I)))
|| (((rowInt > I)||(rowOrigin < I)) && rollover)) {
rowInt++;
}
if( ((rowInt == O) || ((rowOrigin < O) && (rowInt > O)))
|| (((rowInt > O)|| (rowOrigin < O)) && rollover)) {
rowInt++;
if (rowInt == I) {
rowInt++;
}
}
if (rowInt > V) {
rowInt = rowInt - V + A - 1;
}
var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt);
return twoLetter;
}
/**
* Decode the UTM parameters from a MGRS string.
*
* @private
* @param {string} mgrsString an UPPERCASE coordinate string is expected.
* @return {object} An object literal with easting, northing, zoneLetter,
* zoneNumber and accuracy (in meters) properties.
*/
function decode(mgrsString) {
if (mgrsString == null || mgrsString.length == 0) {
throw("MGRSPoint coverting from nothing");
}
var length = mgrsString.length;
var hunK = null;
var sb = "";
var testChar;
var i = 0;
// get Zone number
while (!(/[A-Z]/).test(testChar = mgrsString.charAt(i))) {
if (i >= 2) {
throw("MGRSPoint bad conversion from: "
+ mgrsString);
}
sb += testChar;
i++;
}
var zoneNumber = parseInt(sb, 10);
if (i == 0 || i + 3 > length) {
// A good MGRS string has to be 4-5 digits long,
// ##AAA/#AAA at least.
throw("MGRSPoint bad conversion from: "
+ mgrsString);
}
var zoneLetter = mgrsString.charAt(i++);
// Should we check the zone letter here? Why not.
if (zoneLetter <= 'A' || zoneLetter == 'B' || zoneLetter == 'Y'
|| zoneLetter >= 'Z' || zoneLetter == 'I'
|| zoneLetter == 'O') {
throw("MGRSPoint zone letter "
+ zoneLetter + " not handled: " + mgrsString);
}
hunK = mgrsString.substring(i, i += 2);
var set = get100kSetForZone(zoneNumber);
var east100k = getEastingFromChar(hunK.charAt(0), set);
var north100k = getNorthingFromChar(hunK.charAt(1), set);
// We have a bug where the northing may be 2000000 too low.
// How
// do we know when to roll over?
while (north100k < getMinNorthing(zoneLetter)) {
north100k += 2000000;
}
// calculate the char index for easting/northing separator
var remainder = length - i;
if (remainder % 2 != 0) {
throw("MGRSPoint has to have an even number \nof digits after the zone letter and two 100km letters - front \nhalf for easting meters, second half for \nnorthing meters"
+ mgrsString);
}
var sep = remainder / 2;
var sepEasting = 0.0;
var sepNorthing = 0.0;
if (sep > 0) {
var accuracyBonus = 100000.0 / Math.pow(10, sep);
var sepEastingString = mgrsString.substring(i, i + sep);
sepEasting = parseFloat(sepEastingString) * accuracyBonus;
var sepNorthingString = mgrsString.substring(i + sep);
sepNorthing = parseFloat(sepNorthingString) * accuracyBonus;
}
easting = sepEasting + east100k;
northing = sepNorthing + north100k;
return {
easting: easting,
northing: northing,
zoneLetter: zoneLetter,
zoneNumber: zoneNumber,
accuracy: accuracyBonus
};
}
/**
* Given the first letter from a two-letter MGRS 100k zone, and given the
* MGRS table set for the zone number, figure out the easting value that
* should be added to the other, secondary easting value.
*
* @private
* @param {char} e The first letter from a two-letter MGRS 100´k zone.
* @param {number} set The MGRS table set for the zone number.
* @return {number} The easting value for the given letter and set.
*/
function getEastingFromChar(e, set) {
// colOrigin is the letter at the origin of the set for the
// column
var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1);
var eastingValue = 100000.0;
var rewindMarker = false;
while (curCol != e.charCodeAt(0)) {
curCol++;
if (curCol == I)
curCol++;
if (curCol == O)
curCol++;
if (curCol > Z) {
if (rewindMarker) {
throw("Bad character: " + e);
}
curCol = A;
rewindMarker = true;
}
eastingValue += 100000.0;
}
return eastingValue;
}
/**
* Given the second letter from a two-letter MGRS 100k zone, and given the
* MGRS table set for the zone number, figure out the northing value that
* should be added to the other, secondary northing value. You have to
* remember that Northings are determined from the equator, and the vertical
* cycle of letters mean a 2000000 additional northing meters. This happens
* approx. every 18 degrees of latitude. This method does *NOT* count any
* additional northings. You have to figure out how many 2000000 meters need
* to be added for the zone letter of the MGRS coordinate.
*
* @private
* @param {char} n Second letter of the MGRS 100k zone
* @param {number} set The MGRS table set number, which is dependent on the
* UTM zone number.
* @return {number} The northing value for the given letter and set.
*/
function getNorthingFromChar(n, set) {
if (n > 'V') {
throw("MGRSPoint given invalid Northing "
+ n);
}
// rowOrigin is the letter at the origin of the set for the
// column
var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1);
var northingValue = 0.0;
var rewindMarker = false;
while (curRow != n.charCodeAt(0)) {
curRow++;
if (curRow == I)
curRow++;
if (curRow == O)
curRow++;
// fixing a bug making whole application hang in this loop
// when 'n' is a wrong character
if (curRow > V) {
if (rewindMarker) { // making sure that this loop ends
throw("Bad character: " + n);
}
curRow = A;
rewindMarker = true;
}
northingValue += 100000.0;
}
return northingValue;
}
/**
* The function getMinNorthing returns the minimum northing value of a MGRS
* zone.
*
* Ported from Geotrans' c Lattitude_Band_Value structure table.
*
* @private
* @param {char} zoneLetter The MGRS zone to get the min northing for.
* @return {number}
*/
function getMinNorthing(zoneLetter) {
var northing;
switch (zoneLetter) {
case 'C':
northing = 1100000.0;
break;
case 'D':
northing = 2000000.0;
break;
case 'E':
northing = 2800000.0;
break;
case 'F':
northing = 3700000.0;
break;
case 'G':
northing = 4600000.0;
break;
case 'H':
northing = 5500000.0;
break;
case 'J':
northing = 6400000.0;
break;
case 'K':
northing = 7300000.0;
break;
case 'L':
northing = 8200000.0;
break;
case 'M':
northing = 9100000.0;
break;
case 'N':
northing = 0.0;
break;
case 'P':
northing = 800000.0;
break;
case 'Q':
northing = 1700000.0;
break;
case 'R':
northing = 2600000.0;
break;
case 'S':
northing = 3500000.0;
break;
case 'T':
northing = 4400000.0;
break;
case 'U':
northing = 5300000.0;
break;
case 'V':
northing = 6200000.0;
break;
case 'W':
northing = 7000000.0;
break;
case 'X':
northing = 7900000.0;
break;
default:
northing = -1.0;
}
if (northing >= 0.0) {
return northing;
} else {
throw("Invalid zone letter: "
+ zoneLetter);
}
}
return {
forward: forward,
inverse: inverse
};
})();
if (window.Proj4js && Proj4js.Point) {
/**
* Creates a Proj4js.Point instance from a MGRS reference. The point will
* reference the center of the MGRS reference, and coordinates will be in
* WGS84 longitude and latitude.
*
* Only available if Proj4js is loaded.
*
* @param mgrs {string} MGRS reference
*/
Proj4js.Point.fromMGRS = function(mgrs) {
var llbbox = Proj4js.util.MGRS.inverse(mgrs);
return new Proj4js.Point(
(llbbox[2] + llbbox[0]) / 2,
(llbbox[3] + llbbox[1]) / 2
);
};
/**
* Converts a Proj4js.Point instance to a MGRS reference. The point
* coordinates are expected to be in WGS84 longitude and latitude.
*
* Only available if Proj4js is loaded.
*
* @param accuracy {int} The accuracy for the MGRS reference in digits (5
* for 1 m, 4 for 10 m, 3 for 100 m, 4 for 1000 m or 5 for 10000 m)
*/
Proj4js.Point.prototype.toMGRS = function(accuracy) {
return Proj4js.util.MGRS.forward({lon: this.x, lat: this.y}, accuracy);
};
}
+16
View File
@@ -0,0 +1,16 @@
{
"name": "proj4js",
"filename": "proj4js-compressed.js",
"version": "1.1.0",
"description": "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.",
"homepage": "http://trac.osgeo.org/proj4js/",
"keywords": [
"projection"
],
"repositories": [
{
"type": "svn",
"url": "http://svn.osgeo.org/metacrs/proj4js/trunk/"
}
]
}