@idm-plugin/vessel 1.9.6 → 1.9.8
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 +440 -436
- package/dist/index.umd.cjs +1 -1
- package/dist/speed/src/index.d.ts +0 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
var ht = Object.defineProperty;
|
|
2
|
-
var lt = (
|
|
3
|
-
var
|
|
2
|
+
var lt = (E, e, t) => e in E ? ht(E, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : E[e] = t;
|
|
3
|
+
var K = (E, e, t) => (lt(E, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
4
|
import B from "got";
|
|
5
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
|
-
import { MeteoHelper2 as ft
|
|
9
|
-
import { Meteo2Assist as
|
|
8
|
+
import { MeteoHelper2 as ft } from "@idm-plugin/meteo2";
|
|
9
|
+
import { Meteo2Assist as it } from "@idm-plugin/meteo";
|
|
10
10
|
let p;
|
|
11
11
|
try {
|
|
12
12
|
p = rt.getLogger("vessel");
|
|
@@ -54,45 +54,45 @@ class et {
|
|
|
54
54
|
return { labelCn: t, labelEn: n };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class xt extends et {
|
|
58
58
|
constructor(t, n) {
|
|
59
59
|
super();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
K(this, "clientId");
|
|
61
|
+
K(this, "clientSecret");
|
|
62
|
+
K(this, "token");
|
|
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", i = {
|
|
67
67
|
searchParams: {
|
|
68
68
|
client_id: this.clientId,
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
},
|
|
73
|
-
p == null || p.info("[%s] fetch access token from: %s - %j", t.requestId, n,
|
|
74
|
-
accessToken:
|
|
75
|
-
tokenType:
|
|
76
|
-
expiresIn:
|
|
77
|
-
scope:
|
|
78
|
-
jti:
|
|
72
|
+
}, o = await B.post(n, i).json();
|
|
73
|
+
p == null || p.info("[%s] fetch access token from: %s - %j", t.requestId, n, o), o.error || (this.token = {
|
|
74
|
+
accessToken: o.access_token,
|
|
75
|
+
tokenType: o.token_type,
|
|
76
|
+
expiresIn: o.expires_in,
|
|
77
|
+
scope: o.scope,
|
|
78
|
+
jti: o.jti,
|
|
79
79
|
issuedAt: g().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async realTimePosition(t, n = {}) {
|
|
83
|
-
var d,
|
|
83
|
+
var d, r, 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 i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", o = {
|
|
86
86
|
headers: {
|
|
87
|
-
Authorization: `${(
|
|
87
|
+
Authorization: `${(r = this.token) == null ? void 0 : r.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
|
|
93
|
-
if (
|
|
94
|
-
return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId,
|
|
95
|
-
const s =
|
|
91
|
+
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, o);
|
|
92
|
+
const a = await B.get(i, o).json();
|
|
93
|
+
if (a.code)
|
|
94
|
+
return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, i, { message: a.message, status: a.status, code: a.code }), a;
|
|
95
|
+
const s = a.data;
|
|
96
96
|
for (const M in s)
|
|
97
97
|
!isNaN(s[M]) && Number(s[M]) !== 1 / 0 && (s[M] = Number(s[M]));
|
|
98
98
|
if (s) {
|
|
@@ -131,37 +131,37 @@ class jt extends et {
|
|
|
131
131
|
} else
|
|
132
132
|
return {};
|
|
133
133
|
}
|
|
134
|
-
async trajectory(t, n,
|
|
134
|
+
async trajectory(t, n, i, o, a = !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), r = g(n), h = g(i), M = [];
|
|
137
|
+
for (; h.diff(r, "day", !0) > 30; )
|
|
138
|
+
await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), d, o, M, s), r.add(30, "day");
|
|
139
|
+
return await this.trajectoryIn30Day(t, r, h, d, o, M, s), M;
|
|
140
140
|
}
|
|
141
|
-
async trajectoryIn30Day(t, n,
|
|
142
|
-
var m,
|
|
143
|
-
const
|
|
141
|
+
async trajectoryIn30Day(t, n, i, o, a, s, d = {}) {
|
|
142
|
+
var m, C, S, w, b;
|
|
143
|
+
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
|
|
144
144
|
headers: {
|
|
145
|
-
Authorization: `${(m = this.token) == null ? void 0 : m.tokenType} ${(
|
|
145
|
+
Authorization: `${(m = this.token) == null ? void 0 : m.tokenType} ${(C = this.token) == null ? void 0 : C.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: i.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, r, h);
|
|
154
|
+
const M = await B.post(r, 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, r, { message: M.message, status: M.status, code: M.code }), M;
|
|
157
157
|
let y = -1;
|
|
158
|
-
const
|
|
158
|
+
const v = g(`${(w = (S = M.data) == null ? void 0 : S[0]) == null ? void 0 : w.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]));
|
|
162
|
-
const f = g(`${c.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), l = c.status, { labelCn: u, labelEn: I } = this.parseStatus(l),
|
|
162
|
+
const f = g(`${c.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), l = c.status, { labelCn: u, labelEn: I } = this.parseStatus(l), k = {
|
|
163
163
|
mmsi: c.mmsi,
|
|
164
|
-
imo:
|
|
164
|
+
imo: o == null ? void 0 : o.imo,
|
|
165
165
|
lat: c.lat,
|
|
166
166
|
lng: c.lon,
|
|
167
167
|
sog: c.sog,
|
|
@@ -177,32 +177,32 @@ class jt extends et {
|
|
|
177
177
|
method: "trajectory",
|
|
178
178
|
vendor: "myVessel",
|
|
179
179
|
utc: f.utc().format()
|
|
180
|
-
}, D = Math.floor(f.diff(
|
|
181
|
-
D !== y && (y = D, s.push(
|
|
180
|
+
}, D = Math.floor(f.diff(v, "minute", !0) / (a || 1));
|
|
181
|
+
D !== y && (y = D, s.push(k));
|
|
182
182
|
}), s;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
class Et extends et {
|
|
186
186
|
constructor(t) {
|
|
187
187
|
super();
|
|
188
|
-
|
|
188
|
+
K(this, "token");
|
|
189
189
|
this.token = t;
|
|
190
190
|
}
|
|
191
191
|
async realTimePosition(t, n = {}) {
|
|
192
|
-
const
|
|
192
|
+
const i = "https://api.hifleet.com/position/position/get/token", o = {
|
|
193
193
|
searchParams: {
|
|
194
194
|
mmsi: t,
|
|
195
195
|
usertoken: this.token
|
|
196
196
|
}
|
|
197
|
-
},
|
|
198
|
-
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId,
|
|
199
|
-
const s =
|
|
197
|
+
}, a = await B.post(i, o).json();
|
|
198
|
+
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, o);
|
|
199
|
+
const s = a == null ? void 0 : a.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, i, a), a;
|
|
202
|
+
for (const v in s)
|
|
203
|
+
!isNaN(s[v]) && Number(s[v]) !== 1 / 0 && (s[v] = Number(s[v]));
|
|
204
204
|
s.status = s.sp > 3 ? 0 : 1;
|
|
205
|
-
const d = s.status, { labelCn:
|
|
205
|
+
const d = s.status, { labelCn: r, 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,15 +226,15 @@ class Et extends et {
|
|
|
226
226
|
positionTime: M.unix(),
|
|
227
227
|
utc: M.utc().format(),
|
|
228
228
|
status: d,
|
|
229
|
-
labelCn:
|
|
229
|
+
labelCn: r,
|
|
230
230
|
labelEn: h,
|
|
231
231
|
method: "position",
|
|
232
232
|
vendor: "hifleet"
|
|
233
233
|
};
|
|
234
234
|
}
|
|
235
235
|
async search(t, n = {}) {
|
|
236
|
-
let
|
|
237
|
-
const
|
|
236
|
+
let i = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
237
|
+
const o = {
|
|
238
238
|
searchParams: {
|
|
239
239
|
keyword: t
|
|
240
240
|
},
|
|
@@ -244,24 +244,24 @@ class Et extends et {
|
|
|
244
244
|
Host: "www.hifleet.com"
|
|
245
245
|
}
|
|
246
246
|
};
|
|
247
|
-
let
|
|
248
|
-
p == null || p.info("[%s] fetch vessel props from: %s - %j", n.requestId,
|
|
249
|
-
for (const d in
|
|
250
|
-
!isNaN(
|
|
247
|
+
let a = await B.post(i, o).json();
|
|
248
|
+
p == null || p.info("[%s] fetch vessel props from: %s - %j", n.requestId, i, o), a instanceof Array && (a = a[0]);
|
|
249
|
+
for (const d in a)
|
|
250
|
+
!isNaN(a[d]) && Number(a[d]) !== 1 / 0 && (a[d] = Number(a[d]));
|
|
251
251
|
const s = {
|
|
252
|
-
mmsi:
|
|
253
|
-
name:
|
|
254
|
-
imo:
|
|
255
|
-
callSign:
|
|
256
|
-
length:
|
|
257
|
-
breadth:
|
|
258
|
-
draught:
|
|
259
|
-
type:
|
|
252
|
+
mmsi: a.m,
|
|
253
|
+
name: a.n,
|
|
254
|
+
imo: a.i,
|
|
255
|
+
callSign: a.c,
|
|
256
|
+
length: a.l,
|
|
257
|
+
breadth: a.b,
|
|
258
|
+
draught: a.dr,
|
|
259
|
+
type: a.t
|
|
260
260
|
};
|
|
261
|
-
return
|
|
261
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await B.post(i, o).json(), p == null || p.info("[%s] search vessel dead weight from: %s - %j", n.requestId, i, o), a instanceof Array && (a = a[0]), a && (s.deadweight = Number(a.dwt)), s;
|
|
262
262
|
}
|
|
263
263
|
async suggest(t, n = {}) {
|
|
264
|
-
const
|
|
264
|
+
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", o = {
|
|
265
265
|
searchParams: {
|
|
266
266
|
q: t
|
|
267
267
|
},
|
|
@@ -270,10 +270,10 @@ class Et extends et {
|
|
|
270
270
|
Origin: "https://www.hifleet.com",
|
|
271
271
|
Host: "www.hifleet.com"
|
|
272
272
|
}
|
|
273
|
-
},
|
|
274
|
-
p == null || p.info("[%s] suggest vessel props from: %s - %j", n.requestId,
|
|
273
|
+
}, a = await B.post(i, o).json();
|
|
274
|
+
p == null || p.info("[%s] suggest vessel props from: %s - %j", n.requestId, i, o);
|
|
275
275
|
const s = [];
|
|
276
|
-
for (const d of
|
|
276
|
+
for (const d of a)
|
|
277
277
|
s.push({
|
|
278
278
|
mmsi: !d.mmsi || isNaN(d.mmsi) ? null : Number(d.mmsi),
|
|
279
279
|
name: d.name,
|
|
@@ -281,37 +281,37 @@ 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, r) => r.score - d.score), s;
|
|
285
285
|
}
|
|
286
|
-
async trajectory(t, n,
|
|
286
|
+
async trajectory(t, n, i, o, a = !0, s = {}) {
|
|
287
287
|
var c, f, l;
|
|
288
288
|
const d = await this.realTimePosition(t, s);
|
|
289
|
-
let
|
|
290
|
-
const h = g(
|
|
291
|
-
if (
|
|
292
|
-
let u = h.diff(
|
|
293
|
-
u < 0 ?
|
|
289
|
+
let r = g(n);
|
|
290
|
+
const h = g(i), M = g();
|
|
291
|
+
if (a) {
|
|
292
|
+
let u = h.diff(r, "d", !0);
|
|
293
|
+
u < 0 ? r = h.clone().subtract(40, "d") : u < 30 ? r.subtract(10, "d") : u < 60 ? r.subtract(5, "d") : r = 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: r.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,
|
|
304
|
-
let
|
|
305
|
-
m && (
|
|
306
|
-
const
|
|
307
|
-
let
|
|
308
|
-
const b = g(`${(l =
|
|
309
|
-
for (const u of
|
|
302
|
+
}, v = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", m = await B.get(v, y).json();
|
|
303
|
+
p == null || p.info("[%s] fetch trajectory from: %s - %j", s.requestId, v, y);
|
|
304
|
+
let C;
|
|
305
|
+
m && (C = ((f = (c = m.ships) == null ? void 0 : c.offors) == null ? void 0 : f.ship) || [], C.length || p == null || p.warn("[%s] fetch trajectory failed: %j", s.requestId, m));
|
|
306
|
+
const S = [];
|
|
307
|
+
let w = -1;
|
|
308
|
+
const b = g(`${(l = C == null ? void 0 : C[0]) == null ? void 0 : l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
309
|
+
for (const u of C) {
|
|
310
310
|
for (const P in u)
|
|
311
311
|
!isNaN(u[P]) && Number(u[P]) !== 1 / 0 && (u[P] = Number(u[P]));
|
|
312
312
|
const I = g(`${u.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
313
313
|
u.status = u.sp > 4 ? 0 : 1;
|
|
314
|
-
const { labelEn:
|
|
314
|
+
const { labelEn: k, labelCn: D } = this.parseStatus(u.status), Y = {
|
|
315
315
|
mmsi: u.m,
|
|
316
316
|
name: u.n,
|
|
317
317
|
imo: d == null ? void 0 : d.imo,
|
|
@@ -325,35 +325,35 @@ class Et extends et {
|
|
|
325
325
|
utc: I.utc().format(),
|
|
326
326
|
status: u.status,
|
|
327
327
|
labelCn: D,
|
|
328
|
-
labelEn:
|
|
328
|
+
labelEn: k,
|
|
329
329
|
method: "trajectory",
|
|
330
330
|
vendor: "hifleet"
|
|
331
|
-
},
|
|
332
|
-
|
|
331
|
+
}, j = Math.floor(I.diff(b, "minute", !0) / (o || 1));
|
|
332
|
+
j !== w && (w = j, S.push(Y));
|
|
333
333
|
}
|
|
334
|
-
return
|
|
334
|
+
return S;
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
-
class
|
|
337
|
+
class jt extends et {
|
|
338
338
|
constructor(t) {
|
|
339
339
|
super();
|
|
340
|
-
|
|
340
|
+
K(this, "token");
|
|
341
341
|
this.token = t;
|
|
342
342
|
}
|
|
343
343
|
async realTimePosition(t, n = {}) {
|
|
344
|
-
const
|
|
344
|
+
const i = {
|
|
345
345
|
searchParams: {
|
|
346
346
|
id: t,
|
|
347
347
|
k: this.token,
|
|
348
348
|
enc: 1
|
|
349
349
|
}
|
|
350
|
-
},
|
|
351
|
-
if (p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId,
|
|
352
|
-
return
|
|
353
|
-
const s =
|
|
350
|
+
}, o = "https://api.shipxy.com/apicall/GetSingleShip", a = await B.get(o, i).json();
|
|
351
|
+
if (p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, o, i), (a == null ? void 0 : a.status) !== 0)
|
|
352
|
+
return a;
|
|
353
|
+
const s = a.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: r } = 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: r,
|
|
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, i, o, a = !0, s = {}) {
|
|
381
381
|
var b;
|
|
382
|
-
const d = await this.realTimePosition(t, s),
|
|
382
|
+
const d = await this.realTimePosition(t, s), r = g(n), h = g(i), 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: r.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
|
+
}, v = await B.get(M, y).json();
|
|
392
|
+
if (p == null || p.info("[%s] fetch trajectory from: %s - %j", s.requestId, M, y), (v == null ? void 0 : v.status) !== 0)
|
|
393
|
+
return v;
|
|
394
|
+
const m = v == null ? void 0 : v.points, C = [], S = g.unix((b = m[0]) == null ? void 0 : b.utc);
|
|
395
|
+
let w = -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,
|
|
@@ -405,41 +405,41 @@ class Nt extends et {
|
|
|
405
405
|
utc: f.utc().format(),
|
|
406
406
|
method: "trajectory",
|
|
407
407
|
vendor: "shipxy"
|
|
408
|
-
}, u = Math.floor(f.diff(
|
|
409
|
-
u !==
|
|
408
|
+
}, u = Math.floor(f.diff(S, "minute", !0) / (o || 1));
|
|
409
|
+
u !== w && (w = u, C.push(l));
|
|
410
410
|
}
|
|
411
|
-
return
|
|
411
|
+
return C;
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
|
-
class
|
|
414
|
+
class Nt extends et {
|
|
415
415
|
constructor(t) {
|
|
416
416
|
super();
|
|
417
|
-
|
|
417
|
+
K(this, "token");
|
|
418
418
|
this.token = t;
|
|
419
419
|
}
|
|
420
420
|
async getShipId(t, n = {}) {
|
|
421
|
-
const
|
|
421
|
+
const i = {
|
|
422
422
|
headers: {
|
|
423
423
|
appKey: this.token
|
|
424
424
|
},
|
|
425
425
|
json: {
|
|
426
426
|
mmsiList: t
|
|
427
427
|
}
|
|
428
|
-
},
|
|
429
|
-
return p == null || p.info("[%s] fetch ship id from: %s - %j", n.requestId,
|
|
428
|
+
}, o = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await B.post(o, i).json();
|
|
429
|
+
return p == null || p.info("[%s] fetch ship id from: %s - %j", n.requestId, o, i), a.code !== "0" ? a : a.data[0].shipId;
|
|
430
430
|
}
|
|
431
431
|
async getShipInfo(t, n = {}) {
|
|
432
|
-
const
|
|
432
|
+
const i = {
|
|
433
433
|
headers: {
|
|
434
434
|
appKey: this.token
|
|
435
435
|
},
|
|
436
436
|
json: {
|
|
437
437
|
shipId: t
|
|
438
438
|
}
|
|
439
|
-
},
|
|
440
|
-
if (p == null || p.info("[%s] fetch ship info from: %s - %j", n.requestId,
|
|
441
|
-
return
|
|
442
|
-
const s =
|
|
439
|
+
}, o = "https://api3.myships.com/sp/ships/aissta", a = await B.post(o, i).json();
|
|
440
|
+
if (p == null || p.info("[%s] fetch ship info from: %s - %j", n.requestId, o, i), a.code !== "0")
|
|
441
|
+
return a;
|
|
442
|
+
const s = a.data;
|
|
443
443
|
let d = s.imo;
|
|
444
444
|
return t === "407170" && (d = "9198379", p == null || p.warn("[%s] ship(%s) imo error: %s, should be %s", n.requestId, t, s.imo, d)), {
|
|
445
445
|
mmsi: s.mmsi,
|
|
@@ -452,45 +452,45 @@ class Tt extends et {
|
|
|
452
452
|
};
|
|
453
453
|
}
|
|
454
454
|
async realTimePosition(t, n = {}) {
|
|
455
|
-
const
|
|
455
|
+
const i = await this.getShipId(t, n), o = await this.getShipInfo(i, n), a = {
|
|
456
456
|
headers: {
|
|
457
457
|
appKey: this.token
|
|
458
458
|
},
|
|
459
459
|
json: {
|
|
460
|
-
shipId:
|
|
460
|
+
shipId: i
|
|
461
461
|
}
|
|
462
|
-
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s,
|
|
463
|
-
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, s,
|
|
464
|
-
const
|
|
465
|
-
for (const m in
|
|
466
|
-
!isNaN(
|
|
467
|
-
const { labelCn: h, labelEn: M } = await this.parseStatus(
|
|
462
|
+
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s, a).json();
|
|
463
|
+
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, s, a);
|
|
464
|
+
const r = d.data[0];
|
|
465
|
+
for (const m in r)
|
|
466
|
+
!isNaN(r[m]) && Number(r[m]) !== 1 / 0 && (r[m] = Number(r[m]));
|
|
467
|
+
const { labelCn: h, labelEn: M } = await this.parseStatus(r.aisNavStatus), y = g.unix(r.posTime);
|
|
468
468
|
return {
|
|
469
|
-
...
|
|
469
|
+
...o,
|
|
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(r.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
472
|
+
lng: Math.round(r.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
473
|
+
sog: Math.round(r.sog / 10 * 100) / 100,
|
|
474
|
+
cog: Math.round(r.cog / 10 * 100) / 100,
|
|
475
|
+
hdg: Math.round(r.heading * 100) / 100,
|
|
476
|
+
rot: Math.round(r.rot * 100) / 100,
|
|
477
|
+
positionTime: r.posTime,
|
|
478
478
|
utc: y.utc().format(),
|
|
479
|
-
status:
|
|
479
|
+
status: r.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 (;
|
|
489
|
-
await this.trajectoryIn30Day(h, d.unix(), d.add(30, "day").unix(), M, t,
|
|
490
|
-
return await this.trajectoryIn30Day(h, d.unix(),
|
|
486
|
+
async trajectory(t, n, i, o, a = !0, s = {}) {
|
|
487
|
+
const d = g(n), r = g(i), h = await this.getShipId(t), M = await this.getShipInfo(h), y = [];
|
|
488
|
+
for (; r.diff(d, "day", !0) > 30; )
|
|
489
|
+
await this.trajectoryIn30Day(h, d.unix(), d.add(30, "day").unix(), M, t, o, y);
|
|
490
|
+
return await this.trajectoryIn30Day(h, d.unix(), r.unix(), M, t, o, y), y;
|
|
491
491
|
}
|
|
492
|
-
async trajectoryIn30Day(t, n,
|
|
493
|
-
var
|
|
492
|
+
async trajectoryIn30Day(t, n, i, o, a, s, d, r = {}) {
|
|
493
|
+
var S;
|
|
494
494
|
const h = {
|
|
495
495
|
headers: {
|
|
496
496
|
appKey: this.token
|
|
@@ -498,32 +498,32 @@ class Tt extends et {
|
|
|
498
498
|
json: {
|
|
499
499
|
shipId: t,
|
|
500
500
|
startTime: n,
|
|
501
|
-
endTime:
|
|
501
|
+
endTime: i
|
|
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(w
|
|
509
|
-
const m = g.unix((
|
|
510
|
-
let
|
|
511
|
-
for (const
|
|
512
|
-
const b = g.unix(
|
|
513
|
-
imo:
|
|
514
|
-
mmsi:
|
|
515
|
-
lat: Math.round(
|
|
516
|
-
lng: Math.round(
|
|
517
|
-
sog: Math.round(
|
|
518
|
-
cog: Math.round(
|
|
519
|
-
hdg: Math.round(
|
|
520
|
-
rot: Math.round(
|
|
504
|
+
if (p == null || p.info("[%s] fetch trajectory from: %s - %j", r.requestId, M, h), y.code !== "0")
|
|
505
|
+
return p == null || p.warn("[%s] invoke myship trajectory failed: %j", r.requestId, y), y;
|
|
506
|
+
const v = y.data;
|
|
507
|
+
for (const w in v)
|
|
508
|
+
!isNaN(v[w]) && Number(v[w]) !== 1 / 0 && (v[w] = Number(v[w]));
|
|
509
|
+
const m = g.unix((S = v[0]) == null ? void 0 : S.posTime);
|
|
510
|
+
let C = -1;
|
|
511
|
+
for (const w of v) {
|
|
512
|
+
const b = g.unix(w.posTime), c = {
|
|
513
|
+
imo: o == null ? void 0 : o.imo,
|
|
514
|
+
mmsi: a,
|
|
515
|
+
lat: Math.round(w.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
516
|
+
lng: Math.round(w.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
517
|
+
sog: Math.round(w.sog / 10 * 100) / 100,
|
|
518
|
+
cog: Math.round(w.cog / 10 * 100) / 100,
|
|
519
|
+
hdg: Math.round(w.heading * 100) / 100,
|
|
520
|
+
rot: Math.round(w.rot * 100) / 100,
|
|
521
521
|
positionTime: b.unix(),
|
|
522
522
|
utc: b.utc().format(),
|
|
523
523
|
method: "trajectory",
|
|
524
524
|
vendor: "myship"
|
|
525
525
|
}, f = Math.floor(b.diff(m, "minute", !0) / (s || 1));
|
|
526
|
-
f !==
|
|
526
|
+
f !== C && (C = f, d.push(c));
|
|
527
527
|
}
|
|
528
528
|
return d;
|
|
529
529
|
}
|
|
@@ -534,8 +534,8 @@ try {
|
|
|
534
534
|
} catch {
|
|
535
535
|
} finally {
|
|
536
536
|
}
|
|
537
|
-
var
|
|
538
|
-
class
|
|
537
|
+
var mt = /* @__PURE__ */ ((E) => (E.NOTICE = "NOTICE", E.WARN = "WARN", E.HEAVY = "HEAVY", E.SEVERE = "SEVERE", E.ERROR = "ERROR", E.FATAL = "FATAL", E))(mt || {});
|
|
538
|
+
class yt {
|
|
539
539
|
/**
|
|
540
540
|
* 解析告警规则, 多规则场景
|
|
541
541
|
* @param rule
|
|
@@ -545,23 +545,23 @@ class Mt {
|
|
|
545
545
|
* @param options
|
|
546
546
|
*/
|
|
547
547
|
parsePrinciple(e, t = {}) {
|
|
548
|
-
var s, d,
|
|
548
|
+
var s, d, r;
|
|
549
549
|
_ == null || _.info("[%s] parse rule: %s", t.requestId, e);
|
|
550
|
-
const n = new RegExp("(?<=\\[)(.+)(?=])", "g"),
|
|
551
|
-
if (!
|
|
550
|
+
const n = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = e.match(n) ? (s = e.match(n)) == null ? void 0 : s[0] : void 0, o = i == null ? void 0 : i.split(";");
|
|
551
|
+
if (!o)
|
|
552
552
|
return;
|
|
553
|
-
const
|
|
554
|
-
for (let h = 0; h < (
|
|
555
|
-
const M = (
|
|
553
|
+
const a = {};
|
|
554
|
+
for (let h = 0; h < (o == null ? void 0 : o.length); h++) {
|
|
555
|
+
const M = (r = (d = o[h].match(n)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
|
|
556
556
|
if (h === 0 && !M)
|
|
557
|
-
|
|
557
|
+
a.scope = o[0];
|
|
558
558
|
else if (M)
|
|
559
|
-
for (let y = 0,
|
|
559
|
+
for (let y = 0, v = M.length; y < v; y++) {
|
|
560
560
|
const m = this.parseRule(M[y]);
|
|
561
|
-
m && (
|
|
561
|
+
m && (a[m.level] ? m.key ? a[m.level][m == null ? void 0 : m.key] = m : a[m.level] = m : m.key ? a[m.level] = { [m == null ? void 0 : m.key]: m } : a[m.level] = m);
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
|
-
return
|
|
564
|
+
return a;
|
|
565
565
|
}
|
|
566
566
|
/**
|
|
567
567
|
* 解析单一告警规则
|
|
@@ -570,16 +570,16 @@ class Mt {
|
|
|
570
570
|
* @param options
|
|
571
571
|
*/
|
|
572
572
|
parseRule(e, t = {}) {
|
|
573
|
-
var
|
|
573
|
+
var a;
|
|
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"),
|
|
576
|
-
if (
|
|
575
|
+
const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (a = e == null ? void 0 : e.match(n)) == null ? void 0 : a[0], o = i == null ? void 0 : i.split(",");
|
|
576
|
+
if (o)
|
|
577
577
|
return {
|
|
578
|
-
operator:
|
|
579
|
-
number: Number.isNaN(Number(
|
|
580
|
-
level:
|
|
581
|
-
time: Number(
|
|
582
|
-
key:
|
|
578
|
+
operator: o[0],
|
|
579
|
+
number: Number.isNaN(Number(o[1])) ? o[1] : Number(o[1]),
|
|
580
|
+
level: o[2],
|
|
581
|
+
time: Number(o[3]),
|
|
582
|
+
key: o[4]
|
|
583
583
|
};
|
|
584
584
|
}
|
|
585
585
|
/**
|
|
@@ -589,25 +589,25 @@ class Mt {
|
|
|
589
589
|
* @param options
|
|
590
590
|
*/
|
|
591
591
|
checkWeather(e, t, n = {}) {
|
|
592
|
-
var m,
|
|
593
|
-
let
|
|
594
|
-
const d = Math.round(((
|
|
592
|
+
var m, C, S, w, b, c, f, l, u, I, k, D, Y, j, P;
|
|
593
|
+
let i = 0, o = 0, a = 0, s = 0;
|
|
594
|
+
const d = Math.round(((C = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.sigWave) == null ? void 0 : C.number) * 1.6 * 100) / 100, r = (w = (S = t == null ? void 0 : t.SEVERE) == null ? void 0 : S.sigWave) == null ? void 0 : w.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, v = (D = (k = t == null ? void 0 : t.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : D.number;
|
|
595
595
|
for (let T = 0; T < (e == null ? void 0 : e.length); T++) {
|
|
596
|
-
const N = e[T], A = (
|
|
597
|
-
s =
|
|
596
|
+
const N = e[T], A = (j = (Y = N == null ? void 0 : N.meteo) == null ? void 0 : Y.wave) == null ? void 0 : j.sig, R = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wind, U = T ? g(N.eta).diff(g(e[T - 1].eta), "hour", !0) : 0;
|
|
597
|
+
s = U > s ? U : s, _ == null || _.info("[%s] check sig.wave: %j", n.requestId, { ...A, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h }), (A == null ? void 0 : A.height) >= d ? N.isDangerous = !0 : (A == null ? void 0 : A.height) >= r ? 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: v }), (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) === v && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? U : 0, o += N.isSevere ? U : 0, a += N.isHeavy ? U : 0;
|
|
598
598
|
}
|
|
599
|
-
return
|
|
599
|
+
return i = Math.round(i * 100) / 100, o = Math.round(o * 100) / 100, a = Math.round(a * 100) / 100, s = Math.round(s), { sample: e, dangerous: i, severe: o, heavy: a, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd: y, hvThd4Wd: v }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h } };
|
|
600
600
|
}
|
|
601
601
|
}
|
|
602
|
-
const
|
|
603
|
-
let
|
|
602
|
+
const Tt = new yt();
|
|
603
|
+
let F;
|
|
604
604
|
try {
|
|
605
|
-
|
|
605
|
+
F = rt.getLogger("vessel");
|
|
606
606
|
} catch {
|
|
607
607
|
} finally {
|
|
608
608
|
}
|
|
609
|
-
const
|
|
610
|
-
var
|
|
609
|
+
const Mt = new ft("", !0);
|
|
610
|
+
var gt = /* @__PURE__ */ ((E) => (E.common = "common", E.container = "container", E.tugs = "tugs", E))(gt || {}), bt = /* @__PURE__ */ ((E) => (E.Ballast = "Ballast", E.Laden = "Laden", E))(bt || {}), pt = /* @__PURE__ */ ((E) => (E.Cp = "CP", E.Perf = "Basis", E.Instruct = "Other", E))(pt || {});
|
|
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,11 +621,11 @@ class O {
|
|
|
621
621
|
* @param draught 吃水 m
|
|
622
622
|
* @return [0.55, 0.85]
|
|
623
623
|
*/
|
|
624
|
-
static blockCoefficient(e, t, n,
|
|
625
|
-
let
|
|
626
|
-
|
|
627
|
-
const
|
|
628
|
-
return
|
|
624
|
+
static blockCoefficient(e, t, n, i) {
|
|
625
|
+
let o = Math.round(e / (t * n * i) * 100) / 100;
|
|
626
|
+
o = o < 0.55 ? 0.55 : o > 0.85 ? 0.85 : o;
|
|
627
|
+
const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = a.map((d) => Math.abs(d - o));
|
|
628
|
+
return a[s.indexOf(Math.min(...s))];
|
|
629
629
|
}
|
|
630
630
|
/**
|
|
631
631
|
* @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
|
|
@@ -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 i = Math.round(Math.sqrt(e * e / (n * t)) * 100) / 100;
|
|
643
|
+
return i = i < 0.05 ? 0.05 : i > 0.3 ? 0.3 : i, i;
|
|
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 i = {
|
|
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],
|
|
@@ -659,7 +659,7 @@ class O {
|
|
|
659
659
|
0.8: [2.6, -13.1, -15.1],
|
|
660
660
|
0.85: [3.1, -18.7, 28]
|
|
661
661
|
};
|
|
662
|
-
let
|
|
662
|
+
let a = {
|
|
663
663
|
0.55: [1.7, -1.4, -7.4],
|
|
664
664
|
0.6: [2.2, -2.5, -9.7],
|
|
665
665
|
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" && (
|
|
671
|
+
return n === "Laden" && (a = i[e]), a[0] + a[1] * t + a[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
|
-
|
|
701
|
-
let
|
|
702
|
-
return n === "container" ?
|
|
699
|
+
static vesselTagFactor(e, t, n, i = 0) {
|
|
700
|
+
i = i > 6 ? i - 0.9 * (i - 6) : i;
|
|
701
|
+
let o;
|
|
702
|
+
return n === "container" ? o = 0.7 * i + Math.pow(i, 6.5) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? o = 0.7 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(e, 2 / 3)) : o = 0.5 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(e, 2 / 3)), o;
|
|
703
703
|
}
|
|
704
704
|
/**
|
|
705
705
|
* 浪高影响因子
|
|
@@ -719,21 +719,21 @@ class O {
|
|
|
719
719
|
* @param bearing 方位角
|
|
720
720
|
* @private
|
|
721
721
|
*/
|
|
722
|
-
static assembleProperties(e, t, n,
|
|
722
|
+
static assembleProperties(e, t, n, i) {
|
|
723
723
|
var y;
|
|
724
|
-
const
|
|
724
|
+
const o = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, a = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, d = e.deadweight ?? 67035.7773, r = ((y = e == null ? void 0 : e.type) == null ? void 0 : y.toLowerCase()) || "common";
|
|
725
725
|
return {
|
|
726
|
-
tag:
|
|
727
|
-
lbp:
|
|
726
|
+
tag: r.indexOf("container") > -1 ? "container" : r.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
727
|
+
lbp: o,
|
|
728
728
|
loadCondition: t,
|
|
729
|
-
draught:
|
|
729
|
+
draught: a,
|
|
730
730
|
breadthMoulded: s,
|
|
731
731
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
732
732
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
733
|
-
displacement: Math.round((d / 1.025 +
|
|
733
|
+
displacement: Math.round((d / 1.025 + a * s * o * 0.7) * 1e4) / 1e4,
|
|
734
734
|
// 换算为m/s
|
|
735
735
|
speed: Math.round((n ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
736
|
-
bearing:
|
|
736
|
+
bearing: i || 90
|
|
737
737
|
};
|
|
738
738
|
}
|
|
739
739
|
/**
|
|
@@ -746,37 +746,41 @@ class O {
|
|
|
746
746
|
* @param useMeteo true 启用气象分析
|
|
747
747
|
* @param useRouteParam true 启用设置速度
|
|
748
748
|
*/
|
|
749
|
-
static async speedLoseAt(e, t, n,
|
|
750
|
-
let
|
|
751
|
-
if (t.velocity && s && (e.speed = J.roundPrecision(t.velocity * 1852 / 3600, 6)),
|
|
749
|
+
static async speedLoseAt(e, t, n, i = "", o = 2, a = !0, s = !1, d = {}) {
|
|
750
|
+
let r;
|
|
751
|
+
if (t.velocity && s && (e.speed = J.roundPrecision(t.velocity * 1852 / 3600, 6)), a) {
|
|
752
752
|
let h;
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
753
|
+
try {
|
|
754
|
+
i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
|
|
755
|
+
const { weatherModels: m, marineModels: C } = await it.autoPickMeteoModel(i), S = await Mt.spotForecast(t.lat, t.lng, n.utc().format(), !1, !1, !0, {
|
|
756
|
+
...d,
|
|
757
|
+
pastDays: 1,
|
|
758
|
+
forecastDays: 1,
|
|
759
|
+
weatherModels: m,
|
|
760
|
+
marineModels: C
|
|
761
|
+
}), [w] = it.pickHourly(S, n);
|
|
762
|
+
h = it.toLegacy(w);
|
|
763
|
+
} catch (m) {
|
|
764
|
+
F.warn("[%s] meteo2 spot(%j) forecast failed: %s", d.requestId, { ...t, eta: n.utc().format(), source: i }, m);
|
|
765
|
+
}
|
|
766
|
+
const M = O.weatherFactor(e, h), y = O.currentFactor(e.bearing, h == null ? void 0 : h.current, o), v = Math.round((e.speed * 1.943844 + M + y) * 100) / 100;
|
|
767
|
+
r = {
|
|
764
768
|
meteo: { ...h },
|
|
765
769
|
wxFactor: M,
|
|
766
770
|
cFactor: y,
|
|
767
|
-
speed: t.velocity && s ? t.velocity :
|
|
771
|
+
speed: t.velocity && s ? t.velocity : v < 0 ? 1 : v,
|
|
768
772
|
eta: n.utc().format(),
|
|
769
773
|
etd: n.utc().format()
|
|
770
774
|
};
|
|
771
775
|
} else
|
|
772
|
-
|
|
776
|
+
r = {
|
|
773
777
|
wxFactor: 0,
|
|
774
778
|
cFactor: 0,
|
|
775
779
|
speed: t.velocity && s ? t.velocity : Math.round((e.speed * 1.943844 + 0 + 0) * 100) / 100,
|
|
776
780
|
eta: n.utc().format(),
|
|
777
781
|
etd: n.utc().format()
|
|
778
782
|
};
|
|
779
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
783
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...r, ...t };
|
|
780
784
|
}
|
|
781
785
|
/**
|
|
782
786
|
* 基于步长计算失速样本
|
|
@@ -791,53 +795,53 @@ class O {
|
|
|
791
795
|
* @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
|
|
792
796
|
* @private
|
|
793
797
|
*/
|
|
794
|
-
static async speedLoseInHoursStep(e, t, n,
|
|
798
|
+
static async speedLoseInHoursStep(e, t, n, i, o, a, s = "", d = !0, r = !1, h = {}) {
|
|
795
799
|
t.utc();
|
|
796
|
-
const M = t.clone().add(14, "days"), y = [],
|
|
797
|
-
let m = 0,
|
|
798
|
-
for (let b = 0; b <
|
|
799
|
-
let c =
|
|
800
|
-
c.distanceFromStart = Math.round((
|
|
801
|
-
const f =
|
|
802
|
-
if (e.bearing = W.calculateBearing(c, f, !f.gcToPrevious), c.bearing = e.bearing, c.suspend &&
|
|
800
|
+
const M = t.clone().add(14, "days"), y = [], v = [];
|
|
801
|
+
let m = 0, C = 0, S, w;
|
|
802
|
+
for (let b = 0; b < a.length - 1; b++) {
|
|
803
|
+
let c = a[b];
|
|
804
|
+
c.distanceFromStart = Math.round((o + C) * 1e4) / 1e4;
|
|
805
|
+
const f = a[b + 1];
|
|
806
|
+
if (e.bearing = W.calculateBearing(c, f, !f.gcToPrevious), c.bearing = e.bearing, c.suspend && r) {
|
|
803
807
|
c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
|
|
804
808
|
const I = c.suspend - c.elapsed;
|
|
805
|
-
if (
|
|
806
|
-
|
|
809
|
+
if (i - m > I)
|
|
810
|
+
i = i - m - I, t.add(I, "hour"), c.elapsed = c.suspend;
|
|
807
811
|
else {
|
|
808
|
-
const
|
|
809
|
-
c.elapsed +=
|
|
812
|
+
const k = i - m;
|
|
813
|
+
c.elapsed += k, t.add(k, "hour"), i = 0;
|
|
810
814
|
}
|
|
811
|
-
if (
|
|
812
|
-
return c.distanceFromPrevious =
|
|
815
|
+
if (F == null || F.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`, h.requestId, c), i === 0)
|
|
816
|
+
return c.distanceFromPrevious = C, { etd: t, from: w || c, to: c, next: a.filter((k) => k), wps: y, days: v };
|
|
813
817
|
} else
|
|
814
818
|
c.suspend = 0;
|
|
815
|
-
d = t.isAfter(M) ? !1 : d, c = await O.speedLoseAt(e, c, t, s, 0, d,
|
|
819
|
+
d = t.isAfter(M) ? !1 : d, c = await O.speedLoseAt(e, c, t, s, 0, d, r, h), w = w || c, c.important && y.push(c), t.isSameOrAfter(n) && (v.push(c), n.add(24, "hour"));
|
|
816
820
|
const l = W.calculateDistance(c, f, !f.gcToPrevious);
|
|
817
|
-
let u = Math.round(l /
|
|
818
|
-
if (m + u <
|
|
819
|
-
if (m += u, t.add(u, "hour"), delete
|
|
821
|
+
let u = Math.round(l / w.speed * 1e5) / 1e5;
|
|
822
|
+
if (m + u < i) {
|
|
823
|
+
if (m += u, t.add(u, "hour"), delete a[b], F == null || F.debug(
|
|
820
824
|
`[%s] go to %j from %j with ${l}nm, and cost ${u} hours`,
|
|
821
825
|
h.requestId,
|
|
822
826
|
{ lat: f.lat, lng: f.lng },
|
|
823
|
-
{ lat:
|
|
824
|
-
),
|
|
825
|
-
|
|
827
|
+
{ lat: w.lat, lng: w.lng, etd: w.etd }
|
|
828
|
+
), C += l, a.filter((I) => I).length <= 1) {
|
|
829
|
+
S = f, S.eta = t.utc().format(), S.distanceFromPrevious = l, S.distanceFromStart = Math.round((o + C) * 1e4) / 1e4, y.push(S), delete a[b + 1];
|
|
826
830
|
break;
|
|
827
831
|
}
|
|
828
832
|
} else {
|
|
829
|
-
u =
|
|
830
|
-
const I = J.roundPrecision(
|
|
831
|
-
|
|
833
|
+
u = i - m, t.add(u, "hour");
|
|
834
|
+
const I = J.roundPrecision(w.speed * u, 5);
|
|
835
|
+
S = W.calculateCoordinate(c, e.bearing, I, "nauticalmiles", !f.gcToPrevious), S.eta = t.utc().format(), a[b] = S, F == null || F.debug(
|
|
832
836
|
`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,
|
|
833
837
|
h.requestId,
|
|
834
|
-
{ lat:
|
|
838
|
+
{ lat: S.lat, lng: S.lng },
|
|
835
839
|
{ lat: c.lat, lng: c.lng, etd: c.etd }
|
|
836
|
-
),
|
|
840
|
+
), C += I, S.distanceFromPrevious = Math.round(C * 1e4) / 1e4, S.distanceFromStart = Math.round((o + C) * 1e4) / 1e4;
|
|
837
841
|
break;
|
|
838
842
|
}
|
|
839
843
|
}
|
|
840
|
-
return { etd: t, from:
|
|
844
|
+
return { etd: t, from: w, to: S, next: a.filter((b) => b), wps: y, days: v };
|
|
841
845
|
}
|
|
842
846
|
/**
|
|
843
847
|
* 洋流影响因子
|
|
@@ -846,11 +850,11 @@ class O {
|
|
|
846
850
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
847
851
|
*/
|
|
848
852
|
static currentFactor(e, t, n = 0) {
|
|
849
|
-
const
|
|
850
|
-
if (Math.abs(
|
|
853
|
+
const i = (e - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
854
|
+
if (Math.abs(i) === Math.PI / 2)
|
|
851
855
|
return 0;
|
|
852
|
-
let
|
|
853
|
-
return n & 2 ?
|
|
856
|
+
let o = ((t == null ? void 0 : t.kts) || 0) * Math.cos(i);
|
|
857
|
+
return n & 2 ? o = Math.ceil(o * 100) / 100 : n & 1 ? o = Math.floor(o * 100) / 100 : o = Math.round(o * 100) / 100, Math.abs(o) > 5 ? 0 : o;
|
|
854
858
|
}
|
|
855
859
|
/**
|
|
856
860
|
* 风浪影响因子
|
|
@@ -858,16 +862,16 @@ class O {
|
|
|
858
862
|
* @param wwc 气象要素
|
|
859
863
|
*/
|
|
860
864
|
static weatherFactor(e, t) {
|
|
861
|
-
var M, y,
|
|
862
|
-
|
|
863
|
-
const n = O.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught),
|
|
864
|
-
let
|
|
865
|
-
|
|
866
|
-
const s = O.directionFactor(
|
|
867
|
-
let
|
|
868
|
-
|
|
869
|
-
const h = O.waveHeightFactor(((
|
|
870
|
-
return
|
|
865
|
+
var M, y, v, m, C, S, w;
|
|
866
|
+
F == null || F.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
867
|
+
const n = O.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), i = O.froudeNumber(e.speed, e.lbp), o = O.amendFactor(n, i, e.loadCondition);
|
|
868
|
+
let a = Math.abs(e.bearing % 360 - (((M = t == null ? void 0 : t.wind) == null ? void 0 : M.degree) % 360 || 0));
|
|
869
|
+
a = a > 180 ? 360 - a : a;
|
|
870
|
+
const s = O.directionFactor(a, (y = t == null ? void 0 : t.wind) == null ? void 0 : y.scale), d = O.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (v = t == null ? void 0 : t.wind) == null ? void 0 : v.scale);
|
|
871
|
+
let r = s * o * d / 100 * e.speed;
|
|
872
|
+
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), F == null || F.debug("wind wx factor = %d", r), a = Math.abs(e.bearing % 360 - (((C = (m = t == null ? void 0 : t.wave) == null ? void 0 : m.sig) == null ? void 0 : C.degree) % 360 || 0));
|
|
873
|
+
const h = O.waveHeightFactor(((w = (S = t == null ? void 0 : t.wave) == null ? void 0 : S.sig) == null ? void 0 : w.height) ?? 1, a);
|
|
874
|
+
return F == null || F.debug("wave wx factor = %d", h), r = r * 0.4 + h, F == null || F.debug("weather factor = %d", r), r = Math.abs(r) > 4 ? 4 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 4) * 0.1 : r, Math.round((r || 0) * 100) / 100;
|
|
871
875
|
}
|
|
872
876
|
/**
|
|
873
877
|
* 全程失速分析(走完航程)
|
|
@@ -881,79 +885,79 @@ class O {
|
|
|
881
885
|
* @param useMeteo true 启用气象分析
|
|
882
886
|
* @param useRouteParam
|
|
883
887
|
*/
|
|
884
|
-
static async analyseInstant(e, t, n,
|
|
885
|
-
var
|
|
888
|
+
static async analyseInstant(e, t, n, i, o, a = "", s = 0, d = !0, r = !1, h = {}) {
|
|
889
|
+
var z, G, Q, X, Z, $;
|
|
886
890
|
const M = g().valueOf();
|
|
887
891
|
e.lng = J.convertToStdLng(e.lng);
|
|
888
|
-
const { route: y, waypoints:
|
|
889
|
-
if (((
|
|
892
|
+
const { route: y, waypoints: v } = o.points, m = W.calculateSubRoute(e, y);
|
|
893
|
+
if (((z = m[0]) == null ? void 0 : z.length) <= 1)
|
|
890
894
|
return;
|
|
891
|
-
const { v0:
|
|
895
|
+
const { v0: C, label: S } = e.sog ? {
|
|
892
896
|
v0: e.sog,
|
|
893
|
-
label: "Other"
|
|
897
|
+
label: e.label || "Other"
|
|
894
898
|
/* Instruct */
|
|
895
899
|
} : {
|
|
896
|
-
v0:
|
|
900
|
+
v0: i.speed,
|
|
897
901
|
label: "CP"
|
|
898
902
|
/* Cp */
|
|
899
|
-
},
|
|
903
|
+
}, w = O.assembleProperties(n, i.loadCondition, C, 0), b = v.length ? W.calculateSubWaypoints(e, v) : [];
|
|
900
904
|
b.forEach((q) => q.important = !0);
|
|
901
905
|
const c = {
|
|
902
906
|
from: { ...e },
|
|
903
907
|
route: m,
|
|
904
908
|
waypoints: b,
|
|
905
|
-
v0:
|
|
906
|
-
label:
|
|
909
|
+
v0: C,
|
|
910
|
+
label: S
|
|
907
911
|
}, f = {
|
|
908
912
|
hours: [],
|
|
909
913
|
days: [],
|
|
910
914
|
wps: []
|
|
911
915
|
};
|
|
912
|
-
s || (W.calculateRouteDistance(m) /
|
|
913
|
-
let l = W.simplifyRouteToCoordinates(m, b, 0), u = 0, I = 0,
|
|
916
|
+
s || (W.calculateRouteDistance(m) / i.speed <= 72 ? s = 3 : s = 6);
|
|
917
|
+
let l = W.simplifyRouteToCoordinates(m, b, 0), u = 0, I = 0, k = 0, D = 0;
|
|
914
918
|
t = g(t).utc();
|
|
915
919
|
const Y = t.clone();
|
|
916
920
|
for (; l.length > 0; ) {
|
|
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,
|
|
918
|
-
|
|
921
|
+
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, x = await O.speedLoseInHoursStep(
|
|
922
|
+
w,
|
|
919
923
|
t,
|
|
920
924
|
Y,
|
|
921
925
|
V,
|
|
922
926
|
u,
|
|
923
927
|
l,
|
|
924
|
-
|
|
928
|
+
a,
|
|
925
929
|
d,
|
|
926
|
-
|
|
930
|
+
r,
|
|
927
931
|
h
|
|
928
932
|
);
|
|
929
|
-
(
|
|
933
|
+
(G = x.from) != null && G.speed && (f.hours.push(x.from), f.wps.push(...x.wps), f.days.push(...x.days)), l = x == null ? void 0 : x.next, l.length || f.hours.push(x == null ? void 0 : x.to), u += Math.round((((Q = x == null ? void 0 : x.to) == null ? void 0 : Q.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
930
934
|
}
|
|
931
|
-
const
|
|
932
|
-
for (let q = 0; q <
|
|
933
|
-
const V = g(
|
|
934
|
-
I += (
|
|
935
|
+
const j = f.hours;
|
|
936
|
+
for (let q = 0; q < j.length - 1; q++) {
|
|
937
|
+
const V = g(j[q + 1].eta).diff(j[q].etd, "hour", !0) || 1;
|
|
938
|
+
I += (j[q].wxFactor || 0) * V, k += (j[q].cFactor || 0) * V, D += V;
|
|
935
939
|
}
|
|
936
940
|
(X = f.wps) == null || X.forEach((q, V) => {
|
|
937
941
|
q.positionTime = g.utc(q.etd || q.eta).unix();
|
|
938
|
-
const
|
|
939
|
-
if (
|
|
940
|
-
const L = q.distanceFromStart -
|
|
942
|
+
const x = f.wps[V - 1];
|
|
943
|
+
if (x) {
|
|
944
|
+
const L = q.distanceFromStart - x.distanceFromStart, H = g(q.eta || q.etd).diff(g(x.etd || x.eta), "h", !0);
|
|
941
945
|
q.avgSpd = Math.round(L / H * 100) / 100;
|
|
942
|
-
const nt = W.calculateBearing(
|
|
943
|
-
|
|
946
|
+
const nt = W.calculateBearing(x, q);
|
|
947
|
+
x.bearing = nt;
|
|
944
948
|
}
|
|
945
|
-
}), f.wps = (Z = f.wps) == null ? void 0 : Z.reduce((q, V) => (q.some((
|
|
949
|
+
}), f.wps = (Z = f.wps) == null ? void 0 : Z.reduce((q, V) => (q.some((x) => Math.round(x.positionTime / 60) === Math.round(V.positionTime / 60)) || q.push(V), q), []), c.sample = f;
|
|
946
950
|
const P = f.hours.at(0), T = f.hours.at(-1);
|
|
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(
|
|
948
|
-
const { distanceInECA: N, hoursInECA: A, totalDgoConsInECA: R, eca:
|
|
951
|
+
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(k / D * 1e4) / 1e4, c.avgSpeed = Math.round(T.distanceFromStart / D * 1e4) / 1e4, c.totalHrs = Math.round(D * 1e4) / 1e4;
|
|
952
|
+
const { distanceInECA: N, hoursInECA: A, totalDgoConsInECA: R, eca: U } = await this.calculateECA(c, i, h), st = J.roundPrecision(i.fo / 24 * (D - A), 3), at = J.roundPrecision(i.dgo / 24 * D, 3);
|
|
949
953
|
c.extend = {
|
|
950
|
-
eca:
|
|
954
|
+
eca: U,
|
|
951
955
|
distanceInECA: N,
|
|
952
956
|
hoursInECA: A,
|
|
953
957
|
totalDgoConsInECA: R
|
|
954
958
|
}, c.totalFoCons = st, c.totalDgoCons = at;
|
|
955
959
|
const tt = g().valueOf() - M, ot = (($ = f == null ? void 0 : f.hours) == null ? void 0 : $.length) || 1;
|
|
956
|
-
return
|
|
960
|
+
return F == null || F.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, tt, ot, Math.round(tt / ot * 1e3) / 1e3), c;
|
|
957
961
|
}
|
|
958
962
|
/**
|
|
959
963
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -968,25 +972,25 @@ class O {
|
|
|
968
972
|
* @param useMeteo true 启用气象分析
|
|
969
973
|
* @param useRouteParam
|
|
970
974
|
*/
|
|
971
|
-
static async analyseInstantWithThreshed(e, t, n,
|
|
975
|
+
static async analyseInstantWithThreshed(e, t, n, i, o, a, s, d = "", r = 3, h = !0, M = !1, y = {}) {
|
|
972
976
|
var Q, X, Z, $, q, V;
|
|
973
|
-
const
|
|
977
|
+
const v = g().valueOf();
|
|
974
978
|
e.lng = J.convertToStdLng(e.lng);
|
|
975
|
-
const { v0: m, label:
|
|
979
|
+
const { v0: m, label: C } = e.sog ? {
|
|
976
980
|
v0: e.sog,
|
|
977
|
-
label: "Other"
|
|
981
|
+
label: e.label || "Other"
|
|
978
982
|
/* Instruct */
|
|
979
983
|
} : {
|
|
980
|
-
v0:
|
|
984
|
+
v0: o.speed,
|
|
981
985
|
label: "CP"
|
|
982
986
|
/* Cp */
|
|
983
|
-
},
|
|
984
|
-
if (((Q =
|
|
987
|
+
}, S = O.assembleProperties(i, o.loadCondition, m, 0), w = W.calculateSubRoute(e, a);
|
|
988
|
+
if (((Q = w[0]) == null ? void 0 : Q.length) <= 1)
|
|
985
989
|
return;
|
|
986
990
|
const b = s.length ? W.calculateSubWaypoints(e, s) : [];
|
|
987
|
-
b.forEach((
|
|
988
|
-
let c = W.simplifyRouteToCoordinates(
|
|
989
|
-
const
|
|
991
|
+
b.forEach((x) => x.important = !0);
|
|
992
|
+
let c = W.simplifyRouteToCoordinates(w, b, 0), f = 0, l = 0, u = 0, I = 0;
|
|
993
|
+
const k = {
|
|
990
994
|
hours: [],
|
|
991
995
|
wps: [],
|
|
992
996
|
days: []
|
|
@@ -994,52 +998,52 @@ class O {
|
|
|
994
998
|
t = g(t).utc();
|
|
995
999
|
const D = t.clone();
|
|
996
1000
|
for (; c.length > 0; ) {
|
|
997
|
-
const
|
|
998
|
-
let L = Math.ceil(t.clone().add(
|
|
1001
|
+
const x = r - t.hour() % r;
|
|
1002
|
+
let L = Math.ceil(t.clone().add(x, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
999
1003
|
L = t.clone().add(L, "h").isSameOrAfter(n) ? n.diff(t, "h", !0) * 1e4 / 1e4 : L;
|
|
1000
|
-
const H = await O.speedLoseInHoursStep(
|
|
1001
|
-
if ((X = H.from) != null && X.speed && (
|
|
1004
|
+
const H = await O.speedLoseInHoursStep(S, t, D, L, f, c, d, h, M, y);
|
|
1005
|
+
if ((X = H.from) != null && X.speed && (k.hours.push(H.from), H != null && H.wps && k.wps.push(...H.wps), k.days.push(...H.days)), c = H == null ? void 0 : H.next, c.length || k.hours.push(H == null ? void 0 : H.to), f += Math.round((((Z = H == null ? void 0 : H.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
|
|
1002
1006
|
break;
|
|
1003
1007
|
}
|
|
1004
|
-
|
|
1005
|
-
const H =
|
|
1008
|
+
k.wps = ($ = k.wps) == null ? void 0 : $.reduce((x, L) => (x.some((H) => Math.round(g(H.etd).unix() / 60) === Math.round(g(L.etd).unix() / 60)) || x.push(L), x), []), (q = k.wps) == null || q.forEach((x, L) => {
|
|
1009
|
+
const H = k.wps[L - 1];
|
|
1006
1010
|
if (H) {
|
|
1007
|
-
const nt =
|
|
1008
|
-
|
|
1009
|
-
const ut = W.calculateBearing(H,
|
|
1011
|
+
const nt = x.distanceFromStart - H.distanceFromStart, dt = g(x.eta || x.etd).diff(g(H.etd || H.eta), "h", !0);
|
|
1012
|
+
x.avgSpd = Math.round(nt / dt * 100) / 100;
|
|
1013
|
+
const ut = W.calculateBearing(H, x);
|
|
1010
1014
|
H.bearing = ut;
|
|
1011
1015
|
}
|
|
1012
1016
|
});
|
|
1013
|
-
const Y =
|
|
1014
|
-
for (let
|
|
1015
|
-
const L = g(Y[
|
|
1016
|
-
l += Y[
|
|
1017
|
+
const Y = k.hours;
|
|
1018
|
+
for (let x = 0; x < Y.length - 1; x++) {
|
|
1019
|
+
const L = g(Y[x + 1].eta).diff(Y[x].etd, "hour", !0);
|
|
1020
|
+
l += Y[x].wxFactor * L, u += Y[x].cFactor * L, I += L;
|
|
1017
1021
|
}
|
|
1018
|
-
const
|
|
1019
|
-
sample:
|
|
1022
|
+
const j = k.hours.at(0), P = k.hours.at(-1), T = await W.calculateRangeRoute(j, P, w), N = await W.calculateRangeWaypoints(j, P, w, b), A = {
|
|
1023
|
+
sample: k,
|
|
1020
1024
|
distance: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1021
1025
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1022
|
-
etd: g(
|
|
1026
|
+
etd: g(j.eta).utc().format(),
|
|
1023
1027
|
eta: g(P == null ? void 0 : P.eta).utc().format(),
|
|
1024
1028
|
wxFactor: Math.round(l / I * 1e4) / 1e4,
|
|
1025
1029
|
cFactor: Math.round(u / I * 1e4) / 1e4,
|
|
1026
1030
|
avgSpeed: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) / I * 1e4) / 1e4,
|
|
1027
1031
|
totalHrs: Math.round(I * 1e4) / 1e4,
|
|
1028
|
-
from:
|
|
1032
|
+
from: j,
|
|
1029
1033
|
to: P,
|
|
1030
1034
|
route: T,
|
|
1031
1035
|
waypoints: N,
|
|
1032
1036
|
v0: m,
|
|
1033
|
-
label:
|
|
1034
|
-
}, { distanceInECA: R, hoursInECA:
|
|
1037
|
+
label: C
|
|
1038
|
+
}, { distanceInECA: R, hoursInECA: U, totalDgoConsInECA: st, eca: at } = await this.calculateECA(A, o, y), ct = J.roundPrecision(o.fo / 24 * (I - U), 3), tt = J.roundPrecision(o.dgo / 24 * I, 3);
|
|
1035
1039
|
A.extend = {
|
|
1036
1040
|
eca: at,
|
|
1037
1041
|
distanceInECA: R,
|
|
1038
|
-
hoursInECA:
|
|
1042
|
+
hoursInECA: U,
|
|
1039
1043
|
totalDgoConsInECA: st
|
|
1040
|
-
}, A.totalDgoCons = tt, A.totalFoCons =
|
|
1041
|
-
const
|
|
1042
|
-
return
|
|
1044
|
+
}, A.totalDgoCons = tt, A.totalFoCons = ct;
|
|
1045
|
+
const z = g().valueOf() - v, G = ((V = k == null ? void 0 : k.hours) == null ? void 0 : V.length) || 1;
|
|
1046
|
+
return F == null || F.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", y == null ? void 0 : y.requestId, z, G, Math.round(z / G * 1e3) / 1e3), A;
|
|
1043
1047
|
}
|
|
1044
1048
|
/**
|
|
1045
1049
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1056,20 +1060,20 @@ class O {
|
|
|
1056
1060
|
* @param lane 基础航线(重要转向点)
|
|
1057
1061
|
* @param options
|
|
1058
1062
|
*/
|
|
1059
|
-
static async analyseCost(e, t, n,
|
|
1060
|
-
var
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1063
|
-
const d = W.calculateRouteDistance(
|
|
1064
|
-
let
|
|
1063
|
+
static async analyseCost(e, t, n, i, o = {}) {
|
|
1064
|
+
var w, b;
|
|
1065
|
+
const a = g().valueOf(), s = [];
|
|
1066
|
+
e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
|
|
1067
|
+
const d = W.calculateRouteDistance(i.route);
|
|
1068
|
+
let r = 0;
|
|
1065
1069
|
n.forEach((c) => {
|
|
1066
1070
|
const f = Math.ceil(d / c.speed / 24);
|
|
1067
|
-
|
|
1068
|
-
}),
|
|
1069
|
-
const h = g.utc(e.etd).add(
|
|
1071
|
+
r = r < f ? f : r;
|
|
1072
|
+
}), r = r * 1.3;
|
|
1073
|
+
const h = g.utc(e.etd).add(r ?? 14, "day");
|
|
1070
1074
|
let M = 1;
|
|
1071
1075
|
for (const c of n) {
|
|
1072
|
-
const f = JSON.parse(JSON.stringify(
|
|
1076
|
+
const f = JSON.parse(JSON.stringify(i.route)), l = JSON.parse(JSON.stringify(i.waypoints)), u = await O.analyseInstantWithThreshed(
|
|
1073
1077
|
{ lat: e.lat, lng: e.lng },
|
|
1074
1078
|
e.etd,
|
|
1075
1079
|
h,
|
|
@@ -1081,9 +1085,9 @@ class O {
|
|
|
1081
1085
|
e.speedStep,
|
|
1082
1086
|
e.useMeteo,
|
|
1083
1087
|
e.useRouteParam,
|
|
1084
|
-
|
|
1088
|
+
o
|
|
1085
1089
|
);
|
|
1086
|
-
u && (await O.calculateCost(u, c, e,
|
|
1090
|
+
u && (await O.calculateCost(u, c, e, o), s.push(u), F == null || F.info("[%s][L%d-%d] analyse from %s to %s cost: %j", o.requestId, 1, M, e.etd, h.format(), {
|
|
1087
1091
|
cost: u.cost.total,
|
|
1088
1092
|
hire: u.cost.hire,
|
|
1089
1093
|
bunker: u.cost.bunker,
|
|
@@ -1093,22 +1097,22 @@ class O {
|
|
|
1093
1097
|
})), M++;
|
|
1094
1098
|
}
|
|
1095
1099
|
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 =
|
|
1099
|
-
let
|
|
1100
|
-
|
|
1101
|
-
let D = 2, Y = { combined: !1, speeds: [
|
|
1102
|
-
for (;
|
|
1103
|
-
const P = await O.combinedAnalyse(e, t, h, [c, f],
|
|
1104
|
-
if (Y.cost > P.cost ?
|
|
1100
|
+
const y = s.at(0), v = s.at(1), m = [];
|
|
1101
|
+
if (m.push({ combined: !1, speeds: [y], cost: (w = y.cost) == null ? void 0 : w.total }), v) {
|
|
1102
|
+
const c = y.cost.cp, f = v.cost.cp, l = g(y.eta), u = g(y.etd), I = l.diff(u, "days", !0);
|
|
1103
|
+
let k = Math.ceil(I / 2);
|
|
1104
|
+
k = k > 7 ? 7 : k < e.alterStep ? e.alterStep : k;
|
|
1105
|
+
let D = 2, Y = { combined: !1, speeds: [v], cost: (b = v.cost) == null ? void 0 : b.total }, j;
|
|
1106
|
+
for (; k >= e.alterStep; ) {
|
|
1107
|
+
const P = await O.combinedAnalyse(e, t, h, [c, f], i, k, { ...o, level: D });
|
|
1108
|
+
if (Y.cost > P.cost ? j ? (j == null ? void 0 : j.cost) > P.cost && (j = P) : (j = Y, Y = P) : (!j || (j == null ? void 0 : j.cost) > P.cost) && (j = P), k <= e.alterStep)
|
|
1105
1109
|
break;
|
|
1106
|
-
|
|
1110
|
+
k = Math.ceil(k / 2), D += 1;
|
|
1107
1111
|
}
|
|
1108
|
-
m.push(Y),
|
|
1112
|
+
m.push(Y), j && m.push(j);
|
|
1109
1113
|
}
|
|
1110
|
-
const
|
|
1111
|
-
return
|
|
1114
|
+
const S = g().valueOf() - a;
|
|
1115
|
+
return F == null || F.info("[%s] analyse elapsed: %d ms", o == null ? void 0 : o.requestId, S), m.sort((c, f) => c.cost - f.cost);
|
|
1112
1116
|
}
|
|
1113
1117
|
/**
|
|
1114
1118
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1120,24 +1124,24 @@ class O {
|
|
|
1120
1124
|
* @param step 步长,7,4,2,1
|
|
1121
1125
|
* @param options
|
|
1122
1126
|
*/
|
|
1123
|
-
static async combinedAnalyse(e, t, n,
|
|
1124
|
-
s.counter = 1,
|
|
1125
|
-
const d = await O.alternateAnalyse(e, t, n,
|
|
1126
|
-
|
|
1127
|
-
cost:
|
|
1127
|
+
static async combinedAnalyse(e, t, n, i, o, a, s = {}) {
|
|
1128
|
+
s.counter = 1, F == null || F.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, a);
|
|
1129
|
+
const d = await O.alternateAnalyse(e, t, n, i, 0, o, a, s), r = 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), v = d.reduce((f, l) => f + l.totalHrs, 0);
|
|
1130
|
+
F == null || F.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
|
|
1131
|
+
cost: r,
|
|
1128
1132
|
hire: h,
|
|
1129
1133
|
bunker: M,
|
|
1130
1134
|
distance: y,
|
|
1131
|
-
hours:
|
|
1135
|
+
hours: v
|
|
1132
1136
|
});
|
|
1133
|
-
const m = await O.alternateAnalyse(e, t, n,
|
|
1134
|
-
return
|
|
1135
|
-
cost:
|
|
1136
|
-
hire:
|
|
1137
|
-
bunker:
|
|
1137
|
+
const m = await O.alternateAnalyse(e, t, n, i, 1, o, a, s), C = m.reduce((f, l) => f + l.cost.total, 0), S = m.reduce((f, l) => f + l.cost.hire, 0), w = 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);
|
|
1138
|
+
return F == null || F.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
|
|
1139
|
+
cost: C,
|
|
1140
|
+
hire: S,
|
|
1141
|
+
bunker: w,
|
|
1138
1142
|
distance: b,
|
|
1139
1143
|
hours: c
|
|
1140
|
-
}),
|
|
1144
|
+
}), r < C ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step: a } : { combined: !0, cost: Math.round(C * 1e3) / 1e3, speeds: m, step: a };
|
|
1141
1145
|
}
|
|
1142
1146
|
/**
|
|
1143
1147
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1150,31 +1154,31 @@ class O {
|
|
|
1150
1154
|
* @param step 步长,7,4,2,1
|
|
1151
1155
|
* @param options
|
|
1152
1156
|
*/
|
|
1153
|
-
static async alternateAnalyse(e, t, n,
|
|
1154
|
-
var y,
|
|
1155
|
-
let
|
|
1157
|
+
static async alternateAnalyse(e, t, n, i, o, a, s, d = {}) {
|
|
1158
|
+
var y, v;
|
|
1159
|
+
let r = g.utc(e.etd);
|
|
1156
1160
|
const h = { lat: e.lat, lng: e.lng }, M = [];
|
|
1157
|
-
for (;
|
|
1158
|
-
const m =
|
|
1161
|
+
for (; r.isBefore(n); ) {
|
|
1162
|
+
const m = r.clone().utc().add(s, "day"), C = JSON.parse(JSON.stringify(a.route)), S = JSON.parse(JSON.stringify(a.waypoints)), w = i[o], b = await O.analyseInstantWithThreshed(
|
|
1159
1163
|
h,
|
|
1160
|
-
|
|
1164
|
+
r.utc().format(),
|
|
1161
1165
|
m,
|
|
1162
1166
|
t,
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1167
|
+
w,
|
|
1168
|
+
C,
|
|
1169
|
+
S,
|
|
1166
1170
|
e.meteoVendor,
|
|
1167
1171
|
e.speedStep,
|
|
1168
1172
|
e.useMeteo,
|
|
1169
1173
|
e.useRouteParam,
|
|
1170
1174
|
d
|
|
1171
1175
|
);
|
|
1172
|
-
b && (await O.calculateCost(b,
|
|
1176
|
+
b && (await O.calculateCost(b, w, e, d), F == null || F.info(
|
|
1173
1177
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1174
1178
|
d.requestId,
|
|
1175
1179
|
d.level,
|
|
1176
1180
|
d.counter,
|
|
1177
|
-
|
|
1181
|
+
r.utc().format(),
|
|
1178
1182
|
m.utc().format(),
|
|
1179
1183
|
{
|
|
1180
1184
|
cost: b.cost.total,
|
|
@@ -1182,12 +1186,12 @@ class O {
|
|
|
1182
1186
|
bunker: b.cost.bunker,
|
|
1183
1187
|
distance: b.distance,
|
|
1184
1188
|
hours: b.totalHrs,
|
|
1185
|
-
cp: `${
|
|
1189
|
+
cp: `${w.speed}/${w.fo}/${w.dgo}`
|
|
1186
1190
|
}
|
|
1187
1191
|
)), d.counter = d.counter + 1;
|
|
1188
|
-
const c = (
|
|
1192
|
+
const c = (v = (y = b == null ? void 0 : b.sample) == null ? void 0 : y.hours) == null ? void 0 : v.at(-1);
|
|
1189
1193
|
if (c)
|
|
1190
|
-
h.lat = c.lat, h.lng = c.lng,
|
|
1194
|
+
h.lat = c.lat, h.lng = c.lng, r = g(c.eta), M.push(b), o = o ? 0 : 1;
|
|
1191
1195
|
else
|
|
1192
1196
|
break;
|
|
1193
1197
|
}
|
|
@@ -1200,13 +1204,13 @@ class O {
|
|
|
1200
1204
|
* @param props
|
|
1201
1205
|
* @param options
|
|
1202
1206
|
*/
|
|
1203
|
-
static async calculateCost(e, t, n,
|
|
1204
|
-
var
|
|
1207
|
+
static async calculateCost(e, t, n, i = {}) {
|
|
1208
|
+
var o;
|
|
1205
1209
|
if (e) {
|
|
1206
|
-
const
|
|
1210
|
+
const a = 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 + (((o = e.extend) == null ? void 0 : o.totalDgoConsInECA) || 0)) * (n.priceDGO || 0) * 1e3) / 1e3;
|
|
1207
1211
|
e.cost = {
|
|
1208
|
-
total: Math.round((
|
|
1209
|
-
hire:
|
|
1212
|
+
total: Math.round((a + s + d) * 1e3) / 1e3,
|
|
1213
|
+
hire: a,
|
|
1210
1214
|
bunker: Math.round((s + d) * 1e3) / 1e3,
|
|
1211
1215
|
cp: t
|
|
1212
1216
|
};
|
|
@@ -1217,22 +1221,22 @@ class O {
|
|
|
1217
1221
|
* 计算单cp模式下的ECA属性
|
|
1218
1222
|
*/
|
|
1219
1223
|
static async calculateECA(e, t, n = {}) {
|
|
1220
|
-
var d,
|
|
1221
|
-
const
|
|
1222
|
-
let
|
|
1224
|
+
var d, r;
|
|
1225
|
+
const i = await W.intersectInECA(e.route);
|
|
1226
|
+
let o = 0, a = 0, s = 0;
|
|
1223
1227
|
e.sample.wps.forEach((h) => {
|
|
1224
1228
|
h.positionTime = g.utc(h.etd || h.eta).unix();
|
|
1225
1229
|
});
|
|
1226
|
-
for (const h of
|
|
1227
|
-
|
|
1228
|
-
const M = await W.deadReckoningTime((d = h.waypoints) == null ? void 0 : d.at(0), e.sample.wps), y = await W.deadReckoningTime((
|
|
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),
|
|
1230
|
+
for (const h of i) {
|
|
1231
|
+
o += h.distance;
|
|
1232
|
+
const M = await W.deadReckoningTime((d = h.waypoints) == null ? void 0 : d.at(0), e.sample.wps), y = await W.deadReckoningTime((r = h.waypoints) == null ? void 0 : r.at(-1), e.sample.wps);
|
|
1233
|
+
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), a += h.totalHrs, s += h.totalDgoCons;
|
|
1230
1234
|
}
|
|
1231
|
-
return
|
|
1232
|
-
distanceInECA:
|
|
1233
|
-
hoursInECA:
|
|
1235
|
+
return o = J.roundPrecision(o, 3), a = J.roundPrecision(a, 3), s = J.roundPrecision(s, 3), {
|
|
1236
|
+
distanceInECA: o,
|
|
1237
|
+
hoursInECA: a,
|
|
1234
1238
|
totalDgoConsInECA: s,
|
|
1235
|
-
eca:
|
|
1239
|
+
eca: i
|
|
1236
1240
|
};
|
|
1237
1241
|
}
|
|
1238
1242
|
/**
|
|
@@ -1246,35 +1250,35 @@ class O {
|
|
|
1246
1250
|
hours: [],
|
|
1247
1251
|
wps: [],
|
|
1248
1252
|
days: []
|
|
1249
|
-
},
|
|
1253
|
+
}, i = e.reduce((l, u) => l + u.distance, 0), o = e.reduce((l, u) => {
|
|
1250
1254
|
var I;
|
|
1251
1255
|
return l + (((I = u.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1252
|
-
}, 0),
|
|
1256
|
+
}, 0), a = e.reduce((l, u) => l + u.totalHrs, 0), s = e.reduce((l, u) => {
|
|
1253
1257
|
var I;
|
|
1254
1258
|
return l + (((I = u.extend) == null ? void 0 : I.hoursInECA) || 0);
|
|
1255
1259
|
}, 0), d = e.reduce((l, u) => {
|
|
1256
1260
|
var I;
|
|
1257
1261
|
return l + (((I = u.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1258
|
-
}, 0),
|
|
1262
|
+
}, 0), r = e.reduce((l, u) => l + u.wxFactor * u.totalHrs / a, 0), h = e.reduce((l, u) => l + u.cFactor * u.totalHrs / a, 0), M = e.reduce((l, u) => l + u.totalFoCons, 0), y = e.reduce((l, u) => l + u.totalDgoCons, 0), v = e.reduce((l, u) => l + u.cost.total, 0), m = e.reduce((l, u) => l + u.cost.hire, 0), C = e.reduce((l, u) => l + u.cost.bunker, 0), S = [], w = [];
|
|
1259
1263
|
let b;
|
|
1260
1264
|
for (const l of e) {
|
|
1261
|
-
|
|
1262
|
-
const u = l.sample.hours, I = l.sample.wps,
|
|
1265
|
+
w.push(...((c = l.extend) == null ? void 0 : c.eca) || []);
|
|
1266
|
+
const u = l.sample.hours, I = l.sample.wps, k = l.sample.days, D = u.at(0);
|
|
1263
1267
|
b && (D.distanceFromPrevious = b.distanceFromPrevious, D.distanceFromStart = b.distanceFromStart, u.forEach((T, N) => {
|
|
1264
1268
|
N && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1265
1269
|
}), I.at(0).distanceFromPrevious = b.distanceFromPrevious, I.at(0).distanceFromStart = b.distanceFromStart, I.forEach((T, N) => {
|
|
1266
1270
|
N && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1267
|
-
}),
|
|
1271
|
+
}), k.at(0).distanceFromPrevious = b.distanceFromPrevious, k.at(0).distanceFromStart = b.distanceFromStart, k.forEach((T, N) => {
|
|
1268
1272
|
N && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1269
1273
|
})), D.cp = l.cost.cp;
|
|
1270
|
-
const Y = [l.etd, l.eta],
|
|
1271
|
-
|
|
1274
|
+
const Y = [l.etd, l.eta], j = S.findIndex((T) => T.id === D.cp.id);
|
|
1275
|
+
j === -1 ? (D.cp.segment = [Y], S.push(D.cp)) : S[j].segment.push(Y), u.forEach((T) => {
|
|
1272
1276
|
var A;
|
|
1273
1277
|
((A = n.hours) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.hours.push(T);
|
|
1274
1278
|
}), I.forEach((T) => {
|
|
1275
1279
|
var A;
|
|
1276
1280
|
((A = n.wps) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.wps.push(T);
|
|
1277
|
-
}),
|
|
1281
|
+
}), k.forEach((T) => {
|
|
1278
1282
|
var A;
|
|
1279
1283
|
((A = n == null ? void 0 : n.days) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.days.push(T);
|
|
1280
1284
|
});
|
|
@@ -1286,10 +1290,10 @@ class O {
|
|
|
1286
1290
|
}), n.wps.forEach((l, u) => {
|
|
1287
1291
|
const I = n.wps[u - 1];
|
|
1288
1292
|
if (I) {
|
|
1289
|
-
const
|
|
1293
|
+
const k = l.distanceFromStart - (I.distanceFromStart || 0), D = g(l.eta || l.etd).diff(g(I.etd || I.eta), "hour", !0), Y = Math.round(k / D * 100) / 100;
|
|
1290
1294
|
l.avgSpd = Y;
|
|
1291
|
-
const
|
|
1292
|
-
I.bearing =
|
|
1295
|
+
const j = W.calculateBearing(I, l);
|
|
1296
|
+
I.bearing = j;
|
|
1293
1297
|
}
|
|
1294
1298
|
}), {
|
|
1295
1299
|
sample: n,
|
|
@@ -1299,22 +1303,22 @@ class O {
|
|
|
1299
1303
|
to: e.at(-1).to,
|
|
1300
1304
|
v0: e.at(0).v0,
|
|
1301
1305
|
label: "Combined",
|
|
1302
|
-
distance: Math.round(
|
|
1303
|
-
totalHrs: Math.round(
|
|
1304
|
-
avgSpeed: Math.round(
|
|
1305
|
-
wxFactor: Math.round(
|
|
1306
|
+
distance: Math.round(i * 1e4) / 1e4,
|
|
1307
|
+
totalHrs: Math.round(a * 1e3) / 1e3,
|
|
1308
|
+
avgSpeed: Math.round(i / a * 1e3) / 1e3,
|
|
1309
|
+
wxFactor: Math.round(r * 1e3) / 1e3,
|
|
1306
1310
|
cFactor: Math.round(h * 1e3) / 1e3,
|
|
1307
1311
|
totalFoCons: Math.round(M * 1e3) / 1e3,
|
|
1308
1312
|
totalDgoCons: Math.round(y * 1e3) / 1e3,
|
|
1309
1313
|
cost: {
|
|
1310
|
-
total: Math.round(
|
|
1314
|
+
total: Math.round(v * 1e3) / 1e3,
|
|
1311
1315
|
hire: Math.round(m * 1e3) / 1e3,
|
|
1312
|
-
bunker: Math.round(
|
|
1316
|
+
bunker: Math.round(C * 1e3) / 1e3
|
|
1313
1317
|
},
|
|
1314
1318
|
extend: {
|
|
1315
|
-
cps:
|
|
1316
|
-
eca:
|
|
1317
|
-
distanceInECA: Math.round(
|
|
1319
|
+
cps: S,
|
|
1320
|
+
eca: w,
|
|
1321
|
+
distanceInECA: Math.round(o * 1e4) / 1e4,
|
|
1318
1322
|
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1319
1323
|
totalDgoConsInECA: Math.round(d * 1e3) / 1e3,
|
|
1320
1324
|
speeds: e
|
|
@@ -1324,15 +1328,15 @@ class O {
|
|
|
1324
1328
|
}
|
|
1325
1329
|
export {
|
|
1326
1330
|
et as AISImpl,
|
|
1327
|
-
|
|
1328
|
-
|
|
1331
|
+
yt as AlertHelper,
|
|
1332
|
+
mt as AlertLevel,
|
|
1329
1333
|
Et as HifleetImpl,
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
+
bt as LoadCondition,
|
|
1335
|
+
Nt as MyShipImpl,
|
|
1336
|
+
xt as MyVesselImpl,
|
|
1337
|
+
jt as ShipxyImpl,
|
|
1334
1338
|
O as SpeedHelper,
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1339
|
+
pt as SpeedLabel,
|
|
1340
|
+
gt as VesselTag,
|
|
1341
|
+
Tt as alertHelper
|
|
1338
1342
|
};
|