@idm-plugin/geo 2.1.1 → 2.1.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/dist/index.js +238 -217
- package/dist/index.umd.cjs +7 -6
- package/dist/lane/src/index.d.ts +27 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as S from "@turf/turf";
|
|
2
2
|
import B from "moment";
|
|
3
3
|
import j from "@log4js-node/log4js-api";
|
|
4
4
|
var n0 = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
|
|
@@ -24,42 +24,42 @@ var _ = { exports: {} };
|
|
|
24
24
|
return q > 96 ? q - 87 : q > 64 ? q - 29 : q - 48;
|
|
25
25
|
}
|
|
26
26
|
function T(q) {
|
|
27
|
-
var n = 0, X = q.split("."), L = X[0], N = X[1] || "", U = 1, E,
|
|
28
|
-
for (q.charCodeAt(0) === 45 && (n = 1,
|
|
29
|
-
E = R(L.charCodeAt(n)),
|
|
27
|
+
var n = 0, X = q.split("."), L = X[0], N = X[1] || "", U = 1, E, V = 0, P = 1;
|
|
28
|
+
for (q.charCodeAt(0) === 45 && (n = 1, P = -1), n; n < L.length; n++)
|
|
29
|
+
E = R(L.charCodeAt(n)), V = 60 * V + E;
|
|
30
30
|
for (n = 0; n < N.length; n++)
|
|
31
|
-
U = U / 60, E = R(N.charCodeAt(n)),
|
|
32
|
-
return
|
|
31
|
+
U = U / 60, E = R(N.charCodeAt(n)), V += E * U;
|
|
32
|
+
return V * P;
|
|
33
33
|
}
|
|
34
|
-
function
|
|
34
|
+
function f(q) {
|
|
35
35
|
for (var n = 0; n < q.length; n++)
|
|
36
36
|
q[n] = T(q[n]);
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function i(q, n) {
|
|
39
39
|
for (var X = 0; X < n; X++)
|
|
40
40
|
q[X] = Math.round((q[X - 1] || 0) + q[X] * 6e4);
|
|
41
41
|
q[n - 1] = 1 / 0;
|
|
42
42
|
}
|
|
43
|
-
function
|
|
43
|
+
function e(q, n) {
|
|
44
44
|
var X = [], L;
|
|
45
45
|
for (L = 0; L < n.length; L++)
|
|
46
46
|
X[L] = q[n[L]];
|
|
47
47
|
return X;
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function t(q) {
|
|
50
50
|
var n = q.split("|"), X = n[2].split(" "), L = n[3].split(""), N = n[4].split(" ");
|
|
51
|
-
return
|
|
51
|
+
return f(X), f(L), f(N), i(N, L.length), {
|
|
52
52
|
name: n[0],
|
|
53
|
-
abbrs:
|
|
54
|
-
offsets:
|
|
53
|
+
abbrs: e(n[1].split(" "), L),
|
|
54
|
+
offsets: e(X, L),
|
|
55
55
|
untils: N,
|
|
56
56
|
population: n[5] | 0
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
function
|
|
60
|
-
q && this._set(
|
|
59
|
+
function l(q) {
|
|
60
|
+
q && this._set(t(q));
|
|
61
61
|
}
|
|
62
|
-
function
|
|
62
|
+
function Z(q, n) {
|
|
63
63
|
var X = n.length;
|
|
64
64
|
if (q < n[0])
|
|
65
65
|
return 0;
|
|
@@ -71,13 +71,13 @@ var _ = { exports: {} };
|
|
|
71
71
|
L = Math.floor((N + U) / 2), n[L] <= q ? N = L : U = L;
|
|
72
72
|
return U;
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
l.prototype = {
|
|
75
75
|
_set: function(q) {
|
|
76
76
|
this.name = q.name, this.abbrs = q.abbrs, this.untils = q.untils, this.offsets = q.offsets, this.population = q.population;
|
|
77
77
|
},
|
|
78
78
|
_index: function(q) {
|
|
79
79
|
var n = +q, X = this.untils, L;
|
|
80
|
-
if (L =
|
|
80
|
+
if (L = Z(n, X), L >= 0)
|
|
81
81
|
return L;
|
|
82
82
|
},
|
|
83
83
|
countries: function() {
|
|
@@ -87,10 +87,10 @@ var _ = { exports: {} };
|
|
|
87
87
|
});
|
|
88
88
|
},
|
|
89
89
|
parse: function(q) {
|
|
90
|
-
var n = +q, X = this.offsets, L = this.untils, N = L.length - 1, U, E,
|
|
91
|
-
for (
|
|
92
|
-
if (U = X[
|
|
93
|
-
return X[
|
|
90
|
+
var n = +q, X = this.offsets, L = this.untils, N = L.length - 1, U, E, V, P;
|
|
91
|
+
for (P = 0; P < N; P++)
|
|
92
|
+
if (U = X[P], E = X[P + 1], V = X[P && P - 1], U < E && s.moveAmbiguousForward ? U = E : U > V && s.moveInvalidForward && (U = V), n < L[P] - U * 6e4)
|
|
93
|
+
return X[P];
|
|
94
94
|
return X[N];
|
|
95
95
|
},
|
|
96
96
|
abbr: function(q) {
|
|
@@ -103,7 +103,7 @@ var _ = { exports: {} };
|
|
|
103
103
|
return this.offsets[this._index(q)];
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
|
-
function
|
|
106
|
+
function u(q, n) {
|
|
107
107
|
this.name = q, this.zones = n;
|
|
108
108
|
}
|
|
109
109
|
function G(q) {
|
|
@@ -122,11 +122,11 @@ var _ = { exports: {} };
|
|
|
122
122
|
return q;
|
|
123
123
|
}
|
|
124
124
|
function $() {
|
|
125
|
-
var q = (/* @__PURE__ */ new Date()).getFullYear() - 2, n = new G(new Date(q, 0, 1)), X = n.offset, L = [n], N, U, E,
|
|
126
|
-
for (
|
|
127
|
-
E = new Date(q,
|
|
128
|
-
for (
|
|
129
|
-
L.push(new G(new Date(q +
|
|
125
|
+
var q = (/* @__PURE__ */ new Date()).getFullYear() - 2, n = new G(new Date(q, 0, 1)), X = n.offset, L = [n], N, U, E, V;
|
|
126
|
+
for (V = 1; V < 48; V++)
|
|
127
|
+
E = new Date(q, V, 1).getTimezoneOffset(), E !== X && (U = new G(new Date(q, V, 1)), N = F(n, U), L.push(N), L.push(new G(new Date(N.at + 6e4))), n = U, X = E);
|
|
128
|
+
for (V = 0; V < 4; V++)
|
|
129
|
+
L.push(new G(new Date(q + V, 0, 1))), L.push(new G(new Date(q + V, 6, 1)));
|
|
130
130
|
return L;
|
|
131
131
|
}
|
|
132
132
|
function z0(q, n) {
|
|
@@ -134,17 +134,17 @@ var _ = { exports: {} };
|
|
|
134
134
|
}
|
|
135
135
|
function b0(q, n) {
|
|
136
136
|
var X, L;
|
|
137
|
-
for (
|
|
137
|
+
for (f(n), X = 0; X < n.length; X++)
|
|
138
138
|
L = n[X], A[L] = A[L] || {}, A[L][q] = !0;
|
|
139
139
|
}
|
|
140
140
|
function p0(q) {
|
|
141
|
-
var n = q.length, X = {}, L = [], N = {}, U, E,
|
|
141
|
+
var n = q.length, X = {}, L = [], N = {}, U, E, V, P;
|
|
142
142
|
for (U = 0; U < n; U++)
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
for (E in
|
|
146
|
-
|
|
147
|
-
N[
|
|
143
|
+
if (V = q[U].offset, !N.hasOwnProperty(V)) {
|
|
144
|
+
P = A[V] || {};
|
|
145
|
+
for (E in P)
|
|
146
|
+
P.hasOwnProperty(E) && (X[E] = !0);
|
|
147
|
+
N[V] = !0;
|
|
148
148
|
}
|
|
149
149
|
for (U in X)
|
|
150
150
|
X.hasOwnProperty(U) && L.push(O[U]);
|
|
@@ -161,10 +161,10 @@ var _ = { exports: {} };
|
|
|
161
161
|
}
|
|
162
162
|
} catch {
|
|
163
163
|
}
|
|
164
|
-
var X = $(), L = X.length, N = p0(X), U = [], E,
|
|
165
|
-
for (
|
|
166
|
-
for (E = new H(g(N[
|
|
167
|
-
E.scoreOffsetAt(X[
|
|
164
|
+
var X = $(), L = X.length, N = p0(X), U = [], E, V, P;
|
|
165
|
+
for (V = 0; V < N.length; V++) {
|
|
166
|
+
for (E = new H(g(N[V])), P = 0; P < L; P++)
|
|
167
|
+
E.scoreOffsetAt(X[P]);
|
|
168
168
|
U.push(E);
|
|
169
169
|
}
|
|
170
170
|
return U.sort(z0), U.length > 0 ? U[0].zone.name : void 0;
|
|
@@ -183,7 +183,7 @@ var _ = { exports: {} };
|
|
|
183
183
|
function g(q, n) {
|
|
184
184
|
q = h(q);
|
|
185
185
|
var X = p[q], L;
|
|
186
|
-
return X instanceof
|
|
186
|
+
return X instanceof l ? X : typeof X == "string" ? (X = new l(X), p[q] = X, X) : b[q] && n !== g && (L = g(b[q], g)) ? (X = p[q] = new l(), X._set(L), X.name = O[q], X) : null;
|
|
187
187
|
}
|
|
188
188
|
function c0() {
|
|
189
189
|
var q, n = [];
|
|
@@ -203,7 +203,7 @@ var _ = { exports: {} };
|
|
|
203
203
|
var n, X, L, N;
|
|
204
204
|
if (!(!q || !q.length))
|
|
205
205
|
for (n = 0; n < q.length; n++)
|
|
206
|
-
N = q[n].split("|"), X = N[0].toUpperCase(), L = N[1].split(" "), c[X] = new
|
|
206
|
+
N = q[n].split("|"), X = N[0].toUpperCase(), L = N[1].split(" "), c[X] = new u(
|
|
207
207
|
X,
|
|
208
208
|
L
|
|
209
209
|
);
|
|
@@ -224,7 +224,7 @@ var _ = { exports: {} };
|
|
|
224
224
|
}) : X;
|
|
225
225
|
}
|
|
226
226
|
function d0(q) {
|
|
227
|
-
k(q.zones), y(q.links), o0(q.countries),
|
|
227
|
+
k(q.zones), y(q.links), o0(q.countries), s.dataVersion = q.version;
|
|
228
228
|
}
|
|
229
229
|
function J(q) {
|
|
230
230
|
return J.didShowError || (J.didShowError = !0, D("moment.tz.zoneExists('" + q + "') has been deprecated in favor of !moment.tz.zone('" + q + "')")), !!g(q);
|
|
@@ -236,13 +236,13 @@ var _ = { exports: {} };
|
|
|
236
236
|
function D(q) {
|
|
237
237
|
typeof console < "u" && typeof console.error == "function" && console.error(q);
|
|
238
238
|
}
|
|
239
|
-
function
|
|
239
|
+
function s(q) {
|
|
240
240
|
var n = Array.prototype.slice.call(arguments, 0, -1), X = arguments[arguments.length - 1], L = M.utc.apply(null, n), N;
|
|
241
241
|
return !M.isMoment(q) && v(L) && (N = g(X)) && L.add(N.parse(L), "minutes"), L.tz(X), L;
|
|
242
242
|
}
|
|
243
|
-
|
|
243
|
+
s.version = z, s.dataVersion = "", s._zones = p, s._links = b, s._names = O, s._countries = c, s.add = k, s.link = y, s.load = d0, s.zone = g, s.zoneExists = J, s.guess = A0, s.names = c0, s.Zone = l, s.unpack = t, s.unpackBase60 = T, s.needsOffset = v, s.moveInvalidForward = !0, s.moveAmbiguousForward = !1, s.countries = W0, s.zonesForCountry = Y0;
|
|
244
244
|
var C = M.fn;
|
|
245
|
-
M.tz =
|
|
245
|
+
M.tz = s, M.defaultZone = null, M.updateOffset = function(q, n) {
|
|
246
246
|
var X = M.defaultZone, L;
|
|
247
247
|
if (q._z === void 0 && (X && v(q) && !q._isUTC && q.isValid() && (q._d = M.utc(q._a)._d, q.utc().add(X.parse(q), "minutes")), q._z = X), q._z)
|
|
248
248
|
if (L = q._z.utcOffset(q), Math.abs(L) < 16 && (L = L / 60), q.utcOffset !== void 0) {
|
|
@@ -1135,8 +1135,8 @@ const L0 = "2025b", T0 = [
|
|
|
1135
1135
|
links: i0,
|
|
1136
1136
|
countries: e0
|
|
1137
1137
|
};
|
|
1138
|
-
var
|
|
1139
|
-
|
|
1138
|
+
var f0 = R0;
|
|
1139
|
+
f0.tz.load(r0);
|
|
1140
1140
|
var M0 = { exports: {} };
|
|
1141
1141
|
(function(m) {
|
|
1142
1142
|
function M(z, p) {
|
|
@@ -1152,8 +1152,8 @@ var M0 = { exports: {} };
|
|
|
1152
1152
|
}
|
|
1153
1153
|
m.exports = M;
|
|
1154
1154
|
})(M0);
|
|
1155
|
-
var
|
|
1156
|
-
const S0 = /* @__PURE__ */ X0(
|
|
1155
|
+
var N0 = M0.exports;
|
|
1156
|
+
const S0 = /* @__PURE__ */ X0(N0);
|
|
1157
1157
|
class a {
|
|
1158
1158
|
/**
|
|
1159
1159
|
* 基于输入的经度,计算出时区
|
|
@@ -1350,7 +1350,7 @@ class t0 {
|
|
|
1350
1350
|
if (p && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(o.type))
|
|
1351
1351
|
continue;
|
|
1352
1352
|
const T = R.positionTime - d.positionTime;
|
|
1353
|
-
if (
|
|
1353
|
+
if (r.calculateDistance(R, d, !0, 4) / (T / 3600) < z)
|
|
1354
1354
|
O || (O = o), Y === M.length - 1 && (A = R, W = Y);
|
|
1355
1355
|
else {
|
|
1356
1356
|
O && (A = M[Y - 1], W = Y);
|
|
@@ -1374,8 +1374,8 @@ class t0 {
|
|
|
1374
1374
|
utc: B.unix(A.positionTime).utc().format()
|
|
1375
1375
|
},
|
|
1376
1376
|
duration: A.positionTime - O.positionTime
|
|
1377
|
-
}, d = M.filter((T) => T.positionTime >= Y.start.positionTime && T.positionTime <= Y.end.positionTime), R =
|
|
1378
|
-
Y.distance =
|
|
1377
|
+
}, d = M.filter((T) => T.positionTime >= Y.start.positionTime && T.positionTime <= Y.end.positionTime), R = r.divideAccordingToLng(d);
|
|
1378
|
+
Y.distance = r.calculateRouteDistance(R), Y.hours = Math.round(Y.duration / 3600 * 10) / 10, Y.avgSog = Math.round(Y.distance / Y.hours * 10) / 10, c.push(Y);
|
|
1379
1379
|
}
|
|
1380
1380
|
O = void 0, A = void 0;
|
|
1381
1381
|
}
|
|
@@ -1394,7 +1394,7 @@ class t0 {
|
|
|
1394
1394
|
if (O.length > 1)
|
|
1395
1395
|
for (let Y = 0; Y < O.length - 1; Y++) {
|
|
1396
1396
|
const d = O[Y], R = O[Y + 1];
|
|
1397
|
-
A +=
|
|
1397
|
+
A += r.calculateDistance(d, R, !0, 4), W += Math.abs(R.positionTime - d.positionTime);
|
|
1398
1398
|
}
|
|
1399
1399
|
A = Math.round(A * 100) / 100, W = Math.round(W / 3600 * 100) / 100;
|
|
1400
1400
|
const o = W ? Math.round(A / W * 100) / 100 : 0;
|
|
@@ -1407,7 +1407,7 @@ try {
|
|
|
1407
1407
|
} catch {
|
|
1408
1408
|
} finally {
|
|
1409
1409
|
}
|
|
1410
|
-
class
|
|
1410
|
+
class r {
|
|
1411
1411
|
/**
|
|
1412
1412
|
* 计算方位角
|
|
1413
1413
|
* @param from 坐标 {lng, lat}
|
|
@@ -1417,12 +1417,12 @@ class i {
|
|
|
1417
1417
|
* @returns {number} 单位度
|
|
1418
1418
|
*/
|
|
1419
1419
|
static calculateBearing(M, z, p = !0, b = 4) {
|
|
1420
|
-
const c =
|
|
1420
|
+
const c = S.points([
|
|
1421
1421
|
[M.lng, M.lat],
|
|
1422
1422
|
[z.lng, z.lat]
|
|
1423
1423
|
]);
|
|
1424
1424
|
let O;
|
|
1425
|
-
return p ? O =
|
|
1425
|
+
return p ? O = S.rhumbBearing(c.features[0], c.features[1]) : O = S.bearing(c.features[0], c.features[1]), O < 0 && (O += 360), a.roundPrecision(O, b);
|
|
1426
1426
|
}
|
|
1427
1427
|
/**
|
|
1428
1428
|
* 计算两点间距离
|
|
@@ -1435,12 +1435,12 @@ class i {
|
|
|
1435
1435
|
*/
|
|
1436
1436
|
static calculateDistance(M, z, p = !0, b = 4, c = "nauticalmiles") {
|
|
1437
1437
|
M = { ...M }, z = { ...z }, M.lng = a.convertToStdLng(M.lng, b), z.lng = a.convertToStdLng(z.lng, b);
|
|
1438
|
-
const O =
|
|
1438
|
+
const O = S.points([
|
|
1439
1439
|
[M.lng, M.lat],
|
|
1440
1440
|
[z.lng, z.lat]
|
|
1441
1441
|
]);
|
|
1442
1442
|
let A;
|
|
1443
|
-
return p ? A =
|
|
1443
|
+
return p ? A = S.rhumbDistance(O.features[0], O.features[1], { units: c }) : A = S.distance(O.features[0], O.features[1], { units: c }), a.roundPrecision(A, b);
|
|
1444
1444
|
}
|
|
1445
1445
|
/**
|
|
1446
1446
|
* 计算航线距离
|
|
@@ -1468,9 +1468,9 @@ class i {
|
|
|
1468
1468
|
* @param rhumb
|
|
1469
1469
|
*/
|
|
1470
1470
|
static calculateCoordinate(M, z, p, b = "nauticalmiles", c = !0) {
|
|
1471
|
-
const O =
|
|
1471
|
+
const O = S.point([M.lng, M.lat]);
|
|
1472
1472
|
let A;
|
|
1473
|
-
c ? A =
|
|
1473
|
+
c ? A = S.rhumbDestination(O, p, z, { units: b }) : A = S.destination(O, p, z, { units: b });
|
|
1474
1474
|
const W = A.geometry.coordinates;
|
|
1475
1475
|
return { lng: a.convertToStdLng(W[0], 8), lat: a.roundPrecision(W[1], 8) };
|
|
1476
1476
|
}
|
|
@@ -1519,18 +1519,18 @@ class i {
|
|
|
1519
1519
|
[A, M[W + 1].lat]
|
|
1520
1520
|
]);
|
|
1521
1521
|
let d, R;
|
|
1522
|
-
z ? (d =
|
|
1522
|
+
z ? (d = S.lineString(Y), R = S.lineString([
|
|
1523
1523
|
[o > 0 ? 180 : -180, 89],
|
|
1524
1524
|
[o > 0 ? 180 : -180, -89]
|
|
1525
|
-
])) : (d =
|
|
1526
|
-
const T =
|
|
1527
|
-
let
|
|
1525
|
+
])) : (d = S.greatCircle(Y[0], Y[1]), R = S.greatCircle([o > 0 ? 180 : -180, 89], [o > 0 ? 180 : -180, -89]));
|
|
1526
|
+
const T = S.lineIntersect(d, R);
|
|
1527
|
+
let f;
|
|
1528
1528
|
if (T.features.length) {
|
|
1529
|
-
const
|
|
1530
|
-
|
|
1529
|
+
const i = S.getCoord(T.features[0]);
|
|
1530
|
+
f = a.roundPrecision(i[1], 8);
|
|
1531
1531
|
} else
|
|
1532
|
-
|
|
1533
|
-
o > 0 ? (b.push([180 - 1e-6,
|
|
1532
|
+
f = M[W].lat;
|
|
1533
|
+
o > 0 ? (b.push([180 - 1e-6, f]), c.push([...b]), b = [], b.push([-(180 - 1e-6), f])) : (b.push([-(180 - 1e-6), f]), c.push([...b]), b = [], b.push([180 - 1e-6, f]));
|
|
1534
1534
|
}
|
|
1535
1535
|
W === M.length - 2 && b.push([A, M[W + 1].lat]);
|
|
1536
1536
|
}
|
|
@@ -1606,8 +1606,8 @@ class i {
|
|
|
1606
1606
|
*/
|
|
1607
1607
|
static appendCoordinateToRoute(M, z) {
|
|
1608
1608
|
M.lng = a.convertToStdLng(M.lng, 8);
|
|
1609
|
-
const p =
|
|
1610
|
-
return p.push(M),
|
|
1609
|
+
const p = r.convertRouteToCoordinates(z);
|
|
1610
|
+
return p.push(M), r.divideAccordingToLng(p);
|
|
1611
1611
|
}
|
|
1612
1612
|
/**
|
|
1613
1613
|
* 向route头加1个坐标
|
|
@@ -1615,8 +1615,8 @@ class i {
|
|
|
1615
1615
|
* @param route
|
|
1616
1616
|
*/
|
|
1617
1617
|
static unshiftCoordinateToRoute(M, z) {
|
|
1618
|
-
const p =
|
|
1619
|
-
return p.unshift(M),
|
|
1618
|
+
const p = r.convertRouteToCoordinates(z);
|
|
1619
|
+
return p.unshift(M), r.divideAccordingToLng(p);
|
|
1620
1620
|
}
|
|
1621
1621
|
/**
|
|
1622
1622
|
* 合并多个waypoints进航线
|
|
@@ -1690,8 +1690,8 @@ class i {
|
|
|
1690
1690
|
* @return [[[lng, lat]]]
|
|
1691
1691
|
*/
|
|
1692
1692
|
static calculateSubRoute(M, z) {
|
|
1693
|
-
const p =
|
|
1694
|
-
|
|
1693
|
+
const p = r.convertRouteToCoordinates(z);
|
|
1694
|
+
r.mergeCoordinateToWaypoints(M, p, !0), z = r.divideAccordingToLng(p);
|
|
1695
1695
|
const { segIndex: b, minIndex: c } = this.calculateMinDistanceToRoute({ ...M }, z);
|
|
1696
1696
|
M.lng = a.convertToStdLng(M.lng);
|
|
1697
1697
|
const O = [];
|
|
@@ -1741,10 +1741,10 @@ class i {
|
|
|
1741
1741
|
M.lng = a.convertToStdLng(M.lng, 8), z = { ...z }, p = { ...p }, z.lng = a.convertToStdLng(z.lng, 8), p.lng = a.convertToStdLng(p.lng, 8);
|
|
1742
1742
|
const c = a.convertToMonotonicLng([z, p]);
|
|
1743
1743
|
z = c[0], p = c[1];
|
|
1744
|
-
const O =
|
|
1744
|
+
const O = S.lineString([
|
|
1745
1745
|
[z.lng, z.lat],
|
|
1746
1746
|
[p.lng, p.lat]
|
|
1747
|
-
]), A =
|
|
1747
|
+
]), A = S.pointToLineDistance(S.point([M.lng, M.lat]), O, b), W = S.pointToLineDistance(S.point([M.lng > 0 ? M.lng - 360 : M.lng + 360, M.lat]), O, b);
|
|
1748
1748
|
return a.roundPrecision(Math.min(A, W), 6);
|
|
1749
1749
|
}
|
|
1750
1750
|
/**
|
|
@@ -1829,7 +1829,7 @@ class i {
|
|
|
1829
1829
|
* @param route [[[lng, lat]]]
|
|
1830
1830
|
*/
|
|
1831
1831
|
static nearestCoordinateInRoute(M, z) {
|
|
1832
|
-
const p =
|
|
1832
|
+
const p = S.point([M.lng, M.lat]), c = this.convertRouteToCoordinates(z).map((o) => [o.lng, o.lat]), O = S.lineString(c), A = S.nearestPointOnLine(O, p), W = S.getCoord(A);
|
|
1833
1833
|
return { lng: a.roundPrecision(W[0], 8), lat: a.roundPrecision(W[1], 8) };
|
|
1834
1834
|
}
|
|
1835
1835
|
/**
|
|
@@ -1865,31 +1865,31 @@ class i {
|
|
|
1865
1865
|
var R;
|
|
1866
1866
|
const c = M.speed || 12, O = [];
|
|
1867
1867
|
let A = [], W = !1, o = 0, Y = 0, d;
|
|
1868
|
-
if (z && p.length ? (O.push(M), p.forEach((T,
|
|
1868
|
+
if (z && p.length ? (O.push(M), p.forEach((T, f) => {
|
|
1869
1869
|
if (W)
|
|
1870
1870
|
A.push(T);
|
|
1871
1871
|
else {
|
|
1872
|
-
const
|
|
1873
|
-
let
|
|
1874
|
-
for (let
|
|
1872
|
+
const i = [];
|
|
1873
|
+
let e;
|
|
1874
|
+
for (let t = 0; t < T.length; t++)
|
|
1875
1875
|
if (d)
|
|
1876
|
-
|
|
1876
|
+
i.push(T[t]);
|
|
1877
1877
|
else {
|
|
1878
|
-
|
|
1879
|
-
const
|
|
1880
|
-
if (o +=
|
|
1881
|
-
Y +=
|
|
1878
|
+
e = { lng: T[t][0], lat: T[t][1] };
|
|
1879
|
+
const l = this.calculateDistance(M, e, !0, 8, b);
|
|
1880
|
+
if (o += l, o < z)
|
|
1881
|
+
Y += l, l && O.push(e), M = e;
|
|
1882
1882
|
else {
|
|
1883
1883
|
if (Y = z, o === z)
|
|
1884
|
-
d =
|
|
1884
|
+
d = e, i.push([d.lng, d.lat]);
|
|
1885
1885
|
else {
|
|
1886
|
-
const
|
|
1887
|
-
d = this.calculateCoordinate(
|
|
1886
|
+
const Z = o - z, u = this.calculateBearing(e, M);
|
|
1887
|
+
d = this.calculateCoordinate(e, u, Z, b), i.push([d.lng, d.lat]), i.push([e.lng, e.lat]);
|
|
1888
1888
|
}
|
|
1889
1889
|
W = !0;
|
|
1890
1890
|
}
|
|
1891
1891
|
}
|
|
1892
|
-
|
|
1892
|
+
i.length && A.push(i), f === p.length - 1 && !d && (d = e);
|
|
1893
1893
|
}
|
|
1894
1894
|
})) : (A = p, d = { ...M }), d)
|
|
1895
1895
|
if (O.push(d), d.distanceFromPrevious = Math.round(Y * 1e4) / 1e4, d.hourFromPrevious = Math.round(Y / c * 1e4) / 1e4, ((R = A[0]) == null ? void 0 : R.length) > 1) {
|
|
@@ -1906,10 +1906,10 @@ class i {
|
|
|
1906
1906
|
* @param to {lng, lat}
|
|
1907
1907
|
*/
|
|
1908
1908
|
static nearestCoordinateInLine(M, z, p) {
|
|
1909
|
-
const b = a.convertToStdLng(M.lng, 6), c =
|
|
1909
|
+
const b = a.convertToStdLng(M.lng, 6), c = S.point([b, M.lat]), O = a.convertToStdLng(z.lng, 6), A = a.convertToStdLng(p.lng, 6), W = S.lineString([
|
|
1910
1910
|
[O, z.lat],
|
|
1911
1911
|
[A, p.lat]
|
|
1912
|
-
]), o =
|
|
1912
|
+
]), o = S.nearestPointOnLine(W, c), Y = S.getCoord(o), d = a.roundPrecision(Y[0], 6), R = a.roundPrecision(Y[1], 6);
|
|
1913
1913
|
return { lng: d, lat: R, inline: !(d === O && R === z.lat) && !(d === A && R === p.lat) };
|
|
1914
1914
|
}
|
|
1915
1915
|
/**
|
|
@@ -1978,10 +1978,10 @@ class i {
|
|
|
1978
1978
|
for (const A of M)
|
|
1979
1979
|
for (const W of A)
|
|
1980
1980
|
z.push(W);
|
|
1981
|
-
const p =
|
|
1981
|
+
const p = S.featureCollection([]), b = a.convertToMonotonicLng2(z);
|
|
1982
1982
|
for (const A of b)
|
|
1983
|
-
p.features.push(
|
|
1984
|
-
const O =
|
|
1983
|
+
p.features.push(S.point(A));
|
|
1984
|
+
const O = S.center(p).geometry.coordinates;
|
|
1985
1985
|
return { lng: a.convertToStdLng(O[0], 8), lat: a.roundPrecision(O[1], 8) };
|
|
1986
1986
|
}
|
|
1987
1987
|
/**
|
|
@@ -2001,8 +2001,8 @@ class i {
|
|
|
2001
2001
|
for (const c of M)
|
|
2002
2002
|
for (const O of c)
|
|
2003
2003
|
z.push(O);
|
|
2004
|
-
const p = a.convertToMonotonicLng2(z), b =
|
|
2005
|
-
return
|
|
2004
|
+
const p = a.convertToMonotonicLng2(z), b = S.lineString(p);
|
|
2005
|
+
return S.bbox(b);
|
|
2006
2006
|
}
|
|
2007
2007
|
/**
|
|
2008
2008
|
* 计算BBox
|
|
@@ -2024,8 +2024,8 @@ class i {
|
|
|
2024
2024
|
const O = M[c - 1], A = M[c], W = M[c + 1];
|
|
2025
2025
|
let o = !1, Y = !1;
|
|
2026
2026
|
if ((O.velocity || O.suspend || O.important || O.pilot || c === 1) && (o = !0, b.push(O)), A.gcToPrevious && (o || (o = !0, b.push(O)), Y = !0, b.push(A), c++), W) {
|
|
2027
|
-
const d =
|
|
2028
|
-
Math.round(Math.acos(
|
|
2027
|
+
const d = r.calculateDistance(O, A, !0), R = r.calculateDistance(A, W, !0), T = r.calculateDistance(O, W, !0), f = (Math.pow(d, 2) + Math.pow(R, 2) - Math.pow(T, 2)) / (2 * d * R);
|
|
2028
|
+
Math.round(Math.acos(f) * 180 / Math.PI) < p && T > z && !Y && (b.push(A), c++);
|
|
2029
2029
|
}
|
|
2030
2030
|
if (c >= M.length - 1) {
|
|
2031
2031
|
const d = M.at(-1);
|
|
@@ -2059,8 +2059,8 @@ class i {
|
|
|
2059
2059
|
if (!b) {
|
|
2060
2060
|
const o = (O = (c = z.filter((d) => (d == null ? void 0 : d.positionTime) < p.unix())) == null ? void 0 : c.sort((d, R) => (d.positionTime || 0) - (R.positionTime || 0))) == null ? void 0 : O.at(-1), Y = (W = (A = z.filter((d) => (d == null ? void 0 : d.positionTime) > p.unix())) == null ? void 0 : A.sort((d, R) => (d.positionTime || 0) - (R.positionTime || 0))) == null ? void 0 : W.at(0);
|
|
2061
2061
|
if (o && Y) {
|
|
2062
|
-
const d =
|
|
2063
|
-
b =
|
|
2062
|
+
const d = r.calculateBearing(o, Y, !0), R = r.calculateDistance(o, Y), T = (p.unix() - o.positionTime) / (Y.positionTime - o.positionTime);
|
|
2063
|
+
b = r.calculateCoordinate(o, d, R * T), b.positionTime = p.unix(), b.utc = p.utc().format(), b.cog = d, b.sog = Math.round(R / ((Y.positionTime - o.positionTime) / 3600) * 100) / 100;
|
|
2064
2064
|
} else
|
|
2065
2065
|
b = o || Y, b && (b.utc = B.unix(b == null ? void 0 : b.positionTime).utc().format());
|
|
2066
2066
|
}
|
|
@@ -2075,16 +2075,16 @@ class i {
|
|
|
2075
2075
|
z = JSON.parse(JSON.stringify(z)), z.sort((o, Y) => (o.positionTime || 0) - (Y.positionTime || 0));
|
|
2076
2076
|
let p = Number.MAX_SAFE_INTEGER, b = Number.MAX_SAFE_INTEGER;
|
|
2077
2077
|
for (let o = 0; o < z.length - 1; o++) {
|
|
2078
|
-
const Y = z[o], d = z[o + 1], R =
|
|
2078
|
+
const Y = z[o], d = z[o + 1], R = r.calculatePointToLineDistance(M, Y, d);
|
|
2079
2079
|
R < p && (p = R, b = o);
|
|
2080
2080
|
}
|
|
2081
|
-
const c = z[b], O = z[b + 1], A =
|
|
2081
|
+
const c = z[b], O = z[b + 1], A = r.calculateDistance(c, M), W = r.calculateDistance(O, M);
|
|
2082
2082
|
if (A === 0)
|
|
2083
2083
|
M = c;
|
|
2084
2084
|
else if (W === 0)
|
|
2085
2085
|
M = O;
|
|
2086
2086
|
else {
|
|
2087
|
-
const o = c.positionTime || 0, Y = O.positionTime || 0, d =
|
|
2087
|
+
const o = c.positionTime || 0, Y = O.positionTime || 0, d = r.calculateDistance(c, O);
|
|
2088
2088
|
M.positionTime = Math.round(o + (Y - o) * (A / d));
|
|
2089
2089
|
}
|
|
2090
2090
|
return M.utc = M.positionTime ? B.unix(M.positionTime).utc().format() : void 0, M.positionTime ? M : void 0;
|
|
@@ -2123,7 +2123,7 @@ class i {
|
|
|
2123
2123
|
*/
|
|
2124
2124
|
static waypoints2RTZ(M, z) {
|
|
2125
2125
|
const b = [];
|
|
2126
|
-
return b.push('<?xml version="1.0" encoding="UTF-8"?>'), b.push('<route xmlns="http://www.cirm.org/RTZ/1/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">'), b.push(` <routeInfo routeName="${
|
|
2126
|
+
return b.push('<?xml version="1.0" encoding="UTF-8"?>'), b.push('<route xmlns="http://www.cirm.org/RTZ/1/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">'), b.push(` <routeInfo routeName="${r.xmlEscape(M)}"></routeInfo>`), b.push(...r.toRTZWaypoints(z, 6)), b.push("</route>"), b.join(`
|
|
2127
2127
|
`);
|
|
2128
2128
|
}
|
|
2129
2129
|
/**
|
|
@@ -2134,7 +2134,7 @@ class i {
|
|
|
2134
2134
|
*/
|
|
2135
2135
|
static waypoints2RTZ10(M, z) {
|
|
2136
2136
|
const b = [];
|
|
2137
|
-
return b.push('<?xml version="1.0" encoding="UTF-8"?>'), b.push('<route xmlns="http://www.cirm.org/RTZ/1/0" version="1.0">'), b.push(` <routeInfo routeName="${
|
|
2137
|
+
return b.push('<?xml version="1.0" encoding="UTF-8"?>'), b.push('<route xmlns="http://www.cirm.org/RTZ/1/0" version="1.0">'), b.push(` <routeInfo routeName="${r.xmlEscape(M)}"></routeInfo>`), b.push(...r.toRTZWaypoints(z, 6)), b.push("</route>"), b.join(`
|
|
2138
2138
|
`);
|
|
2139
2139
|
}
|
|
2140
2140
|
static toRTZWaypoints(M, z = 6) {
|
|
@@ -2142,60 +2142,81 @@ class i {
|
|
|
2142
2142
|
p.push(" <waypoints>");
|
|
2143
2143
|
for (let b = 0; b < M.length; b++) {
|
|
2144
2144
|
const c = M[b], O = b + 1, A = (c.lat ?? "").toFixed ? c.lat.toFixed(z).padEnd(z + 2, "0") : c.lat, W = (c.lng ?? "").toFixed ? c.lng.toFixed(z).padEnd(z + 2, "0") : c.lng, o = [`id="${O}"`, 'revision="0"'];
|
|
2145
|
-
if (c.name && o.push(`name="${
|
|
2145
|
+
if (c.name && o.push(`name="${r.xmlEscape(c.name)}"`), p.push(` <waypoint ${o.join(" ")}>`), p.push(` <position lat="${r.xmlEscape(A)}" lon="${r.xmlEscape(W)}" />`), b > 0) {
|
|
2146
2146
|
const d = c.gcToPrevious ? "Orthodrome" : "Loxodrome";
|
|
2147
2147
|
p.push(` <leg geometryType="${d}" />`);
|
|
2148
2148
|
}
|
|
2149
2149
|
const Y = [];
|
|
2150
|
-
if (c.description && Y.push(` <description>${
|
|
2151
|
-
Y.push(` <time>${
|
|
2150
|
+
if (c.description && Y.push(` <description>${r.xmlEscape(c.description)}</description>`), c.utc)
|
|
2151
|
+
Y.push(` <time>${r.xmlEscape(c.utc)}</time>`);
|
|
2152
2152
|
else if (c.positionTime)
|
|
2153
2153
|
try {
|
|
2154
|
-
Y.push(` <time>${
|
|
2154
|
+
Y.push(` <time>${r.xmlEscape(B.unix(c.positionTime).utc().format())}</time>`);
|
|
2155
2155
|
} catch {
|
|
2156
2156
|
}
|
|
2157
|
-
c.cog !== void 0 && Y.push(` <cog>${
|
|
2157
|
+
c.cog !== void 0 && Y.push(` <cog>${r.xmlEscape(c.cog)}</cog>`), c.sog !== void 0 && Y.push(` <sog>${r.xmlEscape(c.sog)}</sog>`), Y.length && (p.push(" <extensions>"), p.push(...Y), p.push(" </extensions>")), p.push(" </waypoint>");
|
|
2158
2158
|
}
|
|
2159
2159
|
return p.push(" </waypoints>"), p;
|
|
2160
2160
|
}
|
|
2161
2161
|
/**
|
|
2162
|
-
*
|
|
2163
|
-
*
|
|
2162
|
+
* 路径转通用CSV (纯十进制度数、无厂商头、RFC 4180标准)
|
|
2163
|
+
* 大部分海图设备/导航软件均可导入此格式
|
|
2164
2164
|
* @param waypoints 途径点
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2165
|
+
* @param options.precision 经纬度小数位数,默认6
|
|
2166
|
+
*/
|
|
2167
|
+
static waypoints2CSV(M, z) {
|
|
2168
|
+
const p = (z == null ? void 0 : z.precision) ?? 6, b = M.some((i) => i.name), c = M.some((i) => i.description), O = M.some((i) => i.port != null), A = M.some((i) => i.stbd != null), W = M.some((i) => i.arrRad != null), o = M.some((i) => i.speed != null), Y = M.some((i, e) => e > 0 && i.gcToPrevious != null), d = M.some((i) => i.bearing != null), R = M.some((i) => i.distanceFromPrevious != null), T = ["WPT No.", "Latitude", "Longitude"];
|
|
2169
|
+
b && T.push("Name"), c && T.push("Description"), Y && T.push("Leg"), d && T.push("Bearing[deg]"), R && T.push("Distance[NM]"), o && T.push("Speed[kn]"), O && T.push("PORT XTD[NM]"), A && T.push("STBD XTD[NM]"), W && T.push("Arr.Rad[NM]");
|
|
2170
|
+
const f = [];
|
|
2171
|
+
f.push(T.map((i) => r.csvEscapeField(i)).join(","));
|
|
2172
|
+
for (let i = 0; i < M.length; i++) {
|
|
2173
|
+
const e = M[i], t = [];
|
|
2174
|
+
t.push((i + 1).toString()), t.push(e.lat.toFixed(p)), t.push(e.lng.toFixed(p)), b && t.push(e.name ?? ""), c && t.push(e.description ?? ""), Y && t.push(i === 0 ? "" : e.gcToPrevious ? "GC" : "RL"), d && t.push(e.bearing != null ? String(e.bearing) : ""), R && t.push(e.distanceFromPrevious != null ? String(e.distanceFromPrevious) : ""), o && t.push(e.speed != null ? String(e.speed) : ""), O && t.push(e.port != null ? String(e.port) : ""), A && t.push(e.stbd != null ? String(e.stbd) : ""), W && t.push(e.arrRad != null ? String(e.arrRad) : ""), f.push(t.map((l) => r.csvEscapeField(l)).join(","));
|
|
2172
2175
|
}
|
|
2173
|
-
return
|
|
2176
|
+
return f.join(`
|
|
2174
2177
|
`);
|
|
2175
2178
|
}
|
|
2176
2179
|
/**
|
|
2177
|
-
*
|
|
2178
|
-
|
|
2180
|
+
* RFC 4180 CSV字段转义:含逗号、双引号、换行时用双引号包裹,内部双引号翻倍
|
|
2181
|
+
*/
|
|
2182
|
+
static csvEscapeField(M) {
|
|
2183
|
+
if (M == null)
|
|
2184
|
+
return "";
|
|
2185
|
+
const z = String(M);
|
|
2186
|
+
return z.includes(",") || z.includes('"') || z.includes(`
|
|
2187
|
+
`) || z.includes("\r") ? `"${z.replace(/"/g, '""')}"` : z;
|
|
2188
|
+
}
|
|
2189
|
+
/**
|
|
2190
|
+
* 十进制度数转NMEA度分格式 (DDMM.MM / DDDMM.MM)
|
|
2191
|
+
* @param value 十进制度数
|
|
2192
|
+
* @param isLat true为纬度,false为经度
|
|
2193
|
+
*/
|
|
2194
|
+
static decimalToNmeaDm(M, z) {
|
|
2195
|
+
const p = Math.abs(M), b = Math.floor(p), c = (p - b) * 60, O = z ? `${b.toString().padStart(2, "0")}${c.toFixed(2).padStart(5, "0")}` : `${b.toString().padStart(3, "0")}${c.toFixed(2).padStart(5, "0")}`, A = z ? M >= 0 ? "N" : "S" : M >= 0 ? "E" : "W";
|
|
2196
|
+
return { dm: O, dir: A };
|
|
2197
|
+
}
|
|
2198
|
+
/**
|
|
2199
|
+
* 计算NMEA 0183校验和 ($与*之间所有字符的异或,两字符十六进制大写)
|
|
2200
|
+
* @param sentence $与*之间的字符串
|
|
2201
|
+
*/
|
|
2202
|
+
static nmeaChecksum(M) {
|
|
2203
|
+
let z = 0;
|
|
2204
|
+
for (let p = 0; p < M.length; p++)
|
|
2205
|
+
z ^= M.charCodeAt(p);
|
|
2206
|
+
return z.toString(16).toUpperCase().padStart(2, "0");
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* 路径转NMEA 0183 WPL航点语句
|
|
2179
2210
|
* @param waypoints 途径点
|
|
2211
|
+
* @returns 多条$GPWPL语句,以\r\n分隔
|
|
2180
2212
|
*/
|
|
2181
|
-
static
|
|
2182
|
-
const
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
const c = ["WPT No.", "LAT", "", "", "LON", "", "", "PORT[NM]", "STBD[NM]", "Arr. Rad[NM]", "Speed[kn]", "Sail(RL/GC)"];
|
|
2187
|
-
b.push(" <Row>");
|
|
2188
|
-
for (const O of c)
|
|
2189
|
-
b.push(` <Cell><Data ss:Type="String">${i.xmlEscape(O)}</Data></Cell>`);
|
|
2190
|
-
b.push(" </Row>");
|
|
2191
|
-
for (let O = 0; O < z.length; O++) {
|
|
2192
|
-
const A = z[O], W = O.toString().padStart(3, "0"), o = a.lat2pretty(A.lat, 6, p), Y = a.lng2pretty(A.lng, 6, p), d = A.port ? A.port : "***", R = A.stbd ? A.stbd : "***", T = A.arrRad ? A.arrRad : "***", r = A.speed ? A.speed : "***", e = A.gcToPrevious ? "GC" : O === 0 ? "" : "RL", S = [W, o.H, o.M, o.direction, Y.H, Y.M, Y.direction, d, R, T, r, e];
|
|
2193
|
-
b.push(" <Row>");
|
|
2194
|
-
for (const s of S)
|
|
2195
|
-
b.push(` <Cell><Data ss:Type="String">${i.xmlEscape(s)}</Data></Cell>`);
|
|
2196
|
-
b.push(" </Row>");
|
|
2213
|
+
static waypoints2NMEA(M) {
|
|
2214
|
+
const z = [];
|
|
2215
|
+
for (let p = 0; p < M.length; p++) {
|
|
2216
|
+
const b = M[p], c = r.decimalToNmeaDm(b.lat, !0), O = r.decimalToNmeaDm(b.lng, !1), A = b.name ? String(b.name).slice(0, 6) : `WPT${(p + 1).toString().padStart(3, "0")}`, W = `GPWPL,${c.dm},${c.dir},${O.dm},${O.dir},${A}`, o = r.nmeaChecksum(W);
|
|
2217
|
+
z.push(`$${W}*${o}`);
|
|
2197
2218
|
}
|
|
2198
|
-
return
|
|
2219
|
+
return z.join(`\r
|
|
2199
2220
|
`);
|
|
2200
2221
|
}
|
|
2201
2222
|
/**
|
|
@@ -2213,7 +2234,7 @@ class i {
|
|
|
2213
2234
|
static coordinatesSummary(M, z = 3) {
|
|
2214
2235
|
if (M.length > 1) {
|
|
2215
2236
|
const p = M[0], b = M[M.length - 1], c = (p == null ? void 0 : p.positionTime) < (b == null ? void 0 : b.positionTime) ? B.unix(p == null ? void 0 : p.positionTime) : B.unix(b == null ? void 0 : b.positionTime), O = (p == null ? void 0 : p.positionTime) > (b == null ? void 0 : b.positionTime) ? B.unix(p == null ? void 0 : p.positionTime) : B.unix(b == null ? void 0 : b.positionTime), A = Math.round(O.diff(c, "hours", !0) * 100) / 100, W = this.generateRouteAccordingToWaypoints(M, !0, !0), o = this.calculateRouteDistance(W), d = t0.inspectStoppages(M, z).reduce(
|
|
2216
|
-
(T,
|
|
2237
|
+
(T, f) => (T.duration += f.duration, T.distance += f.distance, T),
|
|
2217
2238
|
{ hours: 0, distance: 0, spd: 0, duration: 0 }
|
|
2218
2239
|
);
|
|
2219
2240
|
d.hours = Math.round(d.duration / 3600 * 100) / 100, d.distance = Math.round(d.distance * 100) / 100, d.spd = d.hours ? Math.round(d.distance / d.hours * 100) / 100 : 0;
|
|
@@ -2251,18 +2272,18 @@ class i {
|
|
|
2251
2272
|
const p = z.sample.hours.at(0), b = B.utc(M), c = B.utc(z.eta), O = b.isAfter(c) ? c : b;
|
|
2252
2273
|
let A = z.sample.all.find((T) => T.eta === O.format());
|
|
2253
2274
|
if (!A) {
|
|
2254
|
-
const T = z.sample.all.filter((G) => B.utc(G.eta).isBefore(O)).at(-1),
|
|
2255
|
-
A = (R = this.calculateNextCoordinateAlongRoute(T, T.speed * O.diff(B(T.etd), "hours", !0),
|
|
2256
|
-
const { cFactor:
|
|
2275
|
+
const T = z.sample.all.filter((G) => B.utc(G.eta).isBefore(O)).at(-1), f = this.calculateSubRoute(T, z.route);
|
|
2276
|
+
A = (R = this.calculateNextCoordinateAlongRoute(T, T.speed * O.diff(B(T.etd), "hours", !0), f)) == null ? void 0 : R.coordinate;
|
|
2277
|
+
const { cFactor: i, cog: e, wxFactor: t, meteo: l } = T, Z = Math.round(A.distanceFromPrevious * 1e4) / 1e4, u = Math.round((Z + T.distanceFromStart) * 1e4) / 1e4;
|
|
2257
2278
|
A = {
|
|
2258
2279
|
...A,
|
|
2259
|
-
cFactor:
|
|
2260
|
-
cog:
|
|
2280
|
+
cFactor: i,
|
|
2281
|
+
cog: e,
|
|
2261
2282
|
speed: T.speed,
|
|
2262
|
-
wxFactor:
|
|
2263
|
-
distanceFromStart:
|
|
2264
|
-
distanceFromPrevious:
|
|
2265
|
-
meteo:
|
|
2283
|
+
wxFactor: t,
|
|
2284
|
+
distanceFromStart: u,
|
|
2285
|
+
distanceFromPrevious: Z,
|
|
2286
|
+
meteo: l,
|
|
2266
2287
|
eta: O.format(),
|
|
2267
2288
|
etd: O.format()
|
|
2268
2289
|
};
|
|
@@ -2320,7 +2341,7 @@ class V0 {
|
|
|
2320
2341
|
*/
|
|
2321
2342
|
static convert2Geojson(M) {
|
|
2322
2343
|
var p, b, c;
|
|
2323
|
-
const z =
|
|
2344
|
+
const z = S.featureCollection([]);
|
|
2324
2345
|
for (const O of M) {
|
|
2325
2346
|
const A = (p = O.history) == null ? void 0 : p[0];
|
|
2326
2347
|
if (O.forecasts) {
|
|
@@ -2328,72 +2349,72 @@ class V0 {
|
|
|
2328
2349
|
for (const W of O.forecasts) {
|
|
2329
2350
|
let o;
|
|
2330
2351
|
const Y = [], d = [], R = B(W.date).utc(), T = `${O.name}-${W.model}`;
|
|
2331
|
-
for (const
|
|
2332
|
-
const
|
|
2333
|
-
o = o ||
|
|
2334
|
-
const
|
|
2352
|
+
for (const i in W == null ? void 0 : W.hours) {
|
|
2353
|
+
const e = W.hours[i];
|
|
2354
|
+
o = o || e;
|
|
2355
|
+
const t = R.clone().add(Number(i), "hour"), l = S.point([e.lng, e.lat], {
|
|
2335
2356
|
model: W.model,
|
|
2336
2357
|
name: O.name,
|
|
2337
2358
|
nameCn: O.nameCn,
|
|
2338
|
-
date:
|
|
2339
|
-
hour: Number(
|
|
2340
|
-
format:
|
|
2341
|
-
pressure:
|
|
2342
|
-
gusts:
|
|
2343
|
-
wind:
|
|
2344
|
-
movement:
|
|
2359
|
+
date: t.format(),
|
|
2360
|
+
hour: Number(i),
|
|
2361
|
+
format: t.format("MMM-DD/HHmm[Z]"),
|
|
2362
|
+
pressure: e.pressure > 1e4 ? a.roundPrecision(e.pressure / 100, 0) : a.roundPrecision(e.pressure, 0),
|
|
2363
|
+
gusts: e.gusts,
|
|
2364
|
+
wind: e.wind || {},
|
|
2365
|
+
movement: e.movement,
|
|
2345
2366
|
category: T,
|
|
2346
2367
|
type: "forecast"
|
|
2347
2368
|
});
|
|
2348
|
-
d.push(
|
|
2369
|
+
d.push(l), Y.push(l.geometry.coordinates);
|
|
2349
2370
|
}
|
|
2350
|
-
const
|
|
2371
|
+
const f = {
|
|
2351
2372
|
kts: void 0,
|
|
2352
2373
|
deg: void 0
|
|
2353
2374
|
};
|
|
2354
2375
|
if (A) {
|
|
2355
|
-
const
|
|
2376
|
+
const i = B(A.updated).utc();
|
|
2356
2377
|
if (o) {
|
|
2357
|
-
const
|
|
2358
|
-
|
|
2378
|
+
const t = r.calculateDistance(A, o), l = B(o.utc || o.updated).diff(i, "h", !0);
|
|
2379
|
+
f.kts = Math.round(t / l * 100) / 100, f.deg = r.calculateBearing(A, o, !0, 0);
|
|
2359
2380
|
}
|
|
2360
|
-
const
|
|
2381
|
+
const e = S.point([A.lng, A.lat], {
|
|
2361
2382
|
model: W.model,
|
|
2362
2383
|
name: O.name,
|
|
2363
2384
|
nameCn: O.nameCn,
|
|
2364
|
-
date:
|
|
2385
|
+
date: i.format(),
|
|
2365
2386
|
hour: 0,
|
|
2366
|
-
format:
|
|
2387
|
+
format: i.format("MMM-DD/HHmm[Z]"),
|
|
2367
2388
|
pressure: A.pressure > 1e4 ? a.roundPrecision((A == null ? void 0 : A.pressure) / 100, 0) : a.roundPrecision(A.pressure, 0),
|
|
2368
2389
|
wind: A.wind,
|
|
2369
|
-
movement:
|
|
2390
|
+
movement: f,
|
|
2370
2391
|
category: T,
|
|
2371
2392
|
type: "forecast",
|
|
2372
2393
|
important: !0
|
|
2373
2394
|
// 第一个预报点为重要点
|
|
2374
2395
|
});
|
|
2375
|
-
d.unshift(
|
|
2396
|
+
d.unshift(e), Y.unshift(e.geometry.coordinates);
|
|
2376
2397
|
}
|
|
2377
2398
|
if (z.features.push(...d), (Y == null ? void 0 : Y.length) > 1) {
|
|
2378
|
-
const
|
|
2399
|
+
const i = S.lineString(a.convertToMonotonicLng2(Y), {
|
|
2379
2400
|
date: (A == null ? void 0 : A.updated) || (R == null ? void 0 : R.format()),
|
|
2380
2401
|
id: O.id || O.name,
|
|
2381
2402
|
model: W.model,
|
|
2382
2403
|
name: O.name,
|
|
2383
2404
|
category: T,
|
|
2384
2405
|
type: "forecast",
|
|
2385
|
-
movement:
|
|
2406
|
+
movement: f
|
|
2386
2407
|
});
|
|
2387
|
-
z.features.push(
|
|
2408
|
+
z.features.push(i);
|
|
2388
2409
|
}
|
|
2389
2410
|
}
|
|
2390
2411
|
}
|
|
2391
2412
|
if (z.features.sort((W, o) => W.properties.type === "forecast" && o.properties.type === "forecast" && W.geometry.type === "Point" && o.geometry.type === "Point" ? B(W.properties.date).valueOf() - B(o.properties.date).valueOf() : 0), (b = O.history) != null && b.length) {
|
|
2392
2413
|
const W = [], o = B(A == null ? void 0 : A.updated).utc(), Y = B((c = O.history) == null ? void 0 : c.at(-1).updated).utc(), d = o.diff(Y, "h") % 24 > 2 ? 24 : 12;
|
|
2393
2414
|
for (const R of O.history) {
|
|
2394
|
-
const T = B(R.updated).utc(),
|
|
2395
|
-
|
|
2396
|
-
const
|
|
2415
|
+
const T = B(R.updated).utc(), f = T.isSameOrBefore(o) || T.isSame(Y);
|
|
2416
|
+
f && o.add(-d, "h");
|
|
2417
|
+
const i = S.point([R.lng, R.lat], {
|
|
2397
2418
|
name: O.name,
|
|
2398
2419
|
nameCn: O.nameCn,
|
|
2399
2420
|
date: T.format(),
|
|
@@ -2405,12 +2426,12 @@ class V0 {
|
|
|
2405
2426
|
category: `${O.name}-history`,
|
|
2406
2427
|
wind: R.wind,
|
|
2407
2428
|
movement: R.movement,
|
|
2408
|
-
important:
|
|
2429
|
+
important: f
|
|
2409
2430
|
});
|
|
2410
|
-
z.features.push(
|
|
2431
|
+
z.features.push(i), W.push(i.geometry.coordinates);
|
|
2411
2432
|
}
|
|
2412
2433
|
if (W.length === 1 && W.push(W[0]), W.length > 1) {
|
|
2413
|
-
const R =
|
|
2434
|
+
const R = S.lineString(a.convertToMonotonicLng2(W), {
|
|
2414
2435
|
name: O.name,
|
|
2415
2436
|
type: "history",
|
|
2416
2437
|
updated: A == null ? void 0 : A.updated,
|
|
@@ -2433,32 +2454,32 @@ class V0 {
|
|
|
2433
2454
|
var c, O, A, W;
|
|
2434
2455
|
const p = (c = M == null ? void 0 : M.data) == null ? void 0 : c.features.filter((o) => o.geometry.type === "LineString" && o.properties.type === "forecast"), b = [];
|
|
2435
2456
|
for (const o of p) {
|
|
2436
|
-
const Y = o.properties.name, d = o.properties.model, R = o.properties.showCircle, T = o.properties.disabled,
|
|
2437
|
-
let
|
|
2438
|
-
const
|
|
2439
|
-
(
|
|
2457
|
+
const Y = o.properties.name, d = o.properties.model, R = o.properties.showCircle, T = o.properties.disabled, f = B(o.properties.date).utc();
|
|
2458
|
+
let i = z * 60;
|
|
2459
|
+
const e = (O = M == null ? void 0 : M.data) == null ? void 0 : O.features.filter(
|
|
2460
|
+
(Z) => Z.geometry.type === "Point" && Z.properties.type === "forecast" && Z.properties.category === `${Y}-${d}`
|
|
2440
2461
|
);
|
|
2441
|
-
let
|
|
2442
|
-
for (;
|
|
2443
|
-
if (
|
|
2444
|
-
const
|
|
2462
|
+
let t, l = f.clone().add(i, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
2463
|
+
for (; t = this.pickIndex(e, l), t <= e.length - 1; ) {
|
|
2464
|
+
if (t > 0) {
|
|
2465
|
+
const Z = e[t], u = t === 0 ? void 0 : e[t - 1], G = (i / 60 - ((A = u == null ? void 0 : u.properties) == null ? void 0 : A.hour)) / (Z.properties.hour - ((W = u == null ? void 0 : u.properties) == null ? void 0 : W.hour)), H = this.computeNumber(u == null ? void 0 : u.geometry.coordinates[0], Z.geometry.coordinates[0], G), F = this.computeNumber(u == null ? void 0 : u.geometry.coordinates[1], Z.geometry.coordinates[1], G), $ = S.point([H, F], {
|
|
2445
2466
|
name: Y,
|
|
2446
2467
|
model: d,
|
|
2447
|
-
category:
|
|
2448
|
-
date:
|
|
2449
|
-
format:
|
|
2450
|
-
gusts: this.computeNumber(
|
|
2451
|
-
hour: this.computeNumber(
|
|
2452
|
-
movement: this.computeNumber(
|
|
2453
|
-
pressure: this.computeNumber(
|
|
2454
|
-
wind: this.computeNumber(
|
|
2468
|
+
category: Z == null ? void 0 : Z.properties.category,
|
|
2469
|
+
date: l.format(),
|
|
2470
|
+
format: l.format("MMM-DD/HHmm[Z]"),
|
|
2471
|
+
gusts: this.computeNumber(u == null ? void 0 : u.properties.gusts, Z.properties.gusts, G),
|
|
2472
|
+
hour: this.computeNumber(u == null ? void 0 : u.properties.hour, Z.properties.hour, G),
|
|
2473
|
+
movement: this.computeNumber(u == null ? void 0 : u.properties.movement, Z.properties.movement, G),
|
|
2474
|
+
pressure: this.computeNumber(u == null ? void 0 : u.properties.pressure, Z.properties.pressure, G),
|
|
2475
|
+
wind: this.computeNumber(u == null ? void 0 : u.properties.wind, Z.properties.wind, G),
|
|
2455
2476
|
type: "forecast",
|
|
2456
2477
|
disabled: T,
|
|
2457
2478
|
showCircle: R
|
|
2458
2479
|
});
|
|
2459
2480
|
b.push($);
|
|
2460
2481
|
}
|
|
2461
|
-
|
|
2482
|
+
i += z * 60, l = f.clone().add(i, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
2462
2483
|
}
|
|
2463
2484
|
}
|
|
2464
2485
|
return b;
|
|
@@ -2488,19 +2509,19 @@ class V0 {
|
|
|
2488
2509
|
const { t1: c, t2: O, hr: A, hours: W } = this.tropicalCenterTwin(z, 24, b);
|
|
2489
2510
|
if (c && O) {
|
|
2490
2511
|
if (!b.debug) {
|
|
2491
|
-
const
|
|
2492
|
-
if (
|
|
2493
|
-
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", b.requestId,
|
|
2512
|
+
const f = r.calculateDistance(M, c), i = r.calculateDistance(M, O);
|
|
2513
|
+
if (f > 2 * p && i > 2 * p)
|
|
2514
|
+
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", b.requestId, f, i, {
|
|
2494
2515
|
from: M,
|
|
2495
2516
|
t1: c,
|
|
2496
2517
|
t2: O,
|
|
2497
2518
|
hr: A
|
|
2498
2519
|
}), {};
|
|
2499
2520
|
}
|
|
2500
|
-
const o =
|
|
2521
|
+
const o = r.calculateBearing(M, c), Y = r.calculateBearing(c, O), d = Math.abs(o - Y);
|
|
2501
2522
|
let R = 0;
|
|
2502
2523
|
d < 180 ? R = d + 90 : d >= 180 && (R = d - 90);
|
|
2503
|
-
const T =
|
|
2524
|
+
const T = r.calculateCoordinate(c, R, p);
|
|
2504
2525
|
return I == null || I.info("[%s] the right tangent position: %j", b.requestId, {
|
|
2505
2526
|
from: M,
|
|
2506
2527
|
t1: c,
|
|
@@ -2527,17 +2548,17 @@ class V0 {
|
|
|
2527
2548
|
const { t1: c, t2: O, hr: A, hours: W } = this.tropicalCenterTwin(z, 24, b);
|
|
2528
2549
|
if (c && O) {
|
|
2529
2550
|
if (!b.debug) {
|
|
2530
|
-
const T =
|
|
2531
|
-
if (T > 2 * p &&
|
|
2532
|
-
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", b.requestId, T,
|
|
2551
|
+
const T = r.calculateDistance(M, c), f = r.calculateDistance(M, O);
|
|
2552
|
+
if (T > 2 * p && f > 2 * p)
|
|
2553
|
+
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", b.requestId, T, f, {
|
|
2533
2554
|
from: M,
|
|
2534
2555
|
t1: c,
|
|
2535
2556
|
t2: O,
|
|
2536
2557
|
hr: A
|
|
2537
2558
|
}), {};
|
|
2538
2559
|
}
|
|
2539
|
-
const o =
|
|
2540
|
-
return { at:
|
|
2560
|
+
const o = r.calculateBearing(M, c), Y = r.calculateBearing(c, O), d = r.calculateDistance(M, c);
|
|
2561
|
+
return { at: r.calculateCoordinate(c, o - Y + 180, p < d ? p : d), t1: c, t2: O, hr: Number(A), hours: W };
|
|
2541
2562
|
} else
|
|
2542
2563
|
return I == null || I.info("[%s] no need drift: %j", b.requestId, { from: M, t1: c, t2: O, hr: A }), {};
|
|
2543
2564
|
}
|
|
@@ -2550,20 +2571,20 @@ class V0 {
|
|
|
2550
2571
|
* @private
|
|
2551
2572
|
*/
|
|
2552
2573
|
static tropicalCenterTwin(M, z = 24, p = {}) {
|
|
2553
|
-
var Y, d, R, T,
|
|
2574
|
+
var Y, d, R, T, f;
|
|
2554
2575
|
let b = {};
|
|
2555
|
-
(Y = M.forecasts) == null || Y.forEach((
|
|
2556
|
-
b = { ...
|
|
2576
|
+
(Y = M.forecasts) == null || Y.forEach((i) => {
|
|
2577
|
+
b = { ...i.hours, ...b };
|
|
2557
2578
|
});
|
|
2558
2579
|
const c = ((d = M == null ? void 0 : M.history) == null ? void 0 : d[0]) || (b == null ? void 0 : b[(R = Object.keys(b)) == null ? void 0 : R[0]]);
|
|
2559
2580
|
I == null || I.info("[%s] the first tropical center: %j", p.requestId, c);
|
|
2560
|
-
let O = (T = Object.keys(b || {}).filter((
|
|
2561
|
-
O || (O = (
|
|
2581
|
+
let O = (T = Object.keys(b || {}).filter((i) => Number(i) <= (z < 0 ? 24 : z))) == null ? void 0 : T.at(-1);
|
|
2582
|
+
O || (O = (f = Object.keys(b || {}).filter((i) => Number(i) <= (z < 0 ? 24 : 2 * z))) == null ? void 0 : f.at(-1));
|
|
2562
2583
|
const A = b == null ? void 0 : b[O || -1];
|
|
2563
2584
|
I == null || I.info("[%s] the second tropical center: %j in %d hrs", p.requestId, A, O);
|
|
2564
|
-
const W = Object.keys(b || {}).filter((
|
|
2565
|
-
for (const
|
|
2566
|
-
o[
|
|
2585
|
+
const W = Object.keys(b || {}).filter((i) => Number(i) <= Number(O)), o = { 0: c };
|
|
2586
|
+
for (const i of W)
|
|
2587
|
+
o[i] = b[i];
|
|
2567
2588
|
return { t1: c, t2: A, hr: Number(O), hours: o };
|
|
2568
2589
|
}
|
|
2569
2590
|
static pickIndex(M, z) {
|
|
@@ -2593,7 +2614,7 @@ class V0 {
|
|
|
2593
2614
|
}
|
|
2594
2615
|
export {
|
|
2595
2616
|
t0 as AisHelper,
|
|
2596
|
-
|
|
2617
|
+
r as LaneHelper,
|
|
2597
2618
|
a as LngLatHelper,
|
|
2598
2619
|
V0 as TropicalHelper
|
|
2599
2620
|
};
|