@idm-plugin/geo 1.4.3 → 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 +1 -1
- package/dist/index.js +58 -36
- package/dist/index.umd.cjs +1 -1
- package/dist/lane/src/index.d.ts +8 -0
- package/package.json +69 -69
package/README.md
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
## Geo Plugin
|
|
1
|
+
## Geo Plugin
|
|
2
2
|
Geo插件
|
package/dist/index.js
CHANGED
|
@@ -29,10 +29,10 @@ const F = () => {
|
|
|
29
29
|
return null;
|
|
30
30
|
}
|
|
31
31
|
}, x = F(), k = x ? x.getLogger : () => new y();
|
|
32
|
-
var
|
|
32
|
+
var B = {
|
|
33
33
|
getLogger: k
|
|
34
34
|
};
|
|
35
|
-
const O = /* @__PURE__ */ E(
|
|
35
|
+
const O = /* @__PURE__ */ E(B);
|
|
36
36
|
class l {
|
|
37
37
|
/**
|
|
38
38
|
* 基于输入的经度,计算出时区
|
|
@@ -182,7 +182,7 @@ class l {
|
|
|
182
182
|
return `${s}.${o}`;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
class
|
|
185
|
+
class b {
|
|
186
186
|
/**
|
|
187
187
|
* 计算方位角
|
|
188
188
|
* @param from 坐标 {lng, lat}
|
|
@@ -300,8 +300,8 @@ class P {
|
|
|
300
300
|
const f = g.lineIntersect(d, u);
|
|
301
301
|
let h;
|
|
302
302
|
if (f.features.length) {
|
|
303
|
-
const
|
|
304
|
-
h = l.roundPrecision(
|
|
303
|
+
const P = g.getCoord(f.features[0]);
|
|
304
|
+
h = l.roundPrecision(P[1], 8);
|
|
305
305
|
} else
|
|
306
306
|
h = t[r].lat;
|
|
307
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]));
|
|
@@ -380,8 +380,8 @@ class P {
|
|
|
380
380
|
*/
|
|
381
381
|
static appendCoordinateToRoute(t, e) {
|
|
382
382
|
t.lng = l.convertToStdLng(t.lng, 8);
|
|
383
|
-
const n =
|
|
384
|
-
return n.push(t),
|
|
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 P {
|
|
|
389
389
|
* @param route
|
|
390
390
|
*/
|
|
391
391
|
static unshiftCoordinateToRoute(t, e) {
|
|
392
|
-
const n =
|
|
393
|
-
return n.unshift(t),
|
|
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 P {
|
|
|
464
464
|
* @return [[[lng, lat]]]
|
|
465
465
|
*/
|
|
466
466
|
static calculateSubRoute(t, e) {
|
|
467
|
-
const n =
|
|
468
|
-
|
|
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 = [];
|
|
@@ -624,7 +624,7 @@ class P {
|
|
|
624
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((h,
|
|
627
|
+
if (e && n.length ? (i.push(t), n.forEach((h, P) => {
|
|
628
628
|
if (c)
|
|
629
629
|
r.push(h);
|
|
630
630
|
else {
|
|
@@ -648,7 +648,7 @@ class P {
|
|
|
648
648
|
c = !0;
|
|
649
649
|
}
|
|
650
650
|
}
|
|
651
|
-
m.length && r.push(m),
|
|
651
|
+
m.length && r.push(m), P === n.length - 1 && !u && (u = S);
|
|
652
652
|
}
|
|
653
653
|
})) : (r = n, u = { ...t }), u)
|
|
654
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) {
|
|
@@ -771,10 +771,32 @@ class P {
|
|
|
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
|
|
797
|
+
let T;
|
|
776
798
|
try {
|
|
777
|
-
|
|
799
|
+
T = O.getLogger("vessel");
|
|
778
800
|
} catch {
|
|
779
801
|
} finally {
|
|
780
802
|
}
|
|
@@ -881,12 +903,12 @@ 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, f = a.properties.showCircle, h = a.properties.disabled,
|
|
885
|
-
let m = 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
909
|
(v) => v.geometry.type === "Point" && v.properties.type === "forecast" && v.properties.category === `${d}-${u}`
|
|
888
910
|
);
|
|
889
|
-
let M, D =
|
|
911
|
+
let M, D = P.clone().add(m, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
890
912
|
for (; M = this.pickIndex(S, D), M <= S.length - 1; ) {
|
|
891
913
|
if (M > 0) {
|
|
892
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, $], {
|
|
@@ -906,7 +928,7 @@ class q {
|
|
|
906
928
|
});
|
|
907
929
|
s.push(W);
|
|
908
930
|
}
|
|
909
|
-
m += e * 60, D =
|
|
931
|
+
m += e * 60, D = P.clone().add(m, "minute").set({ minute: 0, second: 0, millisecond: 0 });
|
|
910
932
|
}
|
|
911
933
|
}
|
|
912
934
|
return s;
|
|
@@ -936,20 +958,20 @@ class q {
|
|
|
936
958
|
const { t1: o, t2: i, hr: r, hours: c } = this.tropicalCenterTwin(e, 24, s);
|
|
937
959
|
if (o && i) {
|
|
938
960
|
if (!s.debug) {
|
|
939
|
-
const
|
|
940
|
-
if (
|
|
941
|
-
return
|
|
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, {
|
|
942
964
|
from: t,
|
|
943
965
|
t1: o,
|
|
944
966
|
t2: i,
|
|
945
967
|
hr: r
|
|
946
968
|
}), {};
|
|
947
969
|
}
|
|
948
|
-
const a =
|
|
970
|
+
const a = b.calculateBearing(t, o), d = b.calculateBearing(o, i), u = Math.abs(a - d);
|
|
949
971
|
let f = 0;
|
|
950
972
|
u < 180 ? f = u + 90 : u >= 180 && (f = u - 90);
|
|
951
|
-
const h =
|
|
952
|
-
return
|
|
973
|
+
const h = b.calculateCoordinate(o, f, n);
|
|
974
|
+
return T == null || T.info("[%s] the right tangent position: %j", s.requestId, {
|
|
953
975
|
from: t,
|
|
954
976
|
t1: o,
|
|
955
977
|
t2: i,
|
|
@@ -975,19 +997,19 @@ class q {
|
|
|
975
997
|
const { t1: o, t2: i, hr: r, hours: c } = this.tropicalCenterTwin(e, 24, s);
|
|
976
998
|
if (o && i) {
|
|
977
999
|
if (!s.debug) {
|
|
978
|
-
const h =
|
|
979
|
-
if (h > 2 * n &&
|
|
980
|
-
return
|
|
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, {
|
|
981
1003
|
from: t,
|
|
982
1004
|
t1: o,
|
|
983
1005
|
t2: i,
|
|
984
1006
|
hr: r
|
|
985
1007
|
}), {};
|
|
986
1008
|
}
|
|
987
|
-
const a =
|
|
988
|
-
return { at:
|
|
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 };
|
|
989
1011
|
} else
|
|
990
|
-
return
|
|
1012
|
+
return T == null || T.info("[%s] no need drift: %j", s.requestId, { from: t, t1: o, t2: i, hr: r }), {};
|
|
991
1013
|
}
|
|
992
1014
|
/**
|
|
993
1015
|
* 获取台风中心点对
|
|
@@ -998,17 +1020,17 @@ class q {
|
|
|
998
1020
|
* @private
|
|
999
1021
|
*/
|
|
1000
1022
|
static tropicalCenterTwin(t, e = 24, n = {}) {
|
|
1001
|
-
var d, u, f, h,
|
|
1023
|
+
var d, u, f, h, P;
|
|
1002
1024
|
let s = {};
|
|
1003
1025
|
(d = t.forecasts) == null || d.forEach((m) => {
|
|
1004
1026
|
s = { ...m.hours, ...s };
|
|
1005
1027
|
});
|
|
1006
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]]);
|
|
1007
|
-
|
|
1029
|
+
T == null || T.info("[%s] the first tropical center: %j", n.requestId, o);
|
|
1008
1030
|
let i = (h = Object.keys(s || {}).filter((m) => Number(m) <= (e < 0 ? 24 : e))) == null ? void 0 : h.at(-1);
|
|
1009
|
-
i || (i = (
|
|
1031
|
+
i || (i = (P = Object.keys(s || {}).filter((m) => Number(m) <= (e < 0 ? 24 : 2 * e))) == null ? void 0 : P.at(-1));
|
|
1010
1032
|
const r = s == null ? void 0 : s[i || -1];
|
|
1011
|
-
|
|
1033
|
+
T == null || T.info("[%s] the second tropical center: %j in %d hrs", n.requestId, r, i);
|
|
1012
1034
|
const c = Object.keys(s || {}).filter((m) => Number(m) <= Number(i)), a = { 0: o };
|
|
1013
1035
|
for (const m of c)
|
|
1014
1036
|
a[m] = s[m];
|
|
@@ -1040,7 +1062,7 @@ class q {
|
|
|
1040
1062
|
}
|
|
1041
1063
|
}
|
|
1042
1064
|
export {
|
|
1043
|
-
|
|
1065
|
+
b as LaneHelper,
|
|
1044
1066
|
l as LngLatHelper,
|
|
1045
1067
|
q as TropicalHelper
|
|
1046
1068
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
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(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=O(I);function W(P){return P&&P.__esModule&&Object.prototype.hasOwnProperty.call(P,"default")?P.default:P}class x{log(){}isLevelEnabled(){return!1}addContext(){}removeContext(){}clearContext(){}}["Trace","Debug","Info","Warn","Error","Fatal","Mark"].forEach(P=>{x.prototype[P.toLowerCase()]=()=>{},x.prototype[`is${P}Enabled`]=()=>!1});const $=(()=>{try{return require("log4js")}catch{return null}})();var k={getLogger:$?$.getLogger:()=>new x};const L=W(k);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 h=`${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:h}}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 h=`${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:h}}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 b{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 h=g.lineIntersect(d,u);let f;if(h.features.length){const v=g.getCoord(h.features[0]);f=l.roundPrecision(v[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]},h={lng:c[d+1][0],lat:c[d+1][1]},f=this.calculatePointToLineDistance(e,u,h);n>f&&(n=f,o=d,s=a,i=this.calculateDistance(u,e),r=this.calculateDistance(h,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=b.convertRouteToCoordinates(t);return n.push(e),b.divideAccordingToLng(n)}static unshiftCoordinateToRoute(e,t){const n=b.convertRouteToCoordinates(t);return n.unshift(e),b.divideAccordingToLng(n)}static mergeWaypointsToRoute(e,t){for(const n of e)t=this.mergeCoordinateToRoute(n,t);return t}static calculateRangeRoute(e,t,n){n=this.mergeWaypointsToRoute([e,t],n);const s=[];let o=0;return n.forEach(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=b.convertRouteToCoordinates(t);b.mergeCoordinateToWaypoints(e,n,!0),t=b.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 h;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,v)=>{if(c)r.push(f);else{const m=[];let C;for(let D=0;D<f.length;D++)if(u)m.push(f[D]);else{C={lng:f[D][0],lat:f[D][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 S=a-t,p=this.calculateBearing(C,e);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),v===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,((h=r[0])==null?void 0:h.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),h=l.roundPrecision(d[1],6);return{lng:u,lat:h,inline:!(u===i&&h===t.lat)&&!(u===r&&h===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 T;try{T=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 h=c.clone().add(Number(d),"hour"),f=g.point([u.lng,u.lat],{model:i.model,name:s.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(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=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,h=a.properties.showCircle,f=a.properties.disabled,v=R(a.properties.date).utc();let m=t*60-(v.get("hour")*60+v.get("minute"))%(t*60);const C=(i=e==null?void 0:e.data)==null?void 0:i.features.filter(S=>S.geometry.type==="Point"&&S.properties.type==="forecast"&&S.properties.category===`${d}-${u}`);let D,N=v.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)),E=this.computeNumber(p==null?void 0:p.geometry.coordinates[0],S.geometry.coordinates[0],y),F=this.computeNumber(p==null?void 0:p.geometry.coordinates[1],S.geometry.coordinates[1],y),B=g.point([E,F],{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:f,showCircle:h});s.push(B)}m+=t*60,N=v.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 v=b.calculateDistance(e,o),m=b.calculateDistance(e,i);if(v>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,v,m,{from:e,t1:o,t2:i,hr:r}),{}}const a=b.calculateBearing(e,o),d=b.calculateBearing(o,i),u=Math.abs(a-d);let h=0;u<180?h=u+90:u>=180&&(h=u-90);const f=b.calculateCoordinate(o,h,n);return T==null||T.info("[%s] the right tangent position: %j",s.requestId,{from:e,t1:o,t2:i,radius:n,bearing1:a,bearing2:d,right:f}),{at:f,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 f=b.calculateDistance(e,o),v=b.calculateDistance(e,i);if(f>2*n&&v>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,f,v,{from:e,t1:o,t2:i,hr:r}),{}}const a=b.calculateBearing(e,o),d=b.calculateBearing(o,i),u=b.calculateDistance(e,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:e,t1:o,t2:i,hr:r}),{}}static tropicalCenterTwin(e,t=24,n={}){var d,u,h,f,v;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[(h=Object.keys(s))==null?void 0:h[0]]);T==null||T.info("[%s] the first tropical center: %j",n.requestId,o);let i=(f=Object.keys(s||{}).filter(m=>Number(m)<=(t<0?24:t)))==null?void 0:f.at(-1);i||(i=(v=Object.keys(s||{}).filter(m=>Number(m)<=(t<0?24:2*t)))==null?void 0:v.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(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}}M.LaneHelper=b,M.LngLatHelper=l,M.TropicalHelper=A,Object.defineProperty(M,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"})});
|
package/dist/lane/src/index.d.ts
CHANGED
|
@@ -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.
|
|
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
|
+
}
|