@idm-plugin/vessel 1.9.5 → 1.9.6
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 +231 -231
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,14 +2,14 @@ var ht = Object.defineProperty;
|
|
|
2
2
|
var lt = (j, e, t) => e in j ? ht(j, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : j[e] = t;
|
|
3
3
|
var z = (j, e, t) => (lt(j, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
4
|
import B from "got";
|
|
5
|
-
import
|
|
5
|
+
import rt from "@log4js-node/log4js-api";
|
|
6
6
|
import g from "moment";
|
|
7
7
|
import { LngLatHelper as J, LaneHelper as W } from "@idm-plugin/geo2";
|
|
8
8
|
import { MeteoHelper2 as ft, MeteoHelper as mt } from "@idm-plugin/meteo2";
|
|
9
9
|
import { Meteo2Assist as ct } from "@idm-plugin/meteo";
|
|
10
10
|
let p;
|
|
11
11
|
try {
|
|
12
|
-
p =
|
|
12
|
+
p = rt.getLogger("vessel");
|
|
13
13
|
} catch {
|
|
14
14
|
} finally {
|
|
15
15
|
}
|
|
@@ -22,7 +22,7 @@ class et {
|
|
|
22
22
|
let t, n;
|
|
23
23
|
switch (e) {
|
|
24
24
|
case 0:
|
|
25
|
-
t = "在航(主机推动)", n = "
|
|
25
|
+
t = "在航(主机推动)", n = "Underway Using Engine";
|
|
26
26
|
break;
|
|
27
27
|
case 1:
|
|
28
28
|
t = "锚泊", n = "Anchored";
|
|
@@ -63,13 +63,13 @@ class jt extends et {
|
|
|
63
63
|
this.clientId = t, this.clientSecret = n;
|
|
64
64
|
}
|
|
65
65
|
async authToken(t = {}) {
|
|
66
|
-
const n = "https://svc.data.myvessel.cn/ada/oauth/token",
|
|
66
|
+
const n = "https://svc.data.myvessel.cn/ada/oauth/token", r = {
|
|
67
67
|
searchParams: {
|
|
68
68
|
client_id: this.clientId,
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
}, a = await B.post(n,
|
|
72
|
+
}, a = await B.post(n, r).json();
|
|
73
73
|
p == null || p.info("[%s] fetch access token from: %s - %j", t.requestId, n, a), a.error || (this.token = {
|
|
74
74
|
accessToken: a.access_token,
|
|
75
75
|
tokenType: a.token_type,
|
|
@@ -80,18 +80,18 @@ class jt extends et {
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async realTimePosition(t, n = {}) {
|
|
83
|
-
var d,
|
|
83
|
+
var d, i, h;
|
|
84
84
|
(!this.token || g().diff(g(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(n);
|
|
85
|
-
const
|
|
85
|
+
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", a = {
|
|
86
86
|
headers: {
|
|
87
|
-
Authorization: `${(
|
|
87
|
+
Authorization: `${(i = this.token) == null ? void 0 : i.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
|
|
88
88
|
},
|
|
89
89
|
searchParams: { mmsi: t }
|
|
90
90
|
};
|
|
91
|
-
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId,
|
|
92
|
-
const o = await B.get(
|
|
91
|
+
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, r, a);
|
|
92
|
+
const o = await B.get(r, a).json();
|
|
93
93
|
if (o.code)
|
|
94
|
-
return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId,
|
|
94
|
+
return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, r, { message: o.message, status: o.status, code: o.code }), o;
|
|
95
95
|
const s = o.data;
|
|
96
96
|
for (const M in s)
|
|
97
97
|
!isNaN(s[M]) && Number(s[M]) !== 1 / 0 && (s[M] = Number(s[M]));
|
|
@@ -131,31 +131,31 @@ class jt extends et {
|
|
|
131
131
|
} else
|
|
132
132
|
return {};
|
|
133
133
|
}
|
|
134
|
-
async trajectory(t, n,
|
|
134
|
+
async trajectory(t, n, r, a, o = !0, s = {}) {
|
|
135
135
|
(!this.token || g().diff(g(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(s);
|
|
136
|
-
const d = await this.realTimePosition(t, s),
|
|
137
|
-
for (; h.diff(
|
|
138
|
-
await this.trajectoryIn30Day(t,
|
|
139
|
-
return await this.trajectoryIn30Day(t,
|
|
136
|
+
const d = await this.realTimePosition(t, s), i = g(n), h = g(r), M = [];
|
|
137
|
+
for (; h.diff(i, "day", !0) > 30; )
|
|
138
|
+
await this.trajectoryIn30Day(t, i, i.clone().add(30, "day"), d, a, M, s), i.add(30, "day");
|
|
139
|
+
return await this.trajectoryIn30Day(t, i, h, d, a, M, s), M;
|
|
140
140
|
}
|
|
141
|
-
async trajectoryIn30Day(t, n,
|
|
142
|
-
var m, F, x,
|
|
143
|
-
const
|
|
141
|
+
async trajectoryIn30Day(t, n, r, a, o, s, d = {}) {
|
|
142
|
+
var m, F, x, v, b;
|
|
143
|
+
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
|
|
144
144
|
headers: {
|
|
145
145
|
Authorization: `${(m = this.token) == null ? void 0 : m.tokenType} ${(F = this.token) == null ? void 0 : F.accessToken}`
|
|
146
146
|
},
|
|
147
147
|
json: {
|
|
148
148
|
mmsi: t,
|
|
149
149
|
startTime: n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
|
|
150
|
-
endTime:
|
|
150
|
+
endTime: r.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
|
-
p == null || p.info("[%s] fetch trajectory from: %s - %j", d.requestId,
|
|
154
|
-
const M = await B.post(
|
|
153
|
+
p == null || p.info("[%s] fetch trajectory from: %s - %j", d.requestId, i, h);
|
|
154
|
+
const M = await B.post(i, h).json();
|
|
155
155
|
if (M.code)
|
|
156
|
-
return p == null || p.warn("[%s] fetch trajectory failed: %j", d.requestId,
|
|
156
|
+
return p == null || p.warn("[%s] fetch trajectory failed: %j", d.requestId, i, { message: M.message, status: M.status, code: M.code }), M;
|
|
157
157
|
let y = -1;
|
|
158
|
-
const
|
|
158
|
+
const w = g(`${(v = (x = M.data) == null ? void 0 : x[0]) == null ? void 0 : v.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
159
159
|
return (b = M.data) == null || b.forEach((c) => {
|
|
160
160
|
for (const Y in c)
|
|
161
161
|
!isNaN(c[Y]) && Number(c[Y]) !== 1 / 0 && (c[Y] = Number(c[Y]));
|
|
@@ -177,7 +177,7 @@ class jt extends et {
|
|
|
177
177
|
method: "trajectory",
|
|
178
178
|
vendor: "myVessel",
|
|
179
179
|
utc: f.utc().format()
|
|
180
|
-
}, D = Math.floor(f.diff(
|
|
180
|
+
}, D = Math.floor(f.diff(w, "minute", !0) / (o || 1));
|
|
181
181
|
D !== y && (y = D, s.push(S));
|
|
182
182
|
}), s;
|
|
183
183
|
}
|
|
@@ -189,20 +189,20 @@ class Et extends et {
|
|
|
189
189
|
this.token = t;
|
|
190
190
|
}
|
|
191
191
|
async realTimePosition(t, n = {}) {
|
|
192
|
-
const
|
|
192
|
+
const r = "https://api.hifleet.com/position/position/get/token", a = {
|
|
193
193
|
searchParams: {
|
|
194
194
|
mmsi: t,
|
|
195
195
|
usertoken: this.token
|
|
196
196
|
}
|
|
197
|
-
}, o = await B.post(
|
|
198
|
-
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId,
|
|
197
|
+
}, o = await B.post(r, a).json();
|
|
198
|
+
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, r, a);
|
|
199
199
|
const s = o == null ? void 0 : o.list;
|
|
200
200
|
if (!s)
|
|
201
|
-
return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId,
|
|
202
|
-
for (const
|
|
203
|
-
!isNaN(s[
|
|
201
|
+
return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, r, o), o;
|
|
202
|
+
for (const w in s)
|
|
203
|
+
!isNaN(s[w]) && Number(s[w]) !== 1 / 0 && (s[w] = Number(s[w]));
|
|
204
204
|
s.status = s.sp > 3 ? 0 : 1;
|
|
205
|
-
const d = s.status, { labelCn:
|
|
205
|
+
const d = s.status, { labelCn: i, labelEn: h } = this.parseStatus(d), M = g(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
206
206
|
return {
|
|
207
207
|
mmsi: s.m,
|
|
208
208
|
name: s.n,
|
|
@@ -226,14 +226,14 @@ class Et extends et {
|
|
|
226
226
|
positionTime: M.unix(),
|
|
227
227
|
utc: M.utc().format(),
|
|
228
228
|
status: d,
|
|
229
|
-
labelCn:
|
|
229
|
+
labelCn: i,
|
|
230
230
|
labelEn: h,
|
|
231
231
|
method: "position",
|
|
232
232
|
vendor: "hifleet"
|
|
233
233
|
};
|
|
234
234
|
}
|
|
235
235
|
async search(t, n = {}) {
|
|
236
|
-
let
|
|
236
|
+
let r = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
237
237
|
const a = {
|
|
238
238
|
searchParams: {
|
|
239
239
|
keyword: t
|
|
@@ -244,8 +244,8 @@ class Et extends et {
|
|
|
244
244
|
Host: "www.hifleet.com"
|
|
245
245
|
}
|
|
246
246
|
};
|
|
247
|
-
let o = await B.post(
|
|
248
|
-
p == null || p.info("[%s] fetch vessel props from: %s - %j", n.requestId,
|
|
247
|
+
let o = await B.post(r, a).json();
|
|
248
|
+
p == null || p.info("[%s] fetch vessel props from: %s - %j", n.requestId, r, a), o instanceof Array && (o = o[0]);
|
|
249
249
|
for (const d in o)
|
|
250
250
|
!isNaN(o[d]) && Number(o[d]) !== 1 / 0 && (o[d] = Number(o[d]));
|
|
251
251
|
const s = {
|
|
@@ -258,10 +258,10 @@ class Et extends et {
|
|
|
258
258
|
draught: o.dr,
|
|
259
259
|
type: o.t
|
|
260
260
|
};
|
|
261
|
-
return
|
|
261
|
+
return r = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(r, a).json(), p == null || p.info("[%s] search vessel dead weight from: %s - %j", n.requestId, r, a), o instanceof Array && (o = o[0]), o && (s.deadweight = Number(o.dwt)), s;
|
|
262
262
|
}
|
|
263
263
|
async suggest(t, n = {}) {
|
|
264
|
-
const
|
|
264
|
+
const r = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", a = {
|
|
265
265
|
searchParams: {
|
|
266
266
|
q: t
|
|
267
267
|
},
|
|
@@ -270,8 +270,8 @@ class Et extends et {
|
|
|
270
270
|
Origin: "https://www.hifleet.com",
|
|
271
271
|
Host: "www.hifleet.com"
|
|
272
272
|
}
|
|
273
|
-
}, o = await B.post(
|
|
274
|
-
p == null || p.info("[%s] suggest vessel props from: %s - %j", n.requestId,
|
|
273
|
+
}, o = await B.post(r, a).json();
|
|
274
|
+
p == null || p.info("[%s] suggest vessel props from: %s - %j", n.requestId, r, a);
|
|
275
275
|
const s = [];
|
|
276
276
|
for (const d of o)
|
|
277
277
|
s.push({
|
|
@@ -281,30 +281,30 @@ class Et extends et {
|
|
|
281
281
|
imo: !d.imo || isNaN(d.imo) ? null : Number(d.imo),
|
|
282
282
|
score: d._score
|
|
283
283
|
});
|
|
284
|
-
return s.sort((d,
|
|
284
|
+
return s.sort((d, i) => i.score - d.score), s;
|
|
285
285
|
}
|
|
286
|
-
async trajectory(t, n,
|
|
286
|
+
async trajectory(t, n, r, a, o = !0, s = {}) {
|
|
287
287
|
var c, f, l;
|
|
288
288
|
const d = await this.realTimePosition(t, s);
|
|
289
|
-
let
|
|
290
|
-
const h = g(
|
|
289
|
+
let i = g(n);
|
|
290
|
+
const h = g(r), M = g();
|
|
291
291
|
if (o) {
|
|
292
|
-
let u = h.diff(
|
|
293
|
-
u < 0 ?
|
|
292
|
+
let u = h.diff(i, "d", !0);
|
|
293
|
+
u < 0 ? i = h.clone().subtract(40, "d") : u < 30 ? i.subtract(10, "d") : u < 60 ? i.subtract(5, "d") : i = h.clone().subtract(80, "d"), u = M.diff(h, "d", !0), h.add(u > 10 ? 240 : u * 24, "h");
|
|
294
294
|
}
|
|
295
295
|
const y = {
|
|
296
296
|
searchParams: {
|
|
297
297
|
endtime: h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
298
|
-
starttime:
|
|
298
|
+
starttime: i.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
299
299
|
mmsi: t,
|
|
300
300
|
usertoken: this.token
|
|
301
301
|
}
|
|
302
|
-
},
|
|
303
|
-
p == null || p.info("[%s] fetch trajectory from: %s - %j", s.requestId,
|
|
302
|
+
}, w = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", m = await B.get(w, y).json();
|
|
303
|
+
p == null || p.info("[%s] fetch trajectory from: %s - %j", s.requestId, w, y);
|
|
304
304
|
let F;
|
|
305
305
|
m && (F = ((f = (c = m.ships) == null ? void 0 : c.offors) == null ? void 0 : f.ship) || [], F.length || p == null || p.warn("[%s] fetch trajectory failed: %j", s.requestId, m));
|
|
306
306
|
const x = [];
|
|
307
|
-
let
|
|
307
|
+
let v = -1;
|
|
308
308
|
const b = g(`${(l = F == null ? void 0 : F[0]) == null ? void 0 : l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
309
309
|
for (const u of F) {
|
|
310
310
|
for (const P in u)
|
|
@@ -329,7 +329,7 @@ class Et extends et {
|
|
|
329
329
|
method: "trajectory",
|
|
330
330
|
vendor: "hifleet"
|
|
331
331
|
}, E = Math.floor(I.diff(b, "minute", !0) / (a || 1));
|
|
332
|
-
E !==
|
|
332
|
+
E !== v && (v = E, x.push(Y));
|
|
333
333
|
}
|
|
334
334
|
return x;
|
|
335
335
|
}
|
|
@@ -341,19 +341,19 @@ class Nt extends et {
|
|
|
341
341
|
this.token = t;
|
|
342
342
|
}
|
|
343
343
|
async realTimePosition(t, n = {}) {
|
|
344
|
-
const
|
|
344
|
+
const r = {
|
|
345
345
|
searchParams: {
|
|
346
346
|
id: t,
|
|
347
347
|
k: this.token,
|
|
348
348
|
enc: 1
|
|
349
349
|
}
|
|
350
|
-
}, a = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(a,
|
|
351
|
-
if (p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, a,
|
|
350
|
+
}, a = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(a, r).json();
|
|
351
|
+
if (p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, a, r), (o == null ? void 0 : o.status) !== 0)
|
|
352
352
|
return o;
|
|
353
353
|
const s = o.data[0];
|
|
354
354
|
for (const y in s)
|
|
355
355
|
!isNaN(s[y]) && Number(s[y]) !== 1 / 0 && (s[y] = Number(s[y]));
|
|
356
|
-
const { labelCn: d, labelEn:
|
|
356
|
+
const { labelCn: d, labelEn: i } = await this.parseStatus(s.navistat), h = g.unix(s.lasttime);
|
|
357
357
|
return {
|
|
358
358
|
mmsi: s.ShipID,
|
|
359
359
|
name: s.name,
|
|
@@ -371,28 +371,28 @@ class Nt extends et {
|
|
|
371
371
|
positionTime: s.lasttime,
|
|
372
372
|
utc: h.utc().format(),
|
|
373
373
|
status: s.navistat,
|
|
374
|
-
labelEn:
|
|
374
|
+
labelEn: i,
|
|
375
375
|
labelCn: d,
|
|
376
376
|
method: "position",
|
|
377
377
|
vendor: "shipxy"
|
|
378
378
|
};
|
|
379
379
|
}
|
|
380
|
-
async trajectory(t, n,
|
|
380
|
+
async trajectory(t, n, r, a, o = !0, s = {}) {
|
|
381
381
|
var b;
|
|
382
|
-
const d = await this.realTimePosition(t, s),
|
|
382
|
+
const d = await this.realTimePosition(t, s), i = g(n), h = g(r), M = "https://api.shipxy.com/apicall/GetShipTrack", y = {
|
|
383
383
|
searchParams: {
|
|
384
384
|
id: t,
|
|
385
385
|
k: this.token,
|
|
386
386
|
enc: 1,
|
|
387
387
|
cut: 0,
|
|
388
|
-
btm:
|
|
388
|
+
btm: i.unix(),
|
|
389
389
|
etm: h.unix()
|
|
390
390
|
}
|
|
391
|
-
},
|
|
392
|
-
if (p == null || p.info("[%s] fetch trajectory from: %s - %j", s.requestId, M, y), (
|
|
393
|
-
return
|
|
394
|
-
const m =
|
|
395
|
-
let
|
|
391
|
+
}, w = await B.get(M, y).json();
|
|
392
|
+
if (p == null || p.info("[%s] fetch trajectory from: %s - %j", s.requestId, M, y), (w == null ? void 0 : w.status) !== 0)
|
|
393
|
+
return w;
|
|
394
|
+
const m = w == null ? void 0 : w.points, F = [], x = g.unix((b = m[0]) == null ? void 0 : b.utc);
|
|
395
|
+
let v = -1;
|
|
396
396
|
for (const c of m) {
|
|
397
397
|
const f = g.unix(c.utc), l = {
|
|
398
398
|
imo: d == null ? void 0 : d.imo,
|
|
@@ -406,7 +406,7 @@ class Nt extends et {
|
|
|
406
406
|
method: "trajectory",
|
|
407
407
|
vendor: "shipxy"
|
|
408
408
|
}, u = Math.floor(f.diff(x, "minute", !0) / (a || 1));
|
|
409
|
-
u !==
|
|
409
|
+
u !== v && (v = u, F.push(l));
|
|
410
410
|
}
|
|
411
411
|
return F;
|
|
412
412
|
}
|
|
@@ -418,26 +418,26 @@ class Tt extends et {
|
|
|
418
418
|
this.token = t;
|
|
419
419
|
}
|
|
420
420
|
async getShipId(t, n = {}) {
|
|
421
|
-
const
|
|
421
|
+
const r = {
|
|
422
422
|
headers: {
|
|
423
423
|
appKey: this.token
|
|
424
424
|
},
|
|
425
425
|
json: {
|
|
426
426
|
mmsiList: t
|
|
427
427
|
}
|
|
428
|
-
}, a = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await B.post(a,
|
|
429
|
-
return p == null || p.info("[%s] fetch ship id from: %s - %j", n.requestId, a,
|
|
428
|
+
}, a = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await B.post(a, r).json();
|
|
429
|
+
return p == null || p.info("[%s] fetch ship id from: %s - %j", n.requestId, a, r), o.code !== "0" ? o : o.data[0].shipId;
|
|
430
430
|
}
|
|
431
431
|
async getShipInfo(t, n = {}) {
|
|
432
|
-
const
|
|
432
|
+
const r = {
|
|
433
433
|
headers: {
|
|
434
434
|
appKey: this.token
|
|
435
435
|
},
|
|
436
436
|
json: {
|
|
437
437
|
shipId: t
|
|
438
438
|
}
|
|
439
|
-
}, a = "https://api3.myships.com/sp/ships/aissta", o = await B.post(a,
|
|
440
|
-
if (p == null || p.info("[%s] fetch ship info from: %s - %j", n.requestId, a,
|
|
439
|
+
}, a = "https://api3.myships.com/sp/ships/aissta", o = await B.post(a, r).json();
|
|
440
|
+
if (p == null || p.info("[%s] fetch ship info from: %s - %j", n.requestId, a, r), o.code !== "0")
|
|
441
441
|
return o;
|
|
442
442
|
const s = o.data;
|
|
443
443
|
let d = s.imo;
|
|
@@ -452,44 +452,44 @@ class Tt extends et {
|
|
|
452
452
|
};
|
|
453
453
|
}
|
|
454
454
|
async realTimePosition(t, n = {}) {
|
|
455
|
-
const
|
|
455
|
+
const r = await this.getShipId(t, n), a = await this.getShipInfo(r, n), o = {
|
|
456
456
|
headers: {
|
|
457
457
|
appKey: this.token
|
|
458
458
|
},
|
|
459
459
|
json: {
|
|
460
|
-
shipId:
|
|
460
|
+
shipId: r
|
|
461
461
|
}
|
|
462
462
|
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s, o).json();
|
|
463
463
|
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, s, o);
|
|
464
|
-
const
|
|
465
|
-
for (const m in
|
|
466
|
-
!isNaN(
|
|
467
|
-
const { labelCn: h, labelEn: M } = await this.parseStatus(
|
|
464
|
+
const i = d.data[0];
|
|
465
|
+
for (const m in i)
|
|
466
|
+
!isNaN(i[m]) && Number(i[m]) !== 1 / 0 && (i[m] = Number(i[m]));
|
|
467
|
+
const { labelCn: h, labelEn: M } = await this.parseStatus(i.aisNavStatus), y = g.unix(i.posTime);
|
|
468
468
|
return {
|
|
469
469
|
...a,
|
|
470
470
|
mmsi: t,
|
|
471
|
-
lat: Math.round(
|
|
472
|
-
lng: Math.round(
|
|
473
|
-
sog: Math.round(
|
|
474
|
-
cog: Math.round(
|
|
475
|
-
hdg: Math.round(
|
|
476
|
-
rot: Math.round(
|
|
477
|
-
positionTime:
|
|
471
|
+
lat: Math.round(i.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
472
|
+
lng: Math.round(i.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
473
|
+
sog: Math.round(i.sog / 10 * 100) / 100,
|
|
474
|
+
cog: Math.round(i.cog / 10 * 100) / 100,
|
|
475
|
+
hdg: Math.round(i.heading * 100) / 100,
|
|
476
|
+
rot: Math.round(i.rot * 100) / 100,
|
|
477
|
+
positionTime: i.posTime,
|
|
478
478
|
utc: y.utc().format(),
|
|
479
|
-
status:
|
|
479
|
+
status: i.aisNavStatus,
|
|
480
480
|
labelEn: M,
|
|
481
481
|
labelCn: h,
|
|
482
482
|
method: "position",
|
|
483
483
|
vendor: "myship"
|
|
484
484
|
};
|
|
485
485
|
}
|
|
486
|
-
async trajectory(t, n,
|
|
487
|
-
const d = g(n),
|
|
488
|
-
for (;
|
|
486
|
+
async trajectory(t, n, r, a, o = !0, s = {}) {
|
|
487
|
+
const d = g(n), i = g(r), h = await this.getShipId(t), M = await this.getShipInfo(h), y = [];
|
|
488
|
+
for (; i.diff(d, "day", !0) > 30; )
|
|
489
489
|
await this.trajectoryIn30Day(h, d.unix(), d.add(30, "day").unix(), M, t, a, y);
|
|
490
|
-
return await this.trajectoryIn30Day(h, d.unix(),
|
|
490
|
+
return await this.trajectoryIn30Day(h, d.unix(), i.unix(), M, t, a, y), y;
|
|
491
491
|
}
|
|
492
|
-
async trajectoryIn30Day(t, n,
|
|
492
|
+
async trajectoryIn30Day(t, n, r, a, o, s, d, i = {}) {
|
|
493
493
|
var x;
|
|
494
494
|
const h = {
|
|
495
495
|
headers: {
|
|
@@ -498,26 +498,26 @@ class Tt extends et {
|
|
|
498
498
|
json: {
|
|
499
499
|
shipId: t,
|
|
500
500
|
startTime: n,
|
|
501
|
-
endTime:
|
|
501
|
+
endTime: r
|
|
502
502
|
}
|
|
503
503
|
}, M = "https://api3.myships.com/sp/ships/position/history", y = await B.post(M, h).json();
|
|
504
|
-
if (p == null || p.info("[%s] fetch trajectory from: %s - %j",
|
|
505
|
-
return p == null || p.warn("[%s] invoke myship trajectory failed: %j",
|
|
506
|
-
const
|
|
507
|
-
for (const
|
|
508
|
-
!isNaN(v
|
|
509
|
-
const m = g.unix((x =
|
|
504
|
+
if (p == null || p.info("[%s] fetch trajectory from: %s - %j", i.requestId, M, h), y.code !== "0")
|
|
505
|
+
return p == null || p.warn("[%s] invoke myship trajectory failed: %j", i.requestId, y), y;
|
|
506
|
+
const w = y.data;
|
|
507
|
+
for (const v in w)
|
|
508
|
+
!isNaN(w[v]) && Number(w[v]) !== 1 / 0 && (w[v] = Number(w[v]));
|
|
509
|
+
const m = g.unix((x = w[0]) == null ? void 0 : x.posTime);
|
|
510
510
|
let F = -1;
|
|
511
|
-
for (const
|
|
512
|
-
const b = g.unix(
|
|
511
|
+
for (const v of w) {
|
|
512
|
+
const b = g.unix(v.posTime), c = {
|
|
513
513
|
imo: a == null ? void 0 : a.imo,
|
|
514
514
|
mmsi: o,
|
|
515
|
-
lat: Math.round(
|
|
516
|
-
lng: Math.round(
|
|
517
|
-
sog: Math.round(
|
|
518
|
-
cog: Math.round(
|
|
519
|
-
hdg: Math.round(
|
|
520
|
-
rot: Math.round(
|
|
515
|
+
lat: Math.round(v.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
516
|
+
lng: Math.round(v.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
517
|
+
sog: Math.round(v.sog / 10 * 100) / 100,
|
|
518
|
+
cog: Math.round(v.cog / 10 * 100) / 100,
|
|
519
|
+
hdg: Math.round(v.heading * 100) / 100,
|
|
520
|
+
rot: Math.round(v.rot * 100) / 100,
|
|
521
521
|
positionTime: b.unix(),
|
|
522
522
|
utc: b.utc().format(),
|
|
523
523
|
method: "trajectory",
|
|
@@ -530,7 +530,7 @@ class Tt extends et {
|
|
|
530
530
|
}
|
|
531
531
|
let _;
|
|
532
532
|
try {
|
|
533
|
-
_ =
|
|
533
|
+
_ = rt.getLogger("vessel");
|
|
534
534
|
} catch {
|
|
535
535
|
} finally {
|
|
536
536
|
}
|
|
@@ -545,18 +545,18 @@ class Mt {
|
|
|
545
545
|
* @param options
|
|
546
546
|
*/
|
|
547
547
|
parsePrinciple(e, t = {}) {
|
|
548
|
-
var s, d,
|
|
548
|
+
var s, d, i;
|
|
549
549
|
_ == null || _.info("[%s] parse rule: %s", t.requestId, e);
|
|
550
|
-
const n = new RegExp("(?<=\\[)(.+)(?=])", "g"),
|
|
550
|
+
const n = new RegExp("(?<=\\[)(.+)(?=])", "g"), r = e.match(n) ? (s = e.match(n)) == null ? void 0 : s[0] : void 0, a = r == null ? void 0 : r.split(";");
|
|
551
551
|
if (!a)
|
|
552
552
|
return;
|
|
553
553
|
const o = {};
|
|
554
554
|
for (let h = 0; h < (a == null ? void 0 : a.length); h++) {
|
|
555
|
-
const M = (
|
|
555
|
+
const M = (i = (d = a[h].match(n)) == null ? void 0 : d[0]) == null ? void 0 : i.split("],");
|
|
556
556
|
if (h === 0 && !M)
|
|
557
557
|
o.scope = a[0];
|
|
558
558
|
else if (M)
|
|
559
|
-
for (let y = 0,
|
|
559
|
+
for (let y = 0, w = M.length; y < w; y++) {
|
|
560
560
|
const m = this.parseRule(M[y]);
|
|
561
561
|
m && (o[m.level] ? m.key ? o[m.level][m == null ? void 0 : m.key] = m : o[m.level] = m : m.key ? o[m.level] = { [m == null ? void 0 : m.key]: m } : o[m.level] = m);
|
|
562
562
|
}
|
|
@@ -572,7 +572,7 @@ class Mt {
|
|
|
572
572
|
parseRule(e, t = {}) {
|
|
573
573
|
var o;
|
|
574
574
|
_ == null || _.info("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
|
|
575
|
-
const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"),
|
|
575
|
+
const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"), r = (o = e == null ? void 0 : e.match(n)) == null ? void 0 : o[0], a = r == null ? void 0 : r.split(",");
|
|
576
576
|
if (a)
|
|
577
577
|
return {
|
|
578
578
|
operator: a[0],
|
|
@@ -589,25 +589,25 @@ class Mt {
|
|
|
589
589
|
* @param options
|
|
590
590
|
*/
|
|
591
591
|
checkWeather(e, t, n = {}) {
|
|
592
|
-
var m, F, x,
|
|
593
|
-
let
|
|
594
|
-
const d = Math.round(((F = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.sigWave) == null ? void 0 : F.number) * 1.6 * 100) / 100,
|
|
592
|
+
var m, F, x, v, b, c, f, l, u, I, S, D, Y, E, P;
|
|
593
|
+
let r = 0, a = 0, o = 0, s = 0;
|
|
594
|
+
const d = Math.round(((F = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.sigWave) == null ? void 0 : F.number) * 1.6 * 100) / 100, i = (v = (x = t == null ? void 0 : t.SEVERE) == null ? void 0 : x.sigWave) == null ? void 0 : v.number, h = (c = (b = t == null ? void 0 : t.HEAVY) == null ? void 0 : b.sigWave) == null ? void 0 : c.number, M = Math.round((((l = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.wind) == null ? void 0 : l.number) + 2) * 100) / 100, y = (I = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : I.number, w = (D = (S = t == null ? void 0 : t.HEAVY) == null ? void 0 : S.wind) == null ? void 0 : D.number;
|
|
595
595
|
for (let T = 0; T < (e == null ? void 0 : e.length); T++) {
|
|
596
596
|
const N = e[T], A = (E = (Y = N == null ? void 0 : N.meteo) == null ? void 0 : Y.wave) == null ? void 0 : E.sig, R = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wind, K = T ? g(N.eta).diff(g(e[T - 1].eta), "hour", !0) : 0;
|
|
597
|
-
s = K > s ? K : s, _ == null || _.info("[%s] check sig.wave: %j", n.requestId, { ...A, dgThd4Wv: d, svThd4Wv:
|
|
597
|
+
s = K > s ? K : s, _ == null || _.info("[%s] check sig.wave: %j", n.requestId, { ...A, dgThd4Wv: d, svThd4Wv: i, hvThd4Wv: h }), (A == null ? void 0 : A.height) >= d ? N.isDangerous = !0 : (A == null ? void 0 : A.height) >= i ? N.isSevere = !0 : (A == null ? void 0 : A.height) >= h && (N.isHeavy = !0), _ == null || _.info("[%s] check wind: %j", n.requestId, { ...R, dgThd4Wd: M, svThd4Wd: y, hvThd4Wd: w }), (R == null ? void 0 : R.scale) >= M ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > y ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === w && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), r += N.isDangerous ? K : 0, a += N.isSevere ? K : 0, o += N.isHeavy ? K : 0;
|
|
598
598
|
}
|
|
599
|
-
return
|
|
599
|
+
return r = Math.round(r * 100) / 100, a = Math.round(a * 100) / 100, o = Math.round(o * 100) / 100, s = Math.round(s), { sample: e, dangerous: r, severe: a, heavy: o, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd: y, hvThd4Wd: w }, sig: { dgThd4Wv: d, svThd4Wv: i, hvThd4Wv: h } };
|
|
600
600
|
}
|
|
601
601
|
}
|
|
602
602
|
const Dt = new Mt();
|
|
603
603
|
let k;
|
|
604
604
|
try {
|
|
605
|
-
k =
|
|
605
|
+
k = rt.getLogger("vessel");
|
|
606
606
|
} catch {
|
|
607
607
|
} finally {
|
|
608
608
|
}
|
|
609
609
|
const gt = new ft("", !0);
|
|
610
|
-
var bt = /* @__PURE__ */ ((j) => (j.common = "common", j.container = "container", j.tugs = "tugs", j))(bt || {}), pt = /* @__PURE__ */ ((j) => (j.Ballast = "Ballast", j.Laden = "Laden", j))(pt || {}),
|
|
610
|
+
var bt = /* @__PURE__ */ ((j) => (j.common = "common", j.container = "container", j.tugs = "tugs", j))(bt || {}), pt = /* @__PURE__ */ ((j) => (j.Ballast = "Ballast", j.Laden = "Laden", j))(pt || {}), wt = /* @__PURE__ */ ((j) => (j.Cp = "CP", j.Perf = "Basis", j.Instruct = "Other", j))(wt || {});
|
|
611
611
|
class O {
|
|
612
612
|
/**
|
|
613
613
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
@@ -621,8 +621,8 @@ class O {
|
|
|
621
621
|
* @param draught 吃水 m
|
|
622
622
|
* @return [0.55, 0.85]
|
|
623
623
|
*/
|
|
624
|
-
static blockCoefficient(e, t, n,
|
|
625
|
-
let a = Math.round(e / (t * n *
|
|
624
|
+
static blockCoefficient(e, t, n, r) {
|
|
625
|
+
let a = Math.round(e / (t * n * r) * 100) / 100;
|
|
626
626
|
a = a < 0.55 ? 0.55 : a > 0.85 ? 0.85 : a;
|
|
627
627
|
const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = o.map((d) => Math.abs(d - a));
|
|
628
628
|
return o[s.indexOf(Math.min(...s))];
|
|
@@ -639,8 +639,8 @@ class O {
|
|
|
639
639
|
* @return [0.05, 0.30]
|
|
640
640
|
*/
|
|
641
641
|
static froudeNumber(e, t, n = 9.8) {
|
|
642
|
-
let
|
|
643
|
-
return
|
|
642
|
+
let r = Math.round(Math.sqrt(e * e / (n * t)) * 100) / 100;
|
|
643
|
+
return r = r < 0.05 ? 0.05 : r > 0.3 ? 0.3 : r, r;
|
|
644
644
|
}
|
|
645
645
|
/**
|
|
646
646
|
* 失速修正系數
|
|
@@ -650,7 +650,7 @@ class O {
|
|
|
650
650
|
* @private
|
|
651
651
|
*/
|
|
652
652
|
static amendFactor(e, t, n) {
|
|
653
|
-
const
|
|
653
|
+
const r = {
|
|
654
654
|
0.55: [1.7, -1.4, -7.4],
|
|
655
655
|
0.6: [2.2, -2.5, -9.7],
|
|
656
656
|
0.65: [2.6, -3.7, -11.6],
|
|
@@ -668,7 +668,7 @@ class O {
|
|
|
668
668
|
0.8: [3, -16.3, -21.6],
|
|
669
669
|
0.85: [3.4, -20.9, 31.8]
|
|
670
670
|
}[e];
|
|
671
|
-
return n === "Laden" && (o =
|
|
671
|
+
return n === "Laden" && (o = r[e]), o[0] + o[1] * t + o[2] * Math.pow(t, 2);
|
|
672
672
|
}
|
|
673
673
|
/**
|
|
674
674
|
* 失速方向因子
|
|
@@ -696,10 +696,10 @@ class O {
|
|
|
696
696
|
* @param bn
|
|
697
697
|
* @private
|
|
698
698
|
*/
|
|
699
|
-
static vesselTagFactor(e, t, n,
|
|
700
|
-
|
|
699
|
+
static vesselTagFactor(e, t, n, r = 0) {
|
|
700
|
+
r = r > 6 ? r - 0.9 * (r - 6) : r;
|
|
701
701
|
let a;
|
|
702
|
-
return n === "container" ? a = 0.7 *
|
|
702
|
+
return n === "container" ? a = 0.7 * r + Math.pow(r, 6.5) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? a = 0.7 * r + Math.pow(r, 6.5) / (2.7 * Math.pow(e, 2 / 3)) : a = 0.5 * r + Math.pow(r, 6.5) / (2.7 * Math.pow(e, 2 / 3)), a;
|
|
703
703
|
}
|
|
704
704
|
/**
|
|
705
705
|
* 浪高影响因子
|
|
@@ -719,11 +719,11 @@ class O {
|
|
|
719
719
|
* @param bearing 方位角
|
|
720
720
|
* @private
|
|
721
721
|
*/
|
|
722
|
-
static assembleProperties(e, t, n,
|
|
722
|
+
static assembleProperties(e, t, n, r) {
|
|
723
723
|
var y;
|
|
724
|
-
const a = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, o = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, d = e.deadweight ?? 67035.7773,
|
|
724
|
+
const a = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, o = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, d = e.deadweight ?? 67035.7773, i = ((y = e == null ? void 0 : e.type) == null ? void 0 : y.toLowerCase()) || "common";
|
|
725
725
|
return {
|
|
726
|
-
tag:
|
|
726
|
+
tag: i.indexOf("container") > -1 ? "container" : i.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
727
727
|
lbp: a,
|
|
728
728
|
loadCondition: t,
|
|
729
729
|
draught: o,
|
|
@@ -733,7 +733,7 @@ class O {
|
|
|
733
733
|
displacement: Math.round((d / 1.025 + o * s * a * 0.7) * 1e4) / 1e4,
|
|
734
734
|
// 换算为m/s
|
|
735
735
|
speed: Math.round((n ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
736
|
-
bearing:
|
|
736
|
+
bearing: r || 90
|
|
737
737
|
};
|
|
738
738
|
}
|
|
739
739
|
/**
|
|
@@ -746,8 +746,8 @@ class O {
|
|
|
746
746
|
* @param useMeteo true 启用气象分析
|
|
747
747
|
* @param useRouteParam true 启用设置速度
|
|
748
748
|
*/
|
|
749
|
-
static async speedLoseAt(e, t, n,
|
|
750
|
-
let
|
|
749
|
+
static async speedLoseAt(e, t, n, r = "", a = 2, o = !0, s = !1, d = {}) {
|
|
750
|
+
let i;
|
|
751
751
|
if (t.velocity && s && (e.speed = J.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
|
|
752
752
|
let h;
|
|
753
753
|
if (d.meteo2)
|
|
@@ -758,25 +758,25 @@ class O {
|
|
|
758
758
|
k.warn("[%s] meteo2 spot(%j) forecast failed: %s", d.requestId, { ...t, eta: n.utc().format() }, m);
|
|
759
759
|
}
|
|
760
760
|
else
|
|
761
|
-
h = await mt.queryPointFactor(t.lng, t.lat, n.valueOf(), "wind,wave,current,watertemp",
|
|
762
|
-
const M = O.weatherFactor(e, h), y = O.currentFactor(e.bearing, h == null ? void 0 : h.current, a),
|
|
763
|
-
|
|
761
|
+
h = await mt.queryPointFactor(t.lng, t.lat, n.valueOf(), "wind,wave,current,watertemp", r, d);
|
|
762
|
+
const M = O.weatherFactor(e, h), y = O.currentFactor(e.bearing, h == null ? void 0 : h.current, a), w = Math.round((e.speed * 1.943844 + M + y) * 100) / 100;
|
|
763
|
+
i = {
|
|
764
764
|
meteo: { ...h },
|
|
765
765
|
wxFactor: M,
|
|
766
766
|
cFactor: y,
|
|
767
|
-
speed: t.velocity && s ? t.velocity :
|
|
767
|
+
speed: t.velocity && s ? t.velocity : w < 0 ? 1 : w,
|
|
768
768
|
eta: n.utc().format(),
|
|
769
769
|
etd: n.utc().format()
|
|
770
770
|
};
|
|
771
771
|
} else
|
|
772
|
-
|
|
772
|
+
i = {
|
|
773
773
|
wxFactor: 0,
|
|
774
774
|
cFactor: 0,
|
|
775
775
|
speed: t.velocity && s ? t.velocity : Math.round((e.speed * 1.943844 + 0 + 0) * 100) / 100,
|
|
776
776
|
eta: n.utc().format(),
|
|
777
777
|
etd: n.utc().format()
|
|
778
778
|
};
|
|
779
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
779
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...i, ...t };
|
|
780
780
|
}
|
|
781
781
|
/**
|
|
782
782
|
* 基于步长计算失速样本
|
|
@@ -791,43 +791,43 @@ class O {
|
|
|
791
791
|
* @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
|
|
792
792
|
* @private
|
|
793
793
|
*/
|
|
794
|
-
static async speedLoseInHoursStep(e, t, n,
|
|
794
|
+
static async speedLoseInHoursStep(e, t, n, r, a, o, s = "", d = !0, i = !1, h = {}) {
|
|
795
795
|
t.utc();
|
|
796
|
-
const M = t.clone().add(14, "days"), y = [],
|
|
797
|
-
let m = 0, F = 0, x,
|
|
796
|
+
const M = t.clone().add(14, "days"), y = [], w = [];
|
|
797
|
+
let m = 0, F = 0, x, v;
|
|
798
798
|
for (let b = 0; b < o.length - 1; b++) {
|
|
799
799
|
let c = o[b];
|
|
800
800
|
c.distanceFromStart = Math.round((a + F) * 1e4) / 1e4;
|
|
801
801
|
const f = o[b + 1];
|
|
802
|
-
if (e.bearing = W.calculateBearing(c, f, !f.gcToPrevious), c.bearing = e.bearing, c.suspend &&
|
|
802
|
+
if (e.bearing = W.calculateBearing(c, f, !f.gcToPrevious), c.bearing = e.bearing, c.suspend && i) {
|
|
803
803
|
c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
|
|
804
804
|
const I = c.suspend - c.elapsed;
|
|
805
|
-
if (
|
|
806
|
-
|
|
805
|
+
if (r - m > I)
|
|
806
|
+
r = r - m - I, t.add(I, "hour"), c.elapsed = c.suspend;
|
|
807
807
|
else {
|
|
808
|
-
const S =
|
|
809
|
-
c.elapsed += S, t.add(S, "hour"),
|
|
808
|
+
const S = r - m;
|
|
809
|
+
c.elapsed += S, t.add(S, "hour"), r = 0;
|
|
810
810
|
}
|
|
811
|
-
if (k == null || k.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${
|
|
812
|
-
return c.distanceFromPrevious = F, { etd: t, from:
|
|
811
|
+
if (k == null || k.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${r} hours need to go...`, h.requestId, c), r === 0)
|
|
812
|
+
return c.distanceFromPrevious = F, { etd: t, from: v || c, to: c, next: o.filter((S) => S), wps: y, days: w };
|
|
813
813
|
} else
|
|
814
814
|
c.suspend = 0;
|
|
815
|
-
d = t.isAfter(M) ? !1 : d, c = await O.speedLoseAt(e, c, t, s, 0, d,
|
|
815
|
+
d = t.isAfter(M) ? !1 : d, c = await O.speedLoseAt(e, c, t, s, 0, d, i, h), v = v || c, c.important && y.push(c), t.isSameOrAfter(n) && (w.push(c), n.add(24, "hour"));
|
|
816
816
|
const l = W.calculateDistance(c, f, !f.gcToPrevious);
|
|
817
|
-
let u = Math.round(l /
|
|
818
|
-
if (m + u <
|
|
817
|
+
let u = Math.round(l / v.speed * 1e5) / 1e5;
|
|
818
|
+
if (m + u < r) {
|
|
819
819
|
if (m += u, t.add(u, "hour"), delete o[b], k == null || k.debug(
|
|
820
820
|
`[%s] go to %j from %j with ${l}nm, and cost ${u} hours`,
|
|
821
821
|
h.requestId,
|
|
822
822
|
{ lat: f.lat, lng: f.lng },
|
|
823
|
-
{ lat:
|
|
823
|
+
{ lat: v.lat, lng: v.lng, etd: v.etd }
|
|
824
824
|
), F += l, o.filter((I) => I).length <= 1) {
|
|
825
825
|
x = f, x.eta = t.utc().format(), x.distanceFromPrevious = l, x.distanceFromStart = Math.round((a + F) * 1e4) / 1e4, y.push(x), delete o[b + 1];
|
|
826
826
|
break;
|
|
827
827
|
}
|
|
828
828
|
} else {
|
|
829
|
-
u =
|
|
830
|
-
const I = J.roundPrecision(
|
|
829
|
+
u = r - m, t.add(u, "hour");
|
|
830
|
+
const I = J.roundPrecision(v.speed * u, 5);
|
|
831
831
|
x = W.calculateCoordinate(c, e.bearing, I, "nauticalmiles", !f.gcToPrevious), x.eta = t.utc().format(), o[b] = x, k == null || k.debug(
|
|
832
832
|
`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,
|
|
833
833
|
h.requestId,
|
|
@@ -837,7 +837,7 @@ class O {
|
|
|
837
837
|
break;
|
|
838
838
|
}
|
|
839
839
|
}
|
|
840
|
-
return { etd: t, from:
|
|
840
|
+
return { etd: t, from: v, to: x, next: o.filter((b) => b), wps: y, days: w };
|
|
841
841
|
}
|
|
842
842
|
/**
|
|
843
843
|
* 洋流影响因子
|
|
@@ -846,10 +846,10 @@ class O {
|
|
|
846
846
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
847
847
|
*/
|
|
848
848
|
static currentFactor(e, t, n = 0) {
|
|
849
|
-
const
|
|
850
|
-
if (Math.abs(
|
|
849
|
+
const r = (e - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
850
|
+
if (Math.abs(r) === Math.PI / 2)
|
|
851
851
|
return 0;
|
|
852
|
-
let a = ((t == null ? void 0 : t.kts) || 0) * Math.cos(
|
|
852
|
+
let a = ((t == null ? void 0 : t.kts) || 0) * Math.cos(r);
|
|
853
853
|
return n & 2 ? a = Math.ceil(a * 100) / 100 : n & 1 ? a = Math.floor(a * 100) / 100 : a = Math.round(a * 100) / 100, Math.abs(a) > 5 ? 0 : a;
|
|
854
854
|
}
|
|
855
855
|
/**
|
|
@@ -858,16 +858,16 @@ class O {
|
|
|
858
858
|
* @param wwc 气象要素
|
|
859
859
|
*/
|
|
860
860
|
static weatherFactor(e, t) {
|
|
861
|
-
var M, y,
|
|
861
|
+
var M, y, w, m, F, x, v;
|
|
862
862
|
k == null || k.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
863
|
-
const n = O.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught),
|
|
863
|
+
const n = O.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), r = O.froudeNumber(e.speed, e.lbp), a = O.amendFactor(n, r, e.loadCondition);
|
|
864
864
|
let o = Math.abs(e.bearing % 360 - (((M = t == null ? void 0 : t.wind) == null ? void 0 : M.degree) % 360 || 0));
|
|
865
865
|
o = o > 180 ? 360 - o : o;
|
|
866
|
-
const s = O.directionFactor(o, (y = t == null ? void 0 : t.wind) == null ? void 0 : y.scale), d = O.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (
|
|
867
|
-
let
|
|
868
|
-
|
|
869
|
-
const h = O.waveHeightFactor(((
|
|
870
|
-
return k == null || k.debug("wave wx factor = %d", h),
|
|
866
|
+
const s = O.directionFactor(o, (y = t == null ? void 0 : t.wind) == null ? void 0 : y.scale), d = O.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (w = t == null ? void 0 : t.wind) == null ? void 0 : w.scale);
|
|
867
|
+
let i = s * a * d / 100 * e.speed;
|
|
868
|
+
i = Math.round(i * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(i) > 1 && (i = i / (Math.abs(Math.round(i)) + 1)), k == null || k.debug("wind wx factor = %d", i), o = Math.abs(e.bearing % 360 - (((F = (m = t == null ? void 0 : t.wave) == null ? void 0 : m.sig) == null ? void 0 : F.degree) % 360 || 0));
|
|
869
|
+
const h = O.waveHeightFactor(((v = (x = t == null ? void 0 : t.wave) == null ? void 0 : x.sig) == null ? void 0 : v.height) ?? 1, o);
|
|
870
|
+
return k == null || k.debug("wave wx factor = %d", h), i = i * 0.4 + h, k == null || k.debug("weather factor = %d", i), i = Math.abs(i) > 4 ? 4 * (Math.abs(i) / i) + Math.abs(i) / i * (Math.abs(i) - 4) * 0.1 : i, Math.round((i || 0) * 100) / 100;
|
|
871
871
|
}
|
|
872
872
|
/**
|
|
873
873
|
* 全程失速分析(走完航程)
|
|
@@ -881,11 +881,11 @@ class O {
|
|
|
881
881
|
* @param useMeteo true 启用气象分析
|
|
882
882
|
* @param useRouteParam
|
|
883
883
|
*/
|
|
884
|
-
static async analyseInstant(e, t, n,
|
|
884
|
+
static async analyseInstant(e, t, n, r, a, o = "", s = 0, d = !0, i = !1, h = {}) {
|
|
885
885
|
var G, U, Q, X, Z, $;
|
|
886
886
|
const M = g().valueOf();
|
|
887
887
|
e.lng = J.convertToStdLng(e.lng);
|
|
888
|
-
const { route: y, waypoints:
|
|
888
|
+
const { route: y, waypoints: w } = a.points, m = W.calculateSubRoute(e, y);
|
|
889
889
|
if (((G = m[0]) == null ? void 0 : G.length) <= 1)
|
|
890
890
|
return;
|
|
891
891
|
const { v0: F, label: x } = e.sog ? {
|
|
@@ -893,10 +893,10 @@ class O {
|
|
|
893
893
|
label: "Other"
|
|
894
894
|
/* Instruct */
|
|
895
895
|
} : {
|
|
896
|
-
v0:
|
|
896
|
+
v0: r.speed,
|
|
897
897
|
label: "CP"
|
|
898
898
|
/* Cp */
|
|
899
|
-
},
|
|
899
|
+
}, v = O.assembleProperties(n, r.loadCondition, F, 0), b = w.length ? W.calculateSubWaypoints(e, w) : [];
|
|
900
900
|
b.forEach((q) => q.important = !0);
|
|
901
901
|
const c = {
|
|
902
902
|
from: { ...e },
|
|
@@ -909,13 +909,13 @@ class O {
|
|
|
909
909
|
days: [],
|
|
910
910
|
wps: []
|
|
911
911
|
};
|
|
912
|
-
s || (W.calculateRouteDistance(m) /
|
|
912
|
+
s || (W.calculateRouteDistance(m) / r.speed <= 72 ? s = 3 : s = 6);
|
|
913
913
|
let l = W.simplifyRouteToCoordinates(m, b, 0), u = 0, I = 0, S = 0, D = 0;
|
|
914
914
|
t = g(t).utc();
|
|
915
915
|
const Y = t.clone();
|
|
916
916
|
for (; l.length > 0; ) {
|
|
917
917
|
const q = s - t.hour() % s, V = Math.ceil(t.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, C = await O.speedLoseInHoursStep(
|
|
918
|
-
|
|
918
|
+
v,
|
|
919
919
|
t,
|
|
920
920
|
Y,
|
|
921
921
|
V,
|
|
@@ -923,7 +923,7 @@ class O {
|
|
|
923
923
|
l,
|
|
924
924
|
o,
|
|
925
925
|
d,
|
|
926
|
-
|
|
926
|
+
i,
|
|
927
927
|
h
|
|
928
928
|
);
|
|
929
929
|
(U = C.from) != null && U.speed && (f.hours.push(C.from), f.wps.push(...C.wps), f.days.push(...C.days)), l = C == null ? void 0 : C.next, l.length || f.hours.push(C == null ? void 0 : C.to), u += Math.round((((Q = C == null ? void 0 : C.to) == null ? void 0 : Q.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
@@ -945,7 +945,7 @@ class O {
|
|
|
945
945
|
}), f.wps = (Z = f.wps) == null ? void 0 : Z.reduce((q, V) => (q.some((C) => Math.round(C.positionTime / 60) === Math.round(V.positionTime / 60)) || q.push(V), q), []), c.sample = f;
|
|
946
946
|
const P = f.hours.at(0), T = f.hours.at(-1);
|
|
947
947
|
c.distance = Math.round(T.distanceFromStart * 1e4) / 1e4, c.etd = g(P.eta).utc().format(), c.eta = g(T.eta).utc().format(), c.wxFactor = Math.round(I / D * 1e4) / 1e4, c.cFactor = Math.round(S / D * 1e4) / 1e4, c.avgSpeed = Math.round(T.distanceFromStart / D * 1e4) / 1e4, c.totalHrs = Math.round(D * 1e4) / 1e4;
|
|
948
|
-
const { distanceInECA: N, hoursInECA: A, totalDgoConsInECA: R, eca: K } = await this.calculateECA(c,
|
|
948
|
+
const { distanceInECA: N, hoursInECA: A, totalDgoConsInECA: R, eca: K } = await this.calculateECA(c, r, h), st = J.roundPrecision(r.fo / 24 * (D - A), 3), at = J.roundPrecision(r.dgo / 24 * D, 3);
|
|
949
949
|
c.extend = {
|
|
950
950
|
eca: K,
|
|
951
951
|
distanceInECA: N,
|
|
@@ -968,9 +968,9 @@ class O {
|
|
|
968
968
|
* @param useMeteo true 启用气象分析
|
|
969
969
|
* @param useRouteParam
|
|
970
970
|
*/
|
|
971
|
-
static async analyseInstantWithThreshed(e, t, n,
|
|
971
|
+
static async analyseInstantWithThreshed(e, t, n, r, a, o, s, d = "", i = 3, h = !0, M = !1, y = {}) {
|
|
972
972
|
var Q, X, Z, $, q, V;
|
|
973
|
-
const
|
|
973
|
+
const w = g().valueOf();
|
|
974
974
|
e.lng = J.convertToStdLng(e.lng);
|
|
975
975
|
const { v0: m, label: F } = e.sog ? {
|
|
976
976
|
v0: e.sog,
|
|
@@ -980,12 +980,12 @@ class O {
|
|
|
980
980
|
v0: a.speed,
|
|
981
981
|
label: "CP"
|
|
982
982
|
/* Cp */
|
|
983
|
-
}, x = O.assembleProperties(
|
|
984
|
-
if (((Q =
|
|
983
|
+
}, x = O.assembleProperties(r, a.loadCondition, m, 0), v = W.calculateSubRoute(e, o);
|
|
984
|
+
if (((Q = v[0]) == null ? void 0 : Q.length) <= 1)
|
|
985
985
|
return;
|
|
986
986
|
const b = s.length ? W.calculateSubWaypoints(e, s) : [];
|
|
987
987
|
b.forEach((C) => C.important = !0);
|
|
988
|
-
let c = W.simplifyRouteToCoordinates(
|
|
988
|
+
let c = W.simplifyRouteToCoordinates(v, b, 0), f = 0, l = 0, u = 0, I = 0;
|
|
989
989
|
const S = {
|
|
990
990
|
hours: [],
|
|
991
991
|
wps: [],
|
|
@@ -994,7 +994,7 @@ class O {
|
|
|
994
994
|
t = g(t).utc();
|
|
995
995
|
const D = t.clone();
|
|
996
996
|
for (; c.length > 0; ) {
|
|
997
|
-
const C =
|
|
997
|
+
const C = i - t.hour() % i;
|
|
998
998
|
let L = Math.ceil(t.clone().add(C, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
999
999
|
L = t.clone().add(L, "h").isSameOrAfter(n) ? n.diff(t, "h", !0) * 1e4 / 1e4 : L;
|
|
1000
1000
|
const H = await O.speedLoseInHoursStep(x, t, D, L, f, c, d, h, M, y);
|
|
@@ -1015,7 +1015,7 @@ class O {
|
|
|
1015
1015
|
const L = g(Y[C + 1].eta).diff(Y[C].etd, "hour", !0);
|
|
1016
1016
|
l += Y[C].wxFactor * L, u += Y[C].cFactor * L, I += L;
|
|
1017
1017
|
}
|
|
1018
|
-
const E = S.hours.at(0), P = S.hours.at(-1), T = await W.calculateRangeRoute(E, P,
|
|
1018
|
+
const E = S.hours.at(0), P = S.hours.at(-1), T = await W.calculateRangeRoute(E, P, v), N = await W.calculateRangeWaypoints(E, P, v, b), A = {
|
|
1019
1019
|
sample: S,
|
|
1020
1020
|
distance: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1021
1021
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
@@ -1031,14 +1031,14 @@ class O {
|
|
|
1031
1031
|
waypoints: N,
|
|
1032
1032
|
v0: m,
|
|
1033
1033
|
label: F
|
|
1034
|
-
}, { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: st, eca: at } = await this.calculateECA(A, a, y),
|
|
1034
|
+
}, { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: st, eca: at } = await this.calculateECA(A, a, y), it = J.roundPrecision(a.fo / 24 * (I - K), 3), tt = J.roundPrecision(a.dgo / 24 * I, 3);
|
|
1035
1035
|
A.extend = {
|
|
1036
1036
|
eca: at,
|
|
1037
1037
|
distanceInECA: R,
|
|
1038
1038
|
hoursInECA: K,
|
|
1039
1039
|
totalDgoConsInECA: st
|
|
1040
|
-
}, A.totalDgoCons = tt, A.totalFoCons =
|
|
1041
|
-
const G = g().valueOf() -
|
|
1040
|
+
}, A.totalDgoCons = tt, A.totalFoCons = it;
|
|
1041
|
+
const G = g().valueOf() - w, U = ((V = S == null ? void 0 : S.hours) == null ? void 0 : V.length) || 1;
|
|
1042
1042
|
return k == null || k.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", y == null ? void 0 : y.requestId, G, U, Math.round(G / U * 1e3) / 1e3), A;
|
|
1043
1043
|
}
|
|
1044
1044
|
/**
|
|
@@ -1056,20 +1056,20 @@ class O {
|
|
|
1056
1056
|
* @param lane 基础航线(重要转向点)
|
|
1057
1057
|
* @param options
|
|
1058
1058
|
*/
|
|
1059
|
-
static async analyseCost(e, t, n,
|
|
1060
|
-
var
|
|
1059
|
+
static async analyseCost(e, t, n, r, a = {}) {
|
|
1060
|
+
var v, b;
|
|
1061
1061
|
const o = g().valueOf(), s = [];
|
|
1062
1062
|
a.meteo2 = a.meteo2 || !0, e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
|
|
1063
|
-
const d = W.calculateRouteDistance(
|
|
1064
|
-
let
|
|
1063
|
+
const d = W.calculateRouteDistance(r.route);
|
|
1064
|
+
let i = 0;
|
|
1065
1065
|
n.forEach((c) => {
|
|
1066
1066
|
const f = Math.ceil(d / c.speed / 24);
|
|
1067
|
-
|
|
1068
|
-
}),
|
|
1069
|
-
const h = g.utc(e.etd).add(
|
|
1067
|
+
i = i < f ? f : i;
|
|
1068
|
+
}), i = i * 1.3;
|
|
1069
|
+
const h = g.utc(e.etd).add(i ?? 14, "day");
|
|
1070
1070
|
let M = 1;
|
|
1071
1071
|
for (const c of n) {
|
|
1072
|
-
const f = JSON.parse(JSON.stringify(
|
|
1072
|
+
const f = JSON.parse(JSON.stringify(r.route)), l = JSON.parse(JSON.stringify(r.waypoints)), u = await O.analyseInstantWithThreshed(
|
|
1073
1073
|
{ lat: e.lat, lng: e.lng },
|
|
1074
1074
|
e.etd,
|
|
1075
1075
|
h,
|
|
@@ -1093,14 +1093,14 @@ class O {
|
|
|
1093
1093
|
})), M++;
|
|
1094
1094
|
}
|
|
1095
1095
|
s.sort((c, f) => c.cost.total - f.cost.total);
|
|
1096
|
-
const y = s.at(0),
|
|
1097
|
-
if (m.push({ combined: !1, speeds: [y], cost: (
|
|
1098
|
-
const c = y.cost.cp, f =
|
|
1096
|
+
const y = s.at(0), w = s.at(1), m = [];
|
|
1097
|
+
if (m.push({ combined: !1, speeds: [y], cost: (v = y.cost) == null ? void 0 : v.total }), w) {
|
|
1098
|
+
const c = y.cost.cp, f = w.cost.cp, l = g(y.eta), u = g(y.etd), I = l.diff(u, "days", !0);
|
|
1099
1099
|
let S = Math.ceil(I / 2);
|
|
1100
1100
|
S = S > 7 ? 7 : S < e.alterStep ? e.alterStep : S;
|
|
1101
|
-
let D = 2, Y = { combined: !1, speeds: [
|
|
1101
|
+
let D = 2, Y = { combined: !1, speeds: [w], cost: (b = w.cost) == null ? void 0 : b.total }, E;
|
|
1102
1102
|
for (; S >= e.alterStep; ) {
|
|
1103
|
-
const P = await O.combinedAnalyse(e, t, h, [c, f],
|
|
1103
|
+
const P = await O.combinedAnalyse(e, t, h, [c, f], r, S, { ...a, level: D });
|
|
1104
1104
|
if (Y.cost > P.cost ? E ? (E == null ? void 0 : E.cost) > P.cost && (E = P) : (E = Y, Y = P) : (!E || (E == null ? void 0 : E.cost) > P.cost) && (E = P), S <= e.alterStep)
|
|
1105
1105
|
break;
|
|
1106
1106
|
S = Math.ceil(S / 2), D += 1;
|
|
@@ -1120,24 +1120,24 @@ class O {
|
|
|
1120
1120
|
* @param step 步长,7,4,2,1
|
|
1121
1121
|
* @param options
|
|
1122
1122
|
*/
|
|
1123
|
-
static async combinedAnalyse(e, t, n,
|
|
1123
|
+
static async combinedAnalyse(e, t, n, r, a, o, s = {}) {
|
|
1124
1124
|
s.counter = 1, k == null || k.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, o);
|
|
1125
|
-
const d = await O.alternateAnalyse(e, t, n,
|
|
1125
|
+
const d = await O.alternateAnalyse(e, t, n, r, 0, a, o, s), i = d.reduce((f, l) => f + l.cost.total, 0), h = d.reduce((f, l) => f + l.cost.hire, 0), M = d.reduce((f, l) => f + l.cost.bunker, 0), y = d.reduce((f, l) => f + l.distance, 0), w = d.reduce((f, l) => f + l.totalHrs, 0);
|
|
1126
1126
|
k == null || k.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
|
|
1127
|
-
cost:
|
|
1127
|
+
cost: i,
|
|
1128
1128
|
hire: h,
|
|
1129
1129
|
bunker: M,
|
|
1130
1130
|
distance: y,
|
|
1131
|
-
hours:
|
|
1131
|
+
hours: w
|
|
1132
1132
|
});
|
|
1133
|
-
const m = await O.alternateAnalyse(e, t, n,
|
|
1133
|
+
const m = await O.alternateAnalyse(e, t, n, r, 1, a, o, s), F = m.reduce((f, l) => f + l.cost.total, 0), x = m.reduce((f, l) => f + l.cost.hire, 0), v = m.reduce((f, l) => f + l.cost.bunker, 0), b = m.reduce((f, l) => f + l.distance, 0), c = m.reduce((f, l) => f + l.totalHrs, 0);
|
|
1134
1134
|
return k == null || k.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
|
|
1135
1135
|
cost: F,
|
|
1136
1136
|
hire: x,
|
|
1137
|
-
bunker:
|
|
1137
|
+
bunker: v,
|
|
1138
1138
|
distance: b,
|
|
1139
1139
|
hours: c
|
|
1140
|
-
}),
|
|
1140
|
+
}), i < F ? { combined: !0, cost: Math.round(i * 1e3) / 1e3, speeds: d, step: o } : { combined: !0, cost: Math.round(F * 1e3) / 1e3, speeds: m, step: o };
|
|
1141
1141
|
}
|
|
1142
1142
|
/**
|
|
1143
1143
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1150,17 +1150,17 @@ class O {
|
|
|
1150
1150
|
* @param step 步长,7,4,2,1
|
|
1151
1151
|
* @param options
|
|
1152
1152
|
*/
|
|
1153
|
-
static async alternateAnalyse(e, t, n,
|
|
1154
|
-
var y,
|
|
1155
|
-
let
|
|
1153
|
+
static async alternateAnalyse(e, t, n, r, a, o, s, d = {}) {
|
|
1154
|
+
var y, w;
|
|
1155
|
+
let i = g.utc(e.etd);
|
|
1156
1156
|
const h = { lat: e.lat, lng: e.lng }, M = [];
|
|
1157
|
-
for (;
|
|
1158
|
-
const m =
|
|
1157
|
+
for (; i.isBefore(n); ) {
|
|
1158
|
+
const m = i.clone().utc().add(s, "day"), F = JSON.parse(JSON.stringify(o.route)), x = JSON.parse(JSON.stringify(o.waypoints)), v = r[a], b = await O.analyseInstantWithThreshed(
|
|
1159
1159
|
h,
|
|
1160
|
-
|
|
1160
|
+
i.utc().format(),
|
|
1161
1161
|
m,
|
|
1162
1162
|
t,
|
|
1163
|
-
|
|
1163
|
+
v,
|
|
1164
1164
|
F,
|
|
1165
1165
|
x,
|
|
1166
1166
|
e.meteoVendor,
|
|
@@ -1169,12 +1169,12 @@ class O {
|
|
|
1169
1169
|
e.useRouteParam,
|
|
1170
1170
|
d
|
|
1171
1171
|
);
|
|
1172
|
-
b && (await O.calculateCost(b,
|
|
1172
|
+
b && (await O.calculateCost(b, v, e, d), k == null || k.info(
|
|
1173
1173
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1174
1174
|
d.requestId,
|
|
1175
1175
|
d.level,
|
|
1176
1176
|
d.counter,
|
|
1177
|
-
|
|
1177
|
+
i.utc().format(),
|
|
1178
1178
|
m.utc().format(),
|
|
1179
1179
|
{
|
|
1180
1180
|
cost: b.cost.total,
|
|
@@ -1182,12 +1182,12 @@ class O {
|
|
|
1182
1182
|
bunker: b.cost.bunker,
|
|
1183
1183
|
distance: b.distance,
|
|
1184
1184
|
hours: b.totalHrs,
|
|
1185
|
-
cp: `${
|
|
1185
|
+
cp: `${v.speed}/${v.fo}/${v.dgo}`
|
|
1186
1186
|
}
|
|
1187
1187
|
)), d.counter = d.counter + 1;
|
|
1188
|
-
const c = (
|
|
1188
|
+
const c = (w = (y = b == null ? void 0 : b.sample) == null ? void 0 : y.hours) == null ? void 0 : w.at(-1);
|
|
1189
1189
|
if (c)
|
|
1190
|
-
h.lat = c.lat, h.lng = c.lng,
|
|
1190
|
+
h.lat = c.lat, h.lng = c.lng, i = g(c.eta), M.push(b), a = a ? 0 : 1;
|
|
1191
1191
|
else
|
|
1192
1192
|
break;
|
|
1193
1193
|
}
|
|
@@ -1200,7 +1200,7 @@ class O {
|
|
|
1200
1200
|
* @param props
|
|
1201
1201
|
* @param options
|
|
1202
1202
|
*/
|
|
1203
|
-
static async calculateCost(e, t, n,
|
|
1203
|
+
static async calculateCost(e, t, n, r = {}) {
|
|
1204
1204
|
var a;
|
|
1205
1205
|
if (e) {
|
|
1206
1206
|
const o = Math.round(e.totalHrs / 24 * (n.dailyHire || 0) * (1 - (n.addComm || 0)) * 1e3) / 1e3, s = Math.round(e.totalFoCons * (n.priceFO || 0) * 1e3) / 1e3, d = Math.round((e.totalDgoCons + (((a = e.extend) == null ? void 0 : a.totalDgoConsInECA) || 0)) * (n.priceDGO || 0) * 1e3) / 1e3;
|
|
@@ -1217,22 +1217,22 @@ class O {
|
|
|
1217
1217
|
* 计算单cp模式下的ECA属性
|
|
1218
1218
|
*/
|
|
1219
1219
|
static async calculateECA(e, t, n = {}) {
|
|
1220
|
-
var d,
|
|
1221
|
-
const
|
|
1220
|
+
var d, i;
|
|
1221
|
+
const r = await W.intersectInECA(e.route);
|
|
1222
1222
|
let a = 0, o = 0, s = 0;
|
|
1223
1223
|
e.sample.wps.forEach((h) => {
|
|
1224
1224
|
h.positionTime = g.utc(h.etd || h.eta).unix();
|
|
1225
1225
|
});
|
|
1226
|
-
for (const h of
|
|
1226
|
+
for (const h of r) {
|
|
1227
1227
|
a += h.distance;
|
|
1228
|
-
const M = await W.deadReckoningTime((d = h.waypoints) == null ? void 0 : d.at(0), e.sample.wps), y = await W.deadReckoningTime((
|
|
1228
|
+
const M = await W.deadReckoningTime((d = h.waypoints) == null ? void 0 : d.at(0), e.sample.wps), y = await W.deadReckoningTime((i = h.waypoints) == null ? void 0 : i.at(-1), e.sample.wps);
|
|
1229
1229
|
h.in = M, h.out = y, h.totalHrs = J.roundPrecision((y.positionTime - M.positionTime) / 3600, 2), h.totalDgoCons = J.roundPrecision(t.fo / 24 * h.totalHrs, 3), o += h.totalHrs, s += h.totalDgoCons;
|
|
1230
1230
|
}
|
|
1231
1231
|
return a = J.roundPrecision(a, 3), o = J.roundPrecision(o, 3), s = J.roundPrecision(s, 3), {
|
|
1232
1232
|
distanceInECA: a,
|
|
1233
1233
|
hoursInECA: o,
|
|
1234
1234
|
totalDgoConsInECA: s,
|
|
1235
|
-
eca:
|
|
1235
|
+
eca: r
|
|
1236
1236
|
};
|
|
1237
1237
|
}
|
|
1238
1238
|
/**
|
|
@@ -1246,7 +1246,7 @@ class O {
|
|
|
1246
1246
|
hours: [],
|
|
1247
1247
|
wps: [],
|
|
1248
1248
|
days: []
|
|
1249
|
-
},
|
|
1249
|
+
}, r = e.reduce((l, u) => l + u.distance, 0), a = e.reduce((l, u) => {
|
|
1250
1250
|
var I;
|
|
1251
1251
|
return l + (((I = u.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1252
1252
|
}, 0), o = e.reduce((l, u) => l + u.totalHrs, 0), s = e.reduce((l, u) => {
|
|
@@ -1255,10 +1255,10 @@ class O {
|
|
|
1255
1255
|
}, 0), d = e.reduce((l, u) => {
|
|
1256
1256
|
var I;
|
|
1257
1257
|
return l + (((I = u.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1258
|
-
}, 0),
|
|
1258
|
+
}, 0), i = e.reduce((l, u) => l + u.wxFactor * u.totalHrs / o, 0), h = e.reduce((l, u) => l + u.cFactor * u.totalHrs / o, 0), M = e.reduce((l, u) => l + u.totalFoCons, 0), y = e.reduce((l, u) => l + u.totalDgoCons, 0), w = e.reduce((l, u) => l + u.cost.total, 0), m = e.reduce((l, u) => l + u.cost.hire, 0), F = e.reduce((l, u) => l + u.cost.bunker, 0), x = [], v = [];
|
|
1259
1259
|
let b;
|
|
1260
1260
|
for (const l of e) {
|
|
1261
|
-
|
|
1261
|
+
v.push(...((c = l.extend) == null ? void 0 : c.eca) || []);
|
|
1262
1262
|
const u = l.sample.hours, I = l.sample.wps, S = l.sample.days, D = u.at(0);
|
|
1263
1263
|
b && (D.distanceFromPrevious = b.distanceFromPrevious, D.distanceFromStart = b.distanceFromStart, u.forEach((T, N) => {
|
|
1264
1264
|
N && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
@@ -1299,21 +1299,21 @@ class O {
|
|
|
1299
1299
|
to: e.at(-1).to,
|
|
1300
1300
|
v0: e.at(0).v0,
|
|
1301
1301
|
label: "Combined",
|
|
1302
|
-
distance: Math.round(
|
|
1302
|
+
distance: Math.round(r * 1e4) / 1e4,
|
|
1303
1303
|
totalHrs: Math.round(o * 1e3) / 1e3,
|
|
1304
|
-
avgSpeed: Math.round(
|
|
1305
|
-
wxFactor: Math.round(
|
|
1304
|
+
avgSpeed: Math.round(r / o * 1e3) / 1e3,
|
|
1305
|
+
wxFactor: Math.round(i * 1e3) / 1e3,
|
|
1306
1306
|
cFactor: Math.round(h * 1e3) / 1e3,
|
|
1307
1307
|
totalFoCons: Math.round(M * 1e3) / 1e3,
|
|
1308
1308
|
totalDgoCons: Math.round(y * 1e3) / 1e3,
|
|
1309
1309
|
cost: {
|
|
1310
|
-
total: Math.round(
|
|
1310
|
+
total: Math.round(w * 1e3) / 1e3,
|
|
1311
1311
|
hire: Math.round(m * 1e3) / 1e3,
|
|
1312
1312
|
bunker: Math.round(F * 1e3) / 1e3
|
|
1313
1313
|
},
|
|
1314
1314
|
extend: {
|
|
1315
1315
|
cps: x,
|
|
1316
|
-
eca:
|
|
1316
|
+
eca: v,
|
|
1317
1317
|
distanceInECA: Math.round(a * 1e4) / 1e4,
|
|
1318
1318
|
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1319
1319
|
totalDgoConsInECA: Math.round(d * 1e3) / 1e3,
|
|
@@ -1332,7 +1332,7 @@ export {
|
|
|
1332
1332
|
jt as MyVesselImpl,
|
|
1333
1333
|
Nt as ShipxyImpl,
|
|
1334
1334
|
O as SpeedHelper,
|
|
1335
|
-
|
|
1335
|
+
wt as SpeedLabel,
|
|
1336
1336
|
bt as VesselTag,
|
|
1337
1337
|
Dt as alertHelper
|
|
1338
1338
|
};
|