@idm-plugin/vessel 3.8.3 → 3.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +324 -323
- package/dist/index.umd.cjs +1 -1
- package/package.json +9 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var ht = Object.defineProperty;
|
|
2
|
-
var mt = (x,
|
|
3
|
-
var K = (x,
|
|
2
|
+
var mt = (x, t, e) => t in x ? ht(x, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : x[t] = e;
|
|
3
|
+
var K = (x, t, e) => (mt(x, typeof t != "symbol" ? t + "" : t, e), e);
|
|
4
4
|
import z from "got";
|
|
5
5
|
import ut from "@log4js-node/log4js-api";
|
|
6
6
|
import p from "moment";
|
|
@@ -18,51 +18,51 @@ class nt {
|
|
|
18
18
|
* 解析AIS状态码
|
|
19
19
|
* @param status
|
|
20
20
|
*/
|
|
21
|
-
parseStatus(
|
|
22
|
-
let
|
|
23
|
-
switch (
|
|
21
|
+
parseStatus(t) {
|
|
22
|
+
let e, n;
|
|
23
|
+
switch (t) {
|
|
24
24
|
case 0:
|
|
25
|
-
|
|
25
|
+
e = "在航(主机推动)", n = "Underway Using Engine";
|
|
26
26
|
break;
|
|
27
27
|
case 1:
|
|
28
|
-
|
|
28
|
+
e = "锚泊", n = "Anchored";
|
|
29
29
|
break;
|
|
30
30
|
case 2:
|
|
31
|
-
|
|
31
|
+
e = "失控", n = "Not under command";
|
|
32
32
|
break;
|
|
33
33
|
case 3:
|
|
34
|
-
|
|
34
|
+
e = "操纵受限", n = "Limited airworthiness";
|
|
35
35
|
break;
|
|
36
36
|
case 4:
|
|
37
|
-
|
|
37
|
+
e = "吃水受限", n = "Limited by ship's draft";
|
|
38
38
|
break;
|
|
39
39
|
case 5:
|
|
40
|
-
|
|
40
|
+
e = "靠泊", n = "Mooring";
|
|
41
41
|
break;
|
|
42
42
|
case 6:
|
|
43
|
-
|
|
43
|
+
e = "搁浅", n = "Stranded";
|
|
44
44
|
break;
|
|
45
45
|
case 7:
|
|
46
|
-
|
|
46
|
+
e = "捕捞作业", n = "Engaged in fishing";
|
|
47
47
|
break;
|
|
48
48
|
case 8:
|
|
49
|
-
|
|
49
|
+
e = "靠帆船提供动力", n = "Sailing";
|
|
50
50
|
break;
|
|
51
51
|
default:
|
|
52
|
-
|
|
52
|
+
e = "未定义", n = "Undefined";
|
|
53
53
|
}
|
|
54
|
-
return { labelCn:
|
|
54
|
+
return { labelCn: e, labelEn: n };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
class Tt extends nt {
|
|
58
|
-
constructor(
|
|
58
|
+
constructor(e, n) {
|
|
59
59
|
super();
|
|
60
60
|
K(this, "clientId");
|
|
61
61
|
K(this, "clientSecret");
|
|
62
62
|
K(this, "token");
|
|
63
|
-
this.clientId =
|
|
63
|
+
this.clientId = e, this.clientSecret = n;
|
|
64
64
|
}
|
|
65
|
-
async authToken(
|
|
65
|
+
async authToken(e = {}) {
|
|
66
66
|
const n = "https://svc.data.myvessel.cn/ada/oauth/token", o = {
|
|
67
67
|
searchParams: {
|
|
68
68
|
client_id: this.clientId,
|
|
@@ -70,7 +70,7 @@ class Tt extends nt {
|
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
72
|
}, i = await z.post(n, o).json();
|
|
73
|
-
g == null || g.info("[%s] fetch access token from: %s - %j",
|
|
73
|
+
g == null || g.info("[%s] fetch access token from: %s - %j", e.requestId, n, i), i.error || (this.token = {
|
|
74
74
|
accessToken: i.access_token,
|
|
75
75
|
tokenType: i.token_type,
|
|
76
76
|
expiresIn: i.expires_in,
|
|
@@ -79,16 +79,16 @@ class Tt extends nt {
|
|
|
79
79
|
issuedAt: p().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
|
-
async checkToken(
|
|
82
|
+
async checkToken(e = {}) {
|
|
83
83
|
var n;
|
|
84
|
-
return (!this.token || p().diff(p(this.token.issuedAt), "seconds") > (((n = this.token) == null ? void 0 : n.expiresIn) || 0) - 300) && await this.authToken(
|
|
84
|
+
return (!this.token || p().diff(p(this.token.issuedAt), "seconds") > (((n = this.token) == null ? void 0 : n.expiresIn) || 0) - 300) && await this.authToken(e), this.token;
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* 模糊查询
|
|
88
88
|
* @param kw
|
|
89
89
|
* @param options
|
|
90
90
|
*/
|
|
91
|
-
async suggest(
|
|
91
|
+
async suggest(e, n = {}) {
|
|
92
92
|
var s, r;
|
|
93
93
|
await this.checkToken(n);
|
|
94
94
|
const o = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy", i = {
|
|
@@ -96,7 +96,7 @@ class Tt extends nt {
|
|
|
96
96
|
Authorization: `${(s = this.token) == null ? void 0 : s.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
97
97
|
},
|
|
98
98
|
json: {
|
|
99
|
-
kw:
|
|
99
|
+
kw: e,
|
|
100
100
|
recordNum: n.ps || 10
|
|
101
101
|
}
|
|
102
102
|
};
|
|
@@ -119,10 +119,10 @@ class Tt extends nt {
|
|
|
119
119
|
* @param imo
|
|
120
120
|
* @param options
|
|
121
121
|
*/
|
|
122
|
-
async search(
|
|
122
|
+
async search(e, n = {}) {
|
|
123
123
|
var u, l;
|
|
124
124
|
await this.checkToken(n);
|
|
125
|
-
const o = /^\d{7}$/.test(
|
|
125
|
+
const o = /^\d{7}$/.test(e.toString()), i = o ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", a = o ? { imo: e } : { mmsi: e }, s = {
|
|
126
126
|
headers: {
|
|
127
127
|
Authorization: `${(u = this.token) == null ? void 0 : u.tokenType} ${(l = this.token) == null ? void 0 : l.accessToken}`
|
|
128
128
|
},
|
|
@@ -161,7 +161,7 @@ class Tt extends nt {
|
|
|
161
161
|
}
|
|
162
162
|
return {};
|
|
163
163
|
}
|
|
164
|
-
async archives(
|
|
164
|
+
async archives(e, n = {}) {
|
|
165
165
|
var s, r;
|
|
166
166
|
await this.checkToken(n);
|
|
167
167
|
const o = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch", i = {
|
|
@@ -169,21 +169,21 @@ class Tt extends nt {
|
|
|
169
169
|
Authorization: `${(s = this.token) == null ? void 0 : s.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
170
170
|
},
|
|
171
171
|
json: {
|
|
172
|
-
mmsiList: typeof
|
|
172
|
+
mmsiList: typeof e == "number" ? [e] : e
|
|
173
173
|
}
|
|
174
174
|
};
|
|
175
175
|
g == null || g.info("[%s] fetch vessel archive from: %s - %j", n.requestId, o, i);
|
|
176
176
|
const a = await z.post(o, i).json();
|
|
177
177
|
return a.status !== 200 ? (g == null || g.warn("[%s] fetch vessel archive failed: %j", n.requestId, { message: a.message, status: a.status, code: a.code }), {}) : a.data;
|
|
178
178
|
}
|
|
179
|
-
async realTimePosition(
|
|
179
|
+
async realTimePosition(e, n = {}) {
|
|
180
180
|
var r, u;
|
|
181
181
|
await this.checkToken(n);
|
|
182
182
|
const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", i = {
|
|
183
183
|
headers: {
|
|
184
184
|
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(u = this.token) == null ? void 0 : u.accessToken}`
|
|
185
185
|
},
|
|
186
|
-
searchParams: { mmsi:
|
|
186
|
+
searchParams: { mmsi: e }
|
|
187
187
|
};
|
|
188
188
|
g == null || g.info("[%s] fetch realtime position from: %s - %j", n.requestId, o, i);
|
|
189
189
|
const a = await z.get(o, i).json();
|
|
@@ -236,7 +236,7 @@ class Tt extends nt {
|
|
|
236
236
|
* @param excludeSeas 排除水域, [sea.code]
|
|
237
237
|
* @param options { requiretId: '请求ID', useAIModel: '启用AI算法', withECA: '是否计算低硫区航行距离', withSpecial: '是否计算穿越的特战区列表和海盗区列表', draught: '最大吃水' }
|
|
238
238
|
*/
|
|
239
|
-
async calculateRoute(
|
|
239
|
+
async calculateRoute(e, n, o, i, a, s = {}) {
|
|
240
240
|
var I, b, E;
|
|
241
241
|
const r = p();
|
|
242
242
|
await this.checkToken(s);
|
|
@@ -246,9 +246,9 @@ class Tt extends nt {
|
|
|
246
246
|
withECA: s.withECA || !1,
|
|
247
247
|
withSpecialRegion: s.withSpecial || !1
|
|
248
248
|
};
|
|
249
|
-
|
|
250
|
-
lon:
|
|
251
|
-
lat:
|
|
249
|
+
e.code && (l.startPortCode = e.code), e.lng !== void 0 && e.lat !== void 0 && (l.startPoint = {
|
|
250
|
+
lon: e.lng,
|
|
251
|
+
lat: e.lat
|
|
252
252
|
}), n.code && (l.endPortCode = n.code), n.lng !== void 0 && n.lat !== void 0 && (l.endPoint = {
|
|
253
253
|
lon: n.lng,
|
|
254
254
|
lat: n.lat
|
|
@@ -260,9 +260,9 @@ class Tt extends nt {
|
|
|
260
260
|
json: l
|
|
261
261
|
};
|
|
262
262
|
g == null || g.info("[%s] fetch route from: %s - %j", s.requestId, u, h);
|
|
263
|
-
const
|
|
264
|
-
if (
|
|
265
|
-
return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message:
|
|
263
|
+
const d = await z.post(u, h).json();
|
|
264
|
+
if (d.status !== 200)
|
|
265
|
+
return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message: d.message, status: d.status, code: d.code }), {};
|
|
266
266
|
{
|
|
267
267
|
const k = {
|
|
268
268
|
status: "Success",
|
|
@@ -273,7 +273,7 @@ class Tt extends nt {
|
|
|
273
273
|
route: [],
|
|
274
274
|
distance: 0,
|
|
275
275
|
memo: ""
|
|
276
|
-
}, { nodes: w, seas: v, tracks: m, specialRegions:
|
|
276
|
+
}, { nodes: w, seas: v, tracks: m, specialRegions: c, ecaLength: f } = d.data;
|
|
277
277
|
k.nodes = w == null ? void 0 : w.map((M) => ({
|
|
278
278
|
code: M.nodeCode,
|
|
279
279
|
nameEn: M.nameEn,
|
|
@@ -314,7 +314,7 @@ class Tt extends nt {
|
|
|
314
314
|
lng: Math.round(M.maxLon * 1e6) / 1e6
|
|
315
315
|
},
|
|
316
316
|
level: M.mapLevel
|
|
317
|
-
})),
|
|
317
|
+
})), c == null || c.map((M) => {
|
|
318
318
|
M.regionLength && k.regions.push({
|
|
319
319
|
type: M.regionType,
|
|
320
320
|
distance: M.regionLength,
|
|
@@ -334,21 +334,21 @@ class Tt extends nt {
|
|
|
334
334
|
return k.memo = `time cost: ${S}s`, g.info("[%s] calculate route cost: %d seconds", s.requestId, S), k;
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
-
async trajectory(
|
|
337
|
+
async trajectory(e, n, o, i, a = !0, s = {}) {
|
|
338
338
|
await this.checkToken(s);
|
|
339
|
-
const r = await this.realTimePosition(
|
|
339
|
+
const r = await this.realTimePosition(e, s), u = p(n), l = p(o), h = [];
|
|
340
340
|
for (; l.diff(u, "day", !0) > 30; )
|
|
341
|
-
await this.trajectoryIn30Day(
|
|
342
|
-
return await this.trajectoryIn30Day(
|
|
341
|
+
await this.trajectoryIn30Day(e, u, u.clone().add(30, "day"), r, i, h, s), u.add(30, "day");
|
|
342
|
+
return await this.trajectoryIn30Day(e, u, l, r, i, h, s), h;
|
|
343
343
|
}
|
|
344
|
-
async trajectoryIn30Day(
|
|
344
|
+
async trajectoryIn30Day(e, n, o, i, a, s, r = {}) {
|
|
345
345
|
var b, E, k, w, v;
|
|
346
346
|
const u = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", l = {
|
|
347
347
|
headers: {
|
|
348
348
|
Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(E = this.token) == null ? void 0 : E.accessToken}`
|
|
349
349
|
},
|
|
350
350
|
json: {
|
|
351
|
-
mmsi:
|
|
351
|
+
mmsi: e,
|
|
352
352
|
startTime: n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
|
|
353
353
|
endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
354
354
|
}
|
|
@@ -357,12 +357,12 @@ class Tt extends nt {
|
|
|
357
357
|
const h = await z.post(u, l).json();
|
|
358
358
|
if (h.code)
|
|
359
359
|
return g == null || g.warn("[%s] fetch trajectory failed: %j", r.requestId, u, { message: h.message, status: h.status, code: h.code }), h;
|
|
360
|
-
let
|
|
360
|
+
let d = -1;
|
|
361
361
|
const I = p(`${(w = (k = h.data) == null ? void 0 : k[0]) == null ? void 0 : w.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
362
362
|
return (v = h.data) == null || v.forEach((m) => {
|
|
363
363
|
for (const N in m)
|
|
364
364
|
!isNaN(m[N]) && Number(m[N]) !== 1 / 0 && (m[N] = Number(m[N]));
|
|
365
|
-
const
|
|
365
|
+
const c = p(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), f = m.status, { labelCn: y, labelEn: S } = this.parseStatus(f), M = {
|
|
366
366
|
mmsi: m.mmsi,
|
|
367
367
|
imo: i == null ? void 0 : i.imo,
|
|
368
368
|
lat: m.lat,
|
|
@@ -374,27 +374,27 @@ class Tt extends nt {
|
|
|
374
374
|
status: f,
|
|
375
375
|
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta) ? p(`${m.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
|
|
376
376
|
destination: m.dest,
|
|
377
|
-
positionTime:
|
|
377
|
+
positionTime: c.unix(),
|
|
378
378
|
labelCn: y,
|
|
379
379
|
labelEn: S,
|
|
380
380
|
method: "trajectory",
|
|
381
381
|
vendor: "myVessel",
|
|
382
|
-
utc:
|
|
383
|
-
}, j = Math.floor(
|
|
384
|
-
j !==
|
|
382
|
+
utc: c.utc().format()
|
|
383
|
+
}, j = Math.floor(c.diff(I, "minute", !0) / (a || 1));
|
|
384
|
+
j !== d && (d = j, s.push(M));
|
|
385
385
|
}), s;
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
388
|
class jt extends nt {
|
|
389
|
-
constructor(
|
|
389
|
+
constructor(e) {
|
|
390
390
|
super();
|
|
391
391
|
K(this, "token");
|
|
392
|
-
this.token =
|
|
392
|
+
this.token = e;
|
|
393
393
|
}
|
|
394
|
-
async realTimePosition(
|
|
394
|
+
async realTimePosition(e, n = {}) {
|
|
395
395
|
const o = "https://api.hifleet.com/position/position/get/token", i = {
|
|
396
396
|
searchParams: {
|
|
397
|
-
mmsi:
|
|
397
|
+
mmsi: e,
|
|
398
398
|
usertoken: this.token
|
|
399
399
|
}
|
|
400
400
|
}, a = await z.post(o, i).json();
|
|
@@ -435,11 +435,11 @@ class jt extends nt {
|
|
|
435
435
|
vendor: "hifleet"
|
|
436
436
|
};
|
|
437
437
|
}
|
|
438
|
-
async search(
|
|
438
|
+
async search(e, n = {}) {
|
|
439
439
|
let o = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
440
440
|
const i = {
|
|
441
441
|
searchParams: {
|
|
442
|
-
keyword:
|
|
442
|
+
keyword: e
|
|
443
443
|
},
|
|
444
444
|
headers: {
|
|
445
445
|
Referer: "https://www.hifleet.com",
|
|
@@ -463,10 +463,10 @@ class jt extends nt {
|
|
|
463
463
|
};
|
|
464
464
|
return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await z.post(o, i).json(), g == null || g.info("[%s] search vessel dead weight from: %s - %j", n.requestId, o, i), a instanceof Array && (a = a[0]), a && (s.deadweight = Number(a.dwt)), s;
|
|
465
465
|
}
|
|
466
|
-
async suggest(
|
|
466
|
+
async suggest(e, n = {}) {
|
|
467
467
|
const o = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", i = {
|
|
468
468
|
searchParams: {
|
|
469
|
-
q:
|
|
469
|
+
q: e
|
|
470
470
|
},
|
|
471
471
|
headers: {
|
|
472
472
|
Referer: "https://www.hifleet.com",
|
|
@@ -486,32 +486,32 @@ class jt extends nt {
|
|
|
486
486
|
});
|
|
487
487
|
return s.sort((r, u) => u.score - r.score), s;
|
|
488
488
|
}
|
|
489
|
-
async trajectory(
|
|
490
|
-
var m,
|
|
491
|
-
const r = await this.realTimePosition(
|
|
489
|
+
async trajectory(e, n, o, i, a = !0, s = {}) {
|
|
490
|
+
var m, c, f;
|
|
491
|
+
const r = await this.realTimePosition(e, s);
|
|
492
492
|
let u = p(n);
|
|
493
493
|
const l = p(o), h = p();
|
|
494
494
|
if (a) {
|
|
495
495
|
let y = l.diff(u, "d", !0);
|
|
496
496
|
y < 0 ? u = l.clone().subtract(40, "d") : y < 30 ? u.subtract(10, "d") : y < 60 ? u.subtract(5, "d") : u = l.clone().subtract(80, "d"), y = h.diff(l, "d", !0), l.add(y > 10 ? 240 : y * 24, "h");
|
|
497
497
|
}
|
|
498
|
-
const
|
|
498
|
+
const d = {
|
|
499
499
|
searchParams: {
|
|
500
500
|
endtime: l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
501
501
|
starttime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
502
|
-
mmsi:
|
|
502
|
+
mmsi: e,
|
|
503
503
|
usertoken: this.token
|
|
504
504
|
}
|
|
505
|
-
}, I = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await z.get(I,
|
|
506
|
-
g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, I,
|
|
505
|
+
}, I = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await z.get(I, d).json();
|
|
506
|
+
g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, I, d);
|
|
507
507
|
let E;
|
|
508
|
-
b && (E = ((
|
|
508
|
+
b && (E = ((c = (m = b.ships) == null ? void 0 : m.offors) == null ? void 0 : c.ship) || [], E.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
|
|
509
509
|
const k = [];
|
|
510
510
|
let w = -1;
|
|
511
511
|
const v = p(`${(f = E == null ? void 0 : E[0]) == null ? void 0 : f.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
512
512
|
for (const y of E) {
|
|
513
|
-
for (const
|
|
514
|
-
!isNaN(y[
|
|
513
|
+
for (const O in y)
|
|
514
|
+
!isNaN(y[O]) && Number(y[O]) !== 1 / 0 && (y[O] = Number(y[O]));
|
|
515
515
|
const S = p(`${y.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
516
516
|
y.status = y.sp > 4 ? 0 : 1;
|
|
517
517
|
const { labelEn: M, labelCn: j } = this.parseStatus(y.status), N = {
|
|
@@ -538,15 +538,15 @@ class jt extends nt {
|
|
|
538
538
|
}
|
|
539
539
|
}
|
|
540
540
|
class xt extends nt {
|
|
541
|
-
constructor(
|
|
541
|
+
constructor(e) {
|
|
542
542
|
super();
|
|
543
543
|
K(this, "token");
|
|
544
|
-
this.token =
|
|
544
|
+
this.token = e;
|
|
545
545
|
}
|
|
546
|
-
async realTimePosition(
|
|
546
|
+
async realTimePosition(e, n = {}) {
|
|
547
547
|
const o = {
|
|
548
548
|
searchParams: {
|
|
549
|
-
id:
|
|
549
|
+
id: e,
|
|
550
550
|
k: this.token,
|
|
551
551
|
enc: 1
|
|
552
552
|
}
|
|
@@ -554,8 +554,8 @@ class xt extends nt {
|
|
|
554
554
|
if (g == null || g.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, o), (a == null ? void 0 : a.status) !== 0)
|
|
555
555
|
return a;
|
|
556
556
|
const s = a.data[0];
|
|
557
|
-
for (const
|
|
558
|
-
!isNaN(s[
|
|
557
|
+
for (const d in s)
|
|
558
|
+
!isNaN(s[d]) && Number(s[d]) !== 1 / 0 && (s[d] = Number(s[d]));
|
|
559
559
|
const { labelCn: r, labelEn: u } = await this.parseStatus(s.navistat), l = p.unix(s.lasttime);
|
|
560
560
|
return {
|
|
561
561
|
mmsi: s.ShipID,
|
|
@@ -580,71 +580,71 @@ class xt extends nt {
|
|
|
580
580
|
vendor: "shipxy"
|
|
581
581
|
};
|
|
582
582
|
}
|
|
583
|
-
async trajectory(
|
|
583
|
+
async trajectory(e, n, o, i, a = !0, s = {}) {
|
|
584
584
|
var v;
|
|
585
|
-
const r = await this.realTimePosition(
|
|
585
|
+
const r = await this.realTimePosition(e, s), u = p(n), l = p(o), h = "https://api.shipxy.com/apicall/GetShipTrack", d = {
|
|
586
586
|
searchParams: {
|
|
587
|
-
id:
|
|
587
|
+
id: e,
|
|
588
588
|
k: this.token,
|
|
589
589
|
enc: 1,
|
|
590
590
|
cut: 0,
|
|
591
591
|
btm: u.unix(),
|
|
592
592
|
etm: l.unix()
|
|
593
593
|
}
|
|
594
|
-
}, I = await z.get(h,
|
|
595
|
-
if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, h,
|
|
594
|
+
}, I = await z.get(h, d).json();
|
|
595
|
+
if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, h, d), (I == null ? void 0 : I.status) !== 0)
|
|
596
596
|
return I;
|
|
597
597
|
const b = I == null ? void 0 : I.points, E = [], k = p.unix((v = b[0]) == null ? void 0 : v.utc);
|
|
598
598
|
let w = -1;
|
|
599
599
|
for (const m of b) {
|
|
600
|
-
const
|
|
600
|
+
const c = p.unix(m.utc), f = {
|
|
601
601
|
imo: r == null ? void 0 : r.imo,
|
|
602
|
-
mmsi:
|
|
602
|
+
mmsi: e,
|
|
603
603
|
sog: Math.round(m.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
604
604
|
cog: Math.round(m.cog / 100 * 100) / 100,
|
|
605
605
|
lat: Math.round(m.lat / 1e6 * 1e5) / 1e5,
|
|
606
606
|
lng: Math.round(m.lon / 1e6 * 1e5) / 1e5,
|
|
607
|
-
positionTime:
|
|
608
|
-
utc:
|
|
607
|
+
positionTime: c.unix(),
|
|
608
|
+
utc: c.utc().format(),
|
|
609
609
|
method: "trajectory",
|
|
610
610
|
vendor: "shipxy"
|
|
611
|
-
}, y = Math.floor(
|
|
611
|
+
}, y = Math.floor(c.diff(k, "minute", !0) / (i || 1));
|
|
612
612
|
y !== w && (w = y, E.push(f));
|
|
613
613
|
}
|
|
614
614
|
return E;
|
|
615
615
|
}
|
|
616
616
|
}
|
|
617
617
|
class Nt extends nt {
|
|
618
|
-
constructor(
|
|
618
|
+
constructor(e) {
|
|
619
619
|
super();
|
|
620
620
|
K(this, "token");
|
|
621
|
-
this.token =
|
|
621
|
+
this.token = e;
|
|
622
622
|
}
|
|
623
|
-
async getShipId(
|
|
623
|
+
async getShipId(e, n = {}) {
|
|
624
624
|
const o = {
|
|
625
625
|
headers: {
|
|
626
626
|
appKey: this.token
|
|
627
627
|
},
|
|
628
628
|
json: {
|
|
629
|
-
mmsiList:
|
|
629
|
+
mmsiList: e
|
|
630
630
|
}
|
|
631
631
|
}, i = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await z.post(i, o).json();
|
|
632
632
|
return g == null || g.info("[%s] fetch ship id from: %s - %j", n.requestId, i, o), a.code !== "0" ? a : a.data[0].shipId;
|
|
633
633
|
}
|
|
634
|
-
async getShipInfo(
|
|
634
|
+
async getShipInfo(e, n = {}) {
|
|
635
635
|
const o = {
|
|
636
636
|
headers: {
|
|
637
637
|
appKey: this.token
|
|
638
638
|
},
|
|
639
639
|
json: {
|
|
640
|
-
shipId:
|
|
640
|
+
shipId: e
|
|
641
641
|
}
|
|
642
642
|
}, i = "https://api3.myships.com/sp/ships/aissta", a = await z.post(i, o).json();
|
|
643
643
|
if (g == null || g.info("[%s] fetch ship info from: %s - %j", n.requestId, i, o), a.code !== "0")
|
|
644
644
|
return a;
|
|
645
645
|
const s = a.data;
|
|
646
646
|
let r = s.imo;
|
|
647
|
-
return
|
|
647
|
+
return e === "407170" && (r = "9198379", g == null || g.warn("[%s] ship(%s) imo error: %s, should be %s", n.requestId, e, s.imo, r)), {
|
|
648
648
|
mmsi: s.mmsi,
|
|
649
649
|
name: s.shipnameEn,
|
|
650
650
|
imo: r,
|
|
@@ -654,8 +654,8 @@ class Nt extends nt {
|
|
|
654
654
|
draught: (s.draught || 100) / 10
|
|
655
655
|
};
|
|
656
656
|
}
|
|
657
|
-
async realTimePosition(
|
|
658
|
-
const o = await this.getShipId(
|
|
657
|
+
async realTimePosition(e, n = {}) {
|
|
658
|
+
const o = await this.getShipId(e, n), i = await this.getShipInfo(o, n), a = {
|
|
659
659
|
headers: {
|
|
660
660
|
appKey: this.token
|
|
661
661
|
},
|
|
@@ -667,10 +667,10 @@ class Nt extends nt {
|
|
|
667
667
|
const u = r.data[0];
|
|
668
668
|
for (const b in u)
|
|
669
669
|
!isNaN(u[b]) && Number(u[b]) !== 1 / 0 && (u[b] = Number(u[b]));
|
|
670
|
-
const { labelCn: l, labelEn: h } = await this.parseStatus(u.aisNavStatus),
|
|
670
|
+
const { labelCn: l, labelEn: h } = await this.parseStatus(u.aisNavStatus), d = p.unix(u.posTime);
|
|
671
671
|
return {
|
|
672
672
|
...i,
|
|
673
|
-
mmsi:
|
|
673
|
+
mmsi: e,
|
|
674
674
|
lat: Math.round(u.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
675
675
|
lng: Math.round(u.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
676
676
|
sog: Math.round(u.sog / 10 * 100) / 100,
|
|
@@ -678,7 +678,7 @@ class Nt extends nt {
|
|
|
678
678
|
hdg: Math.round(u.heading * 100) / 100,
|
|
679
679
|
rot: Math.round(u.rot * 100) / 100,
|
|
680
680
|
positionTime: u.posTime,
|
|
681
|
-
utc:
|
|
681
|
+
utc: d.utc().format(),
|
|
682
682
|
status: u.aisNavStatus,
|
|
683
683
|
labelEn: h,
|
|
684
684
|
labelCn: l,
|
|
@@ -686,27 +686,27 @@ class Nt extends nt {
|
|
|
686
686
|
vendor: "myship"
|
|
687
687
|
};
|
|
688
688
|
}
|
|
689
|
-
async trajectory(
|
|
690
|
-
const r = p(n), u = p(o), l = await this.getShipId(
|
|
689
|
+
async trajectory(e, n, o, i, a = !0, s = {}) {
|
|
690
|
+
const r = p(n), u = p(o), l = await this.getShipId(e), h = await this.getShipInfo(l), d = [];
|
|
691
691
|
for (; u.diff(r, "day", !0) > 30; )
|
|
692
|
-
await this.trajectoryIn30Day(l, r.unix(), r.add(30, "day").unix(), h,
|
|
693
|
-
return await this.trajectoryIn30Day(l, r.unix(), u.unix(), h,
|
|
692
|
+
await this.trajectoryIn30Day(l, r.unix(), r.add(30, "day").unix(), h, e, i, d);
|
|
693
|
+
return await this.trajectoryIn30Day(l, r.unix(), u.unix(), h, e, i, d), d;
|
|
694
694
|
}
|
|
695
|
-
async trajectoryIn30Day(
|
|
695
|
+
async trajectoryIn30Day(e, n, o, i, a, s, r, u = {}) {
|
|
696
696
|
var k;
|
|
697
697
|
const l = {
|
|
698
698
|
headers: {
|
|
699
699
|
appKey: this.token
|
|
700
700
|
},
|
|
701
701
|
json: {
|
|
702
|
-
shipId:
|
|
702
|
+
shipId: e,
|
|
703
703
|
startTime: n,
|
|
704
704
|
endTime: o
|
|
705
705
|
}
|
|
706
|
-
}, h = "https://api3.myships.com/sp/ships/position/history",
|
|
707
|
-
if (g == null || g.info("[%s] fetch trajectory from: %s - %j", u.requestId, h, l),
|
|
708
|
-
return g == null || g.warn("[%s] invoke myship trajectory failed: %j", u.requestId,
|
|
709
|
-
const I =
|
|
706
|
+
}, h = "https://api3.myships.com/sp/ships/position/history", d = await z.post(h, l).json();
|
|
707
|
+
if (g == null || g.info("[%s] fetch trajectory from: %s - %j", u.requestId, h, l), d.code !== "0")
|
|
708
|
+
return g == null || g.warn("[%s] invoke myship trajectory failed: %j", u.requestId, d), d;
|
|
709
|
+
const I = d.data;
|
|
710
710
|
for (const w in I)
|
|
711
711
|
!isNaN(I[w]) && Number(I[w]) !== 1 / 0 && (I[w] = Number(I[w]));
|
|
712
712
|
const b = p.unix((k = I[0]) == null ? void 0 : k.posTime);
|
|
@@ -725,8 +725,8 @@ class Nt extends nt {
|
|
|
725
725
|
utc: v.utc().format(),
|
|
726
726
|
method: "trajectory",
|
|
727
727
|
vendor: "myship"
|
|
728
|
-
},
|
|
729
|
-
|
|
728
|
+
}, c = Math.floor(v.diff(b, "minute", !0) / (s || 1));
|
|
729
|
+
c !== E && (E = c, r.push(m));
|
|
730
730
|
}
|
|
731
731
|
return r;
|
|
732
732
|
}
|
|
@@ -747,10 +747,10 @@ class Mt {
|
|
|
747
747
|
*
|
|
748
748
|
* @param options
|
|
749
749
|
*/
|
|
750
|
-
parsePrinciple(
|
|
750
|
+
parsePrinciple(t, e = {}) {
|
|
751
751
|
var s, r, u;
|
|
752
|
-
_ == null || _.debug("[%s] parse rule: %s",
|
|
753
|
-
const n = new RegExp("(?<=\\[)(.+)(?=])", "g"), o =
|
|
752
|
+
_ == null || _.debug("[%s] parse rule: %s", e.requestId, t);
|
|
753
|
+
const n = new RegExp("(?<=\\[)(.+)(?=])", "g"), o = t.match(n) ? (s = t.match(n)) == null ? void 0 : s[0] : void 0, i = o == null ? void 0 : o.split(";");
|
|
754
754
|
if (!i)
|
|
755
755
|
return;
|
|
756
756
|
const a = {};
|
|
@@ -759,8 +759,8 @@ class Mt {
|
|
|
759
759
|
if (l === 0 && !h)
|
|
760
760
|
a.scope = i[0];
|
|
761
761
|
else if (h)
|
|
762
|
-
for (let
|
|
763
|
-
const b = this.parseRule(h[
|
|
762
|
+
for (let d = 0, I = h.length; d < I; d++) {
|
|
763
|
+
const b = this.parseRule(h[d]);
|
|
764
764
|
b && (a[b.level] ? b.key ? a[b.level][b == null ? void 0 : b.key] = b : a[b.level] = b : b.key ? a[b.level] = { [b == null ? void 0 : b.key]: b } : a[b.level] = b);
|
|
765
765
|
}
|
|
766
766
|
}
|
|
@@ -772,10 +772,10 @@ class Mt {
|
|
|
772
772
|
* @param rule
|
|
773
773
|
* @param options
|
|
774
774
|
*/
|
|
775
|
-
parseRule(
|
|
775
|
+
parseRule(t, e = {}) {
|
|
776
776
|
var a;
|
|
777
|
-
_ == null || _.debug("[%s] parse rule: %s",
|
|
778
|
-
const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"), o = (a =
|
|
777
|
+
_ == null || _.debug("[%s] parse rule: %s", e.requestId, t), t = t.startsWith("[") ? t : `[${t}`, t = t.endsWith("]") ? t : `${t}]`;
|
|
778
|
+
const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"), o = (a = t == null ? void 0 : t.match(n)) == null ? void 0 : a[0], i = o == null ? void 0 : o.split(",");
|
|
779
779
|
if (i) {
|
|
780
780
|
let s = i[3] === "Number.MAX_VALUE" ? 100 : Number(i[3]);
|
|
781
781
|
return s = isNaN(s) ? 1 : s, {
|
|
@@ -793,15 +793,15 @@ class Mt {
|
|
|
793
793
|
* @param principle 告警规则
|
|
794
794
|
* @param options
|
|
795
795
|
*/
|
|
796
|
-
checkWeather(
|
|
797
|
-
var b, E, k, w, v, m,
|
|
796
|
+
checkWeather(t, e, n = {}) {
|
|
797
|
+
var b, E, k, w, v, m, c, f, y, S, M, j, N, D, O;
|
|
798
798
|
let o = 0, i = 0, a = 0, s = 0;
|
|
799
|
-
const r = Math.round(((E = (b =
|
|
800
|
-
for (let W = 0; W < (
|
|
801
|
-
const F =
|
|
802
|
-
s = V > s ? V : s, _ == null || _.debug("[%s] check sig.wave: %j", n.requestId, { ...Y, dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l }), (Y == null ? void 0 : Y.height) >= r ? F.isDangerous = !0 : (Y == null ? void 0 : Y.height) >= u ? F.isSevere = !0 : (Y == null ? void 0 : Y.height) >= l && (F.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", n.requestId, { ...A, dgThd4Wd: h, svThd4Wd:
|
|
799
|
+
const r = Math.round(((E = (b = e == null ? void 0 : e.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : E.number) * 1.6 * 100) / 100, u = (w = (k = e == null ? void 0 : e.SEVERE) == null ? void 0 : k.sigWave) == null ? void 0 : w.number, l = (m = (v = e == null ? void 0 : e.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : m.number, h = Math.round((((f = (c = e == null ? void 0 : e.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : f.number) + 2) * 100) / 100, d = (S = (y = e == null ? void 0 : e.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : S.number, I = (j = (M = e == null ? void 0 : e.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
|
|
800
|
+
for (let W = 0; W < (t == null ? void 0 : t.length); W++) {
|
|
801
|
+
const F = t[W], Y = (D = (N = F == null ? void 0 : F.meteo) == null ? void 0 : N.wave) == null ? void 0 : D.sig, A = (O = F == null ? void 0 : F.meteo) == null ? void 0 : O.wind, V = W ? p(F.eta).diff(p(t[W - 1].eta), "hour", !0) : 0;
|
|
802
|
+
s = V > s ? V : s, _ == null || _.debug("[%s] check sig.wave: %j", n.requestId, { ...Y, dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l }), (Y == null ? void 0 : Y.height) >= r ? F.isDangerous = !0 : (Y == null ? void 0 : Y.height) >= u ? F.isSevere = !0 : (Y == null ? void 0 : Y.height) >= l && (F.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", n.requestId, { ...A, dgThd4Wd: h, svThd4Wd: d, hvThd4Wd: I }), (A == null ? void 0 : A.scale) >= h ? (F.isDangerous = !0, delete F.isSevere, delete F.isHeavy) : (A == null ? void 0 : A.scale) > d ? (F.isDangerous || (F.isSevere = !0), delete F.isHeavy) : (A == null ? void 0 : A.scale) === I && !F.isDangerous && !F.isSevere && (F.isHeavy = !0), o += F.isDangerous ? V : 0, i += F.isSevere ? V : 0, a += F.isHeavy ? V : 0;
|
|
803
803
|
}
|
|
804
|
-
return o = Math.round(o * 100) / 100, i = Math.round(i * 100) / 100, a = Math.round(a * 100) / 100, s = Math.round(s), { sample:
|
|
804
|
+
return o = Math.round(o * 100) / 100, i = Math.round(i * 100) / 100, a = Math.round(a * 100) / 100, s = Math.round(s), { sample: t, dangerous: o, severe: i, heavy: a, step: s < 3 ? 3 : s, wind: { dgThd4Wd: h, svThd4Wd: d, hvThd4Wd: I }, sig: { dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l } };
|
|
805
805
|
}
|
|
806
806
|
}
|
|
807
807
|
const Dt = new Mt();
|
|
@@ -813,7 +813,7 @@ try {
|
|
|
813
813
|
}
|
|
814
814
|
const gt = new ft("", !0);
|
|
815
815
|
var bt = /* @__PURE__ */ ((x) => (x.common = "common", x.container = "container", x.tugs = "tugs", x))(bt || {}), vt = /* @__PURE__ */ ((x) => (x.Ballast = "Ballast", x.Laden = "Laden", x))(vt || {}), wt = /* @__PURE__ */ ((x) => (x.Cp = "CP", x.Perf = "Basis", x.Instruct = "Other", x))(wt || {});
|
|
816
|
-
class
|
|
816
|
+
class L {
|
|
817
817
|
/**
|
|
818
818
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
819
819
|
* 方形系数(block coefficient)
|
|
@@ -826,8 +826,8 @@ class H {
|
|
|
826
826
|
* @param draught 吃水 m
|
|
827
827
|
* @return [0.55, 0.85]
|
|
828
828
|
*/
|
|
829
|
-
static blockCoefficient(
|
|
830
|
-
let i = Math.round(
|
|
829
|
+
static blockCoefficient(t, e, n, o) {
|
|
830
|
+
let i = Math.round(t / (e * n * o) * 100) / 100;
|
|
831
831
|
i = i < 0.55 ? 0.55 : i > 0.85 ? 0.85 : i;
|
|
832
832
|
const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = a.map((r) => Math.abs(r - i));
|
|
833
833
|
return a[s.indexOf(Math.min(...s))];
|
|
@@ -843,8 +843,9 @@ class H {
|
|
|
843
843
|
* @param g 重力加速度 9.80 m/s^2
|
|
844
844
|
* @return [0.05, 0.30]
|
|
845
845
|
*/
|
|
846
|
-
static froudeNumber(
|
|
847
|
-
|
|
846
|
+
static froudeNumber(t, e, n = 9.8) {
|
|
847
|
+
t = t || 10 * 1852 / 3600;
|
|
848
|
+
let o = Math.round(Math.sqrt(t * t / (n * e)) * 100) / 100;
|
|
848
849
|
return o = o < 0.05 ? 0.05 : o > 0.3 ? 0.3 : o, o;
|
|
849
850
|
}
|
|
850
851
|
/**
|
|
@@ -854,7 +855,7 @@ class H {
|
|
|
854
855
|
* @param loadCondition
|
|
855
856
|
* @private
|
|
856
857
|
*/
|
|
857
|
-
static amendFactor(
|
|
858
|
+
static amendFactor(t, e, n) {
|
|
858
859
|
const o = {
|
|
859
860
|
0.55: [1.7, -1.4, -7.4],
|
|
860
861
|
0.6: [2.2, -2.5, -9.7],
|
|
@@ -872,8 +873,8 @@ class H {
|
|
|
872
873
|
0.75: [2.6, -12.5, -13.5],
|
|
873
874
|
0.8: [3, -16.3, -21.6],
|
|
874
875
|
0.85: [3.4, -20.9, 31.8]
|
|
875
|
-
}[
|
|
876
|
-
return n === "Laden" && (a = o[
|
|
876
|
+
}[t];
|
|
877
|
+
return n === "Laden" && (a = o[t]), a[0] + a[1] * e + a[2] * Math.pow(e, 2);
|
|
877
878
|
}
|
|
878
879
|
/**
|
|
879
880
|
* 失速方向因子
|
|
@@ -886,9 +887,9 @@ class H {
|
|
|
886
887
|
* @param bn
|
|
887
888
|
* @private
|
|
888
889
|
*/
|
|
889
|
-
static directionFactor(
|
|
890
|
+
static directionFactor(t, e = 0) {
|
|
890
891
|
let n;
|
|
891
|
-
return
|
|
892
|
+
return t > 30 && t <= 60 ? n = (1.7 - 0.03 * Math.pow(e - 4, 2)) / 2 : t > 60 && t <= 150 ? n = (0.9 - 0.06 * Math.pow(e - 6, 2)) / 2 : t > 150 && t <= 180 ? n = (0.4 - 0.03 * Math.pow(e - 8, 2)) / 2 : n = 1, Math.round(n * 1e5) / 1e5;
|
|
892
893
|
}
|
|
893
894
|
/**
|
|
894
895
|
* 失速船型因子
|
|
@@ -902,9 +903,9 @@ class H {
|
|
|
902
903
|
* @param kts
|
|
903
904
|
* @private
|
|
904
905
|
*/
|
|
905
|
-
static vesselTagFactor(
|
|
906
|
+
static vesselTagFactor(t, e, n, o) {
|
|
906
907
|
let i;
|
|
907
|
-
return n === "container" ? i = 0.7 * o / 2 + Math.pow(o, 3) / (22 * Math.pow(
|
|
908
|
+
return n === "container" ? i = 0.7 * o / 2 + Math.pow(o, 3) / (22 * Math.pow(t, 2 / 3)) : e === "Ballast" ? i = 0.7 * o / 2 + Math.pow(o, 3) / (2.7 * Math.pow(t, 2 / 3)) : i = 0.5 * o / 2 + Math.pow(o, 3) / (2.7 * Math.pow(t, 2 / 3)), i;
|
|
908
909
|
}
|
|
909
910
|
/**
|
|
910
911
|
* 浪高影响因子
|
|
@@ -914,11 +915,11 @@ class H {
|
|
|
914
915
|
* @param options
|
|
915
916
|
* @private
|
|
916
917
|
*/
|
|
917
|
-
static waveHeightFactor(
|
|
918
|
-
|
|
918
|
+
static waveHeightFactor(t, e, n = 10, o = {}) {
|
|
919
|
+
t = t < 3 ? t * 0.7 : t, t = t < 0 ? 0.2 : t, t = t > 6 ? t - 0.9 * (t - 6) : t, t = t > 9 ? 9 : t;
|
|
919
920
|
const i = Math.max(n > 10 ? n - 10 : 2.8);
|
|
920
921
|
let a;
|
|
921
|
-
return
|
|
922
|
+
return e > 30 && e <= 60 ? a = -0.6 : e > 60 && e <= 90 ? a = -0.5 : e > 90 && e <= 120 ? a = t < i ? 0.2 : -0.3 : e > 120 && e <= 150 ? a = t < i ? 0.25 : -0.2 : e > 150 && e <= 180 ? a = t < i ? 0.3 : -0.1 : a = -0.7, C == null || C.info("[%s] calculate wave height factor with ht(%d), beta(%d), draught(%d) and factor(%d)", o.requestId, t, e, n, a), Math.round(a * (0.144 * Math.pow(t, 2) + 0.378 * t) * 1e4) / 1e4;
|
|
922
923
|
}
|
|
923
924
|
/**
|
|
924
925
|
* 组装船舶运行参数
|
|
@@ -928,13 +929,13 @@ class H {
|
|
|
928
929
|
* @param bearing 方位角
|
|
929
930
|
* @private
|
|
930
931
|
*/
|
|
931
|
-
static assembleProperties(
|
|
932
|
-
var
|
|
933
|
-
const i =
|
|
932
|
+
static assembleProperties(t, e, n, o) {
|
|
933
|
+
var d;
|
|
934
|
+
const i = t.lbp ?? t.length ?? t.lengthOverall ?? 198.9642, a = t.draught ?? 8, s = t.breadthMoulded ?? t.breadth ?? t.breadthExtreme ?? 32.4572, r = t.deadweight ?? 67035.7773, u = ((d = t == null ? void 0 : t.type) == null ? void 0 : d.toLowerCase()) || "common";
|
|
934
935
|
return {
|
|
935
936
|
tag: u.indexOf("container") > -1 ? "container" : u.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
936
937
|
lbp: i,
|
|
937
|
-
loadCondition:
|
|
938
|
+
loadCondition: e,
|
|
938
939
|
draught: a,
|
|
939
940
|
breadthMoulded: s,
|
|
940
941
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
@@ -956,42 +957,42 @@ class H {
|
|
|
956
957
|
* @param useRouteParam true 启用设置速度
|
|
957
958
|
* @param options
|
|
958
959
|
*/
|
|
959
|
-
static async speedLoseAt(
|
|
960
|
+
static async speedLoseAt(t, e, n, o = "", i = 2, a = !0, s = !1, r = {}) {
|
|
960
961
|
let u;
|
|
961
|
-
if (
|
|
962
|
+
if (e.velocity && s && (t.speed = J.roundPrecision(e.velocity * 1852 / 3600, 6)), a) {
|
|
962
963
|
let l;
|
|
963
964
|
try {
|
|
964
965
|
o = (o == null ? void 0 : o.toUpperCase()) === "CMEMS" ? "ECMWF" : o, o = (o == null ? void 0 : o.toUpperCase()) === "METEO2" ? "best_match" : o;
|
|
965
|
-
const { weatherModels: k, marineModels: w } = await dt.autoPickMeteoModel(o), v = n.utc().format(), m = await gt.spotForecast(
|
|
966
|
+
const { weatherModels: k, marineModels: w } = await dt.autoPickMeteoModel(o), v = n.utc().format(), m = await gt.spotForecast(e.lat, e.lng, v, !1, !1, !0, {
|
|
966
967
|
...r,
|
|
967
968
|
pastDays: 1,
|
|
968
969
|
forecastDays: 2,
|
|
969
970
|
weatherModels: k,
|
|
970
971
|
marineModels: w
|
|
971
|
-
}), [
|
|
972
|
-
l = dt.toLegacy(
|
|
972
|
+
}), [c] = dt.pickHourly(m, v);
|
|
973
|
+
l = dt.toLegacy(c);
|
|
973
974
|
} catch (k) {
|
|
974
|
-
C.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...
|
|
975
|
+
C.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...e, eta: n.utc().format(), source: o }, k);
|
|
975
976
|
}
|
|
976
|
-
let h =
|
|
977
|
-
const I =
|
|
978
|
-
I + h +
|
|
977
|
+
let h = L.currentFactor(t.bearing, l == null ? void 0 : l.current, i, r), d = L.weatherFactor(t, l, h, r);
|
|
978
|
+
const I = t.speed * 1.943844;
|
|
979
|
+
I + h + d <= 0 && (C.warn(
|
|
979
980
|
"[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",
|
|
980
981
|
r.requestId,
|
|
981
982
|
I,
|
|
982
|
-
|
|
983
|
-
|
|
983
|
+
d + h,
|
|
984
|
+
d,
|
|
984
985
|
h
|
|
985
|
-
), h = Math.round(h * 0.6 * 1e3) / 1e3,
|
|
986
|
-
const b =
|
|
987
|
-
C == null || C.info("[%s] calculate speed lose with v0Factor(%d), cFactor(%d) and wxFactor(%d)", r.requestId, b, h,
|
|
988
|
-
let E = Math.round((I + h +
|
|
986
|
+
), h = Math.round(h * 0.6 * 1e3) / 1e3, d = Math.round(d * 0.6 * 1e3) / 1e3);
|
|
987
|
+
const b = d <= (r.minV0Factor || -1) ? Math.max(r.maxV0Factor || -1.5, -1 * d * (d / 1.2)) : 0;
|
|
988
|
+
C == null || C.info("[%s] calculate speed lose with v0Factor(%d), cFactor(%d) and wxFactor(%d)", r.requestId, b, h, d), d += b;
|
|
989
|
+
let E = Math.round((I + h + d) * 100) / 100;
|
|
989
990
|
E = E <= 0 ? 1 : E, u = {
|
|
990
991
|
meteo: { ...l },
|
|
991
|
-
wxFactor:
|
|
992
|
+
wxFactor: d,
|
|
992
993
|
v0Factor: b,
|
|
993
994
|
cFactor: h,
|
|
994
|
-
speed:
|
|
995
|
+
speed: e.velocity && s ? e.velocity : E,
|
|
995
996
|
eta: n.utc().format(),
|
|
996
997
|
etd: n.utc().format()
|
|
997
998
|
};
|
|
@@ -1000,11 +1001,11 @@ class H {
|
|
|
1000
1001
|
wxFactor: 0,
|
|
1001
1002
|
v0Factor: 0,
|
|
1002
1003
|
cFactor: 0,
|
|
1003
|
-
speed:
|
|
1004
|
+
speed: e.velocity && s ? e.velocity : Math.round(t.speed * 1.943844 * 100) / 100,
|
|
1004
1005
|
eta: n.utc().format(),
|
|
1005
1006
|
etd: n.utc().format()
|
|
1006
1007
|
};
|
|
1007
|
-
return delete
|
|
1008
|
+
return delete e.meteo, delete e.wxFactor, delete e.cFactor, delete e.speed, delete e.etd, { ...u, ...e };
|
|
1008
1009
|
}
|
|
1009
1010
|
/**
|
|
1010
1011
|
* 基于步长计算失速样本
|
|
@@ -1020,53 +1021,53 @@ class H {
|
|
|
1020
1021
|
* @param options
|
|
1021
1022
|
* @private
|
|
1022
1023
|
*/
|
|
1023
|
-
static async speedLoseInHoursStep(
|
|
1024
|
-
|
|
1025
|
-
const h =
|
|
1024
|
+
static async speedLoseInHoursStep(t, e, n, o, i, a, s = "", r = !0, u = !1, l = {}) {
|
|
1025
|
+
e.utc();
|
|
1026
|
+
const h = e.clone().add(14, "days"), d = [], I = [], b = [];
|
|
1026
1027
|
let E = 0, k = 0, w, v;
|
|
1027
1028
|
for (let m = 0; m < a.length - 1; m++) {
|
|
1028
|
-
let
|
|
1029
|
-
|
|
1029
|
+
let c = a[m];
|
|
1030
|
+
c.distanceFromStart = Math.round((i + k) * 1e3) / 1e3;
|
|
1030
1031
|
const f = a[m + 1];
|
|
1031
|
-
if (
|
|
1032
|
-
|
|
1033
|
-
const M =
|
|
1032
|
+
if (t.bearing = R.calculateBearing(c, f, !f.gcToPrevious), c.bearing = t.bearing, c.suspend && u) {
|
|
1033
|
+
c.eta = c.eta || e.utc().format(), c.elapsed = c.elapsed ?? 0;
|
|
1034
|
+
const M = c.suspend - c.elapsed;
|
|
1034
1035
|
if (o - E > M)
|
|
1035
|
-
o = o - E - M,
|
|
1036
|
+
o = o - E - M, e.add(M, "hour"), c.elapsed = c.suspend;
|
|
1036
1037
|
else {
|
|
1037
1038
|
const j = o - E;
|
|
1038
|
-
|
|
1039
|
+
c.elapsed += j, e.add(j, "hour"), o = 0;
|
|
1039
1040
|
}
|
|
1040
|
-
if (C == null || C.info(`[%s] suspend ${
|
|
1041
|
-
return
|
|
1041
|
+
if (C == null || C.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`, l.requestId, c), o === 0)
|
|
1042
|
+
return c.distanceFromPrevious = k, { etd: e, from: v || c, to: c, next: a.filter((j) => j), wps: d, days: I, all: b };
|
|
1042
1043
|
} else
|
|
1043
|
-
|
|
1044
|
-
r =
|
|
1045
|
-
const y = R.calculateDistance(
|
|
1044
|
+
c.suspend = 0;
|
|
1045
|
+
r = e.isAfter(h) ? !1 : r, c = await L.speedLoseAt(t, c, e, s, 0, r, u, l), b.push(c), v = v || c, c.important && d.push(c), e.isSameOrAfter(n) && (I.push(c), n.add(24, "hour"));
|
|
1046
|
+
const y = R.calculateDistance(c, f, !f.gcToPrevious);
|
|
1046
1047
|
let S = Math.round(y / v.speed * 1e5) / 1e5;
|
|
1047
1048
|
if (E + S < o) {
|
|
1048
|
-
if (E += S,
|
|
1049
|
+
if (E += S, e.add(S, "hour"), delete a[m], C == null || C.debug(
|
|
1049
1050
|
`[%s] go to %j from %j with ${y}nm, and cost ${S} hours`,
|
|
1050
1051
|
l.requestId,
|
|
1051
1052
|
{ lat: f.lat, lng: f.lng },
|
|
1052
1053
|
{ lat: v.lat, lng: v.lng, etd: v.etd }
|
|
1053
1054
|
), k += y, a.filter((M) => M).length <= 1) {
|
|
1054
|
-
w = f, w.eta =
|
|
1055
|
+
w = f, w.eta = e.utc().format(), w.distanceFromPrevious = y, w.distanceFromStart = Math.round((i + k) * 1e4) / 1e4, d.push(w), b.push(w), delete a[m + 1];
|
|
1055
1056
|
break;
|
|
1056
1057
|
}
|
|
1057
1058
|
} else {
|
|
1058
|
-
S = o - E,
|
|
1059
|
+
S = o - E, e.add(S, "hour");
|
|
1059
1060
|
const M = J.roundPrecision(v.speed * S, 5);
|
|
1060
|
-
w = R.calculateCoordinate(
|
|
1061
|
+
w = R.calculateCoordinate(c, t.bearing, M, "nauticalmiles", !f.gcToPrevious), w.eta = e.utc().format(), a[m] = w, C == null || C.debug(
|
|
1061
1062
|
`[%s] go to %j from %j with ${M}nm, and cost ${S} hours`,
|
|
1062
1063
|
l.requestId,
|
|
1063
1064
|
{ lat: w.lat, lng: w.lng },
|
|
1064
|
-
{ lat:
|
|
1065
|
+
{ lat: c.lat, lng: c.lng, etd: c.etd }
|
|
1065
1066
|
), k += M, w.distanceFromPrevious = Math.round(k * 1e4) / 1e4, w.distanceFromStart = Math.round((i + k) * 1e4) / 1e4;
|
|
1066
1067
|
break;
|
|
1067
1068
|
}
|
|
1068
1069
|
}
|
|
1069
|
-
return { etd:
|
|
1070
|
+
return { etd: e, from: v, to: w, next: a.filter((m) => m), wps: d, days: I, all: b };
|
|
1070
1071
|
}
|
|
1071
1072
|
/**
|
|
1072
1073
|
* 洋流影响因子
|
|
@@ -1075,10 +1076,10 @@ class H {
|
|
|
1075
1076
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
1076
1077
|
* @param options
|
|
1077
1078
|
*/
|
|
1078
|
-
static currentFactor(
|
|
1079
|
-
const i = R.includedAngle(
|
|
1079
|
+
static currentFactor(t, e, n = 0, o = {}) {
|
|
1080
|
+
const i = R.includedAngle(t ?? 0, (e == null ? void 0 : e.degree) ?? 0) / 180 * Math.PI;
|
|
1080
1081
|
let a;
|
|
1081
|
-
return Math.abs(i) === Math.PI / 2 && (a = 0), a = ((
|
|
1082
|
+
return Math.abs(i) === Math.PI / 2 && (a = 0), a = ((e == null ? void 0 : e.kts) || 0) * Math.cos(i), n & 2 ? a = Math.ceil(a * 100) / 100 : n & 1 ? a = Math.floor(a * 100) / 100 : a = Math.round(a * 100) / 100, C == null || C.info("[%s] calculate current factor with %j", o.requestId, { beta: i, current: e, factor: a, role: n }), Math.abs(a) > 5 ? 0 : a;
|
|
1082
1083
|
}
|
|
1083
1084
|
/**
|
|
1084
1085
|
* 风浪影响因子
|
|
@@ -1087,32 +1088,32 @@ class H {
|
|
|
1087
1088
|
* @param cFactor 洋流因子
|
|
1088
1089
|
* @param options
|
|
1089
1090
|
*/
|
|
1090
|
-
static weatherFactor(
|
|
1091
|
-
var b, E, k, w, v, m,
|
|
1092
|
-
C == null || C.info("[%s] calculate weather factor via: %j", o.requestId, { ...
|
|
1093
|
-
const i =
|
|
1094
|
-
let u = R.includedAngle(
|
|
1095
|
-
const l =
|
|
1096
|
-
let
|
|
1097
|
-
|
|
1098
|
-
const I =
|
|
1099
|
-
return C == null || C.info("[%s] calculate wave wx factor: %d", o.requestId, I),
|
|
1091
|
+
static weatherFactor(t, e, n = 0, o = {}) {
|
|
1092
|
+
var b, E, k, w, v, m, c;
|
|
1093
|
+
C == null || C.info("[%s] calculate weather factor via: %j", o.requestId, { ...t, ...e }), t.displacement = t.displacement || t.lbp * t.breadthMoulded * t.draught * 0.7 * 1.025, t.speed = t.speed || 10 * 1852 / 3600, t.bearing = t.bearing ?? 0;
|
|
1094
|
+
const i = L.blockCoefficient(t.displacement, t.lbp, t.breadthMoulded, t.draught), a = J.roundPrecision(n * 1852 / 3600, 6), s = L.froudeNumber(t.speed - a, t.lbp), r = L.amendFactor(i, s, t.loadCondition);
|
|
1095
|
+
let u = R.includedAngle(t.bearing ?? 0, (b = e == null ? void 0 : e.wind) == null ? void 0 : b.degree);
|
|
1096
|
+
const l = L.directionFactor(u, (E = e == null ? void 0 : e.wind) == null ? void 0 : E.scale), h = L.vesselTagFactor(t.displacement, t.loadCondition, t.tag, ((k = e == null ? void 0 : e.wind) == null ? void 0 : k.kts) || 10);
|
|
1097
|
+
let d = l * r * h / 100 * (t.speed - a);
|
|
1098
|
+
d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, t.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), C == null || C.info("[%s] calculate wind wx factor: %d", o.requestId, d), u = R.includedAngle(t.bearing, (v = (w = e == null ? void 0 : e.wave) == null ? void 0 : w.sig) == null ? void 0 : v.degree);
|
|
1099
|
+
const I = L.waveHeightFactor(((c = (m = e == null ? void 0 : e.wave) == null ? void 0 : m.sig) == null ? void 0 : c.height) ?? 1, u, t.draught, o);
|
|
1100
|
+
return C == null || C.info("[%s] calculate wave wx factor: %d", o.requestId, I), d = Math.abs(d) > Math.abs(I) ? d : 0.4 * d + 0.6 * I, C == null || C.info("[%s] calculate finial weather factor: %d = (0.4 * wf) + (0.6 * hf)", o.requestId, d), d = Math.abs(d) > 3 ? 3 * (Math.abs(d) / d) + Math.abs(d) / d * (Math.abs(d) - 2) * 0.1 : d, Math.round((d || 0) * 100) / 100;
|
|
1100
1101
|
}
|
|
1101
1102
|
/**
|
|
1102
1103
|
* 以12小时级别去掉重复的days
|
|
1103
1104
|
* @param days
|
|
1104
1105
|
* @param interval 12 hours
|
|
1105
1106
|
*/
|
|
1106
|
-
static async reduceDays(
|
|
1107
|
-
return
|
|
1107
|
+
static async reduceDays(t, e = 12 * 60 * 60) {
|
|
1108
|
+
return t = t == null ? void 0 : t.reduce((n, o) => (o.positionTime || (o.positionTime = p.utc(o.etd || o.eta).unix()), n.some((i) => Math.floor(i.positionTime / e) === Math.floor(o.positionTime / e)) || n.push(o), n), []), t;
|
|
1108
1109
|
}
|
|
1109
1110
|
/**
|
|
1110
1111
|
* 以分钟级别去掉重复的wps
|
|
1111
1112
|
* @param wps
|
|
1112
1113
|
* @param interval 1 minute
|
|
1113
1114
|
*/
|
|
1114
|
-
static async reduceWPS(
|
|
1115
|
-
return
|
|
1115
|
+
static async reduceWPS(t, e = 60) {
|
|
1116
|
+
return t = t == null ? void 0 : t.reduce((n, o) => (n.some((i) => Math.floor(p(i.etd).unix() / e) === Math.floor(p(o.etd).unix() / e)) || n.push(o), n), []), t;
|
|
1116
1117
|
}
|
|
1117
1118
|
/**
|
|
1118
1119
|
* 全程失速分析(走完航程)
|
|
@@ -1127,30 +1128,30 @@ class H {
|
|
|
1127
1128
|
* @param useRouteParam
|
|
1128
1129
|
* @param options
|
|
1129
1130
|
*/
|
|
1130
|
-
static async analyseInstant(
|
|
1131
|
+
static async analyseInstant(t, e, n, o, i, a = "", s = 0, r = !0, u = !1, l = {}) {
|
|
1131
1132
|
var U, G, X, Q, Z, $;
|
|
1132
1133
|
const h = p().valueOf();
|
|
1133
|
-
|
|
1134
|
-
const { route:
|
|
1134
|
+
t.lng = J.convertToStdLng(t.lng);
|
|
1135
|
+
const { route: d, waypoints: I } = i.points, b = R.calculateSubRoute(t, d);
|
|
1135
1136
|
if (((U = b[0]) == null ? void 0 : U.length) <= 1)
|
|
1136
1137
|
return;
|
|
1137
|
-
const { v0: E, label: k } =
|
|
1138
|
-
v0:
|
|
1139
|
-
label:
|
|
1138
|
+
const { v0: E, label: k } = t.sog ? {
|
|
1139
|
+
v0: t.sog,
|
|
1140
|
+
label: t.label || "Other"
|
|
1140
1141
|
/* Instruct */
|
|
1141
1142
|
} : {
|
|
1142
1143
|
v0: o.speed,
|
|
1143
1144
|
label: "CP"
|
|
1144
1145
|
/* Cp */
|
|
1145
|
-
}, w =
|
|
1146
|
+
}, w = L.assembleProperties(n, o.loadCondition, E, 0), v = I.length ? R.calculateSubWaypoints(t, I) : [];
|
|
1146
1147
|
v.forEach((q) => q.important = !0);
|
|
1147
1148
|
const m = {
|
|
1148
|
-
from: { ...
|
|
1149
|
+
from: { ...t },
|
|
1149
1150
|
route: b,
|
|
1150
1151
|
waypoints: v,
|
|
1151
1152
|
v0: E,
|
|
1152
1153
|
label: k
|
|
1153
|
-
},
|
|
1154
|
+
}, c = {
|
|
1154
1155
|
hours: [],
|
|
1155
1156
|
days: [],
|
|
1156
1157
|
wps: [],
|
|
@@ -1158,12 +1159,12 @@ class H {
|
|
|
1158
1159
|
};
|
|
1159
1160
|
s || (R.calculateRouteDistance(b) / o.speed <= 72 ? s = 3 : s = 6);
|
|
1160
1161
|
let f = R.simplifyRouteToCoordinates(b, v, 0), y = 0, S = 0, M = 0, j = 0;
|
|
1161
|
-
|
|
1162
|
-
const N =
|
|
1162
|
+
e = p(e).utc();
|
|
1163
|
+
const N = e.clone();
|
|
1163
1164
|
for (; f.length > 0; ) {
|
|
1164
|
-
const q = s -
|
|
1165
|
+
const q = s - e.hour() % s, B = Math.ceil(e.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4, T = await L.speedLoseInHoursStep(
|
|
1165
1166
|
w,
|
|
1166
|
-
|
|
1167
|
+
e,
|
|
1167
1168
|
N,
|
|
1168
1169
|
B,
|
|
1169
1170
|
y,
|
|
@@ -1173,31 +1174,31 @@ class H {
|
|
|
1173
1174
|
u,
|
|
1174
1175
|
l
|
|
1175
1176
|
);
|
|
1176
|
-
if (
|
|
1177
|
-
const
|
|
1178
|
-
|
|
1177
|
+
if (c.all.push(...T.all), (G = T.from) != null && G.speed && (c.hours.push(T.from), c.wps.push(...T.wps), c.days.push(...T.days)), f = T == null ? void 0 : T.next, !f.length) {
|
|
1178
|
+
const H = await L.speedLoseAt(w, T.to, p(T.to.eta), a, 0, r, u, l);
|
|
1179
|
+
H.bearing = w.bearing, c.hours[c.hours.length - 1] = H, c.all[c.all.length - 1] = H, c.wps[c.wps.length - 1] = H;
|
|
1179
1180
|
}
|
|
1180
1181
|
y += Math.round((((X = T == null ? void 0 : T.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
1181
1182
|
}
|
|
1182
|
-
const D =
|
|
1183
|
+
const D = c.hours;
|
|
1183
1184
|
for (let q = 0; q < D.length - 1; q++) {
|
|
1184
1185
|
const B = p(D[q + 1].eta).diff(D[q].etd, "hour", !0) || 1;
|
|
1185
1186
|
S += (D[q].wxFactor || 0) * B, M += (D[q].cFactor || 0) * B, j += B;
|
|
1186
1187
|
}
|
|
1187
|
-
const
|
|
1188
|
-
(Q =
|
|
1188
|
+
const O = D.reduce((q, B) => q + (B.suspend || 0), 0);
|
|
1189
|
+
(Q = c.wps) == null || Q.forEach((q, B) => {
|
|
1189
1190
|
q.positionTime = p.utc(q.etd || q.eta).unix();
|
|
1190
|
-
const T =
|
|
1191
|
+
const T = c.wps[B - 1];
|
|
1191
1192
|
if (T) {
|
|
1192
|
-
const
|
|
1193
|
-
q.avgSpd = Math.round(
|
|
1193
|
+
const H = q.distanceFromStart - T.distanceFromStart, P = p(q.eta || q.etd).diff(p(T.etd || T.eta), "h", !0);
|
|
1194
|
+
q.avgSpd = Math.round(H / P * 100) / 100;
|
|
1194
1195
|
const at = R.calculateBearing(T, q);
|
|
1195
1196
|
q.avgBearing = at, T.bearing = at;
|
|
1196
1197
|
}
|
|
1197
|
-
}),
|
|
1198
|
-
const W =
|
|
1199
|
-
m.distance = Math.round(F.distanceFromStart * 1e3) / 1e3, m.etd = p(W.eta).utc().format(), m.eta = p(F.eta).utc().format(), m.wxFactor = Math.round(S / j * 1e3) / 1e3, m.cFactor = Math.round(M / j * 1e3) / 1e3, m.avgSpeed = Math.round(F.distanceFromStart / j * 1e3) / 1e3, m.totalHrs = Math.round(j * 1e3) / 1e3, m.suspend = Math.round(
|
|
1200
|
-
const Y = J.roundPrecision(o.dgo / 24 *
|
|
1198
|
+
}), c.wps = await L.reduceWPS(c.wps), c.days = await L.reduceDays(c.days), c.all = (Z = c.all) == null ? void 0 : Z.reduce((q, B) => (B.positionTime = p.utc(B.etd || B.eta).unix(), q.some((T) => Math.round(T.positionTime / 60) === Math.round(B.positionTime / 60)) || q.push(B), q), []), m.sample = c;
|
|
1199
|
+
const W = c.hours.at(0), F = c.hours.at(-1);
|
|
1200
|
+
m.distance = Math.round(F.distanceFromStart * 1e3) / 1e3, m.etd = p(W.eta).utc().format(), m.eta = p(F.eta).utc().format(), m.wxFactor = Math.round(S / j * 1e3) / 1e3, m.cFactor = Math.round(M / j * 1e3) / 1e3, m.avgSpeed = Math.round(F.distanceFromStart / j * 1e3) / 1e3, m.totalHrs = Math.round(j * 1e3) / 1e3, m.suspend = Math.round(O * 1e3) / 1e3;
|
|
1201
|
+
const Y = J.roundPrecision(o.dgo / 24 * O, 3), { distanceInECA: A, hoursInECA: V, totalDgoConsInECA: ot, eca: tt } = await this.calculateECA(m, o, l), et = J.roundPrecision(o.fo / 24 * (j - V), 3), it = J.roundPrecision(o.dgo / 24 * j + Y, 3);
|
|
1201
1202
|
m.extend = {
|
|
1202
1203
|
eca: tt,
|
|
1203
1204
|
distanceInECA: A,
|
|
@@ -1205,7 +1206,7 @@ class H {
|
|
|
1205
1206
|
totalDgoConsInECA: ot,
|
|
1206
1207
|
totalDgoConsInSuspend: Y
|
|
1207
1208
|
}, m.totalFoCons = et < 0 ? 0 : et, m.totalDgoCons = it;
|
|
1208
|
-
const st = p().valueOf() - h, ct = (($ =
|
|
1209
|
+
const st = p().valueOf() - h, ct = (($ = c == null ? void 0 : c.hours) == null ? void 0 : $.length) || 1;
|
|
1209
1210
|
return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, st, ct, Math.round(st / ct * 1e3) / 1e3), m;
|
|
1210
1211
|
}
|
|
1211
1212
|
/**
|
|
@@ -1223,42 +1224,42 @@ class H {
|
|
|
1223
1224
|
* @param useRouteParam
|
|
1224
1225
|
* @param options
|
|
1225
1226
|
*/
|
|
1226
|
-
static async analyseInstantWithThreshed(
|
|
1227
|
+
static async analyseInstantWithThreshed(t, e, n, o, i, a, s, r = "", u = 3, l = !0, h = !1, d = {}) {
|
|
1227
1228
|
var X, Q, Z, $, q, B;
|
|
1228
1229
|
const I = p().valueOf();
|
|
1229
|
-
|
|
1230
|
-
const { v0: b, label: E } =
|
|
1231
|
-
v0:
|
|
1232
|
-
label:
|
|
1230
|
+
t.lng = J.convertToStdLng(t.lng);
|
|
1231
|
+
const { v0: b, label: E } = t.sog ? {
|
|
1232
|
+
v0: t.sog,
|
|
1233
|
+
label: t.label || "Other"
|
|
1233
1234
|
/* Instruct */
|
|
1234
1235
|
} : {
|
|
1235
1236
|
v0: i.speed,
|
|
1236
1237
|
label: "CP"
|
|
1237
1238
|
/* Cp */
|
|
1238
|
-
}, k =
|
|
1239
|
+
}, k = L.assembleProperties(o, i.loadCondition, b, 0), w = R.calculateSubRoute(t, a);
|
|
1239
1240
|
if (((X = w[0]) == null ? void 0 : X.length) <= 1)
|
|
1240
1241
|
return;
|
|
1241
|
-
const v = s.length ? R.calculateSubWaypoints(
|
|
1242
|
+
const v = s.length ? R.calculateSubWaypoints(t, s) : [];
|
|
1242
1243
|
v.forEach((T) => T.important = !0);
|
|
1243
|
-
let m = R.simplifyRouteToCoordinates(w, v, 0),
|
|
1244
|
+
let m = R.simplifyRouteToCoordinates(w, v, 0), c = 0, f = 0, y = 0, S = 0;
|
|
1244
1245
|
const M = {
|
|
1245
1246
|
hours: [],
|
|
1246
1247
|
wps: [],
|
|
1247
1248
|
days: [],
|
|
1248
1249
|
all: []
|
|
1249
1250
|
};
|
|
1250
|
-
|
|
1251
|
-
const j =
|
|
1251
|
+
e = p(e).utc();
|
|
1252
|
+
const j = e.clone();
|
|
1252
1253
|
for (; m.length > 0; ) {
|
|
1253
|
-
const T = u -
|
|
1254
|
-
let
|
|
1255
|
-
|
|
1256
|
-
const P = await
|
|
1257
|
-
if (M.all.push(...P.all), (Q = P.from) != null && Q.speed && (M.hours.push(P.from), P != null && P.wps && M.wps.push(...P.wps), M.days.push(...P.days)), m = P == null ? void 0 : P.next, m.length || M.hours.push(P == null ? void 0 : P.to),
|
|
1254
|
+
const T = u - e.hour() % u;
|
|
1255
|
+
let H = Math.ceil(e.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4;
|
|
1256
|
+
H = e.clone().add(H, "h").isSameOrAfter(n) ? n.diff(e, "h", !0) * 1e4 / 1e4 : H;
|
|
1257
|
+
const P = await L.speedLoseInHoursStep(k, e, j, H, c, m, r, l, h, d);
|
|
1258
|
+
if (M.all.push(...P.all), (Q = P.from) != null && Q.speed && (M.hours.push(P.from), P != null && P.wps && M.wps.push(...P.wps), M.days.push(...P.days)), m = P == null ? void 0 : P.next, m.length || M.hours.push(P == null ? void 0 : P.to), c += Math.round((((Z = P == null ? void 0 : P.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !H)
|
|
1258
1259
|
break;
|
|
1259
1260
|
}
|
|
1260
|
-
M.wps = await
|
|
1261
|
-
const P = M.wps[
|
|
1261
|
+
M.wps = await L.reduceWPS(M.wps), M.days = await L.reduceDays(M.days), M.all = ($ = M.all) == null ? void 0 : $.reduce((T, H) => (H.positionTime = p.utc(H.etd || H.eta).unix(), T.some((P) => Math.round(p(P.etd).unix() / 60) === Math.round(p(H.etd).unix() / 60)) || T.push(H), T), []), (q = M.wps) == null || q.forEach((T, H) => {
|
|
1262
|
+
const P = M.wps[H - 1];
|
|
1262
1263
|
if (P) {
|
|
1263
1264
|
const at = T.distanceFromStart - P.distanceFromStart, lt = p(T.eta || T.etd).diff(p(P.etd || P.eta), "h", !0);
|
|
1264
1265
|
P.bearing = R.calculateBearing(P, T), T.avgSpd = Math.round(at / lt * 100) / 100;
|
|
@@ -1266,27 +1267,27 @@ class H {
|
|
|
1266
1267
|
});
|
|
1267
1268
|
const N = M.hours;
|
|
1268
1269
|
for (let T = 0; T < N.length - 1; T++) {
|
|
1269
|
-
const
|
|
1270
|
-
f += N[T].wxFactor *
|
|
1270
|
+
const H = p(N[T + 1].eta).diff(N[T].etd, "hour", !0);
|
|
1271
|
+
f += N[T].wxFactor * H, y += N[T].cFactor * H, S += H;
|
|
1271
1272
|
}
|
|
1272
|
-
const D = N.reduce((T,
|
|
1273
|
+
const D = N.reduce((T, H) => T + (H.suspend || 0), 0), O = M.hours.at(0), W = M.hours.at(-1), F = await R.calculateRangeRoute(O, W, w), Y = await R.calculateRangeWaypoints(O, W, w, v), A = {
|
|
1273
1274
|
sample: M,
|
|
1274
1275
|
distance: Math.round(((W == null ? void 0 : W.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1275
1276
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1276
|
-
etd: p(
|
|
1277
|
+
etd: p(O.eta).utc().format(),
|
|
1277
1278
|
eta: p(W == null ? void 0 : W.eta).utc().format(),
|
|
1278
1279
|
wxFactor: Math.round(f / S * 1e3) / 1e3,
|
|
1279
1280
|
cFactor: Math.round(y / S * 1e3) / 1e3,
|
|
1280
1281
|
avgSpeed: Math.round(((W == null ? void 0 : W.distanceFromStart) || 0) / S * 1e3) / 1e3,
|
|
1281
1282
|
totalHrs: Math.round(S * 1e3) / 1e3,
|
|
1282
1283
|
suspend: Math.round(D * 1e3) / 1e3,
|
|
1283
|
-
from:
|
|
1284
|
+
from: O,
|
|
1284
1285
|
to: W,
|
|
1285
1286
|
route: F,
|
|
1286
1287
|
waypoints: Y,
|
|
1287
1288
|
v0: b,
|
|
1288
1289
|
label: E
|
|
1289
|
-
}, V = J.roundPrecision(i.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: tt, totalDgoConsInECA: et, eca: it } = await this.calculateECA(A, i,
|
|
1290
|
+
}, V = J.roundPrecision(i.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: tt, totalDgoConsInECA: et, eca: it } = await this.calculateECA(A, i, d), rt = J.roundPrecision(i.fo / 24 * (S - tt), 3), st = J.roundPrecision(i.dgo / 24 * S + V, 3);
|
|
1290
1291
|
A.extend = {
|
|
1291
1292
|
eca: it,
|
|
1292
1293
|
distanceInECA: ot,
|
|
@@ -1295,7 +1296,7 @@ class H {
|
|
|
1295
1296
|
totalDgoConsInSuspend: V
|
|
1296
1297
|
}, A.totalDgoCons = st, A.totalFoCons = rt < 0 ? 0 : rt;
|
|
1297
1298
|
const U = p().valueOf() - I, G = ((B = M == null ? void 0 : M.hours) == null ? void 0 : B.length) || 1;
|
|
1298
|
-
return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",
|
|
1299
|
+
return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", d == null ? void 0 : d.requestId, U, G, Math.round(U / G * 1e3) / 1e3), A;
|
|
1299
1300
|
}
|
|
1300
1301
|
/**
|
|
1301
1302
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1312,34 +1313,34 @@ class H {
|
|
|
1312
1313
|
* @param lane 基础航线(重要转向点)
|
|
1313
1314
|
* @param options
|
|
1314
1315
|
*/
|
|
1315
|
-
static async analyseCost(
|
|
1316
|
+
static async analyseCost(t, e, n, o, i = {}) {
|
|
1316
1317
|
var w, v;
|
|
1317
1318
|
const a = p().valueOf(), s = [];
|
|
1318
|
-
|
|
1319
|
+
t.speedStep = t.speedStep || 3, t.alterStep = t.alterStep ?? 1;
|
|
1319
1320
|
const r = R.calculateRouteDistance(o.route);
|
|
1320
1321
|
let u = 0;
|
|
1321
1322
|
n.forEach((m) => {
|
|
1322
|
-
const
|
|
1323
|
-
u = u <
|
|
1323
|
+
const c = Math.ceil(r / m.speed / 24);
|
|
1324
|
+
u = u < c ? c : u;
|
|
1324
1325
|
}), u = u * 1.3;
|
|
1325
|
-
const l = p.utc(
|
|
1326
|
+
const l = p.utc(t.etd).add(u ?? 14, "day");
|
|
1326
1327
|
let h = 1;
|
|
1327
1328
|
for (const m of n) {
|
|
1328
|
-
const
|
|
1329
|
-
{ lat:
|
|
1330
|
-
|
|
1329
|
+
const c = JSON.parse(JSON.stringify(o.route)), f = JSON.parse(JSON.stringify(o.waypoints)), y = await L.analyseInstantWithThreshed(
|
|
1330
|
+
{ lat: t.lat, lng: t.lng },
|
|
1331
|
+
t.etd,
|
|
1331
1332
|
l,
|
|
1332
|
-
|
|
1333
|
+
e,
|
|
1333
1334
|
m,
|
|
1334
|
-
|
|
1335
|
+
c,
|
|
1335
1336
|
f,
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1337
|
+
t.meteoVendor,
|
|
1338
|
+
t.speedStep,
|
|
1339
|
+
t.useMeteo,
|
|
1340
|
+
t.useRouteParam,
|
|
1340
1341
|
i
|
|
1341
1342
|
);
|
|
1342
|
-
y && (await
|
|
1343
|
+
y && (await L.calculateCost(y, m, t, i), s.push(y), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", i.requestId, 1, h, t.etd, l.format(), {
|
|
1343
1344
|
cost: y.cost.total,
|
|
1344
1345
|
hire: y.cost.hire,
|
|
1345
1346
|
bunker: y.cost.bunker,
|
|
@@ -1348,23 +1349,23 @@ class H {
|
|
|
1348
1349
|
cp: `${m.speed}/${m.fo}/${m.dgo}`
|
|
1349
1350
|
})), h++;
|
|
1350
1351
|
}
|
|
1351
|
-
s.sort((m,
|
|
1352
|
-
const
|
|
1353
|
-
if (b.push({ combined: !1, speeds: [
|
|
1354
|
-
const m =
|
|
1352
|
+
s.sort((m, c) => m.cost.total - c.cost.total);
|
|
1353
|
+
const d = s.at(0), I = s.at(1), b = [];
|
|
1354
|
+
if (b.push({ combined: !1, speeds: [d], cost: (w = d.cost) == null ? void 0 : w.total }), I) {
|
|
1355
|
+
const m = d.cost.cp, c = I.cost.cp, f = p(d.eta), y = p(d.etd), S = f.diff(y, "days", !0);
|
|
1355
1356
|
let M = Math.ceil(S / 2);
|
|
1356
|
-
M = M > 7 ? 7 : M <
|
|
1357
|
+
M = M > 7 ? 7 : M < t.alterStep ? t.alterStep : M;
|
|
1357
1358
|
let j = 2, N = { combined: !1, speeds: [I], cost: (v = I.cost) == null ? void 0 : v.total }, D;
|
|
1358
|
-
for (; M >=
|
|
1359
|
-
const
|
|
1360
|
-
if (N.cost >
|
|
1359
|
+
for (; M >= t.alterStep; ) {
|
|
1360
|
+
const O = await L.combinedAnalyse(t, e, l, [m, c], o, M, { ...i, level: j });
|
|
1361
|
+
if (N.cost > O.cost ? D ? (D == null ? void 0 : D.cost) > O.cost && (D = O) : (D = N, N = O) : (!D || (D == null ? void 0 : D.cost) > O.cost) && (D = O), M <= t.alterStep)
|
|
1361
1362
|
break;
|
|
1362
1363
|
M = Math.ceil(M / 2), j += 1;
|
|
1363
1364
|
}
|
|
1364
1365
|
b.push(N), D && b.push(D);
|
|
1365
1366
|
}
|
|
1366
1367
|
const k = p().valueOf() - a;
|
|
1367
|
-
return C == null || C.info("[%s] analyse elapsed: %d ms", i == null ? void 0 : i.requestId, k), b.sort((m,
|
|
1368
|
+
return C == null || C.info("[%s] analyse elapsed: %d ms", i == null ? void 0 : i.requestId, k), b.sort((m, c) => m.cost - c.cost);
|
|
1368
1369
|
}
|
|
1369
1370
|
/**
|
|
1370
1371
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1376,17 +1377,17 @@ class H {
|
|
|
1376
1377
|
* @param step 步长,7,4,2,1
|
|
1377
1378
|
* @param options
|
|
1378
1379
|
*/
|
|
1379
|
-
static async combinedAnalyse(
|
|
1380
|
+
static async combinedAnalyse(t, e, n, o, i, a, s = {}) {
|
|
1380
1381
|
s.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, a);
|
|
1381
|
-
const r = await
|
|
1382
|
+
const r = await L.alternateAnalyse(t, e, n, o, 0, i, a, s), u = r.reduce((c, f) => c + f.cost.total, 0), l = r.reduce((c, f) => c + f.cost.hire, 0), h = r.reduce((c, f) => c + f.cost.bunker, 0), d = r.reduce((c, f) => c + f.distance, 0), I = r.reduce((c, f) => c + f.totalHrs, 0);
|
|
1382
1383
|
C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
|
|
1383
1384
|
cost: u,
|
|
1384
1385
|
hire: l,
|
|
1385
1386
|
bunker: h,
|
|
1386
|
-
distance:
|
|
1387
|
+
distance: d,
|
|
1387
1388
|
hours: I
|
|
1388
1389
|
});
|
|
1389
|
-
const b = await
|
|
1390
|
+
const b = await L.alternateAnalyse(t, e, n, o, 1, i, a, s), E = b.reduce((c, f) => c + f.cost.total, 0), k = b.reduce((c, f) => c + f.cost.hire, 0), w = b.reduce((c, f) => c + f.cost.bunker, 0), v = b.reduce((c, f) => c + f.distance, 0), m = b.reduce((c, f) => c + f.totalHrs, 0);
|
|
1390
1391
|
return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
|
|
1391
1392
|
cost: E,
|
|
1392
1393
|
hire: k,
|
|
@@ -1406,26 +1407,26 @@ class H {
|
|
|
1406
1407
|
* @param step 步长,7,4,2,1
|
|
1407
1408
|
* @param options
|
|
1408
1409
|
*/
|
|
1409
|
-
static async alternateAnalyse(
|
|
1410
|
-
var
|
|
1411
|
-
let u = p.utc(
|
|
1412
|
-
const l = { lat:
|
|
1410
|
+
static async alternateAnalyse(t, e, n, o, i, a, s, r = {}) {
|
|
1411
|
+
var d, I;
|
|
1412
|
+
let u = p.utc(t.etd);
|
|
1413
|
+
const l = { lat: t.lat, lng: t.lng }, h = [];
|
|
1413
1414
|
for (; u.isBefore(n); ) {
|
|
1414
|
-
const b = u.clone().utc().add(s, "day"), E = JSON.parse(JSON.stringify(a.route)), k = JSON.parse(JSON.stringify(a.waypoints)), w = o[i], v = await
|
|
1415
|
+
const b = u.clone().utc().add(s, "day"), E = JSON.parse(JSON.stringify(a.route)), k = JSON.parse(JSON.stringify(a.waypoints)), w = o[i], v = await L.analyseInstantWithThreshed(
|
|
1415
1416
|
l,
|
|
1416
1417
|
u.utc().format(),
|
|
1417
1418
|
b,
|
|
1418
|
-
|
|
1419
|
+
e,
|
|
1419
1420
|
w,
|
|
1420
1421
|
E,
|
|
1421
1422
|
k,
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1423
|
+
t.meteoVendor,
|
|
1424
|
+
t.speedStep,
|
|
1425
|
+
t.useMeteo,
|
|
1426
|
+
t.useRouteParam,
|
|
1426
1427
|
r
|
|
1427
1428
|
);
|
|
1428
|
-
v && (await
|
|
1429
|
+
v && (await L.calculateCost(v, w, t, r), C == null || C.info(
|
|
1429
1430
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1430
1431
|
r.requestId,
|
|
1431
1432
|
r.level,
|
|
@@ -1441,7 +1442,7 @@ class H {
|
|
|
1441
1442
|
cp: `${w.speed}/${w.fo}/${w.dgo}`
|
|
1442
1443
|
}
|
|
1443
1444
|
)), r.counter = r.counter + 1;
|
|
1444
|
-
const m = (I = (
|
|
1445
|
+
const m = (I = (d = v == null ? void 0 : v.sample) == null ? void 0 : d.hours) == null ? void 0 : I.at(-1);
|
|
1445
1446
|
if (m)
|
|
1446
1447
|
l.lat = m.lat, l.lng = m.lng, u = p(m.eta), h.push(v), i = i ? 0 : 1;
|
|
1447
1448
|
else
|
|
@@ -1456,35 +1457,35 @@ class H {
|
|
|
1456
1457
|
* @param props
|
|
1457
1458
|
* @param options
|
|
1458
1459
|
*/
|
|
1459
|
-
static async calculateCost(
|
|
1460
|
+
static async calculateCost(t, e, n, o = {}) {
|
|
1460
1461
|
var i;
|
|
1461
|
-
if (
|
|
1462
|
-
const a = (n.addComm || 0) >= 1 ? (n.addComm || 0) / 100 : n.addComm || 0, s = Math.round((n.dailyHire || 0) * (
|
|
1463
|
-
|
|
1462
|
+
if (t) {
|
|
1463
|
+
const a = (n.addComm || 0) >= 1 ? (n.addComm || 0) / 100 : n.addComm || 0, s = Math.round((n.dailyHire || 0) * (t.suspend || 0) / 24 * 1e3) / 1e3, r = Math.round(t.totalHrs / 24 * (n.dailyHire || 0) * (1 - a) * 1e3) / 1e3 + s, u = Math.round(t.totalFoCons * (n.priceFO || 0) * 1e3) / 1e3, l = Math.round((t.totalDgoCons + (((i = t.extend) == null ? void 0 : i.totalDgoConsInECA) || 0)) * (n.priceDGO || 0) * 1e3) / 1e3;
|
|
1464
|
+
t.cost = {
|
|
1464
1465
|
total: Math.round((r + u + l) * 1e3) / 1e3,
|
|
1465
1466
|
hire: Math.round(r * 1e3) / 1e3,
|
|
1466
1467
|
suspendHire: s,
|
|
1467
1468
|
bunker: Math.round((u + l) * 1e3) / 1e3,
|
|
1468
|
-
cp:
|
|
1469
|
+
cp: e
|
|
1469
1470
|
};
|
|
1470
1471
|
}
|
|
1471
|
-
return
|
|
1472
|
+
return t;
|
|
1472
1473
|
}
|
|
1473
1474
|
/**
|
|
1474
1475
|
* 计算单cp模式下的ECA属性
|
|
1475
1476
|
*
|
|
1476
1477
|
*/
|
|
1477
|
-
static async calculateECA(
|
|
1478
|
+
static async calculateECA(t, e, n = {}) {
|
|
1478
1479
|
var r, u, l, h;
|
|
1479
|
-
const o = await R.intersectInECA((
|
|
1480
|
+
const o = await R.intersectInECA((t == null ? void 0 : t.route) || []);
|
|
1480
1481
|
let i = 0, a = 0, s = 0;
|
|
1481
|
-
(u = (r =
|
|
1482
|
-
|
|
1482
|
+
(u = (r = t == null ? void 0 : t.sample) == null ? void 0 : r.wps) == null || u.forEach((d) => {
|
|
1483
|
+
d.positionTime = p.utc(d.etd || d.eta).unix();
|
|
1483
1484
|
});
|
|
1484
|
-
for (const
|
|
1485
|
-
i +=
|
|
1486
|
-
const I = await R.deadReckoningTime((l =
|
|
1487
|
-
|
|
1485
|
+
for (const d of o) {
|
|
1486
|
+
i += d.distance;
|
|
1487
|
+
const I = await R.deadReckoningTime((l = d.waypoints) == null ? void 0 : l.at(0), t.sample.all || t.sample.wps), b = await R.deadReckoningTime((h = d.waypoints) == null ? void 0 : h.at(-1), t.sample.all || t.sample.wps);
|
|
1488
|
+
d.in = I, d.out = b, d.totalHrs = J.roundPrecision((b.positionTime - I.positionTime) / 3600, 3), d.totalDgoCons = J.roundPrecision(e.fo / 24 * d.totalHrs, 3), a += d.totalHrs, s += d.totalDgoCons;
|
|
1488
1489
|
}
|
|
1489
1490
|
return i = J.roundPrecision(i, 3), a = J.roundPrecision(a, 3), s = J.roundPrecision(s, 3), {
|
|
1490
1491
|
distanceInECA: i,
|
|
@@ -1498,25 +1499,25 @@ class H {
|
|
|
1498
1499
|
* @param speeds
|
|
1499
1500
|
* @param options
|
|
1500
1501
|
*/
|
|
1501
|
-
static async mergeSpeeds(
|
|
1502
|
-
var m,
|
|
1502
|
+
static async mergeSpeeds(t, e = {}) {
|
|
1503
|
+
var m, c;
|
|
1503
1504
|
const n = {
|
|
1504
1505
|
hours: [],
|
|
1505
1506
|
wps: [],
|
|
1506
1507
|
days: [],
|
|
1507
1508
|
all: []
|
|
1508
|
-
}, o =
|
|
1509
|
+
}, o = t.reduce((f, y) => f + y.distance, 0), i = t.reduce((f, y) => {
|
|
1509
1510
|
var S;
|
|
1510
1511
|
return f + (((S = y.extend) == null ? void 0 : S.distanceInECA) || 0);
|
|
1511
|
-
}, 0), a =
|
|
1512
|
+
}, 0), a = t.reduce((f, y) => f + y.totalHrs, 0), s = t.reduce((f, y) => {
|
|
1512
1513
|
var S;
|
|
1513
1514
|
return f + (((S = y.extend) == null ? void 0 : S.hoursInECA) || 0);
|
|
1514
|
-
}, 0), r =
|
|
1515
|
+
}, 0), r = t.reduce((f, y) => {
|
|
1515
1516
|
var S;
|
|
1516
1517
|
return f + (((S = y.extend) == null ? void 0 : S.totalDgoConsInECA) || 0);
|
|
1517
|
-
}, 0), u =
|
|
1518
|
+
}, 0), u = t.reduce((f, y) => f + y.wxFactor * y.totalHrs / a, 0), l = t.reduce((f, y) => f + y.cFactor * y.totalHrs / a, 0), h = t.reduce((f, y) => f + y.totalFoCons, 0), d = t.reduce((f, y) => f + y.totalDgoCons, 0), I = t.reduce((f, y) => f + y.cost.total, 0), b = t.reduce((f, y) => f + y.cost.hire, 0), E = t.reduce((f, y) => f + y.cost.bunker, 0), k = [], w = [];
|
|
1518
1519
|
let v;
|
|
1519
|
-
for (const f of
|
|
1520
|
+
for (const f of t) {
|
|
1520
1521
|
w.push(...((m = f.extend) == null ? void 0 : m.eca) || []);
|
|
1521
1522
|
const y = f.sample.hours, S = f.sample.all, M = f.sample.wps, j = f.sample.days, N = y.at(0);
|
|
1522
1523
|
v && (N.distanceFromPrevious = v.distanceFromPrevious, N.distanceFromStart = v.distanceFromStart, y.forEach((F, Y) => {
|
|
@@ -1528,8 +1529,8 @@ class H {
|
|
|
1528
1529
|
}), j.at(0).distanceFromPrevious = v.distanceFromPrevious, j.at(0).distanceFromStart = v.distanceFromStart, j.forEach((F, Y) => {
|
|
1529
1530
|
Y && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
|
|
1530
1531
|
})), N.cp = f.cost.cp;
|
|
1531
|
-
const D = [f.etd, f.eta],
|
|
1532
|
-
|
|
1532
|
+
const D = [f.etd, f.eta], O = k.findIndex((F) => F.id === N.cp.id);
|
|
1533
|
+
O === -1 ? (N.cp.segment = [D], k.push(N.cp)) : k[O].segment.push(D), y.forEach((F) => {
|
|
1533
1534
|
var A;
|
|
1534
1535
|
((A = n.hours) == null ? void 0 : A.findIndex((V) => V.eta === F.eta)) === -1 && n.hours.push(F);
|
|
1535
1536
|
}), S.forEach((F) => {
|
|
@@ -1542,7 +1543,7 @@ class H {
|
|
|
1542
1543
|
var A;
|
|
1543
1544
|
((A = n == null ? void 0 : n.days) == null ? void 0 : A.findIndex((V) => V.eta === F.eta)) === -1 && n.days.push(F);
|
|
1544
1545
|
});
|
|
1545
|
-
const W = (
|
|
1546
|
+
const W = (c = n.wps) == null ? void 0 : c.findIndex((F) => F.eta === N.eta);
|
|
1546
1547
|
W === -1 ? n.wps.push(N) : n.wps[W] = N, v = y.at(-1);
|
|
1547
1548
|
}
|
|
1548
1549
|
return n.wps.sort((f, y) => p(f.etd).unix() - p(y.etd).unix()), n.wps.forEach((f, y) => {
|
|
@@ -1555,11 +1556,11 @@ class H {
|
|
|
1555
1556
|
}
|
|
1556
1557
|
}), {
|
|
1557
1558
|
sample: n,
|
|
1558
|
-
etd:
|
|
1559
|
-
eta:
|
|
1560
|
-
from:
|
|
1561
|
-
to:
|
|
1562
|
-
v0:
|
|
1559
|
+
etd: t.at(0).etd,
|
|
1560
|
+
eta: t.at(-1).eta,
|
|
1561
|
+
from: t.at(0).from,
|
|
1562
|
+
to: t.at(-1).to,
|
|
1563
|
+
v0: t.at(0).v0,
|
|
1563
1564
|
label: "Combined",
|
|
1564
1565
|
distance: Math.round(o * 1e3) / 1e3,
|
|
1565
1566
|
totalHrs: Math.round(a * 1e3) / 1e3,
|
|
@@ -1567,7 +1568,7 @@ class H {
|
|
|
1567
1568
|
wxFactor: Math.round(u * 1e3) / 1e3,
|
|
1568
1569
|
cFactor: Math.round(l * 1e3) / 1e3,
|
|
1569
1570
|
totalFoCons: Math.round(h * 1e3) / 1e3,
|
|
1570
|
-
totalDgoCons: Math.round(
|
|
1571
|
+
totalDgoCons: Math.round(d * 1e3) / 1e3,
|
|
1571
1572
|
cost: {
|
|
1572
1573
|
total: Math.round(I * 1e3) / 1e3,
|
|
1573
1574
|
hire: Math.round(b * 1e3) / 1e3,
|
|
@@ -1579,7 +1580,7 @@ class H {
|
|
|
1579
1580
|
distanceInECA: Math.round(i * 1e3) / 1e3,
|
|
1580
1581
|
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1581
1582
|
totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
|
|
1582
|
-
speeds:
|
|
1583
|
+
speeds: t
|
|
1583
1584
|
}
|
|
1584
1585
|
};
|
|
1585
1586
|
}
|
|
@@ -1593,7 +1594,7 @@ export {
|
|
|
1593
1594
|
Nt as MyShipImpl,
|
|
1594
1595
|
Tt as MyVesselImpl,
|
|
1595
1596
|
xt as ShipxyImpl,
|
|
1596
|
-
|
|
1597
|
+
L as SpeedHelper,
|
|
1597
1598
|
wt as SpeedLabel,
|
|
1598
1599
|
bt as VesselTag,
|
|
1599
1600
|
Dt as alertHelper
|