@idm-plugin/vessel 1.5.1 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +166 -162
- package/dist/index.umd.cjs +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -19,79 +19,79 @@ class K {
|
|
|
19
19
|
* @param status
|
|
20
20
|
*/
|
|
21
21
|
parseStatus(s) {
|
|
22
|
-
let t,
|
|
22
|
+
let t, o;
|
|
23
23
|
switch (s) {
|
|
24
24
|
case 0:
|
|
25
|
-
t = "在航(主机推动)",
|
|
25
|
+
t = "在航(主机推动)", o = "The engine is in use";
|
|
26
26
|
break;
|
|
27
27
|
case 1:
|
|
28
|
-
t = "锚泊",
|
|
28
|
+
t = "锚泊", o = "Anchored";
|
|
29
29
|
break;
|
|
30
30
|
case 2:
|
|
31
|
-
t = "失控",
|
|
31
|
+
t = "失控", o = "Not operated";
|
|
32
32
|
break;
|
|
33
33
|
case 3:
|
|
34
|
-
t = "操纵受限",
|
|
34
|
+
t = "操纵受限", o = "Limited airworthiness";
|
|
35
35
|
break;
|
|
36
36
|
case 4:
|
|
37
|
-
t = "吃水受限",
|
|
37
|
+
t = "吃水受限", o = "Limited by ship's draft";
|
|
38
38
|
break;
|
|
39
39
|
case 5:
|
|
40
|
-
t = "靠泊",
|
|
40
|
+
t = "靠泊", o = "Mooring";
|
|
41
41
|
break;
|
|
42
42
|
case 6:
|
|
43
|
-
t = "搁浅",
|
|
43
|
+
t = "搁浅", o = "Stranded";
|
|
44
44
|
break;
|
|
45
45
|
case 7:
|
|
46
|
-
t = "捕捞作业",
|
|
46
|
+
t = "捕捞作业", o = "Engaged in fishing";
|
|
47
47
|
break;
|
|
48
48
|
case 8:
|
|
49
|
-
t = "靠帆船提供动力",
|
|
49
|
+
t = "靠帆船提供动力", o = "Sailing";
|
|
50
50
|
break;
|
|
51
51
|
default:
|
|
52
|
-
t = "未定义",
|
|
52
|
+
t = "未定义", o = "Undefined";
|
|
53
53
|
}
|
|
54
|
-
return { labelCn: t, labelEn:
|
|
54
|
+
return { labelCn: t, labelEn: o };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
class bt extends K {
|
|
58
|
-
constructor(t,
|
|
58
|
+
constructor(t, o) {
|
|
59
59
|
super();
|
|
60
60
|
Z(this, "clientId");
|
|
61
61
|
Z(this, "clientSecret");
|
|
62
62
|
Z(this, "token");
|
|
63
|
-
this.clientId = t, this.clientSecret =
|
|
63
|
+
this.clientId = t, this.clientSecret = o;
|
|
64
64
|
}
|
|
65
65
|
async authToken(t = {}) {
|
|
66
|
-
const
|
|
66
|
+
const o = "https://svc.data.myvessel.cn/ada/oauth/token", n = {
|
|
67
67
|
searchParams: {
|
|
68
68
|
client_id: this.clientId,
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
},
|
|
73
|
-
h == null || h.info("[%s] fetch access token from: %s - %j", t.requestId,
|
|
74
|
-
accessToken:
|
|
75
|
-
tokenType:
|
|
76
|
-
expiresIn:
|
|
77
|
-
scope:
|
|
78
|
-
jti:
|
|
72
|
+
}, i = await A.post(o, n).json();
|
|
73
|
+
h == null || h.info("[%s] fetch access token from: %s - %j", t.requestId, o, i), i.error || (this.token = {
|
|
74
|
+
accessToken: i.access_token,
|
|
75
|
+
tokenType: i.token_type,
|
|
76
|
+
expiresIn: i.expires_in,
|
|
77
|
+
scope: i.scope,
|
|
78
|
+
jti: i.jti,
|
|
79
79
|
issuedAt: v().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
|
-
async realTimePosition(t,
|
|
82
|
+
async realTimePosition(t, o = {}) {
|
|
83
83
|
var d, f, M;
|
|
84
|
-
(!this.token || v().diff(v(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(
|
|
85
|
-
const
|
|
84
|
+
(!this.token || v().diff(v(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(o);
|
|
85
|
+
const n = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", i = {
|
|
86
86
|
headers: {
|
|
87
87
|
Authorization: `${(f = this.token) == null ? void 0 : f.tokenType} ${(M = this.token) == null ? void 0 : M.accessToken}`
|
|
88
88
|
},
|
|
89
89
|
searchParams: { mmsi: t }
|
|
90
90
|
};
|
|
91
|
-
h == null || h.info("[%s] fetch realtime position from: %s - %j",
|
|
92
|
-
const a = await A.get(
|
|
91
|
+
h == null || h.info("[%s] fetch realtime position from: %s - %j", o.requestId, n, i);
|
|
92
|
+
const a = await A.get(n, i).json();
|
|
93
93
|
if (a.code)
|
|
94
|
-
return h == null || h.warn("[%s] fetch realtime position failed: %j",
|
|
94
|
+
return h == null || h.warn("[%s] fetch realtime position failed: %j", o.requestId, n, { message: a.message, status: a.status, code: a.code }), a;
|
|
95
95
|
const e = a.data;
|
|
96
96
|
for (const m in e)
|
|
97
97
|
!isNaN(e[m]) && Number(e[m]) !== 1 / 0 && (e[m] = Number(e[m]));
|
|
@@ -121,14 +121,14 @@ class bt extends K {
|
|
|
121
121
|
utc: c.utc().format()
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
|
-
async trajectory(t,
|
|
124
|
+
async trajectory(t, o, n, i, a = !0, e = {}) {
|
|
125
125
|
(!this.token || v().diff(v(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
|
|
126
|
-
const c = await this.realTimePosition(t, e), r = v(
|
|
126
|
+
const c = await this.realTimePosition(t, e), r = v(o), d = v(n), f = [];
|
|
127
127
|
for (; d.diff(r, "day", !0) > 30; )
|
|
128
|
-
await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), c,
|
|
129
|
-
return await this.trajectoryIn30Day(t, r, d, c,
|
|
128
|
+
await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), c, i, f, e), r.add(30, "day");
|
|
129
|
+
return await this.trajectoryIn30Day(t, r, d, c, i, f, e), f;
|
|
130
130
|
}
|
|
131
|
-
async trajectoryIn30Day(t,
|
|
131
|
+
async trajectoryIn30Day(t, o, n, i, a, e, c = {}) {
|
|
132
132
|
var u, Y, j, b, p;
|
|
133
133
|
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", d = {
|
|
134
134
|
headers: {
|
|
@@ -136,8 +136,8 @@ class bt extends K {
|
|
|
136
136
|
},
|
|
137
137
|
json: {
|
|
138
138
|
mmsi: t,
|
|
139
|
-
startTime:
|
|
140
|
-
endTime:
|
|
139
|
+
startTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
|
|
140
|
+
endTime: n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
143
|
h == null || h.info("[%s] fetch trajectory from: %s - %j", c.requestId, r, d);
|
|
@@ -151,7 +151,7 @@ class bt extends K {
|
|
|
151
151
|
!isNaN(l[O]) && Number(l[O]) !== 1 / 0 && (l[O] = Number(l[O]));
|
|
152
152
|
const k = v(`${l.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), w = l.status, { labelCn: y, labelEn: g } = this.parseStatus(w), H = {
|
|
153
153
|
mmsi: l.mmsi,
|
|
154
|
-
imo:
|
|
154
|
+
imo: i == null ? void 0 : i.imo,
|
|
155
155
|
lat: l.lat,
|
|
156
156
|
lng: l.lon,
|
|
157
157
|
sog: l.sog,
|
|
@@ -178,17 +178,17 @@ class vt extends K {
|
|
|
178
178
|
Z(this, "token");
|
|
179
179
|
this.token = t;
|
|
180
180
|
}
|
|
181
|
-
async realTimePosition(t,
|
|
182
|
-
const
|
|
181
|
+
async realTimePosition(t, o = {}) {
|
|
182
|
+
const n = "https://api.hifleet.com/position/position/get/token", i = {
|
|
183
183
|
searchParams: {
|
|
184
184
|
mmsi: t,
|
|
185
185
|
usertoken: this.token
|
|
186
186
|
}
|
|
187
|
-
}, a = await A.post(
|
|
188
|
-
h == null || h.info("[%s] fetch realtime position from: %s - %j",
|
|
187
|
+
}, a = await A.post(n, i).json();
|
|
188
|
+
h == null || h.info("[%s] fetch realtime position from: %s - %j", o.requestId, n, i);
|
|
189
189
|
const e = a == null ? void 0 : a.list;
|
|
190
190
|
if (!e)
|
|
191
|
-
return h == null || h.warn("[%s] fetch realtime position failed: %j",
|
|
191
|
+
return h == null || h.warn("[%s] fetch realtime position failed: %j", o.requestId, n, a), a;
|
|
192
192
|
for (const m in e)
|
|
193
193
|
!isNaN(e[m]) && Number(e[m]) !== 1 / 0 && (e[m] = Number(e[m]));
|
|
194
194
|
e.status = e.sp > 3 ? 0 : 1;
|
|
@@ -218,9 +218,9 @@ class vt extends K {
|
|
|
218
218
|
vendor: "hifleet"
|
|
219
219
|
};
|
|
220
220
|
}
|
|
221
|
-
async search(t,
|
|
222
|
-
let
|
|
223
|
-
const
|
|
221
|
+
async search(t, o = {}) {
|
|
222
|
+
let n = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
223
|
+
const i = {
|
|
224
224
|
searchParams: {
|
|
225
225
|
keyword: t
|
|
226
226
|
},
|
|
@@ -230,8 +230,8 @@ class vt extends K {
|
|
|
230
230
|
Host: "www.hifleet.com"
|
|
231
231
|
}
|
|
232
232
|
};
|
|
233
|
-
let a = await A.post(
|
|
234
|
-
h == null || h.info("[%s] fetch vessel props from: %s - %j",
|
|
233
|
+
let a = await A.post(n, i).json();
|
|
234
|
+
h == null || h.info("[%s] fetch vessel props from: %s - %j", o.requestId, n, i), a instanceof Array && (a = a[0]);
|
|
235
235
|
for (const c in a)
|
|
236
236
|
!isNaN(a[c]) && Number(a[c]) !== 1 / 0 && (a[c] = Number(a[c]));
|
|
237
237
|
const e = {
|
|
@@ -243,13 +243,13 @@ class vt extends K {
|
|
|
243
243
|
breadth: a.b,
|
|
244
244
|
draught: a.dr
|
|
245
245
|
};
|
|
246
|
-
return
|
|
246
|
+
return n = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await A.post(n, i).json(), h == null || h.info("[%s] fetch vessel dead weight from: %s - %j", o.requestId, n, i), a instanceof Array && (a = a[0]), a && (e.deadweight = Number(a.dwt)), e;
|
|
247
247
|
}
|
|
248
|
-
async trajectory(t,
|
|
248
|
+
async trajectory(t, o, n, i, a = !0, e = {}) {
|
|
249
249
|
var l, k, w;
|
|
250
250
|
const c = await this.realTimePosition(t, e);
|
|
251
|
-
let r = v(
|
|
252
|
-
const d = v(
|
|
251
|
+
let r = v(o);
|
|
252
|
+
const d = v(n), f = v();
|
|
253
253
|
if (a) {
|
|
254
254
|
let y = d.diff(r, "d", !0);
|
|
255
255
|
y < 0 ? r = d.clone().subtract(40, "d") : y < 30 ? r.subtract(10, "d") : y < 60 ? r.subtract(5, "d") : r = d.clone().subtract(80, "d"), y = f.diff(d, "d", !0), d.add(y > 10 ? 240 : y * 24, "h");
|
|
@@ -290,7 +290,7 @@ class vt extends K {
|
|
|
290
290
|
labelEn: H,
|
|
291
291
|
method: "trajectory",
|
|
292
292
|
vendor: "hifleet"
|
|
293
|
-
}, N = Math.floor(g.diff(p, "minute", !0) / (
|
|
293
|
+
}, N = Math.floor(g.diff(p, "minute", !0) / (i || 1));
|
|
294
294
|
N !== b && (b = N, j.push(O));
|
|
295
295
|
}
|
|
296
296
|
return j;
|
|
@@ -302,15 +302,15 @@ class Yt extends K {
|
|
|
302
302
|
Z(this, "token");
|
|
303
303
|
this.token = t;
|
|
304
304
|
}
|
|
305
|
-
async realTimePosition(t,
|
|
306
|
-
const
|
|
305
|
+
async realTimePosition(t, o = {}) {
|
|
306
|
+
const n = {
|
|
307
307
|
searchParams: {
|
|
308
308
|
id: t,
|
|
309
309
|
k: this.token,
|
|
310
310
|
enc: 1
|
|
311
311
|
}
|
|
312
|
-
},
|
|
313
|
-
if (h == null || h.info("[%s] fetch realtime position from: %s - %j",
|
|
312
|
+
}, i = "https://api.shipxy.com/apicall/GetSingleShip", a = await A.get(i, n).json();
|
|
313
|
+
if (h == null || h.info("[%s] fetch realtime position from: %s - %j", o.requestId, i, n), (a == null ? void 0 : a.status) !== 0)
|
|
314
314
|
return a;
|
|
315
315
|
const e = a.data[0];
|
|
316
316
|
for (const M in e)
|
|
@@ -339,9 +339,9 @@ class Yt extends K {
|
|
|
339
339
|
vendor: "shipxy"
|
|
340
340
|
};
|
|
341
341
|
}
|
|
342
|
-
async trajectory(t,
|
|
342
|
+
async trajectory(t, o, n, i, a = !0, e = {}) {
|
|
343
343
|
var p;
|
|
344
|
-
const c = await this.realTimePosition(t, e), r = v(
|
|
344
|
+
const c = await this.realTimePosition(t, e), r = v(o), d = v(n), f = "https://api.shipxy.com/apicall/GetShipTrack", M = {
|
|
345
345
|
searchParams: {
|
|
346
346
|
id: t,
|
|
347
347
|
k: this.token,
|
|
@@ -367,7 +367,7 @@ class Yt extends K {
|
|
|
367
367
|
utc: k.utc().format(),
|
|
368
368
|
method: "trajectory",
|
|
369
369
|
vendor: "shipxy"
|
|
370
|
-
}, y = Math.floor(k.diff(j, "minute", !0) / (
|
|
370
|
+
}, y = Math.floor(k.diff(j, "minute", !0) / (i || 1));
|
|
371
371
|
y !== b && (b = y, Y.push(w));
|
|
372
372
|
}
|
|
373
373
|
return Y;
|
|
@@ -379,31 +379,31 @@ class kt extends K {
|
|
|
379
379
|
Z(this, "token");
|
|
380
380
|
this.token = t;
|
|
381
381
|
}
|
|
382
|
-
async getShipId(t,
|
|
383
|
-
const
|
|
382
|
+
async getShipId(t, o = {}) {
|
|
383
|
+
const n = {
|
|
384
384
|
headers: {
|
|
385
385
|
appKey: this.token
|
|
386
386
|
},
|
|
387
387
|
json: {
|
|
388
388
|
mmsiList: t
|
|
389
389
|
}
|
|
390
|
-
},
|
|
391
|
-
return h == null || h.info("[%s] fetch ship id from: %s - %j",
|
|
390
|
+
}, i = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await A.post(i, n).json();
|
|
391
|
+
return h == null || h.info("[%s] fetch ship id from: %s - %j", o.requestId, i, n), a.code !== "0" ? a : a.data[0].shipId;
|
|
392
392
|
}
|
|
393
|
-
async getShipInfo(t,
|
|
394
|
-
const
|
|
393
|
+
async getShipInfo(t, o = {}) {
|
|
394
|
+
const n = {
|
|
395
395
|
headers: {
|
|
396
396
|
appKey: this.token
|
|
397
397
|
},
|
|
398
398
|
json: {
|
|
399
399
|
shipId: t
|
|
400
400
|
}
|
|
401
|
-
},
|
|
402
|
-
if (h == null || h.info("[%s] fetch ship info from: %s - %j",
|
|
401
|
+
}, i = "https://api3.myships.com/sp/ships/aissta", a = await A.post(i, n).json();
|
|
402
|
+
if (h == null || h.info("[%s] fetch ship info from: %s - %j", o.requestId, i, n), a.code !== "0")
|
|
403
403
|
return a;
|
|
404
404
|
const e = a.data;
|
|
405
405
|
let c = e.imo;
|
|
406
|
-
return t === "407170" && (c = "9198379", h == null || h.warn("[%s] ship(%s) imo error: %s, should be %s",
|
|
406
|
+
return t === "407170" && (c = "9198379", h == null || h.warn("[%s] ship(%s) imo error: %s, should be %s", o.requestId, t, e.imo, c)), {
|
|
407
407
|
mmsi: e.mmsi,
|
|
408
408
|
name: e.shipnameEn,
|
|
409
409
|
imo: c,
|
|
@@ -413,22 +413,22 @@ class kt extends K {
|
|
|
413
413
|
draught: (e.draught || 100) / 10
|
|
414
414
|
};
|
|
415
415
|
}
|
|
416
|
-
async realTimePosition(t,
|
|
417
|
-
const
|
|
416
|
+
async realTimePosition(t, o = {}) {
|
|
417
|
+
const n = await this.getShipId(t, o), i = await this.getShipInfo(n, o), a = {
|
|
418
418
|
headers: {
|
|
419
419
|
appKey: this.token
|
|
420
420
|
},
|
|
421
421
|
json: {
|
|
422
|
-
shipId:
|
|
422
|
+
shipId: n
|
|
423
423
|
}
|
|
424
424
|
}, e = "https://api3.myships.com/sp/ships/position/latest", c = await A.post(e, a).json();
|
|
425
|
-
h == null || h.info("[%s] fetch realtime position from: %s - %j",
|
|
425
|
+
h == null || h.info("[%s] fetch realtime position from: %s - %j", o.requestId, e, a);
|
|
426
426
|
const r = c.data[0];
|
|
427
427
|
for (const u in r)
|
|
428
428
|
!isNaN(r[u]) && Number(r[u]) !== 1 / 0 && (r[u] = Number(r[u]));
|
|
429
429
|
const { labelCn: d, labelEn: f } = await this.parseStatus(r.aisNavStatus), M = v.unix(r.posTime);
|
|
430
430
|
return {
|
|
431
|
-
...
|
|
431
|
+
...i,
|
|
432
432
|
mmsi: t,
|
|
433
433
|
lat: Math.round(r.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
434
434
|
lng: Math.round(r.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
@@ -445,13 +445,13 @@ class kt extends K {
|
|
|
445
445
|
vendor: "myship"
|
|
446
446
|
};
|
|
447
447
|
}
|
|
448
|
-
async trajectory(t,
|
|
449
|
-
const c = v(
|
|
448
|
+
async trajectory(t, o, n, i, a = !0, e = {}) {
|
|
449
|
+
const c = v(o), r = v(n), d = await this.getShipId(t), f = await this.getShipInfo(d), M = [];
|
|
450
450
|
for (; r.diff(c, "day", !0) > 30; )
|
|
451
|
-
await this.trajectoryIn30Day(d, c.unix(), c.add(30, "day").unix(), f, t,
|
|
452
|
-
return await this.trajectoryIn30Day(d, c.unix(), r.unix(), f, t,
|
|
451
|
+
await this.trajectoryIn30Day(d, c.unix(), c.add(30, "day").unix(), f, t, i, M);
|
|
452
|
+
return await this.trajectoryIn30Day(d, c.unix(), r.unix(), f, t, i, M), M;
|
|
453
453
|
}
|
|
454
|
-
async trajectoryIn30Day(t,
|
|
454
|
+
async trajectoryIn30Day(t, o, n, i, a, e, c, r = {}) {
|
|
455
455
|
var j;
|
|
456
456
|
const d = {
|
|
457
457
|
headers: {
|
|
@@ -459,8 +459,8 @@ class kt extends K {
|
|
|
459
459
|
},
|
|
460
460
|
json: {
|
|
461
461
|
shipId: t,
|
|
462
|
-
startTime:
|
|
463
|
-
endTime:
|
|
462
|
+
startTime: o,
|
|
463
|
+
endTime: n
|
|
464
464
|
}
|
|
465
465
|
}, f = "https://api3.myships.com/sp/ships/position/history", M = await A.post(f, d).json();
|
|
466
466
|
if (h == null || h.info("[%s] fetch trajectory from: %s - %j", r.requestId, f, d), M.code !== "0")
|
|
@@ -472,7 +472,7 @@ class kt extends K {
|
|
|
472
472
|
let Y = -1;
|
|
473
473
|
for (const b of m) {
|
|
474
474
|
const p = v.unix(b.posTime), l = {
|
|
475
|
-
imo:
|
|
475
|
+
imo: i == null ? void 0 : i.imo,
|
|
476
476
|
mmsi: a,
|
|
477
477
|
lat: Math.round(b.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
478
478
|
lng: Math.round(b.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
@@ -509,14 +509,14 @@ class rt {
|
|
|
509
509
|
parsePrinciple(s, t = {}) {
|
|
510
510
|
var e, c, r;
|
|
511
511
|
R == null || R.info("[%s] parse rule: %s", t.requestId, s);
|
|
512
|
-
const
|
|
513
|
-
if (!
|
|
512
|
+
const o = new RegExp("(?<=\\[)(.+)(?=])", "g"), n = s.match(o) ? (e = s.match(o)) == null ? void 0 : e[0] : void 0, i = n == null ? void 0 : n.split(";");
|
|
513
|
+
if (!i)
|
|
514
514
|
return;
|
|
515
515
|
const a = {};
|
|
516
|
-
for (let d = 0; d < (
|
|
517
|
-
const f = (r = (c =
|
|
516
|
+
for (let d = 0; d < (i == null ? void 0 : i.length); d++) {
|
|
517
|
+
const f = (r = (c = i[d].match(o)) == null ? void 0 : c[0]) == null ? void 0 : r.split("],");
|
|
518
518
|
if (d === 0 && !f)
|
|
519
|
-
a.scope =
|
|
519
|
+
a.scope = i[0];
|
|
520
520
|
else if (f)
|
|
521
521
|
for (let M = 0, m = f.length; M < m; M++) {
|
|
522
522
|
const u = this.parseRule(f[M]);
|
|
@@ -534,14 +534,14 @@ class rt {
|
|
|
534
534
|
parseRule(s, t = {}) {
|
|
535
535
|
var a;
|
|
536
536
|
R == null || R.info("[%s] parse rule: %s", t.requestId, s), s = s.startsWith("[") ? s : `[${s}`, s = s.endsWith("]") ? s : `${s}]`;
|
|
537
|
-
const
|
|
538
|
-
if (
|
|
537
|
+
const o = new RegExp("(?<=\\[)(.+?)(?=])", "g"), n = (a = s == null ? void 0 : s.match(o)) == null ? void 0 : a[0], i = n == null ? void 0 : n.split(",");
|
|
538
|
+
if (i)
|
|
539
539
|
return {
|
|
540
|
-
operator:
|
|
541
|
-
number: Number.isNaN(Number(
|
|
542
|
-
level:
|
|
543
|
-
time: Number(
|
|
544
|
-
key:
|
|
540
|
+
operator: i[0],
|
|
541
|
+
number: Number.isNaN(Number(i[1])) ? i[1] : Number(i[1]),
|
|
542
|
+
level: i[2],
|
|
543
|
+
time: Number(i[3]),
|
|
544
|
+
key: i[4]
|
|
545
545
|
};
|
|
546
546
|
}
|
|
547
547
|
/**
|
|
@@ -550,15 +550,15 @@ class rt {
|
|
|
550
550
|
* @param principle 告警规则
|
|
551
551
|
* @param options
|
|
552
552
|
*/
|
|
553
|
-
checkWeather(s, t,
|
|
553
|
+
checkWeather(s, t, o = {}) {
|
|
554
554
|
var u, Y, j, b, p, l, k, w, y, g, H, F, O, N, L;
|
|
555
|
-
let
|
|
555
|
+
let n = 0, i = 0, a = 0, e = 0;
|
|
556
556
|
const c = Math.round(((Y = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.sigWave) == null ? void 0 : Y.number) * 1.6 * 100) / 100, r = (b = (j = t == null ? void 0 : t.SEVERE) == null ? void 0 : j.sigWave) == null ? void 0 : b.number, d = (l = (p = t == null ? void 0 : t.HEAVY) == null ? void 0 : p.sigWave) == null ? void 0 : l.number, f = Math.round((((w = (k = t == null ? void 0 : t.SEVERE) == null ? void 0 : k.wind) == null ? void 0 : w.number) + 2) * 100) / 100, M = (g = (y = t == null ? void 0 : t.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : g.number, m = (F = (H = t == null ? void 0 : t.HEAVY) == null ? void 0 : H.wind) == null ? void 0 : F.number;
|
|
557
557
|
for (let W = 0; W < (s == null ? void 0 : s.length); W++) {
|
|
558
558
|
const T = s[W], P = (N = (O = T == null ? void 0 : T.meteo) == null ? void 0 : O.wave) == null ? void 0 : N.sig, D = (L = T == null ? void 0 : T.meteo) == null ? void 0 : L.wind, E = W ? v(T.eta).diff(v(s[W - 1].eta), "hour", !0) : 0;
|
|
559
|
-
e = E > e ? E : e, R == null || R.info("[%s] check sig.wave: %j",
|
|
559
|
+
e = E > e ? E : e, R == null || R.info("[%s] check sig.wave: %j", o.requestId, { ...P, dgThd4Wv: c, svThd4Wv: r, hvThd4Wv: d }), (P == null ? void 0 : P.height) >= c ? T.isDangerous = !0 : (P == null ? void 0 : P.height) >= r ? T.isSevere = !0 : (P == null ? void 0 : P.height) >= d && (T.isHeavy = !0), R == null || R.info("[%s] check wind: %j", o.requestId, { ...D, dgThd4Wd: f, svThd4Wd: M, hvThd4Wd: m }), (D == null ? void 0 : D.scale) >= f ? (T.isDangerous = !0, delete T.isSevere, delete T.isHeavy) : (D == null ? void 0 : D.scale) > M ? (T.isDangerous || (T.isSevere = !0), delete T.isHeavy) : (D == null ? void 0 : D.scale) === m && !T.isDangerous && !T.isSevere && (T.isHeavy = !0), n += T.isDangerous ? E : 0, i += T.isSevere ? E : 0, a += T.isHeavy ? E : 0;
|
|
560
560
|
}
|
|
561
|
-
return
|
|
561
|
+
return n = Math.round(n * 100) / 100, i = Math.round(i * 100) / 100, a = Math.round(a * 100) / 100, e = Math.round(e), { sample: s, dangerous: n, severe: i, heavy: a, step: e < 3 ? 3 : e, wind: { dgThd4Wd: f, svThd4Wd: M, hvThd4Wd: m }, sig: { dgThd4Wv: c, svThd4Wv: r, hvThd4Wv: d } };
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
564
|
const It = new rt();
|
|
@@ -583,10 +583,10 @@ class C {
|
|
|
583
583
|
* @param draught 吃水 m
|
|
584
584
|
* @return [0.55, 0.85]
|
|
585
585
|
*/
|
|
586
|
-
static blockCoefficient(s, t,
|
|
587
|
-
let
|
|
588
|
-
|
|
589
|
-
const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = a.map((c) => Math.abs(c -
|
|
586
|
+
static blockCoefficient(s, t, o, n) {
|
|
587
|
+
let i = Math.round(s / (t * o * n) * 100) / 100;
|
|
588
|
+
i = i < 0.55 ? 0.55 : i > 0.85 ? 0.85 : i;
|
|
589
|
+
const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = a.map((c) => Math.abs(c - i));
|
|
590
590
|
return a[e.indexOf(Math.min(...e))];
|
|
591
591
|
}
|
|
592
592
|
/**
|
|
@@ -600,9 +600,9 @@ class C {
|
|
|
600
600
|
* @param g 重力加速度 9.80 m/s^2
|
|
601
601
|
* @return [0.05, 0.30]
|
|
602
602
|
*/
|
|
603
|
-
static froudeNumber(s, t,
|
|
604
|
-
let
|
|
605
|
-
return
|
|
603
|
+
static froudeNumber(s, t, o = 9.8) {
|
|
604
|
+
let n = Math.round(Math.sqrt(s * s / (o * t)) * 100) / 100;
|
|
605
|
+
return n = n < 0.05 ? 0.05 : n > 0.3 ? 0.3 : n, n;
|
|
606
606
|
}
|
|
607
607
|
/**
|
|
608
608
|
* 失速修正系數
|
|
@@ -611,8 +611,8 @@ class C {
|
|
|
611
611
|
* @param loadCondition
|
|
612
612
|
* @private
|
|
613
613
|
*/
|
|
614
|
-
static amendFactor(s, t,
|
|
615
|
-
const
|
|
614
|
+
static amendFactor(s, t, o) {
|
|
615
|
+
const n = {
|
|
616
616
|
0.55: [1.7, -1.4, -7.4],
|
|
617
617
|
0.6: [2.2, -2.5, -9.7],
|
|
618
618
|
0.65: [2.6, -3.7, -11.6],
|
|
@@ -630,7 +630,7 @@ class C {
|
|
|
630
630
|
0.8: [3, -16.3, -21.6],
|
|
631
631
|
0.85: [3.4, -20.9, 31.8]
|
|
632
632
|
}[s];
|
|
633
|
-
return
|
|
633
|
+
return o === "Laden" && (a = n[s]), a[0] + a[1] * t + a[2] * Math.pow(t, 2);
|
|
634
634
|
}
|
|
635
635
|
/**
|
|
636
636
|
* 失速方向因子
|
|
@@ -644,8 +644,8 @@ class C {
|
|
|
644
644
|
* @private
|
|
645
645
|
*/
|
|
646
646
|
static directionFactor(s, t = 0) {
|
|
647
|
-
let
|
|
648
|
-
return s > 30 && s <= 60 ?
|
|
647
|
+
let o;
|
|
648
|
+
return s > 30 && s <= 60 ? o = (1.7 - 0.03 * Math.pow(t - 4, 2)) / 2 : s > 60 && s <= 150 ? o = (0.9 - 0.06 * Math.pow(t - 6, 2)) / 2 : s > 150 && s <= 180 ? o = (0.4 - 0.03 * Math.pow(t - 8, 2)) / 2 : o = 1, Math.round(o * 1e5) / 1e5;
|
|
649
649
|
}
|
|
650
650
|
/**
|
|
651
651
|
* 失速船型因子
|
|
@@ -658,10 +658,10 @@ class C {
|
|
|
658
658
|
* @param bn
|
|
659
659
|
* @private
|
|
660
660
|
*/
|
|
661
|
-
static vesselTagFactor(s, t,
|
|
662
|
-
|
|
663
|
-
let
|
|
664
|
-
return
|
|
661
|
+
static vesselTagFactor(s, t, o, n = 0) {
|
|
662
|
+
n = n > 6 ? n - 0.9 * (n - 6) : n;
|
|
663
|
+
let i;
|
|
664
|
+
return o === "container" ? i = 0.7 * n + Math.pow(n, 6.5) / (22 * Math.pow(s, 2 / 3)) : t === "Ballast" ? i = 0.7 * n + Math.pow(n, 6.5) / (2.7 * Math.pow(s, 2 / 3)) : i = 0.5 * n + Math.pow(n, 6.5) / (2.7 * Math.pow(s, 2 / 3)), i;
|
|
665
665
|
}
|
|
666
666
|
/**
|
|
667
667
|
* 浪高影响因子
|
|
@@ -670,8 +670,8 @@ class C {
|
|
|
670
670
|
*/
|
|
671
671
|
static waveHeightFactor(s, t) {
|
|
672
672
|
s = s < 0 ? 0.2 : s, s = s > 6 ? s - 0.9 * (s - 6) : s, s = s > 9 ? 9 : s;
|
|
673
|
-
let
|
|
674
|
-
return t > 30 && t <= 60 ?
|
|
673
|
+
let o;
|
|
674
|
+
return t > 30 && t <= 60 ? o = -0.6 : t > 60 && t <= 90 ? o = -0.4 : t > 90 && t <= 120 ? o = s < 3 ? 0.4 : -0.3 : t > 120 && t <= 150 ? o = s < 3 ? 0.6 : -0.5 : t > 150 && t <= 180 ? o = s < 3 ? 0.7 : -0.6 : o = -0.7, Math.round(o * (0.144 * Math.pow(s, 2) + 0.178 * s) * 1e4) / 1e4;
|
|
675
675
|
}
|
|
676
676
|
/**
|
|
677
677
|
* 组装船舶运行参数
|
|
@@ -681,21 +681,21 @@ class C {
|
|
|
681
681
|
* @param bearing 方位角
|
|
682
682
|
* @private
|
|
683
683
|
*/
|
|
684
|
-
static assembleProperties(s, t,
|
|
684
|
+
static assembleProperties(s, t, o, n) {
|
|
685
685
|
var M;
|
|
686
|
-
const
|
|
686
|
+
const i = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, a = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, c = s.deadweight ?? 67035.7773, r = ((M = s == null ? void 0 : s.type) == null ? void 0 : M.toLowerCase()) || "common";
|
|
687
687
|
return {
|
|
688
688
|
tag: r.indexOf("container") > -1 ? "container" : r.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
689
|
-
lbp:
|
|
689
|
+
lbp: i,
|
|
690
690
|
loadCondition: t,
|
|
691
691
|
draught: a,
|
|
692
692
|
breadthMoulded: e,
|
|
693
693
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
694
694
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
695
|
-
displacement: Math.round((c / 1.025 + a * e *
|
|
695
|
+
displacement: Math.round((c / 1.025 + a * e * i * 0.7) * 1e4) / 1e4,
|
|
696
696
|
// 换算为m/s
|
|
697
|
-
speed: Math.round((
|
|
698
|
-
bearing:
|
|
697
|
+
speed: Math.round((o ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
698
|
+
bearing: n || 90
|
|
699
699
|
};
|
|
700
700
|
}
|
|
701
701
|
/**
|
|
@@ -708,31 +708,35 @@ class C {
|
|
|
708
708
|
* @param useMeteo true 启用气象分析
|
|
709
709
|
* @param useRouteParam true 启用设置速度
|
|
710
710
|
*/
|
|
711
|
-
static async speedLoseAt(s, t,
|
|
711
|
+
static async speedLoseAt(s, t, o, n = "", i = 2, a = !0, e = !1, c = {}) {
|
|
712
712
|
let r;
|
|
713
713
|
if (t.velocity && e && (s.speed = B.roundPrecision(t.velocity * 1852 / 3600, 6)), a) {
|
|
714
714
|
let d;
|
|
715
|
-
if (c.meteo2)
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
715
|
+
if (c.meteo2)
|
|
716
|
+
try {
|
|
717
|
+
const u = await ct.spotForecast(t.lat, t.lng, o.utc().format(), !1, !1, !0, c), [Y] = tt.pickHourly(u, o);
|
|
718
|
+
d = tt.toLegacy(Y);
|
|
719
|
+
} catch (u) {
|
|
720
|
+
S.warn("[%s] meteo2 spot(%j) forecast failed: %s", c.requestId, { ...t, eta: o.utc().format() }, u);
|
|
721
|
+
}
|
|
722
|
+
else
|
|
723
|
+
d = await nt.queryPointFactor(t.lng, t.lat, o.valueOf(), "wind,wave,current,watertemp", n, c);
|
|
724
|
+
const f = C.weatherFactor(s, d), M = C.currentFactor(s.bearing, d == null ? void 0 : d.current, i), m = Math.round((s.speed * 1.943844 + f + M) * 100) / 100;
|
|
721
725
|
r = {
|
|
722
726
|
meteo: { ...d },
|
|
723
727
|
wxFactor: f,
|
|
724
728
|
cFactor: M,
|
|
725
729
|
speed: t.velocity && e ? t.velocity : m < 0 ? 1 : m,
|
|
726
|
-
eta:
|
|
727
|
-
etd:
|
|
730
|
+
eta: o.utc().format("YYYY-MM-DDTHH:mm[Z]"),
|
|
731
|
+
etd: o.utc().format("YYYY-MM-DDTHH:mm[Z]")
|
|
728
732
|
};
|
|
729
733
|
} else
|
|
730
734
|
r = {
|
|
731
735
|
wxFactor: 0,
|
|
732
736
|
cFactor: 0,
|
|
733
737
|
speed: t.velocity && e ? t.velocity : Math.round((s.speed * 1.943844 + 0 + 0) * 100) / 100,
|
|
734
|
-
eta:
|
|
735
|
-
etd:
|
|
738
|
+
eta: o.utc().format("YYYY-MM-DDTHH:mm[Z]"),
|
|
739
|
+
etd: o.utc().format("YYYY-MM-DDTHH:mm[Z]")
|
|
736
740
|
};
|
|
737
741
|
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...r, ...t };
|
|
738
742
|
}
|
|
@@ -749,49 +753,49 @@ class C {
|
|
|
749
753
|
* @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
|
|
750
754
|
* @private
|
|
751
755
|
*/
|
|
752
|
-
static async speedLoseInHoursStep(s, t,
|
|
756
|
+
static async speedLoseInHoursStep(s, t, o, n, i, a, e = "", c = !0, r = !1, d = {}) {
|
|
753
757
|
t.utc();
|
|
754
758
|
const f = [], M = [];
|
|
755
759
|
let m = 0, u = 0, Y, j;
|
|
756
760
|
for (let b = 0; b < a.length - 1; b++) {
|
|
757
761
|
let p = a[b];
|
|
758
|
-
p.distanceFromStart =
|
|
762
|
+
p.distanceFromStart = i + u;
|
|
759
763
|
const l = a[b + 1];
|
|
760
764
|
if (s.bearing = V.calculateBearing(p, l, !l.gcToPrevious), p.bearing = s.bearing, p.suspend && r) {
|
|
761
765
|
p.eta = p.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), p.elapsed = p.elapsed ?? 0;
|
|
762
766
|
const y = p.suspend - p.elapsed;
|
|
763
|
-
if (
|
|
764
|
-
|
|
767
|
+
if (n - m > y)
|
|
768
|
+
n = n - m - y, t.add(y, "hour"), p.elapsed = p.suspend;
|
|
765
769
|
else {
|
|
766
|
-
const g =
|
|
767
|
-
p.elapsed += g, t.add(g, "hour"),
|
|
770
|
+
const g = n - m;
|
|
771
|
+
p.elapsed += g, t.add(g, "hour"), n = 0;
|
|
768
772
|
}
|
|
769
|
-
if (S == null || S.info(`[%s] suspend ${p.elapsed} hours at %j, and remain ${
|
|
773
|
+
if (S == null || S.info(`[%s] suspend ${p.elapsed} hours at %j, and remain ${n} hours need to go...`, d.requestId, p), n === 0)
|
|
770
774
|
return p.distanceFromPrevious = u, { etd: t, from: j || p, to: p, next: a.filter((g) => g), wps: f, days: M };
|
|
771
775
|
} else
|
|
772
776
|
p.suspend = 0;
|
|
773
|
-
p = await C.speedLoseAt(s, p, t, e, 0, c, r, d), j = j || p, p.important && f.push(p), t.isSameOrAfter(
|
|
777
|
+
p = await C.speedLoseAt(s, p, t, e, 0, c, r, d), j = j || p, p.important && f.push(p), t.isSameOrAfter(o) && (M.push(p), o.add(24, "hour"));
|
|
774
778
|
const k = V.calculateDistance(p, l, !l.gcToPrevious);
|
|
775
779
|
let w = Math.ceil(k / j.speed * 1e4) / 1e4;
|
|
776
|
-
if (m + w <
|
|
780
|
+
if (m + w < n) {
|
|
777
781
|
if (m += w, t.add(w, "hour"), delete a[b], S == null || S.info(
|
|
778
782
|
`[%s] go to %j from %j with ${k}nm, and cost ${w} hours`,
|
|
779
783
|
d.requestId,
|
|
780
784
|
{ lat: l.lat, lng: l.lng },
|
|
781
785
|
{ lat: j.lat, lng: j.lng, etd: j.etd }
|
|
782
786
|
), u += k, a.filter((y) => y).length <= 1) {
|
|
783
|
-
Y = l, Y.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), Y.distanceFromPrevious = k, Y.distanceFromStart =
|
|
787
|
+
Y = l, Y.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), Y.distanceFromPrevious = k, Y.distanceFromStart = i + u, f.push(Y), delete a[b + 1];
|
|
784
788
|
break;
|
|
785
789
|
}
|
|
786
790
|
} else {
|
|
787
|
-
w =
|
|
791
|
+
w = n - m, t.add(w, "hour");
|
|
788
792
|
const y = B.roundPrecision(j.speed * w, 4);
|
|
789
793
|
Y = V.calculateCoordinate(p, s.bearing, y, "nauticalmiles", !l.gcToPrevious), Y.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[b] = Y, S == null || S.info(
|
|
790
794
|
`[%s] go to %j from %j with ${y}nm, and cost ${w} hours`,
|
|
791
795
|
d.requestId,
|
|
792
796
|
{ lat: Y.lat, lng: Y.lng },
|
|
793
797
|
{ lat: p.lat, lng: p.lng, etd: p.etd }
|
|
794
|
-
), u += y, Y.distanceFromPrevious = u, Y.distanceFromStart =
|
|
798
|
+
), u += y, Y.distanceFromPrevious = u, Y.distanceFromStart = i + u;
|
|
795
799
|
break;
|
|
796
800
|
}
|
|
797
801
|
}
|
|
@@ -803,12 +807,12 @@ class C {
|
|
|
803
807
|
* @param current 洋流要素
|
|
804
808
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
805
809
|
*/
|
|
806
|
-
static currentFactor(s, t,
|
|
807
|
-
const
|
|
808
|
-
if (Math.abs(
|
|
810
|
+
static currentFactor(s, t, o = 0) {
|
|
811
|
+
const n = (s - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
812
|
+
if (Math.abs(n) === Math.PI / 2)
|
|
809
813
|
return 0;
|
|
810
|
-
let
|
|
811
|
-
return
|
|
814
|
+
let i = ((t == null ? void 0 : t.kts) || 0) * Math.cos(n);
|
|
815
|
+
return o & 2 ? i = Math.ceil(i * 100) / 100 : o & 1 ? i = Math.floor(i * 100) / 100 : i = Math.round(i * 100) / 100, Math.abs(i) > 5 ? 0 : i;
|
|
812
816
|
}
|
|
813
817
|
/**
|
|
814
818
|
* 风浪影响因子
|
|
@@ -818,14 +822,14 @@ class C {
|
|
|
818
822
|
static weatherFactor(s, t) {
|
|
819
823
|
var f, M, m, u, Y, j, b;
|
|
820
824
|
S == null || S.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
821
|
-
const
|
|
825
|
+
const o = C.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = C.froudeNumber(s.speed, s.lbp), i = C.amendFactor(o, n, s.loadCondition);
|
|
822
826
|
let a = Math.abs(s.bearing % 360 - (((f = t == null ? void 0 : t.wind) == null ? void 0 : f.degree) % 360 || 0));
|
|
823
827
|
a = a > 180 ? 360 - a : a;
|
|
824
828
|
const e = C.directionFactor(a, (M = t == null ? void 0 : t.wind) == null ? void 0 : M.scale), c = C.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (m = t == null ? void 0 : t.wind) == null ? void 0 : m.scale);
|
|
825
|
-
let r = e *
|
|
829
|
+
let r = e * i * c / 100 * s.speed;
|
|
826
830
|
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), S == null || S.debug("wind wx factor = %d", r), a = Math.abs(s.bearing % 360 - (((Y = (u = t == null ? void 0 : t.wave) == null ? void 0 : u.sig) == null ? void 0 : Y.degree) % 360 || 0));
|
|
827
831
|
const d = C.waveHeightFactor(((b = (j = t == null ? void 0 : t.wave) == null ? void 0 : j.sig) == null ? void 0 : b.height) ?? 1, a);
|
|
828
|
-
return S == null || S.debug("wave wx factor = %d", d), r = r * 0.4 + d, S == null || S.debug("weather factor = %d", r), r = Math.abs(r) > 4 ? 4 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 4) * 0.1 : r, Math.round(r * 100) / 100;
|
|
832
|
+
return S == null || S.debug("wave wx factor = %d", d), r = r * 0.4 + d, S == null || S.debug("weather factor = %d", r), r = Math.abs(r) > 4 ? 4 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 4) * 0.1 : r, Math.round((r || 0) * 100) / 100;
|
|
829
833
|
}
|
|
830
834
|
/**
|
|
831
835
|
* 全程失速分析(走完航程)
|
|
@@ -839,11 +843,11 @@ class C {
|
|
|
839
843
|
* @param useMeteo true 启用气象分析
|
|
840
844
|
* @param useRouteParam
|
|
841
845
|
*/
|
|
842
|
-
static async analyseInstant(s, t,
|
|
846
|
+
static async analyseInstant(s, t, o, n, i, a = "", e = 0, c = !0, r = !1, d = {}) {
|
|
843
847
|
var E, G, U, J, Q;
|
|
844
848
|
const f = v().valueOf();
|
|
845
849
|
s.lng = B.convertToStdLng(s.lng);
|
|
846
|
-
const { route: M, waypoints: m } =
|
|
850
|
+
const { route: M, waypoints: m } = i.points, u = V.calculateSubRoute(s, M);
|
|
847
851
|
if (((E = u[0]) == null ? void 0 : E.length) <= 1)
|
|
848
852
|
return;
|
|
849
853
|
const { v0: Y, label: j } = s.sog ? {
|
|
@@ -851,10 +855,10 @@ class C {
|
|
|
851
855
|
label: "Other"
|
|
852
856
|
/* Instruct */
|
|
853
857
|
} : {
|
|
854
|
-
v0:
|
|
858
|
+
v0: n.speed,
|
|
855
859
|
label: "CP"
|
|
856
860
|
/* Cp */
|
|
857
|
-
}, b = C.assembleProperties(
|
|
861
|
+
}, b = C.assembleProperties(o, n.loadCondition, Y, 0), p = m.length ? V.calculateSubWaypoints(s, m) : [];
|
|
858
862
|
p.forEach((x) => x.important = !0);
|
|
859
863
|
const l = {
|
|
860
864
|
from: { ...s },
|
|
@@ -867,7 +871,7 @@ class C {
|
|
|
867
871
|
days: [],
|
|
868
872
|
wps: []
|
|
869
873
|
};
|
|
870
|
-
e || (V.calculateRouteDistance(u) /
|
|
874
|
+
e || (V.calculateRouteDistance(u) / n.speed <= 72 ? e = 3 : e = 6);
|
|
871
875
|
let w = V.simplifyRouteToCoordinates(u, p, 0), y = 0, g = 0, H = 0, F = 0;
|
|
872
876
|
t = v(t).utc();
|
|
873
877
|
const O = t.clone();
|
|
@@ -904,7 +908,7 @@ class C {
|
|
|
904
908
|
}
|
|
905
909
|
}), l.sample = k;
|
|
906
910
|
const L = k.hours.at(0), W = k.hours.at(-1);
|
|
907
|
-
l.distance = Math.round(W.distanceFromStart * 1e4) / 1e4, l.etd = v(L.eta).utc().format(), l.eta = v(W.eta).utc().format(), l.wxFactor = Math.round(g / F * 1e4) / 1e4, l.cFactor = Math.round(H / F * 1e4) / 1e4, l.avgSpeed = Math.round(W.distanceFromStart / F * 1e4) / 1e4, l.totalHrs = Math.round(F * 1e4) / 1e4, l.totalFoCons = Math.round((
|
|
911
|
+
l.distance = Math.round(W.distanceFromStart * 1e4) / 1e4, l.etd = v(L.eta).utc().format(), l.eta = v(W.eta).utc().format(), l.wxFactor = Math.round(g / F * 1e4) / 1e4, l.cFactor = Math.round(H / F * 1e4) / 1e4, l.avgSpeed = Math.round(W.distanceFromStart / F * 1e4) / 1e4, l.totalHrs = Math.round(F * 1e4) / 1e4, l.totalFoCons = Math.round((n == null ? void 0 : n.fo) / 24 * l.totalHrs * 1e3) / 1e3, l.totalDgoCons = Math.round((n == null ? void 0 : n.dgo) / 24 * l.totalHrs * 1e3) / 1e3;
|
|
908
912
|
const P = v().valueOf() - f, D = ((Q = k == null ? void 0 : k.hours) == null ? void 0 : Q.length) || 1;
|
|
909
913
|
return S == null || S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", d == null ? void 0 : d.requestId, P, D, Math.round(P / D * 1e3) / 1e3), l;
|
|
910
914
|
}
|
|
@@ -921,7 +925,7 @@ class C {
|
|
|
921
925
|
* @param useMeteo true 启用气象分析
|
|
922
926
|
* @param useRouteParam
|
|
923
927
|
*/
|
|
924
|
-
static async analyseInstantWithThreshed(s, t,
|
|
928
|
+
static async analyseInstantWithThreshed(s, t, o, n, i, a, e, c = "", r = 3, d = !0, f = !1, M = {}) {
|
|
925
929
|
var W, T, P;
|
|
926
930
|
s.lng = B.convertToStdLng(s.lng);
|
|
927
931
|
const { v0: m, label: u } = s.sog ? {
|
|
@@ -929,10 +933,10 @@ class C {
|
|
|
929
933
|
label: "Other"
|
|
930
934
|
/* Instruct */
|
|
931
935
|
} : {
|
|
932
|
-
v0:
|
|
936
|
+
v0: i.speed,
|
|
933
937
|
label: "CP"
|
|
934
938
|
/* Cp */
|
|
935
|
-
}, Y = C.assembleProperties(
|
|
939
|
+
}, Y = C.assembleProperties(n, i.loadCondition, m, 0), j = V.calculateSubRoute(s, a);
|
|
936
940
|
if (((W = j[0]) == null ? void 0 : W.length) <= 1)
|
|
937
941
|
return;
|
|
938
942
|
const b = e.length ? V.calculateSubWaypoints(s, e) : [];
|
|
@@ -946,11 +950,11 @@ class C {
|
|
|
946
950
|
for (t = v(t).utc(); p.length > 0; ) {
|
|
947
951
|
const D = r - t.hour() % r;
|
|
948
952
|
let E = Math.ceil(t.clone().add(D, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
949
|
-
if (E = t.clone().add(E, "h").isAfter(
|
|
953
|
+
if (E = t.clone().add(E, "h").isAfter(o) ? o.diff(t, "h", !0) * 1e4 / 1e4 : E, E)
|
|
950
954
|
g = await C.speedLoseInHoursStep(
|
|
951
955
|
Y,
|
|
952
956
|
t,
|
|
953
|
-
|
|
957
|
+
o.clone(),
|
|
954
958
|
E,
|
|
955
959
|
l,
|
|
956
960
|
p,
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(w,T){typeof exports=="object"&&typeof module<"u"?T(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo","@idm-plugin/meteo2","@idm-plugin/meteo"],T):(w=typeof globalThis<"u"?globalThis:w||self,T(w["idm-plugin-rabbitmq"]={},w.got,w["@log4js-node/log4js-api"],w.moment,w["@idm-plugin/geo"],w["@idm-plugin/meteo2"],w["@idm-plugin/meteo"]))})(this,function(w,T,Z,v,O,G,U){"use strict";var mt=Object.defineProperty;var pt=(w,T,Z)=>T in w?mt(w,T,{enumerable:!0,configurable:!0,writable:!0,value:Z}):w[T]=Z;var K=(w,T,Z)=>(pt(w,typeof T!="symbol"?T+"":T,Z),Z);let u;try{u=Z.getLogger("vessel")}catch{}finally{}class z{parseStatus(s){let t,i;switch(s){case 0:t="在航(主机推动)",i="The engine is in use";break;case 1:t="锚泊",i="Anchored";break;case 2:t="失控",i="Not operated";break;case 3:t="操纵受限",i="Limited airworthiness";break;case 4:t="吃水受限",i="Limited by ship's draft";break;case 5:t="靠泊",i="Mooring";break;case 6:t="搁浅",i="Stranded";break;case 7:t="捕捞作业",i="Engaged in fishing";break;case 8:t="靠帆船提供动力",i="Sailing";break;default:t="未定义",i="Undefined"}return{labelCn:t,labelEn:i}}}class rt extends z{constructor(t,i){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",n={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await T.post(i,n).json();u==null||u.info("[%s] fetch access token from: %s - %j",t.requestId,i,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:v().utc().format()})}async realTimePosition(t,i={}){var d,f,M;(!this.token||v().diff(v(this.token.issuedAt),"seconds")>((d=this.token)==null?void 0:d.expiresIn)-300)&&await this.authToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(M=this.token)==null?void 0:M.accessToken}`},searchParams:{mmsi:t}};u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const a=await T.get(n,o).json();if(a.code)return u==null||u.warn("[%s] fetch realtime position failed: %j",i.requestId,n,{message:a.message,status:a.status,code:a.code}),a;const e=a.data;for(const m in e)!isNaN(e[m])&&Number(e[m])!==1/0&&(e[m]=Number(e[m]));const c=v(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName,imo:e.imo,callSign:e.callsign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.dest,positionTime:c.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,method:"position",vendor:"myVessel",utc:c.utc().format()}}async trajectory(t,i,n,o,a=!0,e={}){(!this.token||v().diff(v(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const c=await this.realTimePosition(t,e),r=v(i),d=v(n),f=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),c,o,f,e),r.add(30,"day");return await this.trajectoryIn30Day(t,r,d,c,o,f,e),f}async trajectoryIn30Day(t,i,n,o,a,e,c={}){var h,I,j,b,p;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",d={headers:{Authorization:`${(h=this.token)==null?void 0:h.tokenType} ${(I=this.token)==null?void 0:I.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};u==null||u.info("[%s] fetch trajectory from: %s - %j",c.requestId,r,d);const f=await T.post(r,d).json();if(f.code)return u==null||u.warn("[%s] fetch trajectory failed: %j",c.requestId,r,{message:f.message,status:f.status,code:f.code}),f;let M=-1;const m=v(`${(b=(j=f.data)==null?void 0:j[0])==null?void 0:b.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(p=f.data)==null||p.forEach(l=>{for(const W in l)!isNaN(l[W])&&Number(l[W])!==1/0&&(l[W]=Number(l[W]));const Y=v(`${l.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),H=l.status,{labelCn:y,labelEn:g}=this.parseStatus(H),F={mmsi:l.mmsi,imo:o==null?void 0:o.imo,lat:l.lat,lng:l.lon,sog:l.sog,cog:l.cog,hdg:l.hdg,draught:l.draught,status:H,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(l.eta)?v(`${l.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:l.dest,positionTime:Y.unix(),labelCn:y,labelEn:g,method:"trajectory",vendor:"myVessel",utc:Y.utc().format()},E=Math.floor(Y.diff(m,"minute",!0)/(a||1));E!==M&&(M=E,e.push(F))}),e}}class ct extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:t,usertoken:this.token}},a=await T.post(n,o).json();u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const e=a==null?void 0:a.list;if(!e)return u==null||u.warn("[%s] fetch realtime position failed: %j",i.requestId,n,a),a;for(const m in e)!isNaN(e[m])&&Number(e[m])!==1/0&&(e[m]=Number(e[m]));e.status=e.sp>3?0:1;const c=e.status,{labelCn:r,labelEn:d}=this.parseStatus(c),f=v(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.destination,positionTime:f.unix(),utc:f.utc().format(),status:c,labelCn:r,labelEn:d,method:"position",vendor:"hifleet"}}async search(t,i={}){let n="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await T.post(n,o).json();u==null||u.info("[%s] fetch vessel props from: %s - %j",i.requestId,n,o),a instanceof Array&&(a=a[0]);for(const c in a)!isNaN(a[c])&&Number(a[c])!==1/0&&(a[c]=Number(a[c]));const e={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr};return n="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await T.post(n,o).json(),u==null||u.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,n,o),a instanceof Array&&(a=a[0]),a&&(e.deadweight=Number(a.dwt)),e}async trajectory(t,i,n,o,a=!0,e={}){var l,Y,H;const c=await this.realTimePosition(t,e);let r=v(i);const d=v(n),f=v();if(a){let y=d.diff(r,"d",!0);y<0?r=d.clone().subtract(40,"d"):y<30?r.subtract(10,"d"):y<60?r.subtract(5,"d"):r=d.clone().subtract(80,"d"),y=f.diff(d,"d",!0),d.add(y>10?240:y*24,"h")}const M={searchParams:{endtime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},m="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",h=await T.get(m,M).json();u==null||u.info("[%s] fetch trajectory from: %s - %j",e.requestId,m,M);let I;h&&(I=((Y=(l=h.ships)==null?void 0:l.offors)==null?void 0:Y.ship)||[],I.length||u==null||u.warn("[%s] fetch trajectory failed: %j",e.requestId,h));const j=[];let b=-1;const p=v(`${(H=I==null?void 0:I[0])==null?void 0:H.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of I){for(const _ in y)!isNaN(y[_])&&Number(y[_])!==1/0&&(y[_]=Number(y[_]));const g=v(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:F,labelCn:E}=this.parseStatus(y.status),W={mmsi:y.m,name:y.n,imo:c==null?void 0:c.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:g.unix(),utc:g.utc().format(),status:y.status,labelCn:E,labelEn:F,method:"trajectory",vendor:"hifleet"},q=Math.floor(g.diff(p,"minute",!0)/(o||1));q!==b&&(b=q,j.push(W))}return j}}class dt extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n={searchParams:{id:t,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",a=await T.get(o,n).json();if(u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n),(a==null?void 0:a.status)!==0)return a;const e=a.data[0];for(const M in e)!isNaN(e[M])&&Number(e[M])!==1/0&&(e[M]=Number(e[M]));const{labelCn:c,labelEn:r}=await this.parseStatus(e.navistat),d=v.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:d.utc().format(),status:e.navistat,labelEn:r,labelCn:c,method:"position",vendor:"shipxy"}}async trajectory(t,i,n,o,a=!0,e={}){var p;const c=await this.realTimePosition(t,e),r=v(i),d=v(n),f="https://api.shipxy.com/apicall/GetShipTrack",M={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:d.unix()}},m=await T.get(f,M).json();if(u==null||u.info("[%s] fetch trajectory from: %s - %j",e.requestId,f,M),(m==null?void 0:m.status)!==0)return m;const h=m==null?void 0:m.points,I=[],j=v.unix((p=h[0])==null?void 0:p.utc);let b=-1;for(const l of h){const Y=v.unix(l.utc),H={imo:c==null?void 0:c.imo,mmsi:t,sog:Math.round(l.sog*3600/1e3/1852*100)/100,cog:Math.round(l.cog/100*100)/100,lat:Math.round(l.lat/1e6*1e5)/1e5,lng:Math.round(l.lon/1e6*1e5)/1e5,positionTime:Y.unix(),utc:Y.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(Y.diff(j,"minute",!0)/(o||1));y!==b&&(b=y,I.push(H))}return I}}class ut extends z{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,i={}){const n={headers:{appKey:this.token},json:{mmsiList:t}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await T.post(o,n).json();return u==null||u.info("[%s] fetch ship id from: %s - %j",i.requestId,o,n),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,i={}){const n={headers:{appKey:this.token},json:{shipId:t}},o="https://api3.myships.com/sp/ships/aissta",a=await T.post(o,n).json();if(u==null||u.info("[%s] fetch ship info from: %s - %j",i.requestId,o,n),a.code!=="0")return a;const e=a.data;let c=e.imo;return t==="407170"&&(c="9198379",u==null||u.warn("[%s] ship(%s) imo error: %s, should be %s",i.requestId,t,e.imo,c)),{mmsi:e.mmsi,name:e.shipnameEn,imo:c,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,i={}){const n=await this.getShipId(t,i),o=await this.getShipInfo(n,i),a={headers:{appKey:this.token},json:{shipId:n}},e="https://api3.myships.com/sp/ships/position/latest",c=await T.post(e,a).json();u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,a);const r=c.data[0];for(const h in r)!isNaN(r[h])&&Number(r[h])!==1/0&&(r[h]=Number(r[h]));const{labelCn:d,labelEn:f}=await this.parseStatus(r.aisNavStatus),M=v.unix(r.posTime);return{...o,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:M.utc().format(),status:r.aisNavStatus,labelEn:f,labelCn:d,method:"position",vendor:"myship"}}async trajectory(t,i,n,o,a=!0,e={}){const c=v(i),r=v(n),d=await this.getShipId(t),f=await this.getShipInfo(d),M=[];for(;r.diff(c,"day",!0)>30;)await this.trajectoryIn30Day(d,c.unix(),c.add(30,"day").unix(),f,t,o,M);return await this.trajectoryIn30Day(d,c.unix(),r.unix(),f,t,o,M),M}async trajectoryIn30Day(t,i,n,o,a,e,c,r={}){var j;const d={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:n}},f="https://api3.myships.com/sp/ships/position/history",M=await T.post(f,d).json();if(u==null||u.info("[%s] fetch trajectory from: %s - %j",r.requestId,f,d),M.code!=="0")return u==null||u.warn("[%s] invoke myship trajectory failed: %j",r.requestId,M),M;const m=M.data;for(const b in m)!isNaN(m[b])&&Number(m[b])!==1/0&&(m[b]=Number(m[b]));const h=v.unix((j=m[0])==null?void 0:j.posTime);let I=-1;for(const b of m){const p=v.unix(b.posTime),l={imo:o==null?void 0:o.imo,mmsi:a,lat:Math.round(b.lat/1e4/60*1e5)/1e5,lng:Math.round(b.lon/1e4/60*1e5)/1e5,sog:Math.round(b.sog/10*100)/100,cog:Math.round(b.cog/10*100)/100,hdg:Math.round(b.heading*100)/100,rot:Math.round(b.rot*100)/100,positionTime:p.unix(),utc:p.utc().format(),method:"trajectory",vendor:"myship"},Y=Math.floor(p.diff(h,"minute",!0)/(e||1));Y!==I&&(I=Y,c.push(l))}return c}}let R;try{R=Z.getLogger("vessel")}catch{}finally{}var J=(k=>(k.NOTICE="NOTICE",k.WARN="WARN",k.HEAVY="HEAVY",k.SEVERE="SEVERE",k.ERROR="ERROR",k.FATAL="FATAL",k))(J||{});class Q{parsePrinciple(s,t={}){var e,c,r;R==null||R.info("[%s] parse rule: %s",t.requestId,s);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),n=s.match(i)?(e=s.match(i))==null?void 0:e[0]:void 0,o=n==null?void 0:n.split(";");if(!o)return;const a={};for(let d=0;d<(o==null?void 0:o.length);d++){const f=(r=(c=o[d].match(i))==null?void 0:c[0])==null?void 0:r.split("],");if(d===0&&!f)a.scope=o[0];else if(f)for(let M=0,m=f.length;M<m;M++){const h=this.parseRule(f[M]);h&&(a[h.level]?h.key?a[h.level][h==null?void 0:h.key]=h:a[h.level]=h:h.key?a[h.level]={[h==null?void 0:h.key]:h}:a[h.level]=h)}}return a}parseRule(s,t={}){var a;R==null||R.info("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),n=(a=s==null?void 0:s.match(i))==null?void 0:a[0],o=n==null?void 0:n.split(",");if(o)return{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:Number(o[3]),key:o[4]}}checkWeather(s,t,i={}){var h,I,j,b,p,l,Y,H,y,g,F,E,W,q,_;let n=0,o=0,a=0,e=0;const c=Math.round(((I=(h=t==null?void 0:t.SEVERE)==null?void 0:h.sigWave)==null?void 0:I.number)*1.6*100)/100,r=(b=(j=t==null?void 0:t.SEVERE)==null?void 0:j.sigWave)==null?void 0:b.number,d=(l=(p=t==null?void 0:t.HEAVY)==null?void 0:p.sigWave)==null?void 0:l.number,f=Math.round((((H=(Y=t==null?void 0:t.SEVERE)==null?void 0:Y.wind)==null?void 0:H.number)+2)*100)/100,M=(g=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:g.number,m=(E=(F=t==null?void 0:t.HEAVY)==null?void 0:F.wind)==null?void 0:E.number;for(let V=0;V<(s==null?void 0:s.length);V++){const S=s[V],C=(q=(W=S==null?void 0:S.meteo)==null?void 0:W.wave)==null?void 0:q.sig,N=(_=S==null?void 0:S.meteo)==null?void 0:_.wind,L=V?v(S.eta).diff(v(s[V-1].eta),"hour",!0):0;e=L>e?L:e,R==null||R.info("[%s] check sig.wave: %j",i.requestId,{...C,dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:d}),(C==null?void 0:C.height)>=c?S.isDangerous=!0:(C==null?void 0:C.height)>=r?S.isSevere=!0:(C==null?void 0:C.height)>=d&&(S.isHeavy=!0),R==null||R.info("[%s] check wind: %j",i.requestId,{...N,dgThd4Wd:f,svThd4Wd:M,hvThd4Wd:m}),(N==null?void 0:N.scale)>=f?(S.isDangerous=!0,delete S.isSevere,delete S.isHeavy):(N==null?void 0:N.scale)>M?(S.isDangerous||(S.isSevere=!0),delete S.isHeavy):(N==null?void 0:N.scale)===m&&!S.isDangerous&&!S.isSevere&&(S.isHeavy=!0),n+=S.isDangerous?L:0,o+=S.isSevere?L:0,a+=S.isHeavy?L:0}return n=Math.round(n*100)/100,o=Math.round(o*100)/100,a=Math.round(a*100)/100,e=Math.round(e),{sample:s,dangerous:n,severe:o,heavy:a,step:e<3?3:e,wind:{dgThd4Wd:f,svThd4Wd:M,hvThd4Wd:m},sig:{dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:d}}}}const ht=new Q;let D;try{D=Z.getLogger("vessel")}catch{}finally{}const lt=new G.MeteoHelper2("",!0);var X=(k=>(k.common="common",k.container="container",k.tugs="tugs",k))(X||{}),$=(k=>(k.Ballast="Ballast",k.Laden="Laden",k))($||{}),tt=(k=>(k.Cp="CP",k.Perf="Basis",k.Instruct="Other",k))(tt||{});class A{static blockCoefficient(s,t,i,n){let o=Math.round(s/(t*i*n)*100)/100;o=o<.55?.55:o>.85?.85:o;const a=[.55,.6,.65,.7,.75,.8,.85],e=a.map(c=>Math.abs(c-o));return a[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,i=9.8){let n=Math.round(Math.sqrt(s*s/(i*t))*100)/100;return n=n<.05?.05:n>.3?.3:n,n}static amendFactor(s,t,i){const n={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return i==="Laden"&&(a=n[s]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(s,t=0){let i;return s>30&&s<=60?i=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?i=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?i=(.4-.03*Math.pow(t-8,2))/2:i=1,Math.round(i*1e5)/1e5}static vesselTagFactor(s,t,i,n=0){n=n>6?n-.9*(n-6):n;let o;return i==="container"?o=.7*n+Math.pow(n,6.5)/(22*Math.pow(s,2/3)):t==="Ballast"?o=.7*n+Math.pow(n,6.5)/(2.7*Math.pow(s,2/3)):o=.5*n+Math.pow(n,6.5)/(2.7*Math.pow(s,2/3)),o}static waveHeightFactor(s,t){s=s<0?.2:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let i;return t>30&&t<=60?i=-.6:t>60&&t<=90?i=-.4:t>90&&t<=120?i=s<3?.4:-.3:t>120&&t<=150?i=s<3?.6:-.5:t>150&&t<=180?i=s<3?.7:-.6:i=-.7,Math.round(i*(.144*Math.pow(s,2)+.178*s)*1e4)/1e4}static assembleProperties(s,t,i,n){var M;const o=s.lbp??s.length??s.lengthOverall??198.9642,a=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,c=s.deadweight??67035.7773,r=((M=s==null?void 0:s.type)==null?void 0:M.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:o,loadCondition:t,draught:a,breadthMoulded:e,displacement:Math.round((c/1.025+a*e*o*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:n||90}}static async speedLoseAt(s,t,i,n="",o=2,a=!0,e=!1,c={}){let r;if(t.velocity&&e&&(s.speed=O.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){let d;if(c.meteo2){const h=await lt.spotForecast(t.lat,t.lng,i.utc().format(),!1,!1,!0,c),[I]=U.Meteo2Assist.pickHourly(h,i);d=U.Meteo2Assist.toLegacy(I)}else d=await G.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",n,c);const f=A.weatherFactor(s,d),M=A.currentFactor(s.bearing,d==null?void 0:d.current,o),m=Math.round((s.speed*1.943844+f+M)*100)/100;r={meteo:{...d},wxFactor:f,cFactor:M,speed:t.velocity&&e?t.velocity:m<0?1:m,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round((s.speed*1.943844+0+0)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(s,t,i,n,o,a,e="",c=!0,r=!1,d={}){t.utc();const f=[],M=[];let m=0,h=0,I,j;for(let b=0;b<a.length-1;b++){let p=a[b];p.distanceFromStart=o+h;const l=a[b+1];if(s.bearing=O.LaneHelper.calculateBearing(p,l,!l.gcToPrevious),p.bearing=s.bearing,p.suspend&&r){p.eta=p.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),p.elapsed=p.elapsed??0;const y=p.suspend-p.elapsed;if(n-m>y)n=n-m-y,t.add(y,"hour"),p.elapsed=p.suspend;else{const g=n-m;p.elapsed+=g,t.add(g,"hour"),n=0}if(D==null||D.info(`[%s] suspend ${p.elapsed} hours at %j, and remain ${n} hours need to go...`,d.requestId,p),n===0)return p.distanceFromPrevious=h,{etd:t,from:j||p,to:p,next:a.filter(g=>g),wps:f,days:M}}else p.suspend=0;p=await A.speedLoseAt(s,p,t,e,0,c,r,d),j=j||p,p.important&&f.push(p),t.isSameOrAfter(i)&&(M.push(p),i.add(24,"hour"));const Y=O.LaneHelper.calculateDistance(p,l,!l.gcToPrevious);let H=Math.ceil(Y/j.speed*1e4)/1e4;if(m+H<n){if(m+=H,t.add(H,"hour"),delete a[b],D==null||D.info(`[%s] go to %j from %j with ${Y}nm, and cost ${H} hours`,d.requestId,{lat:l.lat,lng:l.lng},{lat:j.lat,lng:j.lng,etd:j.etd}),h+=Y,a.filter(y=>y).length<=1){I=l,I.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),I.distanceFromPrevious=Y,I.distanceFromStart=o+h,f.push(I),delete a[b+1];break}}else{H=n-m,t.add(H,"hour");const y=O.LngLatHelper.roundPrecision(j.speed*H,4);I=O.LaneHelper.calculateCoordinate(p,s.bearing,y,"nauticalmiles",!l.gcToPrevious),I.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),a[b]=I,D==null||D.info(`[%s] go to %j from %j with ${y}nm, and cost ${H} hours`,d.requestId,{lat:I.lat,lng:I.lng},{lat:p.lat,lng:p.lng,etd:p.etd}),h+=y,I.distanceFromPrevious=h,I.distanceFromStart=o+h;break}}return{etd:t,from:j,to:I,next:a.filter(b=>b),wps:f,days:M}}static currentFactor(s,t,i=0){const n=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(n)===Math.PI/2)return 0;let o=((t==null?void 0:t.kts)||0)*Math.cos(n);return i&2?o=Math.ceil(o*100)/100:i&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(s,t){var f,M,m,h,I,j,b;D==null||D.debug("calculate weather factor via: %j",{...s,...t});const i=A.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=A.froudeNumber(s.speed,s.lbp),o=A.amendFactor(i,n,s.loadCondition);let a=Math.abs(s.bearing%360-(((f=t==null?void 0:t.wind)==null?void 0:f.degree)%360||0));a=a>180?360-a:a;const e=A.directionFactor(a,(M=t==null?void 0:t.wind)==null?void 0:M.scale),c=A.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(m=t==null?void 0:t.wind)==null?void 0:m.scale);let r=e*o*c/100*s.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),D==null||D.debug("wind wx factor = %d",r),a=Math.abs(s.bearing%360-(((I=(h=t==null?void 0:t.wave)==null?void 0:h.sig)==null?void 0:I.degree)%360||0));const d=A.waveHeightFactor(((b=(j=t==null?void 0:t.wave)==null?void 0:j.sig)==null?void 0:b.height)??1,a);return D==null||D.debug("wave wx factor = %d",d),r=r*.4+d,D==null||D.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round(r*100)/100}static async analyseInstant(s,t,i,n,o,a="",e=0,c=!0,r=!1,d={}){var L,et,st,at,nt;const f=v().valueOf();s.lng=O.LngLatHelper.convertToStdLng(s.lng);const{route:M,waypoints:m}=o.points,h=O.LaneHelper.calculateSubRoute(s,M);if(((L=h[0])==null?void 0:L.length)<=1)return;const{v0:I,label:j}=s.sog?{v0:s.sog,label:"Other"}:{v0:n.speed,label:"CP"},b=A.assembleProperties(i,n.loadCondition,I,0),p=m.length?O.LaneHelper.calculateSubWaypoints(s,m):[];p.forEach(x=>x.important=!0);const l={from:{...s},route:h,waypoints:p,v0:I,label:j},Y={hours:[],days:[],wps:[]};e||(O.LaneHelper.calculateRouteDistance(h)/n.speed<=72?e=3:e=6);let H=O.LaneHelper.simplifyRouteToCoordinates(h,p,0),y=0,g=0,F=0,E=0;t=v(t).utc();const W=t.clone();for(;H.length>0;){const x=e-t.hour()%e,B=Math.ceil(t.clone().add(x,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,P=await A.speedLoseInHoursStep(b,t,W,B,y,H,a,c,r,d);(et=P.from)!=null&&et.speed&&(Y.hours.push(P.from),Y.wps.push(...P.wps),Y.days.push(...P.days)),H=P==null?void 0:P.next,H.length||Y.hours.push(P==null?void 0:P.to),y+=((st=P==null?void 0:P.to)==null?void 0:st.distanceFromPrevious)??0}const q=Y.hours;for(let x=0;x<q.length-1;x++){const B=v(q[x+1].eta).diff(q[x].etd,"hour",!0)||1;g+=(q[x].wxFactor||0)*B,F+=(q[x].cFactor||0)*B,E+=B}(at=Y.wps)==null||at.forEach((x,B)=>{if(B){const P=Y.wps[B-1],ft=x.distanceFromStart-P.distanceFromStart,ot=v(x.eta).diff(v(P.etd),"h",!0);if(ot<1)x.avgSpd=P.speed;else{x.avgSpd=Math.round(ft/ot*100)/100;const it=Math.round((P.speed+x.speed)/2*100)/100;x.avgSpd=x.avgSpd>it?it:x.avgSpd}}}),l.sample=Y;const _=Y.hours.at(0),V=Y.hours.at(-1);l.distance=Math.round(V.distanceFromStart*1e4)/1e4,l.etd=v(_.eta).utc().format(),l.eta=v(V.eta).utc().format(),l.wxFactor=Math.round(g/E*1e4)/1e4,l.cFactor=Math.round(F/E*1e4)/1e4,l.avgSpeed=Math.round(V.distanceFromStart/E*1e4)/1e4,l.totalHrs=Math.round(E*1e4)/1e4,l.totalFoCons=Math.round((n==null?void 0:n.fo)/24*l.totalHrs*1e3)/1e3,l.totalDgoCons=Math.round((n==null?void 0:n.dgo)/24*l.totalHrs*1e3)/1e3;const C=v().valueOf()-f,N=((nt=Y==null?void 0:Y.hours)==null?void 0:nt.length)||1;return D==null||D.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",d==null?void 0:d.requestId,C,N,Math.round(C/N*1e3)/1e3),l}static async analyseInstantWithThreshed(s,t,i,n,o,a,e,c="",r=3,d=!0,f=!1,M={}){var V,S,C;s.lng=O.LngLatHelper.convertToStdLng(s.lng);const{v0:m,label:h}=s.sog?{v0:s.sog,label:"Other"}:{v0:o.speed,label:"CP"},I=A.assembleProperties(n,o.loadCondition,m,0),j=O.LaneHelper.calculateSubRoute(s,a);if(((V=j[0])==null?void 0:V.length)<=1)return;const b=e.length?O.LaneHelper.calculateSubWaypoints(s,e):[];b.forEach(N=>N.important=!0);let p=O.LaneHelper.simplifyRouteToCoordinates(j,b,0),l=0,Y=0,H=0,y=0,g;const F={hours:[],wps:[],days:[]};for(t=v(t).utc();p.length>0;){const N=r-t.hour()%r;let L=Math.ceil(t.clone().add(N,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(L=t.clone().add(L,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:L,L)g=await A.speedLoseInHoursStep(I,t,i.clone(),L,l,p,c,d,f,M),(S=g.from)!=null&&S.speed&&(F.hours.push(g.from),g!=null&&g.wps&&F.wps.push(...g.wps),F.days.push(...g.days)),p=g==null?void 0:g.next,p.length||(F.hours.push(g==null?void 0:g.to),g!=null&&g.wps&&F.wps.push(...g.wps),F.days.push(g==null?void 0:g.to)),l+=((C=g==null?void 0:g.to)==null?void 0:C.distanceFromPrevious)??0;else{g&&(F.hours.push(g.to),g!=null&&g.wps&&F.wps.push(...g.wps),F.days.push(g.to));break}}const E=F.hours;for(let N=0;N<E.length-1;N++){const L=v(E[N+1].eta).diff(E[N].etd,"hour",!0);Y+=E[N].wxFactor*L,H+=E[N].cFactor*L,y+=L}const W=F.hours.at(0),q=F.hours.at(-1);return{sample:F,distance:Math.round(((q==null?void 0:q.distanceFromStart)||0)*1e4)/1e4,etd:v(W.eta).utc().format(),eta:v(q==null?void 0:q.eta).utc().format(),wxFactor:Math.round(Y/y*1e4)/1e4,cFactor:Math.round(H/y*1e4)/1e4,avgSpeed:Math.round(((q==null?void 0:q.distanceFromStart)||0)/y*1e4)/1e4,totalHrs:Math.round(y*1e4)/1e4,from:s,to:q,route:j,waypoints:b,v0:m,label:h}}}w.AISImpl=z,w.AlertHelper=Q,w.AlertLevel=J,w.HifleetImpl=ct,w.LoadCondition=$,w.MyShipImpl=ut,w.MyVesselImpl=rt,w.ShipxyImpl=dt,w.SpeedHelper=A,w.SpeedLabel=tt,w.VesselTag=X,w.alertHelper=ht,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(w,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo","@idm-plugin/meteo2","@idm-plugin/meteo"],D):(w=typeof globalThis<"u"?globalThis:w||self,D(w["idm-plugin-rabbitmq"]={},w.got,w["@log4js-node/log4js-api"],w.moment,w["@idm-plugin/geo"],w["@idm-plugin/meteo2"],w["@idm-plugin/meteo"]))})(this,function(w,D,Z,v,O,G,U){"use strict";var mt=Object.defineProperty;var pt=(w,D,Z)=>D in w?mt(w,D,{enumerable:!0,configurable:!0,writable:!0,value:Z}):w[D]=Z;var K=(w,D,Z)=>(pt(w,typeof D!="symbol"?D+"":D,Z),Z);let h;try{h=Z.getLogger("vessel")}catch{}finally{}class z{parseStatus(s){let t,n;switch(s){case 0:t="在航(主机推动)",n="The engine is in use";break;case 1:t="锚泊",n="Anchored";break;case 2:t="失控",n="Not operated";break;case 3:t="操纵受限",n="Limited airworthiness";break;case 4:t="吃水受限",n="Limited by ship's draft";break;case 5:t="靠泊",n="Mooring";break;case 6:t="搁浅",n="Stranded";break;case 7:t="捕捞作业",n="Engaged in fishing";break;case 8:t="靠帆船提供动力",n="Sailing";break;default:t="未定义",n="Undefined"}return{labelCn:t,labelEn:n}}}class rt extends z{constructor(t,n){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=n}async authToken(t={}){const n="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},i=await D.post(n,o).json();h==null||h.info("[%s] fetch access token from: %s - %j",t.requestId,n,i),i.error||(this.token={accessToken:i.access_token,tokenType:i.token_type,expiresIn:i.expires_in,scope:i.scope,jti:i.jti,issuedAt:v().utc().format()})}async realTimePosition(t,n={}){var d,f,M;(!this.token||v().diff(v(this.token.issuedAt),"seconds")>((d=this.token)==null?void 0:d.expiresIn)-300)&&await this.authToken(n);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",i={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(M=this.token)==null?void 0:M.accessToken}`},searchParams:{mmsi:t}};h==null||h.info("[%s] fetch realtime position from: %s - %j",n.requestId,o,i);const a=await D.get(o,i).json();if(a.code)return h==null||h.warn("[%s] fetch realtime position failed: %j",n.requestId,o,{message:a.message,status:a.status,code:a.code}),a;const e=a.data;for(const m in e)!isNaN(e[m])&&Number(e[m])!==1/0&&(e[m]=Number(e[m]));const c=v(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName,imo:e.imo,callSign:e.callsign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.dest,positionTime:c.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,method:"position",vendor:"myVessel",utc:c.utc().format()}}async trajectory(t,n,o,i,a=!0,e={}){(!this.token||v().diff(v(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const c=await this.realTimePosition(t,e),r=v(n),d=v(o),f=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),c,i,f,e),r.add(30,"day");return await this.trajectoryIn30Day(t,r,d,c,i,f,e),f}async trajectoryIn30Day(t,n,o,i,a,e,c={}){var u,I,Y,b,p;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",d={headers:{Authorization:`${(u=this.token)==null?void 0:u.tokenType} ${(I=this.token)==null?void 0:I.accessToken}`},json:{mmsi:t,startTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};h==null||h.info("[%s] fetch trajectory from: %s - %j",c.requestId,r,d);const f=await D.post(r,d).json();if(f.code)return h==null||h.warn("[%s] fetch trajectory failed: %j",c.requestId,r,{message:f.message,status:f.status,code:f.code}),f;let M=-1;const m=v(`${(b=(Y=f.data)==null?void 0:Y[0])==null?void 0:b.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(p=f.data)==null||p.forEach(l=>{for(const W in l)!isNaN(l[W])&&Number(l[W])!==1/0&&(l[W]=Number(l[W]));const j=v(`${l.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),H=l.status,{labelCn:y,labelEn:g}=this.parseStatus(H),F={mmsi:l.mmsi,imo:i==null?void 0:i.imo,lat:l.lat,lng:l.lon,sog:l.sog,cog:l.cog,hdg:l.hdg,draught:l.draught,status:H,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(l.eta)?v(`${l.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:l.dest,positionTime:j.unix(),labelCn:y,labelEn:g,method:"trajectory",vendor:"myVessel",utc:j.utc().format()},E=Math.floor(j.diff(m,"minute",!0)/(a||1));E!==M&&(M=E,e.push(F))}),e}}class ct extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,n={}){const o="https://api.hifleet.com/position/position/get/token",i={searchParams:{mmsi:t,usertoken:this.token}},a=await D.post(o,i).json();h==null||h.info("[%s] fetch realtime position from: %s - %j",n.requestId,o,i);const e=a==null?void 0:a.list;if(!e)return h==null||h.warn("[%s] fetch realtime position failed: %j",n.requestId,o,a),a;for(const m in e)!isNaN(e[m])&&Number(e[m])!==1/0&&(e[m]=Number(e[m]));e.status=e.sp>3?0:1;const c=e.status,{labelCn:r,labelEn:d}=this.parseStatus(c),f=v(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.destination,positionTime:f.unix(),utc:f.utc().format(),status:c,labelCn:r,labelEn:d,method:"position",vendor:"hifleet"}}async search(t,n={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const i={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await D.post(o,i).json();h==null||h.info("[%s] fetch vessel props from: %s - %j",n.requestId,o,i),a instanceof Array&&(a=a[0]);for(const c in a)!isNaN(a[c])&&Number(a[c])!==1/0&&(a[c]=Number(a[c]));const e={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await D.post(o,i).json(),h==null||h.info("[%s] fetch vessel dead weight from: %s - %j",n.requestId,o,i),a instanceof Array&&(a=a[0]),a&&(e.deadweight=Number(a.dwt)),e}async trajectory(t,n,o,i,a=!0,e={}){var l,j,H;const c=await this.realTimePosition(t,e);let r=v(n);const d=v(o),f=v();if(a){let y=d.diff(r,"d",!0);y<0?r=d.clone().subtract(40,"d"):y<30?r.subtract(10,"d"):y<60?r.subtract(5,"d"):r=d.clone().subtract(80,"d"),y=f.diff(d,"d",!0),d.add(y>10?240:y*24,"h")}const M={searchParams:{endtime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},m="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",u=await D.get(m,M).json();h==null||h.info("[%s] fetch trajectory from: %s - %j",e.requestId,m,M);let I;u&&(I=((j=(l=u.ships)==null?void 0:l.offors)==null?void 0:j.ship)||[],I.length||h==null||h.warn("[%s] fetch trajectory failed: %j",e.requestId,u));const Y=[];let b=-1;const p=v(`${(H=I==null?void 0:I[0])==null?void 0:H.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of I){for(const _ in y)!isNaN(y[_])&&Number(y[_])!==1/0&&(y[_]=Number(y[_]));const g=v(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:F,labelCn:E}=this.parseStatus(y.status),W={mmsi:y.m,name:y.n,imo:c==null?void 0:c.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:g.unix(),utc:g.utc().format(),status:y.status,labelCn:E,labelEn:F,method:"trajectory",vendor:"hifleet"},q=Math.floor(g.diff(p,"minute",!0)/(i||1));q!==b&&(b=q,Y.push(W))}return Y}}class dt extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,n={}){const o={searchParams:{id:t,k:this.token,enc:1}},i="https://api.shipxy.com/apicall/GetSingleShip",a=await D.get(i,o).json();if(h==null||h.info("[%s] fetch realtime position from: %s - %j",n.requestId,i,o),(a==null?void 0:a.status)!==0)return a;const e=a.data[0];for(const M in e)!isNaN(e[M])&&Number(e[M])!==1/0&&(e[M]=Number(e[M]));const{labelCn:c,labelEn:r}=await this.parseStatus(e.navistat),d=v.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:d.utc().format(),status:e.navistat,labelEn:r,labelCn:c,method:"position",vendor:"shipxy"}}async trajectory(t,n,o,i,a=!0,e={}){var p;const c=await this.realTimePosition(t,e),r=v(n),d=v(o),f="https://api.shipxy.com/apicall/GetShipTrack",M={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:d.unix()}},m=await D.get(f,M).json();if(h==null||h.info("[%s] fetch trajectory from: %s - %j",e.requestId,f,M),(m==null?void 0:m.status)!==0)return m;const u=m==null?void 0:m.points,I=[],Y=v.unix((p=u[0])==null?void 0:p.utc);let b=-1;for(const l of u){const j=v.unix(l.utc),H={imo:c==null?void 0:c.imo,mmsi:t,sog:Math.round(l.sog*3600/1e3/1852*100)/100,cog:Math.round(l.cog/100*100)/100,lat:Math.round(l.lat/1e6*1e5)/1e5,lng:Math.round(l.lon/1e6*1e5)/1e5,positionTime:j.unix(),utc:j.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(j.diff(Y,"minute",!0)/(i||1));y!==b&&(b=y,I.push(H))}return I}}class ut extends z{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,n={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},i="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await D.post(i,o).json();return h==null||h.info("[%s] fetch ship id from: %s - %j",n.requestId,i,o),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,n={}){const o={headers:{appKey:this.token},json:{shipId:t}},i="https://api3.myships.com/sp/ships/aissta",a=await D.post(i,o).json();if(h==null||h.info("[%s] fetch ship info from: %s - %j",n.requestId,i,o),a.code!=="0")return a;const e=a.data;let c=e.imo;return t==="407170"&&(c="9198379",h==null||h.warn("[%s] ship(%s) imo error: %s, should be %s",n.requestId,t,e.imo,c)),{mmsi:e.mmsi,name:e.shipnameEn,imo:c,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,n={}){const o=await this.getShipId(t,n),i=await this.getShipInfo(o,n),a={headers:{appKey:this.token},json:{shipId:o}},e="https://api3.myships.com/sp/ships/position/latest",c=await D.post(e,a).json();h==null||h.info("[%s] fetch realtime position from: %s - %j",n.requestId,e,a);const r=c.data[0];for(const u in r)!isNaN(r[u])&&Number(r[u])!==1/0&&(r[u]=Number(r[u]));const{labelCn:d,labelEn:f}=await this.parseStatus(r.aisNavStatus),M=v.unix(r.posTime);return{...i,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:M.utc().format(),status:r.aisNavStatus,labelEn:f,labelCn:d,method:"position",vendor:"myship"}}async trajectory(t,n,o,i,a=!0,e={}){const c=v(n),r=v(o),d=await this.getShipId(t),f=await this.getShipInfo(d),M=[];for(;r.diff(c,"day",!0)>30;)await this.trajectoryIn30Day(d,c.unix(),c.add(30,"day").unix(),f,t,i,M);return await this.trajectoryIn30Day(d,c.unix(),r.unix(),f,t,i,M),M}async trajectoryIn30Day(t,n,o,i,a,e,c,r={}){var Y;const d={headers:{appKey:this.token},json:{shipId:t,startTime:n,endTime:o}},f="https://api3.myships.com/sp/ships/position/history",M=await D.post(f,d).json();if(h==null||h.info("[%s] fetch trajectory from: %s - %j",r.requestId,f,d),M.code!=="0")return h==null||h.warn("[%s] invoke myship trajectory failed: %j",r.requestId,M),M;const m=M.data;for(const b in m)!isNaN(m[b])&&Number(m[b])!==1/0&&(m[b]=Number(m[b]));const u=v.unix((Y=m[0])==null?void 0:Y.posTime);let I=-1;for(const b of m){const p=v.unix(b.posTime),l={imo:i==null?void 0:i.imo,mmsi:a,lat:Math.round(b.lat/1e4/60*1e5)/1e5,lng:Math.round(b.lon/1e4/60*1e5)/1e5,sog:Math.round(b.sog/10*100)/100,cog:Math.round(b.cog/10*100)/100,hdg:Math.round(b.heading*100)/100,rot:Math.round(b.rot*100)/100,positionTime:p.unix(),utc:p.utc().format(),method:"trajectory",vendor:"myship"},j=Math.floor(p.diff(u,"minute",!0)/(e||1));j!==I&&(I=j,c.push(l))}return c}}let R;try{R=Z.getLogger("vessel")}catch{}finally{}var J=(k=>(k.NOTICE="NOTICE",k.WARN="WARN",k.HEAVY="HEAVY",k.SEVERE="SEVERE",k.ERROR="ERROR",k.FATAL="FATAL",k))(J||{});class Q{parsePrinciple(s,t={}){var e,c,r;R==null||R.info("[%s] parse rule: %s",t.requestId,s);const n=new RegExp("(?<=\\[)(.+)(?=])","g"),o=s.match(n)?(e=s.match(n))==null?void 0:e[0]:void 0,i=o==null?void 0:o.split(";");if(!i)return;const a={};for(let d=0;d<(i==null?void 0:i.length);d++){const f=(r=(c=i[d].match(n))==null?void 0:c[0])==null?void 0:r.split("],");if(d===0&&!f)a.scope=i[0];else if(f)for(let M=0,m=f.length;M<m;M++){const u=this.parseRule(f[M]);u&&(a[u.level]?u.key?a[u.level][u==null?void 0:u.key]=u:a[u.level]=u:u.key?a[u.level]={[u==null?void 0:u.key]:u}:a[u.level]=u)}}return a}parseRule(s,t={}){var a;R==null||R.info("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const n=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(a=s==null?void 0:s.match(n))==null?void 0:a[0],i=o==null?void 0:o.split(",");if(i)return{operator:i[0],number:Number.isNaN(Number(i[1]))?i[1]:Number(i[1]),level:i[2],time:Number(i[3]),key:i[4]}}checkWeather(s,t,n={}){var u,I,Y,b,p,l,j,H,y,g,F,E,W,q,_;let o=0,i=0,a=0,e=0;const c=Math.round(((I=(u=t==null?void 0:t.SEVERE)==null?void 0:u.sigWave)==null?void 0:I.number)*1.6*100)/100,r=(b=(Y=t==null?void 0:t.SEVERE)==null?void 0:Y.sigWave)==null?void 0:b.number,d=(l=(p=t==null?void 0:t.HEAVY)==null?void 0:p.sigWave)==null?void 0:l.number,f=Math.round((((H=(j=t==null?void 0:t.SEVERE)==null?void 0:j.wind)==null?void 0:H.number)+2)*100)/100,M=(g=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:g.number,m=(E=(F=t==null?void 0:t.HEAVY)==null?void 0:F.wind)==null?void 0:E.number;for(let V=0;V<(s==null?void 0:s.length);V++){const T=s[V],C=(q=(W=T==null?void 0:T.meteo)==null?void 0:W.wave)==null?void 0:q.sig,N=(_=T==null?void 0:T.meteo)==null?void 0:_.wind,L=V?v(T.eta).diff(v(s[V-1].eta),"hour",!0):0;e=L>e?L:e,R==null||R.info("[%s] check sig.wave: %j",n.requestId,{...C,dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:d}),(C==null?void 0:C.height)>=c?T.isDangerous=!0:(C==null?void 0:C.height)>=r?T.isSevere=!0:(C==null?void 0:C.height)>=d&&(T.isHeavy=!0),R==null||R.info("[%s] check wind: %j",n.requestId,{...N,dgThd4Wd:f,svThd4Wd:M,hvThd4Wd:m}),(N==null?void 0:N.scale)>=f?(T.isDangerous=!0,delete T.isSevere,delete T.isHeavy):(N==null?void 0:N.scale)>M?(T.isDangerous||(T.isSevere=!0),delete T.isHeavy):(N==null?void 0:N.scale)===m&&!T.isDangerous&&!T.isSevere&&(T.isHeavy=!0),o+=T.isDangerous?L:0,i+=T.isSevere?L:0,a+=T.isHeavy?L:0}return o=Math.round(o*100)/100,i=Math.round(i*100)/100,a=Math.round(a*100)/100,e=Math.round(e),{sample:s,dangerous:o,severe:i,heavy:a,step:e<3?3:e,wind:{dgThd4Wd:f,svThd4Wd:M,hvThd4Wd:m},sig:{dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:d}}}}const ht=new Q;let S;try{S=Z.getLogger("vessel")}catch{}finally{}const lt=new G.MeteoHelper2("",!0);var X=(k=>(k.common="common",k.container="container",k.tugs="tugs",k))(X||{}),$=(k=>(k.Ballast="Ballast",k.Laden="Laden",k))($||{}),tt=(k=>(k.Cp="CP",k.Perf="Basis",k.Instruct="Other",k))(tt||{});class A{static blockCoefficient(s,t,n,o){let i=Math.round(s/(t*n*o)*100)/100;i=i<.55?.55:i>.85?.85:i;const a=[.55,.6,.65,.7,.75,.8,.85],e=a.map(c=>Math.abs(c-i));return a[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,n=9.8){let o=Math.round(Math.sqrt(s*s/(n*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(s,t,n){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return n==="Laden"&&(a=o[s]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(s,t=0){let n;return s>30&&s<=60?n=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?n=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?n=(.4-.03*Math.pow(t-8,2))/2:n=1,Math.round(n*1e5)/1e5}static vesselTagFactor(s,t,n,o=0){o=o>6?o-.9*(o-6):o;let i;return n==="container"?i=.7*o+Math.pow(o,6.5)/(22*Math.pow(s,2/3)):t==="Ballast"?i=.7*o+Math.pow(o,6.5)/(2.7*Math.pow(s,2/3)):i=.5*o+Math.pow(o,6.5)/(2.7*Math.pow(s,2/3)),i}static waveHeightFactor(s,t){s=s<0?.2:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let n;return t>30&&t<=60?n=-.6:t>60&&t<=90?n=-.4:t>90&&t<=120?n=s<3?.4:-.3:t>120&&t<=150?n=s<3?.6:-.5:t>150&&t<=180?n=s<3?.7:-.6:n=-.7,Math.round(n*(.144*Math.pow(s,2)+.178*s)*1e4)/1e4}static assembleProperties(s,t,n,o){var M;const i=s.lbp??s.length??s.lengthOverall??198.9642,a=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,c=s.deadweight??67035.7773,r=((M=s==null?void 0:s.type)==null?void 0:M.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:i,loadCondition:t,draught:a,breadthMoulded:e,displacement:Math.round((c/1.025+a*e*i*.7)*1e4)/1e4,speed:Math.round((n??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(s,t,n,o="",i=2,a=!0,e=!1,c={}){let r;if(t.velocity&&e&&(s.speed=O.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){let d;if(c.meteo2)try{const u=await lt.spotForecast(t.lat,t.lng,n.utc().format(),!1,!1,!0,c),[I]=U.Meteo2Assist.pickHourly(u,n);d=U.Meteo2Assist.toLegacy(I)}catch(u){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",c.requestId,{...t,eta:n.utc().format()},u)}else d=await G.MeteoHelper.queryPointFactor(t.lng,t.lat,n.valueOf(),"wind,wave,current,watertemp",o,c);const f=A.weatherFactor(s,d),M=A.currentFactor(s.bearing,d==null?void 0:d.current,i),m=Math.round((s.speed*1.943844+f+M)*100)/100;r={meteo:{...d},wxFactor:f,cFactor:M,speed:t.velocity&&e?t.velocity:m<0?1:m,eta:n.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:n.utc().format("YYYY-MM-DDTHH:mm[Z]")}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round((s.speed*1.943844+0+0)*100)/100,eta:n.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:n.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(s,t,n,o,i,a,e="",c=!0,r=!1,d={}){t.utc();const f=[],M=[];let m=0,u=0,I,Y;for(let b=0;b<a.length-1;b++){let p=a[b];p.distanceFromStart=i+u;const l=a[b+1];if(s.bearing=O.LaneHelper.calculateBearing(p,l,!l.gcToPrevious),p.bearing=s.bearing,p.suspend&&r){p.eta=p.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),p.elapsed=p.elapsed??0;const y=p.suspend-p.elapsed;if(o-m>y)o=o-m-y,t.add(y,"hour"),p.elapsed=p.suspend;else{const g=o-m;p.elapsed+=g,t.add(g,"hour"),o=0}if(S==null||S.info(`[%s] suspend ${p.elapsed} hours at %j, and remain ${o} hours need to go...`,d.requestId,p),o===0)return p.distanceFromPrevious=u,{etd:t,from:Y||p,to:p,next:a.filter(g=>g),wps:f,days:M}}else p.suspend=0;p=await A.speedLoseAt(s,p,t,e,0,c,r,d),Y=Y||p,p.important&&f.push(p),t.isSameOrAfter(n)&&(M.push(p),n.add(24,"hour"));const j=O.LaneHelper.calculateDistance(p,l,!l.gcToPrevious);let H=Math.ceil(j/Y.speed*1e4)/1e4;if(m+H<o){if(m+=H,t.add(H,"hour"),delete a[b],S==null||S.info(`[%s] go to %j from %j with ${j}nm, and cost ${H} hours`,d.requestId,{lat:l.lat,lng:l.lng},{lat:Y.lat,lng:Y.lng,etd:Y.etd}),u+=j,a.filter(y=>y).length<=1){I=l,I.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),I.distanceFromPrevious=j,I.distanceFromStart=i+u,f.push(I),delete a[b+1];break}}else{H=o-m,t.add(H,"hour");const y=O.LngLatHelper.roundPrecision(Y.speed*H,4);I=O.LaneHelper.calculateCoordinate(p,s.bearing,y,"nauticalmiles",!l.gcToPrevious),I.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),a[b]=I,S==null||S.info(`[%s] go to %j from %j with ${y}nm, and cost ${H} hours`,d.requestId,{lat:I.lat,lng:I.lng},{lat:p.lat,lng:p.lng,etd:p.etd}),u+=y,I.distanceFromPrevious=u,I.distanceFromStart=i+u;break}}return{etd:t,from:Y,to:I,next:a.filter(b=>b),wps:f,days:M}}static currentFactor(s,t,n=0){const o=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let i=((t==null?void 0:t.kts)||0)*Math.cos(o);return n&2?i=Math.ceil(i*100)/100:n&1?i=Math.floor(i*100)/100:i=Math.round(i*100)/100,Math.abs(i)>5?0:i}static weatherFactor(s,t){var f,M,m,u,I,Y,b;S==null||S.debug("calculate weather factor via: %j",{...s,...t});const n=A.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),o=A.froudeNumber(s.speed,s.lbp),i=A.amendFactor(n,o,s.loadCondition);let a=Math.abs(s.bearing%360-(((f=t==null?void 0:t.wind)==null?void 0:f.degree)%360||0));a=a>180?360-a:a;const e=A.directionFactor(a,(M=t==null?void 0:t.wind)==null?void 0:M.scale),c=A.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(m=t==null?void 0:t.wind)==null?void 0:m.scale);let r=e*i*c/100*s.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),S==null||S.debug("wind wx factor = %d",r),a=Math.abs(s.bearing%360-(((I=(u=t==null?void 0:t.wave)==null?void 0:u.sig)==null?void 0:I.degree)%360||0));const d=A.waveHeightFactor(((b=(Y=t==null?void 0:t.wave)==null?void 0:Y.sig)==null?void 0:b.height)??1,a);return S==null||S.debug("wave wx factor = %d",d),r=r*.4+d,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(s,t,n,o,i,a="",e=0,c=!0,r=!1,d={}){var L,et,st,at,nt;const f=v().valueOf();s.lng=O.LngLatHelper.convertToStdLng(s.lng);const{route:M,waypoints:m}=i.points,u=O.LaneHelper.calculateSubRoute(s,M);if(((L=u[0])==null?void 0:L.length)<=1)return;const{v0:I,label:Y}=s.sog?{v0:s.sog,label:"Other"}:{v0:o.speed,label:"CP"},b=A.assembleProperties(n,o.loadCondition,I,0),p=m.length?O.LaneHelper.calculateSubWaypoints(s,m):[];p.forEach(x=>x.important=!0);const l={from:{...s},route:u,waypoints:p,v0:I,label:Y},j={hours:[],days:[],wps:[]};e||(O.LaneHelper.calculateRouteDistance(u)/o.speed<=72?e=3:e=6);let H=O.LaneHelper.simplifyRouteToCoordinates(u,p,0),y=0,g=0,F=0,E=0;t=v(t).utc();const W=t.clone();for(;H.length>0;){const x=e-t.hour()%e,B=Math.ceil(t.clone().add(x,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,P=await A.speedLoseInHoursStep(b,t,W,B,y,H,a,c,r,d);(et=P.from)!=null&&et.speed&&(j.hours.push(P.from),j.wps.push(...P.wps),j.days.push(...P.days)),H=P==null?void 0:P.next,H.length||j.hours.push(P==null?void 0:P.to),y+=((st=P==null?void 0:P.to)==null?void 0:st.distanceFromPrevious)??0}const q=j.hours;for(let x=0;x<q.length-1;x++){const B=v(q[x+1].eta).diff(q[x].etd,"hour",!0)||1;g+=(q[x].wxFactor||0)*B,F+=(q[x].cFactor||0)*B,E+=B}(at=j.wps)==null||at.forEach((x,B)=>{if(B){const P=j.wps[B-1],ft=x.distanceFromStart-P.distanceFromStart,ot=v(x.eta).diff(v(P.etd),"h",!0);if(ot<1)x.avgSpd=P.speed;else{x.avgSpd=Math.round(ft/ot*100)/100;const it=Math.round((P.speed+x.speed)/2*100)/100;x.avgSpd=x.avgSpd>it?it:x.avgSpd}}}),l.sample=j;const _=j.hours.at(0),V=j.hours.at(-1);l.distance=Math.round(V.distanceFromStart*1e4)/1e4,l.etd=v(_.eta).utc().format(),l.eta=v(V.eta).utc().format(),l.wxFactor=Math.round(g/E*1e4)/1e4,l.cFactor=Math.round(F/E*1e4)/1e4,l.avgSpeed=Math.round(V.distanceFromStart/E*1e4)/1e4,l.totalHrs=Math.round(E*1e4)/1e4,l.totalFoCons=Math.round((o==null?void 0:o.fo)/24*l.totalHrs*1e3)/1e3,l.totalDgoCons=Math.round((o==null?void 0:o.dgo)/24*l.totalHrs*1e3)/1e3;const C=v().valueOf()-f,N=((nt=j==null?void 0:j.hours)==null?void 0:nt.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",d==null?void 0:d.requestId,C,N,Math.round(C/N*1e3)/1e3),l}static async analyseInstantWithThreshed(s,t,n,o,i,a,e,c="",r=3,d=!0,f=!1,M={}){var V,T,C;s.lng=O.LngLatHelper.convertToStdLng(s.lng);const{v0:m,label:u}=s.sog?{v0:s.sog,label:"Other"}:{v0:i.speed,label:"CP"},I=A.assembleProperties(o,i.loadCondition,m,0),Y=O.LaneHelper.calculateSubRoute(s,a);if(((V=Y[0])==null?void 0:V.length)<=1)return;const b=e.length?O.LaneHelper.calculateSubWaypoints(s,e):[];b.forEach(N=>N.important=!0);let p=O.LaneHelper.simplifyRouteToCoordinates(Y,b,0),l=0,j=0,H=0,y=0,g;const F={hours:[],wps:[],days:[]};for(t=v(t).utc();p.length>0;){const N=r-t.hour()%r;let L=Math.ceil(t.clone().add(N,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(L=t.clone().add(L,"h").isAfter(n)?n.diff(t,"h",!0)*1e4/1e4:L,L)g=await A.speedLoseInHoursStep(I,t,n.clone(),L,l,p,c,d,f,M),(T=g.from)!=null&&T.speed&&(F.hours.push(g.from),g!=null&&g.wps&&F.wps.push(...g.wps),F.days.push(...g.days)),p=g==null?void 0:g.next,p.length||(F.hours.push(g==null?void 0:g.to),g!=null&&g.wps&&F.wps.push(...g.wps),F.days.push(g==null?void 0:g.to)),l+=((C=g==null?void 0:g.to)==null?void 0:C.distanceFromPrevious)??0;else{g&&(F.hours.push(g.to),g!=null&&g.wps&&F.wps.push(...g.wps),F.days.push(g.to));break}}const E=F.hours;for(let N=0;N<E.length-1;N++){const L=v(E[N+1].eta).diff(E[N].etd,"hour",!0);j+=E[N].wxFactor*L,H+=E[N].cFactor*L,y+=L}const W=F.hours.at(0),q=F.hours.at(-1);return{sample:F,distance:Math.round(((q==null?void 0:q.distanceFromStart)||0)*1e4)/1e4,etd:v(W.eta).utc().format(),eta:v(q==null?void 0:q.eta).utc().format(),wxFactor:Math.round(j/y*1e4)/1e4,cFactor:Math.round(H/y*1e4)/1e4,avgSpeed:Math.round(((q==null?void 0:q.distanceFromStart)||0)/y*1e4)/1e4,totalHrs:Math.round(y*1e4)/1e4,from:s,to:q,route:Y,waypoints:b,v0:m,label:u}}}w.AISImpl=z,w.AlertHelper=Q,w.AlertLevel=J,w.HifleetImpl=ct,w.LoadCondition=$,w.MyShipImpl=ut,w.MyVesselImpl=rt,w.ShipxyImpl=dt,w.SpeedHelper=A,w.SpeedLabel=tt,w.VesselTag=X,w.alertHelper=ht,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idm-plugin/vessel",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.3",
|
|
5
5
|
"description": "idm plugin for vessel",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"keywords": [
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@idm-plugin/geo": "^1.5.7",
|
|
31
|
-
"@idm-plugin/meteo": "^0.2.
|
|
32
|
-
"@idm-plugin/meteo2": "^0.1.
|
|
31
|
+
"@idm-plugin/meteo": "^0.2.6",
|
|
32
|
+
"@idm-plugin/meteo2": "^0.1.2",
|
|
33
33
|
"@log4js-node/log4js-api": "^1.0.2",
|
|
34
34
|
"got": "11",
|
|
35
35
|
"moment": "^2.30.1"
|