@idm-plugin/geo 2.0.1 → 2.0.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 +235 -229
- package/dist/index.umd.cjs +3 -3
- package/dist/lane/src/index.d.ts +3 -2
- 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 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 : {};
|
|
@@ -24,14 +24,14 @@ var x = { exports: {} };
|
|
|
24
24
|
return o > 96 ? o - 87 : o > 64 ? o - 29 : o - 48;
|
|
25
25
|
}
|
|
26
26
|
function T(o) {
|
|
27
|
-
var n = 0, X = o.split("."), L = X[0], e = X[1] || "", U = 1, E, t = 0,
|
|
28
|
-
for (o.charCodeAt(0) === 45 && (n = 1,
|
|
27
|
+
var n = 0, X = o.split("."), L = X[0], e = X[1] || "", U = 1, E, t = 0, Z = 1;
|
|
28
|
+
for (o.charCodeAt(0) === 45 && (n = 1, Z = -1), n; n < L.length; n++)
|
|
29
29
|
E = R(L.charCodeAt(n)), t = 60 * t + E;
|
|
30
30
|
for (n = 0; n < e.length; n++)
|
|
31
31
|
U = U / 60, E = R(e.charCodeAt(n)), t += E * U;
|
|
32
|
-
return t *
|
|
32
|
+
return t * Z;
|
|
33
33
|
}
|
|
34
|
-
function
|
|
34
|
+
function N(o) {
|
|
35
35
|
for (var n = 0; n < o.length; n++)
|
|
36
36
|
o[n] = T(o[n]);
|
|
37
37
|
}
|
|
@@ -40,7 +40,7 @@ var x = { exports: {} };
|
|
|
40
40
|
o[X] = Math.round((o[X - 1] || 0) + o[X] * 6e4);
|
|
41
41
|
o[n - 1] = 1 / 0;
|
|
42
42
|
}
|
|
43
|
-
function
|
|
43
|
+
function f(o, n) {
|
|
44
44
|
var X = [], L;
|
|
45
45
|
for (L = 0; L < n.length; L++)
|
|
46
46
|
X[L] = o[n[L]];
|
|
@@ -48,18 +48,18 @@ var x = { exports: {} };
|
|
|
48
48
|
}
|
|
49
49
|
function s(o) {
|
|
50
50
|
var n = o.split("|"), X = n[2].split(" "), L = n[3].split(""), e = n[4].split(" ");
|
|
51
|
-
return
|
|
51
|
+
return N(X), N(L), N(e), i(e, L.length), {
|
|
52
52
|
name: n[0],
|
|
53
|
-
abbrs:
|
|
54
|
-
offsets:
|
|
53
|
+
abbrs: f(n[1].split(" "), L),
|
|
54
|
+
offsets: f(X, L),
|
|
55
55
|
untils: e,
|
|
56
56
|
population: n[5] | 0
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
function
|
|
59
|
+
function P(o) {
|
|
60
60
|
o && this._set(s(o));
|
|
61
61
|
}
|
|
62
|
-
function
|
|
62
|
+
function l(o, n) {
|
|
63
63
|
var X = n.length;
|
|
64
64
|
if (o < n[0])
|
|
65
65
|
return 0;
|
|
@@ -71,13 +71,13 @@ var x = { exports: {} };
|
|
|
71
71
|
L = Math.floor((e + U) / 2), n[L] <= o ? e = L : U = L;
|
|
72
72
|
return U;
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
P.prototype = {
|
|
75
75
|
_set: function(o) {
|
|
76
76
|
this.name = o.name, this.abbrs = o.abbrs, this.untils = o.untils, this.offsets = o.offsets, this.population = o.population;
|
|
77
77
|
},
|
|
78
78
|
_index: function(o) {
|
|
79
79
|
var n = +o, X = this.untils, L;
|
|
80
|
-
if (L =
|
|
80
|
+
if (L = l(n, X), L >= 0)
|
|
81
81
|
return L;
|
|
82
82
|
},
|
|
83
83
|
countries: function() {
|
|
@@ -87,10 +87,10 @@ var x = { exports: {} };
|
|
|
87
87
|
});
|
|
88
88
|
},
|
|
89
89
|
parse: function(o) {
|
|
90
|
-
var n = +o, X = this.offsets, L = this.untils, e = L.length - 1, U, E, t,
|
|
91
|
-
for (
|
|
92
|
-
if (U = X[
|
|
93
|
-
return X[
|
|
90
|
+
var n = +o, X = this.offsets, L = this.untils, e = L.length - 1, U, E, t, Z;
|
|
91
|
+
for (Z = 0; Z < e; Z++)
|
|
92
|
+
if (U = X[Z], E = X[Z + 1], t = X[Z && Z - 1], U < E && V.moveAmbiguousForward ? U = E : U > t && V.moveInvalidForward && (U = t), n < L[Z] - U * 6e4)
|
|
93
|
+
return X[Z];
|
|
94
94
|
return X[e];
|
|
95
95
|
},
|
|
96
96
|
abbr: function(o) {
|
|
@@ -103,17 +103,17 @@ var x = { exports: {} };
|
|
|
103
103
|
return this.offsets[this._index(o)];
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
|
-
function
|
|
106
|
+
function B(o, n) {
|
|
107
107
|
this.name = o, this.zones = n;
|
|
108
108
|
}
|
|
109
109
|
function G(o) {
|
|
110
110
|
var n = o.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 = +o, this.abbr = X, this.offset = o.getTimezoneOffset();
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function H(o) {
|
|
114
114
|
this.zone = o, this.offsetScore = 0, this.abbrScore = 0;
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
H.prototype.scoreOffsetAt = function(o) {
|
|
117
117
|
this.offsetScore += Math.abs(this.zone.utcOffset(o.at) - o.offset), this.zone.abbr(o.at).replace(/[^A-Z]/g, "") !== o.abbr && this.abbrScore++;
|
|
118
118
|
};
|
|
119
119
|
function F(o, n) {
|
|
@@ -134,16 +134,16 @@ var x = { exports: {} };
|
|
|
134
134
|
}
|
|
135
135
|
function b0(o, n) {
|
|
136
136
|
var X, L;
|
|
137
|
-
for (
|
|
137
|
+
for (N(n), X = 0; X < n.length; X++)
|
|
138
138
|
L = n[X], A[L] = A[L] || {}, A[L][o] = !0;
|
|
139
139
|
}
|
|
140
140
|
function p0(o) {
|
|
141
|
-
var n = o.length, X = {}, L = [], e = {}, U, E, t,
|
|
141
|
+
var n = o.length, X = {}, L = [], e = {}, U, E, t, Z;
|
|
142
142
|
for (U = 0; U < n; U++)
|
|
143
143
|
if (t = o[U].offset, !e.hasOwnProperty(t)) {
|
|
144
|
-
|
|
145
|
-
for (E in
|
|
146
|
-
|
|
144
|
+
Z = A[t] || {};
|
|
145
|
+
for (E in Z)
|
|
146
|
+
Z.hasOwnProperty(E) && (X[E] = !0);
|
|
147
147
|
e[t] = !0;
|
|
148
148
|
}
|
|
149
149
|
for (U in X)
|
|
@@ -154,17 +154,17 @@ var x = { exports: {} };
|
|
|
154
154
|
try {
|
|
155
155
|
var o = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
156
156
|
if (o && o.length > 3) {
|
|
157
|
-
var n = O[
|
|
157
|
+
var n = O[h(o)];
|
|
158
158
|
if (n)
|
|
159
159
|
return n;
|
|
160
160
|
D("Moment Timezone found " + o + " from the Intl api, but did not have that data loaded.");
|
|
161
161
|
}
|
|
162
162
|
} catch {
|
|
163
163
|
}
|
|
164
|
-
var X = $(), L = X.length, e = p0(X), U = [], E, t,
|
|
164
|
+
var X = $(), L = X.length, e = p0(X), U = [], E, t, Z;
|
|
165
165
|
for (t = 0; t < e.length; t++) {
|
|
166
|
-
for (E = new
|
|
167
|
-
E.scoreOffsetAt(X[
|
|
166
|
+
for (E = new H(g(e[t])), Z = 0; Z < L; Z++)
|
|
167
|
+
E.scoreOffsetAt(X[Z]);
|
|
168
168
|
U.push(E);
|
|
169
169
|
}
|
|
170
170
|
return U.sort(z0), U.length > 0 ? U[0].zone.name : void 0;
|
|
@@ -172,18 +172,18 @@ var x = { exports: {} };
|
|
|
172
172
|
function A0(o) {
|
|
173
173
|
return (!W || o) && (W = O0()), W;
|
|
174
174
|
}
|
|
175
|
-
function
|
|
175
|
+
function h(o) {
|
|
176
176
|
return (o || "").toLowerCase().replace(/\//g, "_");
|
|
177
177
|
}
|
|
178
178
|
function k(o) {
|
|
179
179
|
var n, X, L, e;
|
|
180
180
|
for (typeof o == "string" && (o = [o]), n = 0; n < o.length; n++)
|
|
181
|
-
L = o[n].split("|"), X = L[0], e =
|
|
181
|
+
L = o[n].split("|"), X = L[0], e = h(X), b[e] = o[n], O[e] = X, b0(e, L[2].split(" "));
|
|
182
182
|
}
|
|
183
183
|
function g(o, n) {
|
|
184
|
-
o =
|
|
184
|
+
o = h(o);
|
|
185
185
|
var X = b[o], L;
|
|
186
|
-
return X instanceof
|
|
186
|
+
return X instanceof P ? X : typeof X == "string" ? (X = new P(X), b[o] = X, X) : p[o] && n !== g && (L = g(p[o], g)) ? (X = b[o] = new P(), X._set(L), X.name = O[o], X) : null;
|
|
187
187
|
}
|
|
188
188
|
function c0() {
|
|
189
189
|
var o, n = [];
|
|
@@ -197,13 +197,13 @@ var x = { exports: {} };
|
|
|
197
197
|
function y(o) {
|
|
198
198
|
var n, X, L, e;
|
|
199
199
|
for (typeof o == "string" && (o = [o]), n = 0; n < o.length; n++)
|
|
200
|
-
X = o[n].split("|"), L =
|
|
200
|
+
X = o[n].split("|"), L = h(X[0]), e = h(X[1]), p[L] = e, O[L] = X[0], p[e] = L, O[e] = X[1];
|
|
201
201
|
}
|
|
202
202
|
function o0(o) {
|
|
203
203
|
var n, X, L, e;
|
|
204
204
|
if (!(!o || !o.length))
|
|
205
205
|
for (n = 0; n < o.length; n++)
|
|
206
|
-
e = o[n].split("|"), X = e[0].toUpperCase(), L = e[1].split(" "), c[X] = new
|
|
206
|
+
e = o[n].split("|"), X = e[0].toUpperCase(), L = e[1].split(" "), c[X] = new B(
|
|
207
207
|
X,
|
|
208
208
|
L
|
|
209
209
|
);
|
|
@@ -240,7 +240,7 @@ var x = { exports: {} };
|
|
|
240
240
|
var n = Array.prototype.slice.call(arguments, 0, -1), X = arguments[arguments.length - 1], L = M.utc.apply(null, n), e;
|
|
241
241
|
return !M.isMoment(o) && v(L) && (e = g(X)) && L.add(e.parse(L), "minutes"), L.tz(X), L;
|
|
242
242
|
}
|
|
243
|
-
V.version = z, V.dataVersion = "", V._zones = b, V._links = p, V._names = O, V._countries = c, V.add = k, V.link = y, V.load = d0, V.zone = g, V.zoneExists = J, V.guess = A0, V.names = c0, V.Zone =
|
|
243
|
+
V.version = z, V.dataVersion = "", V._zones = b, V._links = p, V._names = O, V._countries = c, V.add = k, V.link = y, V.load = d0, V.zone = g, V.zoneExists = J, V.guess = A0, V.names = c0, V.Zone = P, V.unpack = s, V.unpackBase60 = T, V.needsOffset = v, V.moveInvalidForward = !0, V.moveAmbiguousForward = !1, V.countries = W0, V.zonesForCountry = Y0;
|
|
244
244
|
var C = M.fn;
|
|
245
245
|
M.tz = V, M.defaultZone = null, M.updateOffset = function(o, n) {
|
|
246
246
|
var X = M.defaultZone, L;
|
|
@@ -277,8 +277,8 @@ var x = { exports: {} };
|
|
|
277
277
|
C.zoneName = w(C.zoneName), C.zoneAbbr = w(C.zoneAbbr), C.utc = _(C.utc), C.local = _(C.local), C.utcOffset = a0(C.utcOffset), M.tz.setDefault = function(o) {
|
|
278
278
|
return (Y < 2 || Y === 2 && d < 9) && D("Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js " + M.version + "."), M.defaultZone = o ? g(o) : null, M;
|
|
279
279
|
};
|
|
280
|
-
var
|
|
281
|
-
return Object.prototype.toString.call(
|
|
280
|
+
var K = M.momentProperties;
|
|
281
|
+
return Object.prototype.toString.call(K) === "[object Array]" ? (K.push("_z"), K.push("_a")) : K && (K._z = null), M;
|
|
282
282
|
});
|
|
283
283
|
})(x);
|
|
284
284
|
var R0 = x.exports;
|
|
@@ -1135,8 +1135,8 @@ const L0 = "2025b", T0 = [
|
|
|
1135
1135
|
links: i0,
|
|
1136
1136
|
countries: e0
|
|
1137
1137
|
};
|
|
1138
|
-
var
|
|
1139
|
-
|
|
1138
|
+
var S0 = R0;
|
|
1139
|
+
S0.tz.load(N0);
|
|
1140
1140
|
var M0 = { exports: {} };
|
|
1141
1141
|
(function(m) {
|
|
1142
1142
|
function M(z, b) {
|
|
@@ -1152,8 +1152,8 @@ var M0 = { exports: {} };
|
|
|
1152
1152
|
}
|
|
1153
1153
|
m.exports = M;
|
|
1154
1154
|
})(M0);
|
|
1155
|
-
var
|
|
1156
|
-
const r0 = /* @__PURE__ */ X0(
|
|
1155
|
+
var f0 = M0.exports;
|
|
1156
|
+
const r0 = /* @__PURE__ */ X0(f0);
|
|
1157
1157
|
class a {
|
|
1158
1158
|
/**
|
|
1159
1159
|
* 基于输入的经度,计算出时区
|
|
@@ -1308,13 +1308,82 @@ class a {
|
|
|
1308
1308
|
return p >= 1 ? c : b > 0 ? `${c}.${Math.trunc(p * Math.pow(10, b)).toString().padStart(b, "0")}` : c;
|
|
1309
1309
|
}
|
|
1310
1310
|
}
|
|
1311
|
+
class B0 {
|
|
1312
|
+
static json2Str(M) {
|
|
1313
|
+
const z = M.type ? M.type[0].toUpperCase() : "A";
|
|
1314
|
+
return `${M.lat}|${M.lng}|${M.positionTime}|${M.sog}|${M.cog}|${M.hdg}|${M.draught}|${z}|${JSON.stringify(M.meteo || {})}|${M.vendor}|${M.deleted}`;
|
|
1315
|
+
}
|
|
1316
|
+
static str2Json(M) {
|
|
1317
|
+
const [z, b, p, c, O, A, W, q, Y, d, R] = M.split("|");
|
|
1318
|
+
return {
|
|
1319
|
+
lat: Number(z),
|
|
1320
|
+
lng: Number(b),
|
|
1321
|
+
positionTime: Number(p),
|
|
1322
|
+
sog: Number(c),
|
|
1323
|
+
cog: Number(O),
|
|
1324
|
+
hdg: Number(A),
|
|
1325
|
+
//@ts-ignore
|
|
1326
|
+
draught: isNaN(W) ? null : Number(W),
|
|
1327
|
+
type: q,
|
|
1328
|
+
important: q !== "A",
|
|
1329
|
+
meteo: Y ? JSON.parse(Y) : void 0,
|
|
1330
|
+
vendor: d,
|
|
1331
|
+
deleted: R === "true"
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1334
|
+
static inspectStoppages(M, z = 1, b = !0) {
|
|
1335
|
+
const p = M.at(0).positionTime < M.at(-1).positionTime;
|
|
1336
|
+
p || M.sort((W, q) => W.positionTime - q.positionTime);
|
|
1337
|
+
const c = [];
|
|
1338
|
+
let O, A;
|
|
1339
|
+
for (let W = 0; W < M.length - 1; W++) {
|
|
1340
|
+
const q = M[W];
|
|
1341
|
+
if (!(b && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(q.type))) {
|
|
1342
|
+
for (let Y = W + 1; Y < M.length; Y++) {
|
|
1343
|
+
const d = M[Y - 1], R = M[Y];
|
|
1344
|
+
if (b && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(q.type))
|
|
1345
|
+
continue;
|
|
1346
|
+
const T = R.positionTime - d.positionTime;
|
|
1347
|
+
if (r.calculateDistance(R, d, !0, 4) / (T / 3600) < z)
|
|
1348
|
+
O || (O = q), Y === M.length - 1 && (A = R, W = Y);
|
|
1349
|
+
else {
|
|
1350
|
+
O && (A = M[Y - 1], W = Y);
|
|
1351
|
+
break;
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
if ((A == null ? void 0 : A.positionTime) > (O == null ? void 0 : O.positionTime) && O) {
|
|
1355
|
+
const Y = {
|
|
1356
|
+
start: {
|
|
1357
|
+
lat: O.lat,
|
|
1358
|
+
lng: O.lng,
|
|
1359
|
+
sog: O.sog,
|
|
1360
|
+
positionTime: O.positionTime,
|
|
1361
|
+
utc: u.unix(O.positionTime).utc().format()
|
|
1362
|
+
},
|
|
1363
|
+
end: {
|
|
1364
|
+
lat: A.lat,
|
|
1365
|
+
lng: A.lng,
|
|
1366
|
+
sog: A.sog,
|
|
1367
|
+
positionTime: A.positionTime,
|
|
1368
|
+
utc: u.unix(A.positionTime).utc().format()
|
|
1369
|
+
},
|
|
1370
|
+
duration: A.positionTime - O.positionTime
|
|
1371
|
+
}, d = M.filter((T) => T.positionTime >= Y.start.positionTime && T.positionTime <= Y.end.positionTime), R = r.divideAccordingToLng(d);
|
|
1372
|
+
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);
|
|
1373
|
+
}
|
|
1374
|
+
O = void 0, A = void 0;
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
return p || M.sort((W, q) => q.positionTime - W.positionTime), c;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1311
1380
|
let Q;
|
|
1312
1381
|
try {
|
|
1313
1382
|
Q = j.getLogger("meteo");
|
|
1314
1383
|
} catch {
|
|
1315
1384
|
} finally {
|
|
1316
1385
|
}
|
|
1317
|
-
class
|
|
1386
|
+
class r {
|
|
1318
1387
|
/**
|
|
1319
1388
|
* 计算方位角
|
|
1320
1389
|
* @param from 坐标 {lng, lat}
|
|
@@ -1324,12 +1393,12 @@ class B {
|
|
|
1324
1393
|
* @returns {number} 单位度
|
|
1325
1394
|
*/
|
|
1326
1395
|
static calculateBearing(M, z, b = !0, p = 4) {
|
|
1327
|
-
const c =
|
|
1396
|
+
const c = S.points([
|
|
1328
1397
|
[M.lng, M.lat],
|
|
1329
1398
|
[z.lng, z.lat]
|
|
1330
1399
|
]);
|
|
1331
1400
|
let O;
|
|
1332
|
-
return b ? O =
|
|
1401
|
+
return b ? 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, p);
|
|
1333
1402
|
}
|
|
1334
1403
|
/**
|
|
1335
1404
|
* 计算两点间距离
|
|
@@ -1342,12 +1411,12 @@ class B {
|
|
|
1342
1411
|
*/
|
|
1343
1412
|
static calculateDistance(M, z, b = !0, p = 4, c = "nauticalmiles") {
|
|
1344
1413
|
M = { ...M }, z = { ...z }, M.lng = a.convertToStdLng(M.lng, p), z.lng = a.convertToStdLng(z.lng, p);
|
|
1345
|
-
const O =
|
|
1414
|
+
const O = S.points([
|
|
1346
1415
|
[M.lng, M.lat],
|
|
1347
1416
|
[z.lng, z.lat]
|
|
1348
1417
|
]);
|
|
1349
1418
|
let A;
|
|
1350
|
-
return b ? A =
|
|
1419
|
+
return b ? 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, p);
|
|
1351
1420
|
}
|
|
1352
1421
|
/**
|
|
1353
1422
|
* 计算航线距离
|
|
@@ -1375,9 +1444,9 @@ class B {
|
|
|
1375
1444
|
* @param rhumb
|
|
1376
1445
|
*/
|
|
1377
1446
|
static calculateCoordinate(M, z, b, p = "nauticalmiles", c = !0) {
|
|
1378
|
-
const O =
|
|
1447
|
+
const O = S.point([M.lng, M.lat]);
|
|
1379
1448
|
let A;
|
|
1380
|
-
c ? A =
|
|
1449
|
+
c ? A = S.rhumbDestination(O, b, z, { units: p }) : A = S.destination(O, b, z, { units: p });
|
|
1381
1450
|
const W = A.geometry.coordinates;
|
|
1382
1451
|
return { lng: a.convertToStdLng(W[0], 8), lat: a.roundPrecision(W[1], 8) };
|
|
1383
1452
|
}
|
|
@@ -1426,18 +1495,18 @@ class B {
|
|
|
1426
1495
|
[A, M[W + 1].lat]
|
|
1427
1496
|
]);
|
|
1428
1497
|
let d, R;
|
|
1429
|
-
z ? (d =
|
|
1498
|
+
z ? (d = S.lineString(Y), R = S.lineString([
|
|
1430
1499
|
[q > 0 ? 180 : -180, 89],
|
|
1431
1500
|
[q > 0 ? 180 : -180, -89]
|
|
1432
|
-
])) : (d =
|
|
1433
|
-
const T =
|
|
1434
|
-
let
|
|
1501
|
+
])) : (d = S.greatCircle(Y[0], Y[1]), R = S.greatCircle([q > 0 ? 180 : -180, 89], [q > 0 ? 180 : -180, -89]));
|
|
1502
|
+
const T = S.lineIntersect(d, R);
|
|
1503
|
+
let N;
|
|
1435
1504
|
if (T.features.length) {
|
|
1436
|
-
const i =
|
|
1437
|
-
|
|
1505
|
+
const i = S.getCoord(T.features[0]);
|
|
1506
|
+
N = a.roundPrecision(i[1], 8);
|
|
1438
1507
|
} else
|
|
1439
|
-
|
|
1440
|
-
q > 0 ? (p.push([180 - 1e-6,
|
|
1508
|
+
N = M[W].lat;
|
|
1509
|
+
q > 0 ? (p.push([180 - 1e-6, N]), c.push([...p]), p = [], p.push([-(180 - 1e-6), N])) : (p.push([-(180 - 1e-6), N]), c.push([...p]), p = [], p.push([180 - 1e-6, N]));
|
|
1441
1510
|
}
|
|
1442
1511
|
W === M.length - 2 && p.push([A, M[W + 1].lat]);
|
|
1443
1512
|
}
|
|
@@ -1513,8 +1582,8 @@ class B {
|
|
|
1513
1582
|
*/
|
|
1514
1583
|
static appendCoordinateToRoute(M, z) {
|
|
1515
1584
|
M.lng = a.convertToStdLng(M.lng, 8);
|
|
1516
|
-
const b =
|
|
1517
|
-
return b.push(M),
|
|
1585
|
+
const b = r.convertRouteToCoordinates(z);
|
|
1586
|
+
return b.push(M), r.divideAccordingToLng(b);
|
|
1518
1587
|
}
|
|
1519
1588
|
/**
|
|
1520
1589
|
* 向route头加1个坐标
|
|
@@ -1522,8 +1591,8 @@ class B {
|
|
|
1522
1591
|
* @param route
|
|
1523
1592
|
*/
|
|
1524
1593
|
static unshiftCoordinateToRoute(M, z) {
|
|
1525
|
-
const b =
|
|
1526
|
-
return b.unshift(M),
|
|
1594
|
+
const b = r.convertRouteToCoordinates(z);
|
|
1595
|
+
return b.unshift(M), r.divideAccordingToLng(b);
|
|
1527
1596
|
}
|
|
1528
1597
|
/**
|
|
1529
1598
|
* 合并多个waypoints进航线
|
|
@@ -1597,8 +1666,8 @@ class B {
|
|
|
1597
1666
|
* @return [[[lng, lat]]]
|
|
1598
1667
|
*/
|
|
1599
1668
|
static calculateSubRoute(M, z) {
|
|
1600
|
-
const b =
|
|
1601
|
-
|
|
1669
|
+
const b = r.convertRouteToCoordinates(z);
|
|
1670
|
+
r.mergeCoordinateToWaypoints(M, b, !0), z = r.divideAccordingToLng(b);
|
|
1602
1671
|
const { segIndex: p, minIndex: c } = this.calculateMinDistanceToRoute({ ...M }, z);
|
|
1603
1672
|
M.lng = a.convertToStdLng(M.lng);
|
|
1604
1673
|
const O = [];
|
|
@@ -1648,10 +1717,10 @@ class B {
|
|
|
1648
1717
|
M.lng = a.convertToStdLng(M.lng, 8), z = { ...z }, b = { ...b }, z.lng = a.convertToStdLng(z.lng, 8), b.lng = a.convertToStdLng(b.lng, 8);
|
|
1649
1718
|
const c = a.convertToMonotonicLng([z, b]);
|
|
1650
1719
|
z = c[0], b = c[1];
|
|
1651
|
-
const O =
|
|
1720
|
+
const O = S.lineString([
|
|
1652
1721
|
[z.lng, z.lat],
|
|
1653
1722
|
[b.lng, b.lat]
|
|
1654
|
-
]), A =
|
|
1723
|
+
]), A = S.pointToLineDistance(S.point([M.lng, M.lat]), O, p), W = S.pointToLineDistance(S.point([M.lng > 0 ? M.lng - 360 : M.lng + 360, M.lat]), O, p);
|
|
1655
1724
|
return a.roundPrecision(Math.min(A, W), 6);
|
|
1656
1725
|
}
|
|
1657
1726
|
/**
|
|
@@ -1736,7 +1805,7 @@ class B {
|
|
|
1736
1805
|
* @param route [[[lng, lat]]]
|
|
1737
1806
|
*/
|
|
1738
1807
|
static nearestCoordinateInRoute(M, z) {
|
|
1739
|
-
const b =
|
|
1808
|
+
const b = S.point([M.lng, M.lat]), c = this.convertRouteToCoordinates(z).map((q) => [q.lng, q.lat]), O = S.lineString(c), A = S.nearestPointOnLine(O, b), W = S.getCoord(A);
|
|
1740
1809
|
return { lng: a.roundPrecision(W[0], 8), lat: a.roundPrecision(W[1], 8) };
|
|
1741
1810
|
}
|
|
1742
1811
|
/**
|
|
@@ -1764,7 +1833,7 @@ class B {
|
|
|
1764
1833
|
* 计算下一个距离单位的坐标及其子航线
|
|
1765
1834
|
* @param from 起点坐标 {lng, lat}
|
|
1766
1835
|
* @param distance 航行距离
|
|
1767
|
-
* @param route
|
|
1836
|
+
* @param route
|
|
1768
1837
|
* @param units
|
|
1769
1838
|
* @return { coordinate: {lng, lat}, route: [[[lng, lat]]]}
|
|
1770
1839
|
*/
|
|
@@ -1772,31 +1841,31 @@ class B {
|
|
|
1772
1841
|
var R;
|
|
1773
1842
|
const c = M.speed || 12, O = [];
|
|
1774
1843
|
let A = [], W = !1, q = 0, Y = 0, d;
|
|
1775
|
-
if (z && b.length ? (O.push(M), b.forEach((T,
|
|
1844
|
+
if (z && b.length ? (O.push(M), b.forEach((T, N) => {
|
|
1776
1845
|
if (W)
|
|
1777
1846
|
A.push(T);
|
|
1778
1847
|
else {
|
|
1779
1848
|
const i = [];
|
|
1780
|
-
let
|
|
1849
|
+
let f;
|
|
1781
1850
|
for (let s = 0; s < T.length; s++)
|
|
1782
1851
|
if (d)
|
|
1783
1852
|
i.push(T[s]);
|
|
1784
1853
|
else {
|
|
1785
|
-
|
|
1786
|
-
const
|
|
1787
|
-
if (q +=
|
|
1788
|
-
Y +=
|
|
1854
|
+
f = { lng: T[s][0], lat: T[s][1] };
|
|
1855
|
+
const P = this.calculateDistance(M, f, !0, 8, p);
|
|
1856
|
+
if (q += P, q < z)
|
|
1857
|
+
Y += P, P && O.push(f), M = f;
|
|
1789
1858
|
else {
|
|
1790
1859
|
if (Y = z, q === z)
|
|
1791
|
-
d =
|
|
1860
|
+
d = f, i.push([d.lng, d.lat]);
|
|
1792
1861
|
else {
|
|
1793
|
-
const
|
|
1794
|
-
d = this.calculateCoordinate(
|
|
1862
|
+
const l = q - z, B = this.calculateBearing(f, M);
|
|
1863
|
+
d = this.calculateCoordinate(f, B, l, p), i.push([d.lng, d.lat]), i.push([f.lng, f.lat]);
|
|
1795
1864
|
}
|
|
1796
1865
|
W = !0;
|
|
1797
1866
|
}
|
|
1798
1867
|
}
|
|
1799
|
-
i.length && A.push(i),
|
|
1868
|
+
i.length && A.push(i), N === b.length - 1 && !d && (d = f);
|
|
1800
1869
|
}
|
|
1801
1870
|
})) : (A = b, d = { ...M }), d)
|
|
1802
1871
|
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) {
|
|
@@ -1813,10 +1882,10 @@ class B {
|
|
|
1813
1882
|
* @param to {lng, lat}
|
|
1814
1883
|
*/
|
|
1815
1884
|
static nearestCoordinateInLine(M, z, b) {
|
|
1816
|
-
const p = a.convertToStdLng(M.lng, 6), c =
|
|
1885
|
+
const p = a.convertToStdLng(M.lng, 6), c = S.point([p, M.lat]), O = a.convertToStdLng(z.lng, 6), A = a.convertToStdLng(b.lng, 6), W = S.lineString([
|
|
1817
1886
|
[O, z.lat],
|
|
1818
1887
|
[A, b.lat]
|
|
1819
|
-
]), q =
|
|
1888
|
+
]), q = S.nearestPointOnLine(W, c), Y = S.getCoord(q), d = a.roundPrecision(Y[0], 6), R = a.roundPrecision(Y[1], 6);
|
|
1820
1889
|
return { lng: d, lat: R, inline: !(d === O && R === z.lat) && !(d === A && R === b.lat) };
|
|
1821
1890
|
}
|
|
1822
1891
|
/**
|
|
@@ -1885,10 +1954,10 @@ class B {
|
|
|
1885
1954
|
for (const A of M)
|
|
1886
1955
|
for (const W of A)
|
|
1887
1956
|
z.push(W);
|
|
1888
|
-
const b =
|
|
1957
|
+
const b = S.featureCollection([]), p = a.convertToMonotonicLng2(z);
|
|
1889
1958
|
for (const A of p)
|
|
1890
|
-
b.features.push(
|
|
1891
|
-
const O =
|
|
1959
|
+
b.features.push(S.point(A));
|
|
1960
|
+
const O = S.center(b).geometry.coordinates;
|
|
1892
1961
|
return { lng: a.convertToStdLng(O[0], 8), lat: a.roundPrecision(O[1], 8) };
|
|
1893
1962
|
}
|
|
1894
1963
|
/**
|
|
@@ -1908,8 +1977,8 @@ class B {
|
|
|
1908
1977
|
for (const c of M)
|
|
1909
1978
|
for (const O of c)
|
|
1910
1979
|
z.push(O);
|
|
1911
|
-
const b = a.convertToMonotonicLng2(z), p =
|
|
1912
|
-
return
|
|
1980
|
+
const b = a.convertToMonotonicLng2(z), p = S.lineString(b);
|
|
1981
|
+
return S.bbox(p);
|
|
1913
1982
|
}
|
|
1914
1983
|
/**
|
|
1915
1984
|
* 计算BBox
|
|
@@ -1931,8 +2000,8 @@ class B {
|
|
|
1931
2000
|
const O = M[c - 1], A = M[c], W = M[c + 1];
|
|
1932
2001
|
let q = !1, Y = !1;
|
|
1933
2002
|
if ((O.velocity || O.suspend || O.important || O.pilot || c === 1) && (q = !0, p.push(O)), A.gcToPrevious && (q || (q = !0, p.push(O)), Y = !0, p.push(A), c++), W) {
|
|
1934
|
-
const d =
|
|
1935
|
-
Math.round(Math.acos(
|
|
2003
|
+
const d = r.calculateDistance(O, A, !0), R = r.calculateDistance(A, W, !0), T = r.calculateDistance(O, W, !0), N = (Math.pow(d, 2) + Math.pow(R, 2) - Math.pow(T, 2)) / (2 * d * R);
|
|
2004
|
+
Math.round(Math.acos(N) * 180 / Math.PI) < b && T > z && !Y && (p.push(A), c++);
|
|
1936
2005
|
}
|
|
1937
2006
|
if (c >= M.length - 1) {
|
|
1938
2007
|
const d = M.at(-1);
|
|
@@ -1966,8 +2035,8 @@ class B {
|
|
|
1966
2035
|
if (!p) {
|
|
1967
2036
|
const q = (O = (c = z.filter((d) => (d == null ? void 0 : d.positionTime) < b.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) > b.unix())) == null ? void 0 : A.sort((d, R) => (d.positionTime || 0) - (R.positionTime || 0))) == null ? void 0 : W.at(0);
|
|
1968
2037
|
if (q && Y) {
|
|
1969
|
-
const d =
|
|
1970
|
-
p =
|
|
2038
|
+
const d = r.calculateBearing(q, Y, !0), R = r.calculateDistance(q, Y), T = (b.unix() - q.positionTime) / (Y.positionTime - q.positionTime);
|
|
2039
|
+
p = r.calculateCoordinate(q, d, R * T), p.positionTime = b.unix(), p.utc = b.utc().format(), p.cog = d, p.sog = Math.round(R / ((Y.positionTime - q.positionTime) / 3600) * 100) / 100;
|
|
1971
2040
|
} else
|
|
1972
2041
|
p = q || Y, p && (p.utc = u.unix(p == null ? void 0 : p.positionTime).utc().format());
|
|
1973
2042
|
}
|
|
@@ -1982,16 +2051,16 @@ class B {
|
|
|
1982
2051
|
z = JSON.parse(JSON.stringify(z)), z.sort((q, Y) => (q.positionTime || 0) - (Y.positionTime || 0));
|
|
1983
2052
|
let b = Number.MAX_SAFE_INTEGER, p = Number.MAX_SAFE_INTEGER;
|
|
1984
2053
|
for (let q = 0; q < z.length - 1; q++) {
|
|
1985
|
-
const Y = z[q], d = z[q + 1], R =
|
|
2054
|
+
const Y = z[q], d = z[q + 1], R = r.calculatePointToLineDistance(M, Y, d);
|
|
1986
2055
|
R < b && (b = R, p = q);
|
|
1987
2056
|
}
|
|
1988
|
-
const c = z[p], O = z[p + 1], A =
|
|
2057
|
+
const c = z[p], O = z[p + 1], A = r.calculateDistance(c, M), W = r.calculateDistance(O, M);
|
|
1989
2058
|
if (A === 0)
|
|
1990
2059
|
M = c;
|
|
1991
2060
|
else if (W === 0)
|
|
1992
2061
|
M = O;
|
|
1993
2062
|
else {
|
|
1994
|
-
const q = c.positionTime || 0, Y = O.positionTime || 0, d =
|
|
2063
|
+
const q = c.positionTime || 0, Y = O.positionTime || 0, d = r.calculateDistance(c, O);
|
|
1995
2064
|
M.positionTime = Math.round(q + (Y - q) * (A / d));
|
|
1996
2065
|
}
|
|
1997
2066
|
return M.utc = M.positionTime ? u.unix(M.positionTime).utc().format() : void 0, M.positionTime ? M : void 0;
|
|
@@ -2031,6 +2100,7 @@ class B {
|
|
|
2031
2100
|
/**
|
|
2032
2101
|
* 路径摘要
|
|
2033
2102
|
* @param coordinates 已排序的坐标
|
|
2103
|
+
* @param slowSpd 排出停航时间
|
|
2034
2104
|
* @return {
|
|
2035
2105
|
* begin: string, // 开始时间
|
|
2036
2106
|
* end: string, // 结束时间
|
|
@@ -2039,15 +2109,21 @@ class B {
|
|
|
2039
2109
|
* avgSpeed: number // 平均航速,单位节
|
|
2040
2110
|
* }
|
|
2041
2111
|
*/
|
|
2042
|
-
static coordinatesSummary(M) {
|
|
2112
|
+
static coordinatesSummary(M, z = 3) {
|
|
2043
2113
|
if (M.length > 1) {
|
|
2044
|
-
const
|
|
2114
|
+
const b = M[0], p = M[M.length - 1], c = (b == null ? void 0 : b.positionTime) < (p == null ? void 0 : p.positionTime) ? u.unix(b == null ? void 0 : b.positionTime) : u.unix(p == null ? void 0 : p.positionTime), O = (b == null ? void 0 : b.positionTime) > (p == null ? void 0 : p.positionTime) ? u.unix(b == null ? void 0 : b.positionTime) : u.unix(p == null ? void 0 : p.positionTime), A = Math.round(O.diff(c, "hours", !0) * 100) / 100, W = this.generateRouteAccordingToWaypoints(M, !0, !0), q = this.calculateRouteDistance(W), d = B0.inspectStoppages(M, z).reduce(
|
|
2115
|
+
(T, N) => (T.duration += N.duration, T.distance += N.distance, T),
|
|
2116
|
+
{ hours: 0, distance: 0, spd: 0, duration: 0 }
|
|
2117
|
+
);
|
|
2118
|
+
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;
|
|
2119
|
+
const R = A ? Math.round(q / (A - d.hours) * 100) / 100 : 0;
|
|
2045
2120
|
return {
|
|
2046
|
-
begin:
|
|
2047
|
-
end:
|
|
2048
|
-
distance:
|
|
2049
|
-
hours:
|
|
2050
|
-
avgSpeed:
|
|
2121
|
+
begin: c.utc().format(),
|
|
2122
|
+
end: O.utc().format(),
|
|
2123
|
+
distance: q,
|
|
2124
|
+
hours: A - d.hours,
|
|
2125
|
+
avgSpeed: R,
|
|
2126
|
+
stoppage: d
|
|
2051
2127
|
};
|
|
2052
2128
|
}
|
|
2053
2129
|
return {
|
|
@@ -2074,18 +2150,17 @@ class B {
|
|
|
2074
2150
|
const b = z.sample.hours.at(0), p = u.utc(M), c = u.utc(z.eta), O = p.isAfter(c) ? c : p;
|
|
2075
2151
|
let A = z.sample.hours.find((T) => T.eta === O.format());
|
|
2076
2152
|
if (!A) {
|
|
2077
|
-
const T = z.sample.hours.filter((
|
|
2078
|
-
A = (R = this.calculateNextCoordinateAlongRoute(T, T.speed * O.diff(u(T.etd), "hours", !0),
|
|
2079
|
-
const {
|
|
2153
|
+
const T = z.sample.hours.filter((G) => u.utc(G.eta).isBefore(O)).at(-1), N = this.calculateSubRoute(T, z.route);
|
|
2154
|
+
A = (R = this.calculateNextCoordinateAlongRoute(T, T.speed * O.diff(u(T.etd), "hours", !0), N)) == null ? void 0 : R.coordinate;
|
|
2155
|
+
const { cFactor: i, cog: f, wxFactor: s, meteo: P } = T, l = Math.round(A.distanceFromPrevious * 1e4) / 1e4, B = Math.round((l + T.distanceFromStart) * 1e4) / 1e4;
|
|
2080
2156
|
A = {
|
|
2081
2157
|
...A,
|
|
2082
|
-
cFactor:
|
|
2083
|
-
|
|
2084
|
-
cog: s,
|
|
2158
|
+
cFactor: i,
|
|
2159
|
+
cog: f,
|
|
2085
2160
|
speed: T.speed,
|
|
2086
|
-
wxFactor:
|
|
2087
|
-
distanceFromStart:
|
|
2088
|
-
distanceFromPrevious:
|
|
2161
|
+
wxFactor: s,
|
|
2162
|
+
distanceFromStart: B,
|
|
2163
|
+
distanceFromPrevious: l,
|
|
2089
2164
|
meteo: P,
|
|
2090
2165
|
eta: O.format(),
|
|
2091
2166
|
etd: O.format()
|
|
@@ -2137,14 +2212,14 @@ try {
|
|
|
2137
2212
|
} catch {
|
|
2138
2213
|
} finally {
|
|
2139
2214
|
}
|
|
2140
|
-
class
|
|
2215
|
+
class V0 {
|
|
2141
2216
|
/**
|
|
2142
2217
|
* 将原始数据转换为geojson
|
|
2143
2218
|
* @param raw
|
|
2144
2219
|
*/
|
|
2145
2220
|
static convert2Geojson(M) {
|
|
2146
2221
|
var b, p, c;
|
|
2147
|
-
const z =
|
|
2222
|
+
const z = S.featureCollection([]);
|
|
2148
2223
|
for (const O of M) {
|
|
2149
2224
|
const A = (b = O.history) == null ? void 0 : b[0];
|
|
2150
2225
|
if (O.forecasts) {
|
|
@@ -2153,35 +2228,35 @@ class t0 {
|
|
|
2153
2228
|
let q;
|
|
2154
2229
|
const Y = [], d = [], R = u(W.date).utc(), T = `${O.name}-${W.model}`;
|
|
2155
2230
|
for (const i in W == null ? void 0 : W.hours) {
|
|
2156
|
-
const
|
|
2157
|
-
q = q ||
|
|
2158
|
-
const s = R.clone().add(Number(i), "hour"),
|
|
2231
|
+
const f = W.hours[i];
|
|
2232
|
+
q = q || f;
|
|
2233
|
+
const s = R.clone().add(Number(i), "hour"), P = S.point([f.lng, f.lat], {
|
|
2159
2234
|
model: W.model,
|
|
2160
2235
|
name: O.name,
|
|
2161
2236
|
nameCn: O.nameCn,
|
|
2162
2237
|
date: s.format(),
|
|
2163
2238
|
hour: Number(i),
|
|
2164
2239
|
format: s.format("MMM-DD/HHmm[Z]"),
|
|
2165
|
-
pressure:
|
|
2166
|
-
gusts:
|
|
2167
|
-
wind:
|
|
2168
|
-
movement:
|
|
2240
|
+
pressure: f.pressure > 1e4 ? a.roundPrecision(f.pressure / 100, 0) : a.roundPrecision(f.pressure, 0),
|
|
2241
|
+
gusts: f.gusts,
|
|
2242
|
+
wind: f.wind || {},
|
|
2243
|
+
movement: f.movement,
|
|
2169
2244
|
category: T,
|
|
2170
2245
|
type: "forecast"
|
|
2171
2246
|
});
|
|
2172
|
-
d.push(
|
|
2247
|
+
d.push(P), Y.push(P.geometry.coordinates);
|
|
2173
2248
|
}
|
|
2174
|
-
const
|
|
2249
|
+
const N = {
|
|
2175
2250
|
kts: void 0,
|
|
2176
2251
|
deg: void 0
|
|
2177
2252
|
};
|
|
2178
2253
|
if (A) {
|
|
2179
2254
|
const i = u(A.updated).utc();
|
|
2180
2255
|
if (q) {
|
|
2181
|
-
const s =
|
|
2182
|
-
|
|
2256
|
+
const s = r.calculateDistance(A, q), P = u(q.utc || q.updated).diff(i, "h", !0);
|
|
2257
|
+
N.kts = Math.round(s / P * 100) / 100, N.deg = r.calculateBearing(A, q, !0, 0);
|
|
2183
2258
|
}
|
|
2184
|
-
const
|
|
2259
|
+
const f = S.point([A.lng, A.lat], {
|
|
2185
2260
|
model: W.model,
|
|
2186
2261
|
name: O.name,
|
|
2187
2262
|
nameCn: O.nameCn,
|
|
@@ -2190,23 +2265,23 @@ class t0 {
|
|
|
2190
2265
|
format: i.format("MMM-DD/HHmm[Z]"),
|
|
2191
2266
|
pressure: A.pressure > 1e4 ? a.roundPrecision((A == null ? void 0 : A.pressure) / 100, 0) : a.roundPrecision(A.pressure, 0),
|
|
2192
2267
|
wind: A.wind,
|
|
2193
|
-
movement:
|
|
2268
|
+
movement: N,
|
|
2194
2269
|
category: T,
|
|
2195
2270
|
type: "forecast",
|
|
2196
2271
|
important: !0
|
|
2197
2272
|
// 第一个预报点为重要点
|
|
2198
2273
|
});
|
|
2199
|
-
d.unshift(
|
|
2274
|
+
d.unshift(f), Y.unshift(f.geometry.coordinates);
|
|
2200
2275
|
}
|
|
2201
2276
|
if (z.features.push(...d), (Y == null ? void 0 : Y.length) > 1) {
|
|
2202
|
-
const i =
|
|
2277
|
+
const i = S.lineString(a.convertToMonotonicLng2(Y), {
|
|
2203
2278
|
date: (A == null ? void 0 : A.updated) || (R == null ? void 0 : R.format()),
|
|
2204
2279
|
id: O.id || O.name,
|
|
2205
2280
|
model: W.model,
|
|
2206
2281
|
name: O.name,
|
|
2207
2282
|
category: T,
|
|
2208
2283
|
type: "forecast",
|
|
2209
|
-
movement:
|
|
2284
|
+
movement: N
|
|
2210
2285
|
});
|
|
2211
2286
|
z.features.push(i);
|
|
2212
2287
|
}
|
|
@@ -2215,9 +2290,9 @@ class t0 {
|
|
|
2215
2290
|
if (z.features.sort((W, q) => W.properties.type === "forecast" && q.properties.type === "forecast" && W.geometry.type === "Point" && q.geometry.type === "Point" ? u(W.properties.date).valueOf() - u(q.properties.date).valueOf() : 0), (p = O.history) != null && p.length) {
|
|
2216
2291
|
const W = [], q = u(A == null ? void 0 : A.updated).utc(), Y = u((c = O.history) == null ? void 0 : c.at(-1).updated).utc(), d = q.diff(Y, "h") % 24 > 2 ? 24 : 12;
|
|
2217
2292
|
for (const R of O.history) {
|
|
2218
|
-
const T = u(R.updated).utc(),
|
|
2219
|
-
|
|
2220
|
-
const i =
|
|
2293
|
+
const T = u(R.updated).utc(), N = T.isSameOrBefore(q) || T.isSame(Y);
|
|
2294
|
+
N && q.add(-d, "h");
|
|
2295
|
+
const i = S.point([R.lng, R.lat], {
|
|
2221
2296
|
name: O.name,
|
|
2222
2297
|
nameCn: O.nameCn,
|
|
2223
2298
|
date: T.format(),
|
|
@@ -2229,12 +2304,12 @@ class t0 {
|
|
|
2229
2304
|
category: `${O.name}-history`,
|
|
2230
2305
|
wind: R.wind,
|
|
2231
2306
|
movement: R.movement,
|
|
2232
|
-
important:
|
|
2307
|
+
important: N
|
|
2233
2308
|
});
|
|
2234
2309
|
z.features.push(i), W.push(i.geometry.coordinates);
|
|
2235
2310
|
}
|
|
2236
2311
|
if (W.length === 1 && W.push(W[0]), W.length > 1) {
|
|
2237
|
-
const R =
|
|
2312
|
+
const R = S.lineString(a.convertToMonotonicLng2(W), {
|
|
2238
2313
|
name: O.name,
|
|
2239
2314
|
type: "history",
|
|
2240
2315
|
updated: A == null ? void 0 : A.updated,
|
|
@@ -2257,32 +2332,32 @@ class t0 {
|
|
|
2257
2332
|
var c, O, A, W;
|
|
2258
2333
|
const b = (c = M == null ? void 0 : M.data) == null ? void 0 : c.features.filter((q) => q.geometry.type === "LineString" && q.properties.type === "forecast"), p = [];
|
|
2259
2334
|
for (const q of b) {
|
|
2260
|
-
const Y = q.properties.name, d = q.properties.model, R = q.properties.showCircle, T = q.properties.disabled,
|
|
2335
|
+
const Y = q.properties.name, d = q.properties.model, R = q.properties.showCircle, T = q.properties.disabled, N = u(q.properties.date).utc();
|
|
2261
2336
|
let i = z * 60;
|
|
2262
|
-
const
|
|
2263
|
-
(
|
|
2337
|
+
const f = (O = M == null ? void 0 : M.data) == null ? void 0 : O.features.filter(
|
|
2338
|
+
(l) => l.geometry.type === "Point" && l.properties.type === "forecast" && l.properties.category === `${Y}-${d}`
|
|
2264
2339
|
);
|
|
2265
|
-
let s,
|
|
2266
|
-
for (; s = this.pickIndex(
|
|
2340
|
+
let s, P = N.clone().add(i, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
2341
|
+
for (; s = this.pickIndex(f, P), s <= f.length - 1; ) {
|
|
2267
2342
|
if (s > 0) {
|
|
2268
|
-
const
|
|
2343
|
+
const l = f[s], B = s === 0 ? void 0 : f[s - 1], G = (i / 60 - ((A = B == null ? void 0 : B.properties) == null ? void 0 : A.hour)) / (l.properties.hour - ((W = B == null ? void 0 : B.properties) == null ? void 0 : W.hour)), H = this.computeNumber(B == null ? void 0 : B.geometry.coordinates[0], l.geometry.coordinates[0], G), F = this.computeNumber(B == null ? void 0 : B.geometry.coordinates[1], l.geometry.coordinates[1], G), $ = S.point([H, F], {
|
|
2269
2344
|
name: Y,
|
|
2270
2345
|
model: d,
|
|
2271
|
-
category:
|
|
2272
|
-
date:
|
|
2273
|
-
format:
|
|
2274
|
-
gusts: this.computeNumber(
|
|
2275
|
-
hour: this.computeNumber(
|
|
2276
|
-
movement: this.computeNumber(
|
|
2277
|
-
pressure: this.computeNumber(
|
|
2278
|
-
wind: this.computeNumber(
|
|
2346
|
+
category: l == null ? void 0 : l.properties.category,
|
|
2347
|
+
date: P.format(),
|
|
2348
|
+
format: P.format("MMM-DD/HHmm[Z]"),
|
|
2349
|
+
gusts: this.computeNumber(B == null ? void 0 : B.properties.gusts, l.properties.gusts, G),
|
|
2350
|
+
hour: this.computeNumber(B == null ? void 0 : B.properties.hour, l.properties.hour, G),
|
|
2351
|
+
movement: this.computeNumber(B == null ? void 0 : B.properties.movement, l.properties.movement, G),
|
|
2352
|
+
pressure: this.computeNumber(B == null ? void 0 : B.properties.pressure, l.properties.pressure, G),
|
|
2353
|
+
wind: this.computeNumber(B == null ? void 0 : B.properties.wind, l.properties.wind, G),
|
|
2279
2354
|
type: "forecast",
|
|
2280
2355
|
disabled: T,
|
|
2281
2356
|
showCircle: R
|
|
2282
2357
|
});
|
|
2283
2358
|
p.push($);
|
|
2284
2359
|
}
|
|
2285
|
-
i += z * 60,
|
|
2360
|
+
i += z * 60, P = N.clone().add(i, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
2286
2361
|
}
|
|
2287
2362
|
}
|
|
2288
2363
|
return p;
|
|
@@ -2312,19 +2387,19 @@ class t0 {
|
|
|
2312
2387
|
const { t1: c, t2: O, hr: A, hours: W } = this.tropicalCenterTwin(z, 24, p);
|
|
2313
2388
|
if (c && O) {
|
|
2314
2389
|
if (!p.debug) {
|
|
2315
|
-
const
|
|
2316
|
-
if (
|
|
2317
|
-
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", p.requestId,
|
|
2390
|
+
const N = r.calculateDistance(M, c), i = r.calculateDistance(M, O);
|
|
2391
|
+
if (N > 2 * b && i > 2 * b)
|
|
2392
|
+
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", p.requestId, N, i, {
|
|
2318
2393
|
from: M,
|
|
2319
2394
|
t1: c,
|
|
2320
2395
|
t2: O,
|
|
2321
2396
|
hr: A
|
|
2322
2397
|
}), {};
|
|
2323
2398
|
}
|
|
2324
|
-
const q =
|
|
2399
|
+
const q = r.calculateBearing(M, c), Y = r.calculateBearing(c, O), d = Math.abs(q - Y);
|
|
2325
2400
|
let R = 0;
|
|
2326
2401
|
d < 180 ? R = d + 90 : d >= 180 && (R = d - 90);
|
|
2327
|
-
const T =
|
|
2402
|
+
const T = r.calculateCoordinate(c, R, b);
|
|
2328
2403
|
return I == null || I.info("[%s] the right tangent position: %j", p.requestId, {
|
|
2329
2404
|
from: M,
|
|
2330
2405
|
t1: c,
|
|
@@ -2351,17 +2426,17 @@ class t0 {
|
|
|
2351
2426
|
const { t1: c, t2: O, hr: A, hours: W } = this.tropicalCenterTwin(z, 24, p);
|
|
2352
2427
|
if (c && O) {
|
|
2353
2428
|
if (!p.debug) {
|
|
2354
|
-
const T =
|
|
2355
|
-
if (T > 2 * b &&
|
|
2356
|
-
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", p.requestId, T,
|
|
2429
|
+
const T = r.calculateDistance(M, c), N = r.calculateDistance(M, O);
|
|
2430
|
+
if (T > 2 * b && N > 2 * b)
|
|
2431
|
+
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", p.requestId, T, N, {
|
|
2357
2432
|
from: M,
|
|
2358
2433
|
t1: c,
|
|
2359
2434
|
t2: O,
|
|
2360
2435
|
hr: A
|
|
2361
2436
|
}), {};
|
|
2362
2437
|
}
|
|
2363
|
-
const q =
|
|
2364
|
-
return { at:
|
|
2438
|
+
const q = r.calculateBearing(M, c), Y = r.calculateBearing(c, O), d = r.calculateDistance(M, c);
|
|
2439
|
+
return { at: r.calculateCoordinate(c, q - Y + 180, b < d ? b : d), t1: c, t2: O, hr: Number(A), hours: W };
|
|
2365
2440
|
} else
|
|
2366
2441
|
return I == null || I.info("[%s] no need drift: %j", p.requestId, { from: M, t1: c, t2: O, hr: A }), {};
|
|
2367
2442
|
}
|
|
@@ -2374,7 +2449,7 @@ class t0 {
|
|
|
2374
2449
|
* @private
|
|
2375
2450
|
*/
|
|
2376
2451
|
static tropicalCenterTwin(M, z = 24, b = {}) {
|
|
2377
|
-
var Y, d, R, T,
|
|
2452
|
+
var Y, d, R, T, N;
|
|
2378
2453
|
let p = {};
|
|
2379
2454
|
(Y = M.forecasts) == null || Y.forEach((i) => {
|
|
2380
2455
|
p = { ...i.hours, ...p };
|
|
@@ -2382,7 +2457,7 @@ class t0 {
|
|
|
2382
2457
|
const c = ((d = M == null ? void 0 : M.history) == null ? void 0 : d[0]) || (p == null ? void 0 : p[(R = Object.keys(p)) == null ? void 0 : R[0]]);
|
|
2383
2458
|
I == null || I.info("[%s] the first tropical center: %j", b.requestId, c);
|
|
2384
2459
|
let O = (T = Object.keys(p || {}).filter((i) => Number(i) <= (z < 0 ? 24 : z))) == null ? void 0 : T.at(-1);
|
|
2385
|
-
O || (O = (
|
|
2460
|
+
O || (O = (N = Object.keys(p || {}).filter((i) => Number(i) <= (z < 0 ? 24 : 2 * z))) == null ? void 0 : N.at(-1));
|
|
2386
2461
|
const A = p == null ? void 0 : p[O || -1];
|
|
2387
2462
|
I == null || I.info("[%s] the second tropical center: %j in %d hrs", b.requestId, A, O);
|
|
2388
2463
|
const W = Object.keys(p || {}).filter((i) => Number(i) <= Number(O)), q = { 0: c };
|
|
@@ -2415,78 +2490,9 @@ class t0 {
|
|
|
2415
2490
|
return z;
|
|
2416
2491
|
}
|
|
2417
2492
|
}
|
|
2418
|
-
class V0 {
|
|
2419
|
-
static json2Str(M) {
|
|
2420
|
-
const z = M.type ? M.type[0].toUpperCase() : "A";
|
|
2421
|
-
return `${M.lat}|${M.lng}|${M.positionTime}|${M.sog}|${M.cog}|${M.hdg}|${M.draught}|${z}|${JSON.stringify(M.meteo || {})}|${M.vendor}|${M.deleted}`;
|
|
2422
|
-
}
|
|
2423
|
-
static str2Json(M) {
|
|
2424
|
-
const [z, b, p, c, O, A, W, q, Y, d, R] = M.split("|");
|
|
2425
|
-
return {
|
|
2426
|
-
lat: Number(z),
|
|
2427
|
-
lng: Number(b),
|
|
2428
|
-
positionTime: Number(p),
|
|
2429
|
-
sog: Number(c),
|
|
2430
|
-
cog: Number(O),
|
|
2431
|
-
hdg: Number(A),
|
|
2432
|
-
//@ts-ignore
|
|
2433
|
-
draught: isNaN(W) ? null : Number(W),
|
|
2434
|
-
type: q,
|
|
2435
|
-
important: q !== "A",
|
|
2436
|
-
meteo: Y ? JSON.parse(Y) : void 0,
|
|
2437
|
-
vendor: d,
|
|
2438
|
-
deleted: R === "true"
|
|
2439
|
-
};
|
|
2440
|
-
}
|
|
2441
|
-
static inspectStoppages(M, z = 1, b = !0) {
|
|
2442
|
-
const p = M.at(0).positionTime < M.at(-1).positionTime;
|
|
2443
|
-
p || M.sort((W, q) => W.positionTime - q.positionTime);
|
|
2444
|
-
const c = [];
|
|
2445
|
-
let O, A;
|
|
2446
|
-
for (let W = 0; W < M.length - 1; W++) {
|
|
2447
|
-
const q = M[W];
|
|
2448
|
-
if (!(b && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(q.type))) {
|
|
2449
|
-
for (let Y = W + 1; Y < M.length; Y++) {
|
|
2450
|
-
const d = M[Y - 1], R = M[Y];
|
|
2451
|
-
if (b && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(q.type))
|
|
2452
|
-
continue;
|
|
2453
|
-
const T = R.positionTime - d.positionTime;
|
|
2454
|
-
if (B.calculateDistance(R, d, !0, 4) / (T / 3600) < z)
|
|
2455
|
-
O || (O = q), Y === M.length - 1 && (A = R, W = Y);
|
|
2456
|
-
else {
|
|
2457
|
-
O && (A = M[Y - 1], W = Y);
|
|
2458
|
-
break;
|
|
2459
|
-
}
|
|
2460
|
-
}
|
|
2461
|
-
if ((A == null ? void 0 : A.positionTime) > (O == null ? void 0 : O.positionTime) && O) {
|
|
2462
|
-
const Y = {
|
|
2463
|
-
start: {
|
|
2464
|
-
lat: O.lat,
|
|
2465
|
-
lng: O.lng,
|
|
2466
|
-
sog: O.sog,
|
|
2467
|
-
positionTime: O.positionTime,
|
|
2468
|
-
utc: u.unix(O.positionTime).utc().format()
|
|
2469
|
-
},
|
|
2470
|
-
end: {
|
|
2471
|
-
lat: A.lat,
|
|
2472
|
-
lng: A.lng,
|
|
2473
|
-
sog: A.sog,
|
|
2474
|
-
positionTime: A.positionTime,
|
|
2475
|
-
utc: u.unix(A.positionTime).utc().format()
|
|
2476
|
-
},
|
|
2477
|
-
duration: A.positionTime - O.positionTime
|
|
2478
|
-
}, d = M.filter((T) => T.positionTime >= Y.start.positionTime && T.positionTime <= Y.end.positionTime), R = B.divideAccordingToLng(d);
|
|
2479
|
-
Y.distance = B.calculateRouteDistance(R), Y.hours = Math.round(Y.duration / 3600 * 10) / 10, Y.avgSog = Math.round(Y.distance / Y.hours * 10) / 10, c.push(Y);
|
|
2480
|
-
}
|
|
2481
|
-
O = void 0, A = void 0;
|
|
2482
|
-
}
|
|
2483
|
-
}
|
|
2484
|
-
return p || M.sort((W, q) => q.positionTime - W.positionTime), c;
|
|
2485
|
-
}
|
|
2486
|
-
}
|
|
2487
2493
|
export {
|
|
2488
|
-
|
|
2489
|
-
|
|
2494
|
+
B0 as AisHelper,
|
|
2495
|
+
r as LaneHelper,
|
|
2490
2496
|
a as LngLatHelper,
|
|
2491
|
-
|
|
2497
|
+
V0 as TropicalHelper
|
|
2492
2498
|
};
|