@idm-plugin/geo 2.2.6 → 2.2.7
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 +165 -129
- 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 x 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 = x().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: x.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: x.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 = x(e), o = x(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), S = new DataView(g.buffer);
|
|
281
|
+
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), 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 S = 0; S < h.length; S++)
|
|
770
770
|
if (u)
|
|
771
|
-
f.push(h[
|
|
771
|
+
f.push(h[S]);
|
|
772
772
|
else {
|
|
773
|
-
g = { lng: h[
|
|
774
|
-
const
|
|
775
|
-
if (a +=
|
|
776
|
-
l +=
|
|
773
|
+
g = { lng: h[S][0], lat: h[S][1] };
|
|
774
|
+
const P = this.calculateDistance(t, g, !0, 8, s);
|
|
775
|
+
if (a += P, a < e)
|
|
776
|
+
l += P, P && 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 N = a - e, y = this.calculateBearing(g, t);
|
|
782
|
+
u = this.calculateCoordinate(g, y, N, 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 = x.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 = x.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 = x.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 ? x.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(x.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, S) => S > 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 S = e[g], P = [];
|
|
1074
|
+
P.push((g + 1).toString()), P.push(S.lat.toFixed(s)), P.push(S.lng.toFixed(s)), o && P.push(S.name ?? ""), r && P.push(S.description ?? ""), u && P.push(g === 0 ? "" : S.gcToPrevious ? "GC" : "RL"), m && P.push(S.bearing != null ? String(S.bearing) : ""), h && P.push(S.distanceFromPrevious != null ? String(S.distanceFromPrevious) : ""), l && P.push(S.speed != null ? String(S.speed) : ""), i && P.push(S.port != null ? String(S.port) : ""), c && P.push(S.stbd != null ? String(S.stbd) : ""), a && P.push(S.arrRad != null ? String(S.arrRad) : ""), f.push(P.map((N) => v.csvEscapeField(N)).join(","));
|
|
1075
1075
|
}
|
|
1076
1076
|
return f.join(`
|
|
1077
1077
|
`);
|
|
@@ -1089,8 +1089,44 @@ 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
|
-
|
|
1092
|
+
const g = [], S = e[f], P = String(f).padStart(3, "0");
|
|
1093
|
+
g.push(P);
|
|
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(","));
|
|
1094
1130
|
}
|
|
1095
1131
|
return p.join(`
|
|
1096
1132
|
`);
|
|
@@ -1107,26 +1143,26 @@ class v {
|
|
|
1107
1143
|
* @returns Uint8Array 二进制数据,可直接用于 new Blob([result], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})
|
|
1108
1144
|
*/
|
|
1109
1145
|
static waypoints2XLSX(t, e, n) {
|
|
1110
|
-
const s = (n == null ? void 0 : n.precision) ?? 6, o = t || "Route", r = e.some((
|
|
1146
|
+
const s = (n == null ? void 0 : n.precision) ?? 6, o = t || "Route", r = e.some((b) => b.name), i = e.some((b) => b.description), c = e.some((b) => b.port != null), a = e.some((b) => b.stbd != null), l = e.some((b) => b.arrRad != null), u = e.some((b) => b.speed != null), m = e.some((b, I) => I > 0 && b.gcToPrevious != null), h = e.some((b) => b.bearing != null), p = e.some((b) => b.distanceFromPrevious != null), f = ["WPT No.", "Latitude", "Longitude"];
|
|
1111
1147
|
r && f.push("Name"), i && f.push("Description"), m && f.push("Leg"), h && f.push("Bearing[deg]"), p && f.push("Distance[NM]"), u && f.push("Speed[kn]"), c && f.push("PORT XTD[NM]"), a && f.push("STBD XTD[NM]"), l && f.push("Arr.Rad[NM]");
|
|
1112
|
-
const g = (
|
|
1113
|
-
let
|
|
1114
|
-
for (let
|
|
1115
|
-
const
|
|
1116
|
-
|
|
1148
|
+
const g = (b) => b == null ? "" : String(b).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1149
|
+
let P = `<row r="1">${f.map((b, I) => `<c r="${G(I)}1" s="1" t="inlineStr"><is><t>${g(b)}</t></is></c>`).join("")}</row>`;
|
|
1150
|
+
for (let b = 0; b < e.length; b++) {
|
|
1151
|
+
const I = e[b], W = b + 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
|
+
L != null ? Z(q, L) : A(q, "");
|
|
1117
1153
|
};
|
|
1118
|
-
|
|
1154
|
+
Z(0, b + 1), A(1, d.lat2pretty(I.lat, s).pretty), A(2, d.lng2pretty(I.lng, s).pretty);
|
|
1119
1155
|
let D = 3;
|
|
1120
|
-
r && (A(D,
|
|
1156
|
+
r && (A(D, I.name ?? ""), D++), i && (A(D, I.description ?? ""), D++), m && (A(D, b === 0 ? "" : I.gcToPrevious ? "GC" : "RL"), D++), h && (w(D, I.bearing), D++), p && (w(D, I.distanceFromPrevious), D++), u && (w(D, I.speed), D++), c && (w(D, I.port), D++), a && (w(D, I.stbd), D++), l && (w(D, I.arrRad), D++), P += `<row r="${W}">${j.join("")}</row>`;
|
|
1121
1157
|
}
|
|
1122
|
-
const
|
|
1158
|
+
const N = "0." + "0".repeat(s), y = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>' + P + "</sheetData></worksheet>", M = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/></Types>', O = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>', 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="' + N + '"/></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>', k = new TextEncoder();
|
|
1123
1159
|
return _([
|
|
1124
|
-
{ name: "[Content_Types].xml", data:
|
|
1125
|
-
{ name: "_rels/.rels", data:
|
|
1126
|
-
{ name: "xl/workbook.xml", data:
|
|
1127
|
-
{ name: "xl/_rels/workbook.xml.rels", data:
|
|
1128
|
-
{ name: "xl/worksheets/sheet1.xml", data:
|
|
1129
|
-
{ name: "xl/styles.xml", data:
|
|
1160
|
+
{ name: "[Content_Types].xml", data: k.encode(M) },
|
|
1161
|
+
{ name: "_rels/.rels", data: k.encode(O) },
|
|
1162
|
+
{ name: "xl/workbook.xml", data: k.encode(U) },
|
|
1163
|
+
{ name: "xl/_rels/workbook.xml.rels", data: k.encode(E) },
|
|
1164
|
+
{ name: "xl/worksheets/sheet1.xml", data: k.encode(y) },
|
|
1165
|
+
{ name: "xl/styles.xml", data: k.encode(B) }
|
|
1130
1166
|
]);
|
|
1131
1167
|
}
|
|
1132
1168
|
/**
|
|
@@ -1186,7 +1222,7 @@ class v {
|
|
|
1186
1222
|
*/
|
|
1187
1223
|
static coordinatesSummary(t, e = 3) {
|
|
1188
1224
|
if (t.length > 1) {
|
|
1189
|
-
const n = t[0], s = t[t.length - 1], o = (n == null ? void 0 : n.positionTime) < (s == null ? void 0 : s.positionTime) ?
|
|
1225
|
+
const n = t[0], s = t[t.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(t, !0, !0), a = this.calculateRouteDistance(c), u = K.inspectStoppages(t, e).reduce(
|
|
1190
1226
|
(h, p) => (h.duration += p.duration, h.distance += p.distance, h),
|
|
1191
1227
|
{ hours: 0, distance: 0, spd: 0, duration: 0 }
|
|
1192
1228
|
);
|
|
@@ -1222,21 +1258,21 @@ class v {
|
|
|
1222
1258
|
var l, u, m;
|
|
1223
1259
|
if (!((u = (l = e == null ? void 0 : e.sample) == null ? void 0 : l.hours) != null && u.length))
|
|
1224
1260
|
return { routes: [], hour: void 0 };
|
|
1225
|
-
const n = e.sample.hours.at(0), s =
|
|
1261
|
+
const n = e.sample.hours.at(0), s = x.utc(t), o = x.utc(e.eta), r = s.isAfter(o) ? o : s;
|
|
1226
1262
|
let i = e.sample.all.find((h) => h.eta === r.format());
|
|
1227
1263
|
if (!i) {
|
|
1228
|
-
const h = e.sample.all.filter((M) =>
|
|
1229
|
-
i = (m = this.calculateNextCoordinateAlongRoute(h, h.speed * r.diff(
|
|
1230
|
-
const { cFactor: f, cog: g, wxFactor:
|
|
1264
|
+
const h = e.sample.all.filter((M) => x.utc(M.eta).isBefore(r)).at(-1), p = this.calculateSubRoute(h, e.route);
|
|
1265
|
+
i = (m = this.calculateNextCoordinateAlongRoute(h, h.speed * r.diff(x(h.etd), "hours", !0), p)) == null ? void 0 : m.coordinate;
|
|
1266
|
+
const { cFactor: f, cog: g, wxFactor: S, meteo: P } = h, N = Math.round(i.distanceFromPrevious * 1e4) / 1e4, y = Math.round((N + h.distanceFromStart) * 1e4) / 1e4;
|
|
1231
1267
|
i = {
|
|
1232
1268
|
...i,
|
|
1233
1269
|
cFactor: f,
|
|
1234
1270
|
cog: g,
|
|
1235
1271
|
speed: h.speed,
|
|
1236
|
-
wxFactor:
|
|
1237
|
-
distanceFromStart:
|
|
1238
|
-
distanceFromPrevious:
|
|
1239
|
-
meteo:
|
|
1272
|
+
wxFactor: S,
|
|
1273
|
+
distanceFromStart: y,
|
|
1274
|
+
distanceFromPrevious: N,
|
|
1275
|
+
meteo: P,
|
|
1240
1276
|
eta: r.format(),
|
|
1241
1277
|
etd: r.format()
|
|
1242
1278
|
};
|
|
@@ -1260,10 +1296,10 @@ class v {
|
|
|
1260
1296
|
*/
|
|
1261
1297
|
static pickUTCSampleFromRoute(t, e, n) {
|
|
1262
1298
|
var h;
|
|
1263
|
-
const s = this.calculateSubRoute(e, n), o = this.calculateRouteDistance(s), r = o / e.speed, i =
|
|
1299
|
+
const s = this.calculateSubRoute(e, n), o = this.calculateRouteDistance(s), r = o / e.speed, i = x.utc(t), c = x(e.etd), a = (h = this.calculateNextCoordinateAlongRoute(e, e.speed * i.diff(x(e.etd), "hours", !0), s)) == null ? void 0 : h.coordinate;
|
|
1264
1300
|
a.speed = e.speed;
|
|
1265
1301
|
const l = c.clone().add(a.hourFromPrevious, "hour");
|
|
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(
|
|
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(x(a.etd), "hour") * 100) / 100;
|
|
1267
1303
|
const u = this.calculateRangeWaypoints(e, a, n);
|
|
1268
1304
|
return {
|
|
1269
1305
|
routes: this.generateRouteAccordingToWaypoints(u),
|
|
@@ -1281,9 +1317,9 @@ class v {
|
|
|
1281
1317
|
return n = n > 180 ? 360 - n : n, n;
|
|
1282
1318
|
}
|
|
1283
1319
|
}
|
|
1284
|
-
let
|
|
1320
|
+
let $;
|
|
1285
1321
|
try {
|
|
1286
|
-
|
|
1322
|
+
$ = z.getLogger("vessel");
|
|
1287
1323
|
} catch {
|
|
1288
1324
|
} finally {
|
|
1289
1325
|
}
|
|
@@ -1301,17 +1337,17 @@ class it {
|
|
|
1301
1337
|
i && i.wind && (i.wind.kts = i.kts);
|
|
1302
1338
|
for (const c of r.forecasts) {
|
|
1303
1339
|
let a;
|
|
1304
|
-
const l = [], u = [], m =
|
|
1340
|
+
const l = [], u = [], m = x(c.date).utc(), h = `${r.name}-${c.model}`;
|
|
1305
1341
|
for (const f in c == null ? void 0 : c.hours) {
|
|
1306
1342
|
const g = c.hours[f];
|
|
1307
1343
|
a = a || g;
|
|
1308
|
-
const
|
|
1344
|
+
const S = m.clone().add(Number(f), "hour"), P = T.point([g.lng, g.lat], {
|
|
1309
1345
|
model: c.model,
|
|
1310
1346
|
name: r.name,
|
|
1311
1347
|
nameCn: r.nameCn,
|
|
1312
|
-
date:
|
|
1348
|
+
date: S.format(),
|
|
1313
1349
|
hour: Number(f),
|
|
1314
|
-
format:
|
|
1350
|
+
format: S.format("MMM-DD/HHmm[Z]"),
|
|
1315
1351
|
pressure: g.pressure > 1e4 ? d.roundPrecision(g.pressure / 100, 0) : d.roundPrecision(g.pressure, 0),
|
|
1316
1352
|
gusts: g.gusts,
|
|
1317
1353
|
wind: g.wind || {},
|
|
@@ -1319,17 +1355,17 @@ class it {
|
|
|
1319
1355
|
category: h,
|
|
1320
1356
|
type: "forecast"
|
|
1321
1357
|
});
|
|
1322
|
-
u.push(
|
|
1358
|
+
u.push(P), l.push(P.geometry.coordinates);
|
|
1323
1359
|
}
|
|
1324
1360
|
const p = {
|
|
1325
1361
|
kts: void 0,
|
|
1326
1362
|
deg: void 0
|
|
1327
1363
|
};
|
|
1328
1364
|
if (i) {
|
|
1329
|
-
const f =
|
|
1365
|
+
const f = x(i.updated).utc();
|
|
1330
1366
|
if (a) {
|
|
1331
|
-
const
|
|
1332
|
-
p.kts = Math.round(
|
|
1367
|
+
const S = v.calculateDistance(i, a), P = x(a.utc || a.updated).diff(f, "h", !0);
|
|
1368
|
+
p.kts = Math.round(S / P * 100) / 100, p.deg = v.calculateBearing(i, a, !0, 0);
|
|
1333
1369
|
}
|
|
1334
1370
|
const g = T.point([i.lng, i.lat], {
|
|
1335
1371
|
model: c.model,
|
|
@@ -1362,10 +1398,10 @@ class it {
|
|
|
1362
1398
|
}
|
|
1363
1399
|
}
|
|
1364
1400
|
}
|
|
1365
|
-
if (e.features.sort((c, a) => c.properties.type === "forecast" && a.properties.type === "forecast" && c.geometry.type === "Point" && a.geometry.type === "Point" ?
|
|
1366
|
-
const c = [], a =
|
|
1401
|
+
if (e.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) {
|
|
1402
|
+
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;
|
|
1367
1403
|
for (const m of r.history) {
|
|
1368
|
-
const h =
|
|
1404
|
+
const h = x(m.updated).utc(), p = h.isSameOrBefore(a) || h.isSame(l);
|
|
1369
1405
|
p && a.add(-u, "h");
|
|
1370
1406
|
const f = T.point([m.lng, m.lat], {
|
|
1371
1407
|
name: r.name,
|
|
@@ -1407,32 +1443,32 @@ class it {
|
|
|
1407
1443
|
var o, r, i, c;
|
|
1408
1444
|
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 = [];
|
|
1409
1445
|
for (const a of n) {
|
|
1410
|
-
const l = a.properties.name, u = a.properties.model, m = a.properties.showCircle, h = a.properties.disabled, p =
|
|
1446
|
+
const l = a.properties.name, u = a.properties.model, m = a.properties.showCircle, h = a.properties.disabled, p = x(a.properties.date).utc();
|
|
1411
1447
|
let f = e * 60;
|
|
1412
1448
|
const g = (r = t == null ? void 0 : t.data) == null ? void 0 : r.features.filter(
|
|
1413
|
-
(
|
|
1449
|
+
(N) => N.geometry.type === "Point" && N.properties.type === "forecast" && N.properties.category === `${l}-${u}`
|
|
1414
1450
|
);
|
|
1415
|
-
let
|
|
1416
|
-
for (;
|
|
1417
|
-
if (
|
|
1418
|
-
const
|
|
1451
|
+
let S, P = p.clone().add(f, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
1452
|
+
for (; S = this.pickIndex(g, P), S <= g.length - 1; ) {
|
|
1453
|
+
if (S > 0) {
|
|
1454
|
+
const N = g[S], y = S === 0 ? void 0 : g[S - 1], M = (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)), O = this.computeNumber(y == null ? void 0 : y.geometry.coordinates[0], N.geometry.coordinates[0], M), U = this.computeNumber(y == null ? void 0 : y.geometry.coordinates[1], N.geometry.coordinates[1], M), E = T.point([O, U], {
|
|
1419
1455
|
name: l,
|
|
1420
1456
|
model: u,
|
|
1421
|
-
category:
|
|
1422
|
-
date:
|
|
1423
|
-
format:
|
|
1424
|
-
gusts: this.computeNumber(
|
|
1425
|
-
hour: this.computeNumber(
|
|
1426
|
-
movement: this.computeNumber(
|
|
1427
|
-
pressure: this.computeNumber(
|
|
1428
|
-
wind: this.computeNumber(
|
|
1457
|
+
category: N == null ? void 0 : N.properties.category,
|
|
1458
|
+
date: P.format(),
|
|
1459
|
+
format: P.format("MMM-DD/HHmm[Z]"),
|
|
1460
|
+
gusts: this.computeNumber(y == null ? void 0 : y.properties.gusts, N.properties.gusts, M),
|
|
1461
|
+
hour: this.computeNumber(y == null ? void 0 : y.properties.hour, N.properties.hour, M),
|
|
1462
|
+
movement: this.computeNumber(y == null ? void 0 : y.properties.movement, N.properties.movement, M),
|
|
1463
|
+
pressure: this.computeNumber(y == null ? void 0 : y.properties.pressure, N.properties.pressure, M),
|
|
1464
|
+
wind: this.computeNumber(y == null ? void 0 : y.properties.wind, N.properties.wind, M),
|
|
1429
1465
|
type: "forecast",
|
|
1430
1466
|
disabled: h,
|
|
1431
1467
|
showCircle: m
|
|
1432
1468
|
});
|
|
1433
1469
|
s.push(E);
|
|
1434
1470
|
}
|
|
1435
|
-
f += e * 60,
|
|
1471
|
+
f += e * 60, P = p.clone().add(f, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
1436
1472
|
}
|
|
1437
1473
|
}
|
|
1438
1474
|
return s;
|
|
@@ -1464,7 +1500,7 @@ class it {
|
|
|
1464
1500
|
if (!s.debug) {
|
|
1465
1501
|
const p = v.calculateDistance(t, o), f = v.calculateDistance(t, r);
|
|
1466
1502
|
if (p > 2 * n && f > 2 * n)
|
|
1467
|
-
return
|
|
1503
|
+
return $ == null || $.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", s.requestId, p, f, {
|
|
1468
1504
|
from: t,
|
|
1469
1505
|
t1: o,
|
|
1470
1506
|
t2: r,
|
|
@@ -1475,7 +1511,7 @@ class it {
|
|
|
1475
1511
|
let m = 0;
|
|
1476
1512
|
u < 180 ? m = u + 90 : u >= 180 && (m = u - 90);
|
|
1477
1513
|
const h = v.calculateCoordinate(o, m, n);
|
|
1478
|
-
return
|
|
1514
|
+
return $ == null || $.info("[%s] the right tangent position: %j", s.requestId, {
|
|
1479
1515
|
from: t,
|
|
1480
1516
|
t1: o,
|
|
1481
1517
|
t2: r,
|
|
@@ -1503,7 +1539,7 @@ class it {
|
|
|
1503
1539
|
if (!s.debug) {
|
|
1504
1540
|
const h = v.calculateDistance(t, o), p = v.calculateDistance(t, r);
|
|
1505
1541
|
if (h > 2 * n && p > 2 * n)
|
|
1506
|
-
return
|
|
1542
|
+
return $ == null || $.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", s.requestId, h, p, {
|
|
1507
1543
|
from: t,
|
|
1508
1544
|
t1: o,
|
|
1509
1545
|
t2: r,
|
|
@@ -1513,7 +1549,7 @@ class it {
|
|
|
1513
1549
|
const a = v.calculateBearing(t, o), l = v.calculateBearing(o, r), u = v.calculateDistance(t, o);
|
|
1514
1550
|
return { at: v.calculateCoordinate(o, a - l + 180, n < u ? n : u), t1: o, t2: r, hr: Number(i), hours: c };
|
|
1515
1551
|
} else
|
|
1516
|
-
return
|
|
1552
|
+
return $ == null || $.info("[%s] no need drift: %j", s.requestId, { from: t, t1: o, t2: r, hr: i }), {};
|
|
1517
1553
|
}
|
|
1518
1554
|
/**
|
|
1519
1555
|
* 获取台风中心点对
|
|
@@ -1530,11 +1566,11 @@ class it {
|
|
|
1530
1566
|
s = { ...f.hours, ...s };
|
|
1531
1567
|
});
|
|
1532
1568
|
const o = ((u = t == null ? void 0 : t.history) == null ? void 0 : u[0]) || (s == null ? void 0 : s[(m = Object.keys(s)) == null ? void 0 : m[0]]);
|
|
1533
|
-
|
|
1569
|
+
$ == null || $.info("[%s] the first tropical center: %j", n.requestId, o);
|
|
1534
1570
|
let r = (h = Object.keys(s || {}).filter((f) => Number(f) <= (e < 0 ? 24 : e))) == null ? void 0 : h.at(-1);
|
|
1535
1571
|
r || (r = (p = Object.keys(s || {}).filter((f) => Number(f) <= (e < 0 ? 24 : 2 * e))) == null ? void 0 : p.at(-1));
|
|
1536
1572
|
const i = s == null ? void 0 : s[r || -1];
|
|
1537
|
-
|
|
1573
|
+
$ == null || $.info("[%s] the second tropical center: %j in %d hrs", n.requestId, i, r);
|
|
1538
1574
|
const c = Object.keys(s || {}).filter((f) => Number(f) <= Number(r)), a = { 0: o };
|
|
1539
1575
|
for (const f of c)
|
|
1540
1576
|
a[f] = s[f];
|
|
@@ -1543,7 +1579,7 @@ class it {
|
|
|
1543
1579
|
static pickIndex(t, e) {
|
|
1544
1580
|
let n = 0;
|
|
1545
1581
|
for (const s of t) {
|
|
1546
|
-
if (
|
|
1582
|
+
if (x(s.properties.date).isAfter(e))
|
|
1547
1583
|
return n === 0 ? -1 : n;
|
|
1548
1584
|
n++;
|
|
1549
1585
|
}
|
|
@@ -1610,7 +1646,7 @@ class F {
|
|
|
1610
1646
|
* @param options 步数、单位等选项
|
|
1611
1647
|
*/
|
|
1612
1648
|
static drawCircle(t, e, n, s = {}) {
|
|
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 =
|
|
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 = x.utc();
|
|
1614
1650
|
i.id = (s == null ? void 0 : s.id) || l.valueOf().toString();
|
|
1615
1651
|
const u = "circle";
|
|
1616
1652
|
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 });
|
|
@@ -1622,7 +1658,7 @@ class F {
|
|
|
1622
1658
|
* @param options 选项
|
|
1623
1659
|
*/
|
|
1624
1660
|
static drawRect(t, e, n = {}) {
|
|
1625
|
-
const s = (n == null ? void 0 : n.properties) ?? {}, o =
|
|
1661
|
+
const s = (n == null ? void 0 : n.properties) ?? {}, o = x.utc();
|
|
1626
1662
|
s.id = (n == null ? void 0 : n.id) || o.valueOf().toString();
|
|
1627
1663
|
const r = "rect";
|
|
1628
1664
|
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);
|
|
@@ -1637,7 +1673,7 @@ class F {
|
|
|
1637
1673
|
* @returns
|
|
1638
1674
|
*/
|
|
1639
1675
|
static drawLine(t, e = {}) {
|
|
1640
|
-
const n = (e == null ? void 0 : e.properties) ?? {}, s =
|
|
1676
|
+
const n = (e == null ? void 0 : e.properties) ?? {}, s = x.utc();
|
|
1641
1677
|
n.id = (e == null ? void 0 : e.id) || s.valueOf().toString();
|
|
1642
1678
|
const o = "line";
|
|
1643
1679
|
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);
|
|
@@ -1651,7 +1687,7 @@ class F {
|
|
|
1651
1687
|
* @returns
|
|
1652
1688
|
*/
|
|
1653
1689
|
static drawPolygon(t, e = {}) {
|
|
1654
|
-
const n = (e == null ? void 0 : e.properties) ?? {}, s =
|
|
1690
|
+
const n = (e == null ? void 0 : e.properties) ?? {}, s = x.utc();
|
|
1655
1691
|
n.id = (e == null ? void 0 : e.id) || s.valueOf().toString();
|
|
1656
1692
|
const o = "polygon";
|
|
1657
1693
|
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);
|
|
@@ -1666,7 +1702,7 @@ class F {
|
|
|
1666
1702
|
* @returns
|
|
1667
1703
|
*/
|
|
1668
1704
|
static drawPoint(t, e, n = {}) {
|
|
1669
|
-
const s = (n == null ? void 0 : n.properties) ?? {}, o =
|
|
1705
|
+
const s = (n == null ? void 0 : n.properties) ?? {}, o = x.utc();
|
|
1670
1706
|
s.id = (n == null ? void 0 : n.id) || o.valueOf().toString();
|
|
1671
1707
|
const r = "point";
|
|
1672
1708
|
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);
|
|
@@ -1683,7 +1719,7 @@ class F {
|
|
|
1683
1719
|
R.info("[%s] parse circle with %j", e == null ? void 0 : e.requestId, t.properties);
|
|
1684
1720
|
const n = t.properties || {};
|
|
1685
1721
|
if (n.shape == "circle") {
|
|
1686
|
-
const r =
|
|
1722
|
+
const r = x.utc();
|
|
1687
1723
|
n.id = (n == null ? void 0 : n.id) || r.valueOf().toString();
|
|
1688
1724
|
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);
|
|
1689
1725
|
let a = "center";
|
|
@@ -1713,7 +1749,7 @@ class F {
|
|
|
1713
1749
|
R.info("[%s] parse rect with %j", e == null ? void 0 : e.requestId, t.properties);
|
|
1714
1750
|
const n = t.properties || {};
|
|
1715
1751
|
if (n.shape == "rect") {
|
|
1716
|
-
const s =
|
|
1752
|
+
const s = x.utc();
|
|
1717
1753
|
n.id = (n == null ? void 0 : n.id) || s.valueOf().toString();
|
|
1718
1754
|
const o = n == null ? void 0 : n.id, r = t.geometry.coordinates[0], c = ["sw", "nw", "ne", "se"].map((a, l) => {
|
|
1719
1755
|
const u = T.point(r[l]);
|
|
@@ -1734,7 +1770,7 @@ class F {
|
|
|
1734
1770
|
R.info("[%s] parse line with %j", e == null ? void 0 : e.requestId, t.properties);
|
|
1735
1771
|
const n = t.properties || {};
|
|
1736
1772
|
if (n.shape == "line") {
|
|
1737
|
-
const s =
|
|
1773
|
+
const s = x.utc();
|
|
1738
1774
|
n.id = (n == null ? void 0 : n.id) || s.valueOf().toString();
|
|
1739
1775
|
const o = n == null ? void 0 : n.id, i = t.geometry.coordinates.map((c, a) => {
|
|
1740
1776
|
const l = `point_${a}`, u = T.point(c);
|
|
@@ -1755,7 +1791,7 @@ class F {
|
|
|
1755
1791
|
R.info("[%s] parse polygon with %j", e == null ? void 0 : e.requestId, t.properties);
|
|
1756
1792
|
const n = t.properties || {};
|
|
1757
1793
|
if (n.shape == "polygon") {
|
|
1758
|
-
const s =
|
|
1794
|
+
const s = x.utc();
|
|
1759
1795
|
n.id = (n == null ? void 0 : n.id) || s.valueOf().toString();
|
|
1760
1796
|
const o = n == null ? void 0 : n.id, i = t.geometry.coordinates[0].map((c, a) => {
|
|
1761
1797
|
const l = T.point(c), u = `corner_${a}`;
|
|
@@ -1802,33 +1838,33 @@ class F {
|
|
|
1802
1838
|
for (; l < u; ) {
|
|
1803
1839
|
if (s.getUint32(l, !0) !== 33639248)
|
|
1804
1840
|
throw new Error(`Invalid ZIP file: Central Directory signature mismatch at offset ${l}`);
|
|
1805
|
-
const p = s.getUint16(l + 10, !0), f = s.getUint32(l + 20, !0), g = s.getUint16(l + 28, !0),
|
|
1841
|
+
const p = s.getUint16(l + 10, !0), f = s.getUint32(l + 20, !0), g = 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 + g), M = new TextDecoder().decode(y), O = s.getUint16(N + 26, !0), U = s.getUint16(N + 28, !0), E = N + 30 + O + U, B = o.slice(E, E + f);
|
|
1806
1842
|
if (p === 0)
|
|
1807
|
-
r.set(M,
|
|
1843
|
+
r.set(M, B);
|
|
1808
1844
|
else if (p === 8) {
|
|
1809
1845
|
if (typeof DecompressionStream < "u") {
|
|
1810
|
-
const
|
|
1811
|
-
|
|
1812
|
-
const
|
|
1813
|
-
let
|
|
1846
|
+
const k = new DecompressionStream("deflate-raw"), b = k.writable.getWriter(), I = k.readable.getReader();
|
|
1847
|
+
b.write(B), b.close();
|
|
1848
|
+
const W = [];
|
|
1849
|
+
let j = 0;
|
|
1814
1850
|
for (; ; ) {
|
|
1815
|
-
const { done:
|
|
1816
|
-
if (
|
|
1851
|
+
const { done: w, value: D } = await I.read();
|
|
1852
|
+
if (w)
|
|
1817
1853
|
break;
|
|
1818
|
-
|
|
1854
|
+
W.push(D), j += D.length;
|
|
1819
1855
|
}
|
|
1820
|
-
const
|
|
1856
|
+
const Z = new Uint8Array(j);
|
|
1821
1857
|
let A = 0;
|
|
1822
|
-
for (const
|
|
1823
|
-
|
|
1824
|
-
r.set(M,
|
|
1858
|
+
for (const w of W)
|
|
1859
|
+
Z.set(w, A), A += w.length;
|
|
1860
|
+
r.set(M, Z);
|
|
1825
1861
|
} else if (typeof process < "u" && ((m = process.versions) != null && m.node))
|
|
1826
1862
|
try {
|
|
1827
|
-
r.set(M, F._inflateRawSync(
|
|
1863
|
+
r.set(M, F._inflateRawSync(B));
|
|
1828
1864
|
} catch {
|
|
1829
1865
|
}
|
|
1830
1866
|
}
|
|
1831
|
-
l += 46 + g +
|
|
1867
|
+
l += 46 + g + S + P;
|
|
1832
1868
|
}
|
|
1833
1869
|
return r;
|
|
1834
1870
|
}
|
|
@@ -1847,36 +1883,36 @@ class F {
|
|
|
1847
1883
|
const s = H().parseFromString(t, "application/xml"), o = Array.from(s.querySelectorAll("Placemark")), r = [];
|
|
1848
1884
|
for (const a of o) {
|
|
1849
1885
|
const l = {}, u = Array.from(a.querySelectorAll("ExtendedData > Data"));
|
|
1850
|
-
for (const
|
|
1851
|
-
const M =
|
|
1886
|
+
for (const y of u) {
|
|
1887
|
+
const M = y.getAttribute("name"), O = (c = (i = y.querySelector("value")) == null ? void 0 : i.textContent) == null ? void 0 : c.trim();
|
|
1852
1888
|
M && O !== void 0 && O !== null && (l[M] = O);
|
|
1853
1889
|
}
|
|
1854
|
-
const m =
|
|
1890
|
+
const m = x.utc(), h = Object.keys(l).find((y) => y.toLowerCase().indexOf("name") !== -1), p = h ? l[h] : void 0, f = `${m.valueOf().toString()}_${Math.random().toString(36).slice(2, 8)}`, g = (y) => y.trim().split(/[\s\n]+/).filter((M) => M.length > 0).map((M) => {
|
|
1855
1891
|
const O = M.split(",").map(Number);
|
|
1856
1892
|
return [O[0], O[1]];
|
|
1857
|
-
}),
|
|
1858
|
-
if (
|
|
1859
|
-
const
|
|
1860
|
-
if (
|
|
1861
|
-
const M = T.lineString(
|
|
1893
|
+
}), S = a.querySelector("LineString > coordinates");
|
|
1894
|
+
if (S) {
|
|
1895
|
+
const y = g(S.textContent || "");
|
|
1896
|
+
if (y.length >= 2) {
|
|
1897
|
+
const M = T.lineString(y, { ...l, shape: "line", id: f, name: p });
|
|
1862
1898
|
r.push(M);
|
|
1863
1899
|
}
|
|
1864
1900
|
continue;
|
|
1865
1901
|
}
|
|
1866
|
-
const
|
|
1867
|
-
if (
|
|
1868
|
-
const
|
|
1869
|
-
if (
|
|
1870
|
-
const M =
|
|
1902
|
+
const P = a.querySelector("Polygon outerBoundaryIs LinearRing > coordinates");
|
|
1903
|
+
if (P) {
|
|
1904
|
+
const y = g(P.textContent || "");
|
|
1905
|
+
if (y.length >= 4) {
|
|
1906
|
+
const M = y[0][0] === y[y.length - 1][0] && y[0][1] === y[y.length - 1][1] ? y : [...y, y[0]], O = T.polygon([M], { ...l, shape: "polygon", id: f, name: p });
|
|
1871
1907
|
r.push(O);
|
|
1872
1908
|
}
|
|
1873
1909
|
continue;
|
|
1874
1910
|
}
|
|
1875
|
-
const
|
|
1876
|
-
if (
|
|
1877
|
-
const
|
|
1878
|
-
if (
|
|
1879
|
-
const M = T.point(
|
|
1911
|
+
const N = a.querySelector("Point > coordinates");
|
|
1912
|
+
if (N) {
|
|
1913
|
+
const y = g(N.textContent || "");
|
|
1914
|
+
if (y.length >= 1) {
|
|
1915
|
+
const M = T.point(y[0], { ...l, shape: "point", id: f, name: p });
|
|
1880
1916
|
r.push(M);
|
|
1881
1917
|
}
|
|
1882
1918
|
continue;
|
|
@@ -1936,7 +1972,7 @@ class F {
|
|
|
1936
1972
|
typeof Buffer < "u" && Buffer.isBuffer(t) && (t = F.toArrayBuffer(t));
|
|
1937
1973
|
const n = await J(t);
|
|
1938
1974
|
if (Array.isArray(n)) {
|
|
1939
|
-
const s = n.flatMap((c) => c.features || []), o =
|
|
1975
|
+
const s = n.flatMap((c) => c.features || []), o = x.utc(), r = (e == null ? void 0 : e.id) || o.valueOf().toString(), i = {
|
|
1940
1976
|
Point: "point",
|
|
1941
1977
|
MultiPoint: "point",
|
|
1942
1978
|
LineString: "line",
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
(function(I,X){typeof exports=="object"&&typeof module<"u"?X(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"],X):(I=typeof globalThis<"u"?globalThis:I||self,X(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,X,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=_(X);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 G;try{G=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(`
|
|
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(`
|
|
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=t[f],
|
|
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(x.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,S)=>S>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 S=t[m],P=[];P.push((m+1).toString()),P.push(S.lat.toFixed(s)),P.push(S.lng.toFixed(s)),o&&P.push(S.name??""),r&&P.push(S.description??""),u&&P.push(m===0?"":S.gcToPrevious?"GC":"RL"),g&&P.push(S.bearing!=null?String(S.bearing):""),h&&P.push(S.distanceFromPrevious!=null?String(S.distanceFromPrevious):""),l&&P.push(S.speed!=null?String(S.speed):""),i&&P.push(S.port!=null?String(S.port):""),c&&P.push(S.stbd!=null?String(S.stbd):""),a&&P.push(S.arrRad!=null?String(S.arrRad):""),f.push(P.map(N=>b.csvEscapeField(N)).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=[],S=t[f],P=String(f).padStart(3,"0");m.push(P);const N=d.lat2pretty(S.lat,6),y=d.lng2pretty(S.lng,6),C=N.H,k=Number(N.minute).toFixed(s),B=N.direction;m.push(C),m.push(k),m.push(B);const U=y.H,j=Number(y.minute).toFixed(s),w=y.direction;if(m.push(U),m.push(j),m.push(w),r){const v=f===0?"***":S.port!=null?String(S.port):"***";m.push(v)}if(i){const v=f===0?"***":S.stbd!=null?String(S.stbd):"***";m.push(v)}if(c){const v=f===0?"***":S.arrRad!=null?String(S.arrRad):"***";m.push(v)}if(a){const v=f===0?"***":S.speed!=null?Number(S.speed).toFixed(1).padStart(5,"0"):"***";m.push(v)}if(l){const v=f===0?"***":S.gcToPrevious?"GC":"RL";m.push(v)}if(u){const v=f===0?"***":S.rot!=null?String(S.rot):"***";m.push(v)}if(g){const v=f===0?"***":S.turnRad!=null?String(S.turnRad):"***";m.push(v)}if(o){const v=f===0?"***":S.name??"";m.push(v)}p.push(m.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(v=>v.name),i=t.some(v=>v.description),c=t.some(v=>v.port!=null),a=t.some(v=>v.stbd!=null),l=t.some(v=>v.arrRad!=null),u=t.some(v=>v.speed!=null),g=t.some((v,O)=>O>0&&v.gcToPrevious!=null),h=t.some(v=>v.bearing!=null),p=t.some(v=>v.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=v=>v==null?"":String(v).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");let P=`<row r="1">${f.map((v,O)=>`<c r="${V(O)}1" s="1" t="inlineStr"><is><t>${m(v)}</t></is></c>`).join("")}</row>`;for(let v=0;v<t.length;v++){const O=t[v],q=v+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,v+1),E(1,d.lat2pretty(O.lat,s).pretty),E(2,d.lng2pretty(O.lng,s).pretty);let R=3;r&&(E(R,O.name??""),R++),i&&(E(R,O.description??""),R++),g&&(E(R,v===0?"":O.gcToPrevious?"GC":"RL"),R++),h&&(A(R,O.bearing),R++),p&&(A(R,O.distanceFromPrevious),R++),u&&(A(R,O.speed),R++),c&&(A(R,O.port),R++),a&&(A(R,O.stbd),R++),l&&(A(R,O.arrRad),R++),P+=`<row r="${q}">${W.join("")}</row>`}const N="0."+"0".repeat(s),y='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>'+P+"</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>',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>',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="'+N+'"/></numFmts><fonts count="2"><font><sz val="11"/><name val="Arial"/></font><font><b/><sz val="11"/><name val="Arial"/></font></fonts><fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills><borders count="2"><border><left/><right/><top/><bottom/><diagonal/></border><border><bottom style="thin"><color auto="1"/></bottom></border></borders><cellStyleXfs count="1"><xf/></cellStyleXfs><cellXfs count="3"><xf/><xf fontId="1" fillId="0" borderId="1" applyFont="1" applyBorder="1"/><xf numFmtId="164" fontId="0" applyNumberFormat="1"/></cellXfs></styleSheet>',w=new TextEncoder;return te([{name:"[Content_Types].xml",data:w.encode(C)},{name:"_rels/.rels",data:w.encode(k)},{name:"xl/workbook.xml",data:w.encode(B)},{name:"xl/_rels/workbook.xml.rels",data:w.encode(U)},{name:"xl/worksheets/sheet1.xml",data:w.encode(y)},{name:"xl/styles.xml",data:w.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)?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){G==null||G.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)),k=this.computeNumber(S==null?void 0:S.geometry.coordinates[0],P.geometry.coordinates[0],C),q=this.computeNumber(S==null?void 0:S.geometry.coordinates[1],P.geometry.coordinates[1],C),U=T.point([k,q],{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 E{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),k=s.getUint16(P+26,!0),q=s.getUint16(P+28,!0),U=P+30+k+q,W=o.slice(U,U+f);if(p===0)r.set(C,W);else if(p===8){if(typeof DecompressionStream<"u"){const A=new DecompressionStream("deflate-raw"),N=A.writable.getWriter(),O=A.readable.getReader();N.write(W),N.close();const B=[];let j=0;for(;;){const{done:w,value:R}=await O.read();if(w)break;B.push(R),j+=R.length}const L=new Uint8Array(j);let F=0;for(const w of B)L.set(w,F),F+=w.length;r.set(C,L)}else if(typeof process<"u"&&((g=process.versions)!=null&&g.node))try{r.set(C,E._inflateRawSync(W))}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"),k=(c=(i=S.querySelector("value"))==null?void 0:i.textContent)==null?void 0:c.trim();C&&k!==void 0&&k!==null&&(l[C]=k)}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 k=C.split(",").map(Number);return[k[0],k[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]],k=T.polygon([C],{...l,shape:"polygon",id:f,name:p});r.push(k)}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=E.toArrayBuffer(e));const n=await E._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 E.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=E.toArrayBuffer(e));const n=await E._parseZipEntries(e),s=[];for(const[o,r]of n){if(!o.toLowerCase().endsWith(".kml"))continue;const i=new TextDecoder().decode(r),c=await E.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=E.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([])}}}I.AisHelper=K,I.GeoJsonHelper=E,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)?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"})});
|