@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 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 $ from "tz-lookup";
5
- function W(v) {
6
- return v && v.__esModule && Object.prototype.hasOwnProperty.call(v, "default") ? v.default : v;
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((v) => {
22
- R.prototype[v.toLowerCase()] = () => {
23
- }, R.prototype[`is${v}Enabled`] = () => !1;
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 E = () => {
25
+ const j = () => {
26
26
  try {
27
27
  return require("log4js");
28
28
  } catch {
29
29
  return null;
30
30
  }
31
- }, I = E(), A = I ? I.getLogger : () => new R();
32
- var F = {
33
- getLogger: A
31
+ }, y = j(), k = y ? y.getLogger : () => new R();
32
+ var A = {
33
+ getLogger: k
34
34
  };
35
- const L = /* @__PURE__ */ W(F);
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 = $(t, e), i = D().tz(n).utcOffset();
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 f = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${i}`;
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: f
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 f = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${i}`;
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: f
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 b {
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 f = g.lineIntersect(d, u);
301
- let p;
302
- if (f.features.length) {
303
- const S = g.getCoord(f.features[0]);
304
- p = l.roundPrecision(S[1], 8);
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
- p = e[r].lat;
307
- 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]));
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] }, f = { lng: c[d + 1][0], lat: c[d + 1][1] }, p = this.calculatePointToLineDistance(e, u, f);
372
- n > p && (n = p, o = d, i = a, s = this.calculateDistance(u, e), r = this.calculateDistance(f, e));
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 = b.convertRouteToCoordinates(t);
384
- return n.push(e), b.divideAccordingToLng(n);
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 = b.convertRouteToCoordinates(t);
393
- return n.unshift(e), b.divideAccordingToLng(n);
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 f;
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((p, S) => {
630
+ if (t && n.length ? (s.push(e), n.forEach((h, S) => {
631
631
  if (c)
632
- r.push(p);
632
+ r.push(h);
633
633
  else {
634
- const P = [];
635
- let T;
636
- for (let m = 0; m < p.length; m++)
634
+ const v = [];
635
+ let b;
636
+ for (let T = 0; T < h.length; T++)
637
637
  if (u)
638
- P.push(p[m]);
638
+ v.push(h[T]);
639
639
  else {
640
- T = { lng: p[m][0], lat: p[m][1] };
641
- const h = this.calculateDistance(e, T, !0, 8, i);
642
- if (a += h, a < t)
643
- d += h, s.push(T), e = T;
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 = T, P.push([u.lng, u.lat]);
646
+ u = b, v.push([u.lng, u.lat]);
647
647
  else {
648
- const C = a - t, N = this.calculateBearing(T, e);
649
- u = this.calculateCoordinate(T, N, C, i), P.push([u.lng, u.lat]), P.push([T.lng, T.lat]);
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
- P.length && r.push(P), S === n.length - 1 && !u && (u = T);
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, ((f = r[0]) == null ? void 0 : f.length) > 1) {
658
- const p = { lng: r[0][1][0], lat: r[0][1][1] };
659
- u.bearing = this.calculateBearing(u, p);
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), f = l.roundPrecision(d[1], 6);
675
- return { lng: u, lat: f, inline: !(u === s && f === t.lat) && !(u === r && f === n.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 M = L.getLogger("vessel");
779
- class O {
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 f = c.clone().add(Number(d), "hour"), p = g.point([u.lng, u.lat], {
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: f.format(),
812
+ date: p.format(),
813
813
  hour: Number(d),
814
- format: f.format("MMM-DD/HHmm[Z]"),
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(p), r.push(p.geometry.coordinates);
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, f = D(a.properties.date).utc();
882
- let p = t * 60 - (f.get("hour") * 60 + f.get("minute")) % (t * 60);
883
- const S = (s = e == null ? void 0 : e.data) == null ? void 0 : s.features.filter(
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 P, T = f.clone().add(p, "minute").set({ minute: 0, second: 0, millisecond: 0 });
887
- for (; P = this.pickIndex(S, T), P <= S.length - 1; ) {
888
- if (P > 0) {
889
- const m = S[P], h = P === 0 ? void 0 : S[P - 1], C = (p / 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)), N = this.computeNumber(h == null ? void 0 : h.geometry.coordinates[0], m.geometry.coordinates[0], C), y = this.computeNumber(h == null ? void 0 : h.geometry.coordinates[1], m.geometry.coordinates[1], C), x = g.point([N, y], {
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(h == null ? void 0 : h.properties.gusts, m.properties.gusts, C),
896
- hour: this.computeNumber(h == null ? void 0 : h.properties.hour, m.properties.hour, C),
897
- movement: this.computeNumber(h == null ? void 0 : h.properties.movement, m.properties.movement, C),
898
- pressure: this.computeNumber(h == null ? void 0 : h.properties.pressure, m.properties.pressure, C),
899
- wind: this.computeNumber(h == null ? void 0 : h.properties.wind, m.properties.wind, C),
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: a.showCircle
901
+ showCircle: p
902
902
  });
903
- i.push(x);
903
+ i.push($);
904
904
  }
905
- p += t * 60, T = f.clone().add(p, "minute").set({ minute: 0, second: 0, millisecond: 0 });
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, f;
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 p = b.calculateBearing(e, s), S = b.calculateBearing(s, r), P = b.calculateCoordinate(s, p - S + 90, n);
926
- M.info("[%s] the right tangent position: %j", o.requestId, { from: e, t1: s, t2: r, radius: n, bearing1: p, bearing2: S, right: P });
927
- const T = b.calculateBearing(e, P);
928
- let m = b.calculateCoordinate(e, T, i * Number(c));
929
- 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(), M.info("[%s] the diversion position: %j", o.requestId, m);
930
- const h = b.calculateDistance(m, r);
931
- return M.info("[%s] the distance(%d) between the diversion position & t2: %j - %j", o.requestId, h, m, r), h < n && (m = b.calculateCoordinate(e, T, i * Number(c) / 2), m.utc = D((f = (u = t == null ? void 0 : t.forecasts) == null ? void 0 : u[0]) == null ? void 0 : f.date).add(Number(c) / 2, "hours").utc().format(), M.warn("[%s] the prev diversion position is too close to t2, replace with 1/2 position: %j", o.requestId, m)), m;
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
- M.info("[%s] no need to diversion: %j", o.requestId, { from: e, t1: s, t2: r });
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 = b.calculateBearing(e, o), a = b.calculateBearing(o, s);
951
- return b.calculateCoordinate(o, c - a + 180, n);
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
- M.info("[%s] no need drift: %j", i.requestId, { from: e, t1: o, t2: s });
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, f;
966
- 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]]);
967
- M.info("[%s] the first tropical center: %j", n.requestId, o);
968
- const s = (f = Object.keys(i || {}).filter((p) => Number(p) <= (t < 0 ? 24 : t))) == null ? void 0 : f.at(-1), r = i == null ? void 0 : i[s || -1];
969
- return M.info("[%s] the second tropical center: %j in %d hrs", n.requestId, r, s), { t1: o, t2: r, hr: s };
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
- b as LaneHelper,
1003
+ P as LaneHelper,
998
1004
  l as LngLatHelper,
999
- O as TropicalHelper
1005
+ q as TropicalHelper
1000
1006
  };
@@ -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"})});
@@ -66,7 +66,7 @@ export declare class TropicalHelper {
66
66
  lat: number;
67
67
  } | undefined;
68
68
  /**
69
- * 获取台风中心点对数
69
+ * 获取台风中心点对
70
70
  * @param tropical { history: any[], forecasts: any[] }
71
71
  * @param hrs 未来小时数,默认24
72
72
  * @param options
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/geo",
3
3
  "private": false,
4
- "version": "1.2.3",
4
+ "version": "1.2.4",
5
5
  "description": "idm plugin for geo",
6
6
  "type": "module",
7
7
  "keywords": [