@idm-plugin/vessel 3.4.2 → 3.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +453 -449
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var U = (
|
|
1
|
+
var mt = Object.defineProperty;
|
|
2
|
+
var ft = (N, e, t) => e in N ? mt(N, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : N[e] = t;
|
|
3
|
+
var U = (N, e, t) => (ft(N, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
4
|
import B from "got";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import ut from "@log4js-node/log4js-api";
|
|
6
|
+
import p from "moment";
|
|
7
7
|
import { LngLatHelper as z, LaneHelper as V } from "@idm-plugin/geo2";
|
|
8
|
-
import { MeteoHelper2 as
|
|
9
|
-
import { Meteo2Assist as
|
|
8
|
+
import { MeteoHelper2 as yt } from "@idm-plugin/meteo2";
|
|
9
|
+
import { Meteo2Assist as dt } from "@idm-plugin/meteo";
|
|
10
10
|
let y;
|
|
11
11
|
try {
|
|
12
|
-
y =
|
|
12
|
+
y = ut.getLogger("vessel");
|
|
13
13
|
} catch {
|
|
14
14
|
} finally {
|
|
15
15
|
}
|
|
16
|
-
class
|
|
16
|
+
class nt {
|
|
17
17
|
/**
|
|
18
18
|
* 解析AIS状态码
|
|
19
19
|
* @param status
|
|
20
20
|
*/
|
|
21
|
-
parseStatus(
|
|
21
|
+
parseStatus(e) {
|
|
22
22
|
let t, a;
|
|
23
|
-
switch (
|
|
23
|
+
switch (e) {
|
|
24
24
|
case 0:
|
|
25
25
|
t = "在航(主机推动)", a = "Underway Using Engine";
|
|
26
26
|
break;
|
|
@@ -54,7 +54,7 @@ class at {
|
|
|
54
54
|
return { labelCn: t, labelEn: a };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class Et extends nt {
|
|
58
58
|
constructor(t, a) {
|
|
59
59
|
super();
|
|
60
60
|
U(this, "clientId");
|
|
@@ -76,12 +76,12 @@ class Tt extends at {
|
|
|
76
76
|
expiresIn: n.expires_in,
|
|
77
77
|
scope: n.scope,
|
|
78
78
|
jti: n.jti,
|
|
79
|
-
issuedAt:
|
|
79
|
+
issuedAt: p().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async checkToken(t = {}) {
|
|
83
83
|
var a;
|
|
84
|
-
return (!this.token ||
|
|
84
|
+
return (!this.token || p().diff(p(this.token.issuedAt), "seconds") > (((a = this.token) == null ? void 0 : a.expiresIn) || 0) - 300) && await this.authToken(t), this.token;
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* 模糊查询
|
|
@@ -89,11 +89,11 @@ class Tt extends at {
|
|
|
89
89
|
* @param options
|
|
90
90
|
*/
|
|
91
91
|
async suggest(t, a = {}) {
|
|
92
|
-
var
|
|
92
|
+
var s, r;
|
|
93
93
|
await this.checkToken(a);
|
|
94
94
|
const i = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy", n = {
|
|
95
95
|
headers: {
|
|
96
|
-
Authorization: `${(
|
|
96
|
+
Authorization: `${(s = this.token) == null ? void 0 : s.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
97
97
|
},
|
|
98
98
|
json: {
|
|
99
99
|
kw: t,
|
|
@@ -122,14 +122,14 @@ class Tt extends at {
|
|
|
122
122
|
async search(t, a = {}) {
|
|
123
123
|
var d, h;
|
|
124
124
|
await this.checkToken(a);
|
|
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 },
|
|
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 }, s = {
|
|
126
126
|
headers: {
|
|
127
127
|
Authorization: `${(d = this.token) == null ? void 0 : d.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
|
|
128
128
|
},
|
|
129
129
|
searchParams: o
|
|
130
130
|
};
|
|
131
|
-
y == null || y.info("[%s] fetch vessel from: %s - %j", a.requestId, n,
|
|
132
|
-
const r = await B.get(n,
|
|
131
|
+
y == null || y.info("[%s] fetch vessel from: %s - %j", a.requestId, n, s);
|
|
132
|
+
const r = await B.get(n, s).json();
|
|
133
133
|
if (r.status !== 200)
|
|
134
134
|
return y == null || y.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
|
|
135
135
|
{
|
|
@@ -162,11 +162,11 @@ class Tt extends at {
|
|
|
162
162
|
return {};
|
|
163
163
|
}
|
|
164
164
|
async archives(t, a = {}) {
|
|
165
|
-
var
|
|
165
|
+
var s, r;
|
|
166
166
|
await this.checkToken(a);
|
|
167
167
|
const i = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch", n = {
|
|
168
168
|
headers: {
|
|
169
|
-
Authorization: `${(
|
|
169
|
+
Authorization: `${(s = this.token) == null ? void 0 : s.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
170
170
|
},
|
|
171
171
|
json: {
|
|
172
172
|
mmsiList: typeof t == "number" ? [t] : t
|
|
@@ -189,38 +189,38 @@ class Tt extends at {
|
|
|
189
189
|
const o = await B.get(i, n).json();
|
|
190
190
|
if (o.code)
|
|
191
191
|
return y == null || y.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), o;
|
|
192
|
-
const
|
|
193
|
-
for (const h in
|
|
194
|
-
!isNaN(
|
|
195
|
-
if (
|
|
196
|
-
const h =
|
|
192
|
+
const s = o.data;
|
|
193
|
+
for (const h in s)
|
|
194
|
+
!isNaN(s[h]) && Number(s[h]) !== 1 / 0 && (s[h] = Number(s[h]));
|
|
195
|
+
if (s) {
|
|
196
|
+
const h = p(`${s.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
197
197
|
return {
|
|
198
|
-
mmsi:
|
|
199
|
-
name:
|
|
200
|
-
imo:
|
|
201
|
-
callSign:
|
|
202
|
-
lat:
|
|
203
|
-
lng:
|
|
204
|
-
length:
|
|
205
|
-
width:
|
|
206
|
-
draught:
|
|
207
|
-
sog:
|
|
208
|
-
cog:
|
|
209
|
-
hdg:
|
|
210
|
-
rot:
|
|
211
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(
|
|
212
|
-
destination:
|
|
198
|
+
mmsi: s.mmsi,
|
|
199
|
+
name: s.vesselName || s.aisVesselName,
|
|
200
|
+
imo: s.imo,
|
|
201
|
+
callSign: s.callsign || s.aisCallSign,
|
|
202
|
+
lat: s.lat,
|
|
203
|
+
lng: s.lon,
|
|
204
|
+
length: s.length,
|
|
205
|
+
width: s.width,
|
|
206
|
+
draught: s.currDraught,
|
|
207
|
+
sog: s.sog,
|
|
208
|
+
cog: s.cog,
|
|
209
|
+
hdg: s.hdg,
|
|
210
|
+
rot: s.rot,
|
|
211
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? p.utc(s.eta).format() : void 0,
|
|
212
|
+
destination: s.dest,
|
|
213
213
|
positionTime: h.unix(),
|
|
214
|
-
status:
|
|
215
|
-
labelCn:
|
|
216
|
-
labelEn:
|
|
217
|
-
vesselType:
|
|
218
|
-
flag:
|
|
219
|
-
clasz:
|
|
220
|
-
build:
|
|
221
|
-
dwt:
|
|
222
|
-
grt:
|
|
223
|
-
net:
|
|
214
|
+
status: s.status,
|
|
215
|
+
labelCn: s.statusNameCn,
|
|
216
|
+
labelEn: s.statusNameEn,
|
|
217
|
+
vesselType: s.vesselTypeNameEn,
|
|
218
|
+
flag: s.flagCtryNameEn,
|
|
219
|
+
clasz: s.classSociety,
|
|
220
|
+
build: s.buildYear,
|
|
221
|
+
dwt: s.dwt,
|
|
222
|
+
grt: s.grt,
|
|
223
|
+
net: s.net,
|
|
224
224
|
method: "position",
|
|
225
225
|
vendor: "myVessel",
|
|
226
226
|
utc: h.utc().format()
|
|
@@ -250,18 +250,18 @@ class Tt extends at {
|
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
252
|
y == null || y.info("[%s] fetch route from: %s - %j", i.requestId, n, o);
|
|
253
|
-
const
|
|
254
|
-
return
|
|
253
|
+
const s = await B.post(n, o).json();
|
|
254
|
+
return s.status !== 200 ? (y == null || y.warn("[%s] fetch route failed: %j", i.requestId, { message: s.message, status: s.status, code: s.code }), {}) : s.data;
|
|
255
255
|
}
|
|
256
|
-
async trajectory(t, a, i, n, o = !0,
|
|
257
|
-
await this.checkToken(
|
|
258
|
-
const r = await this.realTimePosition(t,
|
|
256
|
+
async trajectory(t, a, i, n, o = !0, s = {}) {
|
|
257
|
+
await this.checkToken(s);
|
|
258
|
+
const r = await this.realTimePosition(t, s), d = p(a), h = p(i), c = [];
|
|
259
259
|
for (; h.diff(d, "day", !0) > 30; )
|
|
260
|
-
await this.trajectoryIn30Day(t, d, d.clone().add(30, "day"), r, n, c,
|
|
261
|
-
return await this.trajectoryIn30Day(t, d, h, r, n, c,
|
|
260
|
+
await this.trajectoryIn30Day(t, d, d.clone().add(30, "day"), r, n, c, s), d.add(30, "day");
|
|
261
|
+
return await this.trajectoryIn30Day(t, d, h, r, n, c, s), c;
|
|
262
262
|
}
|
|
263
|
-
async trajectoryIn30Day(t, a, i, n, o,
|
|
264
|
-
var b, j,
|
|
263
|
+
async trajectoryIn30Day(t, a, i, n, o, s, r = {}) {
|
|
264
|
+
var b, j, F, g, v;
|
|
265
265
|
const d = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
|
|
266
266
|
headers: {
|
|
267
267
|
Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(j = this.token) == null ? void 0 : j.accessToken}`
|
|
@@ -277,11 +277,11 @@ class Tt extends at {
|
|
|
277
277
|
if (c.code)
|
|
278
278
|
return y == null || y.warn("[%s] fetch trajectory failed: %j", r.requestId, d, { message: c.message, status: c.status, code: c.code }), c;
|
|
279
279
|
let M = -1;
|
|
280
|
-
const w =
|
|
281
|
-
return (
|
|
282
|
-
for (const
|
|
283
|
-
!isNaN(f[
|
|
284
|
-
const u =
|
|
280
|
+
const w = p(`${(g = (F = c.data) == null ? void 0 : F[0]) == null ? void 0 : g.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
281
|
+
return (v = c.data) == null || v.forEach((f) => {
|
|
282
|
+
for (const q in f)
|
|
283
|
+
!isNaN(f[q]) && Number(f[q]) !== 1 / 0 && (f[q] = Number(f[q]));
|
|
284
|
+
const u = p(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), l = f.status, { labelCn: m, labelEn: I } = this.parseStatus(l), k = {
|
|
285
285
|
mmsi: f.mmsi,
|
|
286
286
|
imo: n == null ? void 0 : n.imo,
|
|
287
287
|
lat: f.lat,
|
|
@@ -291,7 +291,7 @@ class Tt extends at {
|
|
|
291
291
|
hdg: f.hdg,
|
|
292
292
|
draught: f.draught,
|
|
293
293
|
status: l,
|
|
294
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta) ?
|
|
294
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta) ? p(`${f.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
|
|
295
295
|
destination: f.dest,
|
|
296
296
|
positionTime: u.unix(),
|
|
297
297
|
labelCn: m,
|
|
@@ -299,12 +299,12 @@ class Tt extends at {
|
|
|
299
299
|
method: "trajectory",
|
|
300
300
|
vendor: "myVessel",
|
|
301
301
|
utc: u.utc().format()
|
|
302
|
-
},
|
|
303
|
-
|
|
304
|
-
}),
|
|
302
|
+
}, E = Math.floor(u.diff(w, "minute", !0) / (o || 1));
|
|
303
|
+
E !== M && (M = E, s.push(k));
|
|
304
|
+
}), s;
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
|
-
class
|
|
307
|
+
class xt extends nt {
|
|
308
308
|
constructor(t) {
|
|
309
309
|
super();
|
|
310
310
|
U(this, "token");
|
|
@@ -318,33 +318,33 @@ class Ft extends at {
|
|
|
318
318
|
}
|
|
319
319
|
}, o = await B.post(i, n).json();
|
|
320
320
|
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
|
|
321
|
-
const
|
|
322
|
-
if (!
|
|
321
|
+
const s = o == null ? void 0 : o.list;
|
|
322
|
+
if (!s)
|
|
323
323
|
return y == null || y.warn("[%s] fetch realtime position failed: %j", a.requestId, i, o), o;
|
|
324
|
-
for (const w in
|
|
325
|
-
!isNaN(
|
|
326
|
-
|
|
327
|
-
const r =
|
|
324
|
+
for (const w in s)
|
|
325
|
+
!isNaN(s[w]) && Number(s[w]) !== 1 / 0 && (s[w] = Number(s[w]));
|
|
326
|
+
s.status = s.sp > 3 ? 0 : 1;
|
|
327
|
+
const r = s.status, { labelCn: d, labelEn: h } = this.parseStatus(r), c = p(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
328
328
|
return {
|
|
329
|
-
mmsi:
|
|
330
|
-
name:
|
|
331
|
-
imo:
|
|
332
|
-
callSign:
|
|
333
|
-
lat: Math.round(
|
|
334
|
-
lng: Math.round(
|
|
335
|
-
length:
|
|
336
|
-
width:
|
|
337
|
-
draught:
|
|
338
|
-
sog:
|
|
339
|
-
cog:
|
|
340
|
-
hdg:
|
|
341
|
-
rot: isNaN(
|
|
342
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(
|
|
343
|
-
destination:
|
|
344
|
-
vesselType:
|
|
345
|
-
dwt:
|
|
346
|
-
build:
|
|
347
|
-
flag:
|
|
329
|
+
mmsi: s.m,
|
|
330
|
+
name: s.n,
|
|
331
|
+
imo: s.imonumber,
|
|
332
|
+
callSign: s.callsign,
|
|
333
|
+
lat: Math.round(s.la / 60 * 1e5) / 1e5,
|
|
334
|
+
lng: Math.round(s.lo / 60 * 1e5) / 1e5,
|
|
335
|
+
length: s.l,
|
|
336
|
+
width: s.w,
|
|
337
|
+
draught: s.draught,
|
|
338
|
+
sog: s.sp,
|
|
339
|
+
cog: s.co,
|
|
340
|
+
hdg: s.h,
|
|
341
|
+
rot: isNaN(s.rot) ? 0 : s.rot,
|
|
342
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? p.utc(s.eta).format() : void 0,
|
|
343
|
+
destination: s.destination,
|
|
344
|
+
vesselType: s.type,
|
|
345
|
+
dwt: s.dwt,
|
|
346
|
+
build: s.buildyear,
|
|
347
|
+
flag: s.fn,
|
|
348
348
|
positionTime: c.unix(),
|
|
349
349
|
utc: c.utc().format(),
|
|
350
350
|
status: r,
|
|
@@ -370,7 +370,7 @@ class Ft extends at {
|
|
|
370
370
|
y == null || y.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]);
|
|
371
371
|
for (const r in o)
|
|
372
372
|
!isNaN(o[r]) && Number(o[r]) !== 1 / 0 && (o[r] = Number(o[r]));
|
|
373
|
-
const
|
|
373
|
+
const s = {
|
|
374
374
|
mmsi: o.m,
|
|
375
375
|
name: o.n,
|
|
376
376
|
imo: o.i,
|
|
@@ -380,7 +380,7 @@ class Ft extends at {
|
|
|
380
380
|
draught: o.dr,
|
|
381
381
|
type: o.t
|
|
382
382
|
};
|
|
383
|
-
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(), y == null || y.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]), o && (
|
|
383
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(), y == null || y.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]), o && (s.deadweight = Number(o.dwt)), s;
|
|
384
384
|
}
|
|
385
385
|
async suggest(t, a = {}) {
|
|
386
386
|
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
|
|
@@ -394,22 +394,22 @@ class Ft extends at {
|
|
|
394
394
|
}
|
|
395
395
|
}, o = await B.post(i, n).json();
|
|
396
396
|
y == null || y.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, n);
|
|
397
|
-
const
|
|
397
|
+
const s = [];
|
|
398
398
|
for (const r of o)
|
|
399
|
-
|
|
399
|
+
s.push({
|
|
400
400
|
mmsi: !r.mmsi || isNaN(r.mmsi) ? null : Number(r.mmsi),
|
|
401
401
|
name: r.name,
|
|
402
402
|
callSign: r.callsign,
|
|
403
403
|
imo: !r.imo || isNaN(r.imo) ? null : Number(r.imo),
|
|
404
404
|
score: r._score
|
|
405
405
|
});
|
|
406
|
-
return
|
|
406
|
+
return s.sort((r, d) => d.score - r.score), s;
|
|
407
407
|
}
|
|
408
|
-
async trajectory(t, a, i, n, o = !0,
|
|
408
|
+
async trajectory(t, a, i, n, o = !0, s = {}) {
|
|
409
409
|
var f, u, l;
|
|
410
|
-
const r = await this.realTimePosition(t,
|
|
411
|
-
let d =
|
|
412
|
-
const h =
|
|
410
|
+
const r = await this.realTimePosition(t, s);
|
|
411
|
+
let d = p(a);
|
|
412
|
+
const h = p(i), c = p();
|
|
413
413
|
if (o) {
|
|
414
414
|
let m = h.diff(d, "d", !0);
|
|
415
415
|
m < 0 ? d = h.clone().subtract(40, "d") : m < 30 ? d.subtract(10, "d") : m < 60 ? d.subtract(5, "d") : d = h.clone().subtract(80, "d"), m = c.diff(h, "d", !0), h.add(m > 10 ? 240 : m * 24, "h");
|
|
@@ -422,18 +422,18 @@ class Ft extends at {
|
|
|
422
422
|
usertoken: this.token
|
|
423
423
|
}
|
|
424
424
|
}, w = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await B.get(w, M).json();
|
|
425
|
-
y == null || y.info("[%s] fetch trajectory from: %s - %j",
|
|
425
|
+
y == null || y.info("[%s] fetch trajectory from: %s - %j", s.requestId, w, M);
|
|
426
426
|
let j;
|
|
427
|
-
b && (j = ((u = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : u.ship) || [], j.length || y == null || y.warn("[%s] fetch trajectory failed: %j",
|
|
428
|
-
const
|
|
427
|
+
b && (j = ((u = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : u.ship) || [], j.length || y == null || y.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
|
|
428
|
+
const F = [];
|
|
429
429
|
let g = -1;
|
|
430
|
-
const
|
|
430
|
+
const v = p(`${(l = j == null ? void 0 : j[0]) == null ? void 0 : l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
431
431
|
for (const m of j) {
|
|
432
|
-
for (const
|
|
433
|
-
!isNaN(m[
|
|
434
|
-
const I =
|
|
432
|
+
for (const H in m)
|
|
433
|
+
!isNaN(m[H]) && Number(m[H]) !== 1 / 0 && (m[H] = Number(m[H]));
|
|
434
|
+
const I = p(`${m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
435
435
|
m.status = m.sp > 4 ? 0 : 1;
|
|
436
|
-
const { labelEn: k, labelCn:
|
|
436
|
+
const { labelEn: k, labelCn: E } = this.parseStatus(m.status), q = {
|
|
437
437
|
mmsi: m.m,
|
|
438
438
|
name: m.n,
|
|
439
439
|
imo: r == null ? void 0 : r.imo,
|
|
@@ -446,17 +446,17 @@ class Ft extends at {
|
|
|
446
446
|
positionTime: I.unix(),
|
|
447
447
|
utc: I.utc().format(),
|
|
448
448
|
status: m.status,
|
|
449
|
-
labelCn:
|
|
449
|
+
labelCn: E,
|
|
450
450
|
labelEn: k,
|
|
451
451
|
method: "trajectory",
|
|
452
452
|
vendor: "hifleet"
|
|
453
|
-
},
|
|
454
|
-
|
|
453
|
+
}, D = Math.floor(I.diff(v, "minute", !0) / (n || 1));
|
|
454
|
+
D !== g && (g = D, F.push(q));
|
|
455
455
|
}
|
|
456
|
-
return
|
|
456
|
+
return F;
|
|
457
457
|
}
|
|
458
458
|
}
|
|
459
|
-
class
|
|
459
|
+
class Nt extends nt {
|
|
460
460
|
constructor(t) {
|
|
461
461
|
super();
|
|
462
462
|
U(this, "token");
|
|
@@ -472,36 +472,36 @@ class Et extends at {
|
|
|
472
472
|
}, n = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(n, i).json();
|
|
473
473
|
if (y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, i), (o == null ? void 0 : o.status) !== 0)
|
|
474
474
|
return o;
|
|
475
|
-
const
|
|
476
|
-
for (const M in
|
|
477
|
-
!isNaN(
|
|
478
|
-
const { labelCn: r, labelEn: d } = await this.parseStatus(
|
|
475
|
+
const s = o.data[0];
|
|
476
|
+
for (const M in s)
|
|
477
|
+
!isNaN(s[M]) && Number(s[M]) !== 1 / 0 && (s[M] = Number(s[M]));
|
|
478
|
+
const { labelCn: r, labelEn: d } = await this.parseStatus(s.navistat), h = p.unix(s.lasttime);
|
|
479
479
|
return {
|
|
480
|
-
mmsi:
|
|
481
|
-
name:
|
|
482
|
-
imo:
|
|
483
|
-
callSign:
|
|
484
|
-
lat: Math.round(
|
|
485
|
-
lng: Math.round(
|
|
486
|
-
length: Math.round(
|
|
487
|
-
width: Math.round(
|
|
488
|
-
draught: Math.round(
|
|
489
|
-
sog: Math.round(
|
|
490
|
-
cog: Math.round(
|
|
491
|
-
hdg: Math.round(
|
|
492
|
-
rot: Math.round(
|
|
493
|
-
positionTime:
|
|
480
|
+
mmsi: s.ShipID,
|
|
481
|
+
name: s.name,
|
|
482
|
+
imo: s.imo,
|
|
483
|
+
callSign: s.callsign,
|
|
484
|
+
lat: Math.round(s.lat / 1e6 * 1e5) / 1e5,
|
|
485
|
+
lng: Math.round(s.lon / 1e6 * 1e5) / 1e5,
|
|
486
|
+
length: Math.round(s.length / 10 * 100) / 100,
|
|
487
|
+
width: Math.round(s.width / 10 * 100) / 100,
|
|
488
|
+
draught: Math.round(s.draught / 1e3 * 100) / 100,
|
|
489
|
+
sog: Math.round(s.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
490
|
+
cog: Math.round(s.cog / 100 * 100) / 100,
|
|
491
|
+
hdg: Math.round(s.hdg / 100 * 100) / 100,
|
|
492
|
+
rot: Math.round(s.rot / 100 * 100) / 100,
|
|
493
|
+
positionTime: s.lasttime,
|
|
494
494
|
utc: h.utc().format(),
|
|
495
|
-
status:
|
|
495
|
+
status: s.navistat,
|
|
496
496
|
labelEn: d,
|
|
497
497
|
labelCn: r,
|
|
498
498
|
method: "position",
|
|
499
499
|
vendor: "shipxy"
|
|
500
500
|
};
|
|
501
501
|
}
|
|
502
|
-
async trajectory(t, a, i, n, o = !0,
|
|
503
|
-
var
|
|
504
|
-
const r = await this.realTimePosition(t,
|
|
502
|
+
async trajectory(t, a, i, n, o = !0, s = {}) {
|
|
503
|
+
var v;
|
|
504
|
+
const r = await this.realTimePosition(t, s), d = p(a), h = p(i), c = "https://api.shipxy.com/apicall/GetShipTrack", M = {
|
|
505
505
|
searchParams: {
|
|
506
506
|
id: t,
|
|
507
507
|
k: this.token,
|
|
@@ -511,12 +511,12 @@ class Et extends at {
|
|
|
511
511
|
etm: h.unix()
|
|
512
512
|
}
|
|
513
513
|
}, w = await B.get(c, M).json();
|
|
514
|
-
if (y == null || y.info("[%s] fetch trajectory from: %s - %j",
|
|
514
|
+
if (y == null || y.info("[%s] fetch trajectory from: %s - %j", s.requestId, c, M), (w == null ? void 0 : w.status) !== 0)
|
|
515
515
|
return w;
|
|
516
|
-
const b = w == null ? void 0 : w.points, j = [],
|
|
516
|
+
const b = w == null ? void 0 : w.points, j = [], F = p.unix((v = b[0]) == null ? void 0 : v.utc);
|
|
517
517
|
let g = -1;
|
|
518
518
|
for (const f of b) {
|
|
519
|
-
const u =
|
|
519
|
+
const u = p.unix(f.utc), l = {
|
|
520
520
|
imo: r == null ? void 0 : r.imo,
|
|
521
521
|
mmsi: t,
|
|
522
522
|
sog: Math.round(f.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
@@ -527,13 +527,13 @@ class Et extends at {
|
|
|
527
527
|
utc: u.utc().format(),
|
|
528
528
|
method: "trajectory",
|
|
529
529
|
vendor: "shipxy"
|
|
530
|
-
}, m = Math.floor(u.diff(
|
|
530
|
+
}, m = Math.floor(u.diff(F, "minute", !0) / (n || 1));
|
|
531
531
|
m !== g && (g = m, j.push(l));
|
|
532
532
|
}
|
|
533
533
|
return j;
|
|
534
534
|
}
|
|
535
535
|
}
|
|
536
|
-
class
|
|
536
|
+
class Dt extends nt {
|
|
537
537
|
constructor(t) {
|
|
538
538
|
super();
|
|
539
539
|
U(this, "token");
|
|
@@ -561,16 +561,16 @@ class xt extends at {
|
|
|
561
561
|
}, n = "https://api3.myships.com/sp/ships/aissta", o = await B.post(n, i).json();
|
|
562
562
|
if (y == null || y.info("[%s] fetch ship info from: %s - %j", a.requestId, n, i), o.code !== "0")
|
|
563
563
|
return o;
|
|
564
|
-
const
|
|
565
|
-
let r =
|
|
566
|
-
return t === "407170" && (r = "9198379", y == null || y.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t,
|
|
567
|
-
mmsi:
|
|
568
|
-
name:
|
|
564
|
+
const s = o.data;
|
|
565
|
+
let r = s.imo;
|
|
566
|
+
return t === "407170" && (r = "9198379", y == null || y.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, s.imo, r)), {
|
|
567
|
+
mmsi: s.mmsi,
|
|
568
|
+
name: s.shipnameEn,
|
|
569
569
|
imo: r,
|
|
570
|
-
callSign:
|
|
571
|
-
length:
|
|
572
|
-
width:
|
|
573
|
-
draught: (
|
|
570
|
+
callSign: s.callSign,
|
|
571
|
+
length: s.length,
|
|
572
|
+
width: s.breadth,
|
|
573
|
+
draught: (s.draught || 100) / 10
|
|
574
574
|
};
|
|
575
575
|
}
|
|
576
576
|
async realTimePosition(t, a = {}) {
|
|
@@ -581,12 +581,12 @@ class xt extends at {
|
|
|
581
581
|
json: {
|
|
582
582
|
shipId: i
|
|
583
583
|
}
|
|
584
|
-
},
|
|
585
|
-
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
584
|
+
}, s = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(s, o).json();
|
|
585
|
+
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, o);
|
|
586
586
|
const d = r.data[0];
|
|
587
587
|
for (const b in d)
|
|
588
588
|
!isNaN(d[b]) && Number(d[b]) !== 1 / 0 && (d[b] = Number(d[b]));
|
|
589
|
-
const { labelCn: h, labelEn: c } = await this.parseStatus(d.aisNavStatus), M =
|
|
589
|
+
const { labelCn: h, labelEn: c } = await this.parseStatus(d.aisNavStatus), M = p.unix(d.posTime);
|
|
590
590
|
return {
|
|
591
591
|
...n,
|
|
592
592
|
mmsi: t,
|
|
@@ -605,14 +605,14 @@ class xt extends at {
|
|
|
605
605
|
vendor: "myship"
|
|
606
606
|
};
|
|
607
607
|
}
|
|
608
|
-
async trajectory(t, a, i, n, o = !0,
|
|
609
|
-
const r =
|
|
608
|
+
async trajectory(t, a, i, n, o = !0, s = {}) {
|
|
609
|
+
const r = p(a), d = p(i), h = await this.getShipId(t), c = await this.getShipInfo(h), M = [];
|
|
610
610
|
for (; d.diff(r, "day", !0) > 30; )
|
|
611
611
|
await this.trajectoryIn30Day(h, r.unix(), r.add(30, "day").unix(), c, t, n, M);
|
|
612
612
|
return await this.trajectoryIn30Day(h, r.unix(), d.unix(), c, t, n, M), M;
|
|
613
613
|
}
|
|
614
|
-
async trajectoryIn30Day(t, a, i, n, o,
|
|
615
|
-
var
|
|
614
|
+
async trajectoryIn30Day(t, a, i, n, o, s, r, d = {}) {
|
|
615
|
+
var F;
|
|
616
616
|
const h = {
|
|
617
617
|
headers: {
|
|
618
618
|
appKey: this.token
|
|
@@ -628,10 +628,10 @@ class xt extends at {
|
|
|
628
628
|
const w = M.data;
|
|
629
629
|
for (const g in w)
|
|
630
630
|
!isNaN(w[g]) && Number(w[g]) !== 1 / 0 && (w[g] = Number(w[g]));
|
|
631
|
-
const b =
|
|
631
|
+
const b = p.unix((F = w[0]) == null ? void 0 : F.posTime);
|
|
632
632
|
let j = -1;
|
|
633
633
|
for (const g of w) {
|
|
634
|
-
const
|
|
634
|
+
const v = p.unix(g.posTime), f = {
|
|
635
635
|
imo: n == null ? void 0 : n.imo,
|
|
636
636
|
mmsi: o,
|
|
637
637
|
lat: Math.round(g.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
@@ -640,11 +640,11 @@ class xt extends at {
|
|
|
640
640
|
cog: Math.round(g.cog / 10 * 100) / 100,
|
|
641
641
|
hdg: Math.round(g.heading * 100) / 100,
|
|
642
642
|
rot: Math.round(g.rot * 100) / 100,
|
|
643
|
-
positionTime:
|
|
644
|
-
utc:
|
|
643
|
+
positionTime: v.unix(),
|
|
644
|
+
utc: v.utc().format(),
|
|
645
645
|
method: "trajectory",
|
|
646
646
|
vendor: "myship"
|
|
647
|
-
}, u = Math.floor(
|
|
647
|
+
}, u = Math.floor(v.diff(b, "minute", !0) / (s || 1));
|
|
648
648
|
u !== j && (j = u, r.push(f));
|
|
649
649
|
}
|
|
650
650
|
return r;
|
|
@@ -652,12 +652,12 @@ class xt extends at {
|
|
|
652
652
|
}
|
|
653
653
|
let _;
|
|
654
654
|
try {
|
|
655
|
-
_ =
|
|
655
|
+
_ = ut.getLogger("vessel");
|
|
656
656
|
} catch {
|
|
657
657
|
} finally {
|
|
658
658
|
}
|
|
659
|
-
var
|
|
660
|
-
class
|
|
659
|
+
var Mt = /* @__PURE__ */ ((N) => (N.NOTICE = "NOTICE", N.WARN = "WARN", N.HEAVY = "HEAVY", N.SEVERE = "SEVERE", N.ERROR = "ERROR", N.FATAL = "FATAL", N))(Mt || {});
|
|
660
|
+
class bt {
|
|
661
661
|
/**
|
|
662
662
|
* 解析告警规则, 多规则场景
|
|
663
663
|
* @param rule
|
|
@@ -666,10 +666,10 @@ class yt {
|
|
|
666
666
|
*
|
|
667
667
|
* @param options
|
|
668
668
|
*/
|
|
669
|
-
parsePrinciple(
|
|
670
|
-
var
|
|
671
|
-
_ == null || _.debug("[%s] parse rule: %s", t.requestId,
|
|
672
|
-
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i =
|
|
669
|
+
parsePrinciple(e, t = {}) {
|
|
670
|
+
var s, r, d;
|
|
671
|
+
_ == null || _.debug("[%s] parse rule: %s", t.requestId, e);
|
|
672
|
+
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = e.match(a) ? (s = e.match(a)) == null ? void 0 : s[0] : void 0, n = i == null ? void 0 : i.split(";");
|
|
673
673
|
if (!n)
|
|
674
674
|
return;
|
|
675
675
|
const o = {};
|
|
@@ -691,17 +691,17 @@ class yt {
|
|
|
691
691
|
* @param rule
|
|
692
692
|
* @param options
|
|
693
693
|
*/
|
|
694
|
-
parseRule(
|
|
694
|
+
parseRule(e, t = {}) {
|
|
695
695
|
var o;
|
|
696
|
-
_ == null || _.debug("[%s] parse rule: %s", t.requestId,
|
|
697
|
-
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (o =
|
|
696
|
+
_ == null || _.debug("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
|
|
697
|
+
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (o = e == null ? void 0 : e.match(a)) == null ? void 0 : o[0], n = i == null ? void 0 : i.split(",");
|
|
698
698
|
if (n) {
|
|
699
|
-
let
|
|
700
|
-
return
|
|
699
|
+
let s = n[3] === "Number.MAX_VALUE" ? 100 : Number(n[3]);
|
|
700
|
+
return s = isNaN(s) ? 1 : s, {
|
|
701
701
|
operator: n[0],
|
|
702
702
|
number: Number.isNaN(Number(n[1])) ? n[1] : Number(n[1]),
|
|
703
703
|
level: n[2],
|
|
704
|
-
time:
|
|
704
|
+
time: s,
|
|
705
705
|
key: n[4]
|
|
706
706
|
};
|
|
707
707
|
}
|
|
@@ -712,27 +712,27 @@ class yt {
|
|
|
712
712
|
* @param principle 告警规则
|
|
713
713
|
* @param options
|
|
714
714
|
*/
|
|
715
|
-
checkWeather(
|
|
716
|
-
var b, j,
|
|
717
|
-
let i = 0, n = 0, o = 0,
|
|
718
|
-
const r = Math.round(((j = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, d = (g = (
|
|
719
|
-
for (let
|
|
720
|
-
const
|
|
721
|
-
|
|
715
|
+
checkWeather(e, t, a = {}) {
|
|
716
|
+
var b, j, F, g, v, f, u, l, m, I, k, E, q, D, H;
|
|
717
|
+
let i = 0, n = 0, o = 0, s = 0;
|
|
718
|
+
const r = Math.round(((j = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, d = (g = (F = t == null ? void 0 : t.SEVERE) == null ? void 0 : F.sigWave) == null ? void 0 : g.number, h = (f = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : f.number, c = Math.round((((l = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : l.number) + 2) * 100) / 100, M = (I = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.wind) == null ? void 0 : I.number, w = (E = (k = t == null ? void 0 : t.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : E.number;
|
|
719
|
+
for (let T = 0; T < (e == null ? void 0 : e.length); T++) {
|
|
720
|
+
const x = e[T], O = (D = (q = x == null ? void 0 : x.meteo) == null ? void 0 : q.wave) == null ? void 0 : D.sig, R = (H = x == null ? void 0 : x.meteo) == null ? void 0 : H.wind, J = T ? p(x.eta).diff(p(e[T - 1].eta), "hour", !0) : 0;
|
|
721
|
+
s = J > s ? J : s, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...O, dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h }), (O == null ? void 0 : O.height) >= r ? x.isDangerous = !0 : (O == null ? void 0 : O.height) >= d ? x.isSevere = !0 : (O == null ? void 0 : O.height) >= h && (x.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: c, svThd4Wd: M, hvThd4Wd: w }), (R == null ? void 0 : R.scale) >= c ? (x.isDangerous = !0, delete x.isSevere, delete x.isHeavy) : (R == null ? void 0 : R.scale) > M ? (x.isDangerous || (x.isSevere = !0), delete x.isHeavy) : (R == null ? void 0 : R.scale) === w && !x.isDangerous && !x.isSevere && (x.isHeavy = !0), i += x.isDangerous ? J : 0, n += x.isSevere ? J : 0, o += x.isHeavy ? J : 0;
|
|
722
722
|
}
|
|
723
|
-
return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100,
|
|
723
|
+
return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, s = Math.round(s), { sample: e, dangerous: i, severe: n, heavy: o, step: s < 3 ? 3 : s, wind: { dgThd4Wd: c, svThd4Wd: M, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h } };
|
|
724
724
|
}
|
|
725
725
|
}
|
|
726
|
-
const
|
|
726
|
+
const At = new bt();
|
|
727
727
|
let C;
|
|
728
728
|
try {
|
|
729
|
-
C =
|
|
729
|
+
C = ut.getLogger("vessel");
|
|
730
730
|
} catch {
|
|
731
731
|
} finally {
|
|
732
732
|
}
|
|
733
|
-
const
|
|
734
|
-
var
|
|
735
|
-
class
|
|
733
|
+
const gt = new yt("", !0);
|
|
734
|
+
var pt = /* @__PURE__ */ ((N) => (N.common = "common", N.container = "container", N.tugs = "tugs", N))(pt || {}), vt = /* @__PURE__ */ ((N) => (N.Ballast = "Ballast", N.Laden = "Laden", N))(vt || {}), wt = /* @__PURE__ */ ((N) => (N.Cp = "CP", N.Perf = "Basis", N.Instruct = "Other", N))(wt || {});
|
|
735
|
+
class W {
|
|
736
736
|
/**
|
|
737
737
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
738
738
|
* 方形系数(block coefficient)
|
|
@@ -745,11 +745,11 @@ class R {
|
|
|
745
745
|
* @param draught 吃水 m
|
|
746
746
|
* @return [0.55, 0.85]
|
|
747
747
|
*/
|
|
748
|
-
static blockCoefficient(
|
|
749
|
-
let n = Math.round(
|
|
748
|
+
static blockCoefficient(e, t, a, i) {
|
|
749
|
+
let n = Math.round(e / (t * a * i) * 100) / 100;
|
|
750
750
|
n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
|
|
751
|
-
const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85],
|
|
752
|
-
return o[
|
|
751
|
+
const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = o.map((r) => Math.abs(r - n));
|
|
752
|
+
return o[s.indexOf(Math.min(...s))];
|
|
753
753
|
}
|
|
754
754
|
/**
|
|
755
755
|
* @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
|
|
@@ -762,8 +762,8 @@ class R {
|
|
|
762
762
|
* @param g 重力加速度 9.80 m/s^2
|
|
763
763
|
* @return [0.05, 0.30]
|
|
764
764
|
*/
|
|
765
|
-
static froudeNumber(
|
|
766
|
-
let i = Math.round(Math.sqrt(
|
|
765
|
+
static froudeNumber(e, t, a = 9.8) {
|
|
766
|
+
let i = Math.round(Math.sqrt(e * e / (a * t)) * 100) / 100;
|
|
767
767
|
return i = i < 0.05 ? 0.05 : i > 0.3 ? 0.3 : i, i;
|
|
768
768
|
}
|
|
769
769
|
/**
|
|
@@ -773,7 +773,7 @@ class R {
|
|
|
773
773
|
* @param loadCondition
|
|
774
774
|
* @private
|
|
775
775
|
*/
|
|
776
|
-
static amendFactor(
|
|
776
|
+
static amendFactor(e, t, a) {
|
|
777
777
|
const i = {
|
|
778
778
|
0.55: [1.7, -1.4, -7.4],
|
|
779
779
|
0.6: [2.2, -2.5, -9.7],
|
|
@@ -791,8 +791,8 @@ class R {
|
|
|
791
791
|
0.75: [2.6, -12.5, -13.5],
|
|
792
792
|
0.8: [3, -16.3, -21.6],
|
|
793
793
|
0.85: [3.4, -20.9, 31.8]
|
|
794
|
-
}[
|
|
795
|
-
return a === "Laden" && (o = i[
|
|
794
|
+
}[e];
|
|
795
|
+
return a === "Laden" && (o = i[e]), o[0] + o[1] * t + o[2] * Math.pow(t, 2);
|
|
796
796
|
}
|
|
797
797
|
/**
|
|
798
798
|
* 失速方向因子
|
|
@@ -805,9 +805,9 @@ class R {
|
|
|
805
805
|
* @param bn
|
|
806
806
|
* @private
|
|
807
807
|
*/
|
|
808
|
-
static directionFactor(
|
|
808
|
+
static directionFactor(e, t = 0) {
|
|
809
809
|
let a;
|
|
810
|
-
return
|
|
810
|
+
return e > 30 && e <= 60 ? a = (1.7 - 0.03 * Math.pow(t - 4, 2)) / 2 : e > 60 && e <= 150 ? a = (0.9 - 0.06 * Math.pow(t - 6, 2)) / 2 : e > 150 && e <= 180 ? a = (0.4 - 0.03 * Math.pow(t - 8, 2)) / 2 : a = 1, Math.round(a * 1e5) / 1e5;
|
|
811
811
|
}
|
|
812
812
|
/**
|
|
813
813
|
* 失速船型因子
|
|
@@ -821,9 +821,9 @@ class R {
|
|
|
821
821
|
* @param kts
|
|
822
822
|
* @private
|
|
823
823
|
*/
|
|
824
|
-
static vesselTagFactor(
|
|
824
|
+
static vesselTagFactor(e, t, a, i) {
|
|
825
825
|
let n;
|
|
826
|
-
return a === "container" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (22 * Math.pow(
|
|
826
|
+
return a === "container" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (2.7 * Math.pow(e, 2 / 3)) : n = 0.5 * i / 2 + Math.pow(i, 3) / (2.7 * Math.pow(e, 2 / 3)), n;
|
|
827
827
|
}
|
|
828
828
|
/**
|
|
829
829
|
* 浪高影响因子
|
|
@@ -831,10 +831,10 @@ class R {
|
|
|
831
831
|
* @param beta 夹角
|
|
832
832
|
* @private
|
|
833
833
|
*/
|
|
834
|
-
static waveHeightFactor(
|
|
835
|
-
|
|
834
|
+
static waveHeightFactor(e, t) {
|
|
835
|
+
e = e < 3 ? e * 0.7 : e, e = e < 0 ? 0.2 : e, e = e > 6 ? e - 0.9 * (e - 6) : e, e = e > 9 ? 9 : e;
|
|
836
836
|
let a;
|
|
837
|
-
return t > 30 && t <= 60 ? a = -0.6 : t > 60 && t <= 90 ? a = -0.4 : t > 90 && t <= 120 ? a =
|
|
837
|
+
return t > 30 && t <= 60 ? a = -0.6 : t > 60 && t <= 90 ? a = -0.4 : t > 90 && t <= 120 ? a = e < 3 ? 0.4 : -0.3 : t > 120 && t <= 150 ? a = e < 3 ? 0.6 : -0.5 : t > 150 && t <= 180 ? a = e < 3 ? 0.7 : -0.6 : a = -0.7, Math.round(a * (0.144 * Math.pow(e, 2) + 0.278 * e) * 1e4) / 1e4;
|
|
838
838
|
}
|
|
839
839
|
/**
|
|
840
840
|
* 组装船舶运行参数
|
|
@@ -844,18 +844,18 @@ class R {
|
|
|
844
844
|
* @param bearing 方位角
|
|
845
845
|
* @private
|
|
846
846
|
*/
|
|
847
|
-
static assembleProperties(
|
|
847
|
+
static assembleProperties(e, t, a, i) {
|
|
848
848
|
var M;
|
|
849
|
-
const n =
|
|
849
|
+
const n = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, o = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, r = e.deadweight ?? 67035.7773, d = ((M = e == null ? void 0 : e.type) == null ? void 0 : M.toLowerCase()) || "common";
|
|
850
850
|
return {
|
|
851
851
|
tag: d.indexOf("container") > -1 ? "container" : d.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
852
852
|
lbp: n,
|
|
853
853
|
loadCondition: t,
|
|
854
854
|
draught: o,
|
|
855
|
-
breadthMoulded:
|
|
855
|
+
breadthMoulded: s,
|
|
856
856
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
857
857
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
858
|
-
displacement: Math.round((r / 1.025 + o *
|
|
858
|
+
displacement: Math.round((r / 1.025 + o * s * n * 0.7) * 1e4) / 1e4,
|
|
859
859
|
// 换算为m/s
|
|
860
860
|
speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
861
861
|
bearing: i || 90
|
|
@@ -872,29 +872,29 @@ class R {
|
|
|
872
872
|
* @param useRouteParam true 启用设置速度
|
|
873
873
|
* @param options
|
|
874
874
|
*/
|
|
875
|
-
static async speedLoseAt(
|
|
875
|
+
static async speedLoseAt(e, t, a, i = "", n = 2, o = !0, s = !1, r = {}) {
|
|
876
876
|
let d;
|
|
877
|
-
if (t.velocity &&
|
|
877
|
+
if (t.velocity && s && (e.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
|
|
878
878
|
let h;
|
|
879
879
|
try {
|
|
880
880
|
i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
|
|
881
|
-
const { weatherModels: b, marineModels: j } = await
|
|
881
|
+
const { weatherModels: b, marineModels: j } = await dt.autoPickMeteoModel(i), F = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
|
|
882
882
|
...r,
|
|
883
883
|
pastDays: 1,
|
|
884
884
|
forecastDays: 1,
|
|
885
885
|
weatherModels: b,
|
|
886
886
|
marineModels: j
|
|
887
|
-
}), [g] =
|
|
888
|
-
h =
|
|
887
|
+
}), [g] = dt.pickHourly(F, a);
|
|
888
|
+
h = dt.toLegacy(g);
|
|
889
889
|
} catch (b) {
|
|
890
890
|
C.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: i }, b);
|
|
891
891
|
}
|
|
892
|
-
const c =
|
|
892
|
+
const c = W.currentFactor(e.bearing, h == null ? void 0 : h.current, n), M = W.weatherFactor(e, h, c), w = Math.round((e.speed * 1.943844 + M + c) * 100) / 100;
|
|
893
893
|
d = {
|
|
894
894
|
meteo: { ...h },
|
|
895
895
|
wxFactor: M,
|
|
896
896
|
cFactor: c,
|
|
897
|
-
speed: t.velocity &&
|
|
897
|
+
speed: t.velocity && s ? t.velocity : w < 0 ? 1 : w,
|
|
898
898
|
eta: a.utc().format(),
|
|
899
899
|
etd: a.utc().format()
|
|
900
900
|
};
|
|
@@ -902,7 +902,7 @@ class R {
|
|
|
902
902
|
d = {
|
|
903
903
|
wxFactor: 0,
|
|
904
904
|
cFactor: 0,
|
|
905
|
-
speed: t.velocity &&
|
|
905
|
+
speed: t.velocity && s ? t.velocity : Math.round(e.speed * 1.943844 * 100) / 100,
|
|
906
906
|
eta: a.utc().format(),
|
|
907
907
|
etd: a.utc().format()
|
|
908
908
|
};
|
|
@@ -922,53 +922,53 @@ class R {
|
|
|
922
922
|
* @param options
|
|
923
923
|
* @private
|
|
924
924
|
*/
|
|
925
|
-
static async speedLoseInHoursStep(
|
|
925
|
+
static async speedLoseInHoursStep(e, t, a, i, n, o, s = "", r = !0, d = !1, h = {}) {
|
|
926
926
|
t.utc();
|
|
927
927
|
const c = t.clone().add(14, "days"), M = [], w = [], b = [];
|
|
928
|
-
let j = 0,
|
|
928
|
+
let j = 0, F = 0, g, v;
|
|
929
929
|
for (let f = 0; f < o.length - 1; f++) {
|
|
930
930
|
let u = o[f];
|
|
931
|
-
u.distanceFromStart = Math.round((n +
|
|
931
|
+
u.distanceFromStart = Math.round((n + F) * 1e3) / 1e3;
|
|
932
932
|
const l = o[f + 1];
|
|
933
|
-
if (
|
|
933
|
+
if (e.bearing = V.calculateBearing(u, l, !l.gcToPrevious), u.bearing = e.bearing, u.suspend && d) {
|
|
934
934
|
u.eta = u.eta || t.utc().format(), u.elapsed = u.elapsed ?? 0;
|
|
935
935
|
const k = u.suspend - u.elapsed;
|
|
936
936
|
if (i - j > k)
|
|
937
937
|
i = i - j - k, t.add(k, "hour"), u.elapsed = u.suspend;
|
|
938
938
|
else {
|
|
939
|
-
const
|
|
940
|
-
u.elapsed +=
|
|
939
|
+
const E = i - j;
|
|
940
|
+
u.elapsed += E, t.add(E, "hour"), i = 0;
|
|
941
941
|
}
|
|
942
942
|
if (C == null || C.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`, h.requestId, u), i === 0)
|
|
943
|
-
return u.distanceFromPrevious =
|
|
943
|
+
return u.distanceFromPrevious = F, { etd: t, from: v || u, to: u, next: o.filter((E) => E), wps: M, days: w, all: b };
|
|
944
944
|
} else
|
|
945
945
|
u.suspend = 0;
|
|
946
|
-
r = t.isAfter(c) ? !1 : r, u = await
|
|
946
|
+
r = t.isAfter(c) ? !1 : r, u = await W.speedLoseAt(e, u, t, s, 0, r, d, h), b.push(u), v = v || u, u.important && M.push(u), t.isSameOrAfter(a) && (w.push(u), a.add(24, "hour"));
|
|
947
947
|
const m = V.calculateDistance(u, l, !l.gcToPrevious);
|
|
948
|
-
let I = Math.round(m /
|
|
948
|
+
let I = Math.round(m / v.speed * 1e5) / 1e5;
|
|
949
949
|
if (j + I < i) {
|
|
950
950
|
if (j += I, t.add(I, "hour"), delete o[f], C == null || C.debug(
|
|
951
951
|
`[%s] go to %j from %j with ${m}nm, and cost ${I} hours`,
|
|
952
952
|
h.requestId,
|
|
953
953
|
{ lat: l.lat, lng: l.lng },
|
|
954
|
-
{ lat:
|
|
955
|
-
),
|
|
956
|
-
g = l, g.eta = t.utc().format(), g.distanceFromPrevious = m, g.distanceFromStart = Math.round((n +
|
|
954
|
+
{ lat: v.lat, lng: v.lng, etd: v.etd }
|
|
955
|
+
), F += m, o.filter((k) => k).length <= 1) {
|
|
956
|
+
g = l, g.eta = t.utc().format(), g.distanceFromPrevious = m, g.distanceFromStart = Math.round((n + F) * 1e4) / 1e4, M.push(g), b.push(g), delete o[f + 1];
|
|
957
957
|
break;
|
|
958
958
|
}
|
|
959
959
|
} else {
|
|
960
960
|
I = i - j, t.add(I, "hour");
|
|
961
|
-
const k = z.roundPrecision(
|
|
962
|
-
g = V.calculateCoordinate(u,
|
|
961
|
+
const k = z.roundPrecision(v.speed * I, 5);
|
|
962
|
+
g = V.calculateCoordinate(u, e.bearing, k, "nauticalmiles", !l.gcToPrevious), g.eta = t.utc().format(), o[f] = g, C == null || C.debug(
|
|
963
963
|
`[%s] go to %j from %j with ${k}nm, and cost ${I} hours`,
|
|
964
964
|
h.requestId,
|
|
965
965
|
{ lat: g.lat, lng: g.lng },
|
|
966
966
|
{ lat: u.lat, lng: u.lng, etd: u.etd }
|
|
967
|
-
),
|
|
967
|
+
), F += k, g.distanceFromPrevious = Math.round(F * 1e4) / 1e4, g.distanceFromStart = Math.round((n + F) * 1e4) / 1e4;
|
|
968
968
|
break;
|
|
969
969
|
}
|
|
970
970
|
}
|
|
971
|
-
return { etd: t, from:
|
|
971
|
+
return { etd: t, from: v, to: g, next: o.filter((f) => f), wps: M, days: w, all: b };
|
|
972
972
|
}
|
|
973
973
|
/**
|
|
974
974
|
* 洋流影响因子
|
|
@@ -976,8 +976,8 @@ class R {
|
|
|
976
976
|
* @param current 洋流要素
|
|
977
977
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
978
978
|
*/
|
|
979
|
-
static currentFactor(
|
|
980
|
-
const i = (
|
|
979
|
+
static currentFactor(e, t, a = 0) {
|
|
980
|
+
const i = (e - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
981
981
|
if (Math.abs(i) === Math.PI / 2)
|
|
982
982
|
return 0;
|
|
983
983
|
let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(i);
|
|
@@ -989,16 +989,16 @@ class R {
|
|
|
989
989
|
* @param wwc 气象要素
|
|
990
990
|
* @param cFactor 洋流因子
|
|
991
991
|
*/
|
|
992
|
-
static weatherFactor(
|
|
993
|
-
var w, b, j,
|
|
994
|
-
C == null || C.debug("calculate weather factor via: %j", { ...
|
|
995
|
-
const i =
|
|
996
|
-
let r = Math.abs(
|
|
992
|
+
static weatherFactor(e, t, a = 0) {
|
|
993
|
+
var w, b, j, F, g, v, f;
|
|
994
|
+
C == null || C.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
995
|
+
const i = W.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = W.froudeNumber(e.speed - n, e.lbp), s = W.amendFactor(i, o, e.loadCondition);
|
|
996
|
+
let r = Math.abs(e.bearing % 360 - (((w = t == null ? void 0 : t.wind) == null ? void 0 : w.degree) % 360 || 0));
|
|
997
997
|
r = r > 180 ? 360 - r : r;
|
|
998
|
-
const d =
|
|
999
|
-
let c = d *
|
|
1000
|
-
c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1,
|
|
1001
|
-
const M =
|
|
998
|
+
const d = W.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), h = W.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (j = t == null ? void 0 : t.wind) == null ? void 0 : j.kts);
|
|
999
|
+
let c = d * s * h / 100 * (e.speed - n);
|
|
1000
|
+
c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), C == null || C.debug("wind wx factor = %d", c), r = Math.abs(e.bearing % 360 - (((g = (F = t == null ? void 0 : t.wave) == null ? void 0 : F.sig) == null ? void 0 : g.degree) % 360 || 0)), r = r > 180 ? 360 - r : r;
|
|
1001
|
+
const M = W.waveHeightFactor(((f = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : f.height) ?? 1, r);
|
|
1002
1002
|
return C == null || C.debug("wave wx factor = %d", M), c = Math.abs(c) > Math.abs(M) ? c : c * 0.3 + M * 0.7, C == null || C.debug("weather factor = %d", c), c = Math.abs(c) > 3 ? 3 * (Math.abs(c) / c) + Math.abs(c) / c * (Math.abs(c) - 2) * 0.1 : c, Math.round((c || 0) * 100) / 100;
|
|
1003
1003
|
}
|
|
1004
1004
|
/**
|
|
@@ -1014,45 +1014,45 @@ class R {
|
|
|
1014
1014
|
* @param useRouteParam
|
|
1015
1015
|
* @param options
|
|
1016
1016
|
*/
|
|
1017
|
-
static async analyseInstant(
|
|
1017
|
+
static async analyseInstant(e, t, a, i, n, o = "", s = 0, r = !0, d = !1, h = {}) {
|
|
1018
1018
|
var K, G, X, Q, Z, $, tt;
|
|
1019
|
-
const c =
|
|
1020
|
-
|
|
1021
|
-
const { route: M, waypoints: w } = n.points, b = V.calculateSubRoute(
|
|
1019
|
+
const c = p().valueOf();
|
|
1020
|
+
e.lng = z.convertToStdLng(e.lng);
|
|
1021
|
+
const { route: M, waypoints: w } = n.points, b = V.calculateSubRoute(e, M);
|
|
1022
1022
|
if (((K = b[0]) == null ? void 0 : K.length) <= 1)
|
|
1023
1023
|
return;
|
|
1024
|
-
const { v0: j, label:
|
|
1025
|
-
v0:
|
|
1026
|
-
label:
|
|
1024
|
+
const { v0: j, label: F } = e.sog ? {
|
|
1025
|
+
v0: e.sog,
|
|
1026
|
+
label: e.label || "Other"
|
|
1027
1027
|
/* Instruct */
|
|
1028
1028
|
} : {
|
|
1029
1029
|
v0: i.speed,
|
|
1030
1030
|
label: "CP"
|
|
1031
1031
|
/* Cp */
|
|
1032
|
-
}, g =
|
|
1033
|
-
|
|
1032
|
+
}, g = W.assembleProperties(a, i.loadCondition, j, 0), v = w.length ? V.calculateSubWaypoints(e, w) : [];
|
|
1033
|
+
v.forEach((A) => A.important = !0);
|
|
1034
1034
|
const f = {
|
|
1035
|
-
from: { ...
|
|
1035
|
+
from: { ...e },
|
|
1036
1036
|
route: b,
|
|
1037
|
-
waypoints:
|
|
1037
|
+
waypoints: v,
|
|
1038
1038
|
v0: j,
|
|
1039
|
-
label:
|
|
1039
|
+
label: F
|
|
1040
1040
|
}, u = {
|
|
1041
1041
|
hours: [],
|
|
1042
1042
|
days: [],
|
|
1043
1043
|
wps: [],
|
|
1044
1044
|
all: []
|
|
1045
1045
|
};
|
|
1046
|
-
|
|
1047
|
-
let l = V.simplifyRouteToCoordinates(b,
|
|
1048
|
-
t =
|
|
1049
|
-
const
|
|
1046
|
+
s || (V.calculateRouteDistance(b) / i.speed <= 72 ? s = 3 : s = 6);
|
|
1047
|
+
let l = V.simplifyRouteToCoordinates(b, v, 0), m = 0, I = 0, k = 0, E = 0;
|
|
1048
|
+
t = p(t).utc();
|
|
1049
|
+
const q = t.clone();
|
|
1050
1050
|
for (; l.length > 0; ) {
|
|
1051
|
-
const
|
|
1051
|
+
const A = s - t.hour() % s, L = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, S = await W.speedLoseInHoursStep(
|
|
1052
1052
|
g,
|
|
1053
1053
|
t,
|
|
1054
|
-
|
|
1055
|
-
|
|
1054
|
+
q,
|
|
1055
|
+
L,
|
|
1056
1056
|
m,
|
|
1057
1057
|
l,
|
|
1058
1058
|
o,
|
|
@@ -1061,35 +1061,37 @@ class R {
|
|
|
1061
1061
|
h
|
|
1062
1062
|
);
|
|
1063
1063
|
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)), l = S == null ? void 0 : S.next, !l.length) {
|
|
1064
|
-
const
|
|
1065
|
-
|
|
1064
|
+
const Y = await W.speedLoseAt(g, S.to, p(S.to.eta), o, 0, r, d, h);
|
|
1065
|
+
Y.bearing = g.bearing, u.hours.push(Y), u.all.push(Y);
|
|
1066
1066
|
}
|
|
1067
1067
|
m += Math.round((((X = S == null ? void 0 : S.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
1068
1068
|
}
|
|
1069
|
-
const
|
|
1070
|
-
for (let
|
|
1071
|
-
const
|
|
1072
|
-
I += (
|
|
1069
|
+
const D = u.hours;
|
|
1070
|
+
for (let A = 0; A < D.length - 1; A++) {
|
|
1071
|
+
const L = p(D[A + 1].eta).diff(D[A].etd, "hour", !0) || 1;
|
|
1072
|
+
I += (D[A].wxFactor || 0) * L, k += (D[A].cFactor || 0) * L, E += L;
|
|
1073
1073
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1074
|
+
const H = D.reduce((A, L) => A + (L.suspend || 0), 0);
|
|
1075
|
+
(Q = u.wps) == null || Q.forEach((A, L) => {
|
|
1076
|
+
A.positionTime = p.utc(A.etd || A.eta).unix();
|
|
1077
|
+
const S = u.wps[L - 1];
|
|
1077
1078
|
if (S) {
|
|
1078
|
-
const
|
|
1079
|
-
|
|
1079
|
+
const Y = A.distanceFromStart - S.distanceFromStart, P = p(A.eta || A.etd).diff(p(S.etd || S.eta), "h", !0);
|
|
1080
|
+
A.avgSpd = Math.round(Y / P * 100) / 100, S.bearing = V.calculateBearing(S, A);
|
|
1080
1081
|
}
|
|
1081
|
-
}), u.wps = (Z = u.wps) == null ? void 0 : Z.reduce((
|
|
1082
|
-
const
|
|
1083
|
-
f.distance = Math.round(
|
|
1084
|
-
const { distanceInECA:
|
|
1082
|
+
}), u.wps = (Z = u.wps) == null ? void 0 : Z.reduce((A, L) => (A.some((S) => Math.round(S.positionTime / 60) === Math.round(L.positionTime / 60)) || A.push(L), A), []), u.all = ($ = u.all) == null ? void 0 : $.reduce((A, L) => (L.positionTime = p.utc(L.etd || L.eta).unix(), A.some((S) => Math.round(S.positionTime / 60) === Math.round(L.positionTime / 60)) || A.push(L), A), []), f.sample = u;
|
|
1083
|
+
const T = u.hours.at(0), x = u.hours.at(-1);
|
|
1084
|
+
f.distance = Math.round(x.distanceFromStart * 1e3) / 1e3, f.etd = p(T.eta).utc().format(), f.eta = p(x.eta).utc().format(), f.wxFactor = Math.round(I / E * 1e3) / 1e3, f.cFactor = Math.round(k / E * 1e3) / 1e3, f.avgSpeed = Math.round(x.distanceFromStart / E * 1e3) / 1e3, f.totalHrs = Math.round(E * 1e3) / 1e3, f.suspend = Math.round(H * 1e3) / 1e3;
|
|
1085
|
+
const O = z.roundPrecision(i.dgo / 24 * H, 3), { distanceInECA: R, hoursInECA: J, totalDgoConsInECA: ot, eca: et } = await this.calculateECA(f, i, h), st = z.roundPrecision(i.fo / 24 * (E - J), 3), it = z.roundPrecision(i.dgo / 24 * E + O, 3);
|
|
1085
1086
|
f.extend = {
|
|
1086
|
-
eca:
|
|
1087
|
-
distanceInECA:
|
|
1088
|
-
hoursInECA:
|
|
1089
|
-
totalDgoConsInECA:
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1087
|
+
eca: et,
|
|
1088
|
+
distanceInECA: R,
|
|
1089
|
+
hoursInECA: J,
|
|
1090
|
+
totalDgoConsInECA: ot,
|
|
1091
|
+
totalDgoConsInSuspend: O
|
|
1092
|
+
}, f.totalFoCons = st < 0 ? 0 : st, f.totalDgoCons = it;
|
|
1093
|
+
const at = p().valueOf() - c, ct = ((tt = u == null ? void 0 : u.hours) == null ? void 0 : tt.length) || 1;
|
|
1094
|
+
return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, at, ct, Math.round(at / ct * 1e3) / 1e3), f;
|
|
1093
1095
|
}
|
|
1094
1096
|
/**
|
|
1095
1097
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -1106,77 +1108,79 @@ class R {
|
|
|
1106
1108
|
* @param useRouteParam
|
|
1107
1109
|
* @param options
|
|
1108
1110
|
*/
|
|
1109
|
-
static async analyseInstantWithThreshed(
|
|
1110
|
-
var X, Q, Z, $, tt,
|
|
1111
|
-
const w =
|
|
1112
|
-
|
|
1113
|
-
const { v0: b, label: j } =
|
|
1114
|
-
v0:
|
|
1115
|
-
label:
|
|
1111
|
+
static async analyseInstantWithThreshed(e, t, a, i, n, o, s, r = "", d = 3, h = !0, c = !1, M = {}) {
|
|
1112
|
+
var X, Q, Z, $, tt, A, L;
|
|
1113
|
+
const w = p().valueOf();
|
|
1114
|
+
e.lng = z.convertToStdLng(e.lng);
|
|
1115
|
+
const { v0: b, label: j } = e.sog ? {
|
|
1116
|
+
v0: e.sog,
|
|
1117
|
+
label: e.label || "Other"
|
|
1116
1118
|
/* Instruct */
|
|
1117
1119
|
} : {
|
|
1118
1120
|
v0: n.speed,
|
|
1119
1121
|
label: "CP"
|
|
1120
1122
|
/* Cp */
|
|
1121
|
-
},
|
|
1123
|
+
}, F = W.assembleProperties(i, n.loadCondition, b, 0), g = V.calculateSubRoute(e, o);
|
|
1122
1124
|
if (((X = g[0]) == null ? void 0 : X.length) <= 1)
|
|
1123
1125
|
return;
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1126
|
-
let f = V.simplifyRouteToCoordinates(g,
|
|
1126
|
+
const v = s.length ? V.calculateSubWaypoints(e, s) : [];
|
|
1127
|
+
v.forEach((S) => S.important = !0);
|
|
1128
|
+
let f = V.simplifyRouteToCoordinates(g, v, 0), u = 0, l = 0, m = 0, I = 0;
|
|
1127
1129
|
const k = {
|
|
1128
1130
|
hours: [],
|
|
1129
1131
|
wps: [],
|
|
1130
1132
|
days: [],
|
|
1131
1133
|
all: []
|
|
1132
1134
|
};
|
|
1133
|
-
t =
|
|
1134
|
-
const
|
|
1135
|
+
t = p(t).utc();
|
|
1136
|
+
const E = t.clone();
|
|
1135
1137
|
for (; f.length > 0; ) {
|
|
1136
1138
|
const S = d - t.hour() % d;
|
|
1137
|
-
let
|
|
1138
|
-
|
|
1139
|
-
const P = await
|
|
1140
|
-
if (k.all.push(...P.all), (Q = P.from) != null && Q.speed && (k.hours.push(P.from), P != null && P.wps && k.wps.push(...P.wps), k.days.push(...P.days)), f = P == null ? void 0 : P.next, f.length || k.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, !
|
|
1139
|
+
let Y = Math.ceil(t.clone().add(S, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
1140
|
+
Y = t.clone().add(Y, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : Y;
|
|
1141
|
+
const P = await W.speedLoseInHoursStep(F, t, E, Y, u, f, r, h, c, M);
|
|
1142
|
+
if (k.all.push(...P.all), (Q = P.from) != null && Q.speed && (k.hours.push(P.from), P != null && P.wps && k.wps.push(...P.wps), k.days.push(...P.days)), f = P == null ? void 0 : P.next, f.length || k.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, !Y)
|
|
1141
1143
|
break;
|
|
1142
1144
|
}
|
|
1143
|
-
k.wps = ($ = k.wps) == null ? void 0 : $.reduce((S,
|
|
1144
|
-
const P = k.wps[
|
|
1145
|
+
k.wps = ($ = k.wps) == null ? void 0 : $.reduce((S, Y) => (S.some((P) => Math.round(p(P.etd).unix() / 60) === Math.round(p(Y.etd).unix() / 60)) || S.push(Y), S), []), k.all = (tt = k.all) == null ? void 0 : tt.reduce((S, Y) => (Y.positionTime = p.utc(Y.etd || Y.eta).unix(), S.some((P) => Math.round(p(P.etd).unix() / 60) === Math.round(p(Y.etd).unix() / 60)) || S.push(Y), S), []), (A = k.wps) == null || A.forEach((S, Y) => {
|
|
1146
|
+
const P = k.wps[Y - 1];
|
|
1145
1147
|
if (P) {
|
|
1146
|
-
const
|
|
1147
|
-
S.avgSpd = Math.round(
|
|
1148
|
+
const ht = S.distanceFromStart - P.distanceFromStart, lt = p(S.eta || S.etd).diff(p(P.etd || P.eta), "h", !0);
|
|
1149
|
+
S.avgSpd = Math.round(ht / lt * 100) / 100, P.bearing = V.calculateBearing(P, S);
|
|
1148
1150
|
}
|
|
1149
1151
|
});
|
|
1150
|
-
const
|
|
1151
|
-
for (let S = 0; S <
|
|
1152
|
-
const
|
|
1153
|
-
l +=
|
|
1152
|
+
const q = k.hours;
|
|
1153
|
+
for (let S = 0; S < q.length - 1; S++) {
|
|
1154
|
+
const Y = p(q[S + 1].eta).diff(q[S].etd, "hour", !0);
|
|
1155
|
+
l += q[S].wxFactor * Y, m += q[S].cFactor * Y, I += Y;
|
|
1154
1156
|
}
|
|
1155
|
-
const
|
|
1157
|
+
const D = q.reduce((S, Y) => S + (Y.suspend || 0), 0), H = k.hours.at(0), T = k.hours.at(-1), x = await V.calculateRangeRoute(H, T, g), O = await V.calculateRangeWaypoints(H, T, g, v), R = {
|
|
1156
1158
|
sample: k,
|
|
1157
|
-
distance: Math.round(((
|
|
1159
|
+
distance: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1158
1160
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1159
|
-
etd:
|
|
1160
|
-
eta:
|
|
1161
|
+
etd: p(H.eta).utc().format(),
|
|
1162
|
+
eta: p(T == null ? void 0 : T.eta).utc().format(),
|
|
1161
1163
|
wxFactor: Math.round(l / I * 1e3) / 1e3,
|
|
1162
1164
|
cFactor: Math.round(m / I * 1e3) / 1e3,
|
|
1163
|
-
avgSpeed: Math.round(((
|
|
1165
|
+
avgSpeed: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) / I * 1e3) / 1e3,
|
|
1164
1166
|
totalHrs: Math.round(I * 1e3) / 1e3,
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1167
|
+
suspend: Math.round(D * 1e3) / 1e3,
|
|
1168
|
+
from: H,
|
|
1169
|
+
to: T,
|
|
1170
|
+
route: x,
|
|
1171
|
+
waypoints: O,
|
|
1169
1172
|
v0: b,
|
|
1170
1173
|
label: j
|
|
1171
|
-
}, { distanceInECA:
|
|
1172
|
-
|
|
1173
|
-
eca:
|
|
1174
|
-
distanceInECA:
|
|
1175
|
-
hoursInECA:
|
|
1176
|
-
totalDgoConsInECA:
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1174
|
+
}, J = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: et, totalDgoConsInECA: st, eca: it } = await this.calculateECA(R, n, M), rt = z.roundPrecision(n.fo / 24 * (I - et), 3), at = z.roundPrecision(n.dgo / 24 * I + J, 3);
|
|
1175
|
+
R.extend = {
|
|
1176
|
+
eca: it,
|
|
1177
|
+
distanceInECA: ot,
|
|
1178
|
+
hoursInECA: et,
|
|
1179
|
+
totalDgoConsInECA: st,
|
|
1180
|
+
totalDgoConsInSuspend: J
|
|
1181
|
+
}, R.totalDgoCons = at, R.totalFoCons = rt < 0 ? 0 : rt;
|
|
1182
|
+
const K = p().valueOf() - w, G = ((L = k == null ? void 0 : k.hours) == null ? void 0 : L.length) || 1;
|
|
1183
|
+
return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", M == null ? void 0 : M.requestId, K, G, Math.round(K / G * 1e3) / 1e3), R;
|
|
1180
1184
|
}
|
|
1181
1185
|
/**
|
|
1182
1186
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1193,34 +1197,34 @@ class R {
|
|
|
1193
1197
|
* @param lane 基础航线(重要转向点)
|
|
1194
1198
|
* @param options
|
|
1195
1199
|
*/
|
|
1196
|
-
static async analyseCost(
|
|
1197
|
-
var g,
|
|
1198
|
-
const o =
|
|
1199
|
-
|
|
1200
|
+
static async analyseCost(e, t, a, i, n = {}) {
|
|
1201
|
+
var g, v;
|
|
1202
|
+
const o = p().valueOf(), s = [];
|
|
1203
|
+
e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
|
|
1200
1204
|
const r = V.calculateRouteDistance(i.route);
|
|
1201
1205
|
let d = 0;
|
|
1202
1206
|
a.forEach((f) => {
|
|
1203
1207
|
const u = Math.ceil(r / f.speed / 24);
|
|
1204
1208
|
d = d < u ? u : d;
|
|
1205
1209
|
}), d = d * 1.3;
|
|
1206
|
-
const h =
|
|
1210
|
+
const h = p.utc(e.etd).add(d ?? 14, "day");
|
|
1207
1211
|
let c = 1;
|
|
1208
1212
|
for (const f of a) {
|
|
1209
|
-
const u = JSON.parse(JSON.stringify(i.route)), l = JSON.parse(JSON.stringify(i.waypoints)), m = await
|
|
1210
|
-
{ lat:
|
|
1211
|
-
|
|
1213
|
+
const u = JSON.parse(JSON.stringify(i.route)), l = JSON.parse(JSON.stringify(i.waypoints)), m = await W.analyseInstantWithThreshed(
|
|
1214
|
+
{ lat: e.lat, lng: e.lng },
|
|
1215
|
+
e.etd,
|
|
1212
1216
|
h,
|
|
1213
1217
|
t,
|
|
1214
1218
|
f,
|
|
1215
1219
|
u,
|
|
1216
1220
|
l,
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
+
e.meteoVendor,
|
|
1222
|
+
e.speedStep,
|
|
1223
|
+
e.useMeteo,
|
|
1224
|
+
e.useRouteParam,
|
|
1221
1225
|
n
|
|
1222
1226
|
);
|
|
1223
|
-
m && (await
|
|
1227
|
+
m && (await W.calculateCost(m, f, e, n), s.push(m), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, c, e.etd, h.format(), {
|
|
1224
1228
|
cost: m.cost.total,
|
|
1225
1229
|
hire: m.cost.hire,
|
|
1226
1230
|
bunker: m.cost.bunker,
|
|
@@ -1229,23 +1233,23 @@ class R {
|
|
|
1229
1233
|
cp: `${f.speed}/${f.fo}/${f.dgo}`
|
|
1230
1234
|
})), c++;
|
|
1231
1235
|
}
|
|
1232
|
-
|
|
1233
|
-
const M =
|
|
1236
|
+
s.sort((f, u) => f.cost.total - u.cost.total);
|
|
1237
|
+
const M = s.at(0), w = s.at(1), b = [];
|
|
1234
1238
|
if (b.push({ combined: !1, speeds: [M], cost: (g = M.cost) == null ? void 0 : g.total }), w) {
|
|
1235
|
-
const f = M.cost.cp, u = w.cost.cp, l =
|
|
1239
|
+
const f = M.cost.cp, u = w.cost.cp, l = p(M.eta), m = p(M.etd), I = l.diff(m, "days", !0);
|
|
1236
1240
|
let k = Math.ceil(I / 2);
|
|
1237
|
-
k = k > 7 ? 7 : k <
|
|
1238
|
-
let
|
|
1239
|
-
for (; k >=
|
|
1240
|
-
const
|
|
1241
|
-
if (
|
|
1241
|
+
k = k > 7 ? 7 : k < e.alterStep ? e.alterStep : k;
|
|
1242
|
+
let E = 2, q = { combined: !1, speeds: [w], cost: (v = w.cost) == null ? void 0 : v.total }, D;
|
|
1243
|
+
for (; k >= e.alterStep; ) {
|
|
1244
|
+
const H = await W.combinedAnalyse(e, t, h, [f, u], i, k, { ...n, level: E });
|
|
1245
|
+
if (q.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = q, q = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), k <= e.alterStep)
|
|
1242
1246
|
break;
|
|
1243
|
-
k = Math.ceil(k / 2),
|
|
1247
|
+
k = Math.ceil(k / 2), E += 1;
|
|
1244
1248
|
}
|
|
1245
|
-
b.push(
|
|
1249
|
+
b.push(q), D && b.push(D);
|
|
1246
1250
|
}
|
|
1247
|
-
const
|
|
1248
|
-
return C == null || C.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId,
|
|
1251
|
+
const F = p().valueOf() - o;
|
|
1252
|
+
return C == null || C.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, F), b.sort((f, u) => f.cost - u.cost);
|
|
1249
1253
|
}
|
|
1250
1254
|
/**
|
|
1251
1255
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1257,22 +1261,22 @@ class R {
|
|
|
1257
1261
|
* @param step 步长,7,4,2,1
|
|
1258
1262
|
* @param options
|
|
1259
1263
|
*/
|
|
1260
|
-
static async combinedAnalyse(
|
|
1261
|
-
|
|
1262
|
-
const r = await
|
|
1263
|
-
C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j",
|
|
1264
|
+
static async combinedAnalyse(e, t, a, i, n, o, s = {}) {
|
|
1265
|
+
s.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, o);
|
|
1266
|
+
const r = await W.alternateAnalyse(e, t, a, i, 0, n, o, s), d = r.reduce((u, l) => u + l.cost.total, 0), h = r.reduce((u, l) => u + l.cost.hire, 0), c = r.reduce((u, l) => u + l.cost.bunker, 0), M = r.reduce((u, l) => u + l.distance, 0), w = r.reduce((u, l) => u + l.totalHrs, 0);
|
|
1267
|
+
C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
|
|
1264
1268
|
cost: d,
|
|
1265
1269
|
hire: h,
|
|
1266
1270
|
bunker: c,
|
|
1267
1271
|
distance: M,
|
|
1268
1272
|
hours: w
|
|
1269
1273
|
});
|
|
1270
|
-
const b = await
|
|
1271
|
-
return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j",
|
|
1274
|
+
const b = await W.alternateAnalyse(e, t, a, i, 1, n, o, s), j = b.reduce((u, l) => u + l.cost.total, 0), F = b.reduce((u, l) => u + l.cost.hire, 0), g = b.reduce((u, l) => u + l.cost.bunker, 0), v = b.reduce((u, l) => u + l.distance, 0), f = b.reduce((u, l) => u + l.totalHrs, 0);
|
|
1275
|
+
return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
|
|
1272
1276
|
cost: j,
|
|
1273
|
-
hire:
|
|
1277
|
+
hire: F,
|
|
1274
1278
|
bunker: g,
|
|
1275
|
-
distance:
|
|
1279
|
+
distance: v,
|
|
1276
1280
|
hours: f
|
|
1277
1281
|
}), d < j ? { combined: !0, cost: Math.round(d * 1e3) / 1e3, speeds: r, step: o } : { combined: !0, cost: Math.round(j * 1e3) / 1e3, speeds: b, step: o };
|
|
1278
1282
|
}
|
|
@@ -1287,26 +1291,26 @@ class R {
|
|
|
1287
1291
|
* @param step 步长,7,4,2,1
|
|
1288
1292
|
* @param options
|
|
1289
1293
|
*/
|
|
1290
|
-
static async alternateAnalyse(
|
|
1294
|
+
static async alternateAnalyse(e, t, a, i, n, o, s, r = {}) {
|
|
1291
1295
|
var M, w;
|
|
1292
|
-
let d =
|
|
1293
|
-
const h = { lat:
|
|
1296
|
+
let d = p.utc(e.etd);
|
|
1297
|
+
const h = { lat: e.lat, lng: e.lng }, c = [];
|
|
1294
1298
|
for (; d.isBefore(a); ) {
|
|
1295
|
-
const b = d.clone().utc().add(
|
|
1299
|
+
const b = d.clone().utc().add(s, "day"), j = JSON.parse(JSON.stringify(o.route)), F = JSON.parse(JSON.stringify(o.waypoints)), g = i[n], v = await W.analyseInstantWithThreshed(
|
|
1296
1300
|
h,
|
|
1297
1301
|
d.utc().format(),
|
|
1298
1302
|
b,
|
|
1299
1303
|
t,
|
|
1300
1304
|
g,
|
|
1301
1305
|
j,
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1306
|
+
F,
|
|
1307
|
+
e.meteoVendor,
|
|
1308
|
+
e.speedStep,
|
|
1309
|
+
e.useMeteo,
|
|
1310
|
+
e.useRouteParam,
|
|
1307
1311
|
r
|
|
1308
1312
|
);
|
|
1309
|
-
|
|
1313
|
+
v && (await W.calculateCost(v, g, e, r), C == null || C.info(
|
|
1310
1314
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1311
1315
|
r.requestId,
|
|
1312
1316
|
r.level,
|
|
@@ -1314,17 +1318,17 @@ class R {
|
|
|
1314
1318
|
d.utc().format(),
|
|
1315
1319
|
b.utc().format(),
|
|
1316
1320
|
{
|
|
1317
|
-
cost:
|
|
1318
|
-
hire:
|
|
1319
|
-
bunker:
|
|
1320
|
-
distance:
|
|
1321
|
-
hours:
|
|
1321
|
+
cost: v.cost.total,
|
|
1322
|
+
hire: v.cost.hire,
|
|
1323
|
+
bunker: v.cost.bunker,
|
|
1324
|
+
distance: v.distance,
|
|
1325
|
+
hours: v.totalHrs,
|
|
1322
1326
|
cp: `${g.speed}/${g.fo}/${g.dgo}`
|
|
1323
1327
|
}
|
|
1324
1328
|
)), r.counter = r.counter + 1;
|
|
1325
|
-
const f = (w = (M =
|
|
1329
|
+
const f = (w = (M = v == null ? void 0 : v.sample) == null ? void 0 : M.hours) == null ? void 0 : w.at(-1);
|
|
1326
1330
|
if (f)
|
|
1327
|
-
h.lat = f.lat, h.lng = f.lng, d =
|
|
1331
|
+
h.lat = f.lat, h.lng = f.lng, d = p(f.eta), c.push(v), n = n ? 0 : 1;
|
|
1328
1332
|
else
|
|
1329
1333
|
break;
|
|
1330
1334
|
}
|
|
@@ -1337,39 +1341,39 @@ class R {
|
|
|
1337
1341
|
* @param props
|
|
1338
1342
|
* @param options
|
|
1339
1343
|
*/
|
|
1340
|
-
static async calculateCost(
|
|
1344
|
+
static async calculateCost(e, t, a, i = {}) {
|
|
1341
1345
|
var n;
|
|
1342
|
-
if (
|
|
1343
|
-
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3,
|
|
1344
|
-
|
|
1345
|
-
total: Math.round((
|
|
1346
|
-
hire:
|
|
1347
|
-
bunker: Math.round((
|
|
1346
|
+
if (e) {
|
|
1347
|
+
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, s = (a.dailyHire || 0) * e.suspend / 24, r = Math.round(s + e.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3, d = Math.round(e.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, h = Math.round((e.totalDgoCons + (((n = e.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
|
|
1348
|
+
e.cost = {
|
|
1349
|
+
total: Math.round((r + d + h) * 1e3) / 1e3,
|
|
1350
|
+
hire: r,
|
|
1351
|
+
bunker: Math.round((d + h) * 1e3) / 1e3,
|
|
1348
1352
|
cp: t
|
|
1349
1353
|
};
|
|
1350
1354
|
}
|
|
1351
|
-
return
|
|
1355
|
+
return e;
|
|
1352
1356
|
}
|
|
1353
1357
|
/**
|
|
1354
1358
|
* 计算单cp模式下的ECA属性
|
|
1355
1359
|
*
|
|
1356
1360
|
*/
|
|
1357
|
-
static async calculateECA(
|
|
1361
|
+
static async calculateECA(e, t, a = {}) {
|
|
1358
1362
|
var r, d, h, c;
|
|
1359
|
-
const i = await V.intersectInECA((
|
|
1360
|
-
let n = 0, o = 0,
|
|
1361
|
-
(d = (r =
|
|
1362
|
-
M.positionTime =
|
|
1363
|
+
const i = await V.intersectInECA((e == null ? void 0 : e.route) || []);
|
|
1364
|
+
let n = 0, o = 0, s = 0;
|
|
1365
|
+
(d = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || d.forEach((M) => {
|
|
1366
|
+
M.positionTime = p.utc(M.etd || M.eta).unix();
|
|
1363
1367
|
});
|
|
1364
1368
|
for (const M of i) {
|
|
1365
1369
|
n += M.distance;
|
|
1366
|
-
const w = await V.deadReckoningTime((h = M.waypoints) == null ? void 0 : h.at(0),
|
|
1367
|
-
M.in = w, M.out = b, M.totalHrs = z.roundPrecision((b.positionTime - w.positionTime) / 3600, 3), M.totalDgoCons = z.roundPrecision(t.fo / 24 * M.totalHrs, 3), o += M.totalHrs,
|
|
1370
|
+
const w = await V.deadReckoningTime((h = M.waypoints) == null ? void 0 : h.at(0), e.sample.all || e.sample.wps), b = await V.deadReckoningTime((c = M.waypoints) == null ? void 0 : c.at(-1), e.sample.all || e.sample.wps);
|
|
1371
|
+
M.in = w, M.out = b, M.totalHrs = z.roundPrecision((b.positionTime - w.positionTime) / 3600, 3), M.totalDgoCons = z.roundPrecision(t.fo / 24 * M.totalHrs, 3), o += M.totalHrs, s += M.totalDgoCons;
|
|
1368
1372
|
}
|
|
1369
|
-
return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3),
|
|
1373
|
+
return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3), s = z.roundPrecision(s, 3), {
|
|
1370
1374
|
distanceInECA: n,
|
|
1371
1375
|
hoursInECA: o,
|
|
1372
|
-
totalDgoConsInECA:
|
|
1376
|
+
totalDgoConsInECA: s,
|
|
1373
1377
|
eca: i
|
|
1374
1378
|
};
|
|
1375
1379
|
}
|
|
@@ -1378,64 +1382,64 @@ class R {
|
|
|
1378
1382
|
* @param speeds
|
|
1379
1383
|
* @param options
|
|
1380
1384
|
*/
|
|
1381
|
-
static async mergeSpeeds(
|
|
1385
|
+
static async mergeSpeeds(e, t = {}) {
|
|
1382
1386
|
var f, u;
|
|
1383
1387
|
const a = {
|
|
1384
1388
|
hours: [],
|
|
1385
1389
|
wps: [],
|
|
1386
1390
|
days: []
|
|
1387
|
-
}, i =
|
|
1391
|
+
}, i = e.reduce((l, m) => l + m.distance, 0), n = e.reduce((l, m) => {
|
|
1388
1392
|
var I;
|
|
1389
1393
|
return l + (((I = m.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1390
|
-
}, 0), o =
|
|
1394
|
+
}, 0), o = e.reduce((l, m) => l + m.totalHrs, 0), s = e.reduce((l, m) => {
|
|
1391
1395
|
var I;
|
|
1392
1396
|
return l + (((I = m.extend) == null ? void 0 : I.hoursInECA) || 0);
|
|
1393
|
-
}, 0), r =
|
|
1397
|
+
}, 0), r = e.reduce((l, m) => {
|
|
1394
1398
|
var I;
|
|
1395
1399
|
return l + (((I = m.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1396
|
-
}, 0), d =
|
|
1397
|
-
let
|
|
1398
|
-
for (const l of
|
|
1400
|
+
}, 0), d = e.reduce((l, m) => l + m.wxFactor * m.totalHrs / o, 0), h = e.reduce((l, m) => l + m.cFactor * m.totalHrs / o, 0), c = e.reduce((l, m) => l + m.totalFoCons, 0), M = e.reduce((l, m) => l + m.totalDgoCons, 0), w = e.reduce((l, m) => l + m.cost.total, 0), b = e.reduce((l, m) => l + m.cost.hire, 0), j = e.reduce((l, m) => l + m.cost.bunker, 0), F = [], g = [];
|
|
1401
|
+
let v;
|
|
1402
|
+
for (const l of e) {
|
|
1399
1403
|
g.push(...((f = l.extend) == null ? void 0 : f.eca) || []);
|
|
1400
|
-
const m = l.sample.hours, I = l.sample.wps, k = l.sample.days,
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
}), I.at(0).distanceFromPrevious =
|
|
1404
|
-
|
|
1405
|
-
}), k.at(0).distanceFromPrevious =
|
|
1406
|
-
|
|
1407
|
-
})),
|
|
1408
|
-
const
|
|
1409
|
-
|
|
1410
|
-
var
|
|
1411
|
-
((
|
|
1412
|
-
}), I.forEach((
|
|
1413
|
-
var
|
|
1414
|
-
((
|
|
1415
|
-
}), k.forEach((
|
|
1416
|
-
var
|
|
1417
|
-
((
|
|
1404
|
+
const m = l.sample.hours, I = l.sample.wps, k = l.sample.days, E = m.at(0);
|
|
1405
|
+
v && (E.distanceFromPrevious = v.distanceFromPrevious, E.distanceFromStart = v.distanceFromStart, m.forEach((T, x) => {
|
|
1406
|
+
x && (T.distanceFromStart = T.distanceFromStart + v.distanceFromStart);
|
|
1407
|
+
}), I.at(0).distanceFromPrevious = v.distanceFromPrevious, I.at(0).distanceFromStart = v.distanceFromStart, I.forEach((T, x) => {
|
|
1408
|
+
x && (T.distanceFromStart = T.distanceFromStart + v.distanceFromStart);
|
|
1409
|
+
}), k.at(0).distanceFromPrevious = v.distanceFromPrevious, k.at(0).distanceFromStart = v.distanceFromStart, k.forEach((T, x) => {
|
|
1410
|
+
x && (T.distanceFromStart = T.distanceFromStart + v.distanceFromStart);
|
|
1411
|
+
})), E.cp = l.cost.cp;
|
|
1412
|
+
const q = [l.etd, l.eta], D = F.findIndex((T) => T.id === E.cp.id);
|
|
1413
|
+
D === -1 ? (E.cp.segment = [q], F.push(E.cp)) : F[D].segment.push(q), m.forEach((T) => {
|
|
1414
|
+
var O;
|
|
1415
|
+
((O = a.hours) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.hours.push(T);
|
|
1416
|
+
}), I.forEach((T) => {
|
|
1417
|
+
var O;
|
|
1418
|
+
((O = a.wps) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.wps.push(T);
|
|
1419
|
+
}), k.forEach((T) => {
|
|
1420
|
+
var O;
|
|
1421
|
+
((O = a == null ? void 0 : a.days) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.days.push(T);
|
|
1418
1422
|
});
|
|
1419
|
-
const
|
|
1420
|
-
|
|
1423
|
+
const H = (u = a.wps) == null ? void 0 : u.findIndex((T) => T.eta === E.eta);
|
|
1424
|
+
H === -1 ? a.wps.push(E) : a.wps[H] = E, v = m.at(-1);
|
|
1421
1425
|
}
|
|
1422
1426
|
return a.wps.sort((l, m) => {
|
|
1423
|
-
|
|
1427
|
+
p(l.etd).unix() - p(m.etd).unix();
|
|
1424
1428
|
}), a.wps.forEach((l, m) => {
|
|
1425
1429
|
const I = a.wps[m - 1];
|
|
1426
1430
|
if (I) {
|
|
1427
|
-
const k = l.distanceFromStart - (I.distanceFromStart || 0),
|
|
1428
|
-
l.avgSpd =
|
|
1429
|
-
const
|
|
1430
|
-
I.bearing =
|
|
1431
|
+
const k = l.distanceFromStart - (I.distanceFromStart || 0), E = p(l.eta || l.etd).diff(p(I.etd || I.eta), "hour", !0), q = Math.round(k / E * 100) / 100;
|
|
1432
|
+
l.avgSpd = q;
|
|
1433
|
+
const D = V.calculateBearing(I, l);
|
|
1434
|
+
I.bearing = D;
|
|
1431
1435
|
}
|
|
1432
1436
|
}), {
|
|
1433
1437
|
sample: a,
|
|
1434
|
-
etd:
|
|
1435
|
-
eta:
|
|
1436
|
-
from:
|
|
1437
|
-
to:
|
|
1438
|
-
v0:
|
|
1438
|
+
etd: e.at(0).etd,
|
|
1439
|
+
eta: e.at(-1).eta,
|
|
1440
|
+
from: e.at(0).from,
|
|
1441
|
+
to: e.at(-1).to,
|
|
1442
|
+
v0: e.at(0).v0,
|
|
1439
1443
|
label: "Combined",
|
|
1440
1444
|
distance: Math.round(i * 1e3) / 1e3,
|
|
1441
1445
|
totalHrs: Math.round(o * 1e3) / 1e3,
|
|
@@ -1450,27 +1454,27 @@ class R {
|
|
|
1450
1454
|
bunker: Math.round(j * 1e3) / 1e3
|
|
1451
1455
|
},
|
|
1452
1456
|
extend: {
|
|
1453
|
-
cps:
|
|
1457
|
+
cps: F,
|
|
1454
1458
|
eca: g,
|
|
1455
1459
|
distanceInECA: Math.round(n * 1e3) / 1e3,
|
|
1456
|
-
hoursInECA: Math.round(
|
|
1460
|
+
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1457
1461
|
totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
|
|
1458
|
-
speeds:
|
|
1462
|
+
speeds: e
|
|
1459
1463
|
}
|
|
1460
1464
|
};
|
|
1461
1465
|
}
|
|
1462
1466
|
}
|
|
1463
1467
|
export {
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1468
|
+
nt as AISImpl,
|
|
1469
|
+
bt as AlertHelper,
|
|
1470
|
+
Mt as AlertLevel,
|
|
1471
|
+
xt as HifleetImpl,
|
|
1472
|
+
vt as LoadCondition,
|
|
1473
|
+
Dt as MyShipImpl,
|
|
1474
|
+
Et as MyVesselImpl,
|
|
1475
|
+
Nt as ShipxyImpl,
|
|
1476
|
+
W as SpeedHelper,
|
|
1477
|
+
wt as SpeedLabel,
|
|
1478
|
+
pt as VesselTag,
|
|
1479
|
+
At as alertHelper
|
|
1476
1480
|
};
|