@idm-plugin/geo 2.1.1 → 2.1.3
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 +271 -248
- package/dist/index.umd.cjs +7 -6
- package/dist/lane/src/index.d.ts +28 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as t from "@turf/turf";
|
|
2
|
+
import U 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 : {};
|
|
5
5
|
function X0(m) {
|
|
@@ -13,7 +13,7 @@ var _ = { exports: {} };
|
|
|
13
13
|
//! license : MIT
|
|
14
14
|
//! github.com/moment/moment-timezone
|
|
15
15
|
(function(M, z) {
|
|
16
|
-
m.exports ? m.exports = z(
|
|
16
|
+
m.exports ? m.exports = z(U) : z(M.moment);
|
|
17
17
|
})(n0, function(M) {
|
|
18
18
|
M.version === void 0 && M.default && (M = M.default);
|
|
19
19
|
var z = "0.5.48", p = {}, b = {}, c = {}, O = {}, A = {}, W;
|
|
@@ -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] || "",
|
|
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] || "", V = 1, E, s = 0, P = 1;
|
|
28
|
+
for (q.charCodeAt(0) === 45 && (n = 1, P = -1), n; n < L.length; n++)
|
|
29
|
+
E = R(L.charCodeAt(n)), s = 60 * s + E;
|
|
30
30
|
for (n = 0; n < N.length; n++)
|
|
31
|
-
|
|
32
|
-
return
|
|
31
|
+
V = V / 60, E = R(N.charCodeAt(n)), s += E * V;
|
|
32
|
+
return s * P;
|
|
33
33
|
}
|
|
34
|
-
function
|
|
34
|
+
function e(q) {
|
|
35
35
|
for (var n = 0; n < q.length; n++)
|
|
36
36
|
q[n] = T(q[n]);
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function f(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 i(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 S(q) {
|
|
50
50
|
var n = q.split("|"), X = n[2].split(" "), L = n[3].split(""), N = n[4].split(" ");
|
|
51
|
-
return
|
|
51
|
+
return e(X), e(L), e(N), f(N, L.length), {
|
|
52
52
|
name: n[0],
|
|
53
|
-
abbrs:
|
|
54
|
-
offsets:
|
|
53
|
+
abbrs: i(n[1].split(" "), L),
|
|
54
|
+
offsets: i(X, L),
|
|
55
55
|
untils: N,
|
|
56
56
|
population: n[5] | 0
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
function
|
|
60
|
-
q && this._set(
|
|
59
|
+
function u(q) {
|
|
60
|
+
q && this._set(S(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;
|
|
@@ -67,17 +67,17 @@ var _ = { exports: {} };
|
|
|
67
67
|
return X - 1;
|
|
68
68
|
if (q >= n[X - 1])
|
|
69
69
|
return -1;
|
|
70
|
-
for (var L, N = 0,
|
|
71
|
-
L = Math.floor((N +
|
|
72
|
-
return
|
|
70
|
+
for (var L, N = 0, V = X - 1; V - N > 1; )
|
|
71
|
+
L = Math.floor((N + V) / 2), n[L] <= q ? N = L : V = L;
|
|
72
|
+
return V;
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
u.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,
|
|
91
|
-
for (
|
|
92
|
-
if (
|
|
93
|
-
return X[
|
|
90
|
+
var n = +q, X = this.offsets, L = this.untils, N = L.length - 1, V, E, s, P;
|
|
91
|
+
for (P = 0; P < N; P++)
|
|
92
|
+
if (V = X[P], E = X[P + 1], s = X[P && P - 1], V < E && l.moveAmbiguousForward ? V = E : V > s && l.moveInvalidForward && (V = s), n < L[P] - V * 6e4)
|
|
93
|
+
return X[P];
|
|
94
94
|
return X[N];
|
|
95
95
|
},
|
|
96
96
|
abbr: function(q) {
|
|
@@ -103,17 +103,17 @@ var _ = { exports: {} };
|
|
|
103
103
|
return this.offsets[this._index(q)];
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
|
-
function
|
|
106
|
+
function B(q, n) {
|
|
107
107
|
this.name = q, this.zones = n;
|
|
108
108
|
}
|
|
109
109
|
function G(q) {
|
|
110
110
|
var n = q.toTimeString(), X = n.match(/\([a-z ]+\)/i);
|
|
111
111
|
X && X[0] ? (X = X[0].match(/[A-Z]/g), X = X ? X.join("") : void 0) : (X = n.match(/[A-Z]{3,5}/g), X = X ? X[0] : void 0), X === "GMT" && (X = void 0), this.at = +q, this.abbr = X, this.offset = q.getTimezoneOffset();
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function Q(q) {
|
|
114
114
|
this.zone = q, this.offsetScore = 0, this.abbrScore = 0;
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
Q.prototype.scoreOffsetAt = function(q) {
|
|
117
117
|
this.offsetScore += Math.abs(this.zone.utcOffset(q.at) - q.offset), this.zone.abbr(q.at).replace(/[^A-Z]/g, "") !== q.abbr && this.abbrScore++;
|
|
118
118
|
};
|
|
119
119
|
function F(q, n) {
|
|
@@ -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,
|
|
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, V, E, s;
|
|
126
|
+
for (s = 1; s < 48; s++)
|
|
127
|
+
E = new Date(q, s, 1).getTimezoneOffset(), E !== X && (V = new G(new Date(q, s, 1)), N = F(n, V), L.push(N), L.push(new G(new Date(N.at + 6e4))), n = V, X = E);
|
|
128
|
+
for (s = 0; s < 4; s++)
|
|
129
|
+
L.push(new G(new Date(q + s, 0, 1))), L.push(new G(new Date(q + s, 6, 1)));
|
|
130
130
|
return L;
|
|
131
131
|
}
|
|
132
132
|
function z0(q, n) {
|
|
@@ -134,20 +134,20 @@ var _ = { exports: {} };
|
|
|
134
134
|
}
|
|
135
135
|
function b0(q, n) {
|
|
136
136
|
var X, L;
|
|
137
|
-
for (
|
|
137
|
+
for (e(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 = {},
|
|
142
|
-
for (
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
for (E in
|
|
146
|
-
|
|
147
|
-
N[
|
|
141
|
+
var n = q.length, X = {}, L = [], N = {}, V, E, s, P;
|
|
142
|
+
for (V = 0; V < n; V++)
|
|
143
|
+
if (s = q[V].offset, !N.hasOwnProperty(s)) {
|
|
144
|
+
P = A[s] || {};
|
|
145
|
+
for (E in P)
|
|
146
|
+
P.hasOwnProperty(E) && (X[E] = !0);
|
|
147
|
+
N[s] = !0;
|
|
148
148
|
}
|
|
149
|
-
for (
|
|
150
|
-
X.hasOwnProperty(
|
|
149
|
+
for (V in X)
|
|
150
|
+
X.hasOwnProperty(V) && L.push(O[V]);
|
|
151
151
|
return L;
|
|
152
152
|
}
|
|
153
153
|
function O0() {
|
|
@@ -161,13 +161,13 @@ var _ = { exports: {} };
|
|
|
161
161
|
}
|
|
162
162
|
} catch {
|
|
163
163
|
}
|
|
164
|
-
var X = $(), L = X.length, N = p0(X),
|
|
165
|
-
for (
|
|
166
|
-
for (E = new
|
|
167
|
-
E.scoreOffsetAt(X[
|
|
168
|
-
|
|
164
|
+
var X = $(), L = X.length, N = p0(X), V = [], E, s, P;
|
|
165
|
+
for (s = 0; s < N.length; s++) {
|
|
166
|
+
for (E = new Q(g(N[s])), P = 0; P < L; P++)
|
|
167
|
+
E.scoreOffsetAt(X[P]);
|
|
168
|
+
V.push(E);
|
|
169
169
|
}
|
|
170
|
-
return
|
|
170
|
+
return V.sort(z0), V.length > 0 ? V[0].zone.name : void 0;
|
|
171
171
|
}
|
|
172
172
|
function A0(q) {
|
|
173
173
|
return (!W || q) && (W = O0()), W;
|
|
@@ -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 u ? X : typeof X == "string" ? (X = new u(X), p[q] = X, X) : b[q] && n !== g && (L = g(b[q], g)) ? (X = p[q] = new u(), 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 B(
|
|
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), l.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 l(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
|
+
l.version = z, l.dataVersion = "", l._zones = p, l._links = b, l._names = O, l._countries = c, l.add = k, l.link = y, l.load = d0, l.zone = g, l.zoneExists = J, l.guess = A0, l.names = c0, l.Zone = u, l.unpack = S, l.unpackBase60 = T, l.needsOffset = v, l.moveInvalidForward = !0, l.moveAmbiguousForward = !1, l.countries = W0, l.zonesForCountry = Y0;
|
|
244
244
|
var C = M.fn;
|
|
245
|
-
M.tz =
|
|
245
|
+
M.tz = l, 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
|
* 基于输入的经度,计算出时区
|
|
@@ -1162,7 +1162,7 @@ class a {
|
|
|
1162
1162
|
*/
|
|
1163
1163
|
static guessTimeZoneOffset(M, z) {
|
|
1164
1164
|
M = a.convertToStdLng(M);
|
|
1165
|
-
const p = S0(z, M), b =
|
|
1165
|
+
const p = S0(z, M), b = U().tz(p).utcOffset();
|
|
1166
1166
|
return a.roundPrecision(b / 60, 1);
|
|
1167
1167
|
}
|
|
1168
1168
|
/**
|
|
@@ -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);
|
|
@@ -1364,18 +1364,18 @@ class t0 {
|
|
|
1364
1364
|
lng: O.lng,
|
|
1365
1365
|
sog: O.sog,
|
|
1366
1366
|
positionTime: O.positionTime,
|
|
1367
|
-
utc:
|
|
1367
|
+
utc: U.unix(O.positionTime).utc().format()
|
|
1368
1368
|
},
|
|
1369
1369
|
end: {
|
|
1370
1370
|
lat: A.lat,
|
|
1371
1371
|
lng: A.lng,
|
|
1372
1372
|
sog: A.sog,
|
|
1373
1373
|
positionTime: A.positionTime,
|
|
1374
|
-
utc:
|
|
1374
|
+
utc: U.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
|
}
|
|
@@ -1389,25 +1389,25 @@ class t0 {
|
|
|
1389
1389
|
* @param etm
|
|
1390
1390
|
*/
|
|
1391
1391
|
static inspectSummary(M, z, p) {
|
|
1392
|
-
const b =
|
|
1392
|
+
const b = U(z), c = U(p), O = M.filter((Y) => Y.positionTime >= b.unix() && Y.positionTime <= c.unix());
|
|
1393
1393
|
let A = 0, W = 0;
|
|
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;
|
|
1401
1401
|
return { distance: A, interval: W, avgSpd: o };
|
|
1402
1402
|
}
|
|
1403
1403
|
}
|
|
1404
|
-
let
|
|
1404
|
+
let H;
|
|
1405
1405
|
try {
|
|
1406
|
-
|
|
1406
|
+
H = j.getLogger("meteo");
|
|
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 = t.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 = t.rhumbBearing(c.features[0], c.features[1]) : O = t.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 = t.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 = t.rhumbDistance(O.features[0], O.features[1], { units: c }) : A = t.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 = t.point([M.lng, M.lat]);
|
|
1472
1472
|
let A;
|
|
1473
|
-
c ? A =
|
|
1473
|
+
c ? A = t.rhumbDestination(O, p, z, { units: b }) : A = t.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 = t.lineString(Y), R = t.lineString([
|
|
1523
1523
|
[o > 0 ? 180 : -180, 89],
|
|
1524
1524
|
[o > 0 ? 180 : -180, -89]
|
|
1525
|
-
])) : (d =
|
|
1526
|
-
const T =
|
|
1527
|
-
let
|
|
1525
|
+
])) : (d = t.greatCircle(Y[0], Y[1]), R = t.greatCircle([o > 0 ? 180 : -180, 89], [o > 0 ? 180 : -180, -89]));
|
|
1526
|
+
const T = t.lineIntersect(d, R);
|
|
1527
|
+
let e;
|
|
1528
1528
|
if (T.features.length) {
|
|
1529
|
-
const
|
|
1530
|
-
|
|
1529
|
+
const f = t.getCoord(T.features[0]);
|
|
1530
|
+
e = a.roundPrecision(f[1], 8);
|
|
1531
1531
|
} else
|
|
1532
|
-
|
|
1533
|
-
o > 0 ? (b.push([180 - 1e-6,
|
|
1532
|
+
e = M[W].lat;
|
|
1533
|
+
o > 0 ? (b.push([180 - 1e-6, e]), c.push([...b]), b = [], b.push([-(180 - 1e-6), e])) : (b.push([-(180 - 1e-6), e]), c.push([...b]), b = [], b.push([180 - 1e-6, e]));
|
|
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 = t.lineString([
|
|
1745
1745
|
[z.lng, z.lat],
|
|
1746
1746
|
[p.lng, p.lat]
|
|
1747
|
-
]), A =
|
|
1747
|
+
]), A = t.pointToLineDistance(t.point([M.lng, M.lat]), O, b), W = t.pointToLineDistance(t.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 = t.point([M.lng, M.lat]), c = this.convertRouteToCoordinates(z).map((o) => [o.lng, o.lat]), O = t.lineString(c), A = t.nearestPointOnLine(O, p), W = t.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, e) => {
|
|
1869
1869
|
if (W)
|
|
1870
1870
|
A.push(T);
|
|
1871
1871
|
else {
|
|
1872
|
-
const
|
|
1873
|
-
let
|
|
1874
|
-
for (let
|
|
1872
|
+
const f = [];
|
|
1873
|
+
let i;
|
|
1874
|
+
for (let S = 0; S < T.length; S++)
|
|
1875
1875
|
if (d)
|
|
1876
|
-
|
|
1876
|
+
f.push(T[S]);
|
|
1877
1877
|
else {
|
|
1878
|
-
|
|
1879
|
-
const
|
|
1880
|
-
if (o +=
|
|
1881
|
-
Y +=
|
|
1878
|
+
i = { lng: T[S][0], lat: T[S][1] };
|
|
1879
|
+
const u = this.calculateDistance(M, i, !0, 8, b);
|
|
1880
|
+
if (o += u, o < z)
|
|
1881
|
+
Y += u, u && O.push(i), M = i;
|
|
1882
1882
|
else {
|
|
1883
1883
|
if (Y = z, o === z)
|
|
1884
|
-
d =
|
|
1884
|
+
d = i, f.push([d.lng, d.lat]);
|
|
1885
1885
|
else {
|
|
1886
|
-
const
|
|
1887
|
-
d = this.calculateCoordinate(
|
|
1886
|
+
const Z = o - z, B = this.calculateBearing(i, M);
|
|
1887
|
+
d = this.calculateCoordinate(i, B, Z, b), f.push([d.lng, d.lat]), f.push([i.lng, i.lat]);
|
|
1888
1888
|
}
|
|
1889
1889
|
W = !0;
|
|
1890
1890
|
}
|
|
1891
1891
|
}
|
|
1892
|
-
|
|
1892
|
+
f.length && A.push(f), e === p.length - 1 && !d && (d = i);
|
|
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 = t.point([b, M.lat]), O = a.convertToStdLng(z.lng, 6), A = a.convertToStdLng(p.lng, 6), W = t.lineString([
|
|
1910
1910
|
[O, z.lat],
|
|
1911
1911
|
[A, p.lat]
|
|
1912
|
-
]), o =
|
|
1912
|
+
]), o = t.nearestPointOnLine(W, c), Y = t.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 = t.featureCollection([]), b = a.convertToMonotonicLng2(z);
|
|
1982
1982
|
for (const A of b)
|
|
1983
|
-
p.features.push(
|
|
1984
|
-
const O =
|
|
1983
|
+
p.features.push(t.point(A));
|
|
1984
|
+
const O = t.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 = t.lineString(p);
|
|
2005
|
+
return t.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), e = (Math.pow(d, 2) + Math.pow(R, 2) - Math.pow(T, 2)) / (2 * d * R);
|
|
2028
|
+
Math.round(Math.acos(e) * 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);
|
|
@@ -2041,7 +2041,7 @@ class i {
|
|
|
2041
2041
|
* @param waypoints 带时间的轨迹, 单位秒
|
|
2042
2042
|
*/
|
|
2043
2043
|
static nearestTSPointInWaypoints(M, z, p) {
|
|
2044
|
-
const b =
|
|
2044
|
+
const b = U.unix(M), c = p.filter(
|
|
2045
2045
|
(O) => b.clone().subtract(z, "hour").unix() <= (O.positionTime || 0) && b.clone().add(z, "h").unix() >= (O.positionTime || 0)
|
|
2046
2046
|
);
|
|
2047
2047
|
return c.sort((O, A) => (O.positionTime || 0) - (A.positionTime || 0)), c.at(-1);
|
|
@@ -2054,15 +2054,15 @@ class i {
|
|
|
2054
2054
|
static deadReckoning(M, z) {
|
|
2055
2055
|
var c, O, A, W;
|
|
2056
2056
|
M > 1e12 && (M = Math.round(M / 1e3));
|
|
2057
|
-
const p =
|
|
2057
|
+
const p = U.unix(M);
|
|
2058
2058
|
let b = z.find((o) => o.positionTime === p.unix());
|
|
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
|
-
b = o || Y, b && (b.utc =
|
|
2065
|
+
b = o || Y, b && (b.utc = U.unix(b == null ? void 0 : b.positionTime).utc().format());
|
|
2066
2066
|
}
|
|
2067
2067
|
return b;
|
|
2068
2068
|
}
|
|
@@ -2075,19 +2075,19 @@ 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
|
-
return M.utc = M.positionTime ?
|
|
2090
|
+
return M.utc = M.positionTime ? U.unix(M.positionTime).utc().format() : void 0, M.positionTime ? M : void 0;
|
|
2091
2091
|
}
|
|
2092
2092
|
/**
|
|
2093
2093
|
* 翻转轨迹
|
|
@@ -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,83 @@ 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(U.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
|
+
* @param name 兼容旧版本
|
|
2164
2165
|
* @param waypoints 途径点
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2166
|
+
* @param options.precision 经纬度小数位数,默认6
|
|
2167
|
+
*/
|
|
2168
|
+
static waypoints2CSV(M, z, p) {
|
|
2169
|
+
H.debug("keep name for waypoints2CSV for legacy compatibility only", M);
|
|
2170
|
+
const b = (p == null ? void 0 : p.precision) ?? 6, c = z.some((i) => i.name), O = z.some((i) => i.description), A = z.some((i) => i.port != null), W = z.some((i) => i.stbd != null), o = z.some((i) => i.arrRad != null), Y = z.some((i) => i.speed != null), d = z.some((i, S) => S > 0 && i.gcToPrevious != null), R = z.some((i) => i.bearing != null), T = z.some((i) => i.distanceFromPrevious != null), e = ["WPT No.", "Latitude", "Longitude"];
|
|
2171
|
+
c && e.push("Name"), O && e.push("Description"), d && e.push("Leg"), R && e.push("Bearing[deg]"), T && e.push("Distance[NM]"), Y && e.push("Speed[kn]"), A && e.push("PORT XTD[NM]"), W && e.push("STBD XTD[NM]"), o && e.push("Arr.Rad[NM]");
|
|
2172
|
+
const f = [];
|
|
2173
|
+
f.push(e.map((i) => r.csvEscapeField(i)).join(","));
|
|
2174
|
+
for (let i = 0; i < z.length; i++) {
|
|
2175
|
+
const S = z[i], u = [];
|
|
2176
|
+
u.push((i + 1).toString()), u.push(S.lat.toFixed(b)), u.push(S.lng.toFixed(b)), c && u.push(S.name ?? ""), O && u.push(S.description ?? ""), d && u.push(i === 0 ? "" : S.gcToPrevious ? "GC" : "RL"), R && u.push(S.bearing != null ? String(S.bearing) : ""), T && u.push(S.distanceFromPrevious != null ? String(S.distanceFromPrevious) : ""), Y && u.push(S.speed != null ? String(S.speed) : ""), A && u.push(S.port != null ? String(S.port) : ""), W && u.push(S.stbd != null ? String(S.stbd) : ""), o && u.push(S.arrRad != null ? String(S.arrRad) : ""), f.push(u.map((Z) => r.csvEscapeField(Z)).join(","));
|
|
2172
2177
|
}
|
|
2173
|
-
return
|
|
2178
|
+
return f.join(`
|
|
2174
2179
|
`);
|
|
2175
2180
|
}
|
|
2176
2181
|
/**
|
|
2177
|
-
*
|
|
2178
|
-
|
|
2182
|
+
* RFC 4180 CSV字段转义:含逗号、双引号、换行时用双引号包裹,内部双引号翻倍
|
|
2183
|
+
*/
|
|
2184
|
+
static csvEscapeField(M) {
|
|
2185
|
+
if (M == null)
|
|
2186
|
+
return "";
|
|
2187
|
+
const z = String(M);
|
|
2188
|
+
return z.includes(",") || z.includes('"') || z.includes(`
|
|
2189
|
+
`) || z.includes("\r") ? `"${z.replace(/"/g, '""')}"` : z;
|
|
2190
|
+
}
|
|
2191
|
+
/**
|
|
2192
|
+
* 十进制度数转NMEA度分格式 (DDMM.MM / DDDMM.MM)
|
|
2193
|
+
* @param value 十进制度数
|
|
2194
|
+
* @param isLat true为纬度,false为经度
|
|
2195
|
+
*/
|
|
2196
|
+
static decimalToNmeaDm(M, z) {
|
|
2197
|
+
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";
|
|
2198
|
+
return { dm: O, dir: A };
|
|
2199
|
+
}
|
|
2200
|
+
/**
|
|
2201
|
+
* 计算NMEA 0183校验和 ($与*之间所有字符的异或,两字符十六进制大写)
|
|
2202
|
+
* @param sentence $与*之间的字符串
|
|
2203
|
+
*/
|
|
2204
|
+
static nmeaChecksum(M) {
|
|
2205
|
+
let z = 0;
|
|
2206
|
+
for (let p = 0; p < M.length; p++)
|
|
2207
|
+
z ^= M.charCodeAt(p);
|
|
2208
|
+
return z.toString(16).toUpperCase().padStart(2, "0");
|
|
2209
|
+
}
|
|
2210
|
+
/**
|
|
2211
|
+
* 路径转NMEA 0183 WPL航点语句
|
|
2179
2212
|
* @param waypoints 途径点
|
|
2213
|
+
* @returns 多条$GPWPL语句,以\r\n分隔
|
|
2180
2214
|
*/
|
|
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>");
|
|
2215
|
+
static waypoints2NMEA(M) {
|
|
2216
|
+
const z = [];
|
|
2217
|
+
for (let p = 0; p < M.length; p++) {
|
|
2218
|
+
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);
|
|
2219
|
+
z.push(`$${W}*${o}`);
|
|
2197
2220
|
}
|
|
2198
|
-
return
|
|
2221
|
+
return z.join(`\r
|
|
2199
2222
|
`);
|
|
2200
2223
|
}
|
|
2201
2224
|
/**
|
|
@@ -2212,8 +2235,8 @@ class i {
|
|
|
2212
2235
|
*/
|
|
2213
2236
|
static coordinatesSummary(M, z = 3) {
|
|
2214
2237
|
if (M.length > 1) {
|
|
2215
|
-
const p = M[0], b = M[M.length - 1], c = (p == null ? void 0 : p.positionTime) < (b == null ? void 0 : b.positionTime) ?
|
|
2216
|
-
(T,
|
|
2238
|
+
const p = M[0], b = M[M.length - 1], c = (p == null ? void 0 : p.positionTime) < (b == null ? void 0 : b.positionTime) ? U.unix(p == null ? void 0 : p.positionTime) : U.unix(b == null ? void 0 : b.positionTime), O = (p == null ? void 0 : p.positionTime) > (b == null ? void 0 : b.positionTime) ? U.unix(p == null ? void 0 : p.positionTime) : U.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(
|
|
2239
|
+
(T, e) => (T.duration += e.duration, T.distance += e.distance, T),
|
|
2217
2240
|
{ hours: 0, distance: 0, spd: 0, duration: 0 }
|
|
2218
2241
|
);
|
|
2219
2242
|
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;
|
|
@@ -2248,21 +2271,21 @@ class i {
|
|
|
2248
2271
|
var Y, d, R;
|
|
2249
2272
|
if (!((d = (Y = z == null ? void 0 : z.sample) == null ? void 0 : Y.hours) != null && d.length))
|
|
2250
2273
|
return { routes: [], hour: void 0 };
|
|
2251
|
-
const p = z.sample.hours.at(0), b =
|
|
2274
|
+
const p = z.sample.hours.at(0), b = U.utc(M), c = U.utc(z.eta), O = b.isAfter(c) ? c : b;
|
|
2252
2275
|
let A = z.sample.all.find((T) => T.eta === O.format());
|
|
2253
2276
|
if (!A) {
|
|
2254
|
-
const T = z.sample.all.filter((G) =>
|
|
2255
|
-
A = (R = this.calculateNextCoordinateAlongRoute(T, T.speed * O.diff(
|
|
2256
|
-
const { cFactor:
|
|
2277
|
+
const T = z.sample.all.filter((G) => U.utc(G.eta).isBefore(O)).at(-1), e = this.calculateSubRoute(T, z.route);
|
|
2278
|
+
A = (R = this.calculateNextCoordinateAlongRoute(T, T.speed * O.diff(U(T.etd), "hours", !0), e)) == null ? void 0 : R.coordinate;
|
|
2279
|
+
const { cFactor: f, cog: i, wxFactor: S, meteo: u } = T, Z = Math.round(A.distanceFromPrevious * 1e4) / 1e4, B = Math.round((Z + T.distanceFromStart) * 1e4) / 1e4;
|
|
2257
2280
|
A = {
|
|
2258
2281
|
...A,
|
|
2259
|
-
cFactor:
|
|
2260
|
-
cog:
|
|
2282
|
+
cFactor: f,
|
|
2283
|
+
cog: i,
|
|
2261
2284
|
speed: T.speed,
|
|
2262
|
-
wxFactor:
|
|
2263
|
-
distanceFromStart:
|
|
2264
|
-
distanceFromPrevious:
|
|
2265
|
-
meteo:
|
|
2285
|
+
wxFactor: S,
|
|
2286
|
+
distanceFromStart: B,
|
|
2287
|
+
distanceFromPrevious: Z,
|
|
2288
|
+
meteo: u,
|
|
2266
2289
|
eta: O.format(),
|
|
2267
2290
|
etd: O.format()
|
|
2268
2291
|
};
|
|
@@ -2286,10 +2309,10 @@ class i {
|
|
|
2286
2309
|
*/
|
|
2287
2310
|
static pickUTCSampleFromRoute(M, z, p) {
|
|
2288
2311
|
var T;
|
|
2289
|
-
const b = this.calculateSubRoute(z, p), c = this.calculateRouteDistance(b), O = c / z.speed, A =
|
|
2312
|
+
const b = this.calculateSubRoute(z, p), c = this.calculateRouteDistance(b), O = c / z.speed, A = U.utc(M), W = U(z.etd), o = (T = this.calculateNextCoordinateAlongRoute(z, z.speed * A.diff(U(z.etd), "hours", !0), b)) == null ? void 0 : T.coordinate;
|
|
2290
2313
|
o.speed = z.speed;
|
|
2291
2314
|
const Y = W.clone().add(o.hourFromPrevious, "hour");
|
|
2292
|
-
o.eta = Math.abs(Y.diff(A, "second")) < 2 ? A.format() : Y.format(), o.etd = o.eta, o.distanceFromStart = Math.round(o.distanceFromPrevious * 100) / 100, o.distanceToGo = Math.round((c - o.distanceFromStart) * 100) / 100, o.timeToGo = Math.round(W.clone().add(O, "hour").diff(
|
|
2315
|
+
o.eta = Math.abs(Y.diff(A, "second")) < 2 ? A.format() : Y.format(), o.etd = o.eta, o.distanceFromStart = Math.round(o.distanceFromPrevious * 100) / 100, o.distanceToGo = Math.round((c - o.distanceFromStart) * 100) / 100, o.timeToGo = Math.round(W.clone().add(O, "hour").diff(U(o.etd), "hour") * 100) / 100;
|
|
2293
2316
|
const d = this.calculateRangeWaypoints(z, o, p);
|
|
2294
2317
|
return {
|
|
2295
2318
|
routes: this.generateRouteAccordingToWaypoints(d),
|
|
@@ -2302,7 +2325,7 @@ class i {
|
|
|
2302
2325
|
* @param degree 要素角度,如 swell.degree
|
|
2303
2326
|
*/
|
|
2304
2327
|
static includedAngle(M, z) {
|
|
2305
|
-
|
|
2328
|
+
H == null || H.debug("calculate bearing via: %j", { bearing: M, degree: z });
|
|
2306
2329
|
let p = Math.abs(M % 360 - (z % 360 || 0));
|
|
2307
2330
|
return p = p > 180 ? 360 - p : p, p;
|
|
2308
2331
|
}
|
|
@@ -2320,80 +2343,80 @@ class V0 {
|
|
|
2320
2343
|
*/
|
|
2321
2344
|
static convert2Geojson(M) {
|
|
2322
2345
|
var p, b, c;
|
|
2323
|
-
const z =
|
|
2346
|
+
const z = t.featureCollection([]);
|
|
2324
2347
|
for (const O of M) {
|
|
2325
2348
|
const A = (p = O.history) == null ? void 0 : p[0];
|
|
2326
2349
|
if (O.forecasts) {
|
|
2327
2350
|
A && A.wind && (A.wind.kts = A.kts);
|
|
2328
2351
|
for (const W of O.forecasts) {
|
|
2329
2352
|
let o;
|
|
2330
|
-
const Y = [], d = [], R =
|
|
2331
|
-
for (const
|
|
2332
|
-
const
|
|
2333
|
-
o = o ||
|
|
2334
|
-
const
|
|
2353
|
+
const Y = [], d = [], R = U(W.date).utc(), T = `${O.name}-${W.model}`;
|
|
2354
|
+
for (const f in W == null ? void 0 : W.hours) {
|
|
2355
|
+
const i = W.hours[f];
|
|
2356
|
+
o = o || i;
|
|
2357
|
+
const S = R.clone().add(Number(f), "hour"), u = t.point([i.lng, i.lat], {
|
|
2335
2358
|
model: W.model,
|
|
2336
2359
|
name: O.name,
|
|
2337
2360
|
nameCn: O.nameCn,
|
|
2338
|
-
date:
|
|
2339
|
-
hour: Number(
|
|
2340
|
-
format:
|
|
2341
|
-
pressure:
|
|
2342
|
-
gusts:
|
|
2343
|
-
wind:
|
|
2344
|
-
movement:
|
|
2361
|
+
date: S.format(),
|
|
2362
|
+
hour: Number(f),
|
|
2363
|
+
format: S.format("MMM-DD/HHmm[Z]"),
|
|
2364
|
+
pressure: i.pressure > 1e4 ? a.roundPrecision(i.pressure / 100, 0) : a.roundPrecision(i.pressure, 0),
|
|
2365
|
+
gusts: i.gusts,
|
|
2366
|
+
wind: i.wind || {},
|
|
2367
|
+
movement: i.movement,
|
|
2345
2368
|
category: T,
|
|
2346
2369
|
type: "forecast"
|
|
2347
2370
|
});
|
|
2348
|
-
d.push(
|
|
2371
|
+
d.push(u), Y.push(u.geometry.coordinates);
|
|
2349
2372
|
}
|
|
2350
|
-
const
|
|
2373
|
+
const e = {
|
|
2351
2374
|
kts: void 0,
|
|
2352
2375
|
deg: void 0
|
|
2353
2376
|
};
|
|
2354
2377
|
if (A) {
|
|
2355
|
-
const
|
|
2378
|
+
const f = U(A.updated).utc();
|
|
2356
2379
|
if (o) {
|
|
2357
|
-
const
|
|
2358
|
-
|
|
2380
|
+
const S = r.calculateDistance(A, o), u = U(o.utc || o.updated).diff(f, "h", !0);
|
|
2381
|
+
e.kts = Math.round(S / u * 100) / 100, e.deg = r.calculateBearing(A, o, !0, 0);
|
|
2359
2382
|
}
|
|
2360
|
-
const
|
|
2383
|
+
const i = t.point([A.lng, A.lat], {
|
|
2361
2384
|
model: W.model,
|
|
2362
2385
|
name: O.name,
|
|
2363
2386
|
nameCn: O.nameCn,
|
|
2364
|
-
date:
|
|
2387
|
+
date: f.format(),
|
|
2365
2388
|
hour: 0,
|
|
2366
|
-
format:
|
|
2389
|
+
format: f.format("MMM-DD/HHmm[Z]"),
|
|
2367
2390
|
pressure: A.pressure > 1e4 ? a.roundPrecision((A == null ? void 0 : A.pressure) / 100, 0) : a.roundPrecision(A.pressure, 0),
|
|
2368
2391
|
wind: A.wind,
|
|
2369
|
-
movement:
|
|
2392
|
+
movement: e,
|
|
2370
2393
|
category: T,
|
|
2371
2394
|
type: "forecast",
|
|
2372
2395
|
important: !0
|
|
2373
2396
|
// 第一个预报点为重要点
|
|
2374
2397
|
});
|
|
2375
|
-
d.unshift(
|
|
2398
|
+
d.unshift(i), Y.unshift(i.geometry.coordinates);
|
|
2376
2399
|
}
|
|
2377
2400
|
if (z.features.push(...d), (Y == null ? void 0 : Y.length) > 1) {
|
|
2378
|
-
const
|
|
2401
|
+
const f = t.lineString(a.convertToMonotonicLng2(Y), {
|
|
2379
2402
|
date: (A == null ? void 0 : A.updated) || (R == null ? void 0 : R.format()),
|
|
2380
2403
|
id: O.id || O.name,
|
|
2381
2404
|
model: W.model,
|
|
2382
2405
|
name: O.name,
|
|
2383
2406
|
category: T,
|
|
2384
2407
|
type: "forecast",
|
|
2385
|
-
movement:
|
|
2408
|
+
movement: e
|
|
2386
2409
|
});
|
|
2387
|
-
z.features.push(
|
|
2410
|
+
z.features.push(f);
|
|
2388
2411
|
}
|
|
2389
2412
|
}
|
|
2390
2413
|
}
|
|
2391
|
-
if (z.features.sort((W, o) => W.properties.type === "forecast" && o.properties.type === "forecast" && W.geometry.type === "Point" && o.geometry.type === "Point" ?
|
|
2392
|
-
const W = [], o =
|
|
2414
|
+
if (z.features.sort((W, o) => W.properties.type === "forecast" && o.properties.type === "forecast" && W.geometry.type === "Point" && o.geometry.type === "Point" ? U(W.properties.date).valueOf() - U(o.properties.date).valueOf() : 0), (b = O.history) != null && b.length) {
|
|
2415
|
+
const W = [], o = U(A == null ? void 0 : A.updated).utc(), Y = U((c = O.history) == null ? void 0 : c.at(-1).updated).utc(), d = o.diff(Y, "h") % 24 > 2 ? 24 : 12;
|
|
2393
2416
|
for (const R of O.history) {
|
|
2394
|
-
const T =
|
|
2395
|
-
|
|
2396
|
-
const
|
|
2417
|
+
const T = U(R.updated).utc(), e = T.isSameOrBefore(o) || T.isSame(Y);
|
|
2418
|
+
e && o.add(-d, "h");
|
|
2419
|
+
const f = t.point([R.lng, R.lat], {
|
|
2397
2420
|
name: O.name,
|
|
2398
2421
|
nameCn: O.nameCn,
|
|
2399
2422
|
date: T.format(),
|
|
@@ -2405,12 +2428,12 @@ class V0 {
|
|
|
2405
2428
|
category: `${O.name}-history`,
|
|
2406
2429
|
wind: R.wind,
|
|
2407
2430
|
movement: R.movement,
|
|
2408
|
-
important:
|
|
2431
|
+
important: e
|
|
2409
2432
|
});
|
|
2410
|
-
z.features.push(
|
|
2433
|
+
z.features.push(f), W.push(f.geometry.coordinates);
|
|
2411
2434
|
}
|
|
2412
2435
|
if (W.length === 1 && W.push(W[0]), W.length > 1) {
|
|
2413
|
-
const R =
|
|
2436
|
+
const R = t.lineString(a.convertToMonotonicLng2(W), {
|
|
2414
2437
|
name: O.name,
|
|
2415
2438
|
type: "history",
|
|
2416
2439
|
updated: A == null ? void 0 : A.updated,
|
|
@@ -2433,32 +2456,32 @@ class V0 {
|
|
|
2433
2456
|
var c, O, A, W;
|
|
2434
2457
|
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
2458
|
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
|
-
(
|
|
2459
|
+
const Y = o.properties.name, d = o.properties.model, R = o.properties.showCircle, T = o.properties.disabled, e = U(o.properties.date).utc();
|
|
2460
|
+
let f = z * 60;
|
|
2461
|
+
const i = (O = M == null ? void 0 : M.data) == null ? void 0 : O.features.filter(
|
|
2462
|
+
(Z) => Z.geometry.type === "Point" && Z.properties.type === "forecast" && Z.properties.category === `${Y}-${d}`
|
|
2440
2463
|
);
|
|
2441
|
-
let
|
|
2442
|
-
for (;
|
|
2443
|
-
if (
|
|
2444
|
-
const
|
|
2464
|
+
let S, u = e.clone().add(f, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
2465
|
+
for (; S = this.pickIndex(i, u), S <= i.length - 1; ) {
|
|
2466
|
+
if (S > 0) {
|
|
2467
|
+
const Z = i[S], B = S === 0 ? void 0 : i[S - 1], G = (f / 60 - ((A = B == null ? void 0 : B.properties) == null ? void 0 : A.hour)) / (Z.properties.hour - ((W = B == null ? void 0 : B.properties) == null ? void 0 : W.hour)), Q = this.computeNumber(B == null ? void 0 : B.geometry.coordinates[0], Z.geometry.coordinates[0], G), F = this.computeNumber(B == null ? void 0 : B.geometry.coordinates[1], Z.geometry.coordinates[1], G), $ = t.point([Q, F], {
|
|
2445
2468
|
name: Y,
|
|
2446
2469
|
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(
|
|
2470
|
+
category: Z == null ? void 0 : Z.properties.category,
|
|
2471
|
+
date: u.format(),
|
|
2472
|
+
format: u.format("MMM-DD/HHmm[Z]"),
|
|
2473
|
+
gusts: this.computeNumber(B == null ? void 0 : B.properties.gusts, Z.properties.gusts, G),
|
|
2474
|
+
hour: this.computeNumber(B == null ? void 0 : B.properties.hour, Z.properties.hour, G),
|
|
2475
|
+
movement: this.computeNumber(B == null ? void 0 : B.properties.movement, Z.properties.movement, G),
|
|
2476
|
+
pressure: this.computeNumber(B == null ? void 0 : B.properties.pressure, Z.properties.pressure, G),
|
|
2477
|
+
wind: this.computeNumber(B == null ? void 0 : B.properties.wind, Z.properties.wind, G),
|
|
2455
2478
|
type: "forecast",
|
|
2456
2479
|
disabled: T,
|
|
2457
2480
|
showCircle: R
|
|
2458
2481
|
});
|
|
2459
2482
|
b.push($);
|
|
2460
2483
|
}
|
|
2461
|
-
|
|
2484
|
+
f += z * 60, u = e.clone().add(f, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
2462
2485
|
}
|
|
2463
2486
|
}
|
|
2464
2487
|
return b;
|
|
@@ -2488,19 +2511,19 @@ class V0 {
|
|
|
2488
2511
|
const { t1: c, t2: O, hr: A, hours: W } = this.tropicalCenterTwin(z, 24, b);
|
|
2489
2512
|
if (c && O) {
|
|
2490
2513
|
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,
|
|
2514
|
+
const e = r.calculateDistance(M, c), f = r.calculateDistance(M, O);
|
|
2515
|
+
if (e > 2 * p && f > 2 * p)
|
|
2516
|
+
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", b.requestId, e, f, {
|
|
2494
2517
|
from: M,
|
|
2495
2518
|
t1: c,
|
|
2496
2519
|
t2: O,
|
|
2497
2520
|
hr: A
|
|
2498
2521
|
}), {};
|
|
2499
2522
|
}
|
|
2500
|
-
const o =
|
|
2523
|
+
const o = r.calculateBearing(M, c), Y = r.calculateBearing(c, O), d = Math.abs(o - Y);
|
|
2501
2524
|
let R = 0;
|
|
2502
2525
|
d < 180 ? R = d + 90 : d >= 180 && (R = d - 90);
|
|
2503
|
-
const T =
|
|
2526
|
+
const T = r.calculateCoordinate(c, R, p);
|
|
2504
2527
|
return I == null || I.info("[%s] the right tangent position: %j", b.requestId, {
|
|
2505
2528
|
from: M,
|
|
2506
2529
|
t1: c,
|
|
@@ -2527,17 +2550,17 @@ class V0 {
|
|
|
2527
2550
|
const { t1: c, t2: O, hr: A, hours: W } = this.tropicalCenterTwin(z, 24, b);
|
|
2528
2551
|
if (c && O) {
|
|
2529
2552
|
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,
|
|
2553
|
+
const T = r.calculateDistance(M, c), e = r.calculateDistance(M, O);
|
|
2554
|
+
if (T > 2 * p && e > 2 * p)
|
|
2555
|
+
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, e, {
|
|
2533
2556
|
from: M,
|
|
2534
2557
|
t1: c,
|
|
2535
2558
|
t2: O,
|
|
2536
2559
|
hr: A
|
|
2537
2560
|
}), {};
|
|
2538
2561
|
}
|
|
2539
|
-
const o =
|
|
2540
|
-
return { at:
|
|
2562
|
+
const o = r.calculateBearing(M, c), Y = r.calculateBearing(c, O), d = r.calculateDistance(M, c);
|
|
2563
|
+
return { at: r.calculateCoordinate(c, o - Y + 180, p < d ? p : d), t1: c, t2: O, hr: Number(A), hours: W };
|
|
2541
2564
|
} else
|
|
2542
2565
|
return I == null || I.info("[%s] no need drift: %j", b.requestId, { from: M, t1: c, t2: O, hr: A }), {};
|
|
2543
2566
|
}
|
|
@@ -2550,26 +2573,26 @@ class V0 {
|
|
|
2550
2573
|
* @private
|
|
2551
2574
|
*/
|
|
2552
2575
|
static tropicalCenterTwin(M, z = 24, p = {}) {
|
|
2553
|
-
var Y, d, R, T,
|
|
2576
|
+
var Y, d, R, T, e;
|
|
2554
2577
|
let b = {};
|
|
2555
|
-
(Y = M.forecasts) == null || Y.forEach((
|
|
2556
|
-
b = { ...
|
|
2578
|
+
(Y = M.forecasts) == null || Y.forEach((f) => {
|
|
2579
|
+
b = { ...f.hours, ...b };
|
|
2557
2580
|
});
|
|
2558
2581
|
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
2582
|
I == null || I.info("[%s] the first tropical center: %j", p.requestId, c);
|
|
2560
|
-
let O = (T = Object.keys(b || {}).filter((
|
|
2561
|
-
O || (O = (
|
|
2583
|
+
let O = (T = Object.keys(b || {}).filter((f) => Number(f) <= (z < 0 ? 24 : z))) == null ? void 0 : T.at(-1);
|
|
2584
|
+
O || (O = (e = Object.keys(b || {}).filter((f) => Number(f) <= (z < 0 ? 24 : 2 * z))) == null ? void 0 : e.at(-1));
|
|
2562
2585
|
const A = b == null ? void 0 : b[O || -1];
|
|
2563
2586
|
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[
|
|
2587
|
+
const W = Object.keys(b || {}).filter((f) => Number(f) <= Number(O)), o = { 0: c };
|
|
2588
|
+
for (const f of W)
|
|
2589
|
+
o[f] = b[f];
|
|
2567
2590
|
return { t1: c, t2: A, hr: Number(O), hours: o };
|
|
2568
2591
|
}
|
|
2569
2592
|
static pickIndex(M, z) {
|
|
2570
2593
|
let p = 0;
|
|
2571
2594
|
for (const b of M) {
|
|
2572
|
-
if (
|
|
2595
|
+
if (U(b.properties.date).isAfter(z))
|
|
2573
2596
|
return p === 0 ? -1 : p;
|
|
2574
2597
|
p++;
|
|
2575
2598
|
}
|
|
@@ -2593,7 +2616,7 @@ class V0 {
|
|
|
2593
2616
|
}
|
|
2594
2617
|
export {
|
|
2595
2618
|
t0 as AisHelper,
|
|
2596
|
-
|
|
2619
|
+
r as LaneHelper,
|
|
2597
2620
|
a as LngLatHelper,
|
|
2598
2621
|
V0 as TropicalHelper
|
|
2599
2622
|
};
|