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