mirror of
https://github.com/wahyd4/cdnjs.git
synced 2026-08-24 20:26:13 +10:00
Added proj4js 1.1.0 closes #933
This commit is contained in:
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
Proj4js.defs["EPSG26912"] = "+title=NAD83 / UTM zone 12N +proj=utm +zone=12 +a=6378137.0 +b=6356752.3141403";
|
||||
Executable
+5
@@ -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"
|
||||
Executable
+1
@@ -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 ";
|
||||
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -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";
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
Proj4js.defs["EPSG:4272"] = "+title=NZGD49 +proj=longlat +ellps=intl +datum=nzgd49 +no_defs ";
|
||||
Executable
+2
@@ -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";
|
||||
|
||||
Executable
+5
@@ -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";
|
||||
Executable
+11
@@ -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 \
|
||||
";
|
||||
Executable
+2
@@ -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"];
|
||||
Executable
+5438
File diff suppressed because it is too large
Load Diff
+266
File diff suppressed because one or more lines are too long
Executable
+1816
File diff suppressed because it is too large
Load Diff
Executable
+149
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Executable
+75
@@ -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;
|
||||
}
|
||||
};
|
||||
Executable
+108
@@ -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()
|
||||
|
||||
}
|
||||
Executable
+85
@@ -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()
|
||||
};
|
||||
Executable
+42
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
Executable
+140
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
Executable
+72
@@ -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()
|
||||
};
|
||||
|
||||
|
||||
Executable
+44
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
Executable
+117
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable
+52
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
Executable
+135
@@ -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);
|
||||
}
|
||||
};
|
||||
Executable
+358
@@ -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));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Executable
+148
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
Executable
+115
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable
+68
@@ -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()
|
||||
};
|
||||
Executable
+100
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
Executable
+284
@@ -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;
|
||||
}
|
||||
};
|
||||
Executable
+256
@@ -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;
|
||||
}
|
||||
};
|
||||
Executable
+110
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable
+157
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Executable
+121
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable
+110
@@ -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;
|
||||
}
|
||||
};
|
||||
Executable
+247
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Executable
+57
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
Executable
+141
@@ -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()
|
||||
};
|
||||
Executable
+43
@@ -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;
|
||||
}
|
||||
};
|
||||
Executable
+137
@@ -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;
|
||||
}
|
||||
};
|
||||
Executable
+950
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+16
@@ -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/"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user