proj4 2.4.4 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +1 -1
- package/Gruntfile.js +10 -3
- package/LICENSE.md +2 -2
- package/README.md +12 -12
- package/bower.json +1 -1
- package/component.json +1 -1
- package/dist/proj4-src.js +6597 -6322
- package/dist/proj4.js +1 -3
- package/lib/adjust_axis.js +12 -9
- package/lib/core.js +27 -16
- package/lib/datumUtils.js +5 -2
- package/lib/includedProjections.js +8 -4
- package/lib/index.js +1 -2
- package/lib/parseCode.js +28 -2
- package/lib/projections/aeqd.js +4 -3
- package/lib/projections/geocent.js +27 -0
- package/lib/projections/gstmerc.js +1 -1
- package/lib/projections/laea.js +6 -6
- package/lib/projections/robin.js +161 -0
- package/lib/projections/stere.js +1 -1
- package/lib/projections/sterea.js +1 -1
- package/lib/transform.js +14 -7
- package/package.json +17 -15
- package/projs.js +4 -0
- package/test/test.js +84 -23
- package/test/testData.js +121 -10
- package/.npmignore +0 -3
- package/dist/.npmignore +0 -0
- package/lib/version.js +0 -1
package/lib/parseCode.js
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
import defs from './defs';
|
|
2
2
|
import wkt from 'wkt-parser';
|
|
3
3
|
import projStr from './projString';
|
|
4
|
+
import match from './match';
|
|
4
5
|
function testObj(code){
|
|
5
6
|
return typeof code === 'string';
|
|
6
7
|
}
|
|
7
8
|
function testDef(code){
|
|
8
9
|
return code in defs;
|
|
9
10
|
}
|
|
10
|
-
var codeWords = ['PROJECTEDCRS', 'PROJCRS', 'GEOGCS','GEOCCS','PROJCS','LOCAL_CS', 'GEODCRS', 'GEODETICCRS', 'GEODETICDATUM', 'ENGCRS', 'ENGINEERINGCRS'];
|
|
11
|
+
var codeWords = ['PROJECTEDCRS', 'PROJCRS', 'GEOGCS','GEOCCS','PROJCS','LOCAL_CS', 'GEODCRS', 'GEODETICCRS', 'GEODETICDATUM', 'ENGCRS', 'ENGINEERINGCRS'];
|
|
11
12
|
function testWKT(code){
|
|
12
13
|
return codeWords.some(function (word) {
|
|
13
14
|
return code.indexOf(word) > -1;
|
|
14
15
|
});
|
|
15
16
|
}
|
|
17
|
+
var codes = ['3857', '900913', '3785', '102113'];
|
|
18
|
+
function checkMercator(item) {
|
|
19
|
+
var auth = match(item, 'authority');
|
|
20
|
+
if (!auth) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
var code = match(auth, 'epsg');
|
|
24
|
+
return code && codes.indexOf(code) > -1;
|
|
25
|
+
}
|
|
26
|
+
function checkProjStr(item) {
|
|
27
|
+
var ext = match(item, 'extension');
|
|
28
|
+
if (!ext) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
return match(ext, 'proj4');
|
|
32
|
+
}
|
|
16
33
|
function testProj(code){
|
|
17
34
|
return code[0] === '+';
|
|
18
35
|
}
|
|
@@ -23,7 +40,16 @@ function parse(code){
|
|
|
23
40
|
return defs[code];
|
|
24
41
|
}
|
|
25
42
|
if (testWKT(code)) {
|
|
26
|
-
|
|
43
|
+
var out = wkt(code);
|
|
44
|
+
// test of spetial case, due to this being a very common and often malformed
|
|
45
|
+
if (checkMercator(out)) {
|
|
46
|
+
return defs['EPSG:3857'];
|
|
47
|
+
}
|
|
48
|
+
var maybeProjStr = checkProjStr(out);
|
|
49
|
+
if (maybeProjStr) {
|
|
50
|
+
return projStr(maybeProjStr);
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
27
53
|
}
|
|
28
54
|
if (testProj(code)) {
|
|
29
55
|
return projStr(code);
|
package/lib/projections/aeqd.js
CHANGED
|
@@ -41,7 +41,7 @@ export function forward(p) {
|
|
|
41
41
|
//default case
|
|
42
42
|
cos_c = this.sin_p12 * sinphi + this.cos_p12 * cosphi * Math.cos(dlon);
|
|
43
43
|
c = Math.acos(cos_c);
|
|
44
|
-
kp = c / Math.sin(c);
|
|
44
|
+
kp = c ? c / Math.sin(c) : 1;
|
|
45
45
|
p.x = this.x0 + this.a * kp * cosphi * Math.sin(dlon);
|
|
46
46
|
p.y = this.y0 + this.a * kp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * Math.cos(dlon));
|
|
47
47
|
return p;
|
|
@@ -105,7 +105,7 @@ export function forward(p) {
|
|
|
105
105
|
export function inverse(p) {
|
|
106
106
|
p.x -= this.x0;
|
|
107
107
|
p.y -= this.y0;
|
|
108
|
-
var rh, z, sinz, cosz, lon, lat, con, e0, e1, e2, e3, Mlp, M, N1, psi, Az, cosAz, tmp, A, B, D, Ee, F;
|
|
108
|
+
var rh, z, sinz, cosz, lon, lat, con, e0, e1, e2, e3, Mlp, M, N1, psi, Az, cosAz, tmp, A, B, D, Ee, F, sinpsi;
|
|
109
109
|
if (this.sphere) {
|
|
110
110
|
rh = Math.sqrt(p.x * p.x + p.y * p.y);
|
|
111
111
|
if (rh > (2 * HALF_PI * this.a)) {
|
|
@@ -189,7 +189,8 @@ export function inverse(p) {
|
|
|
189
189
|
F = 1 - A * Ee * Ee / 2 - D * Ee * Ee * Ee / 6;
|
|
190
190
|
psi = Math.asin(this.sin_p12 * Math.cos(Ee) + this.cos_p12 * Math.sin(Ee) * cosAz);
|
|
191
191
|
lon = adjust_lon(this.long0 + Math.asin(Math.sin(Az) * Math.sin(Ee) / Math.cos(psi)));
|
|
192
|
-
|
|
192
|
+
sinpsi = Math.sin(psi);
|
|
193
|
+
lat = Math.atan2((sinpsi - this.es * F * this.sin_p12) * Math.tan(psi), sinpsi * (1 - this.es));
|
|
193
194
|
p.x = lon;
|
|
194
195
|
p.y = lat;
|
|
195
196
|
return p;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
geodeticToGeocentric,
|
|
3
|
+
geocentricToGeodetic
|
|
4
|
+
} from '../datumUtils';
|
|
5
|
+
|
|
6
|
+
export function init() {
|
|
7
|
+
this.name = 'geocent';
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function forward(p) {
|
|
12
|
+
var point = geodeticToGeocentric(p, this.es, this.a);
|
|
13
|
+
return point;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function inverse(p) {
|
|
17
|
+
var point = geocentricToGeodetic(p, this.es, this.a, this.b);
|
|
18
|
+
return point;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export var names = ["Geocentric", 'geocentric', "geocent", "Geocent"];
|
|
22
|
+
export default {
|
|
23
|
+
init: init,
|
|
24
|
+
forward: forward,
|
|
25
|
+
inverse: inverse,
|
|
26
|
+
names: names
|
|
27
|
+
};
|
package/lib/projections/laea.js
CHANGED
|
@@ -95,7 +95,7 @@ export function forward(p) {
|
|
|
95
95
|
if (this.mode === this.N_POLE) {
|
|
96
96
|
coslam = -coslam;
|
|
97
97
|
}
|
|
98
|
-
if (Math.abs(phi + this.
|
|
98
|
+
if (Math.abs(phi + this.lat0) < EPSLN) {
|
|
99
99
|
return null;
|
|
100
100
|
}
|
|
101
101
|
y = FORTPI - phi * 0.5;
|
|
@@ -194,7 +194,7 @@ export function inverse(p) {
|
|
|
194
194
|
y = cosz * rh;
|
|
195
195
|
break;
|
|
196
196
|
case this.OBLIQ:
|
|
197
|
-
phi = (Math.abs(rh) <= EPSLN) ? this.
|
|
197
|
+
phi = (Math.abs(rh) <= EPSLN) ? this.lat0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh);
|
|
198
198
|
x *= sinz * this.cosph0;
|
|
199
199
|
y = (cosz - Math.sin(phi) * this.sinph0) * rh;
|
|
200
200
|
break;
|
|
@@ -215,8 +215,8 @@ export function inverse(p) {
|
|
|
215
215
|
y *= this.dd;
|
|
216
216
|
rho = Math.sqrt(x * x + y * y);
|
|
217
217
|
if (rho < EPSLN) {
|
|
218
|
-
p.x =
|
|
219
|
-
p.y = this.
|
|
218
|
+
p.x = this.long0;
|
|
219
|
+
p.y = this.lat0;
|
|
220
220
|
return p;
|
|
221
221
|
}
|
|
222
222
|
sCe = 2 * Math.asin(0.5 * rho / this.rq);
|
|
@@ -239,8 +239,8 @@ export function inverse(p) {
|
|
|
239
239
|
}
|
|
240
240
|
q = (x * x + y * y);
|
|
241
241
|
if (!q) {
|
|
242
|
-
p.x =
|
|
243
|
-
p.y = this.
|
|
242
|
+
p.x = this.long0;
|
|
243
|
+
p.y = this.lat0;
|
|
244
244
|
return p;
|
|
245
245
|
}
|
|
246
246
|
ab = 1 - q / this.qp;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// Robinson projection
|
|
2
|
+
// Based on https://github.com/OSGeo/proj.4/blob/master/src/PJ_robin.c
|
|
3
|
+
// Polynomial coeficients from http://article.gmane.org/gmane.comp.gis.proj-4.devel/6039
|
|
4
|
+
|
|
5
|
+
import {HALF_PI, D2R, R2D, EPSLN} from '../constants/values';
|
|
6
|
+
import adjust_lon from '../common/adjust_lon';
|
|
7
|
+
|
|
8
|
+
var COEFS_X = [
|
|
9
|
+
[1.0000, 2.2199e-17, -7.15515e-05, 3.1103e-06],
|
|
10
|
+
[0.9986, -0.000482243, -2.4897e-05, -1.3309e-06],
|
|
11
|
+
[0.9954, -0.00083103, -4.48605e-05, -9.86701e-07],
|
|
12
|
+
[0.9900, -0.00135364, -5.9661e-05, 3.6777e-06],
|
|
13
|
+
[0.9822, -0.00167442, -4.49547e-06, -5.72411e-06],
|
|
14
|
+
[0.9730, -0.00214868, -9.03571e-05, 1.8736e-08],
|
|
15
|
+
[0.9600, -0.00305085, -9.00761e-05, 1.64917e-06],
|
|
16
|
+
[0.9427, -0.00382792, -6.53386e-05, -2.6154e-06],
|
|
17
|
+
[0.9216, -0.00467746, -0.00010457, 4.81243e-06],
|
|
18
|
+
[0.8962, -0.00536223, -3.23831e-05, -5.43432e-06],
|
|
19
|
+
[0.8679, -0.00609363, -0.000113898, 3.32484e-06],
|
|
20
|
+
[0.8350, -0.00698325, -6.40253e-05, 9.34959e-07],
|
|
21
|
+
[0.7986, -0.00755338, -5.00009e-05, 9.35324e-07],
|
|
22
|
+
[0.7597, -0.00798324, -3.5971e-05, -2.27626e-06],
|
|
23
|
+
[0.7186, -0.00851367, -7.01149e-05, -8.6303e-06],
|
|
24
|
+
[0.6732, -0.00986209, -0.000199569, 1.91974e-05],
|
|
25
|
+
[0.6213, -0.010418, 8.83923e-05, 6.24051e-06],
|
|
26
|
+
[0.5722, -0.00906601, 0.000182, 6.24051e-06],
|
|
27
|
+
[0.5322, -0.00677797, 0.000275608, 6.24051e-06]
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
var COEFS_Y = [
|
|
31
|
+
[-5.20417e-18, 0.0124, 1.21431e-18, -8.45284e-11],
|
|
32
|
+
[0.0620, 0.0124, -1.26793e-09, 4.22642e-10],
|
|
33
|
+
[0.1240, 0.0124, 5.07171e-09, -1.60604e-09],
|
|
34
|
+
[0.1860, 0.0123999, -1.90189e-08, 6.00152e-09],
|
|
35
|
+
[0.2480, 0.0124002, 7.10039e-08, -2.24e-08],
|
|
36
|
+
[0.3100, 0.0123992, -2.64997e-07, 8.35986e-08],
|
|
37
|
+
[0.3720, 0.0124029, 9.88983e-07, -3.11994e-07],
|
|
38
|
+
[0.4340, 0.0123893, -3.69093e-06, -4.35621e-07],
|
|
39
|
+
[0.4958, 0.0123198, -1.02252e-05, -3.45523e-07],
|
|
40
|
+
[0.5571, 0.0121916, -1.54081e-05, -5.82288e-07],
|
|
41
|
+
[0.6176, 0.0119938, -2.41424e-05, -5.25327e-07],
|
|
42
|
+
[0.6769, 0.011713, -3.20223e-05, -5.16405e-07],
|
|
43
|
+
[0.7346, 0.0113541, -3.97684e-05, -6.09052e-07],
|
|
44
|
+
[0.7903, 0.0109107, -4.89042e-05, -1.04739e-06],
|
|
45
|
+
[0.8435, 0.0103431, -6.4615e-05, -1.40374e-09],
|
|
46
|
+
[0.8936, 0.00969686, -6.4636e-05, -8.547e-06],
|
|
47
|
+
[0.9394, 0.00840947, -0.000192841, -4.2106e-06],
|
|
48
|
+
[0.9761, 0.00616527, -0.000256, -4.2106e-06],
|
|
49
|
+
[1.0000, 0.00328947, -0.000319159, -4.2106e-06]
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
var FXC = 0.8487;
|
|
53
|
+
var FYC = 1.3523;
|
|
54
|
+
var C1 = R2D/5; // rad to 5-degree interval
|
|
55
|
+
var RC1 = 1/C1;
|
|
56
|
+
var NODES = 18;
|
|
57
|
+
|
|
58
|
+
var poly3_val = function(coefs, x) {
|
|
59
|
+
return coefs[0] + x * (coefs[1] + x * (coefs[2] + x * coefs[3]));
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
var poly3_der = function(coefs, x) {
|
|
63
|
+
return coefs[1] + x * (2 * coefs[2] + x * 3 * coefs[3]);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
function newton_rapshon(f_df, start, max_err, iters) {
|
|
67
|
+
var x = start;
|
|
68
|
+
for (; iters; --iters) {
|
|
69
|
+
var upd = f_df(x);
|
|
70
|
+
x -= upd;
|
|
71
|
+
if (Math.abs(upd) < max_err) {
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return x;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function init() {
|
|
79
|
+
this.x0 = this.x0 || 0;
|
|
80
|
+
this.y0 = this.y0 || 0;
|
|
81
|
+
this.long0 = this.long0 || 0;
|
|
82
|
+
this.es = 0;
|
|
83
|
+
this.title = this.title || "Robinson";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function forward(ll) {
|
|
87
|
+
var lon = adjust_lon(ll.x - this.long0);
|
|
88
|
+
|
|
89
|
+
var dphi = Math.abs(ll.y);
|
|
90
|
+
var i = Math.floor(dphi * C1);
|
|
91
|
+
if (i < 0) {
|
|
92
|
+
i = 0;
|
|
93
|
+
} else if (i >= NODES) {
|
|
94
|
+
i = NODES - 1;
|
|
95
|
+
}
|
|
96
|
+
dphi = R2D * (dphi - RC1 * i);
|
|
97
|
+
var xy = {
|
|
98
|
+
x: poly3_val(COEFS_X[i], dphi) * lon,
|
|
99
|
+
y: poly3_val(COEFS_Y[i], dphi)
|
|
100
|
+
};
|
|
101
|
+
if (ll.y < 0) {
|
|
102
|
+
xy.y = -xy.y;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
xy.x = xy.x * this.a * FXC + this.x0;
|
|
106
|
+
xy.y = xy.y * this.a * FYC + this.y0;
|
|
107
|
+
return xy;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function inverse(xy) {
|
|
111
|
+
var ll = {
|
|
112
|
+
x: (xy.x - this.x0) / (this.a * FXC),
|
|
113
|
+
y: Math.abs(xy.y - this.y0) / (this.a * FYC)
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
if (ll.y >= 1) { // pathologic case
|
|
117
|
+
ll.x /= COEFS_X[NODES][0];
|
|
118
|
+
ll.y = xy.y < 0 ? -HALF_PI : HALF_PI;
|
|
119
|
+
} else {
|
|
120
|
+
// find table interval
|
|
121
|
+
var i = Math.floor(ll.y * NODES);
|
|
122
|
+
if (i < 0) {
|
|
123
|
+
i = 0;
|
|
124
|
+
} else if (i >= NODES) {
|
|
125
|
+
i = NODES - 1;
|
|
126
|
+
}
|
|
127
|
+
for (;;) {
|
|
128
|
+
if (COEFS_Y[i][0] > ll.y) {
|
|
129
|
+
--i;
|
|
130
|
+
} else if (COEFS_Y[i+1][0] <= ll.y) {
|
|
131
|
+
++i;
|
|
132
|
+
} else {
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// linear interpolation in 5 degree interval
|
|
137
|
+
var coefs = COEFS_Y[i];
|
|
138
|
+
var t = 5 * (ll.y - coefs[0]) / (COEFS_Y[i+1][0] - coefs[0]);
|
|
139
|
+
// find t so that poly3_val(coefs, t) = ll.y
|
|
140
|
+
t = newton_rapshon(function(x) {
|
|
141
|
+
return (poly3_val(coefs, x) - ll.y) / poly3_der(coefs, x);
|
|
142
|
+
}, t, EPSLN, 100);
|
|
143
|
+
|
|
144
|
+
ll.x /= poly3_val(COEFS_X[i], t);
|
|
145
|
+
ll.y = (5 * i + t) * D2R;
|
|
146
|
+
if (xy.y < 0) {
|
|
147
|
+
ll.y = -ll.y;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
ll.x = adjust_lon(ll.x + this.long0);
|
|
152
|
+
return ll;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export var names = ["Robinson", "robin"];
|
|
156
|
+
export default {
|
|
157
|
+
init: init,
|
|
158
|
+
forward: forward,
|
|
159
|
+
inverse: inverse,
|
|
160
|
+
names: names
|
|
161
|
+
};
|
package/lib/projections/stere.js
CHANGED
|
@@ -103,7 +103,7 @@ export function inverse(p) {
|
|
|
103
103
|
var lon, lat, ts, ce, Chi;
|
|
104
104
|
var rh = Math.sqrt(p.x * p.x + p.y * p.y);
|
|
105
105
|
if (this.sphere) {
|
|
106
|
-
var c = 2 * Math.atan(rh / (
|
|
106
|
+
var c = 2 * Math.atan(rh / (2 * this.a * this.k0));
|
|
107
107
|
lon = this.long0;
|
|
108
108
|
lat = this.lat0;
|
|
109
109
|
if (rh <= EPSLN) {
|
|
@@ -55,7 +55,7 @@ export function inverse(p) {
|
|
|
55
55
|
return p;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export var names = ["Stereographic_North_Pole", "Oblique_Stereographic", "Polar_Stereographic", "sterea","Oblique Stereographic Alternative"];
|
|
58
|
+
export var names = ["Stereographic_North_Pole", "Oblique_Stereographic", "Polar_Stereographic", "sterea","Oblique Stereographic Alternative","Double_Stereographic"];
|
|
59
59
|
export default {
|
|
60
60
|
init: init,
|
|
61
61
|
forward: forward,
|
package/lib/transform.js
CHANGED
|
@@ -29,17 +29,21 @@ export default function transform(source, dest, point) {
|
|
|
29
29
|
if (source.projName === 'longlat') {
|
|
30
30
|
point = {
|
|
31
31
|
x: point.x * D2R,
|
|
32
|
-
y: point.y * D2R
|
|
32
|
+
y: point.y * D2R,
|
|
33
|
+
z: point.z || 0
|
|
33
34
|
};
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
35
|
+
} else {
|
|
36
36
|
if (source.to_meter) {
|
|
37
37
|
point = {
|
|
38
38
|
x: point.x * source.to_meter,
|
|
39
|
-
y: point.y * source.to_meter
|
|
39
|
+
y: point.y * source.to_meter,
|
|
40
|
+
z: point.z || 0
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
point = source.inverse(point); // Convert Cartesian to longlat
|
|
44
|
+
if (!point) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
43
47
|
}
|
|
44
48
|
// Adjust for the prime meridian if necessary
|
|
45
49
|
if (source.from_greenwich) {
|
|
@@ -53,7 +57,8 @@ export default function transform(source, dest, point) {
|
|
|
53
57
|
if (dest.from_greenwich) {
|
|
54
58
|
point = {
|
|
55
59
|
x: point.x - dest.from_greenwich,
|
|
56
|
-
y: point.y
|
|
60
|
+
y: point.y,
|
|
61
|
+
z: point.z || 0
|
|
57
62
|
};
|
|
58
63
|
}
|
|
59
64
|
|
|
@@ -61,14 +66,16 @@ export default function transform(source, dest, point) {
|
|
|
61
66
|
// convert radians to decimal degrees
|
|
62
67
|
point = {
|
|
63
68
|
x: point.x * R2D,
|
|
64
|
-
y: point.y * R2D
|
|
69
|
+
y: point.y * R2D,
|
|
70
|
+
z: point.z || 0
|
|
65
71
|
};
|
|
66
72
|
} else { // else project
|
|
67
73
|
point = dest.forward(point);
|
|
68
74
|
if (dest.to_meter) {
|
|
69
75
|
point = {
|
|
70
76
|
x: point.x / dest.to_meter,
|
|
71
|
-
y: point.y / dest.to_meter
|
|
77
|
+
y: point.y / dest.to_meter,
|
|
78
|
+
z: point.z || 0
|
|
72
79
|
};
|
|
73
80
|
}
|
|
74
81
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "proj4",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.2",
|
|
4
4
|
"description": "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.",
|
|
5
5
|
"main": "dist/proj4-src.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"doc": "docs"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
+
"prepare": "grunt",
|
|
12
13
|
"build": "grunt",
|
|
13
14
|
"build:tmerc": "grunt build:tmerc",
|
|
14
15
|
"test": "npm run build && istanbul test _mocha test/test.js"
|
|
@@ -20,24 +21,25 @@
|
|
|
20
21
|
"author": "",
|
|
21
22
|
"license": "MIT",
|
|
22
23
|
"devDependencies": {
|
|
23
|
-
"chai": "~1.
|
|
24
|
-
"curl": "
|
|
24
|
+
"chai": "~4.1.2",
|
|
25
|
+
"curl-amd": "github:cujojs/curl",
|
|
25
26
|
"grunt": "^1.0.1",
|
|
26
|
-
"grunt-cli": "~
|
|
27
|
-
"grunt-contrib-connect": "~0.
|
|
27
|
+
"grunt-cli": "~1.2.0",
|
|
28
|
+
"grunt-contrib-connect": "~1.0.2",
|
|
28
29
|
"grunt-contrib-jshint": "~1.1.0",
|
|
29
|
-
"grunt-contrib-uglify": "~
|
|
30
|
-
"grunt-mocha-phantomjs": "~
|
|
31
|
-
"grunt-rollup": "^
|
|
32
|
-
"istanbul": "~0.
|
|
33
|
-
"mocha": "~
|
|
34
|
-
"rollup": "^0.
|
|
35
|
-
"rollup-plugin-json": "^2.0
|
|
36
|
-
"rollup-plugin-node-resolve": "^
|
|
37
|
-
"
|
|
30
|
+
"grunt-contrib-uglify": "~3.1.0",
|
|
31
|
+
"grunt-mocha-phantomjs": "~4.0.0",
|
|
32
|
+
"grunt-rollup": "^6.0.0",
|
|
33
|
+
"istanbul": "~0.4.5",
|
|
34
|
+
"mocha": "~4.0.0",
|
|
35
|
+
"rollup": "^0.50.0",
|
|
36
|
+
"rollup-plugin-json": "^2.3.0",
|
|
37
|
+
"rollup-plugin-node-resolve": "^3.0.0",
|
|
38
|
+
"rollup-plugin-replace": "^2.0.0",
|
|
39
|
+
"tin": "~0.5.0"
|
|
38
40
|
},
|
|
39
41
|
"dependencies": {
|
|
40
42
|
"mgrs": "1.0.0",
|
|
41
|
-
"wkt-parser": "^1.2.
|
|
43
|
+
"wkt-parser": "^1.2.4"
|
|
42
44
|
}
|
|
43
45
|
}
|
package/projs.js
CHANGED
|
@@ -23,6 +23,8 @@ import vandg from './lib/projections/vandg';
|
|
|
23
23
|
import aeqd from './lib/projections/aeqd';
|
|
24
24
|
import ortho from './lib/projections/ortho';
|
|
25
25
|
import qsc from './lib/projections/qsc';
|
|
26
|
+
import robin from './lib/projections/robin';
|
|
27
|
+
import geocent from './lib/projections/geocent';
|
|
26
28
|
export default function(proj4){
|
|
27
29
|
proj4.Proj.projections.add(tmerc);
|
|
28
30
|
proj4.Proj.projections.add(etmerc);
|
|
@@ -49,4 +51,6 @@ export default function(proj4){
|
|
|
49
51
|
proj4.Proj.projections.add(aeqd);
|
|
50
52
|
proj4.Proj.projections.add(ortho);
|
|
51
53
|
proj4.Proj.projections.add(qsc);
|
|
54
|
+
proj4.Proj.projections.add(robin);
|
|
55
|
+
proj4.Proj.projections.add(geocent);
|
|
52
56
|
}
|
package/test/test.js
CHANGED
|
@@ -122,6 +122,10 @@ function startTests(chai, proj4, testPoints) {
|
|
|
122
122
|
x: testPoint.xy[0],
|
|
123
123
|
y: testPoint.xy[1]
|
|
124
124
|
};
|
|
125
|
+
// in case of geocentric proj we need Z value.
|
|
126
|
+
if (typeof testPoint.xy[2] === 'number') {
|
|
127
|
+
pt.z = testPoint.xy[2]
|
|
128
|
+
}
|
|
125
129
|
var ll = proj4(testPoint.code, proj4.WGS84, pt);
|
|
126
130
|
assert.closeTo(ll.x, testPoint.ll[0], llEPSLN, 'x is close');
|
|
127
131
|
assert.closeTo(ll.y, testPoint.ll[1], llEPSLN, 'y is close');
|
|
@@ -167,42 +171,99 @@ function startTests(chai, proj4, testPoints) {
|
|
|
167
171
|
});
|
|
168
172
|
});
|
|
169
173
|
describe('points', function () {
|
|
170
|
-
it('should ignore stuff it does not know', function (){
|
|
174
|
+
it('should ignore stuff it does not know', function () {
|
|
175
|
+
var sweref99tm = '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs';
|
|
176
|
+
var rt90 = '+lon_0=15.808277777799999 +lat_0=0.0 +k=1.0 +x_0=1500000.0 +y_0=0.0 +proj=tmerc +ellps=bessel +units=m +towgs84=414.1,41.3,603.1,-0.855,2.141,-7.023,0 +no_defs';
|
|
177
|
+
var rslt = proj4(sweref99tm, rt90).forward({
|
|
178
|
+
x: 319180,
|
|
179
|
+
y: 6399862,
|
|
180
|
+
z: 0,
|
|
181
|
+
m: 1000,
|
|
182
|
+
method: function () {
|
|
183
|
+
return 'correct answer';
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
assert.closeTo(rslt.x, 1271137.9275601401, 0.000001);
|
|
187
|
+
assert.closeTo(rslt.y, 6404230.291459564, 0.000001);
|
|
188
|
+
assert.equal(rslt.z, 0);
|
|
189
|
+
assert.equal(rslt.m, 1000);
|
|
190
|
+
assert.equal(rslt.method(), 'correct answer');
|
|
191
|
+
});
|
|
192
|
+
it('should be able to compute X Y Z M in geocenteric coordinates', function () {
|
|
193
|
+
var epsg4978 = '+proj=geocent +datum=WGS84 +units=m +no_defs';
|
|
194
|
+
var rslt = proj4(epsg4978).forward({
|
|
195
|
+
x: -7.76166,
|
|
196
|
+
y: 39.19685,
|
|
197
|
+
z: 0,
|
|
198
|
+
m: 1000,
|
|
199
|
+
method: function () {
|
|
200
|
+
return 'correct answer';
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
assert.closeTo(rslt.x, 4904199.584207411, 0.000001);
|
|
204
|
+
assert.closeTo(rslt.y, -668448.8153664203, 0.000001);
|
|
205
|
+
assert.closeTo(rslt.z, 4009276.930771821, 0.000001);
|
|
206
|
+
assert.equal(rslt.m, 1000);
|
|
207
|
+
assert.equal(rslt.method(), 'correct answer');
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
describe('points array', function () {
|
|
211
|
+
it('should ignore stuff it does not know', function () {
|
|
212
|
+
var sweref99tm = '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs';
|
|
213
|
+
var rt90 = '+lon_0=15.808277777799999 +lat_0=0.0 +k=1.0 +x_0=1500000.0 +y_0=0.0 +proj=tmerc +ellps=bessel +units=m +towgs84=414.1,41.3,603.1,-0.855,2.141,-7.023,0 +no_defs';
|
|
214
|
+
var rslt = proj4(sweref99tm, rt90).forward([
|
|
215
|
+
319180,
|
|
216
|
+
6399862,
|
|
217
|
+
0,
|
|
218
|
+
1000,
|
|
219
|
+
]);
|
|
220
|
+
assert.closeTo(rslt[0], 1271137.9275601401, 0.000001);
|
|
221
|
+
assert.closeTo(rslt[1], 6404230.291459564, 0.000001);
|
|
222
|
+
assert.equal(rslt[2], 0);
|
|
223
|
+
assert.equal(rslt[3], 1000);
|
|
224
|
+
});
|
|
225
|
+
it('should be able to compute X Y Z M in geocenteric coordinates', function () {
|
|
226
|
+
var epsg4978 = '+proj=geocent +datum=WGS84 +units=m +no_defs';
|
|
227
|
+
var rslt = proj4(epsg4978).forward([
|
|
228
|
+
-7.76166,
|
|
229
|
+
39.19685,
|
|
230
|
+
0,
|
|
231
|
+
1000
|
|
232
|
+
]);
|
|
233
|
+
assert.closeTo(rslt[0], 4904199.584207411, 0.000001);
|
|
234
|
+
assert.closeTo(rslt[1], -668448.8153664203, 0.000001);
|
|
235
|
+
assert.closeTo(rslt[2], 4009276.930771821, 0.000001);
|
|
236
|
+
assert.equal(rslt[3], 1000);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
171
239
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
m: 1000,
|
|
179
|
-
method: function () {
|
|
180
|
-
return 'correct answer';
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
assert.closeTo(rslt.x, 1271137.9275601401, 0.000001);
|
|
184
|
-
assert.closeTo(rslt.y, 6404230.291459564, 0.000001);
|
|
185
|
-
assert.equal(rslt.z, 0);
|
|
186
|
-
assert.equal(rslt.m, 1000);
|
|
187
|
-
assert.equal(rslt.method(), 'correct answer');
|
|
240
|
+
it('should use correct axis order', function() {
|
|
241
|
+
var enu = 'PROJCS["NAD83 / Massachusetts Mainland", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26986"]]';
|
|
242
|
+
var neu = 'PROJCS["NAD83 / Massachusetts Mainland NE", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Northing", NORTH], AXIS["Easting", EAST], AUTHORITY["EPSG","26986"]]';
|
|
243
|
+
var rslt = proj4(enu, neu).forward({
|
|
244
|
+
x: 10.2,
|
|
245
|
+
y: 43.4
|
|
188
246
|
});
|
|
247
|
+
assert.closeTo(rslt.x, 43.4, 0.000001);
|
|
248
|
+
assert.closeTo(rslt.y, 10.2, 0.000001);
|
|
189
249
|
});
|
|
190
|
-
|
|
250
|
+
|
|
251
|
+
describe('defs', function () {
|
|
191
252
|
assert.equal(proj4.defs('testmerc'), proj4.defs['testmerc']);
|
|
192
253
|
proj4.defs('foo', '+proj=merc +lon_0=5.937 +lat_ts=45.027 +ellps=sphere');
|
|
193
254
|
assert.typeOf(proj4.defs['foo'], 'object');
|
|
194
255
|
proj4.defs('urn:x-ogc:def:crs:EPSG:4326', proj4.defs('EPSG:4326'));
|
|
195
256
|
assert.strictEqual(proj4.defs['urn:x-ogc:def:crs:EPSG:4326'], proj4.defs['EPSG:4326']);
|
|
196
257
|
|
|
197
|
-
describe('wkt', function() {
|
|
198
|
-
it('should provide the correct conversion factor for WKT GEOGCS projections', function() {
|
|
258
|
+
describe('wkt', function () {
|
|
259
|
+
it('should provide the correct conversion factor for WKT GEOGCS projections', function () {
|
|
199
260
|
proj4.defs('EPSG:4269', 'GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]]');
|
|
200
|
-
assert.equal(proj4.defs['EPSG:4269'].to_meter, 6378137*0.01745329251994328);
|
|
261
|
+
assert.equal(proj4.defs['EPSG:4269'].to_meter, 6378137 * 0.01745329251994328);
|
|
201
262
|
|
|
202
263
|
proj4.defs('EPSG:4279', 'GEOGCS["OS(SN)80",DATUM["OS_SN_1980",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],AUTHORITY["EPSG","6279"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4279"]]');
|
|
203
|
-
assert.equal(proj4.defs['EPSG:4279'].to_meter, 6377563.396*0.01745329251994328);
|
|
264
|
+
assert.equal(proj4.defs['EPSG:4279'].to_meter, 6377563.396 * 0.01745329251994328);
|
|
204
265
|
});
|
|
205
|
-
it('should parse wkt and proj4 of the same crs and result in the same params', function() {
|
|
266
|
+
it('should parse wkt and proj4 of the same crs and result in the same params', function () {
|
|
206
267
|
var s1 = 'GEOGCS["PSD93",DATUM["PDO_Survey_Datum_1993",SPHEROID["Clarke 1880 (RGS)",6378249.145,293.465,AUTHORITY["EPSG","7012"]],TOWGS84[-180.624,-225.516,173.919,-0.81,-1.898,8.336,16.7101],AUTHORITY["EPSG","6134"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4134"]]';
|
|
207
268
|
var s2 = '+proj=longlat +ellps=clrk80 +towgs84=-180.624,-225.516,173.919,-0.81,-1.898,8.336,16.7101 +no_defs';
|
|
208
269
|
var crs1 = proj4(s1);
|