@idm-plugin/geo 2.2.5 → 2.2.6
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 +249 -230
- package/dist/index.umd.cjs +7 -6
- package/dist/lane/src/index.d.ts +10 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as T from "@turf/turf";
|
|
2
2
|
import b from "moment";
|
|
3
|
-
import
|
|
3
|
+
import z from "@log4js-node/log4js-api";
|
|
4
4
|
import "moment-timezone";
|
|
5
5
|
import V from "tz-lookup";
|
|
6
6
|
import J from "shpjs";
|
|
@@ -35,13 +35,13 @@ class d {
|
|
|
35
35
|
t < 0 && (s = "W"), t = Math.abs(t), n = n.toUpperCase();
|
|
36
36
|
let o = t * 3600, r, i, c, a, l, u;
|
|
37
37
|
r = o % 3600 % 60, n.indexOf("S") !== -1 && (o = o - r, i = d.padNumber(r, 2, 2)), c = o / 60 % 60, n.indexOf("M") !== -1 && (n.indexOf("S") !== -1 ? a = d.roundPrecision(c, e).toString().padStart(2, "0") : a = d.padNumber(c, 2, 3), o = o - c * 60), l = o / 3600, n.indexOf("M") !== -1 ? u = d.roundPrecision(l, e).toString().padStart(3, "0") : u = d.padNumber(l, 3, 6), Number(i) >= 60 && (a = Number(a) + 1, i = 0), Number(a) >= 60 && (u = Number(u) + 1, a = 0);
|
|
38
|
-
const
|
|
38
|
+
const m = `${n.replace(/S+/gi, i).replace(/M+/gi, a).replace(/H+/gi, u)}${s}`;
|
|
39
39
|
return {
|
|
40
40
|
direction: s,
|
|
41
41
|
degree: d.roundPrecision(l, e),
|
|
42
42
|
minute: d.roundPrecision(c, e),
|
|
43
43
|
second: d.roundPrecision(r, e),
|
|
44
|
-
pretty:
|
|
44
|
+
pretty: m,
|
|
45
45
|
S: i,
|
|
46
46
|
M: a,
|
|
47
47
|
H: u
|
|
@@ -59,13 +59,13 @@ class d {
|
|
|
59
59
|
t < 0 && (s = "S"), t = Math.abs(t), n = n.toUpperCase();
|
|
60
60
|
let o = t * 3600, r, i, c, a, l, u;
|
|
61
61
|
r = o % 3600 % 60, n.indexOf("S") !== -1 && (o = o - r, i = d.padNumber(r, 2, 2)), c = o / 60 % 60, n.indexOf("M") !== -1 && (n.indexOf("S") !== -1 ? a = d.roundPrecision(c, e).toString().padStart(2, "0") : a = d.padNumber(c, 2, 3), o = o - c * 60), l = o / 3600, n.indexOf("M") !== -1 ? u = d.roundPrecision(l, e).toString().padStart(2, "0") : u = d.padNumber(l, 2, 6), Number(i) >= 60 && (a = Number(a) + 1, i = 0), Number(a) >= 60 && (u = Number(u) + 1, a = 0);
|
|
62
|
-
const
|
|
62
|
+
const m = `${n.replace(/S+/gi, i).replace(/M+/gi, a).replace(/H+/gi, u)}${s}`;
|
|
63
63
|
return {
|
|
64
64
|
direction: s,
|
|
65
65
|
degree: d.roundPrecision(l, e),
|
|
66
66
|
minute: d.roundPrecision(c, e),
|
|
67
67
|
second: d.roundPrecision(r, e),
|
|
68
|
-
pretty:
|
|
68
|
+
pretty: m,
|
|
69
69
|
S: i,
|
|
70
70
|
M: a,
|
|
71
71
|
H: u
|
|
@@ -170,7 +170,7 @@ class K {
|
|
|
170
170
|
return `${t.lat}|${t.lng}|${t.positionTime}|${t.sog}|${t.cog}|${t.hdg}|${t.draught}|${e}|${JSON.stringify(t.meteo || {})}|${t.vendor}|${t.deleted}`;
|
|
171
171
|
}
|
|
172
172
|
static str2Json(t) {
|
|
173
|
-
const [e, n, s, o, r, i, c, a, l, u,
|
|
173
|
+
const [e, n, s, o, r, i, c, a, l, u, m] = t.split("|");
|
|
174
174
|
return {
|
|
175
175
|
lat: Number(e),
|
|
176
176
|
lng: Number(n),
|
|
@@ -184,7 +184,7 @@ class K {
|
|
|
184
184
|
important: a !== "A",
|
|
185
185
|
meteo: l ? JSON.parse(l) : void 0,
|
|
186
186
|
vendor: u,
|
|
187
|
-
deleted:
|
|
187
|
+
deleted: m === "true"
|
|
188
188
|
};
|
|
189
189
|
}
|
|
190
190
|
static inspectStoppages(t, e = 1, n = !0) {
|
|
@@ -196,12 +196,12 @@ class K {
|
|
|
196
196
|
const a = t[c];
|
|
197
197
|
if (!(n && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(a.type))) {
|
|
198
198
|
for (let l = c + 1; l < t.length; l++) {
|
|
199
|
-
const u = t[l - 1],
|
|
199
|
+
const u = t[l - 1], m = t[l];
|
|
200
200
|
if (n && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(a.type))
|
|
201
201
|
continue;
|
|
202
|
-
const h =
|
|
203
|
-
if (v.calculateDistance(
|
|
204
|
-
r || (r = a), l === t.length - 1 && (i =
|
|
202
|
+
const h = m.positionTime - u.positionTime;
|
|
203
|
+
if (v.calculateDistance(m, u, !0, 4) / (h / 3600) < e)
|
|
204
|
+
r || (r = a), l === t.length - 1 && (i = m, c = l);
|
|
205
205
|
else {
|
|
206
206
|
r && (i = t[l - 1], c = l);
|
|
207
207
|
break;
|
|
@@ -224,8 +224,8 @@ class K {
|
|
|
224
224
|
utc: b.unix(i.positionTime).utc().format()
|
|
225
225
|
},
|
|
226
226
|
duration: i.positionTime - r.positionTime
|
|
227
|
-
}, u = t.filter((h) => h.positionTime >= l.start.positionTime && h.positionTime <= l.end.positionTime),
|
|
228
|
-
l.distance = v.calculateRouteDistance(
|
|
227
|
+
}, u = t.filter((h) => h.positionTime >= l.start.positionTime && h.positionTime <= l.end.positionTime), m = v.divideAccordingToLng(u);
|
|
228
|
+
l.distance = v.calculateRouteDistance(m), l.hours = Math.round(l.duration / 3600 * 10) / 10, l.avgSog = Math.round(l.distance / l.hours * 10) / 10, o.push(l);
|
|
229
229
|
}
|
|
230
230
|
r = void 0, i = void 0;
|
|
231
231
|
}
|
|
@@ -243,8 +243,8 @@ class K {
|
|
|
243
243
|
let i = 0, c = 0;
|
|
244
244
|
if (r.length > 1)
|
|
245
245
|
for (let l = 0; l < r.length - 1; l++) {
|
|
246
|
-
const u = r[l],
|
|
247
|
-
i += v.calculateDistance(u,
|
|
246
|
+
const u = r[l], m = r[l + 1];
|
|
247
|
+
i += v.calculateDistance(u, m, !0, 4), c += Math.abs(m.positionTime - u.positionTime);
|
|
248
248
|
}
|
|
249
249
|
i = Math.round(i * 100) / 100, c = Math.round(c / 3600 * 100) / 100;
|
|
250
250
|
const a = c ? Math.round(i / c * 100) / 100 : 0;
|
|
@@ -253,11 +253,11 @@ class K {
|
|
|
253
253
|
}
|
|
254
254
|
let X;
|
|
255
255
|
try {
|
|
256
|
-
X =
|
|
256
|
+
X = z.getLogger("meteo");
|
|
257
257
|
} catch {
|
|
258
258
|
} finally {
|
|
259
259
|
}
|
|
260
|
-
const
|
|
260
|
+
const Y = (() => {
|
|
261
261
|
const C = new Uint32Array(256);
|
|
262
262
|
for (let t = 0; t < 256; t++) {
|
|
263
263
|
let e = t;
|
|
@@ -267,36 +267,36 @@ const Q = (() => {
|
|
|
267
267
|
}
|
|
268
268
|
return C;
|
|
269
269
|
})();
|
|
270
|
-
function
|
|
270
|
+
function Q(C) {
|
|
271
271
|
let t = 4294967295;
|
|
272
272
|
for (let e = 0; e < C.length; e++)
|
|
273
|
-
t =
|
|
273
|
+
t = Y[(t ^ C[e]) & 255] ^ t >>> 8;
|
|
274
274
|
return (t ^ 4294967295) >>> 0;
|
|
275
275
|
}
|
|
276
276
|
function _(C) {
|
|
277
277
|
const t = new TextEncoder(), e = [], n = [];
|
|
278
278
|
let s = 0;
|
|
279
279
|
for (const h of C) {
|
|
280
|
-
const
|
|
281
|
-
|
|
280
|
+
const p = t.encode(h.name), f = Q(h.data), g = new Uint8Array(30 + p.length), y = new DataView(g.buffer);
|
|
281
|
+
y.setUint32(0, 67324752, !0), y.setUint16(4, 20, !0), y.setUint16(8, 0, !0), y.setUint32(14, f, !0), y.setUint32(18, h.data.length, !0), y.setUint32(22, h.data.length, !0), y.setUint16(26, p.length, !0), g.set(p, 30), e.push({ nameBytes: p, data: h.data, crc: f, offset: s }), s += g.length + h.data.length, n.push(g, h.data);
|
|
282
282
|
}
|
|
283
283
|
const o = s, r = [];
|
|
284
284
|
let i = 0;
|
|
285
285
|
for (const h of e) {
|
|
286
|
-
const
|
|
287
|
-
|
|
286
|
+
const p = new Uint8Array(46 + h.nameBytes.length), f = new DataView(p.buffer);
|
|
287
|
+
f.setUint32(0, 33639248, !0), f.setUint16(4, 20, !0), f.setUint16(6, 20, !0), f.setUint16(10, 0, !0), f.setUint32(16, h.crc, !0), f.setUint32(20, h.data.length, !0), f.setUint32(24, h.data.length, !0), f.setUint16(28, h.nameBytes.length, !0), f.setUint32(42, h.offset, !0), p.set(h.nameBytes, 46), i += p.length, r.push(p);
|
|
288
288
|
}
|
|
289
289
|
const c = new Uint8Array(22), a = new DataView(c.buffer);
|
|
290
290
|
a.setUint32(0, 101010256, !0), a.setUint16(8, e.length, !0), a.setUint16(10, e.length, !0), a.setUint32(12, i, !0), a.setUint32(16, o, !0);
|
|
291
|
-
const l = n.reduce((h,
|
|
292
|
-
let
|
|
291
|
+
const l = n.reduce((h, p) => h + p.length, 0) + i + 22, u = new Uint8Array(l);
|
|
292
|
+
let m = 0;
|
|
293
293
|
for (const h of n)
|
|
294
|
-
u.set(h,
|
|
294
|
+
u.set(h, m), m += h.length;
|
|
295
295
|
for (const h of r)
|
|
296
|
-
u.set(h,
|
|
297
|
-
return u.set(c,
|
|
296
|
+
u.set(h, m), m += h.length;
|
|
297
|
+
return u.set(c, m), u;
|
|
298
298
|
}
|
|
299
|
-
function
|
|
299
|
+
function G(C) {
|
|
300
300
|
let t = "", e = C;
|
|
301
301
|
for (; e >= 0; )
|
|
302
302
|
t = String.fromCharCode(65 + e % 26) + t, e = Math.floor(e / 26) - 1;
|
|
@@ -413,19 +413,19 @@ class v {
|
|
|
413
413
|
[r, t[c].lat],
|
|
414
414
|
[i, t[c + 1].lat]
|
|
415
415
|
]);
|
|
416
|
-
let u,
|
|
417
|
-
e ? (u = T.lineString(l),
|
|
416
|
+
let u, m;
|
|
417
|
+
e ? (u = T.lineString(l), m = T.lineString([
|
|
418
418
|
[a > 0 ? 180 : -180, 89],
|
|
419
419
|
[a > 0 ? 180 : -180, -89]
|
|
420
|
-
])) : (u = T.greatCircle(l[0], l[1]),
|
|
421
|
-
const h = T.lineIntersect(u,
|
|
422
|
-
let
|
|
420
|
+
])) : (u = T.greatCircle(l[0], l[1]), m = T.greatCircle([a > 0 ? 180 : -180, 89], [a > 0 ? 180 : -180, -89]));
|
|
421
|
+
const h = T.lineIntersect(u, m);
|
|
422
|
+
let p;
|
|
423
423
|
if (h.features.length) {
|
|
424
|
-
const
|
|
425
|
-
|
|
424
|
+
const f = T.getCoord(h.features[0]);
|
|
425
|
+
p = d.roundPrecision(f[1], 8);
|
|
426
426
|
} else
|
|
427
|
-
|
|
428
|
-
a > 0 ? (s.push([180 - 1e-6,
|
|
427
|
+
p = t[c].lat;
|
|
428
|
+
a > 0 ? (s.push([180 - 1e-6, p]), o.push([...s]), s = [], s.push([-(180 - 1e-6), p])) : (s.push([-(180 - 1e-6), p]), o.push([...s]), s = [], s.push([180 - 1e-6, p]));
|
|
429
429
|
}
|
|
430
430
|
c === t.length - 2 && s.push([i, t[c + 1].lat]);
|
|
431
431
|
}
|
|
@@ -489,8 +489,8 @@ class v {
|
|
|
489
489
|
let n = Number.MAX_VALUE, s = 0, o = 0, r, i;
|
|
490
490
|
return e.forEach((c, a) => {
|
|
491
491
|
for (let l = 0; l < c.length - 1; l++) {
|
|
492
|
-
const u = { lng: c[l][0], lat: c[l][1] },
|
|
493
|
-
n > h && (n = h, o = l, s = a, r = this.calculateDistance(u, t), i = this.calculateDistance(
|
|
492
|
+
const u = { lng: c[l][0], lat: c[l][1] }, m = { lng: c[l + 1][0], lat: c[l + 1][1] }, h = this.calculatePointToLineDistance(t, u, m);
|
|
493
|
+
n > h && (n = h, o = l, s = a, r = this.calculateDistance(u, t), i = this.calculateDistance(m, t));
|
|
494
494
|
}
|
|
495
495
|
}), r !== 0 && i !== 0 ? e[s].splice(o + 1, 0, [t.lng, t.lat]) : r === 0 ? e[s].splice(o, 1, [t.lng, t.lat]) : i === 0 && e[s].splice(o + 1, 1, [t.lng, t.lat]), e;
|
|
496
496
|
}
|
|
@@ -693,8 +693,8 @@ class v {
|
|
|
693
693
|
c.lng = d.convertToStdLng(c.lng);
|
|
694
694
|
const l = e[a + 1];
|
|
695
695
|
if (l && ((c.bearing === null || c.bearing === void 0) && ((c.positionTime || 0) > (l.positionTime || 0) ? c.bearing = this.calculateBearing(l, c, !0) : c.bearing = this.calculateBearing(c, l, !0)), c.cog = c.cog || c.bearing, !c.sog && c.positionTime && l.positionTime)) {
|
|
696
|
-
const u = this.calculateDistance(c, l, !0),
|
|
697
|
-
c.sog = d.roundPrecision(u /
|
|
696
|
+
const u = this.calculateDistance(c, l, !0), m = Math.abs(l.positionTime - c.positionTime) / 3600;
|
|
697
|
+
c.sog = d.roundPrecision(u / m, 2);
|
|
698
698
|
}
|
|
699
699
|
return c;
|
|
700
700
|
});
|
|
@@ -757,37 +757,37 @@ class v {
|
|
|
757
757
|
* @return { coordinate: {lng, lat}, route: [[[lng, lat]]]}
|
|
758
758
|
*/
|
|
759
759
|
static calculateNextCoordinateAlongRoute(t, e, n, s = "nauticalmiles") {
|
|
760
|
-
var
|
|
760
|
+
var m;
|
|
761
761
|
const o = t.speed || 12, r = [];
|
|
762
762
|
let i = [], c = !1, a = 0, l = 0, u;
|
|
763
|
-
if (e && n.length ? (r.push(t), n.forEach((h,
|
|
763
|
+
if (e && n.length ? (r.push(t), n.forEach((h, p) => {
|
|
764
764
|
if (c)
|
|
765
765
|
i.push(h);
|
|
766
766
|
else {
|
|
767
|
-
const
|
|
768
|
-
let
|
|
769
|
-
for (let
|
|
767
|
+
const f = [];
|
|
768
|
+
let g;
|
|
769
|
+
for (let y = 0; y < h.length; y++)
|
|
770
770
|
if (u)
|
|
771
|
-
|
|
771
|
+
f.push(h[y]);
|
|
772
772
|
else {
|
|
773
|
-
|
|
774
|
-
const x = this.calculateDistance(t,
|
|
773
|
+
g = { lng: h[y][0], lat: h[y][1] };
|
|
774
|
+
const x = this.calculateDistance(t, g, !0, 8, s);
|
|
775
775
|
if (a += x, a < e)
|
|
776
|
-
l += x, x && r.push(
|
|
776
|
+
l += x, x && r.push(g), t = g;
|
|
777
777
|
else {
|
|
778
778
|
if (l = e, a === e)
|
|
779
|
-
u =
|
|
779
|
+
u = g, f.push([u.lng, u.lat]);
|
|
780
780
|
else {
|
|
781
|
-
const
|
|
782
|
-
u = this.calculateCoordinate(
|
|
781
|
+
const P = a - e, S = this.calculateBearing(g, t);
|
|
782
|
+
u = this.calculateCoordinate(g, S, P, s), f.push([u.lng, u.lat]), f.push([g.lng, g.lat]);
|
|
783
783
|
}
|
|
784
784
|
c = !0;
|
|
785
785
|
}
|
|
786
786
|
}
|
|
787
|
-
|
|
787
|
+
f.length && i.push(f), p === n.length - 1 && !u && (u = g);
|
|
788
788
|
}
|
|
789
789
|
})) : (i = n, u = { ...t }), u)
|
|
790
|
-
if (r.push(u), u.distanceFromPrevious = Math.round(l * 1e4) / 1e4, u.hourFromPrevious = Math.round(l / o * 1e4) / 1e4, ((
|
|
790
|
+
if (r.push(u), u.distanceFromPrevious = Math.round(l * 1e4) / 1e4, u.hourFromPrevious = Math.round(l / o * 1e4) / 1e4, ((m = i[0]) == null ? void 0 : m.length) > 1) {
|
|
791
791
|
const h = { lng: i[0][1][0], lat: i[0][1][1] };
|
|
792
792
|
u.bearing = this.calculateBearing(u, h);
|
|
793
793
|
} else
|
|
@@ -804,8 +804,8 @@ class v {
|
|
|
804
804
|
const s = d.convertToStdLng(t.lng, 6), o = T.point([s, t.lat]), r = d.convertToStdLng(e.lng, 6), i = d.convertToStdLng(n.lng, 6), c = T.lineString([
|
|
805
805
|
[r, e.lat],
|
|
806
806
|
[i, n.lat]
|
|
807
|
-
]), a = T.nearestPointOnLine(c, o), l = T.getCoord(a), u = d.roundPrecision(l[0], 6),
|
|
808
|
-
return { lng: u, lat:
|
|
807
|
+
]), a = T.nearestPointOnLine(c, o), l = T.getCoord(a), u = d.roundPrecision(l[0], 6), m = d.roundPrecision(l[1], 6);
|
|
808
|
+
return { lng: u, lat: m, inline: !(u === r && m === e.lat) && !(u === i && m === n.lat) };
|
|
809
809
|
}
|
|
810
810
|
/**
|
|
811
811
|
* 将route转coordinate
|
|
@@ -919,8 +919,8 @@ class v {
|
|
|
919
919
|
const r = t[o - 1], i = t[o], c = t[o + 1];
|
|
920
920
|
let a = !1, l = !1;
|
|
921
921
|
if ((r.velocity || r.suspend || r.important || r.pilot || o === 1) && (a = !0, s.push(r)), i.gcToPrevious && (a || (a = !0, s.push(r)), l = !0, s.push(i), o++), c) {
|
|
922
|
-
const u = v.calculateDistance(r, i, !0),
|
|
923
|
-
Math.round(Math.acos(
|
|
922
|
+
const u = v.calculateDistance(r, i, !0), m = v.calculateDistance(i, c, !0), h = v.calculateDistance(r, c, !0), p = (Math.pow(u, 2) + Math.pow(m, 2) - Math.pow(h, 2)) / (2 * u * m);
|
|
923
|
+
Math.round(Math.acos(p) * 180 / Math.PI) < n && h > e && !l && (s.push(i), o++);
|
|
924
924
|
}
|
|
925
925
|
if (o >= t.length - 1) {
|
|
926
926
|
const u = t.at(-1);
|
|
@@ -952,10 +952,10 @@ class v {
|
|
|
952
952
|
const n = b.unix(t);
|
|
953
953
|
let s = e.find((a) => a.positionTime === n.unix());
|
|
954
954
|
if (!s) {
|
|
955
|
-
const a = (r = (o = e.filter((u) => (u == null ? void 0 : u.positionTime) < n.unix())) == null ? void 0 : o.sort((u,
|
|
955
|
+
const a = (r = (o = e.filter((u) => (u == null ? void 0 : u.positionTime) < n.unix())) == null ? void 0 : o.sort((u, m) => (u.positionTime || 0) - (m.positionTime || 0))) == null ? void 0 : r.at(-1), l = (c = (i = e.filter((u) => (u == null ? void 0 : u.positionTime) > n.unix())) == null ? void 0 : i.sort((u, m) => (u.positionTime || 0) - (m.positionTime || 0))) == null ? void 0 : c.at(0);
|
|
956
956
|
if (a && l) {
|
|
957
|
-
const u = v.calculateBearing(a, l, !0),
|
|
958
|
-
s = v.calculateCoordinate(a, u,
|
|
957
|
+
const u = v.calculateBearing(a, l, !0), m = v.calculateDistance(a, l), h = (n.unix() - a.positionTime) / (l.positionTime - a.positionTime);
|
|
958
|
+
s = v.calculateCoordinate(a, u, m * h), s.positionTime = n.unix(), s.utc = n.utc().format(), s.cog = u, s.sog = Math.round(m / ((l.positionTime - a.positionTime) / 3600) * 100) / 100;
|
|
959
959
|
} else
|
|
960
960
|
s = a || l, s && (s.utc = b.unix(s == null ? void 0 : s.positionTime).utc().format());
|
|
961
961
|
}
|
|
@@ -970,8 +970,8 @@ class v {
|
|
|
970
970
|
e = JSON.parse(JSON.stringify(e)), e.sort((a, l) => (a.positionTime || 0) - (l.positionTime || 0));
|
|
971
971
|
let n = Number.MAX_SAFE_INTEGER, s = Number.MAX_SAFE_INTEGER;
|
|
972
972
|
for (let a = 0; a < e.length - 1; a++) {
|
|
973
|
-
const l = e[a], u = e[a + 1],
|
|
974
|
-
|
|
973
|
+
const l = e[a], u = e[a + 1], m = v.calculatePointToLineDistance(t, l, u);
|
|
974
|
+
m < n && (n = m, s = a);
|
|
975
975
|
}
|
|
976
976
|
const o = e[s], r = e[s + 1], i = v.calculateDistance(o, t), c = v.calculateDistance(r, t);
|
|
977
977
|
if (i === 0)
|
|
@@ -1065,15 +1065,34 @@ class v {
|
|
|
1065
1065
|
*/
|
|
1066
1066
|
static waypoints2CSV(t, e, n) {
|
|
1067
1067
|
X.debug("keep name for waypoints2CSV for legacy compatibility only", t);
|
|
1068
|
-
const s = (n == null ? void 0 : n.precision) ?? 6, o = e.some((
|
|
1069
|
-
o &&
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1072
|
-
for (let
|
|
1073
|
-
const
|
|
1074
|
-
x.push((
|
|
1068
|
+
const s = (n == null ? void 0 : n.precision) ?? 6, o = e.some((g) => g.name), r = e.some((g) => g.description), i = e.some((g) => g.port != null), c = e.some((g) => g.stbd != null), a = e.some((g) => g.arrRad != null), l = e.some((g) => g.speed != null), u = e.some((g, y) => y > 0 && g.gcToPrevious != null), m = e.some((g) => g.bearing != null), h = e.some((g) => g.distanceFromPrevious != null), p = ["WPT No.", "Latitude", "Longitude"];
|
|
1069
|
+
o && p.push("Name"), r && p.push("Description"), u && p.push("Leg"), m && p.push("Bearing[deg]"), h && p.push("Distance[NM]"), l && p.push("Speed[kn]"), i && p.push("PORT XTD[NM]"), c && p.push("STBD XTD[NM]"), a && p.push("Arr.Rad[NM]");
|
|
1070
|
+
const f = [];
|
|
1071
|
+
f.push(p.map((g) => v.csvEscapeField(g)).join(","));
|
|
1072
|
+
for (let g = 0; g < e.length; g++) {
|
|
1073
|
+
const y = e[g], x = [];
|
|
1074
|
+
x.push((g + 1).toString()), x.push(y.lat.toFixed(s)), x.push(y.lng.toFixed(s)), o && x.push(y.name ?? ""), r && x.push(y.description ?? ""), u && x.push(g === 0 ? "" : y.gcToPrevious ? "GC" : "RL"), m && x.push(y.bearing != null ? String(y.bearing) : ""), h && x.push(y.distanceFromPrevious != null ? String(y.distanceFromPrevious) : ""), l && x.push(y.speed != null ? String(y.speed) : ""), i && x.push(y.port != null ? String(y.port) : ""), c && x.push(y.stbd != null ? String(y.stbd) : ""), a && x.push(y.arrRad != null ? String(y.arrRad) : ""), f.push(x.map((P) => v.csvEscapeField(P)).join(","));
|
|
1075
|
+
}
|
|
1076
|
+
return f.join(`
|
|
1077
|
+
`);
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* 路径导出为 JRC ECDIS CSV 格式
|
|
1081
|
+
* 符合 JRC ECDIS 路由表导入/导出规范
|
|
1082
|
+
* @param name 航线名称
|
|
1083
|
+
* @param waypoints 途径点
|
|
1084
|
+
* @param options.precision 经纬度分钟小数位数,默认3
|
|
1085
|
+
*/
|
|
1086
|
+
static waypoints2JRCCSV(t, e, n) {
|
|
1087
|
+
const s = (n == null ? void 0 : n.precision) ?? 3, o = e.some((f) => f.name), r = e.some((f) => f.port != null), i = e.some((f) => f.stbd != null), c = e.some((f) => f.arrRad != null), a = e.some((f) => f.speed != null), l = e.some((f, g) => g > 0 && f.gcToPrevious != null), u = e.some((f) => f.rot != null), m = e.some((f) => f.turnRad != null), h = ["// WPT No.", "LAT", "", "", "LON", "", ""];
|
|
1088
|
+
r && h.push("PORT[NM]"), i && h.push("STBD[NM]"), c && h.push("Arr. Rad[NM]"), a && h.push("Speed[kn]"), l && h.push("Sail(RL/GC)"), u && h.push("ROT[deg/min]"), m && h.push("Turn Rad[NM]"), o && h.push("Name");
|
|
1089
|
+
const p = [];
|
|
1090
|
+
p.push("// ROUTE SHEET exported by JRC ECDIS."), p.push("// <<NOTE>>This strings // indicate comment column/cells. You can edit freely."), p.push(`// ${v.xmlEscape(t)}`), p.push(h.join(","));
|
|
1091
|
+
for (let f = 0; f < e.length; f++) {
|
|
1092
|
+
const g = e[f], y = String(f).padStart(3, "0"), x = d.lat2pretty(g.lat, 6), P = d.lng2pretty(g.lng, 6), S = x.H, M = Number(x.minute).toFixed(s), O = x.direction, W = P.H, E = Number(P.minute).toFixed(s), j = P.direction, w = f === 0 ? "***" : g.port != null ? String(g.port) : "***", N = f === 0 ? "***" : g.stbd != null ? String(g.stbd) : "***", $ = f === 0 ? "***" : g.arrRad != null ? String(g.arrRad) : "***", U = f === 0 ? "***" : g.speed != null ? Number(g.speed).toFixed(1).padStart(5, "0") : "***", B = f === 0 ? "***" : g.gcToPrevious ? "GC" : "RL", q = f === 0 ? "***" : g.rot != null ? String(g.rot) : "***", A = f === 0 ? "***" : g.turnRad != null ? String(g.turnRad) : "***", k = g.name ?? "";
|
|
1093
|
+
p.push(`${y},${S},${M},${O},${W},${E},${j},${w},${N},${$},${U},${B},${q},${A},${k}`);
|
|
1075
1094
|
}
|
|
1076
|
-
return
|
|
1095
|
+
return p.join(`
|
|
1077
1096
|
`);
|
|
1078
1097
|
}
|
|
1079
1098
|
/**
|
|
@@ -1088,26 +1107,26 @@ class v {
|
|
|
1088
1107
|
* @returns Uint8Array 二进制数据,可直接用于 new Blob([result], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})
|
|
1089
1108
|
*/
|
|
1090
1109
|
static waypoints2XLSX(t, e, n) {
|
|
1091
|
-
const s = (n == null ? void 0 : n.precision) ?? 6, o = t || "Route", r = e.some((
|
|
1092
|
-
r &&
|
|
1093
|
-
const
|
|
1094
|
-
let x = `<row r="1">${
|
|
1095
|
-
for (let
|
|
1096
|
-
const
|
|
1097
|
-
|
|
1110
|
+
const s = (n == null ? void 0 : n.precision) ?? 6, o = t || "Route", r = e.some((N) => N.name), i = e.some((N) => N.description), c = e.some((N) => N.port != null), a = e.some((N) => N.stbd != null), l = e.some((N) => N.arrRad != null), u = e.some((N) => N.speed != null), m = e.some((N, $) => $ > 0 && N.gcToPrevious != null), h = e.some((N) => N.bearing != null), p = e.some((N) => N.distanceFromPrevious != null), f = ["WPT No.", "Latitude", "Longitude"];
|
|
1111
|
+
r && f.push("Name"), i && f.push("Description"), m && f.push("Leg"), h && f.push("Bearing[deg]"), p && f.push("Distance[NM]"), u && f.push("Speed[kn]"), c && f.push("PORT XTD[NM]"), a && f.push("STBD XTD[NM]"), l && f.push("Arr.Rad[NM]");
|
|
1112
|
+
const g = (N) => N == null ? "" : String(N).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1113
|
+
let x = `<row r="1">${f.map((N, $) => `<c r="${G($)}1" s="1" t="inlineStr"><is><t>${g(N)}</t></is></c>`).join("")}</row>`;
|
|
1114
|
+
for (let N = 0; N < e.length; N++) {
|
|
1115
|
+
const $ = e[N], U = N + 2, B = [], q = (L, Z) => B.push(`<c r="${G(L)}${U}"><v>${Z}</v></c>`), A = (L, Z) => B.push(`<c r="${G(L)}${U}" t="inlineStr"><is><t>${g(Z)}</t></is></c>`), k = (L, Z) => {
|
|
1116
|
+
Z != null ? q(L, Z) : A(L, "");
|
|
1098
1117
|
};
|
|
1099
|
-
|
|
1118
|
+
q(0, N + 1), A(1, d.lat2pretty($.lat, s).pretty), A(2, d.lng2pretty($.lng, s).pretty);
|
|
1100
1119
|
let D = 3;
|
|
1101
|
-
r && (A(D,
|
|
1120
|
+
r && (A(D, $.name ?? ""), D++), i && (A(D, $.description ?? ""), D++), m && (A(D, N === 0 ? "" : $.gcToPrevious ? "GC" : "RL"), D++), h && (k(D, $.bearing), D++), p && (k(D, $.distanceFromPrevious), D++), u && (k(D, $.speed), D++), c && (k(D, $.port), D++), a && (k(D, $.stbd), D++), l && (k(D, $.arrRad), D++), x += `<row r="${U}">${B.join("")}</row>`;
|
|
1102
1121
|
}
|
|
1103
|
-
const
|
|
1122
|
+
const P = "0." + "0".repeat(s), S = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>' + x + "</sheetData></worksheet>", M = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/></Types>', O = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>', W = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets><sheet name="' + g(o) + '" sheetId="1" r:id="rId1"/></sheets></workbook>', E = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>', j = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><numFmts count="1"><numFmt numFmtId="164" formatCode="' + P + '"/></numFmts><fonts count="2"><font><sz val="11"/><name val="Arial"/></font><font><b/><sz val="11"/><name val="Arial"/></font></fonts><fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills><borders count="2"><border><left/><right/><top/><bottom/><diagonal/></border><border><bottom style="thin"><color auto="1"/></bottom></border></borders><cellStyleXfs count="1"><xf/></cellStyleXfs><cellXfs count="3"><xf/><xf fontId="1" fillId="0" borderId="1" applyFont="1" applyBorder="1"/><xf numFmtId="164" fontId="0" applyNumberFormat="1"/></cellXfs></styleSheet>', w = new TextEncoder();
|
|
1104
1123
|
return _([
|
|
1105
|
-
{ name: "[Content_Types].xml", data:
|
|
1106
|
-
{ name: "_rels/.rels", data:
|
|
1107
|
-
{ name: "xl/workbook.xml", data:
|
|
1108
|
-
{ name: "xl/_rels/workbook.xml.rels", data:
|
|
1109
|
-
{ name: "xl/worksheets/sheet1.xml", data:
|
|
1110
|
-
{ name: "xl/styles.xml", data:
|
|
1124
|
+
{ name: "[Content_Types].xml", data: w.encode(M) },
|
|
1125
|
+
{ name: "_rels/.rels", data: w.encode(O) },
|
|
1126
|
+
{ name: "xl/workbook.xml", data: w.encode(W) },
|
|
1127
|
+
{ name: "xl/_rels/workbook.xml.rels", data: w.encode(E) },
|
|
1128
|
+
{ name: "xl/worksheets/sheet1.xml", data: w.encode(S) },
|
|
1129
|
+
{ name: "xl/styles.xml", data: w.encode(j) }
|
|
1111
1130
|
]);
|
|
1112
1131
|
}
|
|
1113
1132
|
/**
|
|
@@ -1168,17 +1187,17 @@ class v {
|
|
|
1168
1187
|
static coordinatesSummary(t, e = 3) {
|
|
1169
1188
|
if (t.length > 1) {
|
|
1170
1189
|
const n = t[0], s = t[t.length - 1], o = (n == null ? void 0 : n.positionTime) < (s == null ? void 0 : s.positionTime) ? b.unix(n == null ? void 0 : n.positionTime) : b.unix(s == null ? void 0 : s.positionTime), r = (n == null ? void 0 : n.positionTime) > (s == null ? void 0 : s.positionTime) ? b.unix(n == null ? void 0 : n.positionTime) : b.unix(s == null ? void 0 : s.positionTime), i = Math.round(r.diff(o, "hours", !0) * 100) / 100, c = this.generateRouteAccordingToWaypoints(t, !0, !0), a = this.calculateRouteDistance(c), u = K.inspectStoppages(t, e).reduce(
|
|
1171
|
-
(h,
|
|
1190
|
+
(h, p) => (h.duration += p.duration, h.distance += p.distance, h),
|
|
1172
1191
|
{ hours: 0, distance: 0, spd: 0, duration: 0 }
|
|
1173
1192
|
);
|
|
1174
1193
|
u.hours = Math.round(u.duration / 3600 * 100) / 100, u.distance = Math.round(u.distance * 100) / 100, u.spd = u.hours ? Math.round(u.distance / u.hours * 100) / 100 : 0;
|
|
1175
|
-
const
|
|
1194
|
+
const m = i ? Math.round((a - u.distance) / (i - u.hours) * 100) / 100 : 0;
|
|
1176
1195
|
return {
|
|
1177
1196
|
begin: o.utc().format(),
|
|
1178
1197
|
end: r.utc().format(),
|
|
1179
1198
|
distance: Math.round((a - u.distance) * 100) / 100,
|
|
1180
1199
|
hours: Math.round((i - u.hours) * 100) / 100,
|
|
1181
|
-
avgSpeed:
|
|
1200
|
+
avgSpeed: m,
|
|
1182
1201
|
stoppage: u
|
|
1183
1202
|
};
|
|
1184
1203
|
}
|
|
@@ -1200,23 +1219,23 @@ class v {
|
|
|
1200
1219
|
* }
|
|
1201
1220
|
*/
|
|
1202
1221
|
static pickUTCSampleFromSpeed(t, e) {
|
|
1203
|
-
var l, u,
|
|
1222
|
+
var l, u, m;
|
|
1204
1223
|
if (!((u = (l = e == null ? void 0 : e.sample) == null ? void 0 : l.hours) != null && u.length))
|
|
1205
1224
|
return { routes: [], hour: void 0 };
|
|
1206
1225
|
const n = e.sample.hours.at(0), s = b.utc(t), o = b.utc(e.eta), r = s.isAfter(o) ? o : s;
|
|
1207
1226
|
let i = e.sample.all.find((h) => h.eta === r.format());
|
|
1208
1227
|
if (!i) {
|
|
1209
|
-
const h = e.sample.all.filter((
|
|
1210
|
-
i = (
|
|
1211
|
-
const { cFactor:
|
|
1228
|
+
const h = e.sample.all.filter((M) => b.utc(M.eta).isBefore(r)).at(-1), p = this.calculateSubRoute(h, e.route);
|
|
1229
|
+
i = (m = this.calculateNextCoordinateAlongRoute(h, h.speed * r.diff(b(h.etd), "hours", !0), p)) == null ? void 0 : m.coordinate;
|
|
1230
|
+
const { cFactor: f, cog: g, wxFactor: y, meteo: x } = h, P = Math.round(i.distanceFromPrevious * 1e4) / 1e4, S = Math.round((P + h.distanceFromStart) * 1e4) / 1e4;
|
|
1212
1231
|
i = {
|
|
1213
1232
|
...i,
|
|
1214
|
-
cFactor:
|
|
1215
|
-
cog:
|
|
1233
|
+
cFactor: f,
|
|
1234
|
+
cog: g,
|
|
1216
1235
|
speed: h.speed,
|
|
1217
|
-
wxFactor:
|
|
1218
|
-
distanceFromStart:
|
|
1219
|
-
distanceFromPrevious:
|
|
1236
|
+
wxFactor: y,
|
|
1237
|
+
distanceFromStart: S,
|
|
1238
|
+
distanceFromPrevious: P,
|
|
1220
1239
|
meteo: x,
|
|
1221
1240
|
eta: r.format(),
|
|
1222
1241
|
etd: r.format()
|
|
@@ -1262,9 +1281,9 @@ class v {
|
|
|
1262
1281
|
return n = n > 180 ? 360 - n : n, n;
|
|
1263
1282
|
}
|
|
1264
1283
|
}
|
|
1265
|
-
let
|
|
1284
|
+
let I;
|
|
1266
1285
|
try {
|
|
1267
|
-
|
|
1286
|
+
I = z.getLogger("vessel");
|
|
1268
1287
|
} catch {
|
|
1269
1288
|
} finally {
|
|
1270
1289
|
}
|
|
@@ -1282,90 +1301,90 @@ class it {
|
|
|
1282
1301
|
i && i.wind && (i.wind.kts = i.kts);
|
|
1283
1302
|
for (const c of r.forecasts) {
|
|
1284
1303
|
let a;
|
|
1285
|
-
const l = [], u = [],
|
|
1286
|
-
for (const
|
|
1287
|
-
const
|
|
1288
|
-
a = a ||
|
|
1289
|
-
const
|
|
1304
|
+
const l = [], u = [], m = b(c.date).utc(), h = `${r.name}-${c.model}`;
|
|
1305
|
+
for (const f in c == null ? void 0 : c.hours) {
|
|
1306
|
+
const g = c.hours[f];
|
|
1307
|
+
a = a || g;
|
|
1308
|
+
const y = m.clone().add(Number(f), "hour"), x = T.point([g.lng, g.lat], {
|
|
1290
1309
|
model: c.model,
|
|
1291
1310
|
name: r.name,
|
|
1292
1311
|
nameCn: r.nameCn,
|
|
1293
|
-
date:
|
|
1294
|
-
hour: Number(
|
|
1295
|
-
format:
|
|
1296
|
-
pressure:
|
|
1297
|
-
gusts:
|
|
1298
|
-
wind:
|
|
1299
|
-
movement:
|
|
1312
|
+
date: y.format(),
|
|
1313
|
+
hour: Number(f),
|
|
1314
|
+
format: y.format("MMM-DD/HHmm[Z]"),
|
|
1315
|
+
pressure: g.pressure > 1e4 ? d.roundPrecision(g.pressure / 100, 0) : d.roundPrecision(g.pressure, 0),
|
|
1316
|
+
gusts: g.gusts,
|
|
1317
|
+
wind: g.wind || {},
|
|
1318
|
+
movement: g.movement,
|
|
1300
1319
|
category: h,
|
|
1301
1320
|
type: "forecast"
|
|
1302
1321
|
});
|
|
1303
1322
|
u.push(x), l.push(x.geometry.coordinates);
|
|
1304
1323
|
}
|
|
1305
|
-
const
|
|
1324
|
+
const p = {
|
|
1306
1325
|
kts: void 0,
|
|
1307
1326
|
deg: void 0
|
|
1308
1327
|
};
|
|
1309
1328
|
if (i) {
|
|
1310
|
-
const
|
|
1329
|
+
const f = b(i.updated).utc();
|
|
1311
1330
|
if (a) {
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1331
|
+
const y = v.calculateDistance(i, a), x = b(a.utc || a.updated).diff(f, "h", !0);
|
|
1332
|
+
p.kts = Math.round(y / x * 100) / 100, p.deg = v.calculateBearing(i, a, !0, 0);
|
|
1314
1333
|
}
|
|
1315
|
-
const
|
|
1334
|
+
const g = T.point([i.lng, i.lat], {
|
|
1316
1335
|
model: c.model,
|
|
1317
1336
|
name: r.name,
|
|
1318
1337
|
nameCn: r.nameCn,
|
|
1319
|
-
date:
|
|
1338
|
+
date: f.format(),
|
|
1320
1339
|
hour: 0,
|
|
1321
|
-
format:
|
|
1340
|
+
format: f.format("MMM-DD/HHmm[Z]"),
|
|
1322
1341
|
pressure: i.pressure > 1e4 ? d.roundPrecision((i == null ? void 0 : i.pressure) / 100, 0) : d.roundPrecision(i.pressure, 0),
|
|
1323
1342
|
wind: i.wind,
|
|
1324
|
-
movement:
|
|
1343
|
+
movement: p,
|
|
1325
1344
|
category: h,
|
|
1326
1345
|
type: "forecast",
|
|
1327
1346
|
important: !0
|
|
1328
1347
|
// 第一个预报点为重要点
|
|
1329
1348
|
});
|
|
1330
|
-
u.unshift(
|
|
1349
|
+
u.unshift(g), l.unshift(g.geometry.coordinates);
|
|
1331
1350
|
}
|
|
1332
1351
|
if (e.features.push(...u), (l == null ? void 0 : l.length) > 1) {
|
|
1333
|
-
const
|
|
1334
|
-
date: (i == null ? void 0 : i.updated) || (
|
|
1352
|
+
const f = T.lineString(d.convertToMonotonicLng2(l), {
|
|
1353
|
+
date: (i == null ? void 0 : i.updated) || (m == null ? void 0 : m.format()),
|
|
1335
1354
|
id: r.id || r.name,
|
|
1336
1355
|
model: c.model,
|
|
1337
1356
|
name: r.name,
|
|
1338
1357
|
category: h,
|
|
1339
1358
|
type: "forecast",
|
|
1340
|
-
movement:
|
|
1359
|
+
movement: p
|
|
1341
1360
|
});
|
|
1342
|
-
e.features.push(
|
|
1361
|
+
e.features.push(f);
|
|
1343
1362
|
}
|
|
1344
1363
|
}
|
|
1345
1364
|
}
|
|
1346
1365
|
if (e.features.sort((c, a) => c.properties.type === "forecast" && a.properties.type === "forecast" && c.geometry.type === "Point" && a.geometry.type === "Point" ? b(c.properties.date).valueOf() - b(a.properties.date).valueOf() : 0), (s = r.history) != null && s.length) {
|
|
1347
1366
|
const c = [], a = b(i == null ? void 0 : i.updated).utc(), l = b((o = r.history) == null ? void 0 : o.at(-1).updated).utc(), u = a.diff(l, "h") % 24 > 2 ? 24 : 12;
|
|
1348
|
-
for (const
|
|
1349
|
-
const h = b(
|
|
1350
|
-
|
|
1351
|
-
const
|
|
1367
|
+
for (const m of r.history) {
|
|
1368
|
+
const h = b(m.updated).utc(), p = h.isSameOrBefore(a) || h.isSame(l);
|
|
1369
|
+
p && a.add(-u, "h");
|
|
1370
|
+
const f = T.point([m.lng, m.lat], {
|
|
1352
1371
|
name: r.name,
|
|
1353
1372
|
nameCn: r.nameCn,
|
|
1354
1373
|
date: h.format(),
|
|
1355
1374
|
format: h.format("MMM-DD/HHmm[Z]"),
|
|
1356
|
-
pressure:
|
|
1357
|
-
kts:
|
|
1358
|
-
level:
|
|
1375
|
+
pressure: m.pressure > 1e4 ? d.roundPrecision(m.pressure / 100, 0) : d.roundPrecision(m.pressure, 0),
|
|
1376
|
+
kts: m.kts,
|
|
1377
|
+
level: m.type,
|
|
1359
1378
|
type: "history",
|
|
1360
1379
|
category: `${r.name}-history`,
|
|
1361
|
-
wind:
|
|
1362
|
-
movement:
|
|
1363
|
-
important:
|
|
1380
|
+
wind: m.wind,
|
|
1381
|
+
movement: m.movement,
|
|
1382
|
+
important: p
|
|
1364
1383
|
});
|
|
1365
|
-
e.features.push(
|
|
1384
|
+
e.features.push(f), c.push(f.geometry.coordinates);
|
|
1366
1385
|
}
|
|
1367
1386
|
if (c.length === 1 && c.push(c[0]), c.length > 1) {
|
|
1368
|
-
const
|
|
1387
|
+
const m = T.lineString(d.convertToMonotonicLng2(c), {
|
|
1369
1388
|
name: r.name,
|
|
1370
1389
|
type: "history",
|
|
1371
1390
|
updated: i == null ? void 0 : i.updated,
|
|
@@ -1373,7 +1392,7 @@ class it {
|
|
|
1373
1392
|
kts: i == null ? void 0 : i.kts,
|
|
1374
1393
|
level: i == null ? void 0 : i.type
|
|
1375
1394
|
});
|
|
1376
|
-
e.features.push(
|
|
1395
|
+
e.features.push(m);
|
|
1377
1396
|
}
|
|
1378
1397
|
}
|
|
1379
1398
|
}
|
|
@@ -1388,32 +1407,32 @@ class it {
|
|
|
1388
1407
|
var o, r, i, c;
|
|
1389
1408
|
const n = (o = t == null ? void 0 : t.data) == null ? void 0 : o.features.filter((a) => a.geometry.type === "LineString" && a.properties.type === "forecast"), s = [];
|
|
1390
1409
|
for (const a of n) {
|
|
1391
|
-
const l = a.properties.name, u = a.properties.model,
|
|
1392
|
-
let
|
|
1393
|
-
const
|
|
1394
|
-
(
|
|
1410
|
+
const l = a.properties.name, u = a.properties.model, m = a.properties.showCircle, h = a.properties.disabled, p = b(a.properties.date).utc();
|
|
1411
|
+
let f = e * 60;
|
|
1412
|
+
const g = (r = t == null ? void 0 : t.data) == null ? void 0 : r.features.filter(
|
|
1413
|
+
(P) => P.geometry.type === "Point" && P.properties.type === "forecast" && P.properties.category === `${l}-${u}`
|
|
1395
1414
|
);
|
|
1396
|
-
let
|
|
1397
|
-
for (;
|
|
1398
|
-
if (
|
|
1399
|
-
const
|
|
1415
|
+
let y, x = p.clone().add(f, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
1416
|
+
for (; y = this.pickIndex(g, x), y <= g.length - 1; ) {
|
|
1417
|
+
if (y > 0) {
|
|
1418
|
+
const P = g[y], S = y === 0 ? void 0 : g[y - 1], M = (f / 60 - ((i = S == null ? void 0 : S.properties) == null ? void 0 : i.hour)) / (P.properties.hour - ((c = S == null ? void 0 : S.properties) == null ? void 0 : c.hour)), O = this.computeNumber(S == null ? void 0 : S.geometry.coordinates[0], P.geometry.coordinates[0], M), W = this.computeNumber(S == null ? void 0 : S.geometry.coordinates[1], P.geometry.coordinates[1], M), E = T.point([O, W], {
|
|
1400
1419
|
name: l,
|
|
1401
1420
|
model: u,
|
|
1402
|
-
category:
|
|
1421
|
+
category: P == null ? void 0 : P.properties.category,
|
|
1403
1422
|
date: x.format(),
|
|
1404
1423
|
format: x.format("MMM-DD/HHmm[Z]"),
|
|
1405
|
-
gusts: this.computeNumber(
|
|
1406
|
-
hour: this.computeNumber(
|
|
1407
|
-
movement: this.computeNumber(
|
|
1408
|
-
pressure: this.computeNumber(
|
|
1409
|
-
wind: this.computeNumber(
|
|
1424
|
+
gusts: this.computeNumber(S == null ? void 0 : S.properties.gusts, P.properties.gusts, M),
|
|
1425
|
+
hour: this.computeNumber(S == null ? void 0 : S.properties.hour, P.properties.hour, M),
|
|
1426
|
+
movement: this.computeNumber(S == null ? void 0 : S.properties.movement, P.properties.movement, M),
|
|
1427
|
+
pressure: this.computeNumber(S == null ? void 0 : S.properties.pressure, P.properties.pressure, M),
|
|
1428
|
+
wind: this.computeNumber(S == null ? void 0 : S.properties.wind, P.properties.wind, M),
|
|
1410
1429
|
type: "forecast",
|
|
1411
1430
|
disabled: h,
|
|
1412
|
-
showCircle:
|
|
1431
|
+
showCircle: m
|
|
1413
1432
|
});
|
|
1414
|
-
s.push(
|
|
1433
|
+
s.push(E);
|
|
1415
1434
|
}
|
|
1416
|
-
|
|
1435
|
+
f += e * 60, x = p.clone().add(f, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
1417
1436
|
}
|
|
1418
1437
|
}
|
|
1419
1438
|
return s;
|
|
@@ -1443,9 +1462,9 @@ class it {
|
|
|
1443
1462
|
const { t1: o, t2: r, hr: i, hours: c } = this.tropicalCenterTwin(e, 24, s);
|
|
1444
1463
|
if (o && r) {
|
|
1445
1464
|
if (!s.debug) {
|
|
1446
|
-
const
|
|
1447
|
-
if (
|
|
1448
|
-
return
|
|
1465
|
+
const p = v.calculateDistance(t, o), f = v.calculateDistance(t, r);
|
|
1466
|
+
if (p > 2 * n && f > 2 * n)
|
|
1467
|
+
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", s.requestId, p, f, {
|
|
1449
1468
|
from: t,
|
|
1450
1469
|
t1: o,
|
|
1451
1470
|
t2: r,
|
|
@@ -1453,10 +1472,10 @@ class it {
|
|
|
1453
1472
|
}), {};
|
|
1454
1473
|
}
|
|
1455
1474
|
const a = v.calculateBearing(t, o), l = v.calculateBearing(o, r), u = Math.abs(a - l);
|
|
1456
|
-
let
|
|
1457
|
-
u < 180 ?
|
|
1458
|
-
const h = v.calculateCoordinate(o,
|
|
1459
|
-
return
|
|
1475
|
+
let m = 0;
|
|
1476
|
+
u < 180 ? m = u + 90 : u >= 180 && (m = u - 90);
|
|
1477
|
+
const h = v.calculateCoordinate(o, m, n);
|
|
1478
|
+
return I == null || I.info("[%s] the right tangent position: %j", s.requestId, {
|
|
1460
1479
|
from: t,
|
|
1461
1480
|
t1: o,
|
|
1462
1481
|
t2: r,
|
|
@@ -1482,9 +1501,9 @@ class it {
|
|
|
1482
1501
|
const { t1: o, t2: r, hr: i, hours: c } = this.tropicalCenterTwin(e, 24, s);
|
|
1483
1502
|
if (o && r) {
|
|
1484
1503
|
if (!s.debug) {
|
|
1485
|
-
const h = v.calculateDistance(t, o),
|
|
1486
|
-
if (h > 2 * n &&
|
|
1487
|
-
return
|
|
1504
|
+
const h = v.calculateDistance(t, o), p = v.calculateDistance(t, r);
|
|
1505
|
+
if (h > 2 * n && p > 2 * n)
|
|
1506
|
+
return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", s.requestId, h, p, {
|
|
1488
1507
|
from: t,
|
|
1489
1508
|
t1: o,
|
|
1490
1509
|
t2: r,
|
|
@@ -1494,7 +1513,7 @@ class it {
|
|
|
1494
1513
|
const a = v.calculateBearing(t, o), l = v.calculateBearing(o, r), u = v.calculateDistance(t, o);
|
|
1495
1514
|
return { at: v.calculateCoordinate(o, a - l + 180, n < u ? n : u), t1: o, t2: r, hr: Number(i), hours: c };
|
|
1496
1515
|
} else
|
|
1497
|
-
return
|
|
1516
|
+
return I == null || I.info("[%s] no need drift: %j", s.requestId, { from: t, t1: o, t2: r, hr: i }), {};
|
|
1498
1517
|
}
|
|
1499
1518
|
/**
|
|
1500
1519
|
* 获取台风中心点对
|
|
@@ -1505,20 +1524,20 @@ class it {
|
|
|
1505
1524
|
* @private
|
|
1506
1525
|
*/
|
|
1507
1526
|
static tropicalCenterTwin(t, e = 24, n = {}) {
|
|
1508
|
-
var l, u,
|
|
1527
|
+
var l, u, m, h, p;
|
|
1509
1528
|
let s = {};
|
|
1510
|
-
(l = t.forecasts) == null || l.forEach((
|
|
1511
|
-
s = { ...
|
|
1529
|
+
(l = t.forecasts) == null || l.forEach((f) => {
|
|
1530
|
+
s = { ...f.hours, ...s };
|
|
1512
1531
|
});
|
|
1513
|
-
const o = ((u = t == null ? void 0 : t.history) == null ? void 0 : u[0]) || (s == null ? void 0 : s[(
|
|
1514
|
-
|
|
1515
|
-
let r = (h = Object.keys(s || {}).filter((
|
|
1516
|
-
r || (r = (
|
|
1532
|
+
const o = ((u = t == null ? void 0 : t.history) == null ? void 0 : u[0]) || (s == null ? void 0 : s[(m = Object.keys(s)) == null ? void 0 : m[0]]);
|
|
1533
|
+
I == null || I.info("[%s] the first tropical center: %j", n.requestId, o);
|
|
1534
|
+
let r = (h = Object.keys(s || {}).filter((f) => Number(f) <= (e < 0 ? 24 : e))) == null ? void 0 : h.at(-1);
|
|
1535
|
+
r || (r = (p = Object.keys(s || {}).filter((f) => Number(f) <= (e < 0 ? 24 : 2 * e))) == null ? void 0 : p.at(-1));
|
|
1517
1536
|
const i = s == null ? void 0 : s[r || -1];
|
|
1518
|
-
|
|
1519
|
-
const c = Object.keys(s || {}).filter((
|
|
1520
|
-
for (const
|
|
1521
|
-
a[
|
|
1537
|
+
I == null || I.info("[%s] the second tropical center: %j in %d hrs", n.requestId, i, r);
|
|
1538
|
+
const c = Object.keys(s || {}).filter((f) => Number(f) <= Number(r)), a = { 0: o };
|
|
1539
|
+
for (const f of c)
|
|
1540
|
+
a[f] = s[f];
|
|
1522
1541
|
return { t1: o, t2: i, hr: Number(r), hours: a };
|
|
1523
1542
|
}
|
|
1524
1543
|
static pickIndex(t, e) {
|
|
@@ -1562,7 +1581,7 @@ typeof globalThis < "u" && typeof globalThis.Buffer > "u" && (globalThis.Buffer
|
|
|
1562
1581
|
});
|
|
1563
1582
|
let R;
|
|
1564
1583
|
try {
|
|
1565
|
-
R =
|
|
1584
|
+
R = z.getLogger("meteo");
|
|
1566
1585
|
} catch {
|
|
1567
1586
|
} finally {
|
|
1568
1587
|
}
|
|
@@ -1594,7 +1613,7 @@ class F {
|
|
|
1594
1613
|
const o = (s == null ? void 0 : s.steps) ?? 64, r = (s == null ? void 0 : s.units) ?? "nauticalmiles", i = (s == null ? void 0 : s.properties) ?? {}, c = T.point([t, e]), a = T.destination(c, n, 90, { units: r }), l = b.utc();
|
|
1595
1614
|
i.id = (s == null ? void 0 : s.id) || l.valueOf().toString();
|
|
1596
1615
|
const u = "circle";
|
|
1597
|
-
return i.name = (s == null ? void 0 : s.name) || `${u}_${l.format()}`, i.radius = n, i.center = [t, e], i.end = a.geometry.coordinates.map((
|
|
1616
|
+
return i.name = (s == null ? void 0 : s.name) || `${u}_${l.format()}`, i.radius = n, i.center = [t, e], i.end = a.geometry.coordinates.map((m) => d.roundPrecision(m, 9)), i.units = r, i.steps = o, i.shape = "circle", R.info("[%s] draw circle with %j", s == null ? void 0 : s.requestId, i), T.circle(c, n, { steps: o, units: r, properties: i });
|
|
1598
1617
|
}
|
|
1599
1618
|
/**
|
|
1600
1619
|
* 基于turf画矩形,返回GeoJSON Feature<Polygon>
|
|
@@ -1672,14 +1691,14 @@ class F {
|
|
|
1672
1691
|
const l = (n == null ? void 0 : n.units) || "nauticalmiles";
|
|
1673
1692
|
let u = n == null ? void 0 : n.radius;
|
|
1674
1693
|
if (!u) {
|
|
1675
|
-
const
|
|
1676
|
-
u = T.pointToLineDistance(c,
|
|
1694
|
+
const p = T.polygonToLine(t);
|
|
1695
|
+
u = T.pointToLineDistance(c, p, { units: l });
|
|
1677
1696
|
}
|
|
1678
1697
|
a = "end";
|
|
1679
|
-
const
|
|
1680
|
-
|
|
1681
|
-
const h = T.lineString([c.geometry.coordinates,
|
|
1682
|
-
return a = "edge", h.properties = { id: `${a}_${i}`, parentId: i, name: a, radius: u, units: l }, T.featureCollection([c,
|
|
1698
|
+
const m = ((o = n == null ? void 0 : n.end) == null ? void 0 : o.length) == 2 ? T.point(n.end) : T.destination(c, u, 90, { units: l });
|
|
1699
|
+
m.properties = { id: `${a}_${i}`, parentId: i, name: a, radius: u, units: l };
|
|
1700
|
+
const h = T.lineString([c.geometry.coordinates, m.geometry.coordinates]);
|
|
1701
|
+
return a = "edge", h.properties = { id: `${a}_${i}`, parentId: i, name: a, radius: u, units: l }, T.featureCollection([c, m, h, t]);
|
|
1683
1702
|
} else
|
|
1684
1703
|
return R.warn("[%s] not a orm-std circle, just return the original feature", e == null ? void 0 : e.requestId), T.featureCollection([t]);
|
|
1685
1704
|
}
|
|
@@ -1766,7 +1785,7 @@ class F {
|
|
|
1766
1785
|
* 使用 Central Directory 解析,避免 Data Descriptor 导致的大小不准问题。
|
|
1767
1786
|
*/
|
|
1768
1787
|
static async _parseZipEntries(t) {
|
|
1769
|
-
var
|
|
1788
|
+
var m;
|
|
1770
1789
|
const e = new Uint8Array(t), n = e.buffer.slice(e.byteOffset, e.byteOffset + e.byteLength), s = new DataView(n), o = new Uint8Array(n), r = /* @__PURE__ */ new Map();
|
|
1771
1790
|
let i = -1;
|
|
1772
1791
|
for (let h = n.byteLength - 22; h >= 0; h--)
|
|
@@ -1783,33 +1802,33 @@ class F {
|
|
|
1783
1802
|
for (; l < u; ) {
|
|
1784
1803
|
if (s.getUint32(l, !0) !== 33639248)
|
|
1785
1804
|
throw new Error(`Invalid ZIP file: Central Directory signature mismatch at offset ${l}`);
|
|
1786
|
-
const
|
|
1787
|
-
if (
|
|
1788
|
-
r.set(
|
|
1789
|
-
else if (
|
|
1805
|
+
const p = s.getUint16(l + 10, !0), f = s.getUint32(l + 20, !0), g = s.getUint16(l + 28, !0), y = s.getUint16(l + 30, !0), x = s.getUint16(l + 32, !0), P = s.getUint32(l + 42, !0), S = o.slice(l + 46, l + 46 + g), M = new TextDecoder().decode(S), O = s.getUint16(P + 26, !0), W = s.getUint16(P + 28, !0), E = P + 30 + O + W, j = o.slice(E, E + f);
|
|
1806
|
+
if (p === 0)
|
|
1807
|
+
r.set(M, j);
|
|
1808
|
+
else if (p === 8) {
|
|
1790
1809
|
if (typeof DecompressionStream < "u") {
|
|
1791
|
-
const
|
|
1792
|
-
|
|
1793
|
-
const
|
|
1810
|
+
const w = new DecompressionStream("deflate-raw"), N = w.writable.getWriter(), $ = w.readable.getReader();
|
|
1811
|
+
N.write(j), N.close();
|
|
1812
|
+
const U = [];
|
|
1794
1813
|
let B = 0;
|
|
1795
1814
|
for (; ; ) {
|
|
1796
|
-
const { done: k, value: D } = await
|
|
1815
|
+
const { done: k, value: D } = await $.read();
|
|
1797
1816
|
if (k)
|
|
1798
1817
|
break;
|
|
1799
|
-
|
|
1818
|
+
U.push(D), B += D.length;
|
|
1800
1819
|
}
|
|
1801
|
-
const
|
|
1820
|
+
const q = new Uint8Array(B);
|
|
1802
1821
|
let A = 0;
|
|
1803
|
-
for (const k of
|
|
1804
|
-
|
|
1805
|
-
r.set(
|
|
1806
|
-
} else if (typeof process < "u" && ((
|
|
1822
|
+
for (const k of U)
|
|
1823
|
+
q.set(k, A), A += k.length;
|
|
1824
|
+
r.set(M, q);
|
|
1825
|
+
} else if (typeof process < "u" && ((m = process.versions) != null && m.node))
|
|
1807
1826
|
try {
|
|
1808
|
-
r.set(
|
|
1827
|
+
r.set(M, F._inflateRawSync(j));
|
|
1809
1828
|
} catch {
|
|
1810
1829
|
}
|
|
1811
1830
|
}
|
|
1812
|
-
l += 46 +
|
|
1831
|
+
l += 46 + g + y + x;
|
|
1813
1832
|
}
|
|
1814
1833
|
return r;
|
|
1815
1834
|
}
|
|
@@ -1828,37 +1847,37 @@ class F {
|
|
|
1828
1847
|
const s = H().parseFromString(t, "application/xml"), o = Array.from(s.querySelectorAll("Placemark")), r = [];
|
|
1829
1848
|
for (const a of o) {
|
|
1830
1849
|
const l = {}, u = Array.from(a.querySelectorAll("ExtendedData > Data"));
|
|
1831
|
-
for (const
|
|
1832
|
-
const
|
|
1833
|
-
|
|
1850
|
+
for (const S of u) {
|
|
1851
|
+
const M = S.getAttribute("name"), O = (c = (i = S.querySelector("value")) == null ? void 0 : i.textContent) == null ? void 0 : c.trim();
|
|
1852
|
+
M && O !== void 0 && O !== null && (l[M] = O);
|
|
1834
1853
|
}
|
|
1835
|
-
const
|
|
1836
|
-
const
|
|
1837
|
-
return [
|
|
1838
|
-
}),
|
|
1839
|
-
if (
|
|
1840
|
-
const
|
|
1841
|
-
if (
|
|
1842
|
-
const
|
|
1843
|
-
r.push(
|
|
1854
|
+
const m = b.utc(), h = Object.keys(l).find((S) => S.toLowerCase().indexOf("name") !== -1), p = h ? l[h] : void 0, f = `${m.valueOf().toString()}_${Math.random().toString(36).slice(2, 8)}`, g = (S) => S.trim().split(/[\s\n]+/).filter((M) => M.length > 0).map((M) => {
|
|
1855
|
+
const O = M.split(",").map(Number);
|
|
1856
|
+
return [O[0], O[1]];
|
|
1857
|
+
}), y = a.querySelector("LineString > coordinates");
|
|
1858
|
+
if (y) {
|
|
1859
|
+
const S = g(y.textContent || "");
|
|
1860
|
+
if (S.length >= 2) {
|
|
1861
|
+
const M = T.lineString(S, { ...l, shape: "line", id: f, name: p });
|
|
1862
|
+
r.push(M);
|
|
1844
1863
|
}
|
|
1845
1864
|
continue;
|
|
1846
1865
|
}
|
|
1847
1866
|
const x = a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");
|
|
1848
1867
|
if (x) {
|
|
1849
|
-
const
|
|
1850
|
-
if (
|
|
1851
|
-
const
|
|
1852
|
-
r.push(
|
|
1868
|
+
const S = g(x.textContent || "");
|
|
1869
|
+
if (S.length >= 4) {
|
|
1870
|
+
const M = S[0][0] === S[S.length - 1][0] && S[0][1] === S[S.length - 1][1] ? S : [...S, S[0]], O = T.polygon([M], { ...l, shape: "polygon", id: f, name: p });
|
|
1871
|
+
r.push(O);
|
|
1853
1872
|
}
|
|
1854
1873
|
continue;
|
|
1855
1874
|
}
|
|
1856
|
-
const
|
|
1857
|
-
if (
|
|
1858
|
-
const
|
|
1859
|
-
if (
|
|
1860
|
-
const
|
|
1861
|
-
r.push(
|
|
1875
|
+
const P = a.querySelector("Point > coordinates");
|
|
1876
|
+
if (P) {
|
|
1877
|
+
const S = g(P.textContent || "");
|
|
1878
|
+
if (S.length >= 1) {
|
|
1879
|
+
const M = T.point(S[0], { ...l, shape: "point", id: f, name: p });
|
|
1880
|
+
r.push(M);
|
|
1862
1881
|
}
|
|
1863
1882
|
continue;
|
|
1864
1883
|
}
|
|
@@ -1926,10 +1945,10 @@ class F {
|
|
|
1926
1945
|
MultiPolygon: "polygon"
|
|
1927
1946
|
};
|
|
1928
1947
|
return s.forEach((c, a) => {
|
|
1929
|
-
var
|
|
1930
|
-
const l = ((
|
|
1948
|
+
var p;
|
|
1949
|
+
const l = ((p = c.geometry) == null ? void 0 : p.type) || "", u = i[l] || l.toLowerCase();
|
|
1931
1950
|
c.properties = c.properties || {}, c.properties.shape = u, c.properties.parentId = r, c.properties.id = `${r}_${a}`;
|
|
1932
|
-
const
|
|
1951
|
+
const m = Object.keys(c.properties).find((f) => f.toLowerCase().indexOf("name") !== -1), h = m ? c.properties[m] : void 0;
|
|
1933
1952
|
c.properties.name = h || `${u}_${o.format()}_${a}`;
|
|
1934
1953
|
}), T.featureCollection(s);
|
|
1935
1954
|
}
|