@idm-plugin/geo 2.2.7 → 2.2.8
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 +122 -158
- package/dist/index.umd.cjs +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as T from "@turf/turf";
|
|
2
|
-
import
|
|
2
|
+
import b from "moment";
|
|
3
3
|
import z from "@log4js-node/log4js-api";
|
|
4
4
|
import "moment-timezone";
|
|
5
5
|
import V from "tz-lookup";
|
|
@@ -12,7 +12,7 @@ class d {
|
|
|
12
12
|
*/
|
|
13
13
|
static guessTimeZoneOffset(t, e) {
|
|
14
14
|
t = d.convertToStdLng(t);
|
|
15
|
-
const n = V(e, t), s =
|
|
15
|
+
const n = V(e, t), s = b().tz(n).utcOffset();
|
|
16
16
|
return d.roundPrecision(s / 60, 1);
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
@@ -214,14 +214,14 @@ class K {
|
|
|
214
214
|
lng: r.lng,
|
|
215
215
|
sog: r.sog,
|
|
216
216
|
positionTime: r.positionTime,
|
|
217
|
-
utc:
|
|
217
|
+
utc: b.unix(r.positionTime).utc().format()
|
|
218
218
|
},
|
|
219
219
|
end: {
|
|
220
220
|
lat: i.lat,
|
|
221
221
|
lng: i.lng,
|
|
222
222
|
sog: i.sog,
|
|
223
223
|
positionTime: i.positionTime,
|
|
224
|
-
utc:
|
|
224
|
+
utc: b.unix(i.positionTime).utc().format()
|
|
225
225
|
},
|
|
226
226
|
duration: i.positionTime - r.positionTime
|
|
227
227
|
}, u = t.filter((h) => h.positionTime >= l.start.positionTime && h.positionTime <= l.end.positionTime), m = v.divideAccordingToLng(u);
|
|
@@ -239,7 +239,7 @@ class K {
|
|
|
239
239
|
* @param etm
|
|
240
240
|
*/
|
|
241
241
|
static inspectSummary(t, e, n) {
|
|
242
|
-
const s =
|
|
242
|
+
const s = b(e), o = b(n), r = t.filter((l) => l.positionTime >= s.unix() && l.positionTime <= o.unix());
|
|
243
243
|
let i = 0, c = 0;
|
|
244
244
|
if (r.length > 1)
|
|
245
245
|
for (let l = 0; l < r.length - 1; l++) {
|
|
@@ -277,8 +277,8 @@ function _(C) {
|
|
|
277
277
|
const t = new TextEncoder(), e = [], n = [];
|
|
278
278
|
let s = 0;
|
|
279
279
|
for (const h of C) {
|
|
280
|
-
const p = t.encode(h.name), f = Q(h.data), g = new Uint8Array(30 + p.length),
|
|
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;
|
|
@@ -766,20 +766,20 @@ class v {
|
|
|
766
766
|
else {
|
|
767
767
|
const f = [];
|
|
768
768
|
let g;
|
|
769
|
-
for (let
|
|
769
|
+
for (let y = 0; y < h.length; y++)
|
|
770
770
|
if (u)
|
|
771
|
-
f.push(h[
|
|
771
|
+
f.push(h[y]);
|
|
772
772
|
else {
|
|
773
|
-
g = { lng: h[
|
|
774
|
-
const
|
|
775
|
-
if (a +=
|
|
776
|
-
l +=
|
|
773
|
+
g = { lng: h[y][0], lat: h[y][1] };
|
|
774
|
+
const x = this.calculateDistance(t, g, !0, 8, s);
|
|
775
|
+
if (a += x, a < e)
|
|
776
|
+
l += x, x && r.push(g), t = g;
|
|
777
777
|
else {
|
|
778
778
|
if (l = e, a === e)
|
|
779
779
|
u = g, f.push([u.lng, u.lat]);
|
|
780
780
|
else {
|
|
781
|
-
const
|
|
782
|
-
u = this.calculateCoordinate(g,
|
|
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
|
}
|
|
@@ -936,7 +936,7 @@ class v {
|
|
|
936
936
|
* @param waypoints 带时间的轨迹, 单位秒
|
|
937
937
|
*/
|
|
938
938
|
static nearestTSPointInWaypoints(t, e, n) {
|
|
939
|
-
const s =
|
|
939
|
+
const s = b.unix(t), o = n.filter(
|
|
940
940
|
(r) => s.clone().subtract(e, "hour").unix() <= (r.positionTime || 0) && s.clone().add(e, "h").unix() >= (r.positionTime || 0)
|
|
941
941
|
);
|
|
942
942
|
return o.sort((r, i) => (r.positionTime || 0) - (i.positionTime || 0)), o.at(-1);
|
|
@@ -949,7 +949,7 @@ class v {
|
|
|
949
949
|
static deadReckoning(t, e) {
|
|
950
950
|
var o, r, i, c;
|
|
951
951
|
t > 1e12 && (t = Math.round(t / 1e3));
|
|
952
|
-
const n =
|
|
952
|
+
const n = b.unix(t);
|
|
953
953
|
let s = e.find((a) => a.positionTime === n.unix());
|
|
954
954
|
if (!s) {
|
|
955
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);
|
|
@@ -957,7 +957,7 @@ class v {
|
|
|
957
957
|
const u = v.calculateBearing(a, l, !0), m = v.calculateDistance(a, l), h = (n.unix() - a.positionTime) / (l.positionTime - a.positionTime);
|
|
958
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
|
-
s = a || l, s && (s.utc =
|
|
960
|
+
s = a || l, s && (s.utc = b.unix(s == null ? void 0 : s.positionTime).utc().format());
|
|
961
961
|
}
|
|
962
962
|
return s;
|
|
963
963
|
}
|
|
@@ -982,7 +982,7 @@ class v {
|
|
|
982
982
|
const a = o.positionTime || 0, l = r.positionTime || 0, u = v.calculateDistance(o, r);
|
|
983
983
|
t.positionTime = Math.round(a + (l - a) * (i / u));
|
|
984
984
|
}
|
|
985
|
-
return t.utc = t.positionTime ?
|
|
985
|
+
return t.utc = t.positionTime ? b.unix(t.positionTime).utc().format() : void 0, t.positionTime ? t : void 0;
|
|
986
986
|
}
|
|
987
987
|
/**
|
|
988
988
|
* 翻转轨迹
|
|
@@ -1047,7 +1047,7 @@ class v {
|
|
|
1047
1047
|
u.push(` <time>${v.xmlEscape(r.utc)}</time>`);
|
|
1048
1048
|
else if (r.positionTime)
|
|
1049
1049
|
try {
|
|
1050
|
-
u.push(` <time>${v.xmlEscape(
|
|
1050
|
+
u.push(` <time>${v.xmlEscape(b.unix(r.positionTime).utc().format())}</time>`);
|
|
1051
1051
|
} catch {
|
|
1052
1052
|
}
|
|
1053
1053
|
r.cog !== void 0 && u.push(` <cog>${v.xmlEscape(r.cog)}</cog>`), r.sog !== void 0 && u.push(` <sog>${v.xmlEscape(r.sog)}</sog>`), u.length && (s.push(" <extensions>"), s.push(...u), s.push(" </extensions>"));
|
|
@@ -1065,13 +1065,13 @@ 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((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,
|
|
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
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
1070
|
const f = [];
|
|
1071
1071
|
f.push(p.map((g) => v.csvEscapeField(g)).join(","));
|
|
1072
1072
|
for (let g = 0; g < e.length; g++) {
|
|
1073
|
-
const
|
|
1074
|
-
|
|
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
1075
|
}
|
|
1076
1076
|
return f.join(`
|
|
1077
1077
|
`);
|
|
@@ -1089,44 +1089,8 @@ class v {
|
|
|
1089
1089
|
const p = [];
|
|
1090
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
1091
|
for (let f = 0; f < e.length; f++) {
|
|
1092
|
-
const g =
|
|
1093
|
-
g.push(
|
|
1094
|
-
const N = d.lat2pretty(S.lat, 6), y = d.lng2pretty(S.lng, 6), M = N.H, O = Number(N.minute).toFixed(s), U = N.direction;
|
|
1095
|
-
g.push(M), g.push(O), g.push(U);
|
|
1096
|
-
const E = y.H, B = Number(y.minute).toFixed(s), k = y.direction;
|
|
1097
|
-
if (g.push(E), g.push(B), g.push(k), r) {
|
|
1098
|
-
const b = f === 0 ? "***" : S.port != null ? String(S.port) : "***";
|
|
1099
|
-
g.push(b);
|
|
1100
|
-
}
|
|
1101
|
-
if (i) {
|
|
1102
|
-
const b = f === 0 ? "***" : S.stbd != null ? String(S.stbd) : "***";
|
|
1103
|
-
g.push(b);
|
|
1104
|
-
}
|
|
1105
|
-
if (c) {
|
|
1106
|
-
const b = f === 0 ? "***" : S.arrRad != null ? String(S.arrRad) : "***";
|
|
1107
|
-
g.push(b);
|
|
1108
|
-
}
|
|
1109
|
-
if (a) {
|
|
1110
|
-
const b = f === 0 ? "***" : S.speed != null ? Number(S.speed).toFixed(1).padStart(5, "0") : "***";
|
|
1111
|
-
g.push(b);
|
|
1112
|
-
}
|
|
1113
|
-
if (l) {
|
|
1114
|
-
const b = f === 0 ? "***" : S.gcToPrevious ? "GC" : "RL";
|
|
1115
|
-
g.push(b);
|
|
1116
|
-
}
|
|
1117
|
-
if (u) {
|
|
1118
|
-
const b = f === 0 ? "***" : S.rot != null ? String(S.rot) : "***";
|
|
1119
|
-
g.push(b);
|
|
1120
|
-
}
|
|
1121
|
-
if (m) {
|
|
1122
|
-
const b = f === 0 ? "***" : S.turnRad != null ? String(S.turnRad) : "***";
|
|
1123
|
-
g.push(b);
|
|
1124
|
-
}
|
|
1125
|
-
if (o) {
|
|
1126
|
-
const b = f === 0 ? "***" : S.name ?? "";
|
|
1127
|
-
g.push(b);
|
|
1128
|
-
}
|
|
1129
|
-
p.push(g.join(","));
|
|
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.degree, M = Number(x.minute).toFixed(s), k = x.direction, U = P.degree, E = Number(P.minute).toFixed(s), B = P.direction, $ = [y, String(S), M, k, String(U), E, B];
|
|
1093
|
+
r && $.push(f === 0 ? "***" : g.port != null ? String(g.port) : "***"), i && $.push(f === 0 ? "***" : g.stbd != null ? String(g.stbd) : "***"), c && $.push(f === 0 ? "***" : g.arrRad != null ? String(g.arrRad) : "***"), a && $.push(f === 0 ? "***" : g.speed != null ? Number(g.speed).toFixed(1).padStart(5, "0") : "***"), l && $.push(f === 0 ? "***" : g.gcToPrevious ? "GC" : "RL"), u && $.push(f === 0 ? "***" : g.rot != null ? String(g.rot) : "***"), m && $.push(f === 0 ? "***" : g.turnRad != null ? String(g.turnRad) : "***"), o && $.push(g.name ?? ""), p.push($.join(","));
|
|
1130
1094
|
}
|
|
1131
1095
|
return p.join(`
|
|
1132
1096
|
`);
|
|
@@ -1143,26 +1107,26 @@ class v {
|
|
|
1143
1107
|
* @returns Uint8Array 二进制数据,可直接用于 new Blob([result], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})
|
|
1144
1108
|
*/
|
|
1145
1109
|
static waypoints2XLSX(t, e, n) {
|
|
1146
|
-
const s = (n == null ? void 0 : n.precision) ?? 6, o = t || "Route", r = e.some((
|
|
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, O) => O > 0 && N.gcToPrevious != null), h = e.some((N) => N.bearing != null), p = e.some((N) => N.distanceFromPrevious != null), f = ["WPT No.", "Latitude", "Longitude"];
|
|
1147
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]");
|
|
1148
|
-
const g = (
|
|
1149
|
-
let
|
|
1150
|
-
for (let
|
|
1151
|
-
const
|
|
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, O) => `<c r="${G(O)}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 O = e[N], W = N + 2, j = [], Z = (q, L) => j.push(`<c r="${G(q)}${W}"><v>${L}</v></c>`), A = (q, L) => j.push(`<c r="${G(q)}${W}" t="inlineStr"><is><t>${g(L)}</t></is></c>`), w = (q, L) => {
|
|
1152
1116
|
L != null ? Z(q, L) : A(q, "");
|
|
1153
1117
|
};
|
|
1154
|
-
Z(0,
|
|
1118
|
+
Z(0, N + 1), A(1, d.lat2pretty(O.lat, s).pretty), A(2, d.lng2pretty(O.lng, s).pretty);
|
|
1155
1119
|
let D = 3;
|
|
1156
|
-
r && (A(D,
|
|
1120
|
+
r && (A(D, O.name ?? ""), D++), i && (A(D, O.description ?? ""), D++), m && (A(D, N === 0 ? "" : O.gcToPrevious ? "GC" : "RL"), D++), h && (w(D, O.bearing), D++), p && (w(D, O.distanceFromPrevious), D++), u && (w(D, O.speed), D++), c && (w(D, O.port), D++), a && (w(D, O.stbd), D++), l && (w(D, O.arrRad), D++), x += `<row r="${W}">${j.join("")}</row>`;
|
|
1157
1121
|
}
|
|
1158
|
-
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>', k = '<?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>', U = '<?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>', B = '<?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>', $ = new TextEncoder();
|
|
1159
1123
|
return _([
|
|
1160
|
-
{ name: "[Content_Types].xml", data:
|
|
1161
|
-
{ name: "_rels/.rels", data:
|
|
1162
|
-
{ name: "xl/workbook.xml", data:
|
|
1163
|
-
{ name: "xl/_rels/workbook.xml.rels", data:
|
|
1164
|
-
{ name: "xl/worksheets/sheet1.xml", data:
|
|
1165
|
-
{ name: "xl/styles.xml", data:
|
|
1124
|
+
{ name: "[Content_Types].xml", data: $.encode(M) },
|
|
1125
|
+
{ name: "_rels/.rels", data: $.encode(k) },
|
|
1126
|
+
{ name: "xl/workbook.xml", data: $.encode(U) },
|
|
1127
|
+
{ name: "xl/_rels/workbook.xml.rels", data: $.encode(E) },
|
|
1128
|
+
{ name: "xl/worksheets/sheet1.xml", data: $.encode(S) },
|
|
1129
|
+
{ name: "xl/styles.xml", data: $.encode(B) }
|
|
1166
1130
|
]);
|
|
1167
1131
|
}
|
|
1168
1132
|
/**
|
|
@@ -1222,7 +1186,7 @@ class v {
|
|
|
1222
1186
|
*/
|
|
1223
1187
|
static coordinatesSummary(t, e = 3) {
|
|
1224
1188
|
if (t.length > 1) {
|
|
1225
|
-
const n = t[0], s = t[t.length - 1], o = (n == null ? void 0 : n.positionTime) < (s == null ? void 0 : s.positionTime) ?
|
|
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(
|
|
1226
1190
|
(h, p) => (h.duration += p.duration, h.distance += p.distance, h),
|
|
1227
1191
|
{ hours: 0, distance: 0, spd: 0, duration: 0 }
|
|
1228
1192
|
);
|
|
@@ -1258,21 +1222,21 @@ class v {
|
|
|
1258
1222
|
var l, u, m;
|
|
1259
1223
|
if (!((u = (l = e == null ? void 0 : e.sample) == null ? void 0 : l.hours) != null && u.length))
|
|
1260
1224
|
return { routes: [], hour: void 0 };
|
|
1261
|
-
const n = e.sample.hours.at(0), s =
|
|
1225
|
+
const n = e.sample.hours.at(0), s = b.utc(t), o = b.utc(e.eta), r = s.isAfter(o) ? o : s;
|
|
1262
1226
|
let i = e.sample.all.find((h) => h.eta === r.format());
|
|
1263
1227
|
if (!i) {
|
|
1264
|
-
const h = e.sample.all.filter((M) =>
|
|
1265
|
-
i = (m = this.calculateNextCoordinateAlongRoute(h, h.speed * r.diff(
|
|
1266
|
-
const { cFactor: f, cog: g, wxFactor:
|
|
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;
|
|
1267
1231
|
i = {
|
|
1268
1232
|
...i,
|
|
1269
1233
|
cFactor: f,
|
|
1270
1234
|
cog: g,
|
|
1271
1235
|
speed: h.speed,
|
|
1272
|
-
wxFactor:
|
|
1273
|
-
distanceFromStart:
|
|
1274
|
-
distanceFromPrevious:
|
|
1275
|
-
meteo:
|
|
1236
|
+
wxFactor: y,
|
|
1237
|
+
distanceFromStart: S,
|
|
1238
|
+
distanceFromPrevious: P,
|
|
1239
|
+
meteo: x,
|
|
1276
1240
|
eta: r.format(),
|
|
1277
1241
|
etd: r.format()
|
|
1278
1242
|
};
|
|
@@ -1296,10 +1260,10 @@ class v {
|
|
|
1296
1260
|
*/
|
|
1297
1261
|
static pickUTCSampleFromRoute(t, e, n) {
|
|
1298
1262
|
var h;
|
|
1299
|
-
const s = this.calculateSubRoute(e, n), o = this.calculateRouteDistance(s), r = o / e.speed, i =
|
|
1263
|
+
const s = this.calculateSubRoute(e, n), o = this.calculateRouteDistance(s), r = o / e.speed, i = b.utc(t), c = b(e.etd), a = (h = this.calculateNextCoordinateAlongRoute(e, e.speed * i.diff(b(e.etd), "hours", !0), s)) == null ? void 0 : h.coordinate;
|
|
1300
1264
|
a.speed = e.speed;
|
|
1301
1265
|
const l = c.clone().add(a.hourFromPrevious, "hour");
|
|
1302
|
-
a.eta = Math.abs(l.diff(i, "second")) < 2 ? i.format() : l.format(), a.etd = a.eta, a.distanceFromStart = Math.round(a.distanceFromPrevious * 100) / 100, a.distanceToGo = Math.round((o - a.distanceFromStart) * 100) / 100, a.timeToGo = Math.round(c.clone().add(r, "hour").diff(
|
|
1266
|
+
a.eta = Math.abs(l.diff(i, "second")) < 2 ? i.format() : l.format(), a.etd = a.eta, a.distanceFromStart = Math.round(a.distanceFromPrevious * 100) / 100, a.distanceToGo = Math.round((o - a.distanceFromStart) * 100) / 100, a.timeToGo = Math.round(c.clone().add(r, "hour").diff(b(a.etd), "hour") * 100) / 100;
|
|
1303
1267
|
const u = this.calculateRangeWaypoints(e, a, n);
|
|
1304
1268
|
return {
|
|
1305
1269
|
routes: this.generateRouteAccordingToWaypoints(u),
|
|
@@ -1317,9 +1281,9 @@ class v {
|
|
|
1317
1281
|
return n = n > 180 ? 360 - n : n, n;
|
|
1318
1282
|
}
|
|
1319
1283
|
}
|
|
1320
|
-
let
|
|
1284
|
+
let I;
|
|
1321
1285
|
try {
|
|
1322
|
-
|
|
1286
|
+
I = z.getLogger("vessel");
|
|
1323
1287
|
} catch {
|
|
1324
1288
|
} finally {
|
|
1325
1289
|
}
|
|
@@ -1337,17 +1301,17 @@ class it {
|
|
|
1337
1301
|
i && i.wind && (i.wind.kts = i.kts);
|
|
1338
1302
|
for (const c of r.forecasts) {
|
|
1339
1303
|
let a;
|
|
1340
|
-
const l = [], u = [], m =
|
|
1304
|
+
const l = [], u = [], m = b(c.date).utc(), h = `${r.name}-${c.model}`;
|
|
1341
1305
|
for (const f in c == null ? void 0 : c.hours) {
|
|
1342
1306
|
const g = c.hours[f];
|
|
1343
1307
|
a = a || g;
|
|
1344
|
-
const
|
|
1308
|
+
const y = m.clone().add(Number(f), "hour"), x = T.point([g.lng, g.lat], {
|
|
1345
1309
|
model: c.model,
|
|
1346
1310
|
name: r.name,
|
|
1347
1311
|
nameCn: r.nameCn,
|
|
1348
|
-
date:
|
|
1312
|
+
date: y.format(),
|
|
1349
1313
|
hour: Number(f),
|
|
1350
|
-
format:
|
|
1314
|
+
format: y.format("MMM-DD/HHmm[Z]"),
|
|
1351
1315
|
pressure: g.pressure > 1e4 ? d.roundPrecision(g.pressure / 100, 0) : d.roundPrecision(g.pressure, 0),
|
|
1352
1316
|
gusts: g.gusts,
|
|
1353
1317
|
wind: g.wind || {},
|
|
@@ -1355,17 +1319,17 @@ class it {
|
|
|
1355
1319
|
category: h,
|
|
1356
1320
|
type: "forecast"
|
|
1357
1321
|
});
|
|
1358
|
-
u.push(
|
|
1322
|
+
u.push(x), l.push(x.geometry.coordinates);
|
|
1359
1323
|
}
|
|
1360
1324
|
const p = {
|
|
1361
1325
|
kts: void 0,
|
|
1362
1326
|
deg: void 0
|
|
1363
1327
|
};
|
|
1364
1328
|
if (i) {
|
|
1365
|
-
const f =
|
|
1329
|
+
const f = b(i.updated).utc();
|
|
1366
1330
|
if (a) {
|
|
1367
|
-
const
|
|
1368
|
-
p.kts = Math.round(
|
|
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);
|
|
1369
1333
|
}
|
|
1370
1334
|
const g = T.point([i.lng, i.lat], {
|
|
1371
1335
|
model: c.model,
|
|
@@ -1398,10 +1362,10 @@ class it {
|
|
|
1398
1362
|
}
|
|
1399
1363
|
}
|
|
1400
1364
|
}
|
|
1401
|
-
if (e.features.sort((c, a) => c.properties.type === "forecast" && a.properties.type === "forecast" && c.geometry.type === "Point" && a.geometry.type === "Point" ?
|
|
1402
|
-
const c = [], a =
|
|
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) {
|
|
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;
|
|
1403
1367
|
for (const m of r.history) {
|
|
1404
|
-
const h =
|
|
1368
|
+
const h = b(m.updated).utc(), p = h.isSameOrBefore(a) || h.isSame(l);
|
|
1405
1369
|
p && a.add(-u, "h");
|
|
1406
1370
|
const f = T.point([m.lng, m.lat], {
|
|
1407
1371
|
name: r.name,
|
|
@@ -1443,32 +1407,32 @@ class it {
|
|
|
1443
1407
|
var o, r, i, c;
|
|
1444
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 = [];
|
|
1445
1409
|
for (const a of n) {
|
|
1446
|
-
const l = a.properties.name, u = a.properties.model, m = a.properties.showCircle, h = a.properties.disabled, p =
|
|
1410
|
+
const l = a.properties.name, u = a.properties.model, m = a.properties.showCircle, h = a.properties.disabled, p = b(a.properties.date).utc();
|
|
1447
1411
|
let f = e * 60;
|
|
1448
1412
|
const g = (r = t == null ? void 0 : t.data) == null ? void 0 : r.features.filter(
|
|
1449
|
-
(
|
|
1413
|
+
(P) => P.geometry.type === "Point" && P.properties.type === "forecast" && P.properties.category === `${l}-${u}`
|
|
1450
1414
|
);
|
|
1451
|
-
let
|
|
1452
|
-
for (;
|
|
1453
|
-
if (
|
|
1454
|
-
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)), k = this.computeNumber(S == null ? void 0 : S.geometry.coordinates[0], P.geometry.coordinates[0], M), U = this.computeNumber(S == null ? void 0 : S.geometry.coordinates[1], P.geometry.coordinates[1], M), E = T.point([k, U], {
|
|
1455
1419
|
name: l,
|
|
1456
1420
|
model: u,
|
|
1457
|
-
category:
|
|
1458
|
-
date:
|
|
1459
|
-
format:
|
|
1460
|
-
gusts: this.computeNumber(
|
|
1461
|
-
hour: this.computeNumber(
|
|
1462
|
-
movement: this.computeNumber(
|
|
1463
|
-
pressure: this.computeNumber(
|
|
1464
|
-
wind: this.computeNumber(
|
|
1421
|
+
category: P == null ? void 0 : P.properties.category,
|
|
1422
|
+
date: x.format(),
|
|
1423
|
+
format: x.format("MMM-DD/HHmm[Z]"),
|
|
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),
|
|
1465
1429
|
type: "forecast",
|
|
1466
1430
|
disabled: h,
|
|
1467
1431
|
showCircle: m
|
|
1468
1432
|
});
|
|
1469
1433
|
s.push(E);
|
|
1470
1434
|
}
|
|
1471
|
-
f += e * 60,
|
|
1435
|
+
f += e * 60, x = p.clone().add(f, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
1472
1436
|
}
|
|
1473
1437
|
}
|
|
1474
1438
|
return s;
|
|
@@ -1500,7 +1464,7 @@ class it {
|
|
|
1500
1464
|
if (!s.debug) {
|
|
1501
1465
|
const p = v.calculateDistance(t, o), f = v.calculateDistance(t, r);
|
|
1502
1466
|
if (p > 2 * n && f > 2 * n)
|
|
1503
|
-
return
|
|
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, {
|
|
1504
1468
|
from: t,
|
|
1505
1469
|
t1: o,
|
|
1506
1470
|
t2: r,
|
|
@@ -1511,7 +1475,7 @@ class it {
|
|
|
1511
1475
|
let m = 0;
|
|
1512
1476
|
u < 180 ? m = u + 90 : u >= 180 && (m = u - 90);
|
|
1513
1477
|
const h = v.calculateCoordinate(o, m, n);
|
|
1514
|
-
return
|
|
1478
|
+
return I == null || I.info("[%s] the right tangent position: %j", s.requestId, {
|
|
1515
1479
|
from: t,
|
|
1516
1480
|
t1: o,
|
|
1517
1481
|
t2: r,
|
|
@@ -1539,7 +1503,7 @@ class it {
|
|
|
1539
1503
|
if (!s.debug) {
|
|
1540
1504
|
const h = v.calculateDistance(t, o), p = v.calculateDistance(t, r);
|
|
1541
1505
|
if (h > 2 * n && p > 2 * n)
|
|
1542
|
-
return
|
|
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, {
|
|
1543
1507
|
from: t,
|
|
1544
1508
|
t1: o,
|
|
1545
1509
|
t2: r,
|
|
@@ -1549,7 +1513,7 @@ class it {
|
|
|
1549
1513
|
const a = v.calculateBearing(t, o), l = v.calculateBearing(o, r), u = v.calculateDistance(t, o);
|
|
1550
1514
|
return { at: v.calculateCoordinate(o, a - l + 180, n < u ? n : u), t1: o, t2: r, hr: Number(i), hours: c };
|
|
1551
1515
|
} else
|
|
1552
|
-
return
|
|
1516
|
+
return I == null || I.info("[%s] no need drift: %j", s.requestId, { from: t, t1: o, t2: r, hr: i }), {};
|
|
1553
1517
|
}
|
|
1554
1518
|
/**
|
|
1555
1519
|
* 获取台风中心点对
|
|
@@ -1566,11 +1530,11 @@ class it {
|
|
|
1566
1530
|
s = { ...f.hours, ...s };
|
|
1567
1531
|
});
|
|
1568
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]]);
|
|
1569
|
-
|
|
1533
|
+
I == null || I.info("[%s] the first tropical center: %j", n.requestId, o);
|
|
1570
1534
|
let r = (h = Object.keys(s || {}).filter((f) => Number(f) <= (e < 0 ? 24 : e))) == null ? void 0 : h.at(-1);
|
|
1571
1535
|
r || (r = (p = Object.keys(s || {}).filter((f) => Number(f) <= (e < 0 ? 24 : 2 * e))) == null ? void 0 : p.at(-1));
|
|
1572
1536
|
const i = s == null ? void 0 : s[r || -1];
|
|
1573
|
-
|
|
1537
|
+
I == null || I.info("[%s] the second tropical center: %j in %d hrs", n.requestId, i, r);
|
|
1574
1538
|
const c = Object.keys(s || {}).filter((f) => Number(f) <= Number(r)), a = { 0: o };
|
|
1575
1539
|
for (const f of c)
|
|
1576
1540
|
a[f] = s[f];
|
|
@@ -1579,7 +1543,7 @@ class it {
|
|
|
1579
1543
|
static pickIndex(t, e) {
|
|
1580
1544
|
let n = 0;
|
|
1581
1545
|
for (const s of t) {
|
|
1582
|
-
if (
|
|
1546
|
+
if (b(s.properties.date).isAfter(e))
|
|
1583
1547
|
return n === 0 ? -1 : n;
|
|
1584
1548
|
n++;
|
|
1585
1549
|
}
|
|
@@ -1646,7 +1610,7 @@ class F {
|
|
|
1646
1610
|
* @param options 步数、单位等选项
|
|
1647
1611
|
*/
|
|
1648
1612
|
static drawCircle(t, e, n, s = {}) {
|
|
1649
|
-
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 =
|
|
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();
|
|
1650
1614
|
i.id = (s == null ? void 0 : s.id) || l.valueOf().toString();
|
|
1651
1615
|
const u = "circle";
|
|
1652
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 });
|
|
@@ -1658,7 +1622,7 @@ class F {
|
|
|
1658
1622
|
* @param options 选项
|
|
1659
1623
|
*/
|
|
1660
1624
|
static drawRect(t, e, n = {}) {
|
|
1661
|
-
const s = (n == null ? void 0 : n.properties) ?? {}, o =
|
|
1625
|
+
const s = (n == null ? void 0 : n.properties) ?? {}, o = b.utc();
|
|
1662
1626
|
s.id = (n == null ? void 0 : n.id) || o.valueOf().toString();
|
|
1663
1627
|
const r = "rect";
|
|
1664
1628
|
s.name = (n == null ? void 0 : n.name) || `${r}_${o.format()}`, s.start = t.map((l) => d.roundPrecision(l, 9)), s.end = e.map((l) => d.roundPrecision(l, 9)), s.shape = "rect", R.info("[%s] draw rect with %j", n == null ? void 0 : n.requestId, s);
|
|
@@ -1673,7 +1637,7 @@ class F {
|
|
|
1673
1637
|
* @returns
|
|
1674
1638
|
*/
|
|
1675
1639
|
static drawLine(t, e = {}) {
|
|
1676
|
-
const n = (e == null ? void 0 : e.properties) ?? {}, s =
|
|
1640
|
+
const n = (e == null ? void 0 : e.properties) ?? {}, s = b.utc();
|
|
1677
1641
|
n.id = (e == null ? void 0 : e.id) || s.valueOf().toString();
|
|
1678
1642
|
const o = "line";
|
|
1679
1643
|
n.name = (e == null ? void 0 : e.name) || `${o}_${s.format()}`, n.shape = "line", R.info("[%s] draw line with %j", e == null ? void 0 : e.requestId, n);
|
|
@@ -1687,7 +1651,7 @@ class F {
|
|
|
1687
1651
|
* @returns
|
|
1688
1652
|
*/
|
|
1689
1653
|
static drawPolygon(t, e = {}) {
|
|
1690
|
-
const n = (e == null ? void 0 : e.properties) ?? {}, s =
|
|
1654
|
+
const n = (e == null ? void 0 : e.properties) ?? {}, s = b.utc();
|
|
1691
1655
|
n.id = (e == null ? void 0 : e.id) || s.valueOf().toString();
|
|
1692
1656
|
const o = "polygon";
|
|
1693
1657
|
n.name = (e == null ? void 0 : e.name) || `${o}_${s.format()}`, n.coordinates = t.map((i) => i.map((c) => d.roundPrecision(c, 9))), n.shape = "polygon", R.info("[%s] draw polygon with %j", e == null ? void 0 : e.requestId, n);
|
|
@@ -1702,7 +1666,7 @@ class F {
|
|
|
1702
1666
|
* @returns
|
|
1703
1667
|
*/
|
|
1704
1668
|
static drawPoint(t, e, n = {}) {
|
|
1705
|
-
const s = (n == null ? void 0 : n.properties) ?? {}, o =
|
|
1669
|
+
const s = (n == null ? void 0 : n.properties) ?? {}, o = b.utc();
|
|
1706
1670
|
s.id = (n == null ? void 0 : n.id) || o.valueOf().toString();
|
|
1707
1671
|
const r = "point";
|
|
1708
1672
|
return s.name = (n == null ? void 0 : n.name) || `${r}_${o.format()}`, s.shape = "point", R.info("[%s] draw point with %j", n == null ? void 0 : n.requestId, s), T.point([e, t], s);
|
|
@@ -1719,7 +1683,7 @@ class F {
|
|
|
1719
1683
|
R.info("[%s] parse circle with %j", e == null ? void 0 : e.requestId, t.properties);
|
|
1720
1684
|
const n = t.properties || {};
|
|
1721
1685
|
if (n.shape == "circle") {
|
|
1722
|
-
const r =
|
|
1686
|
+
const r = b.utc();
|
|
1723
1687
|
n.id = (n == null ? void 0 : n.id) || r.valueOf().toString();
|
|
1724
1688
|
const i = n == null ? void 0 : n.id, c = ((s = n == null ? void 0 : n.center) == null ? void 0 : s.length) == 2 ? T.point(n.center) : T.centroid(t);
|
|
1725
1689
|
let a = "center";
|
|
@@ -1749,7 +1713,7 @@ class F {
|
|
|
1749
1713
|
R.info("[%s] parse rect with %j", e == null ? void 0 : e.requestId, t.properties);
|
|
1750
1714
|
const n = t.properties || {};
|
|
1751
1715
|
if (n.shape == "rect") {
|
|
1752
|
-
const s =
|
|
1716
|
+
const s = b.utc();
|
|
1753
1717
|
n.id = (n == null ? void 0 : n.id) || s.valueOf().toString();
|
|
1754
1718
|
const o = n == null ? void 0 : n.id, r = t.geometry.coordinates[0], c = ["sw", "nw", "ne", "se"].map((a, l) => {
|
|
1755
1719
|
const u = T.point(r[l]);
|
|
@@ -1770,7 +1734,7 @@ class F {
|
|
|
1770
1734
|
R.info("[%s] parse line with %j", e == null ? void 0 : e.requestId, t.properties);
|
|
1771
1735
|
const n = t.properties || {};
|
|
1772
1736
|
if (n.shape == "line") {
|
|
1773
|
-
const s =
|
|
1737
|
+
const s = b.utc();
|
|
1774
1738
|
n.id = (n == null ? void 0 : n.id) || s.valueOf().toString();
|
|
1775
1739
|
const o = n == null ? void 0 : n.id, i = t.geometry.coordinates.map((c, a) => {
|
|
1776
1740
|
const l = `point_${a}`, u = T.point(c);
|
|
@@ -1791,7 +1755,7 @@ class F {
|
|
|
1791
1755
|
R.info("[%s] parse polygon with %j", e == null ? void 0 : e.requestId, t.properties);
|
|
1792
1756
|
const n = t.properties || {};
|
|
1793
1757
|
if (n.shape == "polygon") {
|
|
1794
|
-
const s =
|
|
1758
|
+
const s = b.utc();
|
|
1795
1759
|
n.id = (n == null ? void 0 : n.id) || s.valueOf().toString();
|
|
1796
1760
|
const o = n == null ? void 0 : n.id, i = t.geometry.coordinates[0].map((c, a) => {
|
|
1797
1761
|
const l = T.point(c), u = `corner_${a}`;
|
|
@@ -1838,17 +1802,17 @@ class F {
|
|
|
1838
1802
|
for (; l < u; ) {
|
|
1839
1803
|
if (s.getUint32(l, !0) !== 33639248)
|
|
1840
1804
|
throw new Error(`Invalid ZIP file: Central Directory signature mismatch at offset ${l}`);
|
|
1841
|
-
const p = s.getUint16(l + 10, !0), f = s.getUint32(l + 20, !0), g = s.getUint16(l + 28, !0),
|
|
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), k = s.getUint16(P + 26, !0), U = s.getUint16(P + 28, !0), E = P + 30 + k + U, B = o.slice(E, E + f);
|
|
1842
1806
|
if (p === 0)
|
|
1843
1807
|
r.set(M, B);
|
|
1844
1808
|
else if (p === 8) {
|
|
1845
1809
|
if (typeof DecompressionStream < "u") {
|
|
1846
|
-
const
|
|
1847
|
-
|
|
1810
|
+
const $ = new DecompressionStream("deflate-raw"), N = $.writable.getWriter(), O = $.readable.getReader();
|
|
1811
|
+
N.write(B), N.close();
|
|
1848
1812
|
const W = [];
|
|
1849
1813
|
let j = 0;
|
|
1850
1814
|
for (; ; ) {
|
|
1851
|
-
const { done: w, value: D } = await
|
|
1815
|
+
const { done: w, value: D } = await O.read();
|
|
1852
1816
|
if (w)
|
|
1853
1817
|
break;
|
|
1854
1818
|
W.push(D), j += D.length;
|
|
@@ -1864,7 +1828,7 @@ class F {
|
|
|
1864
1828
|
} catch {
|
|
1865
1829
|
}
|
|
1866
1830
|
}
|
|
1867
|
-
l += 46 + g +
|
|
1831
|
+
l += 46 + g + y + x;
|
|
1868
1832
|
}
|
|
1869
1833
|
return r;
|
|
1870
1834
|
}
|
|
@@ -1883,36 +1847,36 @@ class F {
|
|
|
1883
1847
|
const s = H().parseFromString(t, "application/xml"), o = Array.from(s.querySelectorAll("Placemark")), r = [];
|
|
1884
1848
|
for (const a of o) {
|
|
1885
1849
|
const l = {}, u = Array.from(a.querySelectorAll("ExtendedData > Data"));
|
|
1886
|
-
for (const
|
|
1887
|
-
const M =
|
|
1888
|
-
M &&
|
|
1850
|
+
for (const S of u) {
|
|
1851
|
+
const M = S.getAttribute("name"), k = (c = (i = S.querySelector("value")) == null ? void 0 : i.textContent) == null ? void 0 : c.trim();
|
|
1852
|
+
M && k !== void 0 && k !== null && (l[M] = k);
|
|
1889
1853
|
}
|
|
1890
|
-
const m =
|
|
1891
|
-
const
|
|
1892
|
-
return [
|
|
1893
|
-
}),
|
|
1894
|
-
if (
|
|
1895
|
-
const
|
|
1896
|
-
if (
|
|
1897
|
-
const M = T.lineString(
|
|
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 k = M.split(",").map(Number);
|
|
1856
|
+
return [k[0], k[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 });
|
|
1898
1862
|
r.push(M);
|
|
1899
1863
|
}
|
|
1900
1864
|
continue;
|
|
1901
1865
|
}
|
|
1902
|
-
const
|
|
1903
|
-
if (
|
|
1904
|
-
const
|
|
1905
|
-
if (
|
|
1906
|
-
const M =
|
|
1907
|
-
r.push(
|
|
1866
|
+
const x = a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");
|
|
1867
|
+
if (x) {
|
|
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]], k = T.polygon([M], { ...l, shape: "polygon", id: f, name: p });
|
|
1871
|
+
r.push(k);
|
|
1908
1872
|
}
|
|
1909
1873
|
continue;
|
|
1910
1874
|
}
|
|
1911
|
-
const
|
|
1912
|
-
if (
|
|
1913
|
-
const
|
|
1914
|
-
if (
|
|
1915
|
-
const M = T.point(
|
|
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 });
|
|
1916
1880
|
r.push(M);
|
|
1917
1881
|
}
|
|
1918
1882
|
continue;
|
|
@@ -1972,7 +1936,7 @@ class F {
|
|
|
1972
1936
|
typeof Buffer < "u" && Buffer.isBuffer(t) && (t = F.toArrayBuffer(t));
|
|
1973
1937
|
const n = await J(t);
|
|
1974
1938
|
if (Array.isArray(n)) {
|
|
1975
|
-
const s = n.flatMap((c) => c.features || []), o =
|
|
1939
|
+
const s = n.flatMap((c) => c.features || []), o = b.utc(), r = (e == null ? void 0 : e.id) || o.valueOf().toString(), i = {
|
|
1976
1940
|
Point: "point",
|
|
1977
1941
|
MultiPoint: "point",
|
|
1978
1942
|
LineString: "line",
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
(function(I,Z){typeof exports=="object"&&typeof module<"u"?Z(exports,require("@turf/turf"),require("moment"),require("@log4js-node/log4js-api"),require("moment-timezone"),require("tz-lookup"),require("shpjs")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","@log4js-node/log4js-api","moment-timezone","tz-lookup","shpjs"],Z):(I=typeof globalThis<"u"?globalThis:I||self,Z(I["idm-plugin-rabbitmq"]={},I["@turf/turf"],I.moment,I["@log4js-node/log4js-api"],I["moment-timezone"],I["tz-lookup"],I.shpjs))})(this,function(I,Z,x,J,re,Y,Q){"use strict";function _(M){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(M){for(const t in M)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(M,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>M[t]})}}return e.default=M,Object.freeze(e)}const T=_(Z);class d{static guessTimeZoneOffset(e,t){e=d.convertToStdLng(e);const n=Y(t,e),s=x().tz(n).utcOffset();return d.roundPrecision(s/60,1)}static prettyTimeZoneOffset(e){let t=Math.floor(Math.abs(e)),n=Math.round((Math.abs(e)-t)*60);return n=n>9?n:`0${n}`,t=t>9?t:`0${t}`,e>0?`+${t}:${n}`:`-${t}:${n}`}static lng2pretty(e,t=6,n="H°M′"){e=d.convertToStdLng(e,t);let s="E";e<0&&(s="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,r,i,c,a,l,u;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,t).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,t).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);const g=`${n.replace(/S+/gi,i).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:d.roundPrecision(l,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(r,t),pretty:g,S:i,M:a,H:u}}static lat2pretty(e,t=6,n="H°M′"){e=e%180;let s="N";e<0&&(s="S"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,r,i,c,a,l,u;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,t).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,t).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);const g=`${n.replace(/S+/gi,i).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:d.roundPrecision(l,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(r,t),pretty:g,S:i,M:a,H:u}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LNG");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[r,i,c]=o;if(i=i||0,i=i>60?i/Math.pow(10,String(i).length-2):i,c=c||0,c=c>60?c/Math.pow(10,String(c).length-2):c,r>360&&!i){const a=this.roundPrecision(r/100,0);i=r-a*100,r=a}n=r+i/60+c/3600,s==="W"&&(n=n*-1)}else n=Number(e);return d.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LAT");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[r,i,c]=o;if(c=c||0,i=i||0,i=i>60?i/Math.pow(10,String(i).length-2):i,c=c>60?c/Math.pow(10,String(c).length-2):c,r>90&&!i){const a=this.roundPrecision(r/100,0);i=r-a*100,r=a}if(n=r+i/60+c/3600,n>90)throw new Error(`latitude out of range: ${e}${s}`);s==="S"&&(n=n*-1)}else n=Number(e);return d.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=d.strReplace(e,n);const s=e[e.length-1].toUpperCase();return["N","S"].includes(s)?{lat:d.str2Lat(e,t)}:{lng:d.str2Lng(e,t)}}static convertToStdLng(e,t=6){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),d.roundPrecision(e,t)}static roundPrecision(e,t=6){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}static convertToMonotonicLng2(e){for(let t=1;t<e.length;t++)e[t][0]+=Math.round((e[t-1][0]-e[t][0])/360)*360;return e}static convertToMonotonicLng(e){for(let t=1;t<e.length;t++)e[t].lng+=Math.round((e[t-1].lng-e[t].lng)/360)*360;return e}static strReplace(e,t="LAT"){e=e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g,"$1 $2").replace(/([0-9]+)-([0-9]+\.[0-9]+)/g,"$1 $2").replace(/°/," ").replace(/(\d+)-(\d?)/g,"$1 $2").replace(/'/g," ").replace(/′/g," ").replace(/"/g," ").replace(/∼/g," ").replace(/°/g," ").replace(/,/g,".").replace(/^ /g,"").replace(/ $/g,"").trim();const n=e[e.length-1].toUpperCase();if(!["N","S","E","W"].includes(n)){const s=e,o=Number(s.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${e}`);o>=90?e=`${s}E`:o<=-90?e=`${s}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${s}${o>0?"E":"W"}`:e=`${s}${o>0?"N":"S"}`}return e}static padNumber(e,t=2,n=2){const s=d.roundPrecision(e-Math.trunc(e),n),o=s>=1?Math.trunc(e+1).toString().padStart(t,"0"):Math.trunc(e).toString().padStart(t,"0");return s>=1?o:n>0?`${o}.${Math.trunc(s*Math.pow(10,n)).toString().padStart(n,"0")}`:o}}class K{static json2Str(e){const t=e.type?e.type[0].toUpperCase():"A";return`${e.lat}|${e.lng}|${e.positionTime}|${e.sog}|${e.cog}|${e.hdg}|${e.draught}|${t}|${JSON.stringify(e.meteo||{})}|${e.vendor}|${e.deleted}`}static str2Json(e){const[t,n,s,o,r,i,c,a,l,u,g]=e.split("|");return{lat:Number(t),lng:Number(n),positionTime:Number(s),sog:Number(o),cog:Number(r),hdg:Number(i),draught:isNaN(c)?null:Number(c),type:a,important:a!=="A",meteo:l?JSON.parse(l):void 0,vendor:u,deleted:g==="true"}}static inspectStoppages(e,t=1,n=!0){const s=e.at(0).positionTime<e.at(-1).positionTime;s||e.sort((c,a)=>c.positionTime-a.positionTime);const o=[];let r,i;for(let c=0;c<e.length-1;c++){const a=e[c];if(!(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))){for(let l=c+1;l<e.length;l++){const u=e[l-1],g=e[l];if(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))continue;const h=g.positionTime-u.positionTime;if(b.calculateDistance(g,u,!0,4)/(h/3600)<t)r||(r=a),l===e.length-1&&(i=g,c=l);else{r&&(i=e[l-1],c=l);break}}if((i==null?void 0:i.positionTime)>(r==null?void 0:r.positionTime)&&r){const l={start:{lat:r.lat,lng:r.lng,sog:r.sog,positionTime:r.positionTime,utc:x.unix(r.positionTime).utc().format()},end:{lat:i.lat,lng:i.lng,sog:i.sog,positionTime:i.positionTime,utc:x.unix(i.positionTime).utc().format()},duration:i.positionTime-r.positionTime},u=e.filter(h=>h.positionTime>=l.start.positionTime&&h.positionTime<=l.end.positionTime),g=b.divideAccordingToLng(u);l.distance=b.calculateRouteDistance(g),l.hours=Math.round(l.duration/3600*10)/10,l.avgSog=Math.round(l.distance/l.hours*10)/10,o.push(l)}r=void 0,i=void 0}}return s||e.sort((c,a)=>a.positionTime-c.positionTime),o}static inspectSummary(e,t,n){const s=x(t),o=x(n),r=e.filter(l=>l.positionTime>=s.unix()&&l.positionTime<=o.unix());let i=0,c=0;if(r.length>1)for(let l=0;l<r.length-1;l++){const u=r[l],g=r[l+1];i+=b.calculateDistance(u,g,!0,4),c+=Math.abs(g.positionTime-u.positionTime)}i=Math.round(i*100)/100,c=Math.round(c/3600*100)/100;const a=c?Math.round(i/c*100)/100:0;return{distance:i,interval:c,avgSpd:a}}}let X;try{X=J.getLogger("meteo")}catch{}finally{}const H=(()=>{const M=new Uint32Array(256);for(let e=0;e<256;e++){let t=e;for(let n=0;n<8;n++)t=t&1?3988292384^t>>>1:t>>>1;M[e]=t}return M})();function ee(M){let e=4294967295;for(let t=0;t<M.length;t++)e=H[(e^M[t])&255]^e>>>8;return(e^4294967295)>>>0}function te(M){const e=new TextEncoder,t=[],n=[];let s=0;for(const h of M){const p=e.encode(h.name),f=ee(h.data),m=new Uint8Array(30+p.length),S=new DataView(m.buffer);S.setUint32(0,67324752,!0),S.setUint16(4,20,!0),S.setUint16(8,0,!0),S.setUint32(14,f,!0),S.setUint32(18,h.data.length,!0),S.setUint32(22,h.data.length,!0),S.setUint16(26,p.length,!0),m.set(p,30),t.push({nameBytes:p,data:h.data,crc:f,offset:s}),s+=m.length+h.data.length,n.push(m,h.data)}const o=s,r=[];let i=0;for(const h of t){const p=new Uint8Array(46+h.nameBytes.length),f=new DataView(p.buffer);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)}const c=new Uint8Array(22),a=new DataView(c.buffer);a.setUint32(0,101010256,!0),a.setUint16(8,t.length,!0),a.setUint16(10,t.length,!0),a.setUint32(12,i,!0),a.setUint32(16,o,!0);const l=n.reduce((h,p)=>h+p.length,0)+i+22,u=new Uint8Array(l);let g=0;for(const h of n)u.set(h,g),g+=h.length;for(const h of r)u.set(h,g),g+=h.length;return u.set(c,g),u}function V(M){let e="",t=M;for(;t>=0;)e=String.fromCharCode(65+t%26)+e,t=Math.floor(t/26)-1;return e}class b{static calculateBearing(e,t,n=!0,s=4){const o=T.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=T.rhumbBearing(o.features[0],o.features[1]):r=T.bearing(o.features[0],o.features[1]),r<0&&(r+=360),d.roundPrecision(r,s)}static calculateDistance(e,t,n=!0,s=4,o="nauticalmiles"){e={...e},t={...t},e.lng=d.convertToStdLng(e.lng,s),t.lng=d.convertToStdLng(t.lng,s);const r=T.points([[e.lng,e.lat],[t.lng,t.lat]]);let i;return n?i=T.rhumbDistance(r.features[0],r.features[1],{units:o}):i=T.distance(r.features[0],r.features[1],{units:o}),d.roundPrecision(i,s)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let s=0,o;for(const r of e)for(let i=0;i<r.length-1;i++){const c={lng:r[i][0],lat:r[i][1]};i===0&&o&&(s+=this.calculateDistance(o,c,!0,t,n));const a={lng:r[i+1][0],lat:r[i+1][1]};s+=this.calculateDistance(c,a,!0,t,n),o=a}return d.roundPrecision(s,t)}static calculateCoordinate(e,t,n,s="nauticalmiles",o=!0){const r=T.point([e.lng,e.lat]);let i;o?i=T.rhumbDestination(r,n,t,{units:s}):i=T.destination(r,n,t,{units:s});const c=i.geometry.coordinates;return{lng:d.convertToStdLng(c[0],8),lat:d.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,s=!0,o=!0,r="nauticalmiles"){const i=[],c=this.calculateBearing(e,t,!1),a=this.calculateDistance(e,t,!1,8,r);s&&i.push({lng:e.lng,lat:e.lat});let l=0;for(;l<a;)l+=n,l<a&&i.push(this.calculateCoordinate(e,c,l,r,!1));return o&&i.push({lng:t.lng,lat:t.lat}),i}static divideAccordingToLng(e,t=!1,n=!0){if((e==null?void 0:e.length)<2)return[];e=n?this.deduplicateCoordinates(e):e;let s=[];const o=[];let r,i;for(let c=0;c<e.length-1;c++){r=d.convertToStdLng(e[c].lng,8),i=d.convertToStdLng(e[c+1].lng,8),e[c].lat=d.roundPrecision(e[c].lat,8),e[c+1].lat=d.roundPrecision(e[c+1].lat,8),s.push([r,e[c].lat]);const a=r-i;if(Math.abs(a)>180){const l=d.convertToMonotonicLng2([[r,e[c].lat],[i,e[c+1].lat]]);let u,g;t?(u=T.lineString(l),g=T.lineString([[a>0?180:-180,89],[a>0?180:-180,-89]])):(u=T.greatCircle(l[0],l[1]),g=T.greatCircle([a>0?180:-180,89],[a>0?180:-180,-89]));const h=T.lineIntersect(u,g);let p;if(h.features.length){const f=T.getCoord(h.features[0]);p=d.roundPrecision(f[1],8)}else p=e[c].lat;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]))}c===e.length-2&&s.push([i,e[c+1].lat])}return o.push(s),o}static deduplicateRoute(e){const t=[];for(const n of e){const s=n.reduce((o,r)=>(o.findIndex(i=>i[0]===r[0]&&i[1]===r[1])===-1&&o.push(r),o),[]);t.push(s)}return t}static deduplicateCoordinates(e){return e.reduce((t,n)=>(t.findIndex(s=>s.lat===n.lat&&s.lng===n.lng)===-1&&t.push(n),t),[])}static removeCoordinateFromRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);for(const n of t)for(let s=n.length-1;s>=0;s--)d.roundPrecision(n[s][0],8)===e.lng&&d.roundPrecision(n[s][1],8)===d.roundPrecision(e.lat,8)&&n.splice(s,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=d.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)d.roundPrecision(t[n].lng,8)===e.lng&&d.roundPrecision(t[n].lat,8)===d.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,s=0,o=0,r,i;return t.forEach((c,a)=>{for(let l=0;l<c.length-1;l++){const u={lng:c[l][0],lat:c[l][1]},g={lng:c[l+1][0],lat:c[l+1][1]},h=this.calculatePointToLineDistance(e,u,g);n>h&&(n=h,o=l,s=a,r=this.calculateDistance(u,e),i=this.calculateDistance(g,e))}}),r!==0&&i!==0?t[s].splice(o+1,0,[e.lng,e.lat]):r===0?t[s].splice(o,1,[e.lng,e.lat]):i===0&&t[s].splice(o+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);const n=b.convertRouteToCoordinates(t);return n.push(e),b.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=b.convertRouteToCoordinates(t);return n.unshift(e),b.divideAccordingToLng(n)}static mergeWaypointsToRoute(e,t){for(const n of e)t=this.mergeCoordinateToRoute(n,t);return t}static calculateRangeRoute(e,t,n){n=this.mergeWaypointsToRoute([e,t],n);const s=[];let o=0;return n.forEach(r=>{if(o===2)return;const i=[];for(const c of r){if(d.roundPrecision(t.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(c[1],8)){i.push(c),o===0&&i.push([e.lng,e.lat]),o=2;break}o===1?i.push(c):d.roundPrecision(e.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(c[1],8)&&(o=1,i.push(c))}i.length&&s.push(i)}),s}static calculateRangeWaypoints(e,t,n,s=[]){const o=this.convertRouteToCoordinates(n,0),r=this.mergeCoordinatesToWaypoints([e,t],o.length?o:s),i=r.findIndex(l=>d.roundPrecision(e.lng,8)===d.roundPrecision(l.lng,8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(l.lat,8)),c=r.findIndex(l=>d.roundPrecision(t.lng,8)===d.roundPrecision(l.lng,8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(l.lat,8));return r.filter((l,u)=>u>=i&&u<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,s=0,o=0;return t.forEach((r,i)=>{for(let c=0;c<r.length-1;c++){const a={lng:r[c][0],lat:r[c][1]},l={lng:r[c+1][0],lat:r[c+1][1]},u=this.calculatePointToLineDistance(e,a,l);n>u&&(n=u,s=c,o=i)}}),{minDist:n,segIndex:o,minIndex:s}}static calculateSubRoute(e,t){const n=b.convertRouteToCoordinates(t);b.mergeCoordinateToWaypoints(e,n,!0),t=b.divideAccordingToLng(n);const{segIndex:s,minIndex:o}=this.calculateMinDistanceToRoute({...e},t);e.lng=d.convertToStdLng(e.lng);const r=[];let i=!0;for(let c=s;c<t.length;c++)if(i){const a=[];a.push([e.lng,e.lat]);for(let l=o+1;l<t[c].length;l++)e.lng===t[c][l][0]&&e.lat===t[c][l][1]||a.push(t[c][l]);r.push(a),i=!1}else r.push([...t[c]]);return r}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,s=0;for(let r=0;r<t.length-1;r++){const i=t[r],c=t[r+1];if(this.calculateDistance(e,i)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((l,u)=>u>0);const a=this.calculatePointToLineDistance(e,i,c);n>a&&(n=a,s=r)}e.lng=d.convertToStdLng(e.lng);const o=[e];for(let r=s+1;r<t.length;r++)o.push(t[r]);return o}static calculatePointToLineDistance(e,t,n,s={units:"nauticalmiles",method:"geodesic"}){e.lng=d.convertToStdLng(e.lng,8),t={...t},n={...n},t.lng=d.convertToStdLng(t.lng,8),n.lng=d.convertToStdLng(n.lng,8);const o=d.convertToMonotonicLng([t,n]);t=o[0],n=o[1];const r=T.lineString([[t.lng,t.lat],[n.lng,n.lat]]),i=T.pointToLineDistance(T.point([e.lng,e.lat]),r,s),c=T.pointToLineDistance(T.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),r,s);return d.roundPrecision(Math.min(i,c),6)}static calculateWaypointsPropInRoute(e,t){t=this.mergeWaypointsToRoute(e,t);for(let n=0;n<e.length-1;n++){const s=e[n],o=e[n+1],r=this.calculateRangeRoute(s,o,t);n===0&&(s.distanceFromPrevious=0,s.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(r),o.distanceFromStart=d.roundPrecision((s.distanceFromStart||0)+o.distanceFromPrevious)}return e}static mergeCoordinatesToWaypoints(e,t,n=!0){for(const s of e)this.mergeCoordinateToWaypoints(s,t,n);return t}static mergeCoordinateToWaypoints(e,t,n=!0){e.lng=d.convertToStdLng(e.lng,8);let s=Number.MAX_VALUE,o=0,r=0,i=0;if(t.length<2)t.push(e);else{for(let c=0;c<t.length-1;c++){const a={lng:t[c].lng,lat:t[c].lat},l={lng:t[c+1].lng,lat:t[c+1].lat},u=this.calculatePointToLineDistance(e,a,l);s>=u&&(s=u,o=c,r=this.calculateDistance(a,e,!1,6),i=this.calculateDistance(l,e,!1,6))}r!==0&&i!==0?r<=s&&o===0?t.unshift(e):i<=s&&o===t.length-2?t.push(e):t.splice(o+1,0,e):r===0?n?t.splice(o,1,e):t.splice(o+1,0,e):i===0&&(n?t.splice(o+1,1,e):t.splice(o+1,0,e))}return t.map((c,a)=>{c.lng=d.convertToStdLng(c.lng);const l=t[a+1];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)){const u=this.calculateDistance(c,l,!0),g=Math.abs(l.positionTime-c.positionTime)/3600;c.sog=d.roundPrecision(u/g,2)}return c})}static generateRouteAccordingToWaypoints(e,t=!0,n=!0){const s=[];for(let o=1;o<e.length;o++){const r=e[o-1],i=e[o];if(o===1&&s.push(r),i.gcToPrevious){const c=this.interpolateCoordinates(r,i,200,!1,!0,"nauticalmiles");s.push(...c)}else s.push(i)}return this.divideAccordingToLng(s,t,n)}static nearestCoordinateInRoute(e,t){const n=T.point([e.lng,e.lat]),o=this.convertRouteToCoordinates(t).map(a=>[a.lng,a.lat]),r=T.lineString(o),i=T.nearestPointOnLine(r,n),c=T.getCoord(i);return{lng:d.roundPrecision(c[0],8),lat:d.roundPrecision(c[1],8)}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let s=0;s<t.length-1;s++){const o=t[s],r=t[s+1];if(this.calculateDistance(e,o)===0){n=s;break}if(this.calculateDistance(e,r)===0){n=s+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,s="nauticalmiles"){var g;const o=e.speed||12,r=[];let i=[],c=!1,a=0,l=0,u;if(t&&n.length?(r.push(e),n.forEach((h,p)=>{if(c)i.push(h);else{const f=[];let m;for(let S=0;S<h.length;S++)if(u)f.push(h[S]);else{m={lng:h[S][0],lat:h[S][1]};const P=this.calculateDistance(e,m,!0,8,s);if(a+=P,a<t)l+=P,P&&r.push(m),e=m;else{if(l=t,a===t)u=m,f.push([u.lng,u.lat]);else{const N=a-t,y=this.calculateBearing(m,e);u=this.calculateCoordinate(m,y,N,s),f.push([u.lng,u.lat]),f.push([m.lng,m.lat])}c=!0}}f.length&&i.push(f),p===n.length-1&&!u&&(u=m)}})):(i=n,u={...e}),u)if(r.push(u),u.distanceFromPrevious=Math.round(l*1e4)/1e4,u.hourFromPrevious=Math.round(l/o*1e4)/1e4,((g=i[0])==null?void 0:g.length)>1){const h={lng:i[0][1][0],lat:i[0][1][1]};u.bearing=this.calculateBearing(u,h)}else u.bearing=0;return{coordinate:u,nextRoute:i,prevRoute:r}}static nearestCoordinateInLine(e,t,n){const s=d.convertToStdLng(e.lng,6),o=T.point([s,e.lat]),r=d.convertToStdLng(t.lng,6),i=d.convertToStdLng(n.lng,6),c=T.lineString([[r,t.lat],[i,n.lat]]),a=T.nearestPointOnLine(c,o),l=T.getCoord(a),u=d.roundPrecision(l[0],6),g=d.roundPrecision(l[1],6);return{lng:u,lat:g,inline:!(u===r&&g===t.lat)&&!(u===i&&g===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let s,o;return e.forEach(r=>{r.forEach(i=>{const c={lng:d.roundPrecision(i[0],8),lat:d.roundPrecision(i[1],8)};if(!o)n.push(c),o=c;else if(o.bearing===void 0||o.bearing===null)o.bearing=this.calculateBearing(o,c,!0);else{const a=this.calculateDistance(s,c,!0);a&&a>=t&&(s.bearing=this.calculateBearing(s,c,!0),n.push(s),o=s)}s=c})}),s&&n.push(s),n}static simplifyRouteToCoordinates(e,t,n=1){let s=this.convertRouteToCoordinates(e,n);return s=this.simplifyGCCoordinates(s,t),s}static simplifyGCCoordinates(e,t){t.forEach(s=>{this.mergeCoordinateToWaypoints(s,e,!0)});for(let s=1;s<t.length;s++){const o=t[s-1],r=t[s];if(r.gcToPrevious){const i=e.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=e.findIndex(a=>a.lng===r.lng&&a.lat===r.lat);for(let a=c-1;a>i;a--)e.splice(a,1)}}let n=0;for(let s=1;s<e.length;s++){const o=e[s-1],r=e[s];r.gcToPrevious?(o.bearing=this.calculateBearing(o,r,!1),r.distanceFromPrevious=this.calculateDistance(o,r,!1)):(o.bearing=this.calculateBearing(o,r,!0),r.distanceFromPrevious=this.calculateDistance(o,r,!0)),n=d.roundPrecision(n+r.distanceFromPrevious),r.distanceFromStart=n}return e.map(s=>(s.lng=d.convertToStdLng(s.lng),s))}static calculateCenter(e){const t=[];for(const i of e)for(const c of i)t.push(c);const n=T.featureCollection([]),s=d.convertToMonotonicLng2(t);for(const i of s)n.features.push(T.point(i));const r=T.center(n).geometry.coordinates;return{lng:d.convertToStdLng(r[0],8),lat:d.roundPrecision(r[1],8)}}static calculateCenter2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateCenter(t)}static calculateBBox(e){const t=[];for(const o of e)for(const r of o)t.push(r);const n=d.convertToMonotonicLng2(t),s=T.lineString(n);return T.bbox(s)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}static simplifyCoordinates(e,t=1,n=180){const s=[];for(let o=1;o<e.length;o++){const r=e[o-1],i=e[o],c=e[o+1];let a=!1,l=!1;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){const u=b.calculateDistance(r,i,!0),g=b.calculateDistance(i,c,!0),h=b.calculateDistance(r,c,!0),p=(Math.pow(u,2)+Math.pow(g,2)-Math.pow(h,2))/(2*u*g);Math.round(Math.acos(p)*180/Math.PI)<n&&h>t&&!l&&(s.push(i),o++)}if(o>=e.length-1){const u=e.at(-1);u&&s.push(u)}}return s}static nearestTSPointInWaypoints(e,t,n){const s=x.unix(e),o=n.filter(r=>s.clone().subtract(t,"hour").unix()<=(r.positionTime||0)&&s.clone().add(t,"h").unix()>=(r.positionTime||0));return o.sort((r,i)=>(r.positionTime||0)-(i.positionTime||0)),o.at(-1)}static deadReckoning(e,t){var o,r,i,c;e>1e12&&(e=Math.round(e/1e3));const n=x.unix(e);let s=t.find(a=>a.positionTime===n.unix());if(!s){const a=(r=(o=t.filter(u=>(u==null?void 0:u.positionTime)<n.unix()))==null?void 0:o.sort((u,g)=>(u.positionTime||0)-(g.positionTime||0)))==null?void 0:r.at(-1),l=(c=(i=t.filter(u=>(u==null?void 0:u.positionTime)>n.unix()))==null?void 0:i.sort((u,g)=>(u.positionTime||0)-(g.positionTime||0)))==null?void 0:c.at(0);if(a&&l){const u=b.calculateBearing(a,l,!0),g=b.calculateDistance(a,l),h=(n.unix()-a.positionTime)/(l.positionTime-a.positionTime);s=b.calculateCoordinate(a,u,g*h),s.positionTime=n.unix(),s.utc=n.utc().format(),s.cog=u,s.sog=Math.round(g/((l.positionTime-a.positionTime)/3600)*100)/100}else s=a||l,s&&(s.utc=x.unix(s==null?void 0:s.positionTime).utc().format())}return s}static deadReckoningTime(e,t){t=JSON.parse(JSON.stringify(t)),t.sort((a,l)=>(a.positionTime||0)-(l.positionTime||0));let n=Number.MAX_SAFE_INTEGER,s=Number.MAX_SAFE_INTEGER;for(let a=0;a<t.length-1;a++){const l=t[a],u=t[a+1],g=b.calculatePointToLineDistance(e,l,u);g<n&&(n=g,s=a)}const o=t[s],r=t[s+1],i=b.calculateDistance(o,e),c=b.calculateDistance(r,e);if(i===0)e=o;else if(c===0)e=r;else{const a=o.positionTime||0,l=r.positionTime||0,u=b.calculateDistance(o,r);e.positionTime=Math.round(a+(l-a)*(i/u))}return e.utc=e.positionTime?x.unix(e.positionTime).utc().format():void 0,e.positionTime?e:void 0}static reverseRoute(e){const t=[];for(const n of e)t.push(n.reverse());return t}static reverseCoordinates(e){return e.reverse()}static xmlEscape(e){return e==null?"":String(e).trim().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}static waypoints2RTZ(e,t){const s=[];return s.push('<?xml version="1.0" encoding="UTF-8"?>'),s.push('<route xmlns="http://www.cirm.org/RTZ/1/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">'),s.push(` <routeInfo routeName="${b.xmlEscape(e)}"></routeInfo>`),s.push(...b.toRTZWaypoints(t,6)),s.push("</route>"),s.join(`
|
|
1
|
+
(function(k,Z){typeof exports=="object"&&typeof module<"u"?Z(exports,require("@turf/turf"),require("moment"),require("@log4js-node/log4js-api"),require("moment-timezone"),require("tz-lookup"),require("shpjs")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","@log4js-node/log4js-api","moment-timezone","tz-lookup","shpjs"],Z):(k=typeof globalThis<"u"?globalThis:k||self,Z(k["idm-plugin-rabbitmq"]={},k["@turf/turf"],k.moment,k["@log4js-node/log4js-api"],k["moment-timezone"],k["tz-lookup"],k.shpjs))})(this,function(k,Z,v,J,re,Y,Q){"use strict";function _(M){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(M){for(const t in M)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(M,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>M[t]})}}return e.default=M,Object.freeze(e)}const T=_(Z);class d{static guessTimeZoneOffset(e,t){e=d.convertToStdLng(e);const n=Y(t,e),s=v().tz(n).utcOffset();return d.roundPrecision(s/60,1)}static prettyTimeZoneOffset(e){let t=Math.floor(Math.abs(e)),n=Math.round((Math.abs(e)-t)*60);return n=n>9?n:`0${n}`,t=t>9?t:`0${t}`,e>0?`+${t}:${n}`:`-${t}:${n}`}static lng2pretty(e,t=6,n="H°M′"){e=d.convertToStdLng(e,t);let s="E";e<0&&(s="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,r,i,c,a,l,u;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,t).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,t).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);const g=`${n.replace(/S+/gi,i).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:d.roundPrecision(l,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(r,t),pretty:g,S:i,M:a,H:u}}static lat2pretty(e,t=6,n="H°M′"){e=e%180;let s="N";e<0&&(s="S"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,r,i,c,a,l,u;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,t).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,t).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);const g=`${n.replace(/S+/gi,i).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:d.roundPrecision(l,t),minute:d.roundPrecision(c,t),second:d.roundPrecision(r,t),pretty:g,S:i,M:a,H:u}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LNG");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[r,i,c]=o;if(i=i||0,i=i>60?i/Math.pow(10,String(i).length-2):i,c=c||0,c=c>60?c/Math.pow(10,String(c).length-2):c,r>360&&!i){const a=this.roundPrecision(r/100,0);i=r-a*100,r=a}n=r+i/60+c/3600,s==="W"&&(n=n*-1)}else n=Number(e);return d.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=d.strReplace(e,"LAT");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(a=>a!=="").map(a=>Math.abs(Number(a)));let[r,i,c]=o;if(c=c||0,i=i||0,i=i>60?i/Math.pow(10,String(i).length-2):i,c=c>60?c/Math.pow(10,String(c).length-2):c,r>90&&!i){const a=this.roundPrecision(r/100,0);i=r-a*100,r=a}if(n=r+i/60+c/3600,n>90)throw new Error(`latitude out of range: ${e}${s}`);s==="S"&&(n=n*-1)}else n=Number(e);return d.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=d.strReplace(e,n);const s=e[e.length-1].toUpperCase();return["N","S"].includes(s)?{lat:d.str2Lat(e,t)}:{lng:d.str2Lng(e,t)}}static convertToStdLng(e,t=6){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),d.roundPrecision(e,t)}static roundPrecision(e,t=6){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}static convertToMonotonicLng2(e){for(let t=1;t<e.length;t++)e[t][0]+=Math.round((e[t-1][0]-e[t][0])/360)*360;return e}static convertToMonotonicLng(e){for(let t=1;t<e.length;t++)e[t].lng+=Math.round((e[t-1].lng-e[t].lng)/360)*360;return e}static strReplace(e,t="LAT"){e=e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g,"$1 $2").replace(/([0-9]+)-([0-9]+\.[0-9]+)/g,"$1 $2").replace(/°/," ").replace(/(\d+)-(\d?)/g,"$1 $2").replace(/'/g," ").replace(/′/g," ").replace(/"/g," ").replace(/∼/g," ").replace(/°/g," ").replace(/,/g,".").replace(/^ /g,"").replace(/ $/g,"").trim();const n=e[e.length-1].toUpperCase();if(!["N","S","E","W"].includes(n)){const s=e,o=Number(s.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${e}`);o>=90?e=`${s}E`:o<=-90?e=`${s}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${s}${o>0?"E":"W"}`:e=`${s}${o>0?"N":"S"}`}return e}static padNumber(e,t=2,n=2){const s=d.roundPrecision(e-Math.trunc(e),n),o=s>=1?Math.trunc(e+1).toString().padStart(t,"0"):Math.trunc(e).toString().padStart(t,"0");return s>=1?o:n>0?`${o}.${Math.trunc(s*Math.pow(10,n)).toString().padStart(n,"0")}`:o}}class K{static json2Str(e){const t=e.type?e.type[0].toUpperCase():"A";return`${e.lat}|${e.lng}|${e.positionTime}|${e.sog}|${e.cog}|${e.hdg}|${e.draught}|${t}|${JSON.stringify(e.meteo||{})}|${e.vendor}|${e.deleted}`}static str2Json(e){const[t,n,s,o,r,i,c,a,l,u,g]=e.split("|");return{lat:Number(t),lng:Number(n),positionTime:Number(s),sog:Number(o),cog:Number(r),hdg:Number(i),draught:isNaN(c)?null:Number(c),type:a,important:a!=="A",meteo:l?JSON.parse(l):void 0,vendor:u,deleted:g==="true"}}static inspectStoppages(e,t=1,n=!0){const s=e.at(0).positionTime<e.at(-1).positionTime;s||e.sort((c,a)=>c.positionTime-a.positionTime);const o=[];let r,i;for(let c=0;c<e.length-1;c++){const a=e[c];if(!(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))){for(let l=c+1;l<e.length;l++){const u=e[l-1],g=e[l];if(n&&["N","B","E","NOON","BOSP","EOSP"].includes(a.type))continue;const h=g.positionTime-u.positionTime;if(b.calculateDistance(g,u,!0,4)/(h/3600)<t)r||(r=a),l===e.length-1&&(i=g,c=l);else{r&&(i=e[l-1],c=l);break}}if((i==null?void 0:i.positionTime)>(r==null?void 0:r.positionTime)&&r){const l={start:{lat:r.lat,lng:r.lng,sog:r.sog,positionTime:r.positionTime,utc:v.unix(r.positionTime).utc().format()},end:{lat:i.lat,lng:i.lng,sog:i.sog,positionTime:i.positionTime,utc:v.unix(i.positionTime).utc().format()},duration:i.positionTime-r.positionTime},u=e.filter(h=>h.positionTime>=l.start.positionTime&&h.positionTime<=l.end.positionTime),g=b.divideAccordingToLng(u);l.distance=b.calculateRouteDistance(g),l.hours=Math.round(l.duration/3600*10)/10,l.avgSog=Math.round(l.distance/l.hours*10)/10,o.push(l)}r=void 0,i=void 0}}return s||e.sort((c,a)=>a.positionTime-c.positionTime),o}static inspectSummary(e,t,n){const s=v(t),o=v(n),r=e.filter(l=>l.positionTime>=s.unix()&&l.positionTime<=o.unix());let i=0,c=0;if(r.length>1)for(let l=0;l<r.length-1;l++){const u=r[l],g=r[l+1];i+=b.calculateDistance(u,g,!0,4),c+=Math.abs(g.positionTime-u.positionTime)}i=Math.round(i*100)/100,c=Math.round(c/3600*100)/100;const a=c?Math.round(i/c*100)/100:0;return{distance:i,interval:c,avgSpd:a}}}let X;try{X=J.getLogger("meteo")}catch{}finally{}const H=(()=>{const M=new Uint32Array(256);for(let e=0;e<256;e++){let t=e;for(let n=0;n<8;n++)t=t&1?3988292384^t>>>1:t>>>1;M[e]=t}return M})();function ee(M){let e=4294967295;for(let t=0;t<M.length;t++)e=H[(e^M[t])&255]^e>>>8;return(e^4294967295)>>>0}function te(M){const e=new TextEncoder,t=[],n=[];let s=0;for(const h of M){const p=e.encode(h.name),f=ee(h.data),m=new Uint8Array(30+p.length),y=new DataView(m.buffer);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),m.set(p,30),t.push({nameBytes:p,data:h.data,crc:f,offset:s}),s+=m.length+h.data.length,n.push(m,h.data)}const o=s,r=[];let i=0;for(const h of t){const p=new Uint8Array(46+h.nameBytes.length),f=new DataView(p.buffer);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)}const c=new Uint8Array(22),a=new DataView(c.buffer);a.setUint32(0,101010256,!0),a.setUint16(8,t.length,!0),a.setUint16(10,t.length,!0),a.setUint32(12,i,!0),a.setUint32(16,o,!0);const l=n.reduce((h,p)=>h+p.length,0)+i+22,u=new Uint8Array(l);let g=0;for(const h of n)u.set(h,g),g+=h.length;for(const h of r)u.set(h,g),g+=h.length;return u.set(c,g),u}function V(M){let e="",t=M;for(;t>=0;)e=String.fromCharCode(65+t%26)+e,t=Math.floor(t/26)-1;return e}class b{static calculateBearing(e,t,n=!0,s=4){const o=T.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=T.rhumbBearing(o.features[0],o.features[1]):r=T.bearing(o.features[0],o.features[1]),r<0&&(r+=360),d.roundPrecision(r,s)}static calculateDistance(e,t,n=!0,s=4,o="nauticalmiles"){e={...e},t={...t},e.lng=d.convertToStdLng(e.lng,s),t.lng=d.convertToStdLng(t.lng,s);const r=T.points([[e.lng,e.lat],[t.lng,t.lat]]);let i;return n?i=T.rhumbDistance(r.features[0],r.features[1],{units:o}):i=T.distance(r.features[0],r.features[1],{units:o}),d.roundPrecision(i,s)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let s=0,o;for(const r of e)for(let i=0;i<r.length-1;i++){const c={lng:r[i][0],lat:r[i][1]};i===0&&o&&(s+=this.calculateDistance(o,c,!0,t,n));const a={lng:r[i+1][0],lat:r[i+1][1]};s+=this.calculateDistance(c,a,!0,t,n),o=a}return d.roundPrecision(s,t)}static calculateCoordinate(e,t,n,s="nauticalmiles",o=!0){const r=T.point([e.lng,e.lat]);let i;o?i=T.rhumbDestination(r,n,t,{units:s}):i=T.destination(r,n,t,{units:s});const c=i.geometry.coordinates;return{lng:d.convertToStdLng(c[0],8),lat:d.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,s=!0,o=!0,r="nauticalmiles"){const i=[],c=this.calculateBearing(e,t,!1),a=this.calculateDistance(e,t,!1,8,r);s&&i.push({lng:e.lng,lat:e.lat});let l=0;for(;l<a;)l+=n,l<a&&i.push(this.calculateCoordinate(e,c,l,r,!1));return o&&i.push({lng:t.lng,lat:t.lat}),i}static divideAccordingToLng(e,t=!1,n=!0){if((e==null?void 0:e.length)<2)return[];e=n?this.deduplicateCoordinates(e):e;let s=[];const o=[];let r,i;for(let c=0;c<e.length-1;c++){r=d.convertToStdLng(e[c].lng,8),i=d.convertToStdLng(e[c+1].lng,8),e[c].lat=d.roundPrecision(e[c].lat,8),e[c+1].lat=d.roundPrecision(e[c+1].lat,8),s.push([r,e[c].lat]);const a=r-i;if(Math.abs(a)>180){const l=d.convertToMonotonicLng2([[r,e[c].lat],[i,e[c+1].lat]]);let u,g;t?(u=T.lineString(l),g=T.lineString([[a>0?180:-180,89],[a>0?180:-180,-89]])):(u=T.greatCircle(l[0],l[1]),g=T.greatCircle([a>0?180:-180,89],[a>0?180:-180,-89]));const h=T.lineIntersect(u,g);let p;if(h.features.length){const f=T.getCoord(h.features[0]);p=d.roundPrecision(f[1],8)}else p=e[c].lat;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]))}c===e.length-2&&s.push([i,e[c+1].lat])}return o.push(s),o}static deduplicateRoute(e){const t=[];for(const n of e){const s=n.reduce((o,r)=>(o.findIndex(i=>i[0]===r[0]&&i[1]===r[1])===-1&&o.push(r),o),[]);t.push(s)}return t}static deduplicateCoordinates(e){return e.reduce((t,n)=>(t.findIndex(s=>s.lat===n.lat&&s.lng===n.lng)===-1&&t.push(n),t),[])}static removeCoordinateFromRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);for(const n of t)for(let s=n.length-1;s>=0;s--)d.roundPrecision(n[s][0],8)===e.lng&&d.roundPrecision(n[s][1],8)===d.roundPrecision(e.lat,8)&&n.splice(s,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=d.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)d.roundPrecision(t[n].lng,8)===e.lng&&d.roundPrecision(t[n].lat,8)===d.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,s=0,o=0,r,i;return t.forEach((c,a)=>{for(let l=0;l<c.length-1;l++){const u={lng:c[l][0],lat:c[l][1]},g={lng:c[l+1][0],lat:c[l+1][1]},h=this.calculatePointToLineDistance(e,u,g);n>h&&(n=h,o=l,s=a,r=this.calculateDistance(u,e),i=this.calculateDistance(g,e))}}),r!==0&&i!==0?t[s].splice(o+1,0,[e.lng,e.lat]):r===0?t[s].splice(o,1,[e.lng,e.lat]):i===0&&t[s].splice(o+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=d.convertToStdLng(e.lng,8);const n=b.convertRouteToCoordinates(t);return n.push(e),b.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=b.convertRouteToCoordinates(t);return n.unshift(e),b.divideAccordingToLng(n)}static mergeWaypointsToRoute(e,t){for(const n of e)t=this.mergeCoordinateToRoute(n,t);return t}static calculateRangeRoute(e,t,n){n=this.mergeWaypointsToRoute([e,t],n);const s=[];let o=0;return n.forEach(r=>{if(o===2)return;const i=[];for(const c of r){if(d.roundPrecision(t.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(c[1],8)){i.push(c),o===0&&i.push([e.lng,e.lat]),o=2;break}o===1?i.push(c):d.roundPrecision(e.lng,8)===d.roundPrecision(c[0],8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(c[1],8)&&(o=1,i.push(c))}i.length&&s.push(i)}),s}static calculateRangeWaypoints(e,t,n,s=[]){const o=this.convertRouteToCoordinates(n,0),r=this.mergeCoordinatesToWaypoints([e,t],o.length?o:s),i=r.findIndex(l=>d.roundPrecision(e.lng,8)===d.roundPrecision(l.lng,8)&&d.roundPrecision(e.lat,8)===d.roundPrecision(l.lat,8)),c=r.findIndex(l=>d.roundPrecision(t.lng,8)===d.roundPrecision(l.lng,8)&&d.roundPrecision(t.lat,8)===d.roundPrecision(l.lat,8));return r.filter((l,u)=>u>=i&&u<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,s=0,o=0;return t.forEach((r,i)=>{for(let c=0;c<r.length-1;c++){const a={lng:r[c][0],lat:r[c][1]},l={lng:r[c+1][0],lat:r[c+1][1]},u=this.calculatePointToLineDistance(e,a,l);n>u&&(n=u,s=c,o=i)}}),{minDist:n,segIndex:o,minIndex:s}}static calculateSubRoute(e,t){const n=b.convertRouteToCoordinates(t);b.mergeCoordinateToWaypoints(e,n,!0),t=b.divideAccordingToLng(n);const{segIndex:s,minIndex:o}=this.calculateMinDistanceToRoute({...e},t);e.lng=d.convertToStdLng(e.lng);const r=[];let i=!0;for(let c=s;c<t.length;c++)if(i){const a=[];a.push([e.lng,e.lat]);for(let l=o+1;l<t[c].length;l++)e.lng===t[c][l][0]&&e.lat===t[c][l][1]||a.push(t[c][l]);r.push(a),i=!1}else r.push([...t[c]]);return r}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,s=0;for(let r=0;r<t.length-1;r++){const i=t[r],c=t[r+1];if(this.calculateDistance(e,i)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((l,u)=>u>0);const a=this.calculatePointToLineDistance(e,i,c);n>a&&(n=a,s=r)}e.lng=d.convertToStdLng(e.lng);const o=[e];for(let r=s+1;r<t.length;r++)o.push(t[r]);return o}static calculatePointToLineDistance(e,t,n,s={units:"nauticalmiles",method:"geodesic"}){e.lng=d.convertToStdLng(e.lng,8),t={...t},n={...n},t.lng=d.convertToStdLng(t.lng,8),n.lng=d.convertToStdLng(n.lng,8);const o=d.convertToMonotonicLng([t,n]);t=o[0],n=o[1];const r=T.lineString([[t.lng,t.lat],[n.lng,n.lat]]),i=T.pointToLineDistance(T.point([e.lng,e.lat]),r,s),c=T.pointToLineDistance(T.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),r,s);return d.roundPrecision(Math.min(i,c),6)}static calculateWaypointsPropInRoute(e,t){t=this.mergeWaypointsToRoute(e,t);for(let n=0;n<e.length-1;n++){const s=e[n],o=e[n+1],r=this.calculateRangeRoute(s,o,t);n===0&&(s.distanceFromPrevious=0,s.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(r),o.distanceFromStart=d.roundPrecision((s.distanceFromStart||0)+o.distanceFromPrevious)}return e}static mergeCoordinatesToWaypoints(e,t,n=!0){for(const s of e)this.mergeCoordinateToWaypoints(s,t,n);return t}static mergeCoordinateToWaypoints(e,t,n=!0){e.lng=d.convertToStdLng(e.lng,8);let s=Number.MAX_VALUE,o=0,r=0,i=0;if(t.length<2)t.push(e);else{for(let c=0;c<t.length-1;c++){const a={lng:t[c].lng,lat:t[c].lat},l={lng:t[c+1].lng,lat:t[c+1].lat},u=this.calculatePointToLineDistance(e,a,l);s>=u&&(s=u,o=c,r=this.calculateDistance(a,e,!1,6),i=this.calculateDistance(l,e,!1,6))}r!==0&&i!==0?r<=s&&o===0?t.unshift(e):i<=s&&o===t.length-2?t.push(e):t.splice(o+1,0,e):r===0?n?t.splice(o,1,e):t.splice(o+1,0,e):i===0&&(n?t.splice(o+1,1,e):t.splice(o+1,0,e))}return t.map((c,a)=>{c.lng=d.convertToStdLng(c.lng);const l=t[a+1];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)){const u=this.calculateDistance(c,l,!0),g=Math.abs(l.positionTime-c.positionTime)/3600;c.sog=d.roundPrecision(u/g,2)}return c})}static generateRouteAccordingToWaypoints(e,t=!0,n=!0){const s=[];for(let o=1;o<e.length;o++){const r=e[o-1],i=e[o];if(o===1&&s.push(r),i.gcToPrevious){const c=this.interpolateCoordinates(r,i,200,!1,!0,"nauticalmiles");s.push(...c)}else s.push(i)}return this.divideAccordingToLng(s,t,n)}static nearestCoordinateInRoute(e,t){const n=T.point([e.lng,e.lat]),o=this.convertRouteToCoordinates(t).map(a=>[a.lng,a.lat]),r=T.lineString(o),i=T.nearestPointOnLine(r,n),c=T.getCoord(i);return{lng:d.roundPrecision(c[0],8),lat:d.roundPrecision(c[1],8)}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let s=0;s<t.length-1;s++){const o=t[s],r=t[s+1];if(this.calculateDistance(e,o)===0){n=s;break}if(this.calculateDistance(e,r)===0){n=s+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,s="nauticalmiles"){var g;const o=e.speed||12,r=[];let i=[],c=!1,a=0,l=0,u;if(t&&n.length?(r.push(e),n.forEach((h,p)=>{if(c)i.push(h);else{const f=[];let m;for(let y=0;y<h.length;y++)if(u)f.push(h[y]);else{m={lng:h[y][0],lat:h[y][1]};const x=this.calculateDistance(e,m,!0,8,s);if(a+=x,a<t)l+=x,x&&r.push(m),e=m;else{if(l=t,a===t)u=m,f.push([u.lng,u.lat]);else{const P=a-t,S=this.calculateBearing(m,e);u=this.calculateCoordinate(m,S,P,s),f.push([u.lng,u.lat]),f.push([m.lng,m.lat])}c=!0}}f.length&&i.push(f),p===n.length-1&&!u&&(u=m)}})):(i=n,u={...e}),u)if(r.push(u),u.distanceFromPrevious=Math.round(l*1e4)/1e4,u.hourFromPrevious=Math.round(l/o*1e4)/1e4,((g=i[0])==null?void 0:g.length)>1){const h={lng:i[0][1][0],lat:i[0][1][1]};u.bearing=this.calculateBearing(u,h)}else u.bearing=0;return{coordinate:u,nextRoute:i,prevRoute:r}}static nearestCoordinateInLine(e,t,n){const s=d.convertToStdLng(e.lng,6),o=T.point([s,e.lat]),r=d.convertToStdLng(t.lng,6),i=d.convertToStdLng(n.lng,6),c=T.lineString([[r,t.lat],[i,n.lat]]),a=T.nearestPointOnLine(c,o),l=T.getCoord(a),u=d.roundPrecision(l[0],6),g=d.roundPrecision(l[1],6);return{lng:u,lat:g,inline:!(u===r&&g===t.lat)&&!(u===i&&g===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let s,o;return e.forEach(r=>{r.forEach(i=>{const c={lng:d.roundPrecision(i[0],8),lat:d.roundPrecision(i[1],8)};if(!o)n.push(c),o=c;else if(o.bearing===void 0||o.bearing===null)o.bearing=this.calculateBearing(o,c,!0);else{const a=this.calculateDistance(s,c,!0);a&&a>=t&&(s.bearing=this.calculateBearing(s,c,!0),n.push(s),o=s)}s=c})}),s&&n.push(s),n}static simplifyRouteToCoordinates(e,t,n=1){let s=this.convertRouteToCoordinates(e,n);return s=this.simplifyGCCoordinates(s,t),s}static simplifyGCCoordinates(e,t){t.forEach(s=>{this.mergeCoordinateToWaypoints(s,e,!0)});for(let s=1;s<t.length;s++){const o=t[s-1],r=t[s];if(r.gcToPrevious){const i=e.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=e.findIndex(a=>a.lng===r.lng&&a.lat===r.lat);for(let a=c-1;a>i;a--)e.splice(a,1)}}let n=0;for(let s=1;s<e.length;s++){const o=e[s-1],r=e[s];r.gcToPrevious?(o.bearing=this.calculateBearing(o,r,!1),r.distanceFromPrevious=this.calculateDistance(o,r,!1)):(o.bearing=this.calculateBearing(o,r,!0),r.distanceFromPrevious=this.calculateDistance(o,r,!0)),n=d.roundPrecision(n+r.distanceFromPrevious),r.distanceFromStart=n}return e.map(s=>(s.lng=d.convertToStdLng(s.lng),s))}static calculateCenter(e){const t=[];for(const i of e)for(const c of i)t.push(c);const n=T.featureCollection([]),s=d.convertToMonotonicLng2(t);for(const i of s)n.features.push(T.point(i));const r=T.center(n).geometry.coordinates;return{lng:d.convertToStdLng(r[0],8),lat:d.roundPrecision(r[1],8)}}static calculateCenter2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateCenter(t)}static calculateBBox(e){const t=[];for(const o of e)for(const r of o)t.push(r);const n=d.convertToMonotonicLng2(t),s=T.lineString(n);return T.bbox(s)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}static simplifyCoordinates(e,t=1,n=180){const s=[];for(let o=1;o<e.length;o++){const r=e[o-1],i=e[o],c=e[o+1];let a=!1,l=!1;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){const u=b.calculateDistance(r,i,!0),g=b.calculateDistance(i,c,!0),h=b.calculateDistance(r,c,!0),p=(Math.pow(u,2)+Math.pow(g,2)-Math.pow(h,2))/(2*u*g);Math.round(Math.acos(p)*180/Math.PI)<n&&h>t&&!l&&(s.push(i),o++)}if(o>=e.length-1){const u=e.at(-1);u&&s.push(u)}}return s}static nearestTSPointInWaypoints(e,t,n){const s=v.unix(e),o=n.filter(r=>s.clone().subtract(t,"hour").unix()<=(r.positionTime||0)&&s.clone().add(t,"h").unix()>=(r.positionTime||0));return o.sort((r,i)=>(r.positionTime||0)-(i.positionTime||0)),o.at(-1)}static deadReckoning(e,t){var o,r,i,c;e>1e12&&(e=Math.round(e/1e3));const n=v.unix(e);let s=t.find(a=>a.positionTime===n.unix());if(!s){const a=(r=(o=t.filter(u=>(u==null?void 0:u.positionTime)<n.unix()))==null?void 0:o.sort((u,g)=>(u.positionTime||0)-(g.positionTime||0)))==null?void 0:r.at(-1),l=(c=(i=t.filter(u=>(u==null?void 0:u.positionTime)>n.unix()))==null?void 0:i.sort((u,g)=>(u.positionTime||0)-(g.positionTime||0)))==null?void 0:c.at(0);if(a&&l){const u=b.calculateBearing(a,l,!0),g=b.calculateDistance(a,l),h=(n.unix()-a.positionTime)/(l.positionTime-a.positionTime);s=b.calculateCoordinate(a,u,g*h),s.positionTime=n.unix(),s.utc=n.utc().format(),s.cog=u,s.sog=Math.round(g/((l.positionTime-a.positionTime)/3600)*100)/100}else s=a||l,s&&(s.utc=v.unix(s==null?void 0:s.positionTime).utc().format())}return s}static deadReckoningTime(e,t){t=JSON.parse(JSON.stringify(t)),t.sort((a,l)=>(a.positionTime||0)-(l.positionTime||0));let n=Number.MAX_SAFE_INTEGER,s=Number.MAX_SAFE_INTEGER;for(let a=0;a<t.length-1;a++){const l=t[a],u=t[a+1],g=b.calculatePointToLineDistance(e,l,u);g<n&&(n=g,s=a)}const o=t[s],r=t[s+1],i=b.calculateDistance(o,e),c=b.calculateDistance(r,e);if(i===0)e=o;else if(c===0)e=r;else{const a=o.positionTime||0,l=r.positionTime||0,u=b.calculateDistance(o,r);e.positionTime=Math.round(a+(l-a)*(i/u))}return e.utc=e.positionTime?v.unix(e.positionTime).utc().format():void 0,e.positionTime?e:void 0}static reverseRoute(e){const t=[];for(const n of e)t.push(n.reverse());return t}static reverseCoordinates(e){return e.reverse()}static xmlEscape(e){return e==null?"":String(e).trim().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}static waypoints2RTZ(e,t){const s=[];return s.push('<?xml version="1.0" encoding="UTF-8"?>'),s.push('<route xmlns="http://www.cirm.org/RTZ/1/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">'),s.push(` <routeInfo routeName="${b.xmlEscape(e)}"></routeInfo>`),s.push(...b.toRTZWaypoints(t,6)),s.push("</route>"),s.join(`
|
|
2
2
|
`)}static waypoints2RTZ10(e,t,n=!0){const o=[];return o.push('<?xml version="1.0" encoding="UTF-8"?>'),o.push('<route xmlns="http://www.cirm.org/RTZ/1/0" version="1.0">'),o.push(` <routeInfo routeName="${b.xmlEscape(e)}"></routeInfo>`),o.push(...b.toRTZWaypoints(t,6,n)),o.push("</route>"),o.join(`
|
|
3
|
-
`)}static toRTZWaypoints(e,t=6,n=!0){const s=[];s.push(" <waypoints>");for(let o=0;o<e.length;o++){const r=e[o],i=o+1,c=(r.lat??"").toFixed?r.lat.toFixed(t).padEnd(t+2,"0"):r.lat,a=(r.lng??"").toFixed?r.lng.toFixed(t).padEnd(t+2,"0"):r.lng,l=[`id="${i}"`,'revision="0"'];if(r.name&&l.push(`name="${b.xmlEscape(r.name)}"`),s.push(` <waypoint ${l.join(" ")}>`),s.push(` <position lat="${b.xmlEscape(c)}" lon="${b.xmlEscape(a)}" />`),o>0){const u=r.gcToPrevious?"Orthodrome":"Loxodrome";s.push(` <leg geometryType="${u}" />`)}if(n){const u=[];if(r.description&&u.push(` <description>${b.xmlEscape(r.description)}</description>`),r.utc)u.push(` <time>${b.xmlEscape(r.utc)}</time>`);else if(r.positionTime)try{u.push(` <time>${b.xmlEscape(
|
|
4
|
-
`)}static waypoints2JRCCSV(e,t,n){const s=(n==null?void 0:n.precision)??3,o=t.some(f=>f.name),r=t.some(f=>f.port!=null),i=t.some(f=>f.stbd!=null),c=t.some(f=>f.arrRad!=null),a=t.some(f=>f.speed!=null),l=t.some((f,m)=>m>0&&f.gcToPrevious!=null),u=t.some(f=>f.rot!=null),g=t.some(f=>f.turnRad!=null),h=["// WPT No.","LAT","","","LON","",""];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]"),g&&h.push("Turn Rad[NM]"),o&&h.push("Name");const p=[];p.push("// ROUTE SHEET exported by JRC ECDIS."),p.push("// <<NOTE>>This strings // indicate comment column/cells. You can edit freely."),p.push(`// ${b.xmlEscape(e)}`),p.push(h.join(","));for(let f=0;f<t.length;f++){const m=
|
|
5
|
-
`)}static waypoints2XLSX(e,t,n){const s=(n==null?void 0:n.precision)??6,o=e||"Route",r=t.some(
|
|
3
|
+
`)}static toRTZWaypoints(e,t=6,n=!0){const s=[];s.push(" <waypoints>");for(let o=0;o<e.length;o++){const r=e[o],i=o+1,c=(r.lat??"").toFixed?r.lat.toFixed(t).padEnd(t+2,"0"):r.lat,a=(r.lng??"").toFixed?r.lng.toFixed(t).padEnd(t+2,"0"):r.lng,l=[`id="${i}"`,'revision="0"'];if(r.name&&l.push(`name="${b.xmlEscape(r.name)}"`),s.push(` <waypoint ${l.join(" ")}>`),s.push(` <position lat="${b.xmlEscape(c)}" lon="${b.xmlEscape(a)}" />`),o>0){const u=r.gcToPrevious?"Orthodrome":"Loxodrome";s.push(` <leg geometryType="${u}" />`)}if(n){const u=[];if(r.description&&u.push(` <description>${b.xmlEscape(r.description)}</description>`),r.utc)u.push(` <time>${b.xmlEscape(r.utc)}</time>`);else if(r.positionTime)try{u.push(` <time>${b.xmlEscape(v.unix(r.positionTime).utc().format())}</time>`)}catch{}r.cog!==void 0&&u.push(` <cog>${b.xmlEscape(r.cog)}</cog>`),r.sog!==void 0&&u.push(` <sog>${b.xmlEscape(r.sog)}</sog>`),u.length&&(s.push(" <extensions>"),s.push(...u),s.push(" </extensions>"))}s.push(" </waypoint>")}return s.push(" </waypoints>"),s}static waypoints2CSV(e,t,n){X.debug("keep name for waypoints2CSV for legacy compatibility only",e);const s=(n==null?void 0:n.precision)??6,o=t.some(m=>m.name),r=t.some(m=>m.description),i=t.some(m=>m.port!=null),c=t.some(m=>m.stbd!=null),a=t.some(m=>m.arrRad!=null),l=t.some(m=>m.speed!=null),u=t.some((m,y)=>y>0&&m.gcToPrevious!=null),g=t.some(m=>m.bearing!=null),h=t.some(m=>m.distanceFromPrevious!=null),p=["WPT No.","Latitude","Longitude"];o&&p.push("Name"),r&&p.push("Description"),u&&p.push("Leg"),g&&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]");const f=[];f.push(p.map(m=>b.csvEscapeField(m)).join(","));for(let m=0;m<t.length;m++){const y=t[m],x=[];x.push((m+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(m===0?"":y.gcToPrevious?"GC":"RL"),g&&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=>b.csvEscapeField(P)).join(","))}return f.join(`
|
|
4
|
+
`)}static waypoints2JRCCSV(e,t,n){const s=(n==null?void 0:n.precision)??3,o=t.some(f=>f.name),r=t.some(f=>f.port!=null),i=t.some(f=>f.stbd!=null),c=t.some(f=>f.arrRad!=null),a=t.some(f=>f.speed!=null),l=t.some((f,m)=>m>0&&f.gcToPrevious!=null),u=t.some(f=>f.rot!=null),g=t.some(f=>f.turnRad!=null),h=["// WPT No.","LAT","","","LON","",""];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]"),g&&h.push("Turn Rad[NM]"),o&&h.push("Name");const p=[];p.push("// ROUTE SHEET exported by JRC ECDIS."),p.push("// <<NOTE>>This strings // indicate comment column/cells. You can edit freely."),p.push(`// ${b.xmlEscape(e)}`),p.push(h.join(","));for(let f=0;f<t.length;f++){const m=t[f],y=String(f).padStart(3,"0"),x=d.lat2pretty(m.lat,6),P=d.lng2pretty(m.lng,6),S=x.degree,C=Number(x.minute).toFixed(s),w=x.direction,B=P.degree,U=Number(P.minute).toFixed(s),j=P.direction,O=[y,String(S),C,w,String(B),U,j];r&&O.push(f===0?"***":m.port!=null?String(m.port):"***"),i&&O.push(f===0?"***":m.stbd!=null?String(m.stbd):"***"),c&&O.push(f===0?"***":m.arrRad!=null?String(m.arrRad):"***"),a&&O.push(f===0?"***":m.speed!=null?Number(m.speed).toFixed(1).padStart(5,"0"):"***"),l&&O.push(f===0?"***":m.gcToPrevious?"GC":"RL"),u&&O.push(f===0?"***":m.rot!=null?String(m.rot):"***"),g&&O.push(f===0?"***":m.turnRad!=null?String(m.turnRad):"***"),o&&O.push(m.name??""),p.push(O.join(","))}return p.join(`
|
|
5
|
+
`)}static waypoints2XLSX(e,t,n){const s=(n==null?void 0:n.precision)??6,o=e||"Route",r=t.some(N=>N.name),i=t.some(N=>N.description),c=t.some(N=>N.port!=null),a=t.some(N=>N.stbd!=null),l=t.some(N=>N.arrRad!=null),u=t.some(N=>N.speed!=null),g=t.some((N,I)=>I>0&&N.gcToPrevious!=null),h=t.some(N=>N.bearing!=null),p=t.some(N=>N.distanceFromPrevious!=null),f=["WPT No.","Latitude","Longitude"];r&&f.push("Name"),i&&f.push("Description"),g&&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]");const m=N=>N==null?"":String(N).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");let x=`<row r="1">${f.map((N,I)=>`<c r="${V(I)}1" s="1" t="inlineStr"><is><t>${m(N)}</t></is></c>`).join("")}</row>`;for(let N=0;N<t.length;N++){const I=t[N],q=N+2,W=[],G=(L,z)=>W.push(`<c r="${V(L)}${q}"><v>${z}</v></c>`),E=(L,z)=>W.push(`<c r="${V(L)}${q}" t="inlineStr"><is><t>${m(z)}</t></is></c>`),A=(L,z)=>{z!=null?G(L,z):E(L,"")};G(0,N+1),E(1,d.lat2pretty(I.lat,s).pretty),E(2,d.lng2pretty(I.lng,s).pretty);let R=3;r&&(E(R,I.name??""),R++),i&&(E(R,I.description??""),R++),g&&(E(R,N===0?"":I.gcToPrevious?"GC":"RL"),R++),h&&(A(R,I.bearing),R++),p&&(A(R,I.distanceFromPrevious),R++),u&&(A(R,I.speed),R++),c&&(A(R,I.port),R++),a&&(A(R,I.stbd),R++),l&&(A(R,I.arrRad),R++),x+=`<row r="${q}">${W.join("")}</row>`}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>",C='<?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>',w='<?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>',B='<?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="'+m(o)+'" sheetId="1" r:id="rId1"/></sheets></workbook>',U='<?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>',O=new TextEncoder;return te([{name:"[Content_Types].xml",data:O.encode(C)},{name:"_rels/.rels",data:O.encode(w)},{name:"xl/workbook.xml",data:O.encode(B)},{name:"xl/_rels/workbook.xml.rels",data:O.encode(U)},{name:"xl/worksheets/sheet1.xml",data:O.encode(S)},{name:"xl/styles.xml",data:O.encode(j)}])}static csvEscapeField(e){if(e==null)return"";const t=String(e);return t.includes(",")||t.includes('"')||t.includes(`
|
|
6
6
|
`)||t.includes("\r")?`"${t.replace(/"/g,'""')}"`:t}static decimalToNmeaDm(e,t){const n=Math.abs(e),s=Math.floor(n),o=(n-s)*60,r=t?`${s.toString().padStart(2,"0")}${o.toFixed(2).padStart(5,"0")}`:`${s.toString().padStart(3,"0")}${o.toFixed(2).padStart(5,"0")}`,i=t?e>=0?"N":"S":e>=0?"E":"W";return{dm:r,dir:i}}static nmeaChecksum(e){let t=0;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n);return t.toString(16).toUpperCase().padStart(2,"0")}static waypoints2NMEA(e){const t=[];for(let n=0;n<e.length;n++){const s=e[n],o=b.decimalToNmeaDm(s.lat,!0),r=b.decimalToNmeaDm(s.lng,!1),i=s.name?String(s.name).slice(0,6):`WPT${(n+1).toString().padStart(3,"0")}`,c=`GPWPL,${o.dm},${o.dir},${r.dm},${r.dir},${i}`,a=b.nmeaChecksum(c);t.push(`$${c}*${a}`)}return t.join(`\r
|
|
7
|
-
`)}static coordinatesSummary(e,t=3){if(e.length>1){const n=e[0],s=e[e.length-1],o=(n==null?void 0:n.positionTime)<(s==null?void 0:s.positionTime)?x.unix(n==null?void 0:n.positionTime):x.unix(s==null?void 0:s.positionTime),r=(n==null?void 0:n.positionTime)>(s==null?void 0:s.positionTime)?x.unix(n==null?void 0:n.positionTime):x.unix(s==null?void 0:s.positionTime),i=Math.round(r.diff(o,"hours",!0)*100)/100,c=this.generateRouteAccordingToWaypoints(e,!0,!0),a=this.calculateRouteDistance(c),u=K.inspectStoppages(e,t).reduce((h,p)=>(h.duration+=p.duration,h.distance+=p.distance,h),{hours:0,distance:0,spd:0,duration:0});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;const g=i?Math.round((a-u.distance)/(i-u.hours)*100)/100:0;return{begin:o.utc().format(),end:r.utc().format(),distance:Math.round((a-u.distance)*100)/100,hours:Math.round((i-u.hours)*100)/100,avgSpeed:g,stoppage:u}}return{begin:void 0,end:void 0,distance:0,hours:0,avgSpeed:0}}static pickUTCSampleFromSpeed(e,t){var l,u,g;if(!((u=(l=t==null?void 0:t.sample)==null?void 0:l.hours)!=null&&u.length))return{routes:[],hour:void 0};const n=t.sample.hours.at(0),s=x.utc(e),o=x.utc(t.eta),r=s.isAfter(o)?o:s;let i=t.sample.all.find(h=>h.eta===r.format());if(!i){const h=t.sample.all.filter(C=>x.utc(C.eta).isBefore(r)).at(-1),p=this.calculateSubRoute(h,t.route);i=(g=this.calculateNextCoordinateAlongRoute(h,h.speed*r.diff(x(h.etd),"hours",!0),p))==null?void 0:g.coordinate;const{cFactor:f,cog:m,wxFactor:S,meteo:P}=h,N=Math.round(i.distanceFromPrevious*1e4)/1e4,y=Math.round((N+h.distanceFromStart)*1e4)/1e4;i={...i,cFactor:f,cog:m,speed:h.speed,wxFactor:S,distanceFromStart:y,distanceFromPrevious:N,meteo:P,eta:r.format(),etd:r.format()}}i.distanceToGo=Math.round((t.distance-i.distanceFromStart)*100)/100,i.timeToGo=Math.round(o.diff(i.etd,"hours",!0)*100)/100;const c=this.calculateRangeWaypoints(n,i,t.route);return{routes:this.generateRouteAccordingToWaypoints(c),hour:i}}static pickUTCSampleFromRoute(e,t,n){var h;const s=this.calculateSubRoute(t,n),o=this.calculateRouteDistance(s),r=o/t.speed,i=x.utc(e),c=x(t.etd),a=(h=this.calculateNextCoordinateAlongRoute(t,t.speed*i.diff(x(t.etd),"hours",!0),s))==null?void 0:h.coordinate;a.speed=t.speed;const l=c.clone().add(a.hourFromPrevious,"hour");a.eta=Math.abs(l.diff(i,"second"))<2?i.format():l.format(),a.etd=a.eta,a.distanceFromStart=Math.round(a.distanceFromPrevious*100)/100,a.distanceToGo=Math.round((o-a.distanceFromStart)*100)/100,a.timeToGo=Math.round(c.clone().add(r,"hour").diff(x(a.etd),"hour")*100)/100;const u=this.calculateRangeWaypoints(t,a,n);return{routes:this.generateRouteAccordingToWaypoints(u),hour:a}}static includedAngle(e,t){X==null||X.debug("calculate bearing via: %j",{bearing:e,degree:t});let n=Math.abs(e%360-(t%360||0));return n=n>180?360-n:n,n}}let $;try{$=J.getLogger("vessel")}catch{}finally{}class ne{static convert2Geojson(e){var n,s,o;const t=T.featureCollection([]);for(const r of e){const i=(n=r.history)==null?void 0:n[0];if(r.forecasts){i&&i.wind&&(i.wind.kts=i.kts);for(const c of r.forecasts){let a;const l=[],u=[],g=x(c.date).utc(),h=`${r.name}-${c.model}`;for(const f in c==null?void 0:c.hours){const m=c.hours[f];a=a||m;const S=g.clone().add(Number(f),"hour"),P=T.point([m.lng,m.lat],{model:c.model,name:r.name,nameCn:r.nameCn,date:S.format(),hour:Number(f),format:S.format("MMM-DD/HHmm[Z]"),pressure:m.pressure>1e4?d.roundPrecision(m.pressure/100,0):d.roundPrecision(m.pressure,0),gusts:m.gusts,wind:m.wind||{},movement:m.movement,category:h,type:"forecast"});u.push(P),l.push(P.geometry.coordinates)}const p={kts:void 0,deg:void 0};if(i){const f=x(i.updated).utc();if(a){const S=b.calculateDistance(i,a),P=x(a.utc||a.updated).diff(f,"h",!0);p.kts=Math.round(S/P*100)/100,p.deg=b.calculateBearing(i,a,!0,0)}const m=T.point([i.lng,i.lat],{model:c.model,name:r.name,nameCn:r.nameCn,date:f.format(),hour:0,format:f.format("MMM-DD/HHmm[Z]"),pressure:i.pressure>1e4?d.roundPrecision((i==null?void 0:i.pressure)/100,0):d.roundPrecision(i.pressure,0),wind:i.wind,movement:p,category:h,type:"forecast",important:!0});u.unshift(m),l.unshift(m.geometry.coordinates)}if(t.features.push(...u),(l==null?void 0:l.length)>1){const f=T.lineString(d.convertToMonotonicLng2(l),{date:(i==null?void 0:i.updated)||(g==null?void 0:g.format()),id:r.id||r.name,model:c.model,name:r.name,category:h,type:"forecast",movement:p});t.features.push(f)}}}if(t.features.sort((c,a)=>c.properties.type==="forecast"&&a.properties.type==="forecast"&&c.geometry.type==="Point"&&a.geometry.type==="Point"?x(c.properties.date).valueOf()-x(a.properties.date).valueOf():0),(s=r.history)!=null&&s.length){const c=[],a=x(i==null?void 0:i.updated).utc(),l=x((o=r.history)==null?void 0:o.at(-1).updated).utc(),u=a.diff(l,"h")%24>2?24:12;for(const g of r.history){const h=x(g.updated).utc(),p=h.isSameOrBefore(a)||h.isSame(l);p&&a.add(-u,"h");const f=T.point([g.lng,g.lat],{name:r.name,nameCn:r.nameCn,date:h.format(),format:h.format("MMM-DD/HHmm[Z]"),pressure:g.pressure>1e4?d.roundPrecision(g.pressure/100,0):d.roundPrecision(g.pressure,0),kts:g.kts,level:g.type,type:"history",category:`${r.name}-history`,wind:g.wind,movement:g.movement,important:p});t.features.push(f),c.push(f.geometry.coordinates)}if(c.length===1&&c.push(c[0]),c.length>1){const g=T.lineString(d.convertToMonotonicLng2(c),{name:r.name,type:"history",updated:i==null?void 0:i.updated,pressure:(i==null?void 0:i.pressure)>1e4?d.roundPrecision((i==null?void 0:i.pressure)/100,0):d.roundPrecision(i==null?void 0:i.pressure,0),kts:i==null?void 0:i.kts,level:i==null?void 0:i.type});t.features.push(g)}}}return t}static interpolate(e,t=3){var o,r,i,c;const n=(o=e==null?void 0:e.data)==null?void 0:o.features.filter(a=>a.geometry.type==="LineString"&&a.properties.type==="forecast"),s=[];for(const a of n){const l=a.properties.name,u=a.properties.model,g=a.properties.showCircle,h=a.properties.disabled,p=x(a.properties.date).utc();let f=t*60;const m=(r=e==null?void 0:e.data)==null?void 0:r.features.filter(N=>N.geometry.type==="Point"&&N.properties.type==="forecast"&&N.properties.category===`${l}-${u}`);let S,P=p.clone().add(f,"minute").set({minute:0,second:0,millisecond:0});for(;S=this.pickIndex(m,P),S<=m.length-1;){if(S>0){const N=m[S],y=S===0?void 0:m[S-1],C=(f/60-((i=y==null?void 0:y.properties)==null?void 0:i.hour))/(N.properties.hour-((c=y==null?void 0:y.properties)==null?void 0:c.hour)),k=this.computeNumber(y==null?void 0:y.geometry.coordinates[0],N.geometry.coordinates[0],C),B=this.computeNumber(y==null?void 0:y.geometry.coordinates[1],N.geometry.coordinates[1],C),U=T.point([k,B],{name:l,model:u,category:N==null?void 0:N.properties.category,date:P.format(),format:P.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(y==null?void 0:y.properties.gusts,N.properties.gusts,C),hour:this.computeNumber(y==null?void 0:y.properties.hour,N.properties.hour,C),movement:this.computeNumber(y==null?void 0:y.properties.movement,N.properties.movement,C),pressure:this.computeNumber(y==null?void 0:y.properties.pressure,N.properties.pressure,C),wind:this.computeNumber(y==null?void 0:y.properties.wind,N.properties.wind,C),type:"forecast",disabled:h,showCircle:g});s.push(U)}f+=t*60,P=p.clone().add(f,"minute").set({minute:0,second:0,millisecond:0})}}return s}static accelPassageAt(e,t){const{t1:n,t2:s,hr:o,hours:r}=this.tropicalCenterTwin(e,24,t);return{t1:n,t2:s,hr:o,hours:r}}static diversionPassageAt(e,t,n,s={}){const{t1:o,t2:r,hr:i,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&r){if(!s.debug){const p=b.calculateDistance(e,o),f=b.calculateDistance(e,r);if(p>2*n&&f>2*n)return $==null||$.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j",s.requestId,p,f,{from:e,t1:o,t2:r,hr:i}),{}}const a=b.calculateBearing(e,o),l=b.calculateBearing(o,r),u=Math.abs(a-l);let g=0;u<180?g=u+90:u>=180&&(g=u-90);const h=b.calculateCoordinate(o,g,n);return $==null||$.info("[%s] the right tangent position: %j",s.requestId,{from:e,t1:o,t2:r,radius:n,bearing1:a,bearing2:l,right:h}),{at:h,t1:o,t2:r,hr:Number(i),hours:c}}return{}}static driftPassageAt(e,t,n,s={}){const{t1:o,t2:r,hr:i,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&r){if(!s.debug){const h=b.calculateDistance(e,o),p=b.calculateDistance(e,r);if(h>2*n&&p>2*n)return $==null||$.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j",s.requestId,h,p,{from:e,t1:o,t2:r,hr:i}),{}}const a=b.calculateBearing(e,o),l=b.calculateBearing(o,r),u=b.calculateDistance(e,o);return{at:b.calculateCoordinate(o,a-l+180,n<u?n:u),t1:o,t2:r,hr:Number(i),hours:c}}else return $==null||$.info("[%s] no need drift: %j",s.requestId,{from:e,t1:o,t2:r,hr:i}),{}}static tropicalCenterTwin(e,t=24,n={}){var l,u,g,h,p;let s={};(l=e.forecasts)==null||l.forEach(f=>{s={...f.hours,...s}});const o=((u=e==null?void 0:e.history)==null?void 0:u[0])||(s==null?void 0:s[(g=Object.keys(s))==null?void 0:g[0]]);$==null||$.info("[%s] the first tropical center: %j",n.requestId,o);let r=(h=Object.keys(s||{}).filter(f=>Number(f)<=(t<0?24:t)))==null?void 0:h.at(-1);r||(r=(p=Object.keys(s||{}).filter(f=>Number(f)<=(t<0?24:2*t)))==null?void 0:p.at(-1));const i=s==null?void 0:s[r||-1];$==null||$.info("[%s] the second tropical center: %j in %d hrs",n.requestId,i,r);const c=Object.keys(s||{}).filter(f=>Number(f)<=Number(r)),a={0:o};for(const f of c)a[f]=s[f];return{t1:o,t2:i,hr:Number(r),hours:a}}static pickIndex(e,t){let n=0;for(const s of e){if(x(s.properties.date).isAfter(t))return n===0?-1:n;n++}return n}static computeNumber(e,t,n){if(e)if(t){if(isNaN(e)&&isNaN(t)&&typeof e!="string"&&typeof t!="string"){const s={};for(const o in e)s[o]=this.computeNumber(e[o],t[o],n);return s}return Math.round((e+(t-e)*n)*100)/100}else return e;else return t}}typeof globalThis<"u"&&typeof globalThis.Buffer>"u"&&(globalThis.Buffer={isBuffer(M){return M instanceof Uint8Array},from(M,e){if(typeof M=="string")return new TextEncoder().encode(M);if(M instanceof ArrayBuffer)return new Uint8Array(M);if(Array.isArray(M))return new Uint8Array(M);throw new TypeError("Buffer.from: unsupported source type")}});let D;try{D=J.getLogger("meteo")}catch{}finally{}function se(){if(typeof DOMParser<"u")return new DOMParser;const{JSDOM:M}=require("jsdom"),{DOMParser:e}=new M("").window;return new e}class F{static toArrayBuffer(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}static drawCircle(e,t,n,s={}){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([e,t]),a=T.destination(c,n,90,{units:r}),l=x.utc();i.id=(s==null?void 0:s.id)||l.valueOf().toString();const u="circle";return i.name=(s==null?void 0:s.name)||`${u}_${l.format()}`,i.radius=n,i.center=[e,t],i.end=a.geometry.coordinates.map(g=>d.roundPrecision(g,9)),i.units=r,i.steps=o,i.shape="circle",D.info("[%s] draw circle with %j",s==null?void 0:s.requestId,i),T.circle(c,n,{steps:o,units:r,properties:i})}static drawRect(e,t,n={}){const s=(n==null?void 0:n.properties)??{},o=x.utc();s.id=(n==null?void 0:n.id)||o.valueOf().toString();const r="rect";s.name=(n==null?void 0:n.name)||`${r}_${o.format()}`,s.start=e.map(l=>d.roundPrecision(l,9)),s.end=t.map(l=>d.roundPrecision(l,9)),s.shape="rect",D.info("[%s] draw rect with %j",n==null?void 0:n.requestId,s);const[i,c]=d.convertToMonotonicLng2([e,t]),a=[Math.min(i[0],c[0]),Math.min(i[1],c[1]),Math.max(i[0],c[0]),Math.max(i[1],c[1])];return T.bboxPolygon(a,{properties:s})}static drawLine(e,t={}){const n=(t==null?void 0:t.properties)??{},s=x.utc();n.id=(t==null?void 0:t.id)||s.valueOf().toString();const o="line";n.name=(t==null?void 0:t.name)||`${o}_${s.format()}`,n.shape="line",D.info("[%s] draw line with %j",t==null?void 0:t.requestId,n);const r=d.convertToMonotonicLng2(e);return T.lineString(r,n)}static drawPolygon(e,t={}){const n=(t==null?void 0:t.properties)??{},s=x.utc();n.id=(t==null?void 0:t.id)||s.valueOf().toString();const o="polygon";n.name=(t==null?void 0:t.name)||`${o}_${s.format()}`,n.coordinates=e.map(i=>i.map(c=>d.roundPrecision(c,9))),n.shape="polygon",D.info("[%s] draw polygon with %j",t==null?void 0:t.requestId,n);const r=d.convertToMonotonicLng2(e);return T.polygon([r],n)}static drawPoint(e,t,n={}){const s=(n==null?void 0:n.properties)??{},o=x.utc();s.id=(n==null?void 0:n.id)||o.valueOf().toString();const r="point";return s.name=(n==null?void 0:n.name)||`${r}_${o.format()}`,s.shape="point",D.info("[%s] draw point with %j",n==null?void 0:n.requestId,s),T.point([t,e],s)}static parseCircle(e,t={}){var s,o;D.info("[%s] parse circle with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="circle"){const r=x.utc();n.id=(n==null?void 0:n.id)||r.valueOf().toString();const i=n==null?void 0:n.id,c=((s=n==null?void 0:n.center)==null?void 0:s.length)==2?T.point(n.center):T.centroid(e);let a="center";c.properties={id:`${a}_${i}`,parentId:i,name:a};const l=(n==null?void 0:n.units)||"nauticalmiles";let u=n==null?void 0:n.radius;if(!u){const p=T.polygonToLine(e);u=T.pointToLineDistance(c,p,{units:l})}a="end";const g=((o=n==null?void 0:n.end)==null?void 0:o.length)==2?T.point(n.end):T.destination(c,u,90,{units:l});g.properties={id:`${a}_${i}`,parentId:i,name:a,radius:u,units:l};const h=T.lineString([c.geometry.coordinates,g.geometry.coordinates]);return a="edge",h.properties={id:`${a}_${i}`,parentId:i,name:a,radius:u,units:l},T.featureCollection([c,g,h,e])}else return D.warn("[%s] not a orm-std circle, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parseRect(e,t={}){D.info("[%s] parse rect with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="rect"){const s=x.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,r=e.geometry.coordinates[0],c=["sw","nw","ne","se"].map((a,l)=>{const u=T.point(r[l]);return u.properties={id:`${a}_${o}`,parentId:o,name:a},u});return T.featureCollection([...c,e])}else return D.warn("[%s] not a orm-std rect, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parseLine(e,t={}){D.info("[%s] parse line with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="line"){const s=x.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,i=e.geometry.coordinates.map((c,a)=>{const l=`point_${a}`,u=T.point(c);return u.properties={id:`${l}_${o}`,parentId:o,name:l,index:a},u});return T.featureCollection([...i,e])}else return D.warn("[%s] not a orm-std line, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parsePolygon(e,t={}){D.info("[%s] parse polygon with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="polygon"){const s=x.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,i=e.geometry.coordinates[0].map((c,a)=>{const l=T.point(c),u=`corner_${a}`;return l.properties={id:`${u}_${o}`,parentId:o,name:u,index:a},l});return T.featureCollection([...i,e])}else return D.warn("[%s] not a orm-std polygon, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static _inflateRawSync(e){var t;if(typeof process<"u"&&((t=process.versions)!=null&&t.node)){const n=require("zlib");return new Uint8Array(n.inflateRawSync(Buffer.from(e)))}throw new Error("Sync inflate is not supported in browser; use the async convertKMZ2GeoJSONAsync / convertZIP2GeoJSONAsync instead")}static async _parseZipEntries(e){var g;const t=new Uint8Array(e),n=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength),s=new DataView(n),o=new Uint8Array(n),r=new Map;let i=-1;for(let h=n.byteLength-22;h>=0;h--)if(s.getUint32(h,!0)===101010256){i=h;break}if(i<0)throw new Error("Invalid ZIP file: EOCD not found");s.getUint16(i+8,!0);const c=s.getUint32(i+12,!0),a=s.getUint32(i+16,!0);let l=a;const u=a+c;for(;l<u;){if(s.getUint32(l,!0)!==33639248)throw new Error(`Invalid ZIP file: Central Directory signature mismatch at offset ${l}`);const p=s.getUint16(l+10,!0),f=s.getUint32(l+20,!0),m=s.getUint16(l+28,!0),S=s.getUint16(l+30,!0),P=s.getUint16(l+32,!0),N=s.getUint32(l+42,!0),y=o.slice(l+46,l+46+m),C=new TextDecoder().decode(y),k=s.getUint16(N+26,!0),B=s.getUint16(N+28,!0),U=N+30+k+B,j=o.slice(U,U+f);if(p===0)r.set(C,j);else if(p===8){if(typeof DecompressionStream<"u"){const w=new DecompressionStream("deflate-raw"),v=w.writable.getWriter(),O=w.readable.getReader();v.write(j),v.close();const q=[];let W=0;for(;;){const{done:A,value:R}=await O.read();if(A)break;q.push(R),W+=R.length}const G=new Uint8Array(W);let E=0;for(const A of q)G.set(A,E),E+=A.length;r.set(C,G)}else if(typeof process<"u"&&((g=process.versions)!=null&&g.node))try{r.set(C,F._inflateRawSync(j))}catch{}}l+=46+m+S+P}return r}static async convertKML2GeoJSON(e,t={}){var i,c;D.info("[%s] convert kml to geojson",t==null?void 0:t.requestId);const s=se().parseFromString(e,"application/xml"),o=Array.from(s.querySelectorAll("Placemark")),r=[];for(const a of o){const l={},u=Array.from(a.querySelectorAll("ExtendedData > Data"));for(const y of u){const C=y.getAttribute("name"),k=(c=(i=y.querySelector("value"))==null?void 0:i.textContent)==null?void 0:c.trim();C&&k!==void 0&&k!==null&&(l[C]=k)}const g=x.utc(),h=Object.keys(l).find(y=>y.toLowerCase().indexOf("name")!==-1),p=h?l[h]:void 0,f=`${g.valueOf().toString()}_${Math.random().toString(36).slice(2,8)}`,m=y=>y.trim().split(/[\s\n]+/).filter(C=>C.length>0).map(C=>{const k=C.split(",").map(Number);return[k[0],k[1]]}),S=a.querySelector("LineString > coordinates");if(S){const y=m(S.textContent||"");if(y.length>=2){const C=T.lineString(y,{...l,shape:"line",id:f,name:p});r.push(C)}continue}const P=a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");if(P){const y=m(P.textContent||"");if(y.length>=4){const C=y[0][0]===y[y.length-1][0]&&y[0][1]===y[y.length-1][1]?y:[...y,y[0]],k=T.polygon([C],{...l,shape:"polygon",id:f,name:p});r.push(k)}continue}const N=a.querySelector("Point > coordinates");if(N){const y=m(N.textContent||"");if(y.length>=1){const C=T.point(y[0],{...l,shape:"point",id:f,name:p});r.push(C)}continue}}return T.featureCollection(r)}static async convertKMZ2GeoJSON(e,t={}){var r;D.info("[%s] convert kmz to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await F._parseZipEntries(e),s=n.get("doc.kml")??((r=[...n.entries()].find(([i])=>i.toLowerCase().endsWith(".kml")))==null?void 0:r[1]);if(!s)return D.warn("[%s] no .kml file found in kmz",t==null?void 0:t.requestId),T.featureCollection([]);const o=new TextDecoder().decode(s);return F.convertKML2GeoJSON(o,t)}static async convertZIP2GeoJSON(e,t={}){D.info("[%s] convert zip to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await F._parseZipEntries(e),s=[];for(const[o,r]of n){if(!o.toLowerCase().endsWith(".kml"))continue;const i=new TextDecoder().decode(r),c=await F.convertKML2GeoJSON(i,t);s.push(...c.features)}return s.length===0?(D.warn("[%s] no .kml files found in zip",t==null?void 0:t.requestId),this.convertSHP2GeoJSON(e,t)):T.featureCollection(s)}static async convertSHP2GeoJSON(e,t={}){D.info("[%s] convert shp zip to geojson",t==null?void 0:t.requestId);try{typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await Q(e);if(Array.isArray(n)){const s=n.flatMap(c=>c.features||[]),o=x.utc(),r=(t==null?void 0:t.id)||o.valueOf().toString(),i={Point:"point",MultiPoint:"point",LineString:"line",MultiLineString:"line",Polygon:"polygon",MultiPolygon:"polygon"};return s.forEach((c,a)=>{var p;const l=((p=c.geometry)==null?void 0:p.type)||"",u=i[l]||l.toLowerCase();c.properties=c.properties||{},c.properties.shape=u,c.properties.parentId=r,c.properties.id=`${r}_${a}`;const g=Object.keys(c.properties).find(f=>f.toLowerCase().indexOf("name")!==-1),h=g?c.properties[g]:void 0;c.properties.name=h||`${u}_${o.format()}_${a}`}),T.featureCollection(s)}return n}catch(n){return D.warn("[%s] failed to convert shp zip: %s",t==null?void 0:t.requestId,n),T.featureCollection([])}}}I.AisHelper=K,I.GeoJsonHelper=F,I.LaneHelper=b,I.LngLatHelper=d,I.TropicalHelper=ne,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"})});
|
|
7
|
+
`)}static coordinatesSummary(e,t=3){if(e.length>1){const n=e[0],s=e[e.length-1],o=(n==null?void 0:n.positionTime)<(s==null?void 0:s.positionTime)?v.unix(n==null?void 0:n.positionTime):v.unix(s==null?void 0:s.positionTime),r=(n==null?void 0:n.positionTime)>(s==null?void 0:s.positionTime)?v.unix(n==null?void 0:n.positionTime):v.unix(s==null?void 0:s.positionTime),i=Math.round(r.diff(o,"hours",!0)*100)/100,c=this.generateRouteAccordingToWaypoints(e,!0,!0),a=this.calculateRouteDistance(c),u=K.inspectStoppages(e,t).reduce((h,p)=>(h.duration+=p.duration,h.distance+=p.distance,h),{hours:0,distance:0,spd:0,duration:0});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;const g=i?Math.round((a-u.distance)/(i-u.hours)*100)/100:0;return{begin:o.utc().format(),end:r.utc().format(),distance:Math.round((a-u.distance)*100)/100,hours:Math.round((i-u.hours)*100)/100,avgSpeed:g,stoppage:u}}return{begin:void 0,end:void 0,distance:0,hours:0,avgSpeed:0}}static pickUTCSampleFromSpeed(e,t){var l,u,g;if(!((u=(l=t==null?void 0:t.sample)==null?void 0:l.hours)!=null&&u.length))return{routes:[],hour:void 0};const n=t.sample.hours.at(0),s=v.utc(e),o=v.utc(t.eta),r=s.isAfter(o)?o:s;let i=t.sample.all.find(h=>h.eta===r.format());if(!i){const h=t.sample.all.filter(C=>v.utc(C.eta).isBefore(r)).at(-1),p=this.calculateSubRoute(h,t.route);i=(g=this.calculateNextCoordinateAlongRoute(h,h.speed*r.diff(v(h.etd),"hours",!0),p))==null?void 0:g.coordinate;const{cFactor:f,cog:m,wxFactor:y,meteo:x}=h,P=Math.round(i.distanceFromPrevious*1e4)/1e4,S=Math.round((P+h.distanceFromStart)*1e4)/1e4;i={...i,cFactor:f,cog:m,speed:h.speed,wxFactor:y,distanceFromStart:S,distanceFromPrevious:P,meteo:x,eta:r.format(),etd:r.format()}}i.distanceToGo=Math.round((t.distance-i.distanceFromStart)*100)/100,i.timeToGo=Math.round(o.diff(i.etd,"hours",!0)*100)/100;const c=this.calculateRangeWaypoints(n,i,t.route);return{routes:this.generateRouteAccordingToWaypoints(c),hour:i}}static pickUTCSampleFromRoute(e,t,n){var h;const s=this.calculateSubRoute(t,n),o=this.calculateRouteDistance(s),r=o/t.speed,i=v.utc(e),c=v(t.etd),a=(h=this.calculateNextCoordinateAlongRoute(t,t.speed*i.diff(v(t.etd),"hours",!0),s))==null?void 0:h.coordinate;a.speed=t.speed;const l=c.clone().add(a.hourFromPrevious,"hour");a.eta=Math.abs(l.diff(i,"second"))<2?i.format():l.format(),a.etd=a.eta,a.distanceFromStart=Math.round(a.distanceFromPrevious*100)/100,a.distanceToGo=Math.round((o-a.distanceFromStart)*100)/100,a.timeToGo=Math.round(c.clone().add(r,"hour").diff(v(a.etd),"hour")*100)/100;const u=this.calculateRangeWaypoints(t,a,n);return{routes:this.generateRouteAccordingToWaypoints(u),hour:a}}static includedAngle(e,t){X==null||X.debug("calculate bearing via: %j",{bearing:e,degree:t});let n=Math.abs(e%360-(t%360||0));return n=n>180?360-n:n,n}}let $;try{$=J.getLogger("vessel")}catch{}finally{}class ne{static convert2Geojson(e){var n,s,o;const t=T.featureCollection([]);for(const r of e){const i=(n=r.history)==null?void 0:n[0];if(r.forecasts){i&&i.wind&&(i.wind.kts=i.kts);for(const c of r.forecasts){let a;const l=[],u=[],g=v(c.date).utc(),h=`${r.name}-${c.model}`;for(const f in c==null?void 0:c.hours){const m=c.hours[f];a=a||m;const y=g.clone().add(Number(f),"hour"),x=T.point([m.lng,m.lat],{model:c.model,name:r.name,nameCn:r.nameCn,date:y.format(),hour:Number(f),format:y.format("MMM-DD/HHmm[Z]"),pressure:m.pressure>1e4?d.roundPrecision(m.pressure/100,0):d.roundPrecision(m.pressure,0),gusts:m.gusts,wind:m.wind||{},movement:m.movement,category:h,type:"forecast"});u.push(x),l.push(x.geometry.coordinates)}const p={kts:void 0,deg:void 0};if(i){const f=v(i.updated).utc();if(a){const y=b.calculateDistance(i,a),x=v(a.utc||a.updated).diff(f,"h",!0);p.kts=Math.round(y/x*100)/100,p.deg=b.calculateBearing(i,a,!0,0)}const m=T.point([i.lng,i.lat],{model:c.model,name:r.name,nameCn:r.nameCn,date:f.format(),hour:0,format:f.format("MMM-DD/HHmm[Z]"),pressure:i.pressure>1e4?d.roundPrecision((i==null?void 0:i.pressure)/100,0):d.roundPrecision(i.pressure,0),wind:i.wind,movement:p,category:h,type:"forecast",important:!0});u.unshift(m),l.unshift(m.geometry.coordinates)}if(t.features.push(...u),(l==null?void 0:l.length)>1){const f=T.lineString(d.convertToMonotonicLng2(l),{date:(i==null?void 0:i.updated)||(g==null?void 0:g.format()),id:r.id||r.name,model:c.model,name:r.name,category:h,type:"forecast",movement:p});t.features.push(f)}}}if(t.features.sort((c,a)=>c.properties.type==="forecast"&&a.properties.type==="forecast"&&c.geometry.type==="Point"&&a.geometry.type==="Point"?v(c.properties.date).valueOf()-v(a.properties.date).valueOf():0),(s=r.history)!=null&&s.length){const c=[],a=v(i==null?void 0:i.updated).utc(),l=v((o=r.history)==null?void 0:o.at(-1).updated).utc(),u=a.diff(l,"h")%24>2?24:12;for(const g of r.history){const h=v(g.updated).utc(),p=h.isSameOrBefore(a)||h.isSame(l);p&&a.add(-u,"h");const f=T.point([g.lng,g.lat],{name:r.name,nameCn:r.nameCn,date:h.format(),format:h.format("MMM-DD/HHmm[Z]"),pressure:g.pressure>1e4?d.roundPrecision(g.pressure/100,0):d.roundPrecision(g.pressure,0),kts:g.kts,level:g.type,type:"history",category:`${r.name}-history`,wind:g.wind,movement:g.movement,important:p});t.features.push(f),c.push(f.geometry.coordinates)}if(c.length===1&&c.push(c[0]),c.length>1){const g=T.lineString(d.convertToMonotonicLng2(c),{name:r.name,type:"history",updated:i==null?void 0:i.updated,pressure:(i==null?void 0:i.pressure)>1e4?d.roundPrecision((i==null?void 0:i.pressure)/100,0):d.roundPrecision(i==null?void 0:i.pressure,0),kts:i==null?void 0:i.kts,level:i==null?void 0:i.type});t.features.push(g)}}}return t}static interpolate(e,t=3){var o,r,i,c;const n=(o=e==null?void 0:e.data)==null?void 0:o.features.filter(a=>a.geometry.type==="LineString"&&a.properties.type==="forecast"),s=[];for(const a of n){const l=a.properties.name,u=a.properties.model,g=a.properties.showCircle,h=a.properties.disabled,p=v(a.properties.date).utc();let f=t*60;const m=(r=e==null?void 0:e.data)==null?void 0:r.features.filter(P=>P.geometry.type==="Point"&&P.properties.type==="forecast"&&P.properties.category===`${l}-${u}`);let y,x=p.clone().add(f,"minute").set({minute:0,second:0,millisecond:0});for(;y=this.pickIndex(m,x),y<=m.length-1;){if(y>0){const P=m[y],S=y===0?void 0:m[y-1],C=(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)),w=this.computeNumber(S==null?void 0:S.geometry.coordinates[0],P.geometry.coordinates[0],C),B=this.computeNumber(S==null?void 0:S.geometry.coordinates[1],P.geometry.coordinates[1],C),U=T.point([w,B],{name:l,model:u,category:P==null?void 0:P.properties.category,date:x.format(),format:x.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(S==null?void 0:S.properties.gusts,P.properties.gusts,C),hour:this.computeNumber(S==null?void 0:S.properties.hour,P.properties.hour,C),movement:this.computeNumber(S==null?void 0:S.properties.movement,P.properties.movement,C),pressure:this.computeNumber(S==null?void 0:S.properties.pressure,P.properties.pressure,C),wind:this.computeNumber(S==null?void 0:S.properties.wind,P.properties.wind,C),type:"forecast",disabled:h,showCircle:g});s.push(U)}f+=t*60,x=p.clone().add(f,"minute").set({minute:0,second:0,millisecond:0})}}return s}static accelPassageAt(e,t){const{t1:n,t2:s,hr:o,hours:r}=this.tropicalCenterTwin(e,24,t);return{t1:n,t2:s,hr:o,hours:r}}static diversionPassageAt(e,t,n,s={}){const{t1:o,t2:r,hr:i,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&r){if(!s.debug){const p=b.calculateDistance(e,o),f=b.calculateDistance(e,r);if(p>2*n&&f>2*n)return $==null||$.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j",s.requestId,p,f,{from:e,t1:o,t2:r,hr:i}),{}}const a=b.calculateBearing(e,o),l=b.calculateBearing(o,r),u=Math.abs(a-l);let g=0;u<180?g=u+90:u>=180&&(g=u-90);const h=b.calculateCoordinate(o,g,n);return $==null||$.info("[%s] the right tangent position: %j",s.requestId,{from:e,t1:o,t2:r,radius:n,bearing1:a,bearing2:l,right:h}),{at:h,t1:o,t2:r,hr:Number(i),hours:c}}return{}}static driftPassageAt(e,t,n,s={}){const{t1:o,t2:r,hr:i,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&r){if(!s.debug){const h=b.calculateDistance(e,o),p=b.calculateDistance(e,r);if(h>2*n&&p>2*n)return $==null||$.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j",s.requestId,h,p,{from:e,t1:o,t2:r,hr:i}),{}}const a=b.calculateBearing(e,o),l=b.calculateBearing(o,r),u=b.calculateDistance(e,o);return{at:b.calculateCoordinate(o,a-l+180,n<u?n:u),t1:o,t2:r,hr:Number(i),hours:c}}else return $==null||$.info("[%s] no need drift: %j",s.requestId,{from:e,t1:o,t2:r,hr:i}),{}}static tropicalCenterTwin(e,t=24,n={}){var l,u,g,h,p;let s={};(l=e.forecasts)==null||l.forEach(f=>{s={...f.hours,...s}});const o=((u=e==null?void 0:e.history)==null?void 0:u[0])||(s==null?void 0:s[(g=Object.keys(s))==null?void 0:g[0]]);$==null||$.info("[%s] the first tropical center: %j",n.requestId,o);let r=(h=Object.keys(s||{}).filter(f=>Number(f)<=(t<0?24:t)))==null?void 0:h.at(-1);r||(r=(p=Object.keys(s||{}).filter(f=>Number(f)<=(t<0?24:2*t)))==null?void 0:p.at(-1));const i=s==null?void 0:s[r||-1];$==null||$.info("[%s] the second tropical center: %j in %d hrs",n.requestId,i,r);const c=Object.keys(s||{}).filter(f=>Number(f)<=Number(r)),a={0:o};for(const f of c)a[f]=s[f];return{t1:o,t2:i,hr:Number(r),hours:a}}static pickIndex(e,t){let n=0;for(const s of e){if(v(s.properties.date).isAfter(t))return n===0?-1:n;n++}return n}static computeNumber(e,t,n){if(e)if(t){if(isNaN(e)&&isNaN(t)&&typeof e!="string"&&typeof t!="string"){const s={};for(const o in e)s[o]=this.computeNumber(e[o],t[o],n);return s}return Math.round((e+(t-e)*n)*100)/100}else return e;else return t}}typeof globalThis<"u"&&typeof globalThis.Buffer>"u"&&(globalThis.Buffer={isBuffer(M){return M instanceof Uint8Array},from(M,e){if(typeof M=="string")return new TextEncoder().encode(M);if(M instanceof ArrayBuffer)return new Uint8Array(M);if(Array.isArray(M))return new Uint8Array(M);throw new TypeError("Buffer.from: unsupported source type")}});let D;try{D=J.getLogger("meteo")}catch{}finally{}function se(){if(typeof DOMParser<"u")return new DOMParser;const{JSDOM:M}=require("jsdom"),{DOMParser:e}=new M("").window;return new e}class F{static toArrayBuffer(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}static drawCircle(e,t,n,s={}){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([e,t]),a=T.destination(c,n,90,{units:r}),l=v.utc();i.id=(s==null?void 0:s.id)||l.valueOf().toString();const u="circle";return i.name=(s==null?void 0:s.name)||`${u}_${l.format()}`,i.radius=n,i.center=[e,t],i.end=a.geometry.coordinates.map(g=>d.roundPrecision(g,9)),i.units=r,i.steps=o,i.shape="circle",D.info("[%s] draw circle with %j",s==null?void 0:s.requestId,i),T.circle(c,n,{steps:o,units:r,properties:i})}static drawRect(e,t,n={}){const s=(n==null?void 0:n.properties)??{},o=v.utc();s.id=(n==null?void 0:n.id)||o.valueOf().toString();const r="rect";s.name=(n==null?void 0:n.name)||`${r}_${o.format()}`,s.start=e.map(l=>d.roundPrecision(l,9)),s.end=t.map(l=>d.roundPrecision(l,9)),s.shape="rect",D.info("[%s] draw rect with %j",n==null?void 0:n.requestId,s);const[i,c]=d.convertToMonotonicLng2([e,t]),a=[Math.min(i[0],c[0]),Math.min(i[1],c[1]),Math.max(i[0],c[0]),Math.max(i[1],c[1])];return T.bboxPolygon(a,{properties:s})}static drawLine(e,t={}){const n=(t==null?void 0:t.properties)??{},s=v.utc();n.id=(t==null?void 0:t.id)||s.valueOf().toString();const o="line";n.name=(t==null?void 0:t.name)||`${o}_${s.format()}`,n.shape="line",D.info("[%s] draw line with %j",t==null?void 0:t.requestId,n);const r=d.convertToMonotonicLng2(e);return T.lineString(r,n)}static drawPolygon(e,t={}){const n=(t==null?void 0:t.properties)??{},s=v.utc();n.id=(t==null?void 0:t.id)||s.valueOf().toString();const o="polygon";n.name=(t==null?void 0:t.name)||`${o}_${s.format()}`,n.coordinates=e.map(i=>i.map(c=>d.roundPrecision(c,9))),n.shape="polygon",D.info("[%s] draw polygon with %j",t==null?void 0:t.requestId,n);const r=d.convertToMonotonicLng2(e);return T.polygon([r],n)}static drawPoint(e,t,n={}){const s=(n==null?void 0:n.properties)??{},o=v.utc();s.id=(n==null?void 0:n.id)||o.valueOf().toString();const r="point";return s.name=(n==null?void 0:n.name)||`${r}_${o.format()}`,s.shape="point",D.info("[%s] draw point with %j",n==null?void 0:n.requestId,s),T.point([t,e],s)}static parseCircle(e,t={}){var s,o;D.info("[%s] parse circle with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="circle"){const r=v.utc();n.id=(n==null?void 0:n.id)||r.valueOf().toString();const i=n==null?void 0:n.id,c=((s=n==null?void 0:n.center)==null?void 0:s.length)==2?T.point(n.center):T.centroid(e);let a="center";c.properties={id:`${a}_${i}`,parentId:i,name:a};const l=(n==null?void 0:n.units)||"nauticalmiles";let u=n==null?void 0:n.radius;if(!u){const p=T.polygonToLine(e);u=T.pointToLineDistance(c,p,{units:l})}a="end";const g=((o=n==null?void 0:n.end)==null?void 0:o.length)==2?T.point(n.end):T.destination(c,u,90,{units:l});g.properties={id:`${a}_${i}`,parentId:i,name:a,radius:u,units:l};const h=T.lineString([c.geometry.coordinates,g.geometry.coordinates]);return a="edge",h.properties={id:`${a}_${i}`,parentId:i,name:a,radius:u,units:l},T.featureCollection([c,g,h,e])}else return D.warn("[%s] not a orm-std circle, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parseRect(e,t={}){D.info("[%s] parse rect with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="rect"){const s=v.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,r=e.geometry.coordinates[0],c=["sw","nw","ne","se"].map((a,l)=>{const u=T.point(r[l]);return u.properties={id:`${a}_${o}`,parentId:o,name:a},u});return T.featureCollection([...c,e])}else return D.warn("[%s] not a orm-std rect, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parseLine(e,t={}){D.info("[%s] parse line with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="line"){const s=v.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,i=e.geometry.coordinates.map((c,a)=>{const l=`point_${a}`,u=T.point(c);return u.properties={id:`${l}_${o}`,parentId:o,name:l,index:a},u});return T.featureCollection([...i,e])}else return D.warn("[%s] not a orm-std line, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static parsePolygon(e,t={}){D.info("[%s] parse polygon with %j",t==null?void 0:t.requestId,e.properties);const n=e.properties||{};if(n.shape=="polygon"){const s=v.utc();n.id=(n==null?void 0:n.id)||s.valueOf().toString();const o=n==null?void 0:n.id,i=e.geometry.coordinates[0].map((c,a)=>{const l=T.point(c),u=`corner_${a}`;return l.properties={id:`${u}_${o}`,parentId:o,name:u,index:a},l});return T.featureCollection([...i,e])}else return D.warn("[%s] not a orm-std polygon, just return the original feature",t==null?void 0:t.requestId),T.featureCollection([e])}static _inflateRawSync(e){var t;if(typeof process<"u"&&((t=process.versions)!=null&&t.node)){const n=require("zlib");return new Uint8Array(n.inflateRawSync(Buffer.from(e)))}throw new Error("Sync inflate is not supported in browser; use the async convertKMZ2GeoJSONAsync / convertZIP2GeoJSONAsync instead")}static async _parseZipEntries(e){var g;const t=new Uint8Array(e),n=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength),s=new DataView(n),o=new Uint8Array(n),r=new Map;let i=-1;for(let h=n.byteLength-22;h>=0;h--)if(s.getUint32(h,!0)===101010256){i=h;break}if(i<0)throw new Error("Invalid ZIP file: EOCD not found");s.getUint16(i+8,!0);const c=s.getUint32(i+12,!0),a=s.getUint32(i+16,!0);let l=a;const u=a+c;for(;l<u;){if(s.getUint32(l,!0)!==33639248)throw new Error(`Invalid ZIP file: Central Directory signature mismatch at offset ${l}`);const p=s.getUint16(l+10,!0),f=s.getUint32(l+20,!0),m=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+m),C=new TextDecoder().decode(S),w=s.getUint16(P+26,!0),B=s.getUint16(P+28,!0),U=P+30+w+B,j=o.slice(U,U+f);if(p===0)r.set(C,j);else if(p===8){if(typeof DecompressionStream<"u"){const O=new DecompressionStream("deflate-raw"),N=O.writable.getWriter(),I=O.readable.getReader();N.write(j),N.close();const q=[];let W=0;for(;;){const{done:A,value:R}=await I.read();if(A)break;q.push(R),W+=R.length}const G=new Uint8Array(W);let E=0;for(const A of q)G.set(A,E),E+=A.length;r.set(C,G)}else if(typeof process<"u"&&((g=process.versions)!=null&&g.node))try{r.set(C,F._inflateRawSync(j))}catch{}}l+=46+m+y+x}return r}static async convertKML2GeoJSON(e,t={}){var i,c;D.info("[%s] convert kml to geojson",t==null?void 0:t.requestId);const s=se().parseFromString(e,"application/xml"),o=Array.from(s.querySelectorAll("Placemark")),r=[];for(const a of o){const l={},u=Array.from(a.querySelectorAll("ExtendedData > Data"));for(const S of u){const C=S.getAttribute("name"),w=(c=(i=S.querySelector("value"))==null?void 0:i.textContent)==null?void 0:c.trim();C&&w!==void 0&&w!==null&&(l[C]=w)}const g=v.utc(),h=Object.keys(l).find(S=>S.toLowerCase().indexOf("name")!==-1),p=h?l[h]:void 0,f=`${g.valueOf().toString()}_${Math.random().toString(36).slice(2,8)}`,m=S=>S.trim().split(/[\s\n]+/).filter(C=>C.length>0).map(C=>{const w=C.split(",").map(Number);return[w[0],w[1]]}),y=a.querySelector("LineString > coordinates");if(y){const S=m(y.textContent||"");if(S.length>=2){const C=T.lineString(S,{...l,shape:"line",id:f,name:p});r.push(C)}continue}const x=a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");if(x){const S=m(x.textContent||"");if(S.length>=4){const C=S[0][0]===S[S.length-1][0]&&S[0][1]===S[S.length-1][1]?S:[...S,S[0]],w=T.polygon([C],{...l,shape:"polygon",id:f,name:p});r.push(w)}continue}const P=a.querySelector("Point > coordinates");if(P){const S=m(P.textContent||"");if(S.length>=1){const C=T.point(S[0],{...l,shape:"point",id:f,name:p});r.push(C)}continue}}return T.featureCollection(r)}static async convertKMZ2GeoJSON(e,t={}){var r;D.info("[%s] convert kmz to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await F._parseZipEntries(e),s=n.get("doc.kml")??((r=[...n.entries()].find(([i])=>i.toLowerCase().endsWith(".kml")))==null?void 0:r[1]);if(!s)return D.warn("[%s] no .kml file found in kmz",t==null?void 0:t.requestId),T.featureCollection([]);const o=new TextDecoder().decode(s);return F.convertKML2GeoJSON(o,t)}static async convertZIP2GeoJSON(e,t={}){D.info("[%s] convert zip to geojson (async)",t==null?void 0:t.requestId),typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await F._parseZipEntries(e),s=[];for(const[o,r]of n){if(!o.toLowerCase().endsWith(".kml"))continue;const i=new TextDecoder().decode(r),c=await F.convertKML2GeoJSON(i,t);s.push(...c.features)}return s.length===0?(D.warn("[%s] no .kml files found in zip",t==null?void 0:t.requestId),this.convertSHP2GeoJSON(e,t)):T.featureCollection(s)}static async convertSHP2GeoJSON(e,t={}){D.info("[%s] convert shp zip to geojson",t==null?void 0:t.requestId);try{typeof Buffer<"u"&&Buffer.isBuffer(e)&&(e=F.toArrayBuffer(e));const n=await Q(e);if(Array.isArray(n)){const s=n.flatMap(c=>c.features||[]),o=v.utc(),r=(t==null?void 0:t.id)||o.valueOf().toString(),i={Point:"point",MultiPoint:"point",LineString:"line",MultiLineString:"line",Polygon:"polygon",MultiPolygon:"polygon"};return s.forEach((c,a)=>{var p;const l=((p=c.geometry)==null?void 0:p.type)||"",u=i[l]||l.toLowerCase();c.properties=c.properties||{},c.properties.shape=u,c.properties.parentId=r,c.properties.id=`${r}_${a}`;const g=Object.keys(c.properties).find(f=>f.toLowerCase().indexOf("name")!==-1),h=g?c.properties[g]:void 0;c.properties.name=h||`${u}_${o.format()}_${a}`}),T.featureCollection(s)}return n}catch(n){return D.warn("[%s] failed to convert shp zip: %s",t==null?void 0:t.requestId,n),T.featureCollection([])}}}k.AisHelper=K,k.GeoJsonHelper=F,k.LaneHelper=b,k.LngLatHelper=d,k.TropicalHelper=ne,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})});
|