@idm-plugin/vessel 1.8.6 → 1.8.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/ais/src/index.d.ts +7 -0
- package/dist/index.js +359 -333
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var ht = Object.defineProperty;
|
|
2
|
-
var lt = (
|
|
3
|
-
var
|
|
2
|
+
var lt = (j, e, t) => e in j ? ht(j, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : j[e] = t;
|
|
3
|
+
var z = (j, e, t) => (lt(j, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
4
|
import B from "got";
|
|
5
5
|
import it from "@log4js-node/log4js-api";
|
|
6
|
-
import
|
|
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";
|
|
@@ -54,12 +54,12 @@ class et {
|
|
|
54
54
|
return { labelCn: t, labelEn: n };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class jt extends et {
|
|
58
58
|
constructor(t, n) {
|
|
59
59
|
super();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
z(this, "clientId");
|
|
61
|
+
z(this, "clientSecret");
|
|
62
|
+
z(this, "token");
|
|
63
63
|
this.clientId = t, this.clientSecret = n;
|
|
64
64
|
}
|
|
65
65
|
async authToken(t = {}) {
|
|
@@ -76,15 +76,15 @@ class Ct extends et {
|
|
|
76
76
|
expiresIn: a.expires_in,
|
|
77
77
|
scope: a.scope,
|
|
78
78
|
jti: a.jti,
|
|
79
|
-
issuedAt:
|
|
79
|
+
issuedAt: g().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async realTimePosition(t, n = {}) {
|
|
83
|
-
var
|
|
84
|
-
(!this.token ||
|
|
83
|
+
var d, r, h;
|
|
84
|
+
(!this.token || g().diff(g(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(n);
|
|
85
85
|
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", a = {
|
|
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
|
};
|
|
@@ -93,46 +93,56 @@ class Ct extends et {
|
|
|
93
93
|
if (o.code)
|
|
94
94
|
return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, i, { message: o.message, status: o.status, code: o.code }), o;
|
|
95
95
|
const s = o.data;
|
|
96
|
-
for (const
|
|
97
|
-
!isNaN(s[
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
96
|
+
for (const M in s)
|
|
97
|
+
!isNaN(s[M]) && Number(s[M]) !== 1 / 0 && (s[M] = Number(s[M]));
|
|
98
|
+
if (s) {
|
|
99
|
+
const M = g(`${s.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
100
|
+
return {
|
|
101
|
+
mmsi: s.mmsi,
|
|
102
|
+
name: s.vesselName || s.aisVesselName,
|
|
103
|
+
imo: s.imo,
|
|
104
|
+
callSign: s.callsign || s.aisCallSign,
|
|
105
|
+
lat: s.lat,
|
|
106
|
+
lng: s.lon,
|
|
107
|
+
length: s.length,
|
|
108
|
+
width: s.width,
|
|
109
|
+
draught: s.currDraught,
|
|
110
|
+
sog: s.sog,
|
|
111
|
+
cog: s.cog,
|
|
112
|
+
hdg: s.hdg,
|
|
113
|
+
rot: s.rot,
|
|
114
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? g.utc(s.eta).format() : void 0,
|
|
115
|
+
destination: s.dest,
|
|
116
|
+
positionTime: M.unix(),
|
|
117
|
+
status: s.status,
|
|
118
|
+
labelCn: s.statusNameCn,
|
|
119
|
+
labelEn: s.statusNameEn,
|
|
120
|
+
vesselType: s.vesselTypeNameEn,
|
|
121
|
+
flag: s.flagCtryNameEn,
|
|
122
|
+
clasz: s.classSociety,
|
|
123
|
+
build: s.buildYear,
|
|
124
|
+
dwt: s.dwt,
|
|
125
|
+
grt: s.grt,
|
|
126
|
+
net: s.net,
|
|
127
|
+
method: "position",
|
|
128
|
+
vendor: "myVessel",
|
|
129
|
+
utc: M.utc().format()
|
|
130
|
+
};
|
|
131
|
+
} else
|
|
132
|
+
return {};
|
|
123
133
|
}
|
|
124
134
|
async trajectory(t, n, i, a, o = !0, s = {}) {
|
|
125
|
-
(!this.token ||
|
|
126
|
-
const d = await this.realTimePosition(t, s), r =
|
|
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), r = g(n), h = g(i), M = [];
|
|
127
137
|
for (; h.diff(r, "day", !0) > 30; )
|
|
128
138
|
await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), d, a, M, s), r.add(30, "day");
|
|
129
139
|
return await this.trajectoryIn30Day(t, r, h, d, a, M, s), M;
|
|
130
140
|
}
|
|
131
141
|
async trajectoryIn30Day(t, n, i, a, o, s, d = {}) {
|
|
132
|
-
var
|
|
142
|
+
var m, F, x, w, b;
|
|
133
143
|
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
|
|
134
144
|
headers: {
|
|
135
|
-
Authorization: `${(
|
|
145
|
+
Authorization: `${(m = this.token) == null ? void 0 : m.tokenType} ${(F = this.token) == null ? void 0 : F.accessToken}`
|
|
136
146
|
},
|
|
137
147
|
json: {
|
|
138
148
|
mmsi: t,
|
|
@@ -144,12 +154,12 @@ class Ct extends et {
|
|
|
144
154
|
const M = await B.post(r, h).json();
|
|
145
155
|
if (M.code)
|
|
146
156
|
return p == null || p.warn("[%s] fetch trajectory failed: %j", d.requestId, r, { message: M.message, status: M.status, code: M.code }), M;
|
|
147
|
-
let
|
|
148
|
-
const
|
|
149
|
-
return (
|
|
157
|
+
let y = -1;
|
|
158
|
+
const v = g(`${(w = (x = M.data) == null ? void 0 : x[0]) == null ? void 0 : w.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
159
|
+
return (b = M.data) == null || b.forEach((c) => {
|
|
150
160
|
for (const Y in c)
|
|
151
161
|
!isNaN(c[Y]) && Number(c[Y]) !== 1 / 0 && (c[Y] = Number(c[Y]));
|
|
152
|
-
const
|
|
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), S = {
|
|
153
163
|
mmsi: c.mmsi,
|
|
154
164
|
imo: a == null ? void 0 : a.imo,
|
|
155
165
|
lat: c.lat,
|
|
@@ -158,24 +168,24 @@ class Ct extends et {
|
|
|
158
168
|
cog: c.cog,
|
|
159
169
|
hdg: c.hdg,
|
|
160
170
|
draught: c.draught,
|
|
161
|
-
status:
|
|
162
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta) ?
|
|
171
|
+
status: l,
|
|
172
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta) ? g(`${c.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
|
|
163
173
|
destination: c.dest,
|
|
164
|
-
positionTime:
|
|
174
|
+
positionTime: f.unix(),
|
|
165
175
|
labelCn: u,
|
|
166
|
-
labelEn:
|
|
176
|
+
labelEn: I,
|
|
167
177
|
method: "trajectory",
|
|
168
178
|
vendor: "myVessel",
|
|
169
|
-
utc:
|
|
170
|
-
}, D = Math.floor(
|
|
171
|
-
D !==
|
|
179
|
+
utc: f.utc().format()
|
|
180
|
+
}, D = Math.floor(f.diff(v, "minute", !0) / (o || 1));
|
|
181
|
+
D !== y && (y = D, s.push(S));
|
|
172
182
|
}), s;
|
|
173
183
|
}
|
|
174
184
|
}
|
|
175
185
|
class Et extends et {
|
|
176
186
|
constructor(t) {
|
|
177
187
|
super();
|
|
178
|
-
|
|
188
|
+
z(this, "token");
|
|
179
189
|
this.token = t;
|
|
180
190
|
}
|
|
181
191
|
async realTimePosition(t, n = {}) {
|
|
@@ -189,10 +199,10 @@ class Et extends et {
|
|
|
189
199
|
const s = o == null ? void 0 : o.list;
|
|
190
200
|
if (!s)
|
|
191
201
|
return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, i, o), o;
|
|
192
|
-
for (const
|
|
193
|
-
!isNaN(s[
|
|
202
|
+
for (const v in s)
|
|
203
|
+
!isNaN(s[v]) && Number(s[v]) !== 1 / 0 && (s[v] = Number(s[v]));
|
|
194
204
|
s.status = s.sp > 3 ? 0 : 1;
|
|
195
|
-
const d = s.status, { labelCn: r, labelEn: h } = this.parseStatus(d), M =
|
|
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");
|
|
196
206
|
return {
|
|
197
207
|
mmsi: s.m,
|
|
198
208
|
name: s.n,
|
|
@@ -207,8 +217,12 @@ class Et extends et {
|
|
|
207
217
|
cog: s.co,
|
|
208
218
|
hdg: s.h,
|
|
209
219
|
rot: isNaN(s.rot) ? 0 : s.rot,
|
|
210
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ?
|
|
220
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? g.utc(s.eta).format() : void 0,
|
|
211
221
|
destination: s.destination,
|
|
222
|
+
vesselType: s.type,
|
|
223
|
+
dwt: s.dwt,
|
|
224
|
+
build: s.buildyear,
|
|
225
|
+
flag: s.fn,
|
|
212
226
|
positionTime: M.unix(),
|
|
213
227
|
utc: M.utc().format(),
|
|
214
228
|
status: d,
|
|
@@ -270,32 +284,32 @@ class Et extends et {
|
|
|
270
284
|
return s.sort((d, r) => r.score - d.score), s;
|
|
271
285
|
}
|
|
272
286
|
async trajectory(t, n, i, a, o = !0, s = {}) {
|
|
273
|
-
var c,
|
|
287
|
+
var c, f, l;
|
|
274
288
|
const d = await this.realTimePosition(t, s);
|
|
275
|
-
let r =
|
|
276
|
-
const h =
|
|
289
|
+
let r = g(n);
|
|
290
|
+
const h = g(i), M = g();
|
|
277
291
|
if (o) {
|
|
278
292
|
let u = h.diff(r, "d", !0);
|
|
279
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");
|
|
280
294
|
}
|
|
281
|
-
const
|
|
295
|
+
const y = {
|
|
282
296
|
searchParams: {
|
|
283
297
|
endtime: h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
284
298
|
starttime: r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
285
299
|
mmsi: t,
|
|
286
300
|
usertoken: this.token
|
|
287
301
|
}
|
|
288
|
-
},
|
|
289
|
-
p == null || p.info("[%s] fetch trajectory from: %s - %j", s.requestId,
|
|
290
|
-
let
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
let
|
|
294
|
-
const
|
|
295
|
-
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 F;
|
|
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
|
+
const x = [];
|
|
307
|
+
let w = -1;
|
|
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
|
+
for (const u of F) {
|
|
296
310
|
for (const P in u)
|
|
297
311
|
!isNaN(u[P]) && Number(u[P]) !== 1 / 0 && (u[P] = Number(u[P]));
|
|
298
|
-
const
|
|
312
|
+
const I = g(`${u.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
299
313
|
u.status = u.sp > 4 ? 0 : 1;
|
|
300
314
|
const { labelEn: S, labelCn: D } = this.parseStatus(u.status), Y = {
|
|
301
315
|
mmsi: u.m,
|
|
@@ -307,23 +321,23 @@ class Et extends et {
|
|
|
307
321
|
sog: u.sp,
|
|
308
322
|
cog: u.co,
|
|
309
323
|
hdg: u.hdg,
|
|
310
|
-
positionTime:
|
|
311
|
-
utc:
|
|
324
|
+
positionTime: I.unix(),
|
|
325
|
+
utc: I.utc().format(),
|
|
312
326
|
status: u.status,
|
|
313
327
|
labelCn: D,
|
|
314
328
|
labelEn: S,
|
|
315
329
|
method: "trajectory",
|
|
316
330
|
vendor: "hifleet"
|
|
317
|
-
}, E = Math.floor(
|
|
318
|
-
E !==
|
|
331
|
+
}, E = Math.floor(I.diff(b, "minute", !0) / (a || 1));
|
|
332
|
+
E !== w && (w = E, x.push(Y));
|
|
319
333
|
}
|
|
320
|
-
return
|
|
334
|
+
return x;
|
|
321
335
|
}
|
|
322
336
|
}
|
|
323
337
|
class Nt extends et {
|
|
324
338
|
constructor(t) {
|
|
325
339
|
super();
|
|
326
|
-
|
|
340
|
+
z(this, "token");
|
|
327
341
|
this.token = t;
|
|
328
342
|
}
|
|
329
343
|
async realTimePosition(t, n = {}) {
|
|
@@ -337,9 +351,9 @@ class Nt extends et {
|
|
|
337
351
|
if (p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, a, i), (o == null ? void 0 : o.status) !== 0)
|
|
338
352
|
return o;
|
|
339
353
|
const s = o.data[0];
|
|
340
|
-
for (const
|
|
341
|
-
!isNaN(s[
|
|
342
|
-
const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), h =
|
|
354
|
+
for (const y in s)
|
|
355
|
+
!isNaN(s[y]) && Number(s[y]) !== 1 / 0 && (s[y] = Number(s[y]));
|
|
356
|
+
const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), h = g.unix(s.lasttime);
|
|
343
357
|
return {
|
|
344
358
|
mmsi: s.ShipID,
|
|
345
359
|
name: s.name,
|
|
@@ -364,8 +378,8 @@ class Nt extends et {
|
|
|
364
378
|
};
|
|
365
379
|
}
|
|
366
380
|
async trajectory(t, n, i, a, o = !0, s = {}) {
|
|
367
|
-
var
|
|
368
|
-
const d = await this.realTimePosition(t, s), r =
|
|
381
|
+
var b;
|
|
382
|
+
const d = await this.realTimePosition(t, s), r = g(n), h = g(i), M = "https://api.shipxy.com/apicall/GetShipTrack", y = {
|
|
369
383
|
searchParams: {
|
|
370
384
|
id: t,
|
|
371
385
|
k: this.token,
|
|
@@ -374,33 +388,33 @@ class Nt extends et {
|
|
|
374
388
|
btm: r.unix(),
|
|
375
389
|
etm: h.unix()
|
|
376
390
|
}
|
|
377
|
-
},
|
|
378
|
-
if (p == null || p.info("[%s] fetch trajectory from: %s - %j", s.requestId, M,
|
|
379
|
-
return
|
|
380
|
-
const
|
|
381
|
-
let
|
|
382
|
-
for (const c of
|
|
383
|
-
const
|
|
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, F = [], x = g.unix((b = m[0]) == null ? void 0 : b.utc);
|
|
395
|
+
let w = -1;
|
|
396
|
+
for (const c of m) {
|
|
397
|
+
const f = g.unix(c.utc), l = {
|
|
384
398
|
imo: d == null ? void 0 : d.imo,
|
|
385
399
|
mmsi: t,
|
|
386
400
|
sog: Math.round(c.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
387
401
|
cog: Math.round(c.cog / 100 * 100) / 100,
|
|
388
402
|
lat: Math.round(c.lat / 1e6 * 1e5) / 1e5,
|
|
389
403
|
lng: Math.round(c.lon / 1e6 * 1e5) / 1e5,
|
|
390
|
-
positionTime:
|
|
391
|
-
utc:
|
|
404
|
+
positionTime: f.unix(),
|
|
405
|
+
utc: f.utc().format(),
|
|
392
406
|
method: "trajectory",
|
|
393
407
|
vendor: "shipxy"
|
|
394
|
-
}, u = Math.floor(
|
|
395
|
-
u !==
|
|
408
|
+
}, u = Math.floor(f.diff(x, "minute", !0) / (a || 1));
|
|
409
|
+
u !== w && (w = u, F.push(l));
|
|
396
410
|
}
|
|
397
|
-
return
|
|
411
|
+
return F;
|
|
398
412
|
}
|
|
399
413
|
}
|
|
400
414
|
class Tt extends et {
|
|
401
415
|
constructor(t) {
|
|
402
416
|
super();
|
|
403
|
-
|
|
417
|
+
z(this, "token");
|
|
404
418
|
this.token = t;
|
|
405
419
|
}
|
|
406
420
|
async getShipId(t, n = {}) {
|
|
@@ -448,9 +462,9 @@ class Tt extends et {
|
|
|
448
462
|
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s, o).json();
|
|
449
463
|
p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, s, o);
|
|
450
464
|
const r = d.data[0];
|
|
451
|
-
for (const
|
|
452
|
-
!isNaN(r[
|
|
453
|
-
const { labelCn: h, labelEn: M } = await this.parseStatus(r.aisNavStatus),
|
|
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);
|
|
454
468
|
return {
|
|
455
469
|
...a,
|
|
456
470
|
mmsi: t,
|
|
@@ -461,7 +475,7 @@ class Tt extends et {
|
|
|
461
475
|
hdg: Math.round(r.heading * 100) / 100,
|
|
462
476
|
rot: Math.round(r.rot * 100) / 100,
|
|
463
477
|
positionTime: r.posTime,
|
|
464
|
-
utc:
|
|
478
|
+
utc: y.utc().format(),
|
|
465
479
|
status: r.aisNavStatus,
|
|
466
480
|
labelEn: M,
|
|
467
481
|
labelCn: h,
|
|
@@ -470,13 +484,13 @@ class Tt extends et {
|
|
|
470
484
|
};
|
|
471
485
|
}
|
|
472
486
|
async trajectory(t, n, i, a, o = !0, s = {}) {
|
|
473
|
-
const d =
|
|
487
|
+
const d = g(n), r = g(i), h = await this.getShipId(t), M = await this.getShipInfo(h), y = [];
|
|
474
488
|
for (; r.diff(d, "day", !0) > 30; )
|
|
475
|
-
await this.trajectoryIn30Day(h, d.unix(), d.add(30, "day").unix(), M, t, a,
|
|
476
|
-
return await this.trajectoryIn30Day(h, d.unix(), r.unix(), M, t, a,
|
|
489
|
+
await this.trajectoryIn30Day(h, d.unix(), d.add(30, "day").unix(), M, t, a, y);
|
|
490
|
+
return await this.trajectoryIn30Day(h, d.unix(), r.unix(), M, t, a, y), y;
|
|
477
491
|
}
|
|
478
492
|
async trajectoryIn30Day(t, n, i, a, o, s, d, r = {}) {
|
|
479
|
-
var
|
|
493
|
+
var x;
|
|
480
494
|
const h = {
|
|
481
495
|
headers: {
|
|
482
496
|
appKey: this.token
|
|
@@ -486,30 +500,30 @@ class Tt extends et {
|
|
|
486
500
|
startTime: n,
|
|
487
501
|
endTime: i
|
|
488
502
|
}
|
|
489
|
-
}, M = "https://api3.myships.com/sp/ships/position/history",
|
|
490
|
-
if (p == null || p.info("[%s] fetch trajectory from: %s - %j", r.requestId, M, h),
|
|
491
|
-
return p == null || p.warn("[%s] invoke myship trajectory failed: %j", r.requestId,
|
|
492
|
-
const
|
|
493
|
-
for (const
|
|
494
|
-
!isNaN(
|
|
495
|
-
const
|
|
496
|
-
let
|
|
497
|
-
for (const
|
|
498
|
-
const
|
|
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", 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((x = v[0]) == null ? void 0 : x.posTime);
|
|
510
|
+
let F = -1;
|
|
511
|
+
for (const w of v) {
|
|
512
|
+
const b = g.unix(w.posTime), c = {
|
|
499
513
|
imo: a == null ? void 0 : a.imo,
|
|
500
514
|
mmsi: o,
|
|
501
|
-
lat: Math.round(
|
|
502
|
-
lng: Math.round(
|
|
503
|
-
sog: Math.round(
|
|
504
|
-
cog: Math.round(
|
|
505
|
-
hdg: Math.round(
|
|
506
|
-
rot: Math.round(
|
|
507
|
-
positionTime:
|
|
508
|
-
utc:
|
|
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
|
+
positionTime: b.unix(),
|
|
522
|
+
utc: b.utc().format(),
|
|
509
523
|
method: "trajectory",
|
|
510
524
|
vendor: "myship"
|
|
511
|
-
},
|
|
512
|
-
|
|
525
|
+
}, f = Math.floor(b.diff(m, "minute", !0) / (s || 1));
|
|
526
|
+
f !== F && (F = f, d.push(c));
|
|
513
527
|
}
|
|
514
528
|
return d;
|
|
515
529
|
}
|
|
@@ -520,7 +534,7 @@ try {
|
|
|
520
534
|
} catch {
|
|
521
535
|
} finally {
|
|
522
536
|
}
|
|
523
|
-
var yt = /* @__PURE__ */ ((
|
|
537
|
+
var yt = /* @__PURE__ */ ((j) => (j.NOTICE = "NOTICE", j.WARN = "WARN", j.HEAVY = "HEAVY", j.SEVERE = "SEVERE", j.ERROR = "ERROR", j.FATAL = "FATAL", j))(yt || {});
|
|
524
538
|
class Mt {
|
|
525
539
|
/**
|
|
526
540
|
* 解析告警规则, 多规则场景
|
|
@@ -542,9 +556,9 @@ class Mt {
|
|
|
542
556
|
if (h === 0 && !M)
|
|
543
557
|
o.scope = a[0];
|
|
544
558
|
else if (M)
|
|
545
|
-
for (let
|
|
546
|
-
const
|
|
547
|
-
|
|
559
|
+
for (let y = 0, v = M.length; y < v; y++) {
|
|
560
|
+
const m = this.parseRule(M[y]);
|
|
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);
|
|
548
562
|
}
|
|
549
563
|
}
|
|
550
564
|
return o;
|
|
@@ -575,25 +589,25 @@ class Mt {
|
|
|
575
589
|
* @param options
|
|
576
590
|
*/
|
|
577
591
|
checkWeather(e, t, n = {}) {
|
|
578
|
-
var
|
|
592
|
+
var m, F, x, w, b, c, f, l, u, I, S, D, Y, E, P;
|
|
579
593
|
let i = 0, a = 0, o = 0, s = 0;
|
|
580
|
-
const d = Math.round(((
|
|
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, r = (w = (x = t == null ? void 0 : t.SEVERE) == null ? void 0 : x.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 = (S = t == null ? void 0 : t.HEAVY) == null ? void 0 : S.wind) == null ? void 0 : D.number;
|
|
581
595
|
for (let T = 0; T < (e == null ? void 0 : e.length); T++) {
|
|
582
|
-
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 ?
|
|
583
|
-
s = K > s ? K : 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:
|
|
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: 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 ? K : 0, a += N.isSevere ? K : 0, o += N.isHeavy ? K : 0;
|
|
584
598
|
}
|
|
585
|
-
return i = Math.round(i * 100) / 100, a = Math.round(a * 100) / 100, o = Math.round(o * 100) / 100, s = Math.round(s), { sample: e, dangerous: i, severe: a, heavy: o, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd:
|
|
599
|
+
return i = Math.round(i * 100) / 100, a = Math.round(a * 100) / 100, o = Math.round(o * 100) / 100, s = Math.round(s), { sample: e, dangerous: i, severe: a, heavy: o, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd: y, hvThd4Wd: v }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h } };
|
|
586
600
|
}
|
|
587
601
|
}
|
|
588
602
|
const Dt = new Mt();
|
|
589
|
-
let
|
|
603
|
+
let k;
|
|
590
604
|
try {
|
|
591
|
-
|
|
605
|
+
k = it.getLogger("vessel");
|
|
592
606
|
} catch {
|
|
593
607
|
} finally {
|
|
594
608
|
}
|
|
595
609
|
const gt = new ft("", !0);
|
|
596
|
-
var bt = /* @__PURE__ */ ((
|
|
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 || {}), vt = /* @__PURE__ */ ((j) => (j.Cp = "CP", j.Perf = "Basis", j.Instruct = "Other", j))(vt || {});
|
|
597
611
|
class O {
|
|
598
612
|
/**
|
|
599
613
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
@@ -706,8 +720,8 @@ class O {
|
|
|
706
720
|
* @private
|
|
707
721
|
*/
|
|
708
722
|
static assembleProperties(e, t, n, i) {
|
|
709
|
-
var
|
|
710
|
-
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, r = ((
|
|
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, r = ((y = e == null ? void 0 : e.type) == null ? void 0 : y.toLowerCase()) || "common";
|
|
711
725
|
return {
|
|
712
726
|
tag: r.indexOf("container") > -1 ? "container" : r.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
713
727
|
lbp: a,
|
|
@@ -738,19 +752,19 @@ class O {
|
|
|
738
752
|
let h;
|
|
739
753
|
if (d.meteo2)
|
|
740
754
|
try {
|
|
741
|
-
const
|
|
742
|
-
h = ct.toLegacy(
|
|
743
|
-
} catch (
|
|
744
|
-
|
|
755
|
+
const m = await gt.spotForecast(t.lat, t.lng, n.utc().format(), !1, !1, !0, d), [F] = ct.pickHourly(m, n);
|
|
756
|
+
h = ct.toLegacy(F);
|
|
757
|
+
} catch (m) {
|
|
758
|
+
k.warn("[%s] meteo2 spot(%j) forecast failed: %s", d.requestId, { ...t, eta: n.utc().format() }, m);
|
|
745
759
|
}
|
|
746
760
|
else
|
|
747
761
|
h = await mt.queryPointFactor(t.lng, t.lat, n.valueOf(), "wind,wave,current,watertemp", i, d);
|
|
748
|
-
const M = O.weatherFactor(e, h),
|
|
762
|
+
const M = O.weatherFactor(e, h), y = O.currentFactor(e.bearing, h == null ? void 0 : h.current, a), v = Math.round((e.speed * 1.943844 + M + y) * 100) / 100;
|
|
749
763
|
r = {
|
|
750
764
|
meteo: { ...h },
|
|
751
765
|
wxFactor: M,
|
|
752
|
-
cFactor:
|
|
753
|
-
speed: t.velocity && s ? t.velocity :
|
|
766
|
+
cFactor: y,
|
|
767
|
+
speed: t.velocity && s ? t.velocity : v < 0 ? 1 : v,
|
|
754
768
|
eta: n.utc().format(),
|
|
755
769
|
etd: n.utc().format()
|
|
756
770
|
};
|
|
@@ -779,51 +793,51 @@ class O {
|
|
|
779
793
|
*/
|
|
780
794
|
static async speedLoseInHoursStep(e, t, n, i, a, o, s = "", d = !0, r = !1, h = {}) {
|
|
781
795
|
t.utc();
|
|
782
|
-
const M = t.clone().add(14, "days"),
|
|
783
|
-
let
|
|
784
|
-
for (let
|
|
785
|
-
let c = o[
|
|
786
|
-
c.distanceFromStart = Math.round((a +
|
|
787
|
-
const
|
|
788
|
-
if (e.bearing = W.calculateBearing(c,
|
|
796
|
+
const M = t.clone().add(14, "days"), y = [], v = [];
|
|
797
|
+
let m = 0, F = 0, x, w;
|
|
798
|
+
for (let b = 0; b < o.length - 1; b++) {
|
|
799
|
+
let c = o[b];
|
|
800
|
+
c.distanceFromStart = Math.round((a + F) * 1e4) / 1e4;
|
|
801
|
+
const f = o[b + 1];
|
|
802
|
+
if (e.bearing = W.calculateBearing(c, f, !f.gcToPrevious), c.bearing = e.bearing, c.suspend && r) {
|
|
789
803
|
c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
|
|
790
|
-
const
|
|
791
|
-
if (i -
|
|
792
|
-
i = i -
|
|
804
|
+
const I = c.suspend - c.elapsed;
|
|
805
|
+
if (i - m > I)
|
|
806
|
+
i = i - m - I, t.add(I, "hour"), c.elapsed = c.suspend;
|
|
793
807
|
else {
|
|
794
|
-
const S = i -
|
|
808
|
+
const S = i - m;
|
|
795
809
|
c.elapsed += S, t.add(S, "hour"), i = 0;
|
|
796
810
|
}
|
|
797
|
-
if (
|
|
798
|
-
return c.distanceFromPrevious =
|
|
811
|
+
if (k == null || k.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`, h.requestId, c), i === 0)
|
|
812
|
+
return c.distanceFromPrevious = F, { etd: t, from: w || c, to: c, next: o.filter((S) => S), wps: y, days: v };
|
|
799
813
|
} else
|
|
800
814
|
c.suspend = 0;
|
|
801
|
-
d = t.isAfter(M) ? !1 : d, c = await O.speedLoseAt(e, c, t, s, 0, d, r, h),
|
|
802
|
-
const
|
|
803
|
-
let u = Math.round(
|
|
804
|
-
if (
|
|
805
|
-
if (
|
|
806
|
-
`[%s] go to %j from %j with ${
|
|
815
|
+
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
|
+
const l = W.calculateDistance(c, f, !f.gcToPrevious);
|
|
817
|
+
let u = Math.round(l / w.speed * 1e5) / 1e5;
|
|
818
|
+
if (m + u < i) {
|
|
819
|
+
if (m += u, t.add(u, "hour"), delete o[b], k == null || k.debug(
|
|
820
|
+
`[%s] go to %j from %j with ${l}nm, and cost ${u} hours`,
|
|
807
821
|
h.requestId,
|
|
808
|
-
{ lat:
|
|
809
|
-
{ lat:
|
|
810
|
-
),
|
|
811
|
-
|
|
822
|
+
{ lat: f.lat, lng: f.lng },
|
|
823
|
+
{ lat: w.lat, lng: w.lng, etd: w.etd }
|
|
824
|
+
), F += l, o.filter((I) => I).length <= 1) {
|
|
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];
|
|
812
826
|
break;
|
|
813
827
|
}
|
|
814
828
|
} else {
|
|
815
|
-
u = i -
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
`[%s] go to %j from %j with ${
|
|
829
|
+
u = i - m, t.add(u, "hour");
|
|
830
|
+
const I = J.roundPrecision(w.speed * u, 5);
|
|
831
|
+
x = W.calculateCoordinate(c, e.bearing, I, "nauticalmiles", !f.gcToPrevious), x.eta = t.utc().format(), o[b] = x, k == null || k.debug(
|
|
832
|
+
`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,
|
|
819
833
|
h.requestId,
|
|
820
|
-
{ lat:
|
|
834
|
+
{ lat: x.lat, lng: x.lng },
|
|
821
835
|
{ lat: c.lat, lng: c.lng, etd: c.etd }
|
|
822
|
-
),
|
|
836
|
+
), F += I, x.distanceFromPrevious = Math.round(F * 1e4) / 1e4, x.distanceFromStart = Math.round((a + F) * 1e4) / 1e4;
|
|
823
837
|
break;
|
|
824
838
|
}
|
|
825
839
|
}
|
|
826
|
-
return { etd: t, from:
|
|
840
|
+
return { etd: t, from: w, to: x, next: o.filter((b) => b), wps: y, days: v };
|
|
827
841
|
}
|
|
828
842
|
/**
|
|
829
843
|
* 洋流影响因子
|
|
@@ -844,16 +858,16 @@ class O {
|
|
|
844
858
|
* @param wwc 气象要素
|
|
845
859
|
*/
|
|
846
860
|
static weatherFactor(e, t) {
|
|
847
|
-
var M,
|
|
848
|
-
|
|
861
|
+
var M, y, v, m, F, x, w;
|
|
862
|
+
k == null || k.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
849
863
|
const n = O.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), i = O.froudeNumber(e.speed, e.lbp), a = O.amendFactor(n, i, e.loadCondition);
|
|
850
864
|
let o = Math.abs(e.bearing % 360 - (((M = t == null ? void 0 : t.wind) == null ? void 0 : M.degree) % 360 || 0));
|
|
851
865
|
o = o > 180 ? 360 - o : o;
|
|
852
|
-
const s = O.directionFactor(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, (v = t == null ? void 0 : t.wind) == null ? void 0 : v.scale);
|
|
853
867
|
let r = s * a * d / 100 * e.speed;
|
|
854
|
-
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)),
|
|
855
|
-
const h = O.waveHeightFactor(((
|
|
856
|
-
return
|
|
868
|
+
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), k == null || k.debug("wind wx factor = %d", r), 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(((w = (x = t == null ? void 0 : t.wave) == null ? void 0 : x.sig) == null ? void 0 : w.height) ?? 1, o);
|
|
870
|
+
return k == null || k.debug("wave wx factor = %d", h), r = r * 0.4 + h, k == null || k.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;
|
|
857
871
|
}
|
|
858
872
|
/**
|
|
859
873
|
* 全程失速分析(走完航程)
|
|
@@ -868,13 +882,13 @@ class O {
|
|
|
868
882
|
* @param useRouteParam
|
|
869
883
|
*/
|
|
870
884
|
static async analyseInstant(e, t, n, i, a, o = "", s = 0, d = !0, r = !1, h = {}) {
|
|
871
|
-
var
|
|
872
|
-
const M =
|
|
885
|
+
var G, U, Q, X, Z, $;
|
|
886
|
+
const M = g().valueOf();
|
|
873
887
|
e.lng = J.convertToStdLng(e.lng);
|
|
874
|
-
const { route:
|
|
875
|
-
if (((
|
|
888
|
+
const { route: y, waypoints: v } = a.points, m = W.calculateSubRoute(e, y);
|
|
889
|
+
if (((G = m[0]) == null ? void 0 : G.length) <= 1)
|
|
876
890
|
return;
|
|
877
|
-
const { v0:
|
|
891
|
+
const { v0: F, label: x } = e.sog ? {
|
|
878
892
|
v0: e.sog,
|
|
879
893
|
label: "Other"
|
|
880
894
|
/* Instruct */
|
|
@@ -882,55 +896,55 @@ class O {
|
|
|
882
896
|
v0: i.speed,
|
|
883
897
|
label: "CP"
|
|
884
898
|
/* Cp */
|
|
885
|
-
},
|
|
886
|
-
|
|
899
|
+
}, w = O.assembleProperties(n, i.loadCondition, F, 0), b = v.length ? W.calculateSubWaypoints(e, v) : [];
|
|
900
|
+
b.forEach((q) => q.important = !0);
|
|
887
901
|
const c = {
|
|
888
902
|
from: { ...e },
|
|
889
|
-
route:
|
|
890
|
-
waypoints:
|
|
891
|
-
v0:
|
|
892
|
-
label:
|
|
893
|
-
},
|
|
903
|
+
route: m,
|
|
904
|
+
waypoints: b,
|
|
905
|
+
v0: F,
|
|
906
|
+
label: x
|
|
907
|
+
}, f = {
|
|
894
908
|
hours: [],
|
|
895
909
|
days: [],
|
|
896
910
|
wps: []
|
|
897
911
|
};
|
|
898
|
-
s || (W.calculateRouteDistance(
|
|
899
|
-
let
|
|
900
|
-
t =
|
|
912
|
+
s || (W.calculateRouteDistance(m) / i.speed <= 72 ? s = 3 : s = 6);
|
|
913
|
+
let l = W.simplifyRouteToCoordinates(m, b, 0), u = 0, I = 0, S = 0, D = 0;
|
|
914
|
+
t = g(t).utc();
|
|
901
915
|
const Y = t.clone();
|
|
902
|
-
for (;
|
|
903
|
-
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,
|
|
904
|
-
|
|
916
|
+
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, C = await O.speedLoseInHoursStep(
|
|
918
|
+
w,
|
|
905
919
|
t,
|
|
906
920
|
Y,
|
|
907
921
|
V,
|
|
908
922
|
u,
|
|
909
|
-
|
|
923
|
+
l,
|
|
910
924
|
o,
|
|
911
925
|
d,
|
|
912
926
|
r,
|
|
913
927
|
h
|
|
914
928
|
);
|
|
915
|
-
(U =
|
|
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;
|
|
916
930
|
}
|
|
917
|
-
const E =
|
|
931
|
+
const E = f.hours;
|
|
918
932
|
for (let q = 0; q < E.length - 1; q++) {
|
|
919
|
-
const V =
|
|
920
|
-
|
|
933
|
+
const V = g(E[q + 1].eta).diff(E[q].etd, "hour", !0) || 1;
|
|
934
|
+
I += (E[q].wxFactor || 0) * V, S += (E[q].cFactor || 0) * V, D += V;
|
|
921
935
|
}
|
|
922
|
-
(X =
|
|
923
|
-
q.positionTime =
|
|
924
|
-
const
|
|
925
|
-
if (
|
|
926
|
-
const L = q.distanceFromStart -
|
|
936
|
+
(X = f.wps) == null || X.forEach((q, V) => {
|
|
937
|
+
q.positionTime = g.utc(q.etd || q.eta).unix();
|
|
938
|
+
const C = f.wps[V - 1];
|
|
939
|
+
if (C) {
|
|
940
|
+
const L = q.distanceFromStart - C.distanceFromStart, H = g(q.eta || q.etd).diff(g(C.etd || C.eta), "h", !0);
|
|
927
941
|
q.avgSpd = Math.round(L / H * 100) / 100;
|
|
928
|
-
const nt = W.calculateBearing(
|
|
929
|
-
|
|
942
|
+
const nt = W.calculateBearing(C, q);
|
|
943
|
+
C.bearing = nt;
|
|
930
944
|
}
|
|
931
|
-
}),
|
|
932
|
-
const P =
|
|
933
|
-
c.distance = Math.round(T.distanceFromStart * 1e4) / 1e4, c.etd =
|
|
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
|
+
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(S / D * 1e4) / 1e4, c.avgSpeed = Math.round(T.distanceFromStart / D * 1e4) / 1e4, c.totalHrs = Math.round(D * 1e4) / 1e4;
|
|
934
948
|
const { distanceInECA: N, hoursInECA: A, totalDgoConsInECA: R, eca: K } = await this.calculateECA(c, i, h), st = J.roundPrecision(i.fo / 24 * (D - A), 3), at = J.roundPrecision(i.dgo / 24 * D, 3);
|
|
935
949
|
c.extend = {
|
|
936
950
|
eca: K,
|
|
@@ -938,8 +952,8 @@ class O {
|
|
|
938
952
|
hoursInECA: A,
|
|
939
953
|
totalDgoConsInECA: R
|
|
940
954
|
}, c.totalFoCons = st, c.totalDgoCons = at;
|
|
941
|
-
const tt =
|
|
942
|
-
return
|
|
955
|
+
const tt = g().valueOf() - M, ot = (($ = f == null ? void 0 : f.hours) == null ? void 0 : $.length) || 1;
|
|
956
|
+
return k == null || k.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;
|
|
943
957
|
}
|
|
944
958
|
/**
|
|
945
959
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -954,11 +968,11 @@ class O {
|
|
|
954
968
|
* @param useMeteo true 启用气象分析
|
|
955
969
|
* @param useRouteParam
|
|
956
970
|
*/
|
|
957
|
-
static async analyseInstantWithThreshed(e, t, n, i, a, o, s, d = "", r = 3, h = !0, M = !1,
|
|
971
|
+
static async analyseInstantWithThreshed(e, t, n, i, a, o, s, d = "", r = 3, h = !0, M = !1, y = {}) {
|
|
958
972
|
var Q, X, Z, $, q, V;
|
|
959
|
-
const
|
|
973
|
+
const v = g().valueOf();
|
|
960
974
|
e.lng = J.convertToStdLng(e.lng);
|
|
961
|
-
const { v0:
|
|
975
|
+
const { v0: m, label: F } = e.sog ? {
|
|
962
976
|
v0: e.sog,
|
|
963
977
|
label: "Other"
|
|
964
978
|
/* Instruct */
|
|
@@ -966,66 +980,66 @@ class O {
|
|
|
966
980
|
v0: a.speed,
|
|
967
981
|
label: "CP"
|
|
968
982
|
/* Cp */
|
|
969
|
-
},
|
|
970
|
-
if (((Q =
|
|
983
|
+
}, x = O.assembleProperties(i, a.loadCondition, m, 0), w = W.calculateSubRoute(e, o);
|
|
984
|
+
if (((Q = w[0]) == null ? void 0 : Q.length) <= 1)
|
|
971
985
|
return;
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
let c = W.simplifyRouteToCoordinates(
|
|
986
|
+
const b = s.length ? W.calculateSubWaypoints(e, s) : [];
|
|
987
|
+
b.forEach((C) => C.important = !0);
|
|
988
|
+
let c = W.simplifyRouteToCoordinates(w, b, 0), f = 0, l = 0, u = 0, I = 0;
|
|
975
989
|
const S = {
|
|
976
990
|
hours: [],
|
|
977
991
|
wps: [],
|
|
978
992
|
days: []
|
|
979
993
|
};
|
|
980
|
-
t =
|
|
994
|
+
t = g(t).utc();
|
|
981
995
|
const D = t.clone();
|
|
982
996
|
for (; c.length > 0; ) {
|
|
983
|
-
const
|
|
984
|
-
let L = Math.ceil(t.clone().add(
|
|
997
|
+
const C = r - t.hour() % r;
|
|
998
|
+
let L = Math.ceil(t.clone().add(C, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
985
999
|
L = t.clone().add(L, "h").isSameOrAfter(n) ? n.diff(t, "h", !0) * 1e4 / 1e4 : L;
|
|
986
|
-
const H = await O.speedLoseInHoursStep(
|
|
987
|
-
if ((X = H.from) != null && X.speed && (S.hours.push(H.from), H != null && H.wps && S.wps.push(...H.wps), S.days.push(...H.days)), c = H == null ? void 0 : H.next, c.length || S.hours.push(H == null ? void 0 : H.to),
|
|
1000
|
+
const H = await O.speedLoseInHoursStep(x, t, D, L, f, c, d, h, M, y);
|
|
1001
|
+
if ((X = H.from) != null && X.speed && (S.hours.push(H.from), H != null && H.wps && S.wps.push(...H.wps), S.days.push(...H.days)), c = H == null ? void 0 : H.next, c.length || S.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)
|
|
988
1002
|
break;
|
|
989
1003
|
}
|
|
990
|
-
S.wps = ($ = S.wps) == null ? void 0 : $.reduce((
|
|
1004
|
+
S.wps = ($ = S.wps) == null ? void 0 : $.reduce((C, L) => (C.some((H) => Math.round(g(H.etd).unix() / 60) === Math.round(g(L.etd).unix() / 60)) || C.push(L), C), []), (q = S.wps) == null || q.forEach((C, L) => {
|
|
991
1005
|
const H = S.wps[L - 1];
|
|
992
1006
|
if (H) {
|
|
993
|
-
const nt =
|
|
994
|
-
|
|
995
|
-
const ut = W.calculateBearing(H,
|
|
1007
|
+
const nt = C.distanceFromStart - H.distanceFromStart, dt = g(C.eta || C.etd).diff(g(H.etd || H.eta), "h", !0);
|
|
1008
|
+
C.avgSpd = Math.round(nt / dt * 100) / 100;
|
|
1009
|
+
const ut = W.calculateBearing(H, C);
|
|
996
1010
|
H.bearing = ut;
|
|
997
1011
|
}
|
|
998
1012
|
});
|
|
999
1013
|
const Y = S.hours;
|
|
1000
|
-
for (let
|
|
1001
|
-
const L =
|
|
1002
|
-
|
|
1014
|
+
for (let C = 0; C < Y.length - 1; C++) {
|
|
1015
|
+
const L = g(Y[C + 1].eta).diff(Y[C].etd, "hour", !0);
|
|
1016
|
+
l += Y[C].wxFactor * L, u += Y[C].cFactor * L, I += L;
|
|
1003
1017
|
}
|
|
1004
|
-
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, w), N = await W.calculateRangeWaypoints(E, P, w, b), A = {
|
|
1005
1019
|
sample: S,
|
|
1006
1020
|
distance: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1007
1021
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1008
|
-
etd:
|
|
1009
|
-
eta:
|
|
1010
|
-
wxFactor: Math.round(
|
|
1011
|
-
cFactor: Math.round(u /
|
|
1012
|
-
avgSpeed: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) /
|
|
1013
|
-
totalHrs: Math.round(
|
|
1022
|
+
etd: g(E.eta).utc().format(),
|
|
1023
|
+
eta: g(P == null ? void 0 : P.eta).utc().format(),
|
|
1024
|
+
wxFactor: Math.round(l / I * 1e4) / 1e4,
|
|
1025
|
+
cFactor: Math.round(u / I * 1e4) / 1e4,
|
|
1026
|
+
avgSpeed: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) / I * 1e4) / 1e4,
|
|
1027
|
+
totalHrs: Math.round(I * 1e4) / 1e4,
|
|
1014
1028
|
from: E,
|
|
1015
1029
|
to: P,
|
|
1016
1030
|
route: T,
|
|
1017
1031
|
waypoints: N,
|
|
1018
|
-
v0:
|
|
1019
|
-
label:
|
|
1020
|
-
}, { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: st, eca: at } = await this.calculateECA(A, a,
|
|
1032
|
+
v0: m,
|
|
1033
|
+
label: F
|
|
1034
|
+
}, { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: st, eca: at } = await this.calculateECA(A, a, y), rt = J.roundPrecision(a.fo / 24 * (I - K), 3), tt = J.roundPrecision(a.dgo / 24 * I, 3);
|
|
1021
1035
|
A.extend = {
|
|
1022
1036
|
eca: at,
|
|
1023
1037
|
distanceInECA: R,
|
|
1024
1038
|
hoursInECA: K,
|
|
1025
1039
|
totalDgoConsInECA: st
|
|
1026
1040
|
}, A.totalDgoCons = tt, A.totalFoCons = rt;
|
|
1027
|
-
const
|
|
1028
|
-
return
|
|
1041
|
+
const G = g().valueOf() - v, U = ((V = S == null ? void 0 : S.hours) == null ? void 0 : V.length) || 1;
|
|
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;
|
|
1029
1043
|
}
|
|
1030
1044
|
/**
|
|
1031
1045
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1043,33 +1057,33 @@ class O {
|
|
|
1043
1057
|
* @param options
|
|
1044
1058
|
*/
|
|
1045
1059
|
static async analyseCost(e, t, n, i, a = {}) {
|
|
1046
|
-
var
|
|
1047
|
-
const o =
|
|
1060
|
+
var w, b;
|
|
1061
|
+
const o = g().valueOf(), s = [];
|
|
1048
1062
|
a.meteo2 = a.meteo2 || !0, e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
|
|
1049
1063
|
const d = W.calculateRouteDistance(i.route);
|
|
1050
1064
|
let r = 0;
|
|
1051
1065
|
n.forEach((c) => {
|
|
1052
|
-
const
|
|
1053
|
-
r = r <
|
|
1066
|
+
const f = Math.ceil(d / c.speed / 24);
|
|
1067
|
+
r = r < f ? f : r;
|
|
1054
1068
|
}), r = r * 1.3;
|
|
1055
|
-
const h =
|
|
1069
|
+
const h = g.utc(e.etd).add(r ?? 14, "day");
|
|
1056
1070
|
let M = 1;
|
|
1057
1071
|
for (const c of n) {
|
|
1058
|
-
const
|
|
1072
|
+
const f = JSON.parse(JSON.stringify(i.route)), l = JSON.parse(JSON.stringify(i.waypoints)), u = await O.analyseInstantWithThreshed(
|
|
1059
1073
|
{ lat: e.lat, lng: e.lng },
|
|
1060
1074
|
e.etd,
|
|
1061
1075
|
h,
|
|
1062
1076
|
t,
|
|
1063
1077
|
c,
|
|
1064
|
-
|
|
1065
|
-
|
|
1078
|
+
f,
|
|
1079
|
+
l,
|
|
1066
1080
|
e.meteoVendor,
|
|
1067
1081
|
e.speedStep,
|
|
1068
1082
|
e.useMeteo,
|
|
1069
1083
|
e.useRouteParam,
|
|
1070
1084
|
a
|
|
1071
1085
|
);
|
|
1072
|
-
u && (await O.calculateCost(u, c, e, a), s.push(u),
|
|
1086
|
+
u && (await O.calculateCost(u, c, e, a), s.push(u), k == null || k.info("[%s][L%d-%d] analyse from %s to %s cost: %j", a.requestId, 1, M, e.etd, h.format(), {
|
|
1073
1087
|
cost: u.cost.total,
|
|
1074
1088
|
hire: u.cost.hire,
|
|
1075
1089
|
bunker: u.cost.bunker,
|
|
@@ -1078,23 +1092,23 @@ class O {
|
|
|
1078
1092
|
cp: `${c.speed}/${c.fo}/${c.dgo}`
|
|
1079
1093
|
})), M++;
|
|
1080
1094
|
}
|
|
1081
|
-
s.sort((c,
|
|
1082
|
-
const
|
|
1083
|
-
if (
|
|
1084
|
-
const c =
|
|
1085
|
-
let S = Math.ceil(
|
|
1095
|
+
s.sort((c, f) => c.cost.total - f.cost.total);
|
|
1096
|
+
const y = s.at(0), v = s.at(1), m = [];
|
|
1097
|
+
if (m.push({ combined: !1, speeds: [y], cost: (w = y.cost) == null ? void 0 : w.total }), v) {
|
|
1098
|
+
const c = y.cost.cp, f = v.cost.cp, l = g(y.eta), u = g(y.etd), I = l.diff(u, "days", !0);
|
|
1099
|
+
let S = Math.ceil(I / 2);
|
|
1086
1100
|
S = S > 7 ? 7 : S < e.alterStep ? e.alterStep : S;
|
|
1087
|
-
let D = 2, Y = { combined: !1, speeds: [
|
|
1101
|
+
let D = 2, Y = { combined: !1, speeds: [v], cost: (b = v.cost) == null ? void 0 : b.total }, E;
|
|
1088
1102
|
for (; S >= e.alterStep; ) {
|
|
1089
|
-
const P = await O.combinedAnalyse(e, t, h, [c,
|
|
1103
|
+
const P = await O.combinedAnalyse(e, t, h, [c, f], i, S, { ...a, level: D });
|
|
1090
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)
|
|
1091
1105
|
break;
|
|
1092
1106
|
S = Math.ceil(S / 2), D += 1;
|
|
1093
1107
|
}
|
|
1094
|
-
|
|
1108
|
+
m.push(Y), E && m.push(E);
|
|
1095
1109
|
}
|
|
1096
|
-
const
|
|
1097
|
-
return
|
|
1110
|
+
const x = g().valueOf() - o;
|
|
1111
|
+
return k == null || k.info("[%s] analyse elapsed: %d ms", a == null ? void 0 : a.requestId, x), m.sort((c, f) => c.cost - f.cost);
|
|
1098
1112
|
}
|
|
1099
1113
|
/**
|
|
1100
1114
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1107,11 +1121,23 @@ class O {
|
|
|
1107
1121
|
* @param options
|
|
1108
1122
|
*/
|
|
1109
1123
|
static async combinedAnalyse(e, t, n, i, a, o, s = {}) {
|
|
1110
|
-
s.counter = 1,
|
|
1111
|
-
const d = await O.alternateAnalyse(e, t, n, i, 0, a, o, s), r = d.reduce((
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
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, i, 0, a, o, 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);
|
|
1126
|
+
k == null || k.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
|
|
1127
|
+
cost: r,
|
|
1128
|
+
hire: h,
|
|
1129
|
+
bunker: M,
|
|
1130
|
+
distance: y,
|
|
1131
|
+
hours: v
|
|
1132
|
+
});
|
|
1133
|
+
const m = await O.alternateAnalyse(e, t, n, i, 1, a, o, s), F = m.reduce((f, l) => f + l.cost.total, 0), x = 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);
|
|
1134
|
+
return k == null || k.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
|
|
1135
|
+
cost: F,
|
|
1136
|
+
hire: x,
|
|
1137
|
+
bunker: w,
|
|
1138
|
+
distance: b,
|
|
1139
|
+
hours: c
|
|
1140
|
+
}), r < F ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step: o } : { combined: !0, cost: Math.round(F * 1e3) / 1e3, speeds: m, step: o };
|
|
1115
1141
|
}
|
|
1116
1142
|
/**
|
|
1117
1143
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1125,43 +1151,43 @@ class O {
|
|
|
1125
1151
|
* @param options
|
|
1126
1152
|
*/
|
|
1127
1153
|
static async alternateAnalyse(e, t, n, i, a, o, s, d = {}) {
|
|
1128
|
-
var
|
|
1129
|
-
let r =
|
|
1154
|
+
var y, v;
|
|
1155
|
+
let r = g.utc(e.etd);
|
|
1130
1156
|
const h = { lat: e.lat, lng: e.lng }, M = [];
|
|
1131
1157
|
for (; r.isBefore(n); ) {
|
|
1132
|
-
const
|
|
1158
|
+
const m = r.clone().utc().add(s, "day"), F = JSON.parse(JSON.stringify(o.route)), x = JSON.parse(JSON.stringify(o.waypoints)), w = i[a], b = await O.analyseInstantWithThreshed(
|
|
1133
1159
|
h,
|
|
1134
1160
|
r.utc().format(),
|
|
1135
|
-
f,
|
|
1136
|
-
t,
|
|
1137
1161
|
m,
|
|
1162
|
+
t,
|
|
1163
|
+
w,
|
|
1164
|
+
F,
|
|
1138
1165
|
x,
|
|
1139
|
-
I,
|
|
1140
1166
|
e.meteoVendor,
|
|
1141
1167
|
e.speedStep,
|
|
1142
1168
|
e.useMeteo,
|
|
1143
1169
|
e.useRouteParam,
|
|
1144
1170
|
d
|
|
1145
1171
|
);
|
|
1146
|
-
|
|
1172
|
+
b && (await O.calculateCost(b, w, e, d), k == null || k.info(
|
|
1147
1173
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1148
1174
|
d.requestId,
|
|
1149
1175
|
d.level,
|
|
1150
1176
|
d.counter,
|
|
1151
1177
|
r.utc().format(),
|
|
1152
|
-
|
|
1178
|
+
m.utc().format(),
|
|
1153
1179
|
{
|
|
1154
|
-
cost:
|
|
1155
|
-
hire:
|
|
1156
|
-
bunker:
|
|
1157
|
-
distance:
|
|
1158
|
-
hours:
|
|
1159
|
-
cp: `${
|
|
1180
|
+
cost: b.cost.total,
|
|
1181
|
+
hire: b.cost.hire,
|
|
1182
|
+
bunker: b.cost.bunker,
|
|
1183
|
+
distance: b.distance,
|
|
1184
|
+
hours: b.totalHrs,
|
|
1185
|
+
cp: `${w.speed}/${w.fo}/${w.dgo}`
|
|
1160
1186
|
}
|
|
1161
1187
|
)), d.counter = d.counter + 1;
|
|
1162
|
-
const c = (
|
|
1188
|
+
const c = (v = (y = b == null ? void 0 : b.sample) == null ? void 0 : y.hours) == null ? void 0 : v.at(-1);
|
|
1163
1189
|
if (c)
|
|
1164
|
-
h.lat = c.lat, h.lng = c.lng, r =
|
|
1190
|
+
h.lat = c.lat, h.lng = c.lng, r = g(c.eta), M.push(b), a = a ? 0 : 1;
|
|
1165
1191
|
else
|
|
1166
1192
|
break;
|
|
1167
1193
|
}
|
|
@@ -1195,12 +1221,12 @@ class O {
|
|
|
1195
1221
|
const i = await W.intersectInECA(e.route);
|
|
1196
1222
|
let a = 0, o = 0, s = 0;
|
|
1197
1223
|
e.sample.wps.forEach((h) => {
|
|
1198
|
-
h.positionTime =
|
|
1224
|
+
h.positionTime = g.utc(h.etd || h.eta).unix();
|
|
1199
1225
|
});
|
|
1200
1226
|
for (const h of i) {
|
|
1201
1227
|
a += h.distance;
|
|
1202
|
-
const M = await W.deadReckoningTime((d = h.waypoints) == null ? void 0 : d.at(0), e.sample.wps),
|
|
1203
|
-
h.in = M, h.out =
|
|
1228
|
+
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);
|
|
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;
|
|
1204
1230
|
}
|
|
1205
1231
|
return a = J.roundPrecision(a, 3), o = J.roundPrecision(o, 3), s = J.roundPrecision(s, 3), {
|
|
1206
1232
|
distanceInECA: a,
|
|
@@ -1215,55 +1241,55 @@ class O {
|
|
|
1215
1241
|
* @param options
|
|
1216
1242
|
*/
|
|
1217
1243
|
static async mergeSpeeds(e, t = {}) {
|
|
1218
|
-
var c,
|
|
1244
|
+
var c, f;
|
|
1219
1245
|
const n = {
|
|
1220
1246
|
hours: [],
|
|
1221
1247
|
wps: [],
|
|
1222
1248
|
days: []
|
|
1223
|
-
}, i = e.reduce((
|
|
1224
|
-
var
|
|
1225
|
-
return
|
|
1226
|
-
}, 0), o = e.reduce((
|
|
1227
|
-
var
|
|
1228
|
-
return
|
|
1229
|
-
}, 0), d = e.reduce((
|
|
1230
|
-
var
|
|
1231
|
-
return
|
|
1232
|
-
}, 0), r = e.reduce((
|
|
1233
|
-
let
|
|
1234
|
-
for (const
|
|
1235
|
-
|
|
1236
|
-
const u =
|
|
1237
|
-
|
|
1238
|
-
N && (T.distanceFromStart = T.distanceFromStart +
|
|
1239
|
-
}),
|
|
1240
|
-
N && (T.distanceFromStart = T.distanceFromStart +
|
|
1241
|
-
}), S.at(0).distanceFromPrevious =
|
|
1242
|
-
N && (T.distanceFromStart = T.distanceFromStart +
|
|
1243
|
-
})), D.cp =
|
|
1244
|
-
const Y = [
|
|
1245
|
-
E === -1 ? (D.cp.segment = [Y],
|
|
1249
|
+
}, i = e.reduce((l, u) => l + u.distance, 0), a = e.reduce((l, u) => {
|
|
1250
|
+
var I;
|
|
1251
|
+
return l + (((I = u.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1252
|
+
}, 0), o = e.reduce((l, u) => l + u.totalHrs, 0), s = e.reduce((l, u) => {
|
|
1253
|
+
var I;
|
|
1254
|
+
return l + (((I = u.extend) == null ? void 0 : I.hoursInECA) || 0);
|
|
1255
|
+
}, 0), d = e.reduce((l, u) => {
|
|
1256
|
+
var I;
|
|
1257
|
+
return l + (((I = u.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1258
|
+
}, 0), r = 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), v = 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 = [], w = [];
|
|
1259
|
+
let b;
|
|
1260
|
+
for (const l of e) {
|
|
1261
|
+
w.push(...((c = l.extend) == null ? void 0 : c.eca) || []);
|
|
1262
|
+
const u = l.sample.hours, I = l.sample.wps, S = l.sample.days, D = u.at(0);
|
|
1263
|
+
b && (D.distanceFromPrevious = b.distanceFromPrevious, D.distanceFromStart = b.distanceFromStart, u.forEach((T, N) => {
|
|
1264
|
+
N && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1265
|
+
}), I.at(0).distanceFromPrevious = b.distanceFromPrevious, I.at(0).distanceFromStart = b.distanceFromStart, I.forEach((T, N) => {
|
|
1266
|
+
N && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1267
|
+
}), S.at(0).distanceFromPrevious = b.distanceFromPrevious, S.at(0).distanceFromStart = b.distanceFromStart, S.forEach((T, N) => {
|
|
1268
|
+
N && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1269
|
+
})), D.cp = l.cost.cp;
|
|
1270
|
+
const Y = [l.etd, l.eta], E = x.findIndex((T) => T.id === D.cp.id);
|
|
1271
|
+
E === -1 ? (D.cp.segment = [Y], x.push(D.cp)) : x[E].segment.push(Y), u.forEach((T) => {
|
|
1246
1272
|
var A;
|
|
1247
1273
|
((A = n.hours) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.hours.push(T);
|
|
1248
|
-
}),
|
|
1274
|
+
}), I.forEach((T) => {
|
|
1249
1275
|
var A;
|
|
1250
1276
|
((A = n.wps) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.wps.push(T);
|
|
1251
1277
|
}), S.forEach((T) => {
|
|
1252
1278
|
var A;
|
|
1253
1279
|
((A = n == null ? void 0 : n.days) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.days.push(T);
|
|
1254
1280
|
});
|
|
1255
|
-
const P = (
|
|
1256
|
-
P === -1 ? n.wps.push(D) : n.wps[P] = D,
|
|
1281
|
+
const P = (f = n.wps) == null ? void 0 : f.findIndex((T) => T.eta === D.eta);
|
|
1282
|
+
P === -1 ? n.wps.push(D) : n.wps[P] = D, b = u.at(-1);
|
|
1257
1283
|
}
|
|
1258
|
-
return n.wps.sort((
|
|
1259
|
-
|
|
1260
|
-
}), n.wps.forEach((
|
|
1261
|
-
const
|
|
1262
|
-
if (
|
|
1263
|
-
const S =
|
|
1264
|
-
|
|
1265
|
-
const E = W.calculateBearing(
|
|
1266
|
-
|
|
1284
|
+
return n.wps.sort((l, u) => {
|
|
1285
|
+
g(l.etd).unix() - g(u.etd).unix();
|
|
1286
|
+
}), n.wps.forEach((l, u) => {
|
|
1287
|
+
const I = n.wps[u - 1];
|
|
1288
|
+
if (I) {
|
|
1289
|
+
const S = l.distanceFromStart - (I.distanceFromStart || 0), D = g(l.eta || l.etd).diff(g(I.etd || I.eta), "hour", !0), Y = Math.round(S / D * 100) / 100;
|
|
1290
|
+
l.avgSpd = Y;
|
|
1291
|
+
const E = W.calculateBearing(I, l);
|
|
1292
|
+
I.bearing = E;
|
|
1267
1293
|
}
|
|
1268
1294
|
}), {
|
|
1269
1295
|
sample: n,
|
|
@@ -1279,15 +1305,15 @@ class O {
|
|
|
1279
1305
|
wxFactor: Math.round(r * 1e3) / 1e3,
|
|
1280
1306
|
cFactor: Math.round(h * 1e3) / 1e3,
|
|
1281
1307
|
totalFoCons: Math.round(M * 1e3) / 1e3,
|
|
1282
|
-
totalDgoCons: Math.round(
|
|
1308
|
+
totalDgoCons: Math.round(y * 1e3) / 1e3,
|
|
1283
1309
|
cost: {
|
|
1284
|
-
total: Math.round(
|
|
1285
|
-
hire: Math.round(
|
|
1286
|
-
bunker: Math.round(
|
|
1310
|
+
total: Math.round(v * 1e3) / 1e3,
|
|
1311
|
+
hire: Math.round(m * 1e3) / 1e3,
|
|
1312
|
+
bunker: Math.round(F * 1e3) / 1e3
|
|
1287
1313
|
},
|
|
1288
1314
|
extend: {
|
|
1289
|
-
cps:
|
|
1290
|
-
eca:
|
|
1315
|
+
cps: x,
|
|
1316
|
+
eca: w,
|
|
1291
1317
|
distanceInECA: Math.round(a * 1e4) / 1e4,
|
|
1292
1318
|
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1293
1319
|
totalDgoConsInECA: Math.round(d * 1e3) / 1e3,
|
|
@@ -1303,7 +1329,7 @@ export {
|
|
|
1303
1329
|
Et as HifleetImpl,
|
|
1304
1330
|
pt as LoadCondition,
|
|
1305
1331
|
Tt as MyShipImpl,
|
|
1306
|
-
|
|
1332
|
+
jt as MyVesselImpl,
|
|
1307
1333
|
Nt as ShipxyImpl,
|
|
1308
1334
|
O as SpeedHelper,
|
|
1309
1335
|
vt as SpeedLabel,
|