@idm-plugin/vessel 3.4.6 → 3.4.7
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 -324
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var K = (
|
|
1
|
+
var ft = Object.defineProperty;
|
|
2
|
+
var yt = (D, s, t) => s in D ? ft(D, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : D[s] = t;
|
|
3
|
+
var K = (D, s, t) => (yt(D, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
4
|
import B from "got";
|
|
5
|
-
import
|
|
5
|
+
import ht from "@log4js-node/log4js-api";
|
|
6
6
|
import v from "moment";
|
|
7
7
|
import { LaneHelper as V, LngLatHelper as z } from "@idm-plugin/geo2";
|
|
8
|
-
import { MeteoHelper2 as
|
|
9
|
-
import { Meteo2Assist as
|
|
8
|
+
import { MeteoHelper2 as Mt } from "@idm-plugin/meteo2";
|
|
9
|
+
import { Meteo2Assist as ut } from "@idm-plugin/meteo";
|
|
10
10
|
let M;
|
|
11
11
|
try {
|
|
12
|
-
M =
|
|
12
|
+
M = ht.getLogger("vessel");
|
|
13
13
|
} catch {
|
|
14
14
|
} finally {
|
|
15
15
|
}
|
|
16
|
-
class
|
|
16
|
+
class ot {
|
|
17
17
|
/**
|
|
18
18
|
* 解析AIS状态码
|
|
19
19
|
* @param status
|
|
@@ -54,7 +54,7 @@ class nt {
|
|
|
54
54
|
return { labelCn: t, labelEn: a };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class Nt extends ot {
|
|
58
58
|
constructor(t, a) {
|
|
59
59
|
super();
|
|
60
60
|
K(this, "clientId");
|
|
@@ -120,11 +120,11 @@ class Ft extends nt {
|
|
|
120
120
|
* @param options
|
|
121
121
|
*/
|
|
122
122
|
async search(t, a = {}) {
|
|
123
|
-
var
|
|
123
|
+
var h, l;
|
|
124
124
|
await this.checkToken(a);
|
|
125
125
|
const i = /^\d{7}$/.test(t.toString()), n = i ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", o = i ? { imo: t } : { mmsi: t }, e = {
|
|
126
126
|
headers: {
|
|
127
|
-
Authorization: `${(
|
|
127
|
+
Authorization: `${(h = this.token) == null ? void 0 : h.tokenType} ${(l = this.token) == null ? void 0 : l.accessToken}`
|
|
128
128
|
},
|
|
129
129
|
searchParams: o
|
|
130
130
|
};
|
|
@@ -177,11 +177,11 @@ class Ft extends nt {
|
|
|
177
177
|
return o.status !== 200 ? (M == null || M.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), {}) : o.data;
|
|
178
178
|
}
|
|
179
179
|
async realTimePosition(t, a = {}) {
|
|
180
|
-
var r,
|
|
180
|
+
var r, h;
|
|
181
181
|
await this.checkToken(a);
|
|
182
182
|
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
|
|
183
183
|
headers: {
|
|
184
|
-
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(
|
|
184
|
+
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
|
|
185
185
|
},
|
|
186
186
|
searchParams: { mmsi: t }
|
|
187
187
|
};
|
|
@@ -240,7 +240,7 @@ class Ft extends nt {
|
|
|
240
240
|
var y, w, g;
|
|
241
241
|
const r = v();
|
|
242
242
|
await this.checkToken(e);
|
|
243
|
-
const
|
|
243
|
+
const h = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", l = {
|
|
244
244
|
headers: {
|
|
245
245
|
Authorization: `${(y = this.token) == null ? void 0 : y.tokenType} ${(w = this.token) == null ? void 0 : w.accessToken}`
|
|
246
246
|
},
|
|
@@ -259,8 +259,8 @@ class Ft extends nt {
|
|
|
259
259
|
withSpecialRegion: e.withSpecial || !1
|
|
260
260
|
}
|
|
261
261
|
};
|
|
262
|
-
i != null && i.length && (l.json.crossMonthList = i), n != null && n.length && (l.json.excludeNodes = n), o != null && o.length && (l.json.excludeSeaAreas = o), M == null || M.info("[%s] fetch route from: %s - %j", e.requestId,
|
|
263
|
-
const d = await B.post(
|
|
262
|
+
i != null && i.length && (l.json.crossMonthList = i), n != null && n.length && (l.json.excludeNodes = n), o != null && o.length && (l.json.excludeSeaAreas = o), M == null || M.info("[%s] fetch route from: %s - %j", e.requestId, h, l);
|
|
263
|
+
const d = await B.post(h, l).json();
|
|
264
264
|
if (d.status !== 200)
|
|
265
265
|
return M == null || M.warn("[%s] fetch route failed: %j", e.requestId, { message: d.message, status: d.status, code: d.code }), {};
|
|
266
266
|
{
|
|
@@ -273,8 +273,8 @@ class Ft extends nt {
|
|
|
273
273
|
route: [],
|
|
274
274
|
distance: 0,
|
|
275
275
|
memo: ""
|
|
276
|
-
}, { nodes:
|
|
277
|
-
k.nodes =
|
|
276
|
+
}, { nodes: j, seas: p, tracks: b, specialRegions: f } = d.data;
|
|
277
|
+
k.nodes = j == null ? void 0 : j.map((c) => ({
|
|
278
278
|
code: c.nodeCode,
|
|
279
279
|
nameEn: c.nameEn,
|
|
280
280
|
nameCn: c.nameCn,
|
|
@@ -297,7 +297,7 @@ class Ft extends nt {
|
|
|
297
297
|
isKey: c.isKeyNode,
|
|
298
298
|
// 重要枢纽节点
|
|
299
299
|
isHub: c.isHubNode
|
|
300
|
-
})), k.seas =
|
|
300
|
+
})), k.seas = p == null ? void 0 : p.map((c) => ({
|
|
301
301
|
code: c.mrgidSea,
|
|
302
302
|
nameEn: c.nameEn,
|
|
303
303
|
nameCn: c.nameCn,
|
|
@@ -326,7 +326,7 @@ class Ft extends nt {
|
|
|
326
326
|
distance: I.length
|
|
327
327
|
}))
|
|
328
328
|
});
|
|
329
|
-
}), k.waypoints =
|
|
329
|
+
}), k.waypoints = b == null ? void 0 : b.map((c) => ({
|
|
330
330
|
lat: Math.round(c.lat * 1e5) / 1e5,
|
|
331
331
|
lng: Math.round(c.lon * 1e5) / 1e5
|
|
332
332
|
})), (g = k.waypoints) != null && g.length && (k.waypoints = V.simplifyCoordinates(k.waypoints), k.route = V.divideAccordingToLng(k.waypoints), k.distance = V.calculateRouteDistance(k.route));
|
|
@@ -336,14 +336,14 @@ class Ft extends nt {
|
|
|
336
336
|
}
|
|
337
337
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
338
338
|
await this.checkToken(e);
|
|
339
|
-
const r = await this.realTimePosition(t, e),
|
|
340
|
-
for (; l.diff(
|
|
341
|
-
await this.trajectoryIn30Day(t,
|
|
342
|
-
return await this.trajectoryIn30Day(t,
|
|
339
|
+
const r = await this.realTimePosition(t, e), h = v(a), l = v(i), d = [];
|
|
340
|
+
for (; l.diff(h, "day", !0) > 30; )
|
|
341
|
+
await this.trajectoryIn30Day(t, h, h.clone().add(30, "day"), r, n, d, e), h.add(30, "day");
|
|
342
|
+
return await this.trajectoryIn30Day(t, h, l, r, n, d, e), d;
|
|
343
343
|
}
|
|
344
344
|
async trajectoryIn30Day(t, a, i, n, o, e, r = {}) {
|
|
345
|
-
var g, k,
|
|
346
|
-
const
|
|
345
|
+
var g, k, j, p, b;
|
|
346
|
+
const h = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", l = {
|
|
347
347
|
headers: {
|
|
348
348
|
Authorization: `${(g = this.token) == null ? void 0 : g.tokenType} ${(k = this.token) == null ? void 0 : k.accessToken}`
|
|
349
349
|
},
|
|
@@ -353,16 +353,16 @@ class Ft extends nt {
|
|
|
353
353
|
endTime: i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
354
354
|
}
|
|
355
355
|
};
|
|
356
|
-
M == null || M.info("[%s] fetch trajectory from: %s - %j", r.requestId,
|
|
357
|
-
const d = await B.post(
|
|
356
|
+
M == null || M.info("[%s] fetch trajectory from: %s - %j", r.requestId, h, l);
|
|
357
|
+
const d = await B.post(h, l).json();
|
|
358
358
|
if (d.code)
|
|
359
|
-
return M == null || M.warn("[%s] fetch trajectory failed: %j", r.requestId,
|
|
359
|
+
return M == null || M.warn("[%s] fetch trajectory failed: %j", r.requestId, h, { message: d.message, status: d.status, code: d.code }), d;
|
|
360
360
|
let y = -1;
|
|
361
|
-
const w = v(`${(
|
|
362
|
-
return (
|
|
363
|
-
for (const
|
|
364
|
-
!isNaN(f[
|
|
365
|
-
const
|
|
361
|
+
const w = v(`${(p = (j = d.data) == null ? void 0 : j[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
362
|
+
return (b = d.data) == null || b.forEach((f) => {
|
|
363
|
+
for (const Y in f)
|
|
364
|
+
!isNaN(f[Y]) && Number(f[Y]) !== 1 / 0 && (f[Y] = Number(f[Y]));
|
|
365
|
+
const u = v(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), m = f.status, { labelCn: c, labelEn: I } = this.parseStatus(m), C = {
|
|
366
366
|
mmsi: f.mmsi,
|
|
367
367
|
imo: n == null ? void 0 : n.imo,
|
|
368
368
|
lat: f.lat,
|
|
@@ -374,18 +374,18 @@ class Ft extends nt {
|
|
|
374
374
|
status: m,
|
|
375
375
|
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta) ? v(`${f.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
|
|
376
376
|
destination: f.dest,
|
|
377
|
-
positionTime:
|
|
377
|
+
positionTime: u.unix(),
|
|
378
378
|
labelCn: c,
|
|
379
379
|
labelEn: I,
|
|
380
380
|
method: "trajectory",
|
|
381
381
|
vendor: "myVessel",
|
|
382
|
-
utc:
|
|
383
|
-
}, F = Math.floor(
|
|
382
|
+
utc: u.utc().format()
|
|
383
|
+
}, F = Math.floor(u.diff(w, "minute", !0) / (o || 1));
|
|
384
384
|
F !== y && (y = F, e.push(C));
|
|
385
385
|
}), e;
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
|
-
class
|
|
388
|
+
class xt extends ot {
|
|
389
389
|
constructor(t) {
|
|
390
390
|
super();
|
|
391
391
|
K(this, "token");
|
|
@@ -405,7 +405,7 @@ class Nt extends nt {
|
|
|
405
405
|
for (const w in e)
|
|
406
406
|
!isNaN(e[w]) && Number(e[w]) !== 1 / 0 && (e[w] = Number(e[w]));
|
|
407
407
|
e.status = e.sp > 3 ? 0 : 1;
|
|
408
|
-
const r = e.status, { labelCn:
|
|
408
|
+
const r = e.status, { labelCn: h, labelEn: l } = this.parseStatus(r), d = v(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
409
409
|
return {
|
|
410
410
|
mmsi: e.m,
|
|
411
411
|
name: e.n,
|
|
@@ -429,7 +429,7 @@ class Nt extends nt {
|
|
|
429
429
|
positionTime: d.unix(),
|
|
430
430
|
utc: d.utc().format(),
|
|
431
431
|
status: r,
|
|
432
|
-
labelCn:
|
|
432
|
+
labelCn: h,
|
|
433
433
|
labelEn: l,
|
|
434
434
|
method: "position",
|
|
435
435
|
vendor: "hifleet"
|
|
@@ -484,37 +484,37 @@ class Nt extends nt {
|
|
|
484
484
|
imo: !r.imo || isNaN(r.imo) ? null : Number(r.imo),
|
|
485
485
|
score: r._score
|
|
486
486
|
});
|
|
487
|
-
return e.sort((r,
|
|
487
|
+
return e.sort((r, h) => h.score - r.score), e;
|
|
488
488
|
}
|
|
489
489
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
490
|
-
var f,
|
|
490
|
+
var f, u, m;
|
|
491
491
|
const r = await this.realTimePosition(t, e);
|
|
492
|
-
let
|
|
492
|
+
let h = v(a);
|
|
493
493
|
const l = v(i), d = v();
|
|
494
494
|
if (o) {
|
|
495
|
-
let c = l.diff(
|
|
496
|
-
c < 0 ?
|
|
495
|
+
let c = l.diff(h, "d", !0);
|
|
496
|
+
c < 0 ? h = l.clone().subtract(40, "d") : c < 30 ? h.subtract(10, "d") : c < 60 ? h.subtract(5, "d") : h = l.clone().subtract(80, "d"), c = d.diff(l, "d", !0), l.add(c > 10 ? 240 : c * 24, "h");
|
|
497
497
|
}
|
|
498
498
|
const y = {
|
|
499
499
|
searchParams: {
|
|
500
500
|
endtime: l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
501
|
-
starttime:
|
|
501
|
+
starttime: h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
502
502
|
mmsi: t,
|
|
503
503
|
usertoken: this.token
|
|
504
504
|
}
|
|
505
505
|
}, w = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", g = await B.get(w, y).json();
|
|
506
506
|
M == null || M.info("[%s] fetch trajectory from: %s - %j", e.requestId, w, y);
|
|
507
507
|
let k;
|
|
508
|
-
g && (k = ((
|
|
509
|
-
const
|
|
510
|
-
let
|
|
511
|
-
const
|
|
508
|
+
g && (k = ((u = (f = g.ships) == null ? void 0 : f.offors) == null ? void 0 : u.ship) || [], k.length || M == null || M.warn("[%s] fetch trajectory failed: %j", e.requestId, g));
|
|
509
|
+
const j = [];
|
|
510
|
+
let p = -1;
|
|
511
|
+
const b = v(`${(m = k == null ? void 0 : k[0]) == null ? void 0 : m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
512
512
|
for (const c of k) {
|
|
513
513
|
for (const H in c)
|
|
514
514
|
!isNaN(c[H]) && Number(c[H]) !== 1 / 0 && (c[H] = Number(c[H]));
|
|
515
515
|
const I = v(`${c.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
516
516
|
c.status = c.sp > 4 ? 0 : 1;
|
|
517
|
-
const { labelEn: C, labelCn: F } = this.parseStatus(c.status),
|
|
517
|
+
const { labelEn: C, labelCn: F } = this.parseStatus(c.status), Y = {
|
|
518
518
|
mmsi: c.m,
|
|
519
519
|
name: c.n,
|
|
520
520
|
imo: r == null ? void 0 : r.imo,
|
|
@@ -531,13 +531,13 @@ class Nt extends nt {
|
|
|
531
531
|
labelEn: C,
|
|
532
532
|
method: "trajectory",
|
|
533
533
|
vendor: "hifleet"
|
|
534
|
-
},
|
|
535
|
-
|
|
534
|
+
}, A = Math.floor(I.diff(b, "minute", !0) / (n || 1));
|
|
535
|
+
A !== p && (p = A, j.push(Y));
|
|
536
536
|
}
|
|
537
|
-
return
|
|
537
|
+
return j;
|
|
538
538
|
}
|
|
539
539
|
}
|
|
540
|
-
class
|
|
540
|
+
class Dt extends ot {
|
|
541
541
|
constructor(t) {
|
|
542
542
|
super();
|
|
543
543
|
K(this, "token");
|
|
@@ -556,7 +556,7 @@ class xt extends nt {
|
|
|
556
556
|
const e = o.data[0];
|
|
557
557
|
for (const y in e)
|
|
558
558
|
!isNaN(e[y]) && Number(e[y]) !== 1 / 0 && (e[y] = Number(e[y]));
|
|
559
|
-
const { labelCn: r, labelEn:
|
|
559
|
+
const { labelCn: r, labelEn: h } = await this.parseStatus(e.navistat), l = v.unix(e.lasttime);
|
|
560
560
|
return {
|
|
561
561
|
mmsi: e.ShipID,
|
|
562
562
|
name: e.name,
|
|
@@ -574,47 +574,47 @@ class xt extends nt {
|
|
|
574
574
|
positionTime: e.lasttime,
|
|
575
575
|
utc: l.utc().format(),
|
|
576
576
|
status: e.navistat,
|
|
577
|
-
labelEn:
|
|
577
|
+
labelEn: h,
|
|
578
578
|
labelCn: r,
|
|
579
579
|
method: "position",
|
|
580
580
|
vendor: "shipxy"
|
|
581
581
|
};
|
|
582
582
|
}
|
|
583
583
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
584
|
-
var
|
|
585
|
-
const r = await this.realTimePosition(t, e),
|
|
584
|
+
var b;
|
|
585
|
+
const r = await this.realTimePosition(t, e), h = v(a), l = v(i), d = "https://api.shipxy.com/apicall/GetShipTrack", y = {
|
|
586
586
|
searchParams: {
|
|
587
587
|
id: t,
|
|
588
588
|
k: this.token,
|
|
589
589
|
enc: 1,
|
|
590
590
|
cut: 0,
|
|
591
|
-
btm:
|
|
591
|
+
btm: h.unix(),
|
|
592
592
|
etm: l.unix()
|
|
593
593
|
}
|
|
594
594
|
}, w = await B.get(d, y).json();
|
|
595
595
|
if (M == null || M.info("[%s] fetch trajectory from: %s - %j", e.requestId, d, y), (w == null ? void 0 : w.status) !== 0)
|
|
596
596
|
return w;
|
|
597
|
-
const g = w == null ? void 0 : w.points, k = [],
|
|
598
|
-
let
|
|
597
|
+
const g = w == null ? void 0 : w.points, k = [], j = v.unix((b = g[0]) == null ? void 0 : b.utc);
|
|
598
|
+
let p = -1;
|
|
599
599
|
for (const f of g) {
|
|
600
|
-
const
|
|
600
|
+
const u = v.unix(f.utc), m = {
|
|
601
601
|
imo: r == null ? void 0 : r.imo,
|
|
602
602
|
mmsi: t,
|
|
603
603
|
sog: Math.round(f.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
604
604
|
cog: Math.round(f.cog / 100 * 100) / 100,
|
|
605
605
|
lat: Math.round(f.lat / 1e6 * 1e5) / 1e5,
|
|
606
606
|
lng: Math.round(f.lon / 1e6 * 1e5) / 1e5,
|
|
607
|
-
positionTime:
|
|
608
|
-
utc:
|
|
607
|
+
positionTime: u.unix(),
|
|
608
|
+
utc: u.utc().format(),
|
|
609
609
|
method: "trajectory",
|
|
610
610
|
vendor: "shipxy"
|
|
611
|
-
}, c = Math.floor(
|
|
612
|
-
c !==
|
|
611
|
+
}, c = Math.floor(u.diff(j, "minute", !0) / (n || 1));
|
|
612
|
+
c !== p && (p = c, k.push(m));
|
|
613
613
|
}
|
|
614
614
|
return k;
|
|
615
615
|
}
|
|
616
616
|
}
|
|
617
|
-
class
|
|
617
|
+
class At extends ot {
|
|
618
618
|
constructor(t) {
|
|
619
619
|
super();
|
|
620
620
|
K(this, "token");
|
|
@@ -664,22 +664,22 @@ class Dt extends nt {
|
|
|
664
664
|
}
|
|
665
665
|
}, e = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(e, o).json();
|
|
666
666
|
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, e, o);
|
|
667
|
-
const
|
|
668
|
-
for (const g in
|
|
669
|
-
!isNaN(
|
|
670
|
-
const { labelCn: l, labelEn: d } = await this.parseStatus(
|
|
667
|
+
const h = r.data[0];
|
|
668
|
+
for (const g in h)
|
|
669
|
+
!isNaN(h[g]) && Number(h[g]) !== 1 / 0 && (h[g] = Number(h[g]));
|
|
670
|
+
const { labelCn: l, labelEn: d } = await this.parseStatus(h.aisNavStatus), y = v.unix(h.posTime);
|
|
671
671
|
return {
|
|
672
672
|
...n,
|
|
673
673
|
mmsi: t,
|
|
674
|
-
lat: Math.round(
|
|
675
|
-
lng: Math.round(
|
|
676
|
-
sog: Math.round(
|
|
677
|
-
cog: Math.round(
|
|
678
|
-
hdg: Math.round(
|
|
679
|
-
rot: Math.round(
|
|
680
|
-
positionTime:
|
|
674
|
+
lat: Math.round(h.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
675
|
+
lng: Math.round(h.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
676
|
+
sog: Math.round(h.sog / 10 * 100) / 100,
|
|
677
|
+
cog: Math.round(h.cog / 10 * 100) / 100,
|
|
678
|
+
hdg: Math.round(h.heading * 100) / 100,
|
|
679
|
+
rot: Math.round(h.rot * 100) / 100,
|
|
680
|
+
positionTime: h.posTime,
|
|
681
681
|
utc: y.utc().format(),
|
|
682
|
-
status:
|
|
682
|
+
status: h.aisNavStatus,
|
|
683
683
|
labelEn: d,
|
|
684
684
|
labelCn: l,
|
|
685
685
|
method: "position",
|
|
@@ -687,13 +687,13 @@ class Dt extends nt {
|
|
|
687
687
|
};
|
|
688
688
|
}
|
|
689
689
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
690
|
-
const r = v(a),
|
|
691
|
-
for (;
|
|
690
|
+
const r = v(a), h = v(i), l = await this.getShipId(t), d = await this.getShipInfo(l), y = [];
|
|
691
|
+
for (; h.diff(r, "day", !0) > 30; )
|
|
692
692
|
await this.trajectoryIn30Day(l, r.unix(), r.add(30, "day").unix(), d, t, n, y);
|
|
693
|
-
return await this.trajectoryIn30Day(l, r.unix(),
|
|
693
|
+
return await this.trajectoryIn30Day(l, r.unix(), h.unix(), d, t, n, y), y;
|
|
694
694
|
}
|
|
695
|
-
async trajectoryIn30Day(t, a, i, n, o, e, r,
|
|
696
|
-
var
|
|
695
|
+
async trajectoryIn30Day(t, a, i, n, o, e, r, h = {}) {
|
|
696
|
+
var j;
|
|
697
697
|
const l = {
|
|
698
698
|
headers: {
|
|
699
699
|
appKey: this.token
|
|
@@ -704,41 +704,41 @@ class Dt extends nt {
|
|
|
704
704
|
endTime: i
|
|
705
705
|
}
|
|
706
706
|
}, d = "https://api3.myships.com/sp/ships/position/history", y = await B.post(d, l).json();
|
|
707
|
-
if (M == null || M.info("[%s] fetch trajectory from: %s - %j",
|
|
708
|
-
return M == null || M.warn("[%s] invoke myship trajectory failed: %j",
|
|
707
|
+
if (M == null || M.info("[%s] fetch trajectory from: %s - %j", h.requestId, d, l), y.code !== "0")
|
|
708
|
+
return M == null || M.warn("[%s] invoke myship trajectory failed: %j", h.requestId, y), y;
|
|
709
709
|
const w = y.data;
|
|
710
|
-
for (const
|
|
711
|
-
!isNaN(w[
|
|
712
|
-
const g = v.unix((
|
|
710
|
+
for (const p in w)
|
|
711
|
+
!isNaN(w[p]) && Number(w[p]) !== 1 / 0 && (w[p] = Number(w[p]));
|
|
712
|
+
const g = v.unix((j = w[0]) == null ? void 0 : j.posTime);
|
|
713
713
|
let k = -1;
|
|
714
|
-
for (const
|
|
715
|
-
const
|
|
714
|
+
for (const p of w) {
|
|
715
|
+
const b = v.unix(p.posTime), f = {
|
|
716
716
|
imo: n == null ? void 0 : n.imo,
|
|
717
717
|
mmsi: o,
|
|
718
|
-
lat: Math.round(
|
|
719
|
-
lng: Math.round(
|
|
720
|
-
sog: Math.round(
|
|
721
|
-
cog: Math.round(
|
|
722
|
-
hdg: Math.round(
|
|
723
|
-
rot: Math.round(
|
|
724
|
-
positionTime:
|
|
725
|
-
utc:
|
|
718
|
+
lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
719
|
+
lng: Math.round(p.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
720
|
+
sog: Math.round(p.sog / 10 * 100) / 100,
|
|
721
|
+
cog: Math.round(p.cog / 10 * 100) / 100,
|
|
722
|
+
hdg: Math.round(p.heading * 100) / 100,
|
|
723
|
+
rot: Math.round(p.rot * 100) / 100,
|
|
724
|
+
positionTime: b.unix(),
|
|
725
|
+
utc: b.utc().format(),
|
|
726
726
|
method: "trajectory",
|
|
727
727
|
vendor: "myship"
|
|
728
|
-
},
|
|
729
|
-
|
|
728
|
+
}, u = Math.floor(b.diff(g, "minute", !0) / (e || 1));
|
|
729
|
+
u !== k && (k = u, r.push(f));
|
|
730
730
|
}
|
|
731
731
|
return r;
|
|
732
732
|
}
|
|
733
733
|
}
|
|
734
734
|
let _;
|
|
735
735
|
try {
|
|
736
|
-
_ =
|
|
736
|
+
_ = ht.getLogger("vessel");
|
|
737
737
|
} catch {
|
|
738
738
|
} finally {
|
|
739
739
|
}
|
|
740
|
-
var
|
|
741
|
-
class
|
|
740
|
+
var gt = /* @__PURE__ */ ((D) => (D.NOTICE = "NOTICE", D.WARN = "WARN", D.HEAVY = "HEAVY", D.SEVERE = "SEVERE", D.ERROR = "ERROR", D.FATAL = "FATAL", D))(gt || {});
|
|
741
|
+
class pt {
|
|
742
742
|
/**
|
|
743
743
|
* 解析告警规则, 多规则场景
|
|
744
744
|
* @param rule
|
|
@@ -748,14 +748,14 @@ class gt {
|
|
|
748
748
|
* @param options
|
|
749
749
|
*/
|
|
750
750
|
parsePrinciple(s, t = {}) {
|
|
751
|
-
var e, r,
|
|
751
|
+
var e, r, h;
|
|
752
752
|
_ == null || _.debug("[%s] parse rule: %s", t.requestId, s);
|
|
753
753
|
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = s.match(a) ? (e = s.match(a)) == null ? void 0 : e[0] : void 0, n = i == null ? void 0 : i.split(";");
|
|
754
754
|
if (!n)
|
|
755
755
|
return;
|
|
756
756
|
const o = {};
|
|
757
757
|
for (let l = 0; l < (n == null ? void 0 : n.length); l++) {
|
|
758
|
-
const d = (
|
|
758
|
+
const d = (h = (r = n[l].match(a)) == null ? void 0 : r[0]) == null ? void 0 : h.split("],");
|
|
759
759
|
if (l === 0 && !d)
|
|
760
760
|
o.scope = n[0];
|
|
761
761
|
else if (d)
|
|
@@ -794,25 +794,25 @@ class gt {
|
|
|
794
794
|
* @param options
|
|
795
795
|
*/
|
|
796
796
|
checkWeather(s, t, a = {}) {
|
|
797
|
-
var g, k,
|
|
797
|
+
var g, k, j, p, b, f, u, m, c, I, C, F, Y, A, H;
|
|
798
798
|
let i = 0, n = 0, o = 0, e = 0;
|
|
799
|
-
const r = Math.round(((k = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.sigWave) == null ? void 0 : k.number) * 1.6 * 100) / 100,
|
|
800
|
-
for (let
|
|
801
|
-
const N = s[
|
|
802
|
-
e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...
|
|
799
|
+
const r = Math.round(((k = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.sigWave) == null ? void 0 : k.number) * 1.6 * 100) / 100, h = (p = (j = t == null ? void 0 : t.SEVERE) == null ? void 0 : j.sigWave) == null ? void 0 : p.number, l = (f = (b = t == null ? void 0 : t.HEAVY) == null ? void 0 : b.sigWave) == null ? void 0 : f.number, d = Math.round((((m = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : m.number) + 2) * 100) / 100, y = (I = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : I.number, w = (F = (C = t == null ? void 0 : t.HEAVY) == null ? void 0 : C.wind) == null ? void 0 : F.number;
|
|
800
|
+
for (let E = 0; E < (s == null ? void 0 : s.length); E++) {
|
|
801
|
+
const N = s[E], O = (A = (Y = N == null ? void 0 : N.meteo) == null ? void 0 : Y.wave) == null ? void 0 : A.sig, R = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wind, J = E ? v(N.eta).diff(v(s[E - 1].eta), "hour", !0) : 0;
|
|
802
|
+
e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...O, dgThd4Wv: r, svThd4Wv: h, hvThd4Wv: l }), (O == null ? void 0 : O.height) >= r ? N.isDangerous = !0 : (O == null ? void 0 : O.height) >= h ? N.isSevere = !0 : (O == null ? void 0 : O.height) >= l && (N.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }), (R == null ? void 0 : R.scale) >= d ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > y ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === w && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? J : 0, n += N.isSevere ? J : 0, o += N.isHeavy ? J : 0;
|
|
803
803
|
}
|
|
804
|
-
return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, e = Math.round(e), { sample: s, dangerous: i, severe: n, heavy: o, step: e < 3 ? 3 : e, wind: { dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv:
|
|
804
|
+
return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, e = Math.round(e), { sample: s, dangerous: i, severe: n, heavy: o, step: e < 3 ? 3 : e, wind: { dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv: h, hvThd4Wv: l } };
|
|
805
805
|
}
|
|
806
806
|
}
|
|
807
|
-
const
|
|
808
|
-
let
|
|
807
|
+
const Pt = new pt();
|
|
808
|
+
let T;
|
|
809
809
|
try {
|
|
810
|
-
|
|
810
|
+
T = ht.getLogger("vessel");
|
|
811
811
|
} catch {
|
|
812
812
|
} finally {
|
|
813
813
|
}
|
|
814
|
-
const bt = new
|
|
815
|
-
var
|
|
814
|
+
const bt = new Mt("", !0);
|
|
815
|
+
var vt = /* @__PURE__ */ ((D) => (D.common = "common", D.container = "container", D.tugs = "tugs", D))(vt || {}), wt = /* @__PURE__ */ ((D) => (D.Ballast = "Ballast", D.Laden = "Laden", D))(wt || {}), kt = /* @__PURE__ */ ((D) => (D.Cp = "CP", D.Perf = "Basis", D.Instruct = "Other", D))(kt || {});
|
|
816
816
|
class W {
|
|
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
|
|
@@ -927,9 +927,9 @@ class W {
|
|
|
927
927
|
*/
|
|
928
928
|
static assembleProperties(s, t, a, i) {
|
|
929
929
|
var y;
|
|
930
|
-
const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, o = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, r = s.deadweight ?? 67035.7773,
|
|
930
|
+
const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, o = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, r = s.deadweight ?? 67035.7773, h = ((y = s == null ? void 0 : s.type) == null ? void 0 : y.toLowerCase()) || "common";
|
|
931
931
|
return {
|
|
932
|
-
tag:
|
|
932
|
+
tag: h.indexOf("container") > -1 ? "container" : h.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
933
933
|
lbp: n,
|
|
934
934
|
loadCondition: t,
|
|
935
935
|
draught: o,
|
|
@@ -954,24 +954,24 @@ class W {
|
|
|
954
954
|
* @param options
|
|
955
955
|
*/
|
|
956
956
|
static async speedLoseAt(s, t, a, i = "", n = 2, o = !0, e = !1, r = {}) {
|
|
957
|
-
let
|
|
957
|
+
let h;
|
|
958
958
|
if (t.velocity && e && (s.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
|
|
959
959
|
let l;
|
|
960
960
|
try {
|
|
961
961
|
i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
|
|
962
|
-
const { weatherModels: g, marineModels: k } = await
|
|
962
|
+
const { weatherModels: g, marineModels: k } = await ut.autoPickMeteoModel(i), j = await bt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
|
|
963
963
|
...r,
|
|
964
964
|
pastDays: 1,
|
|
965
965
|
forecastDays: 1,
|
|
966
966
|
weatherModels: g,
|
|
967
967
|
marineModels: k
|
|
968
|
-
}), [
|
|
969
|
-
l =
|
|
968
|
+
}), [p] = ut.pickHourly(j, a);
|
|
969
|
+
l = ut.toLegacy(p);
|
|
970
970
|
} catch (g) {
|
|
971
|
-
|
|
971
|
+
T.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: i }, g);
|
|
972
972
|
}
|
|
973
973
|
const d = W.currentFactor(s.bearing, l == null ? void 0 : l.current, n), y = W.weatherFactor(s, l, d), w = Math.round((s.speed * 1.943844 + y + d) * 100) / 100;
|
|
974
|
-
|
|
974
|
+
h = {
|
|
975
975
|
meteo: { ...l },
|
|
976
976
|
wxFactor: y,
|
|
977
977
|
cFactor: d,
|
|
@@ -980,14 +980,14 @@ class W {
|
|
|
980
980
|
etd: a.utc().format()
|
|
981
981
|
};
|
|
982
982
|
} else
|
|
983
|
-
|
|
983
|
+
h = {
|
|
984
984
|
wxFactor: 0,
|
|
985
985
|
cFactor: 0,
|
|
986
986
|
speed: t.velocity && e ? t.velocity : Math.round(s.speed * 1.943844 * 100) / 100,
|
|
987
987
|
eta: a.utc().format(),
|
|
988
988
|
etd: a.utc().format()
|
|
989
989
|
};
|
|
990
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
990
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...h, ...t };
|
|
991
991
|
}
|
|
992
992
|
/**
|
|
993
993
|
* 基于步长计算失速样本
|
|
@@ -1003,53 +1003,53 @@ class W {
|
|
|
1003
1003
|
* @param options
|
|
1004
1004
|
* @private
|
|
1005
1005
|
*/
|
|
1006
|
-
static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", r = !0,
|
|
1006
|
+
static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", r = !0, h = !1, l = {}) {
|
|
1007
1007
|
t.utc();
|
|
1008
1008
|
const d = t.clone().add(14, "days"), y = [], w = [], g = [];
|
|
1009
|
-
let k = 0,
|
|
1009
|
+
let k = 0, j = 0, p, b;
|
|
1010
1010
|
for (let f = 0; f < o.length - 1; f++) {
|
|
1011
|
-
let
|
|
1012
|
-
|
|
1011
|
+
let u = o[f];
|
|
1012
|
+
u.distanceFromStart = Math.round((n + j) * 1e3) / 1e3;
|
|
1013
1013
|
const m = o[f + 1];
|
|
1014
|
-
if (s.bearing = V.calculateBearing(
|
|
1015
|
-
|
|
1016
|
-
const C =
|
|
1014
|
+
if (s.bearing = V.calculateBearing(u, m, !m.gcToPrevious), u.bearing = s.bearing, u.suspend && h) {
|
|
1015
|
+
u.eta = u.eta || t.utc().format(), u.elapsed = u.elapsed ?? 0;
|
|
1016
|
+
const C = u.suspend - u.elapsed;
|
|
1017
1017
|
if (i - k > C)
|
|
1018
|
-
i = i - k - C, t.add(C, "hour"),
|
|
1018
|
+
i = i - k - C, t.add(C, "hour"), u.elapsed = u.suspend;
|
|
1019
1019
|
else {
|
|
1020
1020
|
const F = i - k;
|
|
1021
|
-
|
|
1021
|
+
u.elapsed += F, t.add(F, "hour"), i = 0;
|
|
1022
1022
|
}
|
|
1023
|
-
if (
|
|
1024
|
-
return
|
|
1023
|
+
if (T == null || T.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`, l.requestId, u), i === 0)
|
|
1024
|
+
return u.distanceFromPrevious = j, { etd: t, from: b || u, to: u, next: o.filter((F) => F), wps: y, days: w, all: g };
|
|
1025
1025
|
} else
|
|
1026
|
-
|
|
1027
|
-
r = t.isAfter(d) ? !1 : r,
|
|
1028
|
-
const c = V.calculateDistance(
|
|
1029
|
-
let I = Math.round(c /
|
|
1026
|
+
u.suspend = 0;
|
|
1027
|
+
r = t.isAfter(d) ? !1 : r, u = await W.speedLoseAt(s, u, t, e, 0, r, h, l), g.push(u), b = b || u, u.important && y.push(u), t.isSameOrAfter(a) && (w.push(u), a.add(24, "hour"));
|
|
1028
|
+
const c = V.calculateDistance(u, m, !m.gcToPrevious);
|
|
1029
|
+
let I = Math.round(c / b.speed * 1e5) / 1e5;
|
|
1030
1030
|
if (k + I < i) {
|
|
1031
|
-
if (k += I, t.add(I, "hour"), delete o[f],
|
|
1031
|
+
if (k += I, t.add(I, "hour"), delete o[f], T == null || T.debug(
|
|
1032
1032
|
`[%s] go to %j from %j with ${c}nm, and cost ${I} hours`,
|
|
1033
1033
|
l.requestId,
|
|
1034
1034
|
{ lat: m.lat, lng: m.lng },
|
|
1035
|
-
{ lat:
|
|
1036
|
-
),
|
|
1037
|
-
|
|
1035
|
+
{ lat: b.lat, lng: b.lng, etd: b.etd }
|
|
1036
|
+
), j += c, o.filter((C) => C).length <= 1) {
|
|
1037
|
+
p = m, p.eta = t.utc().format(), p.distanceFromPrevious = c, p.distanceFromStart = Math.round((n + j) * 1e4) / 1e4, y.push(p), g.push(p), delete o[f + 1];
|
|
1038
1038
|
break;
|
|
1039
1039
|
}
|
|
1040
1040
|
} else {
|
|
1041
1041
|
I = i - k, t.add(I, "hour");
|
|
1042
|
-
const C = z.roundPrecision(
|
|
1043
|
-
|
|
1042
|
+
const C = z.roundPrecision(b.speed * I, 5);
|
|
1043
|
+
p = V.calculateCoordinate(u, s.bearing, C, "nauticalmiles", !m.gcToPrevious), p.eta = t.utc().format(), o[f] = p, T == null || T.debug(
|
|
1044
1044
|
`[%s] go to %j from %j with ${C}nm, and cost ${I} hours`,
|
|
1045
1045
|
l.requestId,
|
|
1046
|
-
{ lat:
|
|
1047
|
-
{ lat:
|
|
1048
|
-
),
|
|
1046
|
+
{ lat: p.lat, lng: p.lng },
|
|
1047
|
+
{ lat: u.lat, lng: u.lng, etd: u.etd }
|
|
1048
|
+
), j += C, p.distanceFromPrevious = Math.round(j * 1e4) / 1e4, p.distanceFromStart = Math.round((n + j) * 1e4) / 1e4;
|
|
1049
1049
|
break;
|
|
1050
1050
|
}
|
|
1051
1051
|
}
|
|
1052
|
-
return { etd: t, from:
|
|
1052
|
+
return { etd: t, from: b, to: p, next: o.filter((f) => f), wps: y, days: w, all: g };
|
|
1053
1053
|
}
|
|
1054
1054
|
/**
|
|
1055
1055
|
* 洋流影响因子
|
|
@@ -1071,16 +1071,16 @@ class W {
|
|
|
1071
1071
|
* @param cFactor 洋流因子
|
|
1072
1072
|
*/
|
|
1073
1073
|
static weatherFactor(s, t, a = 0) {
|
|
1074
|
-
var w, g, k,
|
|
1075
|
-
|
|
1074
|
+
var w, g, k, j, p, b, f;
|
|
1075
|
+
T == null || T.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
1076
1076
|
const i = W.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = W.froudeNumber(s.speed - n, s.lbp), e = W.amendFactor(i, o, s.loadCondition);
|
|
1077
1077
|
let r = Math.abs(s.bearing % 360 - (((w = t == null ? void 0 : t.wind) == null ? void 0 : w.degree) % 360 || 0));
|
|
1078
1078
|
r = r > 180 ? 360 - r : r;
|
|
1079
|
-
const
|
|
1080
|
-
let d =
|
|
1081
|
-
d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)),
|
|
1082
|
-
const y = W.waveHeightFactor(((f = (
|
|
1083
|
-
return
|
|
1079
|
+
const h = W.directionFactor(r, (g = t == null ? void 0 : t.wind) == null ? void 0 : g.scale), l = W.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.kts);
|
|
1080
|
+
let d = h * e * l / 100 * (s.speed - n);
|
|
1081
|
+
d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), T == null || T.debug("wind wx factor = %d", d), r = Math.abs(s.bearing % 360 - (((p = (j = t == null ? void 0 : t.wave) == null ? void 0 : j.sig) == null ? void 0 : p.degree) % 360 || 0)), r = r > 180 ? 360 - r : r;
|
|
1082
|
+
const y = W.waveHeightFactor(((f = (b = t == null ? void 0 : t.wave) == null ? void 0 : b.sig) == null ? void 0 : f.height) ?? 1, r);
|
|
1083
|
+
return T == null || T.debug("wave wx factor = %d", y), d = Math.abs(d) > Math.abs(y) ? d : d * 0.3 + y * 0.7, T == null || T.debug("weather factor = %d", 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;
|
|
1084
1084
|
}
|
|
1085
1085
|
/**
|
|
1086
1086
|
* 全程失速分析(走完航程)
|
|
@@ -1095,14 +1095,14 @@ class W {
|
|
|
1095
1095
|
* @param useRouteParam
|
|
1096
1096
|
* @param options
|
|
1097
1097
|
*/
|
|
1098
|
-
static async analyseInstant(s, t, a, i, n, o = "", e = 0, r = !0,
|
|
1099
|
-
var U, G, X, Q, Z, $, tt;
|
|
1098
|
+
static async analyseInstant(s, t, a, i, n, o = "", e = 0, r = !0, h = !1, l = {}) {
|
|
1099
|
+
var U, G, X, Q, Z, $, tt, et;
|
|
1100
1100
|
const d = v().valueOf();
|
|
1101
1101
|
s.lng = z.convertToStdLng(s.lng);
|
|
1102
1102
|
const { route: y, waypoints: w } = n.points, g = V.calculateSubRoute(s, y);
|
|
1103
1103
|
if (((U = g[0]) == null ? void 0 : U.length) <= 1)
|
|
1104
1104
|
return;
|
|
1105
|
-
const { v0: k, label:
|
|
1105
|
+
const { v0: k, label: j } = s.sog ? {
|
|
1106
1106
|
v0: s.sog,
|
|
1107
1107
|
label: s.label || "Other"
|
|
1108
1108
|
/* Instruct */
|
|
@@ -1110,69 +1110,69 @@ class W {
|
|
|
1110
1110
|
v0: i.speed,
|
|
1111
1111
|
label: "CP"
|
|
1112
1112
|
/* Cp */
|
|
1113
|
-
},
|
|
1114
|
-
|
|
1113
|
+
}, p = W.assembleProperties(a, i.loadCondition, k, 0), b = w.length ? V.calculateSubWaypoints(s, w) : [];
|
|
1114
|
+
b.forEach((x) => x.important = !0);
|
|
1115
1115
|
const f = {
|
|
1116
1116
|
from: { ...s },
|
|
1117
1117
|
route: g,
|
|
1118
|
-
waypoints:
|
|
1118
|
+
waypoints: b,
|
|
1119
1119
|
v0: k,
|
|
1120
|
-
label:
|
|
1121
|
-
},
|
|
1120
|
+
label: j
|
|
1121
|
+
}, u = {
|
|
1122
1122
|
hours: [],
|
|
1123
1123
|
days: [],
|
|
1124
1124
|
wps: [],
|
|
1125
1125
|
all: []
|
|
1126
1126
|
};
|
|
1127
1127
|
e || (V.calculateRouteDistance(g) / i.speed <= 72 ? e = 3 : e = 6);
|
|
1128
|
-
let m = V.simplifyRouteToCoordinates(g,
|
|
1128
|
+
let m = V.simplifyRouteToCoordinates(g, b, 0), c = 0, I = 0, C = 0, F = 0;
|
|
1129
1129
|
t = v(t).utc();
|
|
1130
|
-
const
|
|
1130
|
+
const Y = t.clone();
|
|
1131
1131
|
for (; m.length > 0; ) {
|
|
1132
|
-
const
|
|
1133
|
-
|
|
1132
|
+
const x = e - t.hour() % e, L = Math.ceil(t.clone().add(x, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, S = await W.speedLoseInHoursStep(
|
|
1133
|
+
p,
|
|
1134
1134
|
t,
|
|
1135
|
-
|
|
1136
|
-
|
|
1135
|
+
Y,
|
|
1136
|
+
L,
|
|
1137
1137
|
c,
|
|
1138
1138
|
m,
|
|
1139
1139
|
o,
|
|
1140
1140
|
r,
|
|
1141
|
-
|
|
1141
|
+
h,
|
|
1142
1142
|
l
|
|
1143
1143
|
);
|
|
1144
|
-
if (
|
|
1145
|
-
const
|
|
1146
|
-
|
|
1144
|
+
if (u.all.push(...S.all), (G = S.from) != null && G.speed && (u.hours.push(S.from), u.wps.push(...S.wps), u.days.push(...S.days)), m = S == null ? void 0 : S.next, !m.length) {
|
|
1145
|
+
const q = await W.speedLoseAt(p, S.to, v(S.to.eta), o, 0, r, h, l);
|
|
1146
|
+
q.bearing = p.bearing, u.hours.push(q), u.all.push(q);
|
|
1147
1147
|
}
|
|
1148
1148
|
c += Math.round((((X = S == null ? void 0 : S.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
1149
1149
|
}
|
|
1150
|
-
const
|
|
1151
|
-
for (let
|
|
1152
|
-
const
|
|
1153
|
-
I += (
|
|
1150
|
+
const A = u.hours;
|
|
1151
|
+
for (let x = 0; x < A.length - 1; x++) {
|
|
1152
|
+
const L = v(A[x + 1].eta).diff(A[x].etd, "hour", !0) || 1;
|
|
1153
|
+
I += (A[x].wxFactor || 0) * L, C += (A[x].cFactor || 0) * L, F += L;
|
|
1154
1154
|
}
|
|
1155
|
-
const H =
|
|
1156
|
-
(Q =
|
|
1157
|
-
|
|
1158
|
-
const S =
|
|
1155
|
+
const H = A.reduce((x, L) => x + (L.suspend || 0), 0);
|
|
1156
|
+
(Q = u.wps) == null || Q.forEach((x, L) => {
|
|
1157
|
+
x.positionTime = v.utc(x.etd || x.eta).unix();
|
|
1158
|
+
const S = u.wps[L - 1];
|
|
1159
1159
|
if (S) {
|
|
1160
|
-
const
|
|
1161
|
-
|
|
1160
|
+
const q = x.distanceFromStart - S.distanceFromStart, P = v(x.eta || x.etd).diff(v(S.etd || S.eta), "h", !0);
|
|
1161
|
+
x.avgSpd = Math.round(q / P * 100) / 100, S.bearing = V.calculateBearing(S, x);
|
|
1162
1162
|
}
|
|
1163
|
-
}),
|
|
1164
|
-
const
|
|
1165
|
-
f.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, f.etd = v(
|
|
1166
|
-
const
|
|
1163
|
+
}), u.wps = (Z = u.wps) == null ? void 0 : Z.reduce((x, L) => (x.some((S) => Math.round(S.positionTime / 60) === Math.round(L.positionTime / 60)) || x.push(L), x), []), u.days = ($ = u.days) == null ? void 0 : $.reduce((x, L) => (x.some((S) => Math.round(S.positionTime / (60 * 60 * 12)) === Math.round(L.positionTime / (60 * 60 * 12))) || x.push(L), x), []), u.all = (tt = u.all) == null ? void 0 : tt.reduce((x, L) => (L.positionTime = v.utc(L.etd || L.eta).unix(), x.some((S) => Math.round(S.positionTime / 60) === Math.round(L.positionTime / 60)) || x.push(L), x), []), f.sample = u;
|
|
1164
|
+
const E = u.hours.at(0), N = u.hours.at(-1);
|
|
1165
|
+
f.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, f.etd = v(E.eta).utc().format(), f.eta = v(N.eta).utc().format(), f.wxFactor = Math.round(I / F * 1e3) / 1e3, f.cFactor = Math.round(C / F * 1e3) / 1e3, f.avgSpeed = Math.round(N.distanceFromStart / F * 1e3) / 1e3, f.totalHrs = Math.round(F * 1e3) / 1e3, f.suspend = Math.round(H * 1e3) / 1e3;
|
|
1166
|
+
const O = z.roundPrecision(i.dgo / 24 * H, 3), { distanceInECA: R, hoursInECA: J, totalDgoConsInECA: it, eca: st } = await this.calculateECA(f, i, l), at = z.roundPrecision(i.fo / 24 * (F - J), 3), rt = z.roundPrecision(i.dgo / 24 * F + O, 3);
|
|
1167
1167
|
f.extend = {
|
|
1168
|
-
eca:
|
|
1169
|
-
distanceInECA:
|
|
1168
|
+
eca: st,
|
|
1169
|
+
distanceInECA: R,
|
|
1170
1170
|
hoursInECA: J,
|
|
1171
|
-
totalDgoConsInECA:
|
|
1172
|
-
totalDgoConsInSuspend:
|
|
1173
|
-
}, f.totalFoCons =
|
|
1174
|
-
const
|
|
1175
|
-
return
|
|
1171
|
+
totalDgoConsInECA: it,
|
|
1172
|
+
totalDgoConsInSuspend: O
|
|
1173
|
+
}, f.totalFoCons = at < 0 ? 0 : at, f.totalDgoCons = rt;
|
|
1174
|
+
const nt = v().valueOf() - d, dt = ((et = u == null ? void 0 : u.hours) == null ? void 0 : et.length) || 1;
|
|
1175
|
+
return T == null || T.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, nt, dt, Math.round(nt / dt * 1e3) / 1e3), f;
|
|
1176
1176
|
}
|
|
1177
1177
|
/**
|
|
1178
1178
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -1189,8 +1189,8 @@ class W {
|
|
|
1189
1189
|
* @param useRouteParam
|
|
1190
1190
|
* @param options
|
|
1191
1191
|
*/
|
|
1192
|
-
static async analyseInstantWithThreshed(s, t, a, i, n, o, e, r = "",
|
|
1193
|
-
var X, Q, Z, $, tt,
|
|
1192
|
+
static async analyseInstantWithThreshed(s, t, a, i, n, o, e, r = "", h = 3, l = !0, d = !1, y = {}) {
|
|
1193
|
+
var X, Q, Z, $, tt, et, x, L;
|
|
1194
1194
|
const w = v().valueOf();
|
|
1195
1195
|
s.lng = z.convertToStdLng(s.lng);
|
|
1196
1196
|
const { v0: g, label: k } = s.sog ? {
|
|
@@ -1201,12 +1201,12 @@ class W {
|
|
|
1201
1201
|
v0: n.speed,
|
|
1202
1202
|
label: "CP"
|
|
1203
1203
|
/* Cp */
|
|
1204
|
-
},
|
|
1205
|
-
if (((X =
|
|
1204
|
+
}, j = W.assembleProperties(i, n.loadCondition, g, 0), p = V.calculateSubRoute(s, o);
|
|
1205
|
+
if (((X = p[0]) == null ? void 0 : X.length) <= 1)
|
|
1206
1206
|
return;
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
let f = V.simplifyRouteToCoordinates(
|
|
1207
|
+
const b = e.length ? V.calculateSubWaypoints(s, e) : [];
|
|
1208
|
+
b.forEach((S) => S.important = !0);
|
|
1209
|
+
let f = V.simplifyRouteToCoordinates(p, b, 0), u = 0, m = 0, c = 0, I = 0;
|
|
1210
1210
|
const C = {
|
|
1211
1211
|
hours: [],
|
|
1212
1212
|
wps: [],
|
|
@@ -1216,52 +1216,52 @@ class W {
|
|
|
1216
1216
|
t = v(t).utc();
|
|
1217
1217
|
const F = t.clone();
|
|
1218
1218
|
for (; f.length > 0; ) {
|
|
1219
|
-
const S =
|
|
1220
|
-
let
|
|
1221
|
-
|
|
1222
|
-
const P = await W.speedLoseInHoursStep(
|
|
1223
|
-
if (C.all.push(...P.all), (Q = P.from) != null && Q.speed && (C.hours.push(P.from), P != null && P.wps && C.wps.push(...P.wps), C.days.push(...P.days)), f = P == null ? void 0 : P.next, f.length || C.hours.push(P == null ? void 0 : P.to),
|
|
1219
|
+
const S = h - t.hour() % h;
|
|
1220
|
+
let q = Math.ceil(t.clone().add(S, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
1221
|
+
q = t.clone().add(q, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : q;
|
|
1222
|
+
const P = await W.speedLoseInHoursStep(j, t, F, q, u, f, r, l, d, y);
|
|
1223
|
+
if (C.all.push(...P.all), (Q = P.from) != null && Q.speed && (C.hours.push(P.from), P != null && P.wps && C.wps.push(...P.wps), C.days.push(...P.days)), f = P == null ? void 0 : P.next, f.length || C.hours.push(P == null ? void 0 : P.to), u += Math.round((((Z = P == null ? void 0 : P.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !q)
|
|
1224
1224
|
break;
|
|
1225
1225
|
}
|
|
1226
|
-
C.wps = ($ = C.wps) == null ? void 0 : $.reduce((S,
|
|
1227
|
-
const P = C.wps[
|
|
1226
|
+
C.wps = ($ = C.wps) == null ? void 0 : $.reduce((S, q) => (S.some((P) => Math.round(v(P.etd).unix() / 60) === Math.round(v(q.etd).unix() / 60)) || S.push(q), S), []), C.days = (tt = C.days) == null ? void 0 : tt.reduce((S, q) => (S.some((P) => Math.round(P.positionTime / (60 * 60 * 12)) === Math.round(q.positionTime / (60 * 60 * 12))) || S.push(q), S), []), C.all = (et = C.all) == null ? void 0 : et.reduce((S, q) => (q.positionTime = v.utc(q.etd || q.eta).unix(), S.some((P) => Math.round(v(P.etd).unix() / 60) === Math.round(v(q.etd).unix() / 60)) || S.push(q), S), []), (x = C.wps) == null || x.forEach((S, q) => {
|
|
1227
|
+
const P = C.wps[q - 1];
|
|
1228
1228
|
if (P) {
|
|
1229
|
-
const
|
|
1230
|
-
S.avgSpd = Math.round(
|
|
1229
|
+
const lt = S.distanceFromStart - P.distanceFromStart, mt = v(S.eta || S.etd).diff(v(P.etd || P.eta), "h", !0);
|
|
1230
|
+
P.bearing = V.calculateBearing(P, S), S.avgSpd = Math.round(lt / mt * 100) / 100;
|
|
1231
1231
|
}
|
|
1232
1232
|
});
|
|
1233
|
-
const
|
|
1234
|
-
for (let S = 0; S <
|
|
1235
|
-
const
|
|
1236
|
-
m +=
|
|
1233
|
+
const Y = C.hours;
|
|
1234
|
+
for (let S = 0; S < Y.length - 1; S++) {
|
|
1235
|
+
const q = v(Y[S + 1].eta).diff(Y[S].etd, "hour", !0);
|
|
1236
|
+
m += Y[S].wxFactor * q, c += Y[S].cFactor * q, I += q;
|
|
1237
1237
|
}
|
|
1238
|
-
const
|
|
1238
|
+
const A = Y.reduce((S, q) => S + (q.suspend || 0), 0), H = C.hours.at(0), E = C.hours.at(-1), N = await V.calculateRangeRoute(H, E, p), O = await V.calculateRangeWaypoints(H, E, p, b), R = {
|
|
1239
1239
|
sample: C,
|
|
1240
|
-
distance: Math.round(((
|
|
1240
|
+
distance: Math.round(((E == null ? void 0 : E.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1241
1241
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1242
1242
|
etd: v(H.eta).utc().format(),
|
|
1243
|
-
eta: v(
|
|
1243
|
+
eta: v(E == null ? void 0 : E.eta).utc().format(),
|
|
1244
1244
|
wxFactor: Math.round(m / I * 1e3) / 1e3,
|
|
1245
1245
|
cFactor: Math.round(c / I * 1e3) / 1e3,
|
|
1246
|
-
avgSpeed: Math.round(((
|
|
1246
|
+
avgSpeed: Math.round(((E == null ? void 0 : E.distanceFromStart) || 0) / I * 1e3) / 1e3,
|
|
1247
1247
|
totalHrs: Math.round(I * 1e3) / 1e3,
|
|
1248
|
-
suspend: Math.round(
|
|
1248
|
+
suspend: Math.round(A * 1e3) / 1e3,
|
|
1249
1249
|
from: H,
|
|
1250
|
-
to:
|
|
1250
|
+
to: E,
|
|
1251
1251
|
route: N,
|
|
1252
|
-
waypoints:
|
|
1252
|
+
waypoints: O,
|
|
1253
1253
|
v0: g,
|
|
1254
1254
|
label: k
|
|
1255
|
-
}, J = z.roundPrecision(n.dgo / 24 *
|
|
1256
|
-
|
|
1257
|
-
eca:
|
|
1258
|
-
distanceInECA:
|
|
1259
|
-
hoursInECA:
|
|
1260
|
-
totalDgoConsInECA:
|
|
1255
|
+
}, J = z.roundPrecision(n.dgo / 24 * A, 3), { distanceInECA: it, hoursInECA: st, totalDgoConsInECA: at, eca: rt } = await this.calculateECA(R, n, y), ct = z.roundPrecision(n.fo / 24 * (I - st), 3), nt = z.roundPrecision(n.dgo / 24 * I + J, 3);
|
|
1256
|
+
R.extend = {
|
|
1257
|
+
eca: rt,
|
|
1258
|
+
distanceInECA: it,
|
|
1259
|
+
hoursInECA: st,
|
|
1260
|
+
totalDgoConsInECA: at,
|
|
1261
1261
|
totalDgoConsInSuspend: J
|
|
1262
|
-
},
|
|
1263
|
-
const U = v().valueOf() - w, G = ((
|
|
1264
|
-
return
|
|
1262
|
+
}, R.totalDgoCons = nt, R.totalFoCons = ct < 0 ? 0 : ct;
|
|
1263
|
+
const U = v().valueOf() - w, G = ((L = C == null ? void 0 : C.hours) == null ? void 0 : L.length) || 1;
|
|
1264
|
+
return T == null || T.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", y == null ? void 0 : y.requestId, U, G, Math.round(U / G * 1e3) / 1e3), R;
|
|
1265
1265
|
}
|
|
1266
1266
|
/**
|
|
1267
1267
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1279,25 +1279,25 @@ class W {
|
|
|
1279
1279
|
* @param options
|
|
1280
1280
|
*/
|
|
1281
1281
|
static async analyseCost(s, t, a, i, n = {}) {
|
|
1282
|
-
var
|
|
1282
|
+
var p, b;
|
|
1283
1283
|
const o = v().valueOf(), e = [];
|
|
1284
1284
|
s.speedStep = s.speedStep || 3, s.alterStep = s.alterStep ?? 1;
|
|
1285
1285
|
const r = V.calculateRouteDistance(i.route);
|
|
1286
|
-
let
|
|
1286
|
+
let h = 0;
|
|
1287
1287
|
a.forEach((f) => {
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1290
|
-
}),
|
|
1291
|
-
const l = v.utc(s.etd).add(
|
|
1288
|
+
const u = Math.ceil(r / f.speed / 24);
|
|
1289
|
+
h = h < u ? u : h;
|
|
1290
|
+
}), h = h * 1.3;
|
|
1291
|
+
const l = v.utc(s.etd).add(h ?? 14, "day");
|
|
1292
1292
|
let d = 1;
|
|
1293
1293
|
for (const f of a) {
|
|
1294
|
-
const
|
|
1294
|
+
const u = JSON.parse(JSON.stringify(i.route)), m = JSON.parse(JSON.stringify(i.waypoints)), c = await W.analyseInstantWithThreshed(
|
|
1295
1295
|
{ lat: s.lat, lng: s.lng },
|
|
1296
1296
|
s.etd,
|
|
1297
1297
|
l,
|
|
1298
1298
|
t,
|
|
1299
1299
|
f,
|
|
1300
|
-
|
|
1300
|
+
u,
|
|
1301
1301
|
m,
|
|
1302
1302
|
s.meteoVendor,
|
|
1303
1303
|
s.speedStep,
|
|
@@ -1305,7 +1305,7 @@ class W {
|
|
|
1305
1305
|
s.useRouteParam,
|
|
1306
1306
|
n
|
|
1307
1307
|
);
|
|
1308
|
-
c && (await W.calculateCost(c, f, s, n), e.push(c),
|
|
1308
|
+
c && (await W.calculateCost(c, f, s, n), e.push(c), T == null || T.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, d, s.etd, l.format(), {
|
|
1309
1309
|
cost: c.cost.total,
|
|
1310
1310
|
hire: c.cost.hire,
|
|
1311
1311
|
bunker: c.cost.bunker,
|
|
@@ -1314,23 +1314,23 @@ class W {
|
|
|
1314
1314
|
cp: `${f.speed}/${f.fo}/${f.dgo}`
|
|
1315
1315
|
})), d++;
|
|
1316
1316
|
}
|
|
1317
|
-
e.sort((f,
|
|
1317
|
+
e.sort((f, u) => f.cost.total - u.cost.total);
|
|
1318
1318
|
const y = e.at(0), w = e.at(1), g = [];
|
|
1319
|
-
if (g.push({ combined: !1, speeds: [y], cost: (
|
|
1320
|
-
const f = y.cost.cp,
|
|
1319
|
+
if (g.push({ combined: !1, speeds: [y], cost: (p = y.cost) == null ? void 0 : p.total }), w) {
|
|
1320
|
+
const f = y.cost.cp, u = w.cost.cp, m = v(y.eta), c = v(y.etd), I = m.diff(c, "days", !0);
|
|
1321
1321
|
let C = Math.ceil(I / 2);
|
|
1322
1322
|
C = C > 7 ? 7 : C < s.alterStep ? s.alterStep : C;
|
|
1323
|
-
let F = 2,
|
|
1323
|
+
let F = 2, Y = { combined: !1, speeds: [w], cost: (b = w.cost) == null ? void 0 : b.total }, A;
|
|
1324
1324
|
for (; C >= s.alterStep; ) {
|
|
1325
|
-
const H = await W.combinedAnalyse(s, t, l, [f,
|
|
1326
|
-
if (
|
|
1325
|
+
const H = await W.combinedAnalyse(s, t, l, [f, u], i, C, { ...n, level: F });
|
|
1326
|
+
if (Y.cost > H.cost ? A ? (A == null ? void 0 : A.cost) > H.cost && (A = H) : (A = Y, Y = H) : (!A || (A == null ? void 0 : A.cost) > H.cost) && (A = H), C <= s.alterStep)
|
|
1327
1327
|
break;
|
|
1328
1328
|
C = Math.ceil(C / 2), F += 1;
|
|
1329
1329
|
}
|
|
1330
|
-
g.push(
|
|
1330
|
+
g.push(Y), A && g.push(A);
|
|
1331
1331
|
}
|
|
1332
|
-
const
|
|
1333
|
-
return
|
|
1332
|
+
const j = v().valueOf() - o;
|
|
1333
|
+
return T == null || T.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, j), g.sort((f, u) => f.cost - u.cost);
|
|
1334
1334
|
}
|
|
1335
1335
|
/**
|
|
1336
1336
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1343,23 +1343,23 @@ class W {
|
|
|
1343
1343
|
* @param options
|
|
1344
1344
|
*/
|
|
1345
1345
|
static async combinedAnalyse(s, t, a, i, n, o, e = {}) {
|
|
1346
|
-
e.counter = 1,
|
|
1347
|
-
const r = await W.alternateAnalyse(s, t, a, i, 0, n, o, e),
|
|
1348
|
-
|
|
1349
|
-
cost:
|
|
1346
|
+
e.counter = 1, T == null || T.info("[%s][L%d] analyse with alternate cp in every %d days", e.requestId, e.level, o);
|
|
1347
|
+
const r = await W.alternateAnalyse(s, t, a, i, 0, n, o, e), h = r.reduce((u, m) => u + m.cost.total, 0), l = r.reduce((u, m) => u + m.cost.hire, 0), d = r.reduce((u, m) => u + m.cost.bunker, 0), y = r.reduce((u, m) => u + m.distance, 0), w = r.reduce((u, m) => u + m.totalHrs, 0);
|
|
1348
|
+
T == null || T.info("[%s][L%d] cost with cpa/cpb turn: %j", e.requestId, e.level, {
|
|
1349
|
+
cost: h,
|
|
1350
1350
|
hire: l,
|
|
1351
1351
|
bunker: d,
|
|
1352
1352
|
distance: y,
|
|
1353
1353
|
hours: w
|
|
1354
1354
|
});
|
|
1355
|
-
const g = await W.alternateAnalyse(s, t, a, i, 1, n, o, e), k = g.reduce((
|
|
1356
|
-
return
|
|
1355
|
+
const g = await W.alternateAnalyse(s, t, a, i, 1, n, o, e), k = g.reduce((u, m) => u + m.cost.total, 0), j = g.reduce((u, m) => u + m.cost.hire, 0), p = g.reduce((u, m) => u + m.cost.bunker, 0), b = g.reduce((u, m) => u + m.distance, 0), f = g.reduce((u, m) => u + m.totalHrs, 0);
|
|
1356
|
+
return T == null || T.info("[%s][L%d] cost with cpb/cpa turn: %j", e.requestId, e.level, {
|
|
1357
1357
|
cost: k,
|
|
1358
|
-
hire:
|
|
1359
|
-
bunker:
|
|
1360
|
-
distance:
|
|
1358
|
+
hire: j,
|
|
1359
|
+
bunker: p,
|
|
1360
|
+
distance: b,
|
|
1361
1361
|
hours: f
|
|
1362
|
-
}),
|
|
1362
|
+
}), h < k ? { combined: !0, cost: Math.round(h * 1e3) / 1e3, speeds: r, step: o } : { combined: !0, cost: Math.round(k * 1e3) / 1e3, speeds: g, step: o };
|
|
1363
1363
|
}
|
|
1364
1364
|
/**
|
|
1365
1365
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1374,42 +1374,42 @@ class W {
|
|
|
1374
1374
|
*/
|
|
1375
1375
|
static async alternateAnalyse(s, t, a, i, n, o, e, r = {}) {
|
|
1376
1376
|
var y, w;
|
|
1377
|
-
let
|
|
1377
|
+
let h = v.utc(s.etd);
|
|
1378
1378
|
const l = { lat: s.lat, lng: s.lng }, d = [];
|
|
1379
|
-
for (;
|
|
1380
|
-
const g =
|
|
1379
|
+
for (; h.isBefore(a); ) {
|
|
1380
|
+
const g = h.clone().utc().add(e, "day"), k = JSON.parse(JSON.stringify(o.route)), j = JSON.parse(JSON.stringify(o.waypoints)), p = i[n], b = await W.analyseInstantWithThreshed(
|
|
1381
1381
|
l,
|
|
1382
|
-
|
|
1382
|
+
h.utc().format(),
|
|
1383
1383
|
g,
|
|
1384
1384
|
t,
|
|
1385
|
-
|
|
1385
|
+
p,
|
|
1386
1386
|
k,
|
|
1387
|
-
|
|
1387
|
+
j,
|
|
1388
1388
|
s.meteoVendor,
|
|
1389
1389
|
s.speedStep,
|
|
1390
1390
|
s.useMeteo,
|
|
1391
1391
|
s.useRouteParam,
|
|
1392
1392
|
r
|
|
1393
1393
|
);
|
|
1394
|
-
|
|
1394
|
+
b && (await W.calculateCost(b, p, s, r), T == null || T.info(
|
|
1395
1395
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1396
1396
|
r.requestId,
|
|
1397
1397
|
r.level,
|
|
1398
1398
|
r.counter,
|
|
1399
|
-
|
|
1399
|
+
h.utc().format(),
|
|
1400
1400
|
g.utc().format(),
|
|
1401
1401
|
{
|
|
1402
|
-
cost:
|
|
1403
|
-
hire:
|
|
1404
|
-
bunker:
|
|
1405
|
-
distance:
|
|
1406
|
-
hours:
|
|
1407
|
-
cp: `${
|
|
1402
|
+
cost: b.cost.total,
|
|
1403
|
+
hire: b.cost.hire,
|
|
1404
|
+
bunker: b.cost.bunker,
|
|
1405
|
+
distance: b.distance,
|
|
1406
|
+
hours: b.totalHrs,
|
|
1407
|
+
cp: `${p.speed}/${p.fo}/${p.dgo}`
|
|
1408
1408
|
}
|
|
1409
1409
|
)), r.counter = r.counter + 1;
|
|
1410
|
-
const f = (w = (y =
|
|
1410
|
+
const f = (w = (y = b == null ? void 0 : b.sample) == null ? void 0 : y.hours) == null ? void 0 : w.at(-1);
|
|
1411
1411
|
if (f)
|
|
1412
|
-
l.lat = f.lat, l.lng = f.lng,
|
|
1412
|
+
l.lat = f.lat, l.lng = f.lng, h = v(f.eta), d.push(b), n = n ? 0 : 1;
|
|
1413
1413
|
else
|
|
1414
1414
|
break;
|
|
1415
1415
|
}
|
|
@@ -1425,12 +1425,12 @@ class W {
|
|
|
1425
1425
|
static async calculateCost(s, t, a, i = {}) {
|
|
1426
1426
|
var n;
|
|
1427
1427
|
if (s) {
|
|
1428
|
-
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round((a.dailyHire || 0) * (s.suspend || 0) / 24 * 1e3) / 1e3, r = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3 + e,
|
|
1428
|
+
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round((a.dailyHire || 0) * (s.suspend || 0) / 24 * 1e3) / 1e3, r = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3 + e, h = Math.round(s.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, l = Math.round((s.totalDgoCons + (((n = s.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
|
|
1429
1429
|
s.cost = {
|
|
1430
|
-
total: Math.round((r +
|
|
1430
|
+
total: Math.round((r + h + l) * 1e3) / 1e3,
|
|
1431
1431
|
hire: Math.round(r * 1e3) / 1e3,
|
|
1432
1432
|
suspendHire: e,
|
|
1433
|
-
bunker: Math.round((
|
|
1433
|
+
bunker: Math.round((h + l) * 1e3) / 1e3,
|
|
1434
1434
|
cp: t
|
|
1435
1435
|
};
|
|
1436
1436
|
}
|
|
@@ -1441,10 +1441,10 @@ class W {
|
|
|
1441
1441
|
*
|
|
1442
1442
|
*/
|
|
1443
1443
|
static async calculateECA(s, t, a = {}) {
|
|
1444
|
-
var r,
|
|
1444
|
+
var r, h, l, d;
|
|
1445
1445
|
const i = await V.intersectInECA((s == null ? void 0 : s.route) || []);
|
|
1446
1446
|
let n = 0, o = 0, e = 0;
|
|
1447
|
-
(
|
|
1447
|
+
(h = (r = s == null ? void 0 : s.sample) == null ? void 0 : r.wps) == null || h.forEach((y) => {
|
|
1448
1448
|
y.positionTime = v.utc(y.etd || y.eta).unix();
|
|
1449
1449
|
});
|
|
1450
1450
|
for (const y of i) {
|
|
@@ -1465,7 +1465,7 @@ class W {
|
|
|
1465
1465
|
* @param options
|
|
1466
1466
|
*/
|
|
1467
1467
|
static async mergeSpeeds(s, t = {}) {
|
|
1468
|
-
var f,
|
|
1468
|
+
var f, u;
|
|
1469
1469
|
const a = {
|
|
1470
1470
|
hours: [],
|
|
1471
1471
|
wps: [],
|
|
@@ -1479,41 +1479,41 @@ class W {
|
|
|
1479
1479
|
}, 0), r = s.reduce((m, c) => {
|
|
1480
1480
|
var I;
|
|
1481
1481
|
return m + (((I = c.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1482
|
-
}, 0),
|
|
1483
|
-
let
|
|
1482
|
+
}, 0), h = s.reduce((m, c) => m + c.wxFactor * c.totalHrs / o, 0), l = s.reduce((m, c) => m + c.cFactor * c.totalHrs / o, 0), d = s.reduce((m, c) => m + c.totalFoCons, 0), y = s.reduce((m, c) => m + c.totalDgoCons, 0), w = s.reduce((m, c) => m + c.cost.total, 0), g = s.reduce((m, c) => m + c.cost.hire, 0), k = s.reduce((m, c) => m + c.cost.bunker, 0), j = [], p = [];
|
|
1483
|
+
let b;
|
|
1484
1484
|
for (const m of s) {
|
|
1485
|
-
|
|
1485
|
+
p.push(...((f = m.extend) == null ? void 0 : f.eca) || []);
|
|
1486
1486
|
const c = m.sample.hours, I = m.sample.wps, C = m.sample.days, F = c.at(0);
|
|
1487
|
-
|
|
1488
|
-
N && (
|
|
1489
|
-
}), I.at(0).distanceFromPrevious =
|
|
1490
|
-
N && (
|
|
1491
|
-
}), C.at(0).distanceFromPrevious =
|
|
1492
|
-
N && (
|
|
1487
|
+
b && (F.distanceFromPrevious = b.distanceFromPrevious, F.distanceFromStart = b.distanceFromStart, c.forEach((E, N) => {
|
|
1488
|
+
N && (E.distanceFromStart = E.distanceFromStart + b.distanceFromStart);
|
|
1489
|
+
}), I.at(0).distanceFromPrevious = b.distanceFromPrevious, I.at(0).distanceFromStart = b.distanceFromStart, I.forEach((E, N) => {
|
|
1490
|
+
N && (E.distanceFromStart = E.distanceFromStart + b.distanceFromStart);
|
|
1491
|
+
}), C.at(0).distanceFromPrevious = b.distanceFromPrevious, C.at(0).distanceFromStart = b.distanceFromStart, C.forEach((E, N) => {
|
|
1492
|
+
N && (E.distanceFromStart = E.distanceFromStart + b.distanceFromStart);
|
|
1493
1493
|
})), F.cp = m.cost.cp;
|
|
1494
|
-
const
|
|
1495
|
-
|
|
1496
|
-
var
|
|
1497
|
-
((
|
|
1498
|
-
}), I.forEach((
|
|
1499
|
-
var
|
|
1500
|
-
((
|
|
1501
|
-
}), C.forEach((
|
|
1502
|
-
var
|
|
1503
|
-
((
|
|
1494
|
+
const Y = [m.etd, m.eta], A = j.findIndex((E) => E.id === F.cp.id);
|
|
1495
|
+
A === -1 ? (F.cp.segment = [Y], j.push(F.cp)) : j[A].segment.push(Y), c.forEach((E) => {
|
|
1496
|
+
var O;
|
|
1497
|
+
((O = a.hours) == null ? void 0 : O.findIndex((R) => R.eta === E.eta)) === -1 && a.hours.push(E);
|
|
1498
|
+
}), I.forEach((E) => {
|
|
1499
|
+
var O;
|
|
1500
|
+
((O = a.wps) == null ? void 0 : O.findIndex((R) => R.eta === E.eta)) === -1 && a.wps.push(E);
|
|
1501
|
+
}), C.forEach((E) => {
|
|
1502
|
+
var O;
|
|
1503
|
+
((O = a == null ? void 0 : a.days) == null ? void 0 : O.findIndex((R) => R.eta === E.eta)) === -1 && a.days.push(E);
|
|
1504
1504
|
});
|
|
1505
|
-
const H = (
|
|
1506
|
-
H === -1 ? a.wps.push(F) : a.wps[H] = F,
|
|
1505
|
+
const H = (u = a.wps) == null ? void 0 : u.findIndex((E) => E.eta === F.eta);
|
|
1506
|
+
H === -1 ? a.wps.push(F) : a.wps[H] = F, b = c.at(-1);
|
|
1507
1507
|
}
|
|
1508
1508
|
return a.wps.sort((m, c) => {
|
|
1509
1509
|
v(m.etd).unix() - v(c.etd).unix();
|
|
1510
1510
|
}), a.wps.forEach((m, c) => {
|
|
1511
1511
|
const I = a.wps[c - 1];
|
|
1512
1512
|
if (I) {
|
|
1513
|
-
const C = m.distanceFromStart - (I.distanceFromStart || 0), F = v(m.eta || m.etd).diff(v(I.etd || I.eta), "hour", !0),
|
|
1514
|
-
m.avgSpd =
|
|
1515
|
-
const
|
|
1516
|
-
I.bearing =
|
|
1513
|
+
const C = m.distanceFromStart - (I.distanceFromStart || 0), F = v(m.eta || m.etd).diff(v(I.etd || I.eta), "hour", !0), Y = Math.round(C / F * 100) / 100;
|
|
1514
|
+
m.avgSpd = Y;
|
|
1515
|
+
const A = V.calculateBearing(I, m);
|
|
1516
|
+
I.bearing = A;
|
|
1517
1517
|
}
|
|
1518
1518
|
}), {
|
|
1519
1519
|
sample: a,
|
|
@@ -1526,7 +1526,7 @@ class W {
|
|
|
1526
1526
|
distance: Math.round(i * 1e3) / 1e3,
|
|
1527
1527
|
totalHrs: Math.round(o * 1e3) / 1e3,
|
|
1528
1528
|
avgSpeed: Math.round(i / o * 1e3) / 1e3,
|
|
1529
|
-
wxFactor: Math.round(
|
|
1529
|
+
wxFactor: Math.round(h * 1e3) / 1e3,
|
|
1530
1530
|
cFactor: Math.round(l * 1e3) / 1e3,
|
|
1531
1531
|
totalFoCons: Math.round(d * 1e3) / 1e3,
|
|
1532
1532
|
totalDgoCons: Math.round(y * 1e3) / 1e3,
|
|
@@ -1536,8 +1536,8 @@ class W {
|
|
|
1536
1536
|
bunker: Math.round(k * 1e3) / 1e3
|
|
1537
1537
|
},
|
|
1538
1538
|
extend: {
|
|
1539
|
-
cps:
|
|
1540
|
-
eca:
|
|
1539
|
+
cps: j,
|
|
1540
|
+
eca: p,
|
|
1541
1541
|
distanceInECA: Math.round(n * 1e3) / 1e3,
|
|
1542
1542
|
hoursInECA: Math.round(e * 1e3) / 1e3,
|
|
1543
1543
|
totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
|
|
@@ -1547,16 +1547,16 @@ class W {
|
|
|
1547
1547
|
}
|
|
1548
1548
|
}
|
|
1549
1549
|
export {
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1550
|
+
ot as AISImpl,
|
|
1551
|
+
pt as AlertHelper,
|
|
1552
|
+
gt as AlertLevel,
|
|
1553
|
+
xt as HifleetImpl,
|
|
1554
|
+
wt as LoadCondition,
|
|
1555
|
+
At as MyShipImpl,
|
|
1556
|
+
Nt as MyVesselImpl,
|
|
1557
|
+
Dt as ShipxyImpl,
|
|
1558
1558
|
W as SpeedHelper,
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1559
|
+
kt as SpeedLabel,
|
|
1560
|
+
vt as VesselTag,
|
|
1561
|
+
Pt as alertHelper
|
|
1562
1562
|
};
|