@idm-plugin/geo 1.2.3 → 1.2.4
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 +97 -91
- package/dist/index.umd.cjs +1 -1
- package/dist/tropicals/src/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as g from "@turf/turf";
|
|
2
2
|
import D from "moment";
|
|
3
3
|
import "moment-timezone";
|
|
4
|
-
import
|
|
5
|
-
function
|
|
6
|
-
return
|
|
4
|
+
import W from "tz-lookup";
|
|
5
|
+
function E(C) {
|
|
6
|
+
return C && C.__esModule && Object.prototype.hasOwnProperty.call(C, "default") ? C.default : C;
|
|
7
7
|
}
|
|
8
8
|
class R {
|
|
9
9
|
log() {
|
|
@@ -18,21 +18,21 @@ class R {
|
|
|
18
18
|
clearContext() {
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
["Trace", "Debug", "Info", "Warn", "Error", "Fatal", "Mark"].forEach((
|
|
22
|
-
R.prototype[
|
|
23
|
-
}, R.prototype[`is${
|
|
21
|
+
["Trace", "Debug", "Info", "Warn", "Error", "Fatal", "Mark"].forEach((C) => {
|
|
22
|
+
R.prototype[C.toLowerCase()] = () => {
|
|
23
|
+
}, R.prototype[`is${C}Enabled`] = () => !1;
|
|
24
24
|
});
|
|
25
|
-
const
|
|
25
|
+
const j = () => {
|
|
26
26
|
try {
|
|
27
27
|
return require("log4js");
|
|
28
28
|
} catch {
|
|
29
29
|
return null;
|
|
30
30
|
}
|
|
31
|
-
},
|
|
32
|
-
var
|
|
33
|
-
getLogger:
|
|
31
|
+
}, y = j(), k = y ? y.getLogger : () => new R();
|
|
32
|
+
var A = {
|
|
33
|
+
getLogger: k
|
|
34
34
|
};
|
|
35
|
-
const
|
|
35
|
+
const F = /* @__PURE__ */ E(A);
|
|
36
36
|
class l {
|
|
37
37
|
/**
|
|
38
38
|
* 基于输入的经度,计算出时区
|
|
@@ -40,7 +40,7 @@ class l {
|
|
|
40
40
|
* @param lat
|
|
41
41
|
*/
|
|
42
42
|
static guessTimeZoneOffset(e, t) {
|
|
43
|
-
const n =
|
|
43
|
+
const n = W(t, e), i = D().tz(n).utcOffset();
|
|
44
44
|
return this.roundPrecision(i / 60, 1);
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
@@ -58,13 +58,13 @@ class l {
|
|
|
58
58
|
e < 0 && (i = "W"), e = Math.abs(e), n = n.toUpperCase();
|
|
59
59
|
let o = e * 3600, s, r, c, a, d, u;
|
|
60
60
|
s = o % 3600 % 60, n.indexOf("S") !== -1 && (o = o - s, r = l.padNumber(s, 2, 2)), c = o / 60 % 60, n.indexOf("M") !== -1 && (n.indexOf("S") !== -1 ? a = l.roundPrecision(c, t).toString().padStart(2, "0") : a = l.padNumber(c, 2, 2), o = o - c * 60), d = o / 3600, n.indexOf("M") !== -1 ? u = l.roundPrecision(d, t).toString().padStart(3, "0") : u = l.padNumber(d, 3, 2);
|
|
61
|
-
const
|
|
61
|
+
const p = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${i}`;
|
|
62
62
|
return {
|
|
63
63
|
direction: i,
|
|
64
64
|
degree: l.roundPrecision(d, t),
|
|
65
65
|
minute: l.roundPrecision(c, t),
|
|
66
66
|
second: l.roundPrecision(s, t),
|
|
67
|
-
pretty:
|
|
67
|
+
pretty: p
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
@@ -79,13 +79,13 @@ class l {
|
|
|
79
79
|
e < 0 && (i = "S"), e = Math.abs(e), n = n.toUpperCase();
|
|
80
80
|
let o = e * 3600, s, r, c, a, d, u;
|
|
81
81
|
s = o % 3600 % 60, n.indexOf("S") !== -1 && (o = o - s, r = l.padNumber(s, 2, 2)), c = o / 60 % 60, n.indexOf("M") !== -1 && (n.indexOf("S") !== -1 ? a = l.roundPrecision(c, t).toString().padStart(2, "0") : a = l.padNumber(c, 2, 2), o = o - c * 60), d = o / 3600, n.indexOf("M") !== -1 ? u = l.roundPrecision(d, t).toString().padStart(2, "0") : u = l.padNumber(d, 2, 2);
|
|
82
|
-
const
|
|
82
|
+
const p = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${i}`;
|
|
83
83
|
return {
|
|
84
84
|
direction: i,
|
|
85
85
|
degree: l.roundPrecision(d, t),
|
|
86
86
|
minute: l.roundPrecision(c, t),
|
|
87
87
|
second: l.roundPrecision(s, t),
|
|
88
|
-
pretty:
|
|
88
|
+
pretty: p
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
static str2Lng(e, t = 6) {
|
|
@@ -182,7 +182,7 @@ class l {
|
|
|
182
182
|
return `${i}.${o}`;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
class
|
|
185
|
+
class P {
|
|
186
186
|
/**
|
|
187
187
|
* 计算方位角
|
|
188
188
|
* @param from 坐标 {lng, lat}
|
|
@@ -297,14 +297,14 @@ class b {
|
|
|
297
297
|
[c > 0 ? 180 : -180, 89],
|
|
298
298
|
[c > 0 ? 180 : -180, -89]
|
|
299
299
|
])) : (d = g.greatCircle(a[0], a[1]), u = g.greatCircle([c > 0 ? 180 : -180, 89], [c > 0 ? 180 : -180, -89]));
|
|
300
|
-
const
|
|
301
|
-
let
|
|
302
|
-
if (
|
|
303
|
-
const S = g.getCoord(
|
|
304
|
-
|
|
300
|
+
const p = g.lineIntersect(d, u);
|
|
301
|
+
let h;
|
|
302
|
+
if (p.features.length) {
|
|
303
|
+
const S = g.getCoord(p.features[0]);
|
|
304
|
+
h = l.roundPrecision(S[1], 8);
|
|
305
305
|
} else
|
|
306
|
-
|
|
307
|
-
c > 0 ? (n.push([180 - 1e-6,
|
|
306
|
+
h = e[r].lat;
|
|
307
|
+
c > 0 ? (n.push([180 - 1e-6, h]), i.push([...n]), n = [], n.push([-(180 - 1e-6), h])) : (n.push([-(180 - 1e-6), h]), i.push([...n]), n = [], n.push([180 - 1e-6, h]));
|
|
308
308
|
}
|
|
309
309
|
r === e.length - 2 && n.push([s, e[r + 1].lat]);
|
|
310
310
|
}
|
|
@@ -368,8 +368,8 @@ class b {
|
|
|
368
368
|
let n = Number.MAX_VALUE, i = 0, o = 0, s, r;
|
|
369
369
|
return t.forEach((c, a) => {
|
|
370
370
|
for (let d = 0; d < c.length - 1; d++) {
|
|
371
|
-
const u = { lng: c[d][0], lat: c[d][1] },
|
|
372
|
-
n >
|
|
371
|
+
const u = { lng: c[d][0], lat: c[d][1] }, p = { lng: c[d + 1][0], lat: c[d + 1][1] }, h = this.calculatePointToLineDistance(e, u, p);
|
|
372
|
+
n > h && (n = h, o = d, i = a, s = this.calculateDistance(u, e), r = this.calculateDistance(p, e));
|
|
373
373
|
}
|
|
374
374
|
}), s !== 0 && r !== 0 ? t[i].splice(o + 1, 0, [e.lng, e.lat]) : s === 0 ? t[i].splice(o, 1, [e.lng, e.lat]) : r === 0 && t[i].splice(o + 1, 1, [e.lng, e.lat]), t;
|
|
375
375
|
}
|
|
@@ -380,8 +380,8 @@ class b {
|
|
|
380
380
|
*/
|
|
381
381
|
static appendCoordinateToRoute(e, t) {
|
|
382
382
|
e.lng = l.convertToStdLng(e.lng, 8);
|
|
383
|
-
const n =
|
|
384
|
-
return n.push(e),
|
|
383
|
+
const n = P.convertRouteToCoordinates(t);
|
|
384
|
+
return n.push(e), P.divideAccordingToLng(n);
|
|
385
385
|
}
|
|
386
386
|
/**
|
|
387
387
|
* 向route头加1个坐标
|
|
@@ -389,8 +389,8 @@ class b {
|
|
|
389
389
|
* @param route
|
|
390
390
|
*/
|
|
391
391
|
static unshiftCoordinateToRoute(e, t) {
|
|
392
|
-
const n =
|
|
393
|
-
return n.unshift(e),
|
|
392
|
+
const n = P.convertRouteToCoordinates(t);
|
|
393
|
+
return n.unshift(e), P.divideAccordingToLng(n);
|
|
394
394
|
}
|
|
395
395
|
/**
|
|
396
396
|
* 合并多个waypoints进航线
|
|
@@ -624,39 +624,39 @@ class b {
|
|
|
624
624
|
* @return { coordinate: {lng, lat}, route: [[[lng, lat]]]}
|
|
625
625
|
*/
|
|
626
626
|
static calculateNextCoordinateAlongRoute(e, t, n, i = "nauticalmiles") {
|
|
627
|
-
var
|
|
627
|
+
var p;
|
|
628
628
|
const o = e.speed || 12, s = [];
|
|
629
629
|
let r = [], c = !1, a = 0, d = 0, u;
|
|
630
|
-
if (t && n.length ? (s.push(e), n.forEach((
|
|
630
|
+
if (t && n.length ? (s.push(e), n.forEach((h, S) => {
|
|
631
631
|
if (c)
|
|
632
|
-
r.push(
|
|
632
|
+
r.push(h);
|
|
633
633
|
else {
|
|
634
|
-
const
|
|
635
|
-
let
|
|
636
|
-
for (let
|
|
634
|
+
const v = [];
|
|
635
|
+
let b;
|
|
636
|
+
for (let T = 0; T < h.length; T++)
|
|
637
637
|
if (u)
|
|
638
|
-
|
|
638
|
+
v.push(h[T]);
|
|
639
639
|
else {
|
|
640
|
-
|
|
641
|
-
const
|
|
642
|
-
if (a +=
|
|
643
|
-
d +=
|
|
640
|
+
b = { lng: h[T][0], lat: h[T][1] };
|
|
641
|
+
const m = this.calculateDistance(e, b, !0, 8, i);
|
|
642
|
+
if (a += m, a < t)
|
|
643
|
+
d += m, s.push(b), e = b;
|
|
644
644
|
else {
|
|
645
645
|
if (d = t, a === t)
|
|
646
|
-
u =
|
|
646
|
+
u = b, v.push([u.lng, u.lat]);
|
|
647
647
|
else {
|
|
648
|
-
const
|
|
649
|
-
u = this.calculateCoordinate(
|
|
648
|
+
const f = a - t, M = this.calculateBearing(b, e);
|
|
649
|
+
u = this.calculateCoordinate(b, M, f, i), v.push([u.lng, u.lat]), v.push([b.lng, b.lat]);
|
|
650
650
|
}
|
|
651
651
|
c = !0;
|
|
652
652
|
}
|
|
653
653
|
}
|
|
654
|
-
|
|
654
|
+
v.length && r.push(v), S === n.length - 1 && !u && (u = b);
|
|
655
655
|
}
|
|
656
656
|
})) : (r = n, u = { ...e }), u)
|
|
657
|
-
if (s.push(u), u.distanceFromPrevious = d, u.hourFromPrevious = Math.round(d / o * 1e4) / 1e4, ((
|
|
658
|
-
const
|
|
659
|
-
u.bearing = this.calculateBearing(u,
|
|
657
|
+
if (s.push(u), u.distanceFromPrevious = d, u.hourFromPrevious = Math.round(d / o * 1e4) / 1e4, ((p = r[0]) == null ? void 0 : p.length) > 1) {
|
|
658
|
+
const h = { lng: r[0][1][0], lat: r[0][1][1] };
|
|
659
|
+
u.bearing = this.calculateBearing(u, h);
|
|
660
660
|
} else
|
|
661
661
|
u.bearing = 0;
|
|
662
662
|
return { coordinate: u, nextRoute: r, prevRoute: s };
|
|
@@ -671,8 +671,8 @@ class b {
|
|
|
671
671
|
const i = l.convertToStdLng(e.lng, 6), o = g.point([i, e.lat]), s = l.convertToStdLng(t.lng, 6), r = l.convertToStdLng(n.lng, 6), c = g.lineString([
|
|
672
672
|
[s, t.lat],
|
|
673
673
|
[r, n.lat]
|
|
674
|
-
]), a = g.nearestPointOnLine(c, o), d = g.getCoord(a), u = l.roundPrecision(d[0], 6),
|
|
675
|
-
return { lng: u, lat:
|
|
674
|
+
]), a = g.nearestPointOnLine(c, o), d = g.getCoord(a), u = l.roundPrecision(d[0], 6), p = l.roundPrecision(d[1], 6);
|
|
675
|
+
return { lng: u, lat: p, inline: !(u === s && p === t.lat) && !(u === r && p === n.lat) };
|
|
676
676
|
}
|
|
677
677
|
/**
|
|
678
678
|
* 将route转coordinate
|
|
@@ -775,8 +775,8 @@ class b {
|
|
|
775
775
|
return this.calculateBBox(t);
|
|
776
776
|
}
|
|
777
777
|
}
|
|
778
|
-
const
|
|
779
|
-
class
|
|
778
|
+
const N = F.getLogger("vessel");
|
|
779
|
+
class q {
|
|
780
780
|
/**
|
|
781
781
|
* 将原始数据转换为geojson
|
|
782
782
|
* @param raw
|
|
@@ -806,12 +806,12 @@ class O {
|
|
|
806
806
|
for (const d in s == null ? void 0 : s.hours) {
|
|
807
807
|
const u = s.hours[d];
|
|
808
808
|
u.wind.spd = u.wind.spd || u.wind.speed;
|
|
809
|
-
const
|
|
809
|
+
const p = c.clone().add(Number(d), "hour"), h = g.point([u.lng, u.lat], {
|
|
810
810
|
model: s.model,
|
|
811
811
|
name: i.name,
|
|
812
|
-
date:
|
|
812
|
+
date: p.format(),
|
|
813
813
|
hour: Number(d),
|
|
814
|
-
format:
|
|
814
|
+
format: p.format("MMM-DD/HHmm[Z]"),
|
|
815
815
|
pressure: u.pressure > 1e4 ? l.roundPrecision(u.pressure / 100, 0) : l.roundPrecision(u.pressure, 0),
|
|
816
816
|
gusts: u.gusts,
|
|
817
817
|
wind: u.wind || {},
|
|
@@ -819,7 +819,7 @@ class O {
|
|
|
819
819
|
category: a,
|
|
820
820
|
type: "forecast"
|
|
821
821
|
});
|
|
822
|
-
t.features.push(
|
|
822
|
+
t.features.push(h), r.push(h.geometry.coordinates);
|
|
823
823
|
}
|
|
824
824
|
if ((r == null ? void 0 : r.length) > 1) {
|
|
825
825
|
const d = g.lineString(l.convertToMonotonicLng2(r), {
|
|
@@ -878,31 +878,31 @@ class O {
|
|
|
878
878
|
var o, s, r, c;
|
|
879
879
|
const n = (o = e == null ? void 0 : e.data) == null ? void 0 : o.features.filter((a) => a.geometry.type === "LineString" && a.properties.type === "forecast"), i = [];
|
|
880
880
|
for (const a of n) {
|
|
881
|
-
const d = a.properties.name, u = a.properties.model,
|
|
882
|
-
let
|
|
883
|
-
const
|
|
881
|
+
const d = a.properties.name, u = a.properties.model, p = a.properties.showCircle, h = D(a.properties.date).utc();
|
|
882
|
+
let S = t * 60 - (h.get("hour") * 60 + h.get("minute")) % (t * 60);
|
|
883
|
+
const v = (s = e == null ? void 0 : e.data) == null ? void 0 : s.features.filter(
|
|
884
884
|
(m) => m.geometry.type === "Point" && m.properties.type === "forecast" && m.properties.category === `${d}-${u}`
|
|
885
885
|
);
|
|
886
|
-
let
|
|
887
|
-
for (;
|
|
888
|
-
if (
|
|
889
|
-
const m =
|
|
886
|
+
let b, T = h.clone().add(S, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
887
|
+
for (; b = this.pickIndex(v, T), b <= v.length - 1; ) {
|
|
888
|
+
if (b > 0) {
|
|
889
|
+
const m = v[b], f = b === 0 ? void 0 : v[b - 1], M = (S / 60 - ((r = f == null ? void 0 : f.properties) == null ? void 0 : r.hour)) / (m.properties.hour - ((c = f == null ? void 0 : f.properties) == null ? void 0 : c.hour)), I = this.computeNumber(f == null ? void 0 : f.geometry.coordinates[0], m.geometry.coordinates[0], M), x = this.computeNumber(f == null ? void 0 : f.geometry.coordinates[1], m.geometry.coordinates[1], M), $ = g.point([I, x], {
|
|
890
890
|
name: d,
|
|
891
891
|
model: u,
|
|
892
892
|
category: m == null ? void 0 : m.properties.category,
|
|
893
893
|
date: T.format(),
|
|
894
894
|
format: T.format("MMM-DD/HHmm[Z]"),
|
|
895
|
-
gusts: this.computeNumber(
|
|
896
|
-
hour: this.computeNumber(
|
|
897
|
-
movement: this.computeNumber(
|
|
898
|
-
pressure: this.computeNumber(
|
|
899
|
-
wind: this.computeNumber(
|
|
895
|
+
gusts: this.computeNumber(f == null ? void 0 : f.properties.gusts, m.properties.gusts, M),
|
|
896
|
+
hour: this.computeNumber(f == null ? void 0 : f.properties.hour, m.properties.hour, M),
|
|
897
|
+
movement: this.computeNumber(f == null ? void 0 : f.properties.movement, m.properties.movement, M),
|
|
898
|
+
pressure: this.computeNumber(f == null ? void 0 : f.properties.pressure, m.properties.pressure, M),
|
|
899
|
+
wind: this.computeNumber(f == null ? void 0 : f.properties.wind, m.properties.wind, M),
|
|
900
900
|
type: "forecast",
|
|
901
|
-
showCircle:
|
|
901
|
+
showCircle: p
|
|
902
902
|
});
|
|
903
|
-
i.push(
|
|
903
|
+
i.push($);
|
|
904
904
|
}
|
|
905
|
-
|
|
905
|
+
S += t * 60, T = h.clone().add(S, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
906
906
|
}
|
|
907
907
|
}
|
|
908
908
|
return i;
|
|
@@ -919,18 +919,18 @@ class O {
|
|
|
919
919
|
* @param options
|
|
920
920
|
*/
|
|
921
921
|
static diversionPassageAt(e, t, n, i, o = { requestId: "" }) {
|
|
922
|
-
var a, d, u,
|
|
922
|
+
var a, d, u, p;
|
|
923
923
|
const { t1: s, t2: r, hr: c } = this.tropicalCenterTwin(t, 24, o);
|
|
924
924
|
if (s && r) {
|
|
925
|
-
const
|
|
926
|
-
|
|
927
|
-
const
|
|
928
|
-
let
|
|
929
|
-
|
|
930
|
-
const
|
|
931
|
-
return
|
|
925
|
+
const h = P.calculateBearing(e, s), S = P.calculateBearing(s, r), v = P.calculateCoordinate(s, h - S + 90, n);
|
|
926
|
+
N.info("[%s] the right tangent position: %j", o.requestId, { from: e, t1: s, t2: r, radius: n, bearing1: h, bearing2: S, right: v });
|
|
927
|
+
const b = P.calculateBearing(e, v);
|
|
928
|
+
let T = P.calculateCoordinate(e, b, i * Number(c));
|
|
929
|
+
T.utc = D((d = (a = t == null ? void 0 : t.forecasts) == null ? void 0 : a[0]) == null ? void 0 : d.date).add(Number(c), "hours").utc().format(), N.info("[%s] the diversion position: %j", o.requestId, T);
|
|
930
|
+
const m = P.calculateDistance(T, r);
|
|
931
|
+
return N.info("[%s] the distance(%d) between the diversion position & t2: %j - %j", o.requestId, m, T, r), m < n && (T = P.calculateCoordinate(e, b, i * Number(c) / 2), T.utc = D((p = (u = t == null ? void 0 : t.forecasts) == null ? void 0 : u[0]) == null ? void 0 : p.date).add(Number(c) / 2, "hours").utc().format(), N.warn("[%s] the prev diversion position is too close to t2, replace with 1/2 position: %j", o.requestId, T)), T;
|
|
932
932
|
} else {
|
|
933
|
-
|
|
933
|
+
N.info("[%s] no need to diversion: %j", o.requestId, { from: e, t1: s, t2: r });
|
|
934
934
|
return;
|
|
935
935
|
}
|
|
936
936
|
}
|
|
@@ -947,26 +947,32 @@ class O {
|
|
|
947
947
|
static driftPassageAt(e, t, n, i = { requestId: "" }) {
|
|
948
948
|
const { t1: o, t2: s, hr: r } = this.tropicalCenterTwin(t, 24, i);
|
|
949
949
|
if (o && s) {
|
|
950
|
-
const c =
|
|
951
|
-
return
|
|
950
|
+
const c = P.calculateBearing(e, o), a = P.calculateBearing(o, s);
|
|
951
|
+
return P.calculateCoordinate(o, c - a + 180, n);
|
|
952
952
|
} else {
|
|
953
|
-
|
|
953
|
+
N.info("[%s] no need drift: %j", i.requestId, { from: e, t1: o, t2: s });
|
|
954
954
|
return;
|
|
955
955
|
}
|
|
956
956
|
}
|
|
957
957
|
/**
|
|
958
|
-
*
|
|
958
|
+
* 获取台风中心点对
|
|
959
959
|
* @param tropical { history: any[], forecasts: any[] }
|
|
960
960
|
* @param hrs 未来小时数,默认24
|
|
961
961
|
* @param options
|
|
962
962
|
* @private
|
|
963
963
|
*/
|
|
964
964
|
static tropicalCenterTwin(e, t = 24, n = { requestId: "" }) {
|
|
965
|
-
var c, a, d, u,
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
965
|
+
var c, a, d, u, p;
|
|
966
|
+
let i = {};
|
|
967
|
+
(c = e.forecasts) == null || c.forEach((h) => {
|
|
968
|
+
i = { ...h.hours, ...i };
|
|
969
|
+
});
|
|
970
|
+
const o = ((a = e == null ? void 0 : e.history) == null ? void 0 : a[0]) || (i == null ? void 0 : i[(d = Object.keys(i)) == null ? void 0 : d[0]]);
|
|
971
|
+
N.info("[%s] the first tropical center: %j", n.requestId, o);
|
|
972
|
+
let s = (u = Object.keys(i || {}).filter((h) => Number(h) <= (t < 0 ? 24 : t))) == null ? void 0 : u.at(-1);
|
|
973
|
+
s || (s = (p = Object.keys(i || {}).filter((h) => Number(h) <= (t < 0 ? 24 : 2 * t))) == null ? void 0 : p.at(-1));
|
|
974
|
+
const r = i == null ? void 0 : i[s || -1];
|
|
975
|
+
return N.info("[%s] the second tropical center: %j in %d hrs", n.requestId, r, s), { t1: o, t2: r, hr: s };
|
|
970
976
|
}
|
|
971
977
|
static pickIndex(e, t) {
|
|
972
978
|
let n = 0;
|
|
@@ -994,7 +1000,7 @@ class O {
|
|
|
994
1000
|
}
|
|
995
1001
|
}
|
|
996
1002
|
export {
|
|
997
|
-
|
|
1003
|
+
P as LaneHelper,
|
|
998
1004
|
l as LngLatHelper,
|
|
999
|
-
|
|
1005
|
+
q as TropicalHelper
|
|
1000
1006
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(S,y){typeof exports=="object"&&typeof module<"u"?y(exports,require("@turf/turf"),require("moment"),require("moment-timezone"),require("tz-lookup")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","moment-timezone","tz-lookup"],y):(S=typeof globalThis<"u"?globalThis:S||self,y(S["idm-plugin-rabbitmq"]={},S["@turf/turf"],S.moment,S["moment-timezone"],S["tz-lookup"]))})(this,function(S,y,D,A,$){"use strict";function j(b){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(b){for(const t in b)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(b,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>b[t]})}}return e.default=b,Object.freeze(e)}const g=j(y);function k(b){return b&&b.__esModule&&Object.prototype.hasOwnProperty.call(b,"default")?b.default:b}class R{log(){}isLevelEnabled(){return!1}addContext(){}removeContext(){}clearContext(){}}["Trace","Debug","Info","Warn","Error","Fatal","Mark"].forEach(b=>{R.prototype[b.toLowerCase()]=()=>{},R.prototype[`is${b}Enabled`]=()=>!1});const x=(()=>{try{return require("log4js")}catch{return null}})();var L={getLogger:x?x.getLogger:()=>new R};const W=k(L);class l{static guessTimeZoneOffset(e,t){const n=$(t,e),i=D().tz(n).utcOffset();return this.roundPrecision(i/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=l.convertToStdLng(e,t);let i="E";e<0&&(i="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,s,r,c,a,d,u;s=o%3600%60,n.indexOf("S")!==-1&&(o=o-s,r=l.padNumber(s,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=l.roundPrecision(c,t).toString().padStart(2,"0"):a=l.padNumber(c,2,2),o=o-c*60),d=o/3600,n.indexOf("M")!==-1?u=l.roundPrecision(d,t).toString().padStart(3,"0"):u=l.padNumber(d,3,2);const h=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${i}`;return{direction:i,degree:l.roundPrecision(d,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(s,t),pretty:h}}static lat2pretty(e,t=6,n="H°M′"){e=e%180;let i="N";e<0&&(i="S"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,s,r,c,a,d,u;s=o%3600%60,n.indexOf("S")!==-1&&(o=o-s,r=l.padNumber(s,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=l.roundPrecision(c,t).toString().padStart(2,"0"):a=l.padNumber(c,2,2),o=o-c*60),d=o/3600,n.indexOf("M")!==-1?u=l.roundPrecision(d,t).toString().padStart(2,"0"):u=l.padNumber(d,2,2);const h=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${i}`;return{direction:i,degree:l.roundPrecision(d,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(s,t),pretty:h}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LNG");const i=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[s,r]=o;if(r=r>60?r/Math.pow(10,String(r).length-2):r,s>360&&!r){const c=this.roundPrecision(s/100,0);r=s-c*100,s=c}n=s+(r??0)/60,i==="W"&&(n=n*-1)}else n=Number(e);return l.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LAT");const i=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[s,r]=o;if(r=r>60?r/Math.pow(10,String(r).length-2):r,s>90&&!r){const c=this.roundPrecision(s/100,0);r=s-c*100,s=c}n=s+(r??0)/60,i==="S"&&(n=n*-1)}else n=Number(e);return l.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=l.strReplace(e,n);const i=e[e.length-1].toUpperCase();return["N","S"].includes(i)?{lat:l.str2Lat(e,t)}:{lng:l.str2Lng(e,t)}}static convertToStdLng(e,t=4){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),l.roundPrecision(e,t)}static roundPrecision(e,t=4){if(typeof e=="number"){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}return e}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(/-/g," ").replace(/°/," ").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 i=e,o=Number(i.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${e}`);o>=90?e=`${i}E`:o<=-90?e=`${i}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${i}${o>0?"E":"W"}`:e=`${i}${o>0?"N":"S"}`}return e}static padNumber(e,t=2,n=2){const i=Math.trunc(e).toString().padStart(t,"0"),o=Math.trunc(l.roundPrecision(e-Math.trunc(e),n)*Math.pow(10,n)).toString().padStart(n,"0");return`${i}.${o}`}}class P{static calculateBearing(e,t,n=!0,i=4){const o=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let s;return n?s=g.rhumbBearing(o.features[0],o.features[1]):s=g.bearing(o.features[0],o.features[1]),s<0&&(s+=360),l.roundPrecision(s,i)}static calculateDistance(e,t,n=!0,i=4,o="nauticalmiles"){e={...e},t={...t},e.lng=l.convertToStdLng(e.lng,i),t.lng=l.convertToStdLng(t.lng,i);const s=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=g.rhumbDistance(s.features[0],s.features[1],{units:o}):r=g.distance(s.features[0],s.features[1],{units:o}),l.roundPrecision(r,i)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let i=0,o;for(const s of e)for(let r=0;r<s.length-1;r++){const c={lng:s[r][0],lat:s[r][1]};r===0&&o&&(i+=this.calculateDistance(o,c,!0,t,n));const a={lng:s[r+1][0],lat:s[r+1][1]};i+=this.calculateDistance(c,a,!0,t,n),o=a}return l.roundPrecision(i,t)}static calculateCoordinate(e,t,n,i="nauticalmiles",o=!0){const s=g.point([e.lng,e.lat]);let r;o?r=g.rhumbDestination(s,n,t,{units:i}):r=g.destination(s,n,t,{units:i});const c=r.geometry.coordinates;return{lng:l.convertToStdLng(c[0],8),lat:l.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,i=!0,o=!0,s="nauticalmiles"){const r=[],c=this.calculateBearing(e,t,!1),a=this.calculateDistance(e,t,!1,8,s);i&&r.push({lng:e.lng,lat:e.lat});let d=0;for(;d<a;)d+=n,d<a&&r.push(this.calculateCoordinate(e,c,d,s,!1));return o&&r.push({lng:t.lng,lat:t.lat}),r}static divideAccordingToLng(e,t=!1){if((e==null?void 0:e.length)<2)return[];e=this.deduplicateCoordinates(e);let n=[];const i=[];let o,s;for(let r=0;r<e.length-1;r++){o=l.convertToStdLng(e[r].lng,8),s=l.convertToStdLng(e[r+1].lng,8),n.push([o,e[r].lat]);const c=o-s;if(Math.abs(c)>180){const a=l.convertToMonotonicLng2([[o,e[r].lat],[s,e[r+1].lat]]);let d,u;t?(d=g.lineString(a),u=g.lineString([[c>0?180:-180,89],[c>0?180:-180,-89]])):(d=g.greatCircle(a[0],a[1]),u=g.greatCircle([c>0?180:-180,89],[c>0?180:-180,-89]));const h=g.lineIntersect(d,u);let p;if(h.features.length){const C=g.getCoord(h.features[0]);p=l.roundPrecision(C[1],8)}else p=e[r].lat;c>0?(n.push([180-1e-6,p]),i.push([...n]),n=[],n.push([-(180-1e-6),p])):(n.push([-(180-1e-6),p]),i.push([...n]),n=[],n.push([180-1e-6,p]))}r===e.length-2&&n.push([s,e[r+1].lat])}return i.push(n),i}static deduplicateRoute(e){const t=[];for(const n of e){const i=n.reduce((o,s)=>(o.findIndex(r=>r[0]===s[0]&&r[1]===s[1])===-1&&o.push(s),o),[]);t.push(i)}return t}static deduplicateCoordinates(e){return e.reduce((t,n)=>(t.findIndex(i=>i.lat===n.lat&&i.lng===n.lng)===-1&&t.push(n),t),[])}static removeCoordinateFromRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);for(const n of t)for(let i=n.length-1;i>=0;i--)l.roundPrecision(n[i][0],8)===e.lng&&l.roundPrecision(n[i][1],8)===l.roundPrecision(e.lat,8)&&n.splice(i,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=l.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)l.roundPrecision(t[n].lng,8)===e.lng&&l.roundPrecision(t[n].lat,8)===l.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,i=0,o=0,s,r;return t.forEach((c,a)=>{for(let d=0;d<c.length-1;d++){const u={lng:c[d][0],lat:c[d][1]},h={lng:c[d+1][0],lat:c[d+1][1]},p=this.calculatePointToLineDistance(e,u,h);n>p&&(n=p,o=d,i=a,s=this.calculateDistance(u,e),r=this.calculateDistance(h,e))}}),s!==0&&r!==0?t[i].splice(o+1,0,[e.lng,e.lat]):s===0?t[i].splice(o,1,[e.lng,e.lat]):r===0&&t[i].splice(o+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);const n=P.convertRouteToCoordinates(t);return n.push(e),P.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=P.convertRouteToCoordinates(t);return n.unshift(e),P.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 i=[];let o=0;return n.forEach(s=>{if(o===2)return;const r=[];for(const c of s){if(l.roundPrecision(t.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(c[1],8)){r.push(c),o===0&&r.push([e.lng,e.lat]),o=2;break}o===1?r.push(c):l.roundPrecision(e.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(c[1],8)&&(o=1,r.push(c))}r.length&&i.push(r)}),i}static calculateRangeWaypoints(e,t,n,i=[]){const o=this.convertRouteToCoordinates(n,0),s=this.mergeCoordinatesToWaypoints([e,t,...i],o),r=s.findIndex(d=>l.roundPrecision(e.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(d.lat,8)),c=s.findIndex(d=>l.roundPrecision(t.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(d.lat,8));return s.filter((d,u)=>u>=r&&u<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,i=0,o=0;return t.forEach((s,r)=>{for(let c=0;c<s.length-1;c++){const a={lng:s[c][0],lat:s[c][1]},d={lng:s[c+1][0],lat:s[c+1][1]},u=this.calculatePointToLineDistance(e,a,d);n>u&&(n=u,i=c,o=r)}}),{minDist:n,segIndex:o,minIndex:i}}static calculateSubRoute(e,t){const{segIndex:n,minIndex:i}=this.calculateMinDistanceToRoute({...e},t);e.lng=l.convertToStdLng(e.lng);const o=[];let s=!0;for(let r=n;r<t.length;r++)if(s){const c=[];c.push([e.lng,e.lat]);for(let a=i+1;a<t[r].length;a++)e.lng===t[r][a][0]&&e.lat===t[r][a][1]||c.push(t[r][a]);o.push(c),s=!1}else o.push([...t[r]]);return o}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,i=0;for(let s=0;s<t.length-1;s++){const r=t[s],c=t[s+1];if(this.calculateDistance(e,r)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((d,u)=>u>0);const a=this.calculatePointToLineDistance(e,r,c);n>a&&(n=a,i=s)}e.lng=l.convertToStdLng(e.lng);const o=[e];for(let s=i+1;s<t.length;s++)o.push(t[s]);return o}static calculatePointToLineDistance(e,t,n,i={units:"nauticalmiles",method:"geodesic"}){e.lng=l.convertToStdLng(e.lng),t={...t},n={...n},t.lng=l.convertToStdLng(t.lng,8),n.lng=l.convertToStdLng(n.lng,8);const o=l.convertToMonotonicLng([t,n]);t=o[0],n=o[1];const s=g.lineString([[t.lng,t.lat],[n.lng,n.lat]]),r=g.pointToLineDistance(g.point([e.lng,e.lat]),s,i),c=g.pointToLineDistance(g.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),s,i);return l.roundPrecision(Math.min(r,c),6)}static calculateWaypointsPropInRoute(e,t){t=this.mergeWaypointsToRoute(e,t);for(let n=0;n<e.length-1;n++){const i=e[n],o=e[n+1],s=this.calculateRangeRoute(i,o,t);n===0&&(i.distanceFromPrevious=0,i.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(s),o.distanceFromStart=l.roundPrecision((i.distanceFromStart||0)+o.distanceFromPrevious)}return e}static mergeCoordinatesToWaypoints(e,t,n=!0){for(const i of e)this.mergeCoordinateToWaypoints(i,t,n);return t}static mergeCoordinateToWaypoints(e,t,n=!0){e.lng=l.convertToStdLng(e.lng,8);let i=Number.MAX_VALUE,o=0,s=0,r=0;for(let c=0;c<t.length-1;c++){const a={lng:t[c].lng,lat:t[c].lat},d={lng:t[c+1].lng,lat:t[c+1].lat},u=this.calculatePointToLineDistance(e,a,d);i>=u&&(i=u,o=c,s=this.calculateDistance(a,e,!1,6),r=this.calculateDistance(d,e,!1,6))}return s!==0&&r!==0?s<i||s===i&&o===0?t.unshift(e):r<i||r===i&&o===t.length-2?t.push(e):t.splice(o+1,0,e):s===0?n&&t.splice(o,1,e):r===0&&n&&t.splice(o+1,1,e),t.map(c=>(c.lng=l.convertToStdLng(c.lng),c))}static generateRouteAccordingToWaypoints(e){const t=[];for(let n=1;n<e.length;n++){const i=e[n-1],o=e[n];if(n===1&&t.push(i),o.gcToPrevious){const s=this.interpolateCoordinates(i,o,200,!1,!0,"nauticalmiles");t.push(...s)}else t.push(o)}return this.divideAccordingToLng(t,!0)}static nearestCoordinateInRoute(e,t){const n=g.point([e.lng,e.lat]),i=[];for(const c of t){const a=c.map(d=>g.point(d));i.push(...a)}const o=g.featureCollection(i),s=g.nearestPoint(n,o),r=g.getCoord(s);return{lng:r[0],lat:r[1]}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let i=0;i<t.length-1;i++){const o=t[i],s=t[i+1];if(this.calculateDistance(e,o)===0){n=i;break}if(this.calculateDistance(e,s)===0){n=i+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,i="nauticalmiles"){var h;const o=e.speed||12,s=[];let r=[],c=!1,a=0,d=0,u;if(t&&n.length?(s.push(e),n.forEach((p,C)=>{if(c)r.push(p);else{const v=[];let T;for(let m=0;m<p.length;m++)if(u)v.push(p[m]);else{T={lng:p[m][0],lat:p[m][1]};const f=this.calculateDistance(e,T,!0,8,i);if(a+=f,a<t)d+=f,s.push(T),e=T;else{if(d=t,a===t)u=T,v.push([u.lng,u.lat]);else{const M=a-t,I=this.calculateBearing(T,e);u=this.calculateCoordinate(T,I,M,i),v.push([u.lng,u.lat]),v.push([T.lng,T.lat])}c=!0}}v.length&&r.push(v),C===n.length-1&&!u&&(u=T)}})):(r=n,u={...e}),u)if(s.push(u),u.distanceFromPrevious=d,u.hourFromPrevious=Math.round(d/o*1e4)/1e4,((h=r[0])==null?void 0:h.length)>1){const p={lng:r[0][1][0],lat:r[0][1][1]};u.bearing=this.calculateBearing(u,p)}else u.bearing=0;return{coordinate:u,nextRoute:r,prevRoute:s}}static nearestCoordinateInLine(e,t,n){const i=l.convertToStdLng(e.lng,6),o=g.point([i,e.lat]),s=l.convertToStdLng(t.lng,6),r=l.convertToStdLng(n.lng,6),c=g.lineString([[s,t.lat],[r,n.lat]]),a=g.nearestPointOnLine(c,o),d=g.getCoord(a),u=l.roundPrecision(d[0],6),h=l.roundPrecision(d[1],6);return{lng:u,lat:h,inline:!(u===s&&h===t.lat)&&!(u===r&&h===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let i,o;return e.forEach(s=>{s.forEach(r=>{const c={lng:r[0],lat:r[1]};if(!o)n.push(c),o=c;else if(o.bearing===void 0)o.bearing=this.calculateBearing(o,c,!0);else{const a=this.calculateDistance(i,c,!0);a&&a>=t&&(i.bearing=this.calculateBearing(i,c,!0),n.push(i),o=i)}i=c})}),i&&n.push(i),n}static simplifyRouteToCoordinates(e,t,n=1){let i=this.convertRouteToCoordinates(e,n);return i=this.simplifyGCCoordinates(i,t),i}static simplifyGCCoordinates(e,t){t.forEach(i=>{this.mergeCoordinateToWaypoints(i,e)});for(let i=1;i<t.length;i++){const o=t[i-1],s=t[i];if(s.gcToPrevious){const r=e.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=e.findIndex(a=>a.lng===s.lng&&a.lat===s.lat);for(let a=c-1;a>r;a--)e.splice(a,1)}}let n=0;for(let i=1;i<e.length;i++){const o=e[i-1],s=e[i];s.gcToPrevious?(o.bearing=this.calculateBearing(o,s,!1),s.distanceFromPrevious=this.calculateDistance(o,s,!1)):(o.bearing=this.calculateBearing(o,s,!0),s.distanceFromPrevious=this.calculateDistance(o,s,!0)),n=l.roundPrecision(n+s.distanceFromPrevious),s.distanceFromStart=n}return e.map(i=>(i.lng=l.convertToStdLng(i.lng),i))}static calculateCenter(e){const t=[];for(const r of e)for(const c of r)t.push(c);const n=g.featureCollection([]),i=l.convertToMonotonicLng2(t);for(const r of i)n.features.push(g.point(r));const s=g.center(n).geometry.coordinates;return{lng:l.convertToStdLng(s[0],8),lat:l.roundPrecision(s[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 s of o)t.push(s);const n=l.convertToMonotonicLng2(t),i=g.lineString(n);return g.bbox(i)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}}const N=W.getLogger("vessel");class F{static convert2Geojson(e){var n;const t=g.featureCollection([]);for(const i of e){if(i.forecasts){const o=(n=i.history)==null?void 0:n[0];for(const s of i.forecasts){const r=[],c=D(s.date).utc(),a=`${i.name}-${s.model}`;if(o){const d=D(o.updated).utc(),u=g.point([o.lng,o.lat],{model:s.model,name:i.name,date:d.format(),hour:0,format:d.format("MMM-DD/HHmm[Z]"),pressure:o.pressure>1e4?l.roundPrecision(o.pressure/100,0):l.roundPrecision(o.pressure,0),wind:{kts:o.kts,spd:o.speed||o.spd},category:a,type:"forecast"});t.features.push(u),r.push(u.geometry.coordinates)}for(const d in s==null?void 0:s.hours){const u=s.hours[d];u.wind.spd=u.wind.spd||u.wind.speed;const h=c.clone().add(Number(d),"hour"),p=g.point([u.lng,u.lat],{model:s.model,name:i.name,date:h.format(),hour:Number(d),format:h.format("MMM-DD/HHmm[Z]"),pressure:u.pressure>1e4?l.roundPrecision(u.pressure/100,0):l.roundPrecision(u.pressure,0),gusts:u.gusts,wind:u.wind||{},movement:u.movement,category:a,type:"forecast"});t.features.push(p),r.push(p.geometry.coordinates)}if((r==null?void 0:r.length)>1){const d=g.lineString(l.convertToMonotonicLng2(r),{date:s.date,id:i.id||i.name,model:s.model,name:i.name,category:a,type:"forecast"});t.features.push(d)}}}if(i.history){const o=[];for(const r of i.history){const c=D(r.updated).utc(),a=g.point([r.lng,r.lat],{name:i.name,date:c.format(),format:c.format("MMM-DD/HHmm[Z]"),pressure:r.pressure>1e4?l.roundPrecision(r.pressure/100,0):l.roundPrecision(r.pressure,0),spd:r.speed||r.spd,kts:r.kts,source:r.source,level:r.type,type:"history",category:`${i.name}-history`});t.features.push(a),o.push(a.geometry.coordinates)}const s=i.history[0];if(o.length===1&&o.push(o[0]),o.length>1){const r=g.lineString(l.convertToMonotonicLng2(o),{name:i.name,type:"history",updated:s==null?void 0:s.updated,pressure:(s==null?void 0:s.pressure)>1e4?l.roundPrecision((s==null?void 0:s.pressure)/100,0):l.roundPrecision(s==null?void 0:s.pressure,0),spd:(s==null?void 0:s.speed)||(s==null?void 0:s.spd),kts:s==null?void 0:s.kts,source:s==null?void 0:s.source,level:s==null?void 0:s.type});t.features.push(r)}}}return t}static interpolate(e,t=3){var o,s,r,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"),i=[];for(const a of n){const d=a.properties.name,u=a.properties.model,h=D(a.properties.date).utc();let p=t*60-(h.get("hour")*60+h.get("minute"))%(t*60);const C=(s=e==null?void 0:e.data)==null?void 0:s.features.filter(m=>m.geometry.type==="Point"&&m.properties.type==="forecast"&&m.properties.category===`${d}-${u}`);let v,T=h.clone().add(p,"minute").set({minute:0,second:0,millisecond:0});for(;v=this.pickIndex(C,T),v<=C.length-1;){if(v>0){const m=C[v],f=v===0?void 0:C[v-1],M=(p/60-((r=f==null?void 0:f.properties)==null?void 0:r.hour))/(m.properties.hour-((c=f==null?void 0:f.properties)==null?void 0:c.hour)),I=this.computeNumber(f==null?void 0:f.geometry.coordinates[0],m.geometry.coordinates[0],M),O=this.computeNumber(f==null?void 0:f.geometry.coordinates[1],m.geometry.coordinates[1],M),E=g.point([I,O],{name:d,model:u,category:m==null?void 0:m.properties.category,date:T.format(),format:T.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(f==null?void 0:f.properties.gusts,m.properties.gusts,M),hour:this.computeNumber(f==null?void 0:f.properties.hour,m.properties.hour,M),movement:this.computeNumber(f==null?void 0:f.properties.movement,m.properties.movement,M),pressure:this.computeNumber(f==null?void 0:f.properties.pressure,m.properties.pressure,M),wind:this.computeNumber(f==null?void 0:f.properties.wind,m.properties.wind,M),type:"forecast",showCircle:a.showCircle});i.push(E)}p+=t*60,T=h.clone().add(p,"minute").set({minute:0,second:0,millisecond:0})}}return i}static diversionPassageAt(e,t,n,i,o={requestId:""}){var a,d,u,h;const{t1:s,t2:r,hr:c}=this.tropicalCenterTwin(t,24,o);if(s&&r){const p=P.calculateBearing(e,s),C=P.calculateBearing(s,r),v=P.calculateCoordinate(s,p-C+90,n);N.info("[%s] the right tangent position: %j",o.requestId,{from:e,t1:s,t2:r,radius:n,bearing1:p,bearing2:C,right:v});const T=P.calculateBearing(e,v);let m=P.calculateCoordinate(e,T,i*Number(c));m.utc=D((d=(a=t==null?void 0:t.forecasts)==null?void 0:a[0])==null?void 0:d.date).add(Number(c),"hours").utc().format(),N.info("[%s] the diversion position: %j",o.requestId,m);const f=P.calculateDistance(m,r);return N.info("[%s] the distance(%d) between the diversion position & t2: %j - %j",o.requestId,f,m,r),f<n&&(m=P.calculateCoordinate(e,T,i*Number(c)/2),m.utc=D((h=(u=t==null?void 0:t.forecasts)==null?void 0:u[0])==null?void 0:h.date).add(Number(c)/2,"hours").utc().format(),N.warn("[%s] the prev diversion position is too close to t2, replace with 1/2 position: %j",o.requestId,m)),m}else{N.info("[%s] no need to diversion: %j",o.requestId,{from:e,t1:s,t2:r});return}}static driftPassageAt(e,t,n,i={requestId:""}){const{t1:o,t2:s,hr:r}=this.tropicalCenterTwin(t,24,i);if(o&&s){const c=P.calculateBearing(e,o),a=P.calculateBearing(o,s);return P.calculateCoordinate(o,c-a+180,n)}else{N.info("[%s] no need drift: %j",i.requestId,{from:e,t1:o,t2:s});return}}static tropicalCenterTwin(e,t=24,n={requestId:""}){var c,a,d,u,h;const i=(a=(c=e==null?void 0:e.forecasts)==null?void 0:c[0])==null?void 0:a.hours,o=((d=e==null?void 0:e.history)==null?void 0:d[0])||(i==null?void 0:i[(u=Object.keys(i))==null?void 0:u[0]]);N.info("[%s] the first tropical center: %j",n.requestId,o);const s=(h=Object.keys(i||{}).filter(p=>Number(p)<=(t<0?24:t)))==null?void 0:h.at(-1),r=i==null?void 0:i[s||-1];return N.info("[%s] the second tropical center: %j in %d hrs",n.requestId,r,s),{t1:o,t2:r,hr:s}}static pickIndex(e,t){let n=0;for(const i of e){if(D(i.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 i={};for(const o in e)i[o]=this.computeNumber(e[o],t[o],n);return i}return Math.round((e+(t-e)*n)*100)/100}else return e;else return t}}S.LaneHelper=P,S.LngLatHelper=l,S.TropicalHelper=F,Object.defineProperty(S,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(C,R){typeof exports=="object"&&typeof module<"u"?R(exports,require("@turf/turf"),require("moment"),require("moment-timezone"),require("tz-lookup")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","moment-timezone","tz-lookup"],R):(C=typeof globalThis<"u"?globalThis:C||self,R(C["idm-plugin-rabbitmq"]={},C["@turf/turf"],C.moment,C["moment-timezone"],C["tz-lookup"]))})(this,function(C,R,N,B,j){"use strict";function $(P){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(P){for(const t in P)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(P,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>P[t]})}}return e.default=P,Object.freeze(e)}const g=$(R);function k(P){return P&&P.__esModule&&Object.prototype.hasOwnProperty.call(P,"default")?P.default:P}class I{log(){}isLevelEnabled(){return!1}addContext(){}removeContext(){}clearContext(){}}["Trace","Debug","Info","Warn","Error","Fatal","Mark"].forEach(P=>{I.prototype[P.toLowerCase()]=()=>{},I.prototype[`is${P}Enabled`]=()=>!1});const x=(()=>{try{return require("log4js")}catch{return null}})();var L={getLogger:x?x.getLogger:()=>new I};const W=k(L);class l{static guessTimeZoneOffset(e,t){const n=j(t,e),s=N().tz(n).utcOffset();return this.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=l.convertToStdLng(e,t);let s="E";e<0&&(s="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,i,r,c,a,d,u;i=o%3600%60,n.indexOf("S")!==-1&&(o=o-i,r=l.padNumber(i,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=l.roundPrecision(c,t).toString().padStart(2,"0"):a=l.padNumber(c,2,2),o=o-c*60),d=o/3600,n.indexOf("M")!==-1?u=l.roundPrecision(d,t).toString().padStart(3,"0"):u=l.padNumber(d,3,2);const p=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:l.roundPrecision(d,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(i,t),pretty:p}}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,i,r,c,a,d,u;i=o%3600%60,n.indexOf("S")!==-1&&(o=o-i,r=l.padNumber(i,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?a=l.roundPrecision(c,t).toString().padStart(2,"0"):a=l.padNumber(c,2,2),o=o-c*60),d=o/3600,n.indexOf("M")!==-1?u=l.roundPrecision(d,t).toString().padStart(2,"0"):u=l.padNumber(d,2,2);const p=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:l.roundPrecision(d,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(i,t),pretty:p}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LNG");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[i,r]=o;if(r=r>60?r/Math.pow(10,String(r).length-2):r,i>360&&!r){const c=this.roundPrecision(i/100,0);r=i-c*100,i=c}n=i+(r??0)/60,s==="W"&&(n=n*-1)}else n=Number(e);return l.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LAT");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[i,r]=o;if(r=r>60?r/Math.pow(10,String(r).length-2):r,i>90&&!r){const c=this.roundPrecision(i/100,0);r=i-c*100,i=c}n=i+(r??0)/60,s==="S"&&(n=n*-1)}else n=Number(e);return l.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=l.strReplace(e,n);const s=e[e.length-1].toUpperCase();return["N","S"].includes(s)?{lat:l.str2Lat(e,t)}:{lng:l.str2Lng(e,t)}}static convertToStdLng(e,t=4){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),l.roundPrecision(e,t)}static roundPrecision(e,t=4){if(typeof e=="number"){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}return e}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(/-/g," ").replace(/°/," ").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=Math.trunc(e).toString().padStart(t,"0"),o=Math.trunc(l.roundPrecision(e-Math.trunc(e),n)*Math.pow(10,n)).toString().padStart(n,"0");return`${s}.${o}`}}class v{static calculateBearing(e,t,n=!0,s=4){const o=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let i;return n?i=g.rhumbBearing(o.features[0],o.features[1]):i=g.bearing(o.features[0],o.features[1]),i<0&&(i+=360),l.roundPrecision(i,s)}static calculateDistance(e,t,n=!0,s=4,o="nauticalmiles"){e={...e},t={...t},e.lng=l.convertToStdLng(e.lng,s),t.lng=l.convertToStdLng(t.lng,s);const i=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=g.rhumbDistance(i.features[0],i.features[1],{units:o}):r=g.distance(i.features[0],i.features[1],{units:o}),l.roundPrecision(r,s)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let s=0,o;for(const i of e)for(let r=0;r<i.length-1;r++){const c={lng:i[r][0],lat:i[r][1]};r===0&&o&&(s+=this.calculateDistance(o,c,!0,t,n));const a={lng:i[r+1][0],lat:i[r+1][1]};s+=this.calculateDistance(c,a,!0,t,n),o=a}return l.roundPrecision(s,t)}static calculateCoordinate(e,t,n,s="nauticalmiles",o=!0){const i=g.point([e.lng,e.lat]);let r;o?r=g.rhumbDestination(i,n,t,{units:s}):r=g.destination(i,n,t,{units:s});const c=r.geometry.coordinates;return{lng:l.convertToStdLng(c[0],8),lat:l.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,s=!0,o=!0,i="nauticalmiles"){const r=[],c=this.calculateBearing(e,t,!1),a=this.calculateDistance(e,t,!1,8,i);s&&r.push({lng:e.lng,lat:e.lat});let d=0;for(;d<a;)d+=n,d<a&&r.push(this.calculateCoordinate(e,c,d,i,!1));return o&&r.push({lng:t.lng,lat:t.lat}),r}static divideAccordingToLng(e,t=!1){if((e==null?void 0:e.length)<2)return[];e=this.deduplicateCoordinates(e);let n=[];const s=[];let o,i;for(let r=0;r<e.length-1;r++){o=l.convertToStdLng(e[r].lng,8),i=l.convertToStdLng(e[r+1].lng,8),n.push([o,e[r].lat]);const c=o-i;if(Math.abs(c)>180){const a=l.convertToMonotonicLng2([[o,e[r].lat],[i,e[r+1].lat]]);let d,u;t?(d=g.lineString(a),u=g.lineString([[c>0?180:-180,89],[c>0?180:-180,-89]])):(d=g.greatCircle(a[0],a[1]),u=g.greatCircle([c>0?180:-180,89],[c>0?180:-180,-89]));const p=g.lineIntersect(d,u);let f;if(p.features.length){const M=g.getCoord(p.features[0]);f=l.roundPrecision(M[1],8)}else f=e[r].lat;c>0?(n.push([180-1e-6,f]),s.push([...n]),n=[],n.push([-(180-1e-6),f])):(n.push([-(180-1e-6),f]),s.push([...n]),n=[],n.push([180-1e-6,f]))}r===e.length-2&&n.push([i,e[r+1].lat])}return s.push(n),s}static deduplicateRoute(e){const t=[];for(const n of e){const s=n.reduce((o,i)=>(o.findIndex(r=>r[0]===i[0]&&r[1]===i[1])===-1&&o.push(i),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=l.convertToStdLng(e.lng,8);for(const n of t)for(let s=n.length-1;s>=0;s--)l.roundPrecision(n[s][0],8)===e.lng&&l.roundPrecision(n[s][1],8)===l.roundPrecision(e.lat,8)&&n.splice(s,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=l.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)l.roundPrecision(t[n].lng,8)===e.lng&&l.roundPrecision(t[n].lat,8)===l.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,s=0,o=0,i,r;return t.forEach((c,a)=>{for(let d=0;d<c.length-1;d++){const u={lng:c[d][0],lat:c[d][1]},p={lng:c[d+1][0],lat:c[d+1][1]},f=this.calculatePointToLineDistance(e,u,p);n>f&&(n=f,o=d,s=a,i=this.calculateDistance(u,e),r=this.calculateDistance(p,e))}}),i!==0&&r!==0?t[s].splice(o+1,0,[e.lng,e.lat]):i===0?t[s].splice(o,1,[e.lng,e.lat]):r===0&&t[s].splice(o+1,1,[e.lng,e.lat]),t}static appendCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);const n=v.convertRouteToCoordinates(t);return n.push(e),v.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=v.convertRouteToCoordinates(t);return n.unshift(e),v.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(i=>{if(o===2)return;const r=[];for(const c of i){if(l.roundPrecision(t.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(c[1],8)){r.push(c),o===0&&r.push([e.lng,e.lat]),o=2;break}o===1?r.push(c):l.roundPrecision(e.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(c[1],8)&&(o=1,r.push(c))}r.length&&s.push(r)}),s}static calculateRangeWaypoints(e,t,n,s=[]){const o=this.convertRouteToCoordinates(n,0),i=this.mergeCoordinatesToWaypoints([e,t,...s],o),r=i.findIndex(d=>l.roundPrecision(e.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(d.lat,8)),c=i.findIndex(d=>l.roundPrecision(t.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(d.lat,8));return i.filter((d,u)=>u>=r&&u<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,s=0,o=0;return t.forEach((i,r)=>{for(let c=0;c<i.length-1;c++){const a={lng:i[c][0],lat:i[c][1]},d={lng:i[c+1][0],lat:i[c+1][1]},u=this.calculatePointToLineDistance(e,a,d);n>u&&(n=u,s=c,o=r)}}),{minDist:n,segIndex:o,minIndex:s}}static calculateSubRoute(e,t){const{segIndex:n,minIndex:s}=this.calculateMinDistanceToRoute({...e},t);e.lng=l.convertToStdLng(e.lng);const o=[];let i=!0;for(let r=n;r<t.length;r++)if(i){const c=[];c.push([e.lng,e.lat]);for(let a=s+1;a<t[r].length;a++)e.lng===t[r][a][0]&&e.lat===t[r][a][1]||c.push(t[r][a]);o.push(c),i=!1}else o.push([...t[r]]);return o}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,s=0;for(let i=0;i<t.length-1;i++){const r=t[i],c=t[i+1];if(this.calculateDistance(e,r)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((d,u)=>u>0);const a=this.calculatePointToLineDistance(e,r,c);n>a&&(n=a,s=i)}e.lng=l.convertToStdLng(e.lng);const o=[e];for(let i=s+1;i<t.length;i++)o.push(t[i]);return o}static calculatePointToLineDistance(e,t,n,s={units:"nauticalmiles",method:"geodesic"}){e.lng=l.convertToStdLng(e.lng),t={...t},n={...n},t.lng=l.convertToStdLng(t.lng,8),n.lng=l.convertToStdLng(n.lng,8);const o=l.convertToMonotonicLng([t,n]);t=o[0],n=o[1];const i=g.lineString([[t.lng,t.lat],[n.lng,n.lat]]),r=g.pointToLineDistance(g.point([e.lng,e.lat]),i,s),c=g.pointToLineDistance(g.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),i,s);return l.roundPrecision(Math.min(r,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],i=this.calculateRangeRoute(s,o,t);n===0&&(s.distanceFromPrevious=0,s.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(i),o.distanceFromStart=l.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=l.convertToStdLng(e.lng,8);let s=Number.MAX_VALUE,o=0,i=0,r=0;for(let c=0;c<t.length-1;c++){const a={lng:t[c].lng,lat:t[c].lat},d={lng:t[c+1].lng,lat:t[c+1].lat},u=this.calculatePointToLineDistance(e,a,d);s>=u&&(s=u,o=c,i=this.calculateDistance(a,e,!1,6),r=this.calculateDistance(d,e,!1,6))}return i!==0&&r!==0?i<s||i===s&&o===0?t.unshift(e):r<s||r===s&&o===t.length-2?t.push(e):t.splice(o+1,0,e):i===0?n&&t.splice(o,1,e):r===0&&n&&t.splice(o+1,1,e),t.map(c=>(c.lng=l.convertToStdLng(c.lng),c))}static generateRouteAccordingToWaypoints(e){const t=[];for(let n=1;n<e.length;n++){const s=e[n-1],o=e[n];if(n===1&&t.push(s),o.gcToPrevious){const i=this.interpolateCoordinates(s,o,200,!1,!0,"nauticalmiles");t.push(...i)}else t.push(o)}return this.divideAccordingToLng(t,!0)}static nearestCoordinateInRoute(e,t){const n=g.point([e.lng,e.lat]),s=[];for(const c of t){const a=c.map(d=>g.point(d));s.push(...a)}const o=g.featureCollection(s),i=g.nearestPoint(n,o),r=g.getCoord(i);return{lng:r[0],lat:r[1]}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let s=0;s<t.length-1;s++){const o=t[s],i=t[s+1];if(this.calculateDistance(e,o)===0){n=s;break}if(this.calculateDistance(e,i)===0){n=s+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,s="nauticalmiles"){var p;const o=e.speed||12,i=[];let r=[],c=!1,a=0,d=0,u;if(t&&n.length?(i.push(e),n.forEach((f,M)=>{if(c)r.push(f);else{const S=[];let b;for(let T=0;T<f.length;T++)if(u)S.push(f[T]);else{b={lng:f[T][0],lat:f[T][1]};const m=this.calculateDistance(e,b,!0,8,s);if(a+=m,a<t)d+=m,i.push(b),e=b;else{if(d=t,a===t)u=b,S.push([u.lng,u.lat]);else{const h=a-t,D=this.calculateBearing(b,e);u=this.calculateCoordinate(b,D,h,s),S.push([u.lng,u.lat]),S.push([b.lng,b.lat])}c=!0}}S.length&&r.push(S),M===n.length-1&&!u&&(u=b)}})):(r=n,u={...e}),u)if(i.push(u),u.distanceFromPrevious=d,u.hourFromPrevious=Math.round(d/o*1e4)/1e4,((p=r[0])==null?void 0:p.length)>1){const f={lng:r[0][1][0],lat:r[0][1][1]};u.bearing=this.calculateBearing(u,f)}else u.bearing=0;return{coordinate:u,nextRoute:r,prevRoute:i}}static nearestCoordinateInLine(e,t,n){const s=l.convertToStdLng(e.lng,6),o=g.point([s,e.lat]),i=l.convertToStdLng(t.lng,6),r=l.convertToStdLng(n.lng,6),c=g.lineString([[i,t.lat],[r,n.lat]]),a=g.nearestPointOnLine(c,o),d=g.getCoord(a),u=l.roundPrecision(d[0],6),p=l.roundPrecision(d[1],6);return{lng:u,lat:p,inline:!(u===i&&p===t.lat)&&!(u===r&&p===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let s,o;return e.forEach(i=>{i.forEach(r=>{const c={lng:r[0],lat:r[1]};if(!o)n.push(c),o=c;else if(o.bearing===void 0)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)});for(let s=1;s<t.length;s++){const o=t[s-1],i=t[s];if(i.gcToPrevious){const r=e.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=e.findIndex(a=>a.lng===i.lng&&a.lat===i.lat);for(let a=c-1;a>r;a--)e.splice(a,1)}}let n=0;for(let s=1;s<e.length;s++){const o=e[s-1],i=e[s];i.gcToPrevious?(o.bearing=this.calculateBearing(o,i,!1),i.distanceFromPrevious=this.calculateDistance(o,i,!1)):(o.bearing=this.calculateBearing(o,i,!0),i.distanceFromPrevious=this.calculateDistance(o,i,!0)),n=l.roundPrecision(n+i.distanceFromPrevious),i.distanceFromStart=n}return e.map(s=>(s.lng=l.convertToStdLng(s.lng),s))}static calculateCenter(e){const t=[];for(const r of e)for(const c of r)t.push(c);const n=g.featureCollection([]),s=l.convertToMonotonicLng2(t);for(const r of s)n.features.push(g.point(r));const i=g.center(n).geometry.coordinates;return{lng:l.convertToStdLng(i[0],8),lat:l.roundPrecision(i[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 i of o)t.push(i);const n=l.convertToMonotonicLng2(t),s=g.lineString(n);return g.bbox(s)}static calculateBBox2(e){const t=this.generateRouteAccordingToWaypoints(e);return this.calculateBBox(t)}}const y=W.getLogger("vessel");class O{static convert2Geojson(e){var n;const t=g.featureCollection([]);for(const s of e){if(s.forecasts){const o=(n=s.history)==null?void 0:n[0];for(const i of s.forecasts){const r=[],c=N(i.date).utc(),a=`${s.name}-${i.model}`;if(o){const d=N(o.updated).utc(),u=g.point([o.lng,o.lat],{model:i.model,name:s.name,date:d.format(),hour:0,format:d.format("MMM-DD/HHmm[Z]"),pressure:o.pressure>1e4?l.roundPrecision(o.pressure/100,0):l.roundPrecision(o.pressure,0),wind:{kts:o.kts,spd:o.speed||o.spd},category:a,type:"forecast"});t.features.push(u),r.push(u.geometry.coordinates)}for(const d in i==null?void 0:i.hours){const u=i.hours[d];u.wind.spd=u.wind.spd||u.wind.speed;const p=c.clone().add(Number(d),"hour"),f=g.point([u.lng,u.lat],{model:i.model,name:s.name,date:p.format(),hour:Number(d),format:p.format("MMM-DD/HHmm[Z]"),pressure:u.pressure>1e4?l.roundPrecision(u.pressure/100,0):l.roundPrecision(u.pressure,0),gusts:u.gusts,wind:u.wind||{},movement:u.movement,category:a,type:"forecast"});t.features.push(f),r.push(f.geometry.coordinates)}if((r==null?void 0:r.length)>1){const d=g.lineString(l.convertToMonotonicLng2(r),{date:i.date,id:s.id||s.name,model:i.model,name:s.name,category:a,type:"forecast"});t.features.push(d)}}}if(s.history){const o=[];for(const r of s.history){const c=N(r.updated).utc(),a=g.point([r.lng,r.lat],{name:s.name,date:c.format(),format:c.format("MMM-DD/HHmm[Z]"),pressure:r.pressure>1e4?l.roundPrecision(r.pressure/100,0):l.roundPrecision(r.pressure,0),spd:r.speed||r.spd,kts:r.kts,source:r.source,level:r.type,type:"history",category:`${s.name}-history`});t.features.push(a),o.push(a.geometry.coordinates)}const i=s.history[0];if(o.length===1&&o.push(o[0]),o.length>1){const r=g.lineString(l.convertToMonotonicLng2(o),{name:s.name,type:"history",updated:i==null?void 0:i.updated,pressure:(i==null?void 0:i.pressure)>1e4?l.roundPrecision((i==null?void 0:i.pressure)/100,0):l.roundPrecision(i==null?void 0:i.pressure,0),spd:(i==null?void 0:i.speed)||(i==null?void 0:i.spd),kts:i==null?void 0:i.kts,source:i==null?void 0:i.source,level:i==null?void 0:i.type});t.features.push(r)}}}return t}static interpolate(e,t=3){var o,i,r,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 d=a.properties.name,u=a.properties.model,p=a.properties.showCircle,f=N(a.properties.date).utc();let M=t*60-(f.get("hour")*60+f.get("minute"))%(t*60);const S=(i=e==null?void 0:e.data)==null?void 0:i.features.filter(m=>m.geometry.type==="Point"&&m.properties.type==="forecast"&&m.properties.category===`${d}-${u}`);let b,T=f.clone().add(M,"minute").set({minute:0,second:0,millisecond:0});for(;b=this.pickIndex(S,T),b<=S.length-1;){if(b>0){const m=S[b],h=b===0?void 0:S[b-1],D=(M/60-((r=h==null?void 0:h.properties)==null?void 0:r.hour))/(m.properties.hour-((c=h==null?void 0:h.properties)==null?void 0:c.hour)),E=this.computeNumber(h==null?void 0:h.geometry.coordinates[0],m.geometry.coordinates[0],D),F=this.computeNumber(h==null?void 0:h.geometry.coordinates[1],m.geometry.coordinates[1],D),A=g.point([E,F],{name:d,model:u,category:m==null?void 0:m.properties.category,date:T.format(),format:T.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(h==null?void 0:h.properties.gusts,m.properties.gusts,D),hour:this.computeNumber(h==null?void 0:h.properties.hour,m.properties.hour,D),movement:this.computeNumber(h==null?void 0:h.properties.movement,m.properties.movement,D),pressure:this.computeNumber(h==null?void 0:h.properties.pressure,m.properties.pressure,D),wind:this.computeNumber(h==null?void 0:h.properties.wind,m.properties.wind,D),type:"forecast",showCircle:p});s.push(A)}M+=t*60,T=f.clone().add(M,"minute").set({minute:0,second:0,millisecond:0})}}return s}static diversionPassageAt(e,t,n,s,o={requestId:""}){var a,d,u,p;const{t1:i,t2:r,hr:c}=this.tropicalCenterTwin(t,24,o);if(i&&r){const f=v.calculateBearing(e,i),M=v.calculateBearing(i,r),S=v.calculateCoordinate(i,f-M+90,n);y.info("[%s] the right tangent position: %j",o.requestId,{from:e,t1:i,t2:r,radius:n,bearing1:f,bearing2:M,right:S});const b=v.calculateBearing(e,S);let T=v.calculateCoordinate(e,b,s*Number(c));T.utc=N((d=(a=t==null?void 0:t.forecasts)==null?void 0:a[0])==null?void 0:d.date).add(Number(c),"hours").utc().format(),y.info("[%s] the diversion position: %j",o.requestId,T);const m=v.calculateDistance(T,r);return y.info("[%s] the distance(%d) between the diversion position & t2: %j - %j",o.requestId,m,T,r),m<n&&(T=v.calculateCoordinate(e,b,s*Number(c)/2),T.utc=N((p=(u=t==null?void 0:t.forecasts)==null?void 0:u[0])==null?void 0:p.date).add(Number(c)/2,"hours").utc().format(),y.warn("[%s] the prev diversion position is too close to t2, replace with 1/2 position: %j",o.requestId,T)),T}else{y.info("[%s] no need to diversion: %j",o.requestId,{from:e,t1:i,t2:r});return}}static driftPassageAt(e,t,n,s={requestId:""}){const{t1:o,t2:i,hr:r}=this.tropicalCenterTwin(t,24,s);if(o&&i){const c=v.calculateBearing(e,o),a=v.calculateBearing(o,i);return v.calculateCoordinate(o,c-a+180,n)}else{y.info("[%s] no need drift: %j",s.requestId,{from:e,t1:o,t2:i});return}}static tropicalCenterTwin(e,t=24,n={requestId:""}){var c,a,d,u,p;let s={};(c=e.forecasts)==null||c.forEach(f=>{s={...f.hours,...s}});const o=((a=e==null?void 0:e.history)==null?void 0:a[0])||(s==null?void 0:s[(d=Object.keys(s))==null?void 0:d[0]]);y.info("[%s] the first tropical center: %j",n.requestId,o);let i=(u=Object.keys(s||{}).filter(f=>Number(f)<=(t<0?24:t)))==null?void 0:u.at(-1);i||(i=(p=Object.keys(s||{}).filter(f=>Number(f)<=(t<0?24:2*t)))==null?void 0:p.at(-1));const r=s==null?void 0:s[i||-1];return y.info("[%s] the second tropical center: %j in %d hrs",n.requestId,r,i),{t1:o,t2:r,hr:i}}static pickIndex(e,t){let n=0;for(const s of e){if(N(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}}C.LaneHelper=v,C.LngLatHelper=l,C.TropicalHelper=O,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
|