@idm-plugin/geo 1.4.2 → 1.4.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/README.md CHANGED
@@ -1,2 +1,2 @@
1
- ## Geo Plugin
1
+ ## Geo Plugin
2
2
  Geo插件
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@ import * as g from "@turf/turf";
2
2
  import R from "moment";
3
3
  import "moment-timezone";
4
4
  import A from "tz-lookup";
5
- function E(M) {
6
- return M && M.__esModule && Object.prototype.hasOwnProperty.call(M, "default") ? M.default : M;
5
+ function E(C) {
6
+ return C && C.__esModule && Object.prototype.hasOwnProperty.call(C, "default") ? C.default : C;
7
7
  }
8
8
  class y {
9
9
  log() {
@@ -18,21 +18,21 @@ class y {
18
18
  clearContext() {
19
19
  }
20
20
  }
21
- ["Trace", "Debug", "Info", "Warn", "Error", "Fatal", "Mark"].forEach((M) => {
22
- y.prototype[M.toLowerCase()] = () => {
23
- }, y.prototype[`is${M}Enabled`] = () => !1;
21
+ ["Trace", "Debug", "Info", "Warn", "Error", "Fatal", "Mark"].forEach((C) => {
22
+ y.prototype[C.toLowerCase()] = () => {
23
+ }, y.prototype[`is${C}Enabled`] = () => !1;
24
24
  });
25
- const k = () => {
25
+ const F = () => {
26
26
  try {
27
27
  return require("log4js");
28
28
  } catch {
29
29
  return null;
30
30
  }
31
- }, I = k(), F = I ? I.getLogger : () => new y();
32
- var L = {
33
- getLogger: F
31
+ }, x = F(), k = x ? x.getLogger : () => new y();
32
+ var B = {
33
+ getLogger: k
34
34
  };
35
- const O = /* @__PURE__ */ E(L);
35
+ const O = /* @__PURE__ */ E(B);
36
36
  class l {
37
37
  /**
38
38
  * 基于输入的经度,计算出时区
@@ -58,13 +58,13 @@ class l {
58
58
  t < 0 && (s = "W"), t = Math.abs(t), n = n.toUpperCase();
59
59
  let o = t * 3600, i, r, c, a, d, u;
60
60
  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, e).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, e).toString().padStart(3, "0") : u = l.padNumber(d, 3, 2);
61
- const p = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${s}`;
61
+ const f = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${s}`;
62
62
  return {
63
63
  direction: s,
64
64
  degree: l.roundPrecision(d, e),
65
65
  minute: l.roundPrecision(c, e),
66
66
  second: l.roundPrecision(i, e),
67
- pretty: p
67
+ pretty: f
68
68
  };
69
69
  }
70
70
  /**
@@ -79,13 +79,13 @@ class l {
79
79
  t < 0 && (s = "S"), t = Math.abs(t), n = n.toUpperCase();
80
80
  let o = t * 3600, i, r, c, a, d, u;
81
81
  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, e).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, e).toString().padStart(2, "0") : u = l.padNumber(d, 2, 2);
82
- const p = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${s}`;
82
+ const f = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${s}`;
83
83
  return {
84
84
  direction: s,
85
85
  degree: l.roundPrecision(d, e),
86
86
  minute: l.roundPrecision(c, e),
87
87
  second: l.roundPrecision(i, e),
88
- pretty: p
88
+ pretty: f
89
89
  };
90
90
  }
91
91
  static str2Lng(t, e = 6) {
@@ -182,7 +182,7 @@ class l {
182
182
  return `${s}.${o}`;
183
183
  }
184
184
  }
185
- class T {
185
+ class b {
186
186
  /**
187
187
  * 计算方位角
188
188
  * @param from 坐标 {lng, lat}
@@ -297,14 +297,14 @@ class T {
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 p = g.lineIntersect(d, u);
301
- let f;
302
- if (p.features.length) {
303
- const v = g.getCoord(p.features[0]);
304
- f = l.roundPrecision(v[1], 8);
300
+ const f = g.lineIntersect(d, u);
301
+ let h;
302
+ if (f.features.length) {
303
+ const P = g.getCoord(f.features[0]);
304
+ h = l.roundPrecision(P[1], 8);
305
305
  } else
306
- f = t[r].lat;
307
- 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]));
306
+ h = t[r].lat;
307
+ c > 0 ? (n.push([180 - 1e-6, h]), s.push([...n]), n = [], n.push([-(180 - 1e-6), h])) : (n.push([-(180 - 1e-6), h]), s.push([...n]), n = [], n.push([180 - 1e-6, h]));
308
308
  }
309
309
  r === t.length - 2 && n.push([i, t[r + 1].lat]);
310
310
  }
@@ -368,8 +368,8 @@ class T {
368
368
  let n = Number.MAX_VALUE, s = 0, o = 0, i, r;
369
369
  return e.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] }, p = { lng: c[d + 1][0], lat: c[d + 1][1] }, f = this.calculatePointToLineDistance(t, u, p);
372
- n > f && (n = f, o = d, s = a, i = this.calculateDistance(u, t), r = this.calculateDistance(p, t));
371
+ const u = { lng: c[d][0], lat: c[d][1] }, f = { lng: c[d + 1][0], lat: c[d + 1][1] }, h = this.calculatePointToLineDistance(t, u, f);
372
+ n > h && (n = h, o = d, s = a, i = this.calculateDistance(u, t), r = this.calculateDistance(f, t));
373
373
  }
374
374
  }), i !== 0 && r !== 0 ? e[s].splice(o + 1, 0, [t.lng, t.lat]) : i === 0 ? e[s].splice(o, 1, [t.lng, t.lat]) : r === 0 && e[s].splice(o + 1, 1, [t.lng, t.lat]), e;
375
375
  }
@@ -380,8 +380,8 @@ class T {
380
380
  */
381
381
  static appendCoordinateToRoute(t, e) {
382
382
  t.lng = l.convertToStdLng(t.lng, 8);
383
- const n = T.convertRouteToCoordinates(e);
384
- return n.push(t), T.divideAccordingToLng(n);
383
+ const n = b.convertRouteToCoordinates(e);
384
+ return n.push(t), b.divideAccordingToLng(n);
385
385
  }
386
386
  /**
387
387
  * 向route头加1个坐标
@@ -389,8 +389,8 @@ class T {
389
389
  * @param route
390
390
  */
391
391
  static unshiftCoordinateToRoute(t, e) {
392
- const n = T.convertRouteToCoordinates(e);
393
- return n.unshift(t), T.divideAccordingToLng(n);
392
+ const n = b.convertRouteToCoordinates(e);
393
+ return n.unshift(t), b.divideAccordingToLng(n);
394
394
  }
395
395
  /**
396
396
  * 合并多个waypoints进航线
@@ -464,8 +464,8 @@ class T {
464
464
  * @return [[[lng, lat]]]
465
465
  */
466
466
  static calculateSubRoute(t, e) {
467
- const n = T.convertRouteToCoordinates(e);
468
- T.mergeCoordinateToWaypoints(t, n, !0), e = T.divideAccordingToLng(n);
467
+ const n = b.convertRouteToCoordinates(e);
468
+ b.mergeCoordinateToWaypoints(t, n, !0), e = b.divideAccordingToLng(n);
469
469
  const { segIndex: s, minIndex: o } = this.calculateMinDistanceToRoute({ ...t }, e);
470
470
  t.lng = l.convertToStdLng(t.lng);
471
471
  const i = [];
@@ -621,20 +621,20 @@ class T {
621
621
  * @return { coordinate: {lng, lat}, route: [[[lng, lat]]]}
622
622
  */
623
623
  static calculateNextCoordinateAlongRoute(t, e, n, s = "nauticalmiles") {
624
- var p;
624
+ var f;
625
625
  const o = t.speed || 12, i = [];
626
626
  let r = [], c = !1, a = 0, d = 0, u;
627
- if (e && n.length ? (i.push(t), n.forEach((f, v) => {
627
+ if (e && n.length ? (i.push(t), n.forEach((h, P) => {
628
628
  if (c)
629
- r.push(f);
629
+ r.push(h);
630
630
  else {
631
631
  const m = [];
632
632
  let S;
633
- for (let C = 0; C < f.length; C++)
633
+ for (let M = 0; M < h.length; M++)
634
634
  if (u)
635
- m.push(f[C]);
635
+ m.push(h[M]);
636
636
  else {
637
- S = { lng: f[C][0], lat: f[C][1] };
637
+ S = { lng: h[M][0], lat: h[M][1] };
638
638
  const D = this.calculateDistance(t, S, !0, 8, s);
639
639
  if (a += D, a < e)
640
640
  d += D, i.push(S), t = S;
@@ -642,18 +642,18 @@ class T {
642
642
  if (d = e, a === e)
643
643
  u = S, m.push([u.lng, u.lat]);
644
644
  else {
645
- const b = a - e, h = this.calculateBearing(S, t);
646
- u = this.calculateCoordinate(S, h, b, s), m.push([u.lng, u.lat]), m.push([S.lng, S.lat]);
645
+ const v = a - e, p = this.calculateBearing(S, t);
646
+ u = this.calculateCoordinate(S, p, v, s), m.push([u.lng, u.lat]), m.push([S.lng, S.lat]);
647
647
  }
648
648
  c = !0;
649
649
  }
650
650
  }
651
- m.length && r.push(m), v === n.length - 1 && !u && (u = S);
651
+ m.length && r.push(m), P === n.length - 1 && !u && (u = S);
652
652
  }
653
653
  })) : (r = n, u = { ...t }), u)
654
- if (i.push(u), u.distanceFromPrevious = d, u.hourFromPrevious = Math.round(d / o * 1e4) / 1e4, ((p = r[0]) == null ? void 0 : p.length) > 1) {
655
- const f = { lng: r[0][1][0], lat: r[0][1][1] };
656
- u.bearing = this.calculateBearing(u, f);
654
+ if (i.push(u), u.distanceFromPrevious = d, u.hourFromPrevious = Math.round(d / o * 1e4) / 1e4, ((f = r[0]) == null ? void 0 : f.length) > 1) {
655
+ const h = { lng: r[0][1][0], lat: r[0][1][1] };
656
+ u.bearing = this.calculateBearing(u, h);
657
657
  } else
658
658
  u.bearing = 0;
659
659
  return { coordinate: u, nextRoute: r, prevRoute: i };
@@ -668,8 +668,8 @@ class T {
668
668
  const s = l.convertToStdLng(t.lng, 6), o = g.point([s, t.lat]), i = l.convertToStdLng(e.lng, 6), r = l.convertToStdLng(n.lng, 6), c = g.lineString([
669
669
  [i, e.lat],
670
670
  [r, n.lat]
671
- ]), a = g.nearestPointOnLine(c, o), d = g.getCoord(a), u = l.roundPrecision(d[0], 6), p = l.roundPrecision(d[1], 6);
672
- return { lng: u, lat: p, inline: !(u === i && p === e.lat) && !(u === r && p === n.lat) };
671
+ ]), a = g.nearestPointOnLine(c, o), d = g.getCoord(a), u = l.roundPrecision(d[0], 6), f = l.roundPrecision(d[1], 6);
672
+ return { lng: u, lat: f, inline: !(u === i && f === e.lat) && !(u === r && f === n.lat) };
673
673
  }
674
674
  /**
675
675
  * 将route转coordinate
@@ -771,10 +771,32 @@ class T {
771
771
  const e = this.generateRouteAccordingToWaypoints(t);
772
772
  return this.calculateBBox(e);
773
773
  }
774
+ /**
775
+ * 抽稀 三点抽稀, 对比A,B,C; 基于三点距离及夹角抽稀
776
+ * @param coordinates
777
+ * @param distance 三点最小距离, 小于此距离时,B点将被忽略(三点太近)
778
+ * @param angle 三点夹角, 大于此角度时,B点将被忽略(近似走RL)
779
+ */
780
+ static simplifyCoordinates(t, e = 10, n = 160) {
781
+ const s = [];
782
+ for (let o = 1; o < t.length; o++) {
783
+ const i = t[o - 1], r = t[o], c = t[o + 1];
784
+ let a = !1, d = !1;
785
+ if ((i.velocity || i.suspend || i.important || i.pilot || o === 1) && (a = !0, s.push(i)), r.gcToPrevious && (a || (a = !0, s.push(i)), d = !0, s.push(r), o++), c) {
786
+ const u = b.calculateDistance(i, r, !0), f = b.calculateDistance(r, c, !0), h = b.calculateDistance(i, c, !0), P = (Math.pow(u, 2) + Math.pow(f, 2) - Math.pow(h, 2)) / (2 * u * f);
787
+ Math.round(Math.acos(P) * 180 / Math.PI) < n && h > e && !d && (s.push(r), o++);
788
+ }
789
+ if (o >= t.length - 1) {
790
+ const u = t.at(-1);
791
+ u && s.push(u);
792
+ }
793
+ }
794
+ return s;
795
+ }
774
796
  }
775
- let P;
797
+ let T;
776
798
  try {
777
- P = O.getLogger("vessel");
799
+ T = O.getLogger("vessel");
778
800
  } catch {
779
801
  } finally {
780
802
  }
@@ -808,12 +830,12 @@ class q {
808
830
  for (const d in i == null ? void 0 : i.hours) {
809
831
  const u = i.hours[d];
810
832
  u.wind.spd = u.wind.spd || u.wind.speed;
811
- const p = c.clone().add(Number(d), "hour"), f = g.point([u.lng, u.lat], {
833
+ const f = c.clone().add(Number(d), "hour"), h = g.point([u.lng, u.lat], {
812
834
  model: i.model,
813
835
  name: s.name,
814
- date: p.format(),
836
+ date: f.format(),
815
837
  hour: Number(d),
816
- format: p.format("MMM-DD/HHmm[Z]"),
838
+ format: f.format("MMM-DD/HHmm[Z]"),
817
839
  pressure: u.pressure > 1e4 ? l.roundPrecision(u.pressure / 100, 0) : l.roundPrecision(u.pressure, 0),
818
840
  gusts: u.gusts,
819
841
  wind: u.wind || {},
@@ -821,7 +843,7 @@ class q {
821
843
  category: a,
822
844
  type: "forecast"
823
845
  });
824
- e.features.push(f), r.push(f.geometry.coordinates);
846
+ e.features.push(h), r.push(h.geometry.coordinates);
825
847
  }
826
848
  if ((r == null ? void 0 : r.length) > 1) {
827
849
  const d = g.lineString(l.convertToMonotonicLng2(r), {
@@ -881,34 +903,32 @@ class q {
881
903
  var o, i, r, c;
882
904
  const n = (o = t == null ? void 0 : t.data) == null ? void 0 : o.features.filter((a) => a.geometry.type === "LineString" && a.properties.type === "forecast"), s = [];
883
905
  for (const a of n) {
884
- const d = a.properties.name, u = a.properties.model, p = a.properties.showCircle, f = a.properties.disabled, v = R(a.properties.date).utc();
885
- let m = e * 60 - (v.get("hour") * 60 + v.get("minute")) % (e * 60);
906
+ const d = a.properties.name, u = a.properties.model, f = a.properties.showCircle, h = a.properties.disabled, P = R(a.properties.date).utc();
907
+ let m = e * 60 - (P.get("hour") * 60 + P.get("minute")) % (e * 60);
886
908
  const S = (i = t == null ? void 0 : t.data) == null ? void 0 : i.features.filter(
887
- (b) => b.geometry.type === "Point" && b.properties.type === "forecast" && b.properties.category === `${d}-${u}`
909
+ (v) => v.geometry.type === "Point" && v.properties.type === "forecast" && v.properties.category === `${d}-${u}`
888
910
  );
889
- let C, D = v.clone().add(m, "minute").set({ minute: 0, second: 0, millisecond: 0 });
890
- for (; C = this.pickIndex(S, D), C <= S.length - 1; ) {
891
- if (C > 0) {
892
- const b = S[C], h = C === 0 ? void 0 : S[C - 1];
893
- C === this.pickIndex(S, D) && (b == null ? void 0 : b.properties.category) === "yagi-cma" && console.log(D.format(), h, h == null ? void 0 : h.properties.wind, b, b.properties.wind);
894
- const N = (m / 60 - ((r = h == null ? void 0 : h.properties) == null ? void 0 : r.hour)) / (b.properties.hour - ((c = h == null ? void 0 : h.properties) == null ? void 0 : c.hour)), x = this.computeNumber(h == null ? void 0 : h.geometry.coordinates[0], b.geometry.coordinates[0], N), $ = this.computeNumber(h == null ? void 0 : h.geometry.coordinates[1], b.geometry.coordinates[1], N), W = g.point([x, $], {
911
+ let M, D = P.clone().add(m, "minute").set({ minute: 0, second: 0, millisecond: 0 });
912
+ for (; M = this.pickIndex(S, D), M <= S.length - 1; ) {
913
+ if (M > 0) {
914
+ const v = S[M], p = M === 0 ? void 0 : S[M - 1], N = (m / 60 - ((r = p == null ? void 0 : p.properties) == null ? void 0 : r.hour)) / (v.properties.hour - ((c = p == null ? void 0 : p.properties) == null ? void 0 : c.hour)), I = this.computeNumber(p == null ? void 0 : p.geometry.coordinates[0], v.geometry.coordinates[0], N), $ = this.computeNumber(p == null ? void 0 : p.geometry.coordinates[1], v.geometry.coordinates[1], N), W = g.point([I, $], {
895
915
  name: d,
896
916
  model: u,
897
- category: b == null ? void 0 : b.properties.category,
917
+ category: v == null ? void 0 : v.properties.category,
898
918
  date: D.format(),
899
919
  format: D.format("MMM-DD/HHmm[Z]"),
900
- gusts: this.computeNumber(h == null ? void 0 : h.properties.gusts, b.properties.gusts, N),
901
- hour: this.computeNumber(h == null ? void 0 : h.properties.hour, b.properties.hour, N),
902
- movement: this.computeNumber(h == null ? void 0 : h.properties.movement, b.properties.movement, N),
903
- pressure: this.computeNumber(h == null ? void 0 : h.properties.pressure, b.properties.pressure, N),
904
- wind: this.computeNumber(h == null ? void 0 : h.properties.wind, b.properties.wind, N),
920
+ gusts: this.computeNumber(p == null ? void 0 : p.properties.gusts, v.properties.gusts, N),
921
+ hour: this.computeNumber(p == null ? void 0 : p.properties.hour, v.properties.hour, N),
922
+ movement: this.computeNumber(p == null ? void 0 : p.properties.movement, v.properties.movement, N),
923
+ pressure: this.computeNumber(p == null ? void 0 : p.properties.pressure, v.properties.pressure, N),
924
+ wind: this.computeNumber(p == null ? void 0 : p.properties.wind, v.properties.wind, N),
905
925
  type: "forecast",
906
- disabled: f,
907
- showCircle: p
926
+ disabled: h,
927
+ showCircle: f
908
928
  });
909
929
  s.push(W);
910
930
  }
911
- m += e * 60, D = v.clone().add(m, "minute").set({ minute: 0, second: 0, millisecond: 0 });
931
+ m += e * 60, D = P.clone().add(m, "minute").set({ minute: 0, second: 0, millisecond: 0 });
912
932
  }
913
933
  }
914
934
  return s;
@@ -938,28 +958,28 @@ class q {
938
958
  const { t1: o, t2: i, hr: r, hours: c } = this.tropicalCenterTwin(e, 24, s);
939
959
  if (o && i) {
940
960
  if (!s.debug) {
941
- const v = T.calculateDistance(t, o), m = T.calculateDistance(t, i);
942
- if (v > 2 * n && m > 2 * n)
943
- return P == null || P.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", s.requestId, v, m, {
961
+ const P = b.calculateDistance(t, o), m = b.calculateDistance(t, i);
962
+ if (P > 2 * n && m > 2 * n)
963
+ return T == null || T.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", s.requestId, P, m, {
944
964
  from: t,
945
965
  t1: o,
946
966
  t2: i,
947
967
  hr: r
948
968
  }), {};
949
969
  }
950
- const a = T.calculateBearing(t, o), d = T.calculateBearing(o, i), u = Math.abs(a - d);
951
- let p = 0;
952
- u < 180 ? p = u + 90 : u >= 180 && (p = u - 90);
953
- const f = T.calculateCoordinate(o, p, n);
954
- return P == null || P.info("[%s] the right tangent position: %j", s.requestId, {
970
+ const a = b.calculateBearing(t, o), d = b.calculateBearing(o, i), u = Math.abs(a - d);
971
+ let f = 0;
972
+ u < 180 ? f = u + 90 : u >= 180 && (f = u - 90);
973
+ const h = b.calculateCoordinate(o, f, n);
974
+ return T == null || T.info("[%s] the right tangent position: %j", s.requestId, {
955
975
  from: t,
956
976
  t1: o,
957
977
  t2: i,
958
978
  radius: n,
959
979
  bearing1: a,
960
980
  bearing2: d,
961
- right: f
962
- }), { at: f, t1: o, t2: i, hr: Number(r), hours: c };
981
+ right: h
982
+ }), { at: h, t1: o, t2: i, hr: Number(r), hours: c };
963
983
  }
964
984
  return {};
965
985
  }
@@ -977,19 +997,19 @@ class q {
977
997
  const { t1: o, t2: i, hr: r, hours: c } = this.tropicalCenterTwin(e, 24, s);
978
998
  if (o && i) {
979
999
  if (!s.debug) {
980
- const f = T.calculateDistance(t, o), v = T.calculateDistance(t, i);
981
- if (f > 2 * n && v > 2 * n)
982
- return P == null || P.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", s.requestId, f, v, {
1000
+ const h = b.calculateDistance(t, o), P = b.calculateDistance(t, i);
1001
+ if (h > 2 * n && P > 2 * n)
1002
+ return T == null || T.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", s.requestId, h, P, {
983
1003
  from: t,
984
1004
  t1: o,
985
1005
  t2: i,
986
1006
  hr: r
987
1007
  }), {};
988
1008
  }
989
- const a = T.calculateBearing(t, o), d = T.calculateBearing(o, i), u = T.calculateDistance(t, o);
990
- return { at: T.calculateCoordinate(o, a - d + 180, n < u ? n : u), t1: o, t2: i, hr: Number(r), hours: c };
1009
+ const a = b.calculateBearing(t, o), d = b.calculateBearing(o, i), u = b.calculateDistance(t, o);
1010
+ return { at: b.calculateCoordinate(o, a - d + 180, n < u ? n : u), t1: o, t2: i, hr: Number(r), hours: c };
991
1011
  } else
992
- return P == null || P.info("[%s] no need drift: %j", s.requestId, { from: t, t1: o, t2: i, hr: r }), {};
1012
+ return T == null || T.info("[%s] no need drift: %j", s.requestId, { from: t, t1: o, t2: i, hr: r }), {};
993
1013
  }
994
1014
  /**
995
1015
  * 获取台风中心点对
@@ -1000,17 +1020,17 @@ class q {
1000
1020
  * @private
1001
1021
  */
1002
1022
  static tropicalCenterTwin(t, e = 24, n = {}) {
1003
- var d, u, p, f, v;
1023
+ var d, u, f, h, P;
1004
1024
  let s = {};
1005
1025
  (d = t.forecasts) == null || d.forEach((m) => {
1006
1026
  s = { ...m.hours, ...s };
1007
1027
  });
1008
- const o = ((u = t == null ? void 0 : t.history) == null ? void 0 : u[0]) || (s == null ? void 0 : s[(p = Object.keys(s)) == null ? void 0 : p[0]]);
1009
- P == null || P.info("[%s] the first tropical center: %j", n.requestId, o);
1010
- let i = (f = Object.keys(s || {}).filter((m) => Number(m) <= (e < 0 ? 24 : e))) == null ? void 0 : f.at(-1);
1011
- i || (i = (v = Object.keys(s || {}).filter((m) => Number(m) <= (e < 0 ? 24 : 2 * e))) == null ? void 0 : v.at(-1));
1028
+ const o = ((u = t == null ? void 0 : t.history) == null ? void 0 : u[0]) || (s == null ? void 0 : s[(f = Object.keys(s)) == null ? void 0 : f[0]]);
1029
+ T == null || T.info("[%s] the first tropical center: %j", n.requestId, o);
1030
+ let i = (h = Object.keys(s || {}).filter((m) => Number(m) <= (e < 0 ? 24 : e))) == null ? void 0 : h.at(-1);
1031
+ i || (i = (P = Object.keys(s || {}).filter((m) => Number(m) <= (e < 0 ? 24 : 2 * e))) == null ? void 0 : P.at(-1));
1012
1032
  const r = s == null ? void 0 : s[i || -1];
1013
- P == null || P.info("[%s] the second tropical center: %j in %d hrs", n.requestId, r, i);
1033
+ T == null || T.info("[%s] the second tropical center: %j in %d hrs", n.requestId, r, i);
1014
1034
  const c = Object.keys(s || {}).filter((m) => Number(m) <= Number(i)), a = { 0: o };
1015
1035
  for (const m of c)
1016
1036
  a[m] = s[m];
@@ -1042,7 +1062,7 @@ class q {
1042
1062
  }
1043
1063
  }
1044
1064
  export {
1045
- T as LaneHelper,
1065
+ b as LaneHelper,
1046
1066
  l as LngLatHelper,
1047
1067
  q as TropicalHelper
1048
1068
  };
@@ -1 +1 @@
1
- (function(D,I){typeof exports=="object"&&typeof module<"u"?I(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"],I):(D=typeof globalThis<"u"?globalThis:D||self,I(D["idm-plugin-rabbitmq"]={},D["@turf/turf"],D.moment,D["moment-timezone"],D["tz-lookup"]))})(this,function(D,I,R,q,j){"use strict";function k(v){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(v){for(const t in v)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(v,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>v[t]})}}return e.default=v,Object.freeze(e)}const g=k(I);function O(v){return v&&v.__esModule&&Object.prototype.hasOwnProperty.call(v,"default")?v.default:v}class x{log(){}isLevelEnabled(){return!1}addContext(){}removeContext(){}clearContext(){}}["Trace","Debug","Info","Warn","Error","Fatal","Mark"].forEach(v=>{x.prototype[v.toLowerCase()]=()=>{},x.prototype[`is${v}Enabled`]=()=>!1});const $=(()=>{try{return require("log4js")}catch{return null}})();var W={getLogger:$?$.getLogger:()=>new x};const L=O(W);class l{static guessTimeZoneOffset(e,t){const n=j(t,e),s=R().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=6){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 T{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),e[r].lat=l.roundPrecision(e[r].lat,8),e[r+1].lat=l.roundPrecision(e[r+1].lat,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 h;if(p.features.length){const S=g.getCoord(p.features[0]);h=l.roundPrecision(S[1],8)}else h=e[r].lat;c>0?(n.push([180-1e-6,h]),s.push([...n]),n=[],n.push([-(180-1e-6),h])):(n.push([-(180-1e-6),h]),s.push([...n]),n=[],n.push([180-1e-6,h]))}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]},h=this.calculatePointToLineDistance(e,u,p);n>h&&(n=h,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=T.convertRouteToCoordinates(t);return n.push(e),T.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=T.convertRouteToCoordinates(t);return n.unshift(e),T.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 n=T.convertRouteToCoordinates(t);T.mergeCoordinateToWaypoints(e,n,!0),t=T.divideAccordingToLng(n);const{segIndex:s,minIndex:o}=this.calculateMinDistanceToRoute({...e},t);e.lng=l.convertToStdLng(e.lng);const i=[];let r=!0;for(let c=s;c<t.length;c++)if(r){const a=[];a.push([e.lng,e.lat]);for(let d=o+1;d<t[c].length;d++)e.lng===t[c][d][0]&&e.lat===t[c][d][1]||a.push(t[c][d]);i.push(a),r=!1}else i.push([...t[c]]);return i}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,8),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]),o=this.convertRouteToCoordinates(t).map(a=>[a.lng,a.lat]),i=g.lineString(o),r=g.nearestPointOnLine(i,n),c=g.getCoord(r);return{lng:l.roundPrecision(c[0],8),lat:l.roundPrecision(c[1],8)}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let s=0;s<t.length-1;s++){const o=t[s],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((h,S)=>{if(c)r.push(h);else{const m=[];let C;for(let M=0;M<h.length;M++)if(u)m.push(h[M]);else{C={lng:h[M][0],lat:h[M][1]};const N=this.calculateDistance(e,C,!0,8,s);if(a+=N,a<t)d+=N,i.push(C),e=C;else{if(d=t,a===t)u=C,m.push([u.lng,u.lat]);else{const b=a-t,f=this.calculateBearing(C,e);u=this.calculateCoordinate(C,f,b,s),m.push([u.lng,u.lat]),m.push([C.lng,C.lat])}c=!0}}m.length&&r.push(m),S===n.length-1&&!u&&(u=C)}})):(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 h={lng:r[0][1][0],lat:r[0][1][1]};u.bearing=this.calculateBearing(u,h)}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:l.roundPrecision(r[0],8),lat:l.roundPrecision(r[1],8)};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,!0)});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)}}let P;try{P=L.getLogger("vessel")}catch{}finally{}class A{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=R(i.date).utc(),a=`${s.name}-${i.model}`;if(o){const d=R(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:o==null?void 0:o.wind,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"),h=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(h),r.push(h.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=R(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`,wind:r.wind});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,h=a.properties.disabled,S=R(a.properties.date).utc();let m=t*60-(S.get("hour")*60+S.get("minute"))%(t*60);const C=(i=e==null?void 0:e.data)==null?void 0:i.features.filter(b=>b.geometry.type==="Point"&&b.properties.type==="forecast"&&b.properties.category===`${d}-${u}`);let M,N=S.clone().add(m,"minute").set({minute:0,second:0,millisecond:0});for(;M=this.pickIndex(C,N),M<=C.length-1;){if(M>0){const b=C[M],f=M===0?void 0:C[M-1];M===this.pickIndex(C,N)&&(b==null?void 0:b.properties.category)==="yagi-cma"&&console.log(N.format(),f,f==null?void 0:f.properties.wind,b,b.properties.wind);const y=(m/60-((r=f==null?void 0:f.properties)==null?void 0:r.hour))/(b.properties.hour-((c=f==null?void 0:f.properties)==null?void 0:c.hour)),E=this.computeNumber(f==null?void 0:f.geometry.coordinates[0],b.geometry.coordinates[0],y),F=this.computeNumber(f==null?void 0:f.geometry.coordinates[1],b.geometry.coordinates[1],y),B=g.point([E,F],{name:d,model:u,category:b==null?void 0:b.properties.category,date:N.format(),format:N.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(f==null?void 0:f.properties.gusts,b.properties.gusts,y),hour:this.computeNumber(f==null?void 0:f.properties.hour,b.properties.hour,y),movement:this.computeNumber(f==null?void 0:f.properties.movement,b.properties.movement,y),pressure:this.computeNumber(f==null?void 0:f.properties.pressure,b.properties.pressure,y),wind:this.computeNumber(f==null?void 0:f.properties.wind,b.properties.wind,y),type:"forecast",disabled:h,showCircle:p});s.push(B)}m+=t*60,N=S.clone().add(m,"minute").set({minute:0,second:0,millisecond:0})}}return s}static accelPassageAt(e,t){const{t1:n,t2:s,hr:o,hours:i}=this.tropicalCenterTwin(e,24,t);return{t1:n,t2:s,hr:o,hours:i}}static diversionPassageAt(e,t,n,s={}){const{t1:o,t2:i,hr:r,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&i){if(!s.debug){const S=T.calculateDistance(e,o),m=T.calculateDistance(e,i);if(S>2*n&&m>2*n)return P==null||P.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j",s.requestId,S,m,{from:e,t1:o,t2:i,hr:r}),{}}const a=T.calculateBearing(e,o),d=T.calculateBearing(o,i),u=Math.abs(a-d);let p=0;u<180?p=u+90:u>=180&&(p=u-90);const h=T.calculateCoordinate(o,p,n);return P==null||P.info("[%s] the right tangent position: %j",s.requestId,{from:e,t1:o,t2:i,radius:n,bearing1:a,bearing2:d,right:h}),{at:h,t1:o,t2:i,hr:Number(r),hours:c}}return{}}static driftPassageAt(e,t,n,s={}){const{t1:o,t2:i,hr:r,hours:c}=this.tropicalCenterTwin(t,24,s);if(o&&i){if(!s.debug){const h=T.calculateDistance(e,o),S=T.calculateDistance(e,i);if(h>2*n&&S>2*n)return P==null||P.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j",s.requestId,h,S,{from:e,t1:o,t2:i,hr:r}),{}}const a=T.calculateBearing(e,o),d=T.calculateBearing(o,i),u=T.calculateDistance(e,o);return{at:T.calculateCoordinate(o,a-d+180,n<u?n:u),t1:o,t2:i,hr:Number(r),hours:c}}else return P==null||P.info("[%s] no need drift: %j",s.requestId,{from:e,t1:o,t2:i,hr:r}),{}}static tropicalCenterTwin(e,t=24,n={}){var d,u,p,h,S;let s={};(d=e.forecasts)==null||d.forEach(m=>{s={...m.hours,...s}});const o=((u=e==null?void 0:e.history)==null?void 0:u[0])||(s==null?void 0:s[(p=Object.keys(s))==null?void 0:p[0]]);P==null||P.info("[%s] the first tropical center: %j",n.requestId,o);let i=(h=Object.keys(s||{}).filter(m=>Number(m)<=(t<0?24:t)))==null?void 0:h.at(-1);i||(i=(S=Object.keys(s||{}).filter(m=>Number(m)<=(t<0?24:2*t)))==null?void 0:S.at(-1));const r=s==null?void 0:s[i||-1];P==null||P.info("[%s] the second tropical center: %j in %d hrs",n.requestId,r,i);const c=Object.keys(s||{}).filter(m=>Number(m)<=Number(i)),a={0:o};for(const m of c)a[m]=s[m];return{t1:o,t2:r,hr:Number(i),hours:a}}static pickIndex(e,t){let n=0;for(const s of e){if(R(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}}D.LaneHelper=T,D.LngLatHelper=l,D.TropicalHelper=A,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
1
+ (function(M,I){typeof exports=="object"&&typeof module<"u"?I(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"],I):(M=typeof globalThis<"u"?globalThis:M||self,I(M["idm-plugin-rabbitmq"]={},M["@turf/turf"],M.moment,M["moment-timezone"],M["tz-lookup"]))})(this,function(M,I,R,q,j){"use strict";function O(v){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(v){for(const e in v)if(e!=="default"){const n=Object.getOwnPropertyDescriptor(v,e);Object.defineProperty(t,e,n.get?n:{enumerable:!0,get:()=>v[e]})}}return t.default=v,Object.freeze(t)}const g=O(I);function W(v){return v&&v.__esModule&&Object.prototype.hasOwnProperty.call(v,"default")?v.default:v}class x{log(){}isLevelEnabled(){return!1}addContext(){}removeContext(){}clearContext(){}}["Trace","Debug","Info","Warn","Error","Fatal","Mark"].forEach(v=>{x.prototype[v.toLowerCase()]=()=>{},x.prototype[`is${v}Enabled`]=()=>!1});const $=(()=>{try{return require("log4js")}catch{return null}})();var k={getLogger:$?$.getLogger:()=>new x};const A=W(k);class l{static guessTimeZoneOffset(t,e){const n=j(e,t),s=R().tz(n).utcOffset();return this.roundPrecision(s/60,1)}static prettyTimeZoneOffset(t){let e=Math.floor(Math.abs(t)),n=Math.round((Math.abs(t)-e)*60);return n=n>9?n:`0${n}`,e=e>9?e:`0${e}`,t>0?`+${e}:${n}`:`-${e}:${n}`}static lng2pretty(t,e=6,n="H°M′"){t=l.convertToStdLng(t,e);let s="E";t<0&&(s="W"),t=Math.abs(t),n=n.toUpperCase();let o=t*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,e).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,e).toString().padStart(3,"0"):u=l.padNumber(d,3,2);const f=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:l.roundPrecision(d,e),minute:l.roundPrecision(c,e),second:l.roundPrecision(i,e),pretty:f}}static lat2pretty(t,e=6,n="H°M′"){t=t%180;let s="N";t<0&&(s="S"),t=Math.abs(t),n=n.toUpperCase();let o=t*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,e).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,e).toString().padStart(2,"0"):u=l.padNumber(d,2,2);const f=`${n.replace(/S+/gi,r).replace(/M+/gi,a).replace(/H+/gi,u)}${s}`;return{direction:s,degree:l.roundPrecision(d,e),minute:l.roundPrecision(c,e),second:l.roundPrecision(i,e),pretty:f}}static str2Lng(t,e=6){let n;if(isNaN(t)){t=l.strReplace(t,"LNG");const s=t[t.length-1].toUpperCase();t=t.substring(0,t.length-1).trim();const o=t.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(t);return l.convertToStdLng(n,e)}static str2Lat(t,e=6){let n;if(isNaN(t)){t=l.strReplace(t,"LAT");const s=t[t.length-1].toUpperCase();t=t.substring(0,t.length-1).trim();const o=t.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(t);return l.roundPrecision(n,e)}static str2LngOrLat(t,e=6,n="LAT"){t=l.strReplace(t,n);const s=t[t.length-1].toUpperCase();return["N","S"].includes(s)?{lat:l.str2Lat(t,e)}:{lng:l.str2Lng(t,e)}}static convertToStdLng(t,e=6){return t>180?(t=t%360,t=t>180?t-360:t):t<-180&&(t=t%360,t=t<-180?t+360:t),l.roundPrecision(t,e)}static roundPrecision(t,e=4){if(typeof t=="number"){const n=Number("1".padEnd(e+1,"0"));return Math.round(t*n)/n}return t}static convertToMonotonicLng2(t){for(let e=1;e<t.length;e++)t[e][0]+=Math.round((t[e-1][0]-t[e][0])/360)*360;return t}static convertToMonotonicLng(t){for(let e=1;e<t.length;e++)t[e].lng+=Math.round((t[e-1].lng-t[e].lng)/360)*360;return t}static strReplace(t,e="LAT"){t=t.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=t[t.length-1].toUpperCase();if(!["N","S","E","W"].includes(n)){const s=t,o=Number(s.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${t}`);o>=90?t=`${s}E`:o<=-90?t=`${s}W`:["LAN","LNG"].includes(e==null?void 0:e.toUpperCase())?t=`${s}${o>0?"E":"W"}`:t=`${s}${o>0?"N":"S"}`}return t}static padNumber(t,e=2,n=2){const s=Math.trunc(t).toString().padStart(e,"0"),o=Math.trunc(l.roundPrecision(t-Math.trunc(t),n)*Math.pow(10,n)).toString().padStart(n,"0");return`${s}.${o}`}}class b{static calculateBearing(t,e,n=!0,s=4){const o=g.points([[t.lng,t.lat],[e.lng,e.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(t,e,n=!0,s=4,o="nauticalmiles"){t={...t},e={...e},t.lng=l.convertToStdLng(t.lng,s),e.lng=l.convertToStdLng(e.lng,s);const i=g.points([[t.lng,t.lat],[e.lng,e.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(t,e=4,n="nauticalmiles"){let s=0,o;for(const i of t)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,e,n));const a={lng:i[r+1][0],lat:i[r+1][1]};s+=this.calculateDistance(c,a,!0,e,n),o=a}return l.roundPrecision(s,e)}static calculateCoordinate(t,e,n,s="nauticalmiles",o=!0){const i=g.point([t.lng,t.lat]);let r;o?r=g.rhumbDestination(i,n,e,{units:s}):r=g.destination(i,n,e,{units:s});const c=r.geometry.coordinates;return{lng:l.convertToStdLng(c[0],8),lat:l.roundPrecision(c[1],8)}}static interpolateCoordinates(t,e,n,s=!0,o=!0,i="nauticalmiles"){const r=[],c=this.calculateBearing(t,e,!1),a=this.calculateDistance(t,e,!1,8,i);s&&r.push({lng:t.lng,lat:t.lat});let d=0;for(;d<a;)d+=n,d<a&&r.push(this.calculateCoordinate(t,c,d,i,!1));return o&&r.push({lng:e.lng,lat:e.lat}),r}static divideAccordingToLng(t,e=!1){if((t==null?void 0:t.length)<2)return[];t=this.deduplicateCoordinates(t);let n=[];const s=[];let o,i;for(let r=0;r<t.length-1;r++){o=l.convertToStdLng(t[r].lng,8),i=l.convertToStdLng(t[r+1].lng,8),t[r].lat=l.roundPrecision(t[r].lat,8),t[r+1].lat=l.roundPrecision(t[r+1].lat,8),n.push([o,t[r].lat]);const c=o-i;if(Math.abs(c)>180){const a=l.convertToMonotonicLng2([[o,t[r].lat],[i,t[r+1].lat]]);let d,u;e?(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 f=g.lineIntersect(d,u);let h;if(f.features.length){const P=g.getCoord(f.features[0]);h=l.roundPrecision(P[1],8)}else h=t[r].lat;c>0?(n.push([180-1e-6,h]),s.push([...n]),n=[],n.push([-(180-1e-6),h])):(n.push([-(180-1e-6),h]),s.push([...n]),n=[],n.push([180-1e-6,h]))}r===t.length-2&&n.push([i,t[r+1].lat])}return s.push(n),s}static deduplicateRoute(t){const e=[];for(const n of t){const s=n.reduce((o,i)=>(o.findIndex(r=>r[0]===i[0]&&r[1]===i[1])===-1&&o.push(i),o),[]);e.push(s)}return e}static deduplicateCoordinates(t){return t.reduce((e,n)=>(e.findIndex(s=>s.lat===n.lat&&s.lng===n.lng)===-1&&e.push(n),e),[])}static removeCoordinateFromRoute(t,e){t.lng=l.convertToStdLng(t.lng,8);for(const n of e)for(let s=n.length-1;s>=0;s--)l.roundPrecision(n[s][0],8)===t.lng&&l.roundPrecision(n[s][1],8)===l.roundPrecision(t.lat,8)&&n.splice(s,1);return e}static removeCoordinateFromWaypoints(t,e){t.lng=l.convertToStdLng(t.lng,8);for(let n=e.length-1;n>=0;n--)l.roundPrecision(e[n].lng,8)===t.lng&&l.roundPrecision(e[n].lat,8)===l.roundPrecision(t.lat,8)&&e.splice(n,1);return e}static mergeCoordinateToRoute(t,e){t.lng=l.convertToStdLng(t.lng,8);let n=Number.MAX_VALUE,s=0,o=0,i,r;return e.forEach((c,a)=>{for(let d=0;d<c.length-1;d++){const u={lng:c[d][0],lat:c[d][1]},f={lng:c[d+1][0],lat:c[d+1][1]},h=this.calculatePointToLineDistance(t,u,f);n>h&&(n=h,o=d,s=a,i=this.calculateDistance(u,t),r=this.calculateDistance(f,t))}}),i!==0&&r!==0?e[s].splice(o+1,0,[t.lng,t.lat]):i===0?e[s].splice(o,1,[t.lng,t.lat]):r===0&&e[s].splice(o+1,1,[t.lng,t.lat]),e}static appendCoordinateToRoute(t,e){t.lng=l.convertToStdLng(t.lng,8);const n=b.convertRouteToCoordinates(e);return n.push(t),b.divideAccordingToLng(n)}static unshiftCoordinateToRoute(t,e){const n=b.convertRouteToCoordinates(e);return n.unshift(t),b.divideAccordingToLng(n)}static mergeWaypointsToRoute(t,e){for(const n of t)e=this.mergeCoordinateToRoute(n,e);return e}static calculateRangeRoute(t,e,n){n=this.mergeWaypointsToRoute([t,e],n);const s=[];let o=0;return n.forEach(i=>{if(o===2)return;const r=[];for(const c of i){if(l.roundPrecision(e.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(c[1],8)){r.push(c),o===0&&r.push([t.lng,t.lat]),o=2;break}o===1?r.push(c):l.roundPrecision(t.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(c[1],8)&&(o=1,r.push(c))}r.length&&s.push(r)}),s}static calculateRangeWaypoints(t,e,n,s=[]){const o=this.convertRouteToCoordinates(n,0),i=this.mergeCoordinatesToWaypoints([t,e,...s],o),r=i.findIndex(d=>l.roundPrecision(t.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(d.lat,8)),c=i.findIndex(d=>l.roundPrecision(e.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(d.lat,8));return i.filter((d,u)=>u>=r&&u<=c)}static calculateMinDistanceToRoute(t,e){let n=Number.MAX_VALUE,s=0,o=0;return e.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(t,a,d);n>u&&(n=u,s=c,o=r)}}),{minDist:n,segIndex:o,minIndex:s}}static calculateSubRoute(t,e){const n=b.convertRouteToCoordinates(e);b.mergeCoordinateToWaypoints(t,n,!0),e=b.divideAccordingToLng(n);const{segIndex:s,minIndex:o}=this.calculateMinDistanceToRoute({...t},e);t.lng=l.convertToStdLng(t.lng);const i=[];let r=!0;for(let c=s;c<e.length;c++)if(r){const a=[];a.push([t.lng,t.lat]);for(let d=o+1;d<e[c].length;d++)t.lng===e[c][d][0]&&t.lat===e[c][d][1]||a.push(e[c][d]);i.push(a),r=!1}else i.push([...e[c]]);return i}static calculateSubWaypoints(t,e){let n=Number.MAX_VALUE,s=0;for(let i=0;i<e.length-1;i++){const r=e[i],c=e[i+1];if(this.calculateDistance(t,r)===0)return e;if(this.calculateDistance(t,c)===0)return e.filter((d,u)=>u>0);const a=this.calculatePointToLineDistance(t,r,c);n>a&&(n=a,s=i)}t.lng=l.convertToStdLng(t.lng);const o=[t];for(let i=s+1;i<e.length;i++)o.push(e[i]);return o}static calculatePointToLineDistance(t,e,n,s={units:"nauticalmiles",method:"geodesic"}){t.lng=l.convertToStdLng(t.lng,8),e={...e},n={...n},e.lng=l.convertToStdLng(e.lng,8),n.lng=l.convertToStdLng(n.lng,8);const o=l.convertToMonotonicLng([e,n]);e=o[0],n=o[1];const i=g.lineString([[e.lng,e.lat],[n.lng,n.lat]]),r=g.pointToLineDistance(g.point([t.lng,t.lat]),i,s),c=g.pointToLineDistance(g.point([t.lng>0?t.lng-360:t.lng+360,t.lat]),i,s);return l.roundPrecision(Math.min(r,c),6)}static calculateWaypointsPropInRoute(t,e){e=this.mergeWaypointsToRoute(t,e);for(let n=0;n<t.length-1;n++){const s=t[n],o=t[n+1],i=this.calculateRangeRoute(s,o,e);n===0&&(s.distanceFromPrevious=0,s.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(i),o.distanceFromStart=l.roundPrecision((s.distanceFromStart||0)+o.distanceFromPrevious)}return t}static mergeCoordinatesToWaypoints(t,e,n=!0){for(const s of t)this.mergeCoordinateToWaypoints(s,e,n);return e}static mergeCoordinateToWaypoints(t,e,n=!0){t.lng=l.convertToStdLng(t.lng,8);let s=Number.MAX_VALUE,o=0,i=0,r=0;for(let c=0;c<e.length-1;c++){const a={lng:e[c].lng,lat:e[c].lat},d={lng:e[c+1].lng,lat:e[c+1].lat},u=this.calculatePointToLineDistance(t,a,d);s>=u&&(s=u,o=c,i=this.calculateDistance(a,t,!1,6),r=this.calculateDistance(d,t,!1,6))}return i!==0&&r!==0?i<s||i===s&&o===0?e.unshift(t):r<s||r===s&&o===e.length-2?e.push(t):e.splice(o+1,0,t):i===0?n&&e.splice(o,1,t):r===0&&n&&e.splice(o+1,1,t),e.map(c=>(c.lng=l.convertToStdLng(c.lng),c))}static generateRouteAccordingToWaypoints(t){const e=[];for(let n=1;n<t.length;n++){const s=t[n-1],o=t[n];if(n===1&&e.push(s),o.gcToPrevious){const i=this.interpolateCoordinates(s,o,200,!1,!0,"nauticalmiles");e.push(...i)}else e.push(o)}return this.divideAccordingToLng(e,!0)}static nearestCoordinateInRoute(t,e){const n=g.point([t.lng,t.lat]),o=this.convertRouteToCoordinates(e).map(a=>[a.lng,a.lat]),i=g.lineString(o),r=g.nearestPointOnLine(i,n),c=g.getCoord(r);return{lng:l.roundPrecision(c[0],8),lat:l.roundPrecision(c[1],8)}}static calculatePrevWaypoint(t,e){let n=0;this.mergeCoordinateToWaypoints(t,e);for(let s=0;s<e.length-1;s++){const o=e[s],i=e[s+1];if(this.calculateDistance(t,o)===0){n=s;break}if(this.calculateDistance(t,i)===0){n=s+1;break}}return e[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(t,e,n,s="nauticalmiles"){var f;const o=t.speed||12,i=[];let r=[],c=!1,a=0,d=0,u;if(e&&n.length?(i.push(t),n.forEach((h,P)=>{if(c)r.push(h);else{const m=[];let C;for(let D=0;D<h.length;D++)if(u)m.push(h[D]);else{C={lng:h[D][0],lat:h[D][1]};const N=this.calculateDistance(t,C,!0,8,s);if(a+=N,a<e)d+=N,i.push(C),t=C;else{if(d=e,a===e)u=C,m.push([u.lng,u.lat]);else{const S=a-e,p=this.calculateBearing(C,t);u=this.calculateCoordinate(C,p,S,s),m.push([u.lng,u.lat]),m.push([C.lng,C.lat])}c=!0}}m.length&&r.push(m),P===n.length-1&&!u&&(u=C)}})):(r=n,u={...t}),u)if(i.push(u),u.distanceFromPrevious=d,u.hourFromPrevious=Math.round(d/o*1e4)/1e4,((f=r[0])==null?void 0:f.length)>1){const h={lng:r[0][1][0],lat:r[0][1][1]};u.bearing=this.calculateBearing(u,h)}else u.bearing=0;return{coordinate:u,nextRoute:r,prevRoute:i}}static nearestCoordinateInLine(t,e,n){const s=l.convertToStdLng(t.lng,6),o=g.point([s,t.lat]),i=l.convertToStdLng(e.lng,6),r=l.convertToStdLng(n.lng,6),c=g.lineString([[i,e.lat],[r,n.lat]]),a=g.nearestPointOnLine(c,o),d=g.getCoord(a),u=l.roundPrecision(d[0],6),f=l.roundPrecision(d[1],6);return{lng:u,lat:f,inline:!(u===i&&f===e.lat)&&!(u===r&&f===n.lat)}}static convertRouteToCoordinates(t,e=0){const n=[];let s,o;return t.forEach(i=>{i.forEach(r=>{const c={lng:l.roundPrecision(r[0],8),lat:l.roundPrecision(r[1],8)};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>=e&&(s.bearing=this.calculateBearing(s,c,!0),n.push(s),o=s)}s=c})}),s&&n.push(s),n}static simplifyRouteToCoordinates(t,e,n=1){let s=this.convertRouteToCoordinates(t,n);return s=this.simplifyGCCoordinates(s,e),s}static simplifyGCCoordinates(t,e){e.forEach(s=>{this.mergeCoordinateToWaypoints(s,t,!0)});for(let s=1;s<e.length;s++){const o=e[s-1],i=e[s];if(i.gcToPrevious){const r=t.findIndex(a=>a.lng===o.lng&&a.lat===o.lat),c=t.findIndex(a=>a.lng===i.lng&&a.lat===i.lat);for(let a=c-1;a>r;a--)t.splice(a,1)}}let n=0;for(let s=1;s<t.length;s++){const o=t[s-1],i=t[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 t.map(s=>(s.lng=l.convertToStdLng(s.lng),s))}static calculateCenter(t){const e=[];for(const r of t)for(const c of r)e.push(c);const n=g.featureCollection([]),s=l.convertToMonotonicLng2(e);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(t){const e=this.generateRouteAccordingToWaypoints(t);return this.calculateCenter(e)}static calculateBBox(t){const e=[];for(const o of t)for(const i of o)e.push(i);const n=l.convertToMonotonicLng2(e),s=g.lineString(n);return g.bbox(s)}static calculateBBox2(t){const e=this.generateRouteAccordingToWaypoints(t);return this.calculateBBox(e)}static simplifyCoordinates(t,e=10,n=160){const s=[];for(let o=1;o<t.length;o++){const i=t[o-1],r=t[o],c=t[o+1];let a=!1,d=!1;if((i.velocity||i.suspend||i.important||i.pilot||o===1)&&(a=!0,s.push(i)),r.gcToPrevious&&(a||(a=!0,s.push(i)),d=!0,s.push(r),o++),c){const u=b.calculateDistance(i,r,!0),f=b.calculateDistance(r,c,!0),h=b.calculateDistance(i,c,!0),P=(Math.pow(u,2)+Math.pow(f,2)-Math.pow(h,2))/(2*u*f);Math.round(Math.acos(P)*180/Math.PI)<n&&h>e&&!d&&(s.push(r),o++)}if(o>=t.length-1){const u=t.at(-1);u&&s.push(u)}}return s}}let T;try{T=A.getLogger("vessel")}catch{}finally{}class E{static convert2Geojson(t){var n;const e=g.featureCollection([]);for(const s of t){if(s.forecasts){const o=(n=s.history)==null?void 0:n[0];for(const i of s.forecasts){const r=[],c=R(i.date).utc(),a=`${s.name}-${i.model}`;if(o){const d=R(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:o==null?void 0:o.wind,category:a,type:"forecast"});e.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 f=c.clone().add(Number(d),"hour"),h=g.point([u.lng,u.lat],{model:i.model,name:s.name,date:f.format(),hour:Number(d),format:f.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"});e.features.push(h),r.push(h.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"});e.features.push(d)}}}if(s.history){const o=[];for(const r of s.history){const c=R(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`,wind:r.wind});e.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});e.features.push(r)}}}return e}static interpolate(t,e=3){var o,i,r,c;const n=(o=t==null?void 0:t.data)==null?void 0:o.features.filter(a=>a.geometry.type==="LineString"&&a.properties.type==="forecast"),s=[];for(const a of n){const d=a.properties.name,u=a.properties.model,f=a.properties.showCircle,h=a.properties.disabled,P=R(a.properties.date).utc();let m=e*60-(P.get("hour")*60+P.get("minute"))%(e*60);const C=(i=t==null?void 0:t.data)==null?void 0:i.features.filter(S=>S.geometry.type==="Point"&&S.properties.type==="forecast"&&S.properties.category===`${d}-${u}`);let D,N=P.clone().add(m,"minute").set({minute:0,second:0,millisecond:0});for(;D=this.pickIndex(C,N),D<=C.length-1;){if(D>0){const S=C[D],p=D===0?void 0:C[D-1],y=(m/60-((r=p==null?void 0:p.properties)==null?void 0:r.hour))/(S.properties.hour-((c=p==null?void 0:p.properties)==null?void 0:c.hour)),F=this.computeNumber(p==null?void 0:p.geometry.coordinates[0],S.geometry.coordinates[0],y),L=this.computeNumber(p==null?void 0:p.geometry.coordinates[1],S.geometry.coordinates[1],y),B=g.point([F,L],{name:d,model:u,category:S==null?void 0:S.properties.category,date:N.format(),format:N.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(p==null?void 0:p.properties.gusts,S.properties.gusts,y),hour:this.computeNumber(p==null?void 0:p.properties.hour,S.properties.hour,y),movement:this.computeNumber(p==null?void 0:p.properties.movement,S.properties.movement,y),pressure:this.computeNumber(p==null?void 0:p.properties.pressure,S.properties.pressure,y),wind:this.computeNumber(p==null?void 0:p.properties.wind,S.properties.wind,y),type:"forecast",disabled:h,showCircle:f});s.push(B)}m+=e*60,N=P.clone().add(m,"minute").set({minute:0,second:0,millisecond:0})}}return s}static accelPassageAt(t,e){const{t1:n,t2:s,hr:o,hours:i}=this.tropicalCenterTwin(t,24,e);return{t1:n,t2:s,hr:o,hours:i}}static diversionPassageAt(t,e,n,s={}){const{t1:o,t2:i,hr:r,hours:c}=this.tropicalCenterTwin(e,24,s);if(o&&i){if(!s.debug){const P=b.calculateDistance(t,o),m=b.calculateDistance(t,i);if(P>2*n&&m>2*n)return T==null||T.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j",s.requestId,P,m,{from:t,t1:o,t2:i,hr:r}),{}}const a=b.calculateBearing(t,o),d=b.calculateBearing(o,i),u=Math.abs(a-d);let f=0;u<180?f=u+90:u>=180&&(f=u-90);const h=b.calculateCoordinate(o,f,n);return T==null||T.info("[%s] the right tangent position: %j",s.requestId,{from:t,t1:o,t2:i,radius:n,bearing1:a,bearing2:d,right:h}),{at:h,t1:o,t2:i,hr:Number(r),hours:c}}return{}}static driftPassageAt(t,e,n,s={}){const{t1:o,t2:i,hr:r,hours:c}=this.tropicalCenterTwin(e,24,s);if(o&&i){if(!s.debug){const h=b.calculateDistance(t,o),P=b.calculateDistance(t,i);if(h>2*n&&P>2*n)return T==null||T.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j",s.requestId,h,P,{from:t,t1:o,t2:i,hr:r}),{}}const a=b.calculateBearing(t,o),d=b.calculateBearing(o,i),u=b.calculateDistance(t,o);return{at:b.calculateCoordinate(o,a-d+180,n<u?n:u),t1:o,t2:i,hr:Number(r),hours:c}}else return T==null||T.info("[%s] no need drift: %j",s.requestId,{from:t,t1:o,t2:i,hr:r}),{}}static tropicalCenterTwin(t,e=24,n={}){var d,u,f,h,P;let s={};(d=t.forecasts)==null||d.forEach(m=>{s={...m.hours,...s}});const o=((u=t==null?void 0:t.history)==null?void 0:u[0])||(s==null?void 0:s[(f=Object.keys(s))==null?void 0:f[0]]);T==null||T.info("[%s] the first tropical center: %j",n.requestId,o);let i=(h=Object.keys(s||{}).filter(m=>Number(m)<=(e<0?24:e)))==null?void 0:h.at(-1);i||(i=(P=Object.keys(s||{}).filter(m=>Number(m)<=(e<0?24:2*e)))==null?void 0:P.at(-1));const r=s==null?void 0:s[i||-1];T==null||T.info("[%s] the second tropical center: %j in %d hrs",n.requestId,r,i);const c=Object.keys(s||{}).filter(m=>Number(m)<=Number(i)),a={0:o};for(const m of c)a[m]=s[m];return{t1:o,t2:r,hr:Number(i),hours:a}}static pickIndex(t,e){let n=0;for(const s of t){if(R(s.properties.date).isAfter(e))return n===0?-1:n;n++}return n}static computeNumber(t,e,n){if(t)if(e){if(isNaN(t)&&isNaN(e)&&typeof t!="string"&&typeof e!="string"){const s={};for(const o in t)s[o]=this.computeNumber(t[o],e[o],n);return s}return Math.round((t+(e-t)*n)*100)/100}else return t;else return e}}M.LaneHelper=b,M.LngLatHelper=l,M.TropicalHelper=E,Object.defineProperty(M,Symbol.toStringTag,{value:"Module"})});
@@ -15,6 +15,7 @@ export interface Coordinate {
15
15
  important?: boolean;
16
16
  suspend?: number;
17
17
  velocity?: number;
18
+ pilot?: boolean;
18
19
  }
19
20
  export declare class LaneHelper {
20
21
  /**
@@ -299,4 +300,11 @@ export declare class LaneHelper {
299
300
  * @param coords
300
301
  */
301
302
  static calculateBBox2(coords: Coordinate[]): turf.helpers.BBox;
303
+ /**
304
+ * 抽稀 三点抽稀, 对比A,B,C; 基于三点距离及夹角抽稀
305
+ * @param coordinates
306
+ * @param distance 三点最小距离, 小于此距离时,B点将被忽略(三点太近)
307
+ * @param angle 三点夹角, 大于此角度时,B点将被忽略(近似走RL)
308
+ */
309
+ static simplifyCoordinates(coordinates: Coordinate[], minDistance?: number, minAngle?: number): Coordinate[];
302
310
  }
package/package.json CHANGED
@@ -1,69 +1,69 @@
1
- {
2
- "name": "@idm-plugin/geo",
3
- "private": false,
4
- "version": "1.4.2",
5
- "description": "idm plugin for geo",
6
- "type": "module",
7
- "keywords": [
8
- "idm",
9
- "geo"
10
- ],
11
- "author": "chenheng@idmwx.com",
12
- "contributors": [
13
- "ChenHeng"
14
- ],
15
- "license": "GPL-3.0",
16
- "files": [
17
- "dist"
18
- ],
19
- "main": "./dist/index.umd.cjs",
20
- "module": "./dist/index.js",
21
- "types": "index.d.ts",
22
- "scripts": {
23
- "dev": "vite --config ./build/base.config.ts",
24
- "build": "vite build --config ./build/lib.config.ts",
25
- "lint:fix": "eslint --fix --ext .js,.ts,.",
26
- "prettier": "yarn lint:fix && prettier --write '**/*.{js,ts}'",
27
- "release": "yarn build && yarn publish --access public"
28
- },
29
- "dependencies": {
30
- "@log4js-node/log4js-api": "^1.0.2",
31
- "@turf/turf": "^6.5.0",
32
- "moment": "^2.30.1",
33
- "moment-timezone": "^0.5.45",
34
- "tz-lookup": "^6.1.25"
35
- },
36
- "devDependencies": {
37
- "@types/jest": "^25.2.2",
38
- "@types/node": "^18.14.2",
39
- "@types/tz-lookup": "^6.1.2",
40
- "@typescript-eslint/eslint-plugin": "^5.53.0",
41
- "@typescript-eslint/parser": "^5.53.0",
42
- "@vitejs/plugin-vue": "^4.2.3",
43
- "eslint": "^8.35.0",
44
- "eslint-config-prettier": "^8.6.0",
45
- "eslint-define-config": "^1.15.0",
46
- "eslint-plugin-prettier": "^4.2.1",
47
- "jest": "^26.6.3",
48
- "lint-staged": "^13.1.2",
49
- "prettier": "^2.8.4",
50
- "sass": "^1.58.3",
51
- "simple-git-hooks": "^2.8.1",
52
- "stylelint": "^15.2.0",
53
- "supertest": "^4.0.2",
54
- "ts-jest": "^26.5.3",
55
- "ts-node-dev": "^2.0.0-0",
56
- "tsconfig-paths": "^3.12.0",
57
- "typescript": "^4.9.3",
58
- "vite": "^4.1.0",
59
- "vite-plugin-dts": "^2.0.2",
60
- "vite-plugin-static-copy": "^0.17.0"
61
- },
62
- "lint-staged": {
63
- "*.{ts,tsx,js}": "eslint --fix",
64
- "*.{ts,tsx,js,scss}": "prettier --write"
65
- },
66
- "simple-git-hooks": {
67
- "pre-commit": "npx lint-staged"
68
- }
69
- }
1
+ {
2
+ "name": "@idm-plugin/geo",
3
+ "private": false,
4
+ "version": "1.4.4",
5
+ "description": "idm plugin for geo",
6
+ "type": "module",
7
+ "keywords": [
8
+ "idm",
9
+ "geo"
10
+ ],
11
+ "author": "chenheng@idmwx.com",
12
+ "contributors": [
13
+ "ChenHeng"
14
+ ],
15
+ "license": "GPL-3.0",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "main": "./dist/index.umd.cjs",
20
+ "module": "./dist/index.js",
21
+ "types": "index.d.ts",
22
+ "scripts": {
23
+ "dev": "vite --config ./build/base.config.ts",
24
+ "build": "vite build --config ./build/lib.config.ts",
25
+ "lint:fix": "eslint --fix --ext .js,.ts,.",
26
+ "prettier": "yarn lint:fix && prettier --write '**/*.{js,ts}'",
27
+ "release": "yarn build && yarn publish --access public"
28
+ },
29
+ "dependencies": {
30
+ "@log4js-node/log4js-api": "^1.0.2",
31
+ "@turf/turf": "^6.5.0",
32
+ "moment": "^2.30.1",
33
+ "moment-timezone": "^0.5.45",
34
+ "tz-lookup": "^6.1.25"
35
+ },
36
+ "devDependencies": {
37
+ "@types/jest": "^25.2.2",
38
+ "@types/node": "^18.14.2",
39
+ "@types/tz-lookup": "^6.1.2",
40
+ "@typescript-eslint/eslint-plugin": "^5.53.0",
41
+ "@typescript-eslint/parser": "^5.53.0",
42
+ "@vitejs/plugin-vue": "^4.2.3",
43
+ "eslint": "^8.35.0",
44
+ "eslint-config-prettier": "^8.6.0",
45
+ "eslint-define-config": "^1.15.0",
46
+ "eslint-plugin-prettier": "^4.2.1",
47
+ "jest": "^26.6.3",
48
+ "lint-staged": "^13.1.2",
49
+ "prettier": "^2.8.4",
50
+ "sass": "^1.58.3",
51
+ "simple-git-hooks": "^2.8.1",
52
+ "stylelint": "^15.2.0",
53
+ "supertest": "^4.0.2",
54
+ "ts-jest": "^26.5.3",
55
+ "ts-node-dev": "^2.0.0-0",
56
+ "tsconfig-paths": "^3.12.0",
57
+ "typescript": "^4.9.3",
58
+ "vite": "^4.1.0",
59
+ "vite-plugin-dts": "^2.0.2",
60
+ "vite-plugin-static-copy": "^0.17.0"
61
+ },
62
+ "lint-staged": {
63
+ "*.{ts,tsx,js}": "eslint --fix",
64
+ "*.{ts,tsx,js,scss}": "prettier --write"
65
+ },
66
+ "simple-git-hooks": {
67
+ "pre-commit": "npx lint-staged"
68
+ }
69
+ }