@idm-plugin/vessel 1.2.0 → 1.2.1
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 +250 -247
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var Q = Object.defineProperty;
|
|
2
|
-
var X = (
|
|
3
|
-
var L = (
|
|
2
|
+
var X = (k, s, t) => s in k ? Q(k, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : k[s] = t;
|
|
3
|
+
var L = (k, s, t) => (X(k, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
4
|
import P from "got";
|
|
5
5
|
import K from "@log4js-node/log4js-api";
|
|
6
6
|
import y from "moment";
|
|
@@ -74,11 +74,11 @@ class lt extends Z {
|
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
async realTimePosition(t, r = {}) {
|
|
77
|
-
var m,
|
|
77
|
+
var m, g, p;
|
|
78
78
|
(!this.token || y().diff(y(this.token.issuedAt), "seconds") > ((m = this.token) == null ? void 0 : m.expiresIn) - 300) && await this.authToken(r);
|
|
79
79
|
const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
|
|
80
80
|
headers: {
|
|
81
|
-
Authorization: `${(
|
|
81
|
+
Authorization: `${(g = this.token) == null ? void 0 : g.tokenType} ${(p = this.token) == null ? void 0 : p.accessToken}`
|
|
82
82
|
},
|
|
83
83
|
searchParams: { mmsi: t }
|
|
84
84
|
};
|
|
@@ -87,9 +87,9 @@ class lt extends Z {
|
|
|
87
87
|
if (a.code)
|
|
88
88
|
return S.warn("[%s] fetch realtime position failed: %j", r.requestId, o, { message: a.message, status: a.status, code: a.code }), a;
|
|
89
89
|
const e = a.data;
|
|
90
|
-
for (const
|
|
91
|
-
!isNaN(e[
|
|
92
|
-
const
|
|
90
|
+
for (const f in e)
|
|
91
|
+
!isNaN(e[f]) && Number(e[f]) !== 1 / 0 && (e[f] = Number(e[f]));
|
|
92
|
+
const d = y(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
93
93
|
return {
|
|
94
94
|
mmsi: e.mmsi,
|
|
95
95
|
name: e.vesselName,
|
|
@@ -106,27 +106,27 @@ class lt extends Z {
|
|
|
106
106
|
rot: e.rot,
|
|
107
107
|
eta: e.eta,
|
|
108
108
|
destination: e.dest,
|
|
109
|
-
positionTime:
|
|
109
|
+
positionTime: d.unix(),
|
|
110
110
|
status: e.status,
|
|
111
111
|
labelCn: e.statusNameCn,
|
|
112
112
|
labelEn: e.statusNameEn,
|
|
113
113
|
method: "position",
|
|
114
114
|
vendor: "myVessel",
|
|
115
|
-
utc:
|
|
115
|
+
utc: d.utc().format()
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
118
|
async trajectory(t, r, o, n, a = !0, e = {}) {
|
|
119
119
|
(!this.token || y().diff(y(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
|
|
120
|
-
const
|
|
120
|
+
const d = await this.realTimePosition(t, e), i = y(r), m = y(o), g = [];
|
|
121
121
|
for (; m.diff(i, "day", !0) > 30; )
|
|
122
|
-
await this.trajectoryIn30Day(t, i, i.clone().add(30, "day"),
|
|
123
|
-
return await this.trajectoryIn30Day(t, i, m,
|
|
122
|
+
await this.trajectoryIn30Day(t, i, i.clone().add(30, "day"), d, n, g, e), i.add(30, "day");
|
|
123
|
+
return await this.trajectoryIn30Day(t, i, m, d, n, g, e), g;
|
|
124
124
|
}
|
|
125
|
-
async trajectoryIn30Day(t, r, o, n, a, e,
|
|
126
|
-
var
|
|
125
|
+
async trajectoryIn30Day(t, r, o, n, a, e, d = {}) {
|
|
126
|
+
var l, b, I, u, c;
|
|
127
127
|
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", m = {
|
|
128
128
|
headers: {
|
|
129
|
-
Authorization: `${(
|
|
129
|
+
Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(b = this.token) == null ? void 0 : b.accessToken}`
|
|
130
130
|
},
|
|
131
131
|
json: {
|
|
132
132
|
mmsi: t,
|
|
@@ -134,39 +134,39 @@ class lt extends Z {
|
|
|
134
134
|
endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
135
135
|
}
|
|
136
136
|
};
|
|
137
|
-
S.info("[%s] fetch trajectory from: %s - %j",
|
|
138
|
-
const
|
|
139
|
-
if (
|
|
140
|
-
return S.warn("[%s] fetch trajectory failed: %j",
|
|
141
|
-
let
|
|
142
|
-
const
|
|
143
|
-
return (
|
|
144
|
-
for (const
|
|
145
|
-
!isNaN(
|
|
146
|
-
const v = y(`${
|
|
147
|
-
mmsi:
|
|
137
|
+
S.info("[%s] fetch trajectory from: %s - %j", d.requestId, i, m);
|
|
138
|
+
const g = await P.post(i, m).json();
|
|
139
|
+
if (g.code)
|
|
140
|
+
return S.warn("[%s] fetch trajectory failed: %j", d.requestId, i, { message: g.message, status: g.status, code: g.code }), g;
|
|
141
|
+
let p = -1;
|
|
142
|
+
const f = y(`${(u = (I = g.data) == null ? void 0 : I[0]) == null ? void 0 : u.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
143
|
+
return (c = g.data) == null || c.forEach((h) => {
|
|
144
|
+
for (const T in h)
|
|
145
|
+
!isNaN(h[T]) && Number(h[T]) !== 1 / 0 && (h[T] = Number(h[T]));
|
|
146
|
+
const v = y(`${h.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), w = h.eta ? y(`${h.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, M = h.status, { labelCn: x, labelEn: N } = this.parseStatus(M), C = {
|
|
147
|
+
mmsi: h.mmsi,
|
|
148
148
|
imo: n == null ? void 0 : n.imo,
|
|
149
|
-
lat:
|
|
150
|
-
lng:
|
|
151
|
-
sog:
|
|
152
|
-
cog:
|
|
153
|
-
hdg:
|
|
154
|
-
draught:
|
|
155
|
-
status:
|
|
156
|
-
eta:
|
|
157
|
-
destination:
|
|
149
|
+
lat: h.lat,
|
|
150
|
+
lng: h.lon,
|
|
151
|
+
sog: h.sog,
|
|
152
|
+
cog: h.cog,
|
|
153
|
+
hdg: h.hdg,
|
|
154
|
+
draught: h.draught,
|
|
155
|
+
status: M,
|
|
156
|
+
eta: w == null ? void 0 : w.unix(),
|
|
157
|
+
destination: h.dest,
|
|
158
158
|
positionTime: v.unix(),
|
|
159
159
|
labelCn: x,
|
|
160
160
|
labelEn: N,
|
|
161
161
|
method: "trajectory",
|
|
162
162
|
vendor: "myVessel",
|
|
163
163
|
utc: v.utc().format()
|
|
164
|
-
},
|
|
165
|
-
|
|
164
|
+
}, j = Math.floor(v.diff(f, "minute", !0) / (a || 1));
|
|
165
|
+
j !== p && (p = j, e.push(C));
|
|
166
166
|
}), e;
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
class
|
|
169
|
+
class ft extends Z {
|
|
170
170
|
constructor(t) {
|
|
171
171
|
super();
|
|
172
172
|
L(this, "token");
|
|
@@ -183,10 +183,10 @@ class mt extends Z {
|
|
|
183
183
|
const e = a == null ? void 0 : a.list;
|
|
184
184
|
if (!e)
|
|
185
185
|
return S.warn("[%s] fetch realtime position failed: %j", r.requestId, o, a), a;
|
|
186
|
-
for (const
|
|
187
|
-
!isNaN(e[
|
|
186
|
+
for (const f in e)
|
|
187
|
+
!isNaN(e[f]) && Number(e[f]) !== 1 / 0 && (e[f] = Number(e[f]));
|
|
188
188
|
e.status = e.sp > 3 ? 0 : 1;
|
|
189
|
-
const
|
|
189
|
+
const d = e.status, { labelCn: i, labelEn: m } = this.parseStatus(d), g = y(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
190
190
|
return {
|
|
191
191
|
mmsi: e.m,
|
|
192
192
|
name: e.n,
|
|
@@ -203,9 +203,9 @@ class mt extends Z {
|
|
|
203
203
|
rot: isNaN(e.rot) ? 0 : e.rot,
|
|
204
204
|
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? y(`${e.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
|
|
205
205
|
destination: e.destination,
|
|
206
|
-
positionTime:
|
|
207
|
-
utc:
|
|
208
|
-
status:
|
|
206
|
+
positionTime: g.unix(),
|
|
207
|
+
utc: g.utc().format(),
|
|
208
|
+
status: d,
|
|
209
209
|
labelCn: i,
|
|
210
210
|
labelEn: m,
|
|
211
211
|
method: "position",
|
|
@@ -226,8 +226,8 @@ class mt extends Z {
|
|
|
226
226
|
};
|
|
227
227
|
let a = await P.post(o, n).json();
|
|
228
228
|
S.info("[%s] fetch vessel props from: %s - %j", r.requestId, o, n), a instanceof Array && (a = a[0]);
|
|
229
|
-
for (const
|
|
230
|
-
!isNaN(a[
|
|
229
|
+
for (const d in a)
|
|
230
|
+
!isNaN(a[d]) && Number(a[d]) !== 1 / 0 && (a[d] = Number(a[d]));
|
|
231
231
|
const e = {
|
|
232
232
|
mmsi: a.m,
|
|
233
233
|
name: a.n,
|
|
@@ -240,57 +240,57 @@ class mt extends Z {
|
|
|
240
240
|
return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await P.post(o, n).json(), S.info("[%s] fetch vessel dead weight from: %s - %j", r.requestId, o, n), a instanceof Array && (a = a[0]), a && (e.deadweight = Number(a.dwt)), e;
|
|
241
241
|
}
|
|
242
242
|
async trajectory(t, r, o, n, a = !0, e = {}) {
|
|
243
|
-
var
|
|
244
|
-
const
|
|
243
|
+
var h, v, w;
|
|
244
|
+
const d = await this.realTimePosition(t, e);
|
|
245
245
|
let i = y(r);
|
|
246
|
-
const m = y(o),
|
|
246
|
+
const m = y(o), g = y();
|
|
247
247
|
if (a) {
|
|
248
|
-
let
|
|
249
|
-
|
|
248
|
+
let M = m.diff(i, "d", !0);
|
|
249
|
+
M < 0 ? i = m.clone().subtract(40, "d") : M < 30 ? i.subtract(10, "d") : M < 60 ? i.subtract(5, "d") : i = m.clone().subtract(80, "d"), M = g.diff(m, "d", !0), m.add(M > 10 ? 240 : M * 24, "h");
|
|
250
250
|
}
|
|
251
|
-
const
|
|
251
|
+
const p = {
|
|
252
252
|
searchParams: {
|
|
253
253
|
endtime: m.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
254
254
|
starttime: i.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
255
255
|
mmsi: t,
|
|
256
256
|
usertoken: this.token
|
|
257
257
|
}
|
|
258
|
-
},
|
|
259
|
-
S.info("[%s] fetch trajectory from: %s - %j", e.requestId,
|
|
258
|
+
}, f = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", l = await P.get(f, p).json();
|
|
259
|
+
S.info("[%s] fetch trajectory from: %s - %j", e.requestId, f, p);
|
|
260
260
|
let b;
|
|
261
|
-
|
|
262
|
-
const
|
|
263
|
-
let
|
|
264
|
-
const
|
|
265
|
-
for (const
|
|
266
|
-
for (const A in
|
|
267
|
-
!isNaN(
|
|
268
|
-
const x = y(`${
|
|
269
|
-
|
|
270
|
-
const { labelEn: N, labelCn: C } = this.parseStatus(
|
|
271
|
-
mmsi:
|
|
272
|
-
name:
|
|
273
|
-
imo:
|
|
274
|
-
lat:
|
|
275
|
-
lng:
|
|
276
|
-
draught:
|
|
277
|
-
sog:
|
|
278
|
-
cog:
|
|
279
|
-
hdg:
|
|
261
|
+
l && (b = ((v = (h = l.ships) == null ? void 0 : h.offors) == null ? void 0 : v.ship) || [], b.length || S.warn("[%s] fetch trajectory failed: %j", e.requestId, l));
|
|
262
|
+
const I = [];
|
|
263
|
+
let u = -1;
|
|
264
|
+
const c = y(`${(w = b == null ? void 0 : b[0]) == null ? void 0 : w.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
265
|
+
for (const M of b) {
|
|
266
|
+
for (const A in M)
|
|
267
|
+
!isNaN(M[A]) && Number(M[A]) !== 1 / 0 && (M[A] = Number(M[A]));
|
|
268
|
+
const x = y(`${M.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
269
|
+
M.status = M.sp > 4 ? 0 : 1;
|
|
270
|
+
const { labelEn: N, labelCn: C } = this.parseStatus(M.status), j = {
|
|
271
|
+
mmsi: M.m,
|
|
272
|
+
name: M.n,
|
|
273
|
+
imo: d == null ? void 0 : d.imo,
|
|
274
|
+
lat: M.la,
|
|
275
|
+
lng: M.lo,
|
|
276
|
+
draught: M.draught,
|
|
277
|
+
sog: M.sp,
|
|
278
|
+
cog: M.co,
|
|
279
|
+
hdg: M.hdg,
|
|
280
280
|
positionTime: x.unix(),
|
|
281
281
|
utc: x.utc().format(),
|
|
282
|
-
status:
|
|
282
|
+
status: M.status,
|
|
283
283
|
labelCn: C,
|
|
284
284
|
labelEn: N,
|
|
285
285
|
method: "trajectory",
|
|
286
286
|
vendor: "hifleet"
|
|
287
|
-
},
|
|
288
|
-
|
|
287
|
+
}, T = Math.floor(x.diff(c, "minute", !0) / (n || 1));
|
|
288
|
+
T !== u && (u = T, I.push(j));
|
|
289
289
|
}
|
|
290
|
-
return
|
|
290
|
+
return I;
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
|
-
class
|
|
293
|
+
class mt extends Z {
|
|
294
294
|
constructor(t) {
|
|
295
295
|
super();
|
|
296
296
|
L(this, "token");
|
|
@@ -307,9 +307,9 @@ class ft extends Z {
|
|
|
307
307
|
if (S.info("[%s] fetch realtime position from: %s - %j", r.requestId, n, o), (a == null ? void 0 : a.status) !== 0)
|
|
308
308
|
return a;
|
|
309
309
|
const e = a.data[0];
|
|
310
|
-
for (const
|
|
311
|
-
!isNaN(e[
|
|
312
|
-
const { labelCn:
|
|
310
|
+
for (const p in e)
|
|
311
|
+
!isNaN(e[p]) && Number(e[p]) !== 1 / 0 && (e[p] = Number(e[p]));
|
|
312
|
+
const { labelCn: d, labelEn: i } = await this.parseStatus(e.navistat), m = y.unix(e.lasttime);
|
|
313
313
|
return {
|
|
314
314
|
mmsi: e.ShipID,
|
|
315
315
|
name: e.name,
|
|
@@ -328,14 +328,14 @@ class ft extends Z {
|
|
|
328
328
|
utc: m.utc().format(),
|
|
329
329
|
status: e.navistat,
|
|
330
330
|
labelEn: i,
|
|
331
|
-
labelCn:
|
|
331
|
+
labelCn: d,
|
|
332
332
|
method: "position",
|
|
333
333
|
vendor: "shipxy"
|
|
334
334
|
};
|
|
335
335
|
}
|
|
336
336
|
async trajectory(t, r, o, n, a = !0, e = {}) {
|
|
337
|
-
var
|
|
338
|
-
const
|
|
337
|
+
var c;
|
|
338
|
+
const d = await this.realTimePosition(t, e), i = y(r), m = y(o), g = "https://api.shipxy.com/apicall/GetShipTrack", p = {
|
|
339
339
|
searchParams: {
|
|
340
340
|
id: t,
|
|
341
341
|
k: this.token,
|
|
@@ -344,25 +344,25 @@ class ft extends Z {
|
|
|
344
344
|
btm: i.unix(),
|
|
345
345
|
etm: m.unix()
|
|
346
346
|
}
|
|
347
|
-
},
|
|
348
|
-
if (S.info("[%s] fetch trajectory from: %s - %j", e.requestId,
|
|
349
|
-
return
|
|
350
|
-
const
|
|
351
|
-
let
|
|
352
|
-
for (const
|
|
353
|
-
const v = y.unix(
|
|
354
|
-
imo:
|
|
347
|
+
}, f = await P.get(g, p).json();
|
|
348
|
+
if (S.info("[%s] fetch trajectory from: %s - %j", e.requestId, g, p), (f == null ? void 0 : f.status) !== 0)
|
|
349
|
+
return f;
|
|
350
|
+
const l = f == null ? void 0 : f.points, b = [], I = y.unix((c = l[0]) == null ? void 0 : c.utc);
|
|
351
|
+
let u = -1;
|
|
352
|
+
for (const h of l) {
|
|
353
|
+
const v = y.unix(h.utc), w = {
|
|
354
|
+
imo: d == null ? void 0 : d.imo,
|
|
355
355
|
mmsi: t,
|
|
356
|
-
sog: Math.round(
|
|
357
|
-
cog: Math.round(
|
|
358
|
-
lat: Math.round(
|
|
359
|
-
lng: Math.round(
|
|
356
|
+
sog: Math.round(h.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
357
|
+
cog: Math.round(h.cog / 100 * 100) / 100,
|
|
358
|
+
lat: Math.round(h.lat / 1e6 * 1e5) / 1e5,
|
|
359
|
+
lng: Math.round(h.lon / 1e6 * 1e5) / 1e5,
|
|
360
360
|
positionTime: v.unix(),
|
|
361
361
|
utc: v.utc().format(),
|
|
362
362
|
method: "trajectory",
|
|
363
363
|
vendor: "shipxy"
|
|
364
|
-
},
|
|
365
|
-
|
|
364
|
+
}, M = Math.floor(v.diff(I, "minute", !0) / (n || 1));
|
|
365
|
+
M !== u && (u = M, b.push(w));
|
|
366
366
|
}
|
|
367
367
|
return b;
|
|
368
368
|
}
|
|
@@ -396,11 +396,11 @@ class gt extends Z {
|
|
|
396
396
|
if (S.info("[%s] fetch ship info from: %s - %j", r.requestId, n, o), a.code !== "0")
|
|
397
397
|
return a;
|
|
398
398
|
const e = a.data;
|
|
399
|
-
let
|
|
400
|
-
return t === "407170" && (
|
|
399
|
+
let d = e.imo;
|
|
400
|
+
return t === "407170" && (d = "9198379", S.warn("[%s] ship(%s) imo error: %s, should be %s", r.requestId, t, e.imo, d)), {
|
|
401
401
|
mmsi: e.mmsi,
|
|
402
402
|
name: e.shipnameEn,
|
|
403
|
-
imo:
|
|
403
|
+
imo: d,
|
|
404
404
|
callSign: e.callSign,
|
|
405
405
|
length: e.length,
|
|
406
406
|
width: e.breadth,
|
|
@@ -415,12 +415,12 @@ class gt extends Z {
|
|
|
415
415
|
json: {
|
|
416
416
|
shipId: o
|
|
417
417
|
}
|
|
418
|
-
}, e = "https://api3.myships.com/sp/ships/position/latest",
|
|
418
|
+
}, e = "https://api3.myships.com/sp/ships/position/latest", d = await P.post(e, a).json();
|
|
419
419
|
S.info("[%s] fetch realtime position from: %s - %j", r.requestId, e, a);
|
|
420
|
-
const i =
|
|
421
|
-
for (const
|
|
422
|
-
!isNaN(i[
|
|
423
|
-
const { labelCn: m, labelEn:
|
|
420
|
+
const i = d.data[0];
|
|
421
|
+
for (const l in i)
|
|
422
|
+
!isNaN(i[l]) && Number(i[l]) !== 1 / 0 && (i[l] = Number(i[l]));
|
|
423
|
+
const { labelCn: m, labelEn: g } = await this.parseStatus(i.aisNavStatus), p = y.unix(i.posTime);
|
|
424
424
|
return {
|
|
425
425
|
...n,
|
|
426
426
|
mmsi: t,
|
|
@@ -431,22 +431,22 @@ class gt extends Z {
|
|
|
431
431
|
hdg: Math.round(i.heading * 100) / 100,
|
|
432
432
|
rot: Math.round(i.rot * 100) / 100,
|
|
433
433
|
positionTime: i.posTime,
|
|
434
|
-
utc:
|
|
434
|
+
utc: p.utc().format(),
|
|
435
435
|
status: i.aisNavStatus,
|
|
436
|
-
labelEn:
|
|
436
|
+
labelEn: g,
|
|
437
437
|
labelCn: m,
|
|
438
438
|
method: "position",
|
|
439
439
|
vendor: "myship"
|
|
440
440
|
};
|
|
441
441
|
}
|
|
442
442
|
async trajectory(t, r, o, n, a = !0, e = {}) {
|
|
443
|
-
const
|
|
444
|
-
for (; i.diff(
|
|
445
|
-
await this.trajectoryIn30Day(m,
|
|
446
|
-
return await this.trajectoryIn30Day(m,
|
|
443
|
+
const d = y(r), i = y(o), m = await this.getShipId(t), g = await this.getShipInfo(m), p = [];
|
|
444
|
+
for (; i.diff(d, "day", !0) > 30; )
|
|
445
|
+
await this.trajectoryIn30Day(m, d.unix(), d.add(30, "day").unix(), g, t, n, p);
|
|
446
|
+
return await this.trajectoryIn30Day(m, d.unix(), i.unix(), g, t, n, p), p;
|
|
447
447
|
}
|
|
448
|
-
async trajectoryIn30Day(t, r, o, n, a, e,
|
|
449
|
-
var
|
|
448
|
+
async trajectoryIn30Day(t, r, o, n, a, e, d, i = {}) {
|
|
449
|
+
var I;
|
|
450
450
|
const m = {
|
|
451
451
|
headers: {
|
|
452
452
|
appKey: this.token
|
|
@@ -456,36 +456,36 @@ class gt extends Z {
|
|
|
456
456
|
startTime: r,
|
|
457
457
|
endTime: o
|
|
458
458
|
}
|
|
459
|
-
},
|
|
460
|
-
if (S.info("[%s] fetch trajectory from: %s - %j", i.requestId,
|
|
461
|
-
return S.warn("[%s] invoke myship trajectory failed: %j", i.requestId,
|
|
462
|
-
const
|
|
463
|
-
for (const
|
|
464
|
-
!isNaN(
|
|
465
|
-
const
|
|
459
|
+
}, g = "https://api3.myships.com/sp/ships/position/history", p = await P.post(g, m).json();
|
|
460
|
+
if (S.info("[%s] fetch trajectory from: %s - %j", i.requestId, g, m), p.code !== "0")
|
|
461
|
+
return S.warn("[%s] invoke myship trajectory failed: %j", i.requestId, p), p;
|
|
462
|
+
const f = p.data;
|
|
463
|
+
for (const u in f)
|
|
464
|
+
!isNaN(f[u]) && Number(f[u]) !== 1 / 0 && (f[u] = Number(f[u]));
|
|
465
|
+
const l = y.unix((I = f[0]) == null ? void 0 : I.posTime);
|
|
466
466
|
let b = -1;
|
|
467
|
-
for (const
|
|
468
|
-
const
|
|
467
|
+
for (const u of f) {
|
|
468
|
+
const c = y.unix(u.posTime), h = {
|
|
469
469
|
imo: n == null ? void 0 : n.imo,
|
|
470
470
|
mmsi: a,
|
|
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:
|
|
478
|
-
utc:
|
|
471
|
+
lat: Math.round(u.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
472
|
+
lng: Math.round(u.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
473
|
+
sog: Math.round(u.sog / 10 * 100) / 100,
|
|
474
|
+
cog: Math.round(u.cog / 10 * 100) / 100,
|
|
475
|
+
hdg: Math.round(u.heading * 100) / 100,
|
|
476
|
+
rot: Math.round(u.rot * 100) / 100,
|
|
477
|
+
positionTime: c.unix(),
|
|
478
|
+
utc: c.utc().format(),
|
|
479
479
|
method: "trajectory",
|
|
480
480
|
vendor: "myship"
|
|
481
|
-
}, v = Math.floor(
|
|
482
|
-
v !== b && (b = v,
|
|
481
|
+
}, v = Math.floor(c.diff(l, "minute", !0) / (e || 1));
|
|
482
|
+
v !== b && (b = v, d.push(h));
|
|
483
483
|
}
|
|
484
|
-
return
|
|
484
|
+
return d;
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
487
|
const B = K.getLogger("vessel");
|
|
488
|
-
var et = /* @__PURE__ */ ((
|
|
488
|
+
var et = /* @__PURE__ */ ((k) => (k.NOTICE = "NOTICE", k.WARN = "WARN", k.HEAVY = "HEAVY", k.SEVERE = "SEVERE", k.ERROR = "ERROR", k.FATAL = "FATAL", k))(et || {});
|
|
489
489
|
class st {
|
|
490
490
|
/**
|
|
491
491
|
* 解析告警规则, 多规则场景
|
|
@@ -496,20 +496,20 @@ class st {
|
|
|
496
496
|
* @param options
|
|
497
497
|
*/
|
|
498
498
|
parsePrinciple(s, t = {}) {
|
|
499
|
-
var e,
|
|
499
|
+
var e, d, i;
|
|
500
500
|
B.info("[%s] parse rule: %s", t.requestId, s);
|
|
501
501
|
const r = new RegExp("(?<=\\[)(.+)(?=])", "g"), o = s.match(r) ? (e = s.match(r)) == null ? void 0 : e[0] : void 0, n = o == null ? void 0 : o.split(";");
|
|
502
502
|
if (!n)
|
|
503
503
|
return;
|
|
504
504
|
const a = {};
|
|
505
505
|
for (let m = 0; m < (n == null ? void 0 : n.length); m++) {
|
|
506
|
-
const
|
|
507
|
-
if (m === 0 && !
|
|
506
|
+
const g = (i = (d = n[m].match(r)) == null ? void 0 : d[0]) == null ? void 0 : i.split("],");
|
|
507
|
+
if (m === 0 && !g)
|
|
508
508
|
a.scope = n[0];
|
|
509
|
-
else if (
|
|
510
|
-
for (let
|
|
511
|
-
const
|
|
512
|
-
|
|
509
|
+
else if (g)
|
|
510
|
+
for (let p = 0, f = g.length; p < f; p++) {
|
|
511
|
+
const l = this.parseRule(g[p]);
|
|
512
|
+
l && (a[l.level] ? l.key ? a[l.level][l == null ? void 0 : l.key] = l : a[l.level] = l : l.key ? a[l.level] = { [l == null ? void 0 : l.key]: l } : a[l.level] = l);
|
|
513
513
|
}
|
|
514
514
|
}
|
|
515
515
|
return a;
|
|
@@ -540,18 +540,18 @@ class st {
|
|
|
540
540
|
* @param options
|
|
541
541
|
*/
|
|
542
542
|
checkWeather(s, t, r = {}) {
|
|
543
|
-
var
|
|
543
|
+
var l, b, I, u, c, h, v, w, M, x, N, C, j, T, A;
|
|
544
544
|
let o = 0, n = 0, a = 0, e = 0;
|
|
545
|
-
const
|
|
545
|
+
const d = Math.round(((b = (l = t == null ? void 0 : t.SEVERE) == null ? void 0 : l.sigWave) == null ? void 0 : b.number) * 1.6 * 100) / 100, i = (u = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : u.number, m = (h = (c = t == null ? void 0 : t.HEAVY) == null ? void 0 : c.sigWave) == null ? void 0 : h.number, g = Math.round((((w = (v = t == null ? void 0 : t.SEVERE) == null ? void 0 : v.wind) == null ? void 0 : w.number) + 2) * 100) / 100, p = (x = (M = t == null ? void 0 : t.SEVERE) == null ? void 0 : M.wind) == null ? void 0 : x.number, f = (C = (N = t == null ? void 0 : t.HEAVY) == null ? void 0 : N.wind) == null ? void 0 : C.number;
|
|
546
546
|
for (let O = 0; O < (s == null ? void 0 : s.length); O++) {
|
|
547
|
-
const
|
|
548
|
-
e = W > e ? W : e, B.info("[%s] check sig.wave: %j", r.requestId, { ...E, dgThd4Wv:
|
|
547
|
+
const Y = s[O], E = (T = (j = Y == null ? void 0 : Y.meteo) == null ? void 0 : j.wave) == null ? void 0 : T.sig, q = (A = Y == null ? void 0 : Y.meteo) == null ? void 0 : A.wind, W = O ? y(Y.eta).diff(y(s[O - 1].eta), "hour", !0) : 0;
|
|
548
|
+
e = W > e ? W : e, B.info("[%s] check sig.wave: %j", r.requestId, { ...E, dgThd4Wv: d, svThd4Wv: i, hvThd4Wv: m }), (E == null ? void 0 : E.height) >= d ? Y.isDangerous = !0 : (E == null ? void 0 : E.height) >= i ? Y.isSevere = !0 : (E == null ? void 0 : E.height) >= m && (Y.isHeavy = !0), B.info("[%s] check wind: %j", r.requestId, { ...q, dgThd4Wd: g, svThd4Wd: p, hvThd4Wd: f }), (q == null ? void 0 : q.scale) >= g ? (Y.isDangerous = !0, delete Y.isSevere, delete Y.isHeavy) : (q == null ? void 0 : q.scale) > p ? (Y.isDangerous || (Y.isSevere = !0), delete Y.isHeavy) : (q == null ? void 0 : q.scale) === f && !Y.isDangerous && !Y.isSevere && (Y.isHeavy = !0), o += Y.isDangerous ? W : 0, n += Y.isSevere ? W : 0, a += Y.isHeavy ? W : 0;
|
|
549
549
|
}
|
|
550
|
-
return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, a = Math.round(a * 100) / 100, e = Math.round(e), { sample: s, dangerous: o, severe: n, heavy: a, step: e < 3 ? 3 : e, wind: { dgThd4Wd:
|
|
550
|
+
return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, a = Math.round(a * 100) / 100, e = Math.round(e), { sample: s, dangerous: o, severe: n, heavy: a, step: e < 3 ? 3 : e, wind: { dgThd4Wd: g, svThd4Wd: p, hvThd4Wd: f }, sig: { dgThd4Wv: d, svThd4Wv: i, hvThd4Wv: m } };
|
|
551
551
|
}
|
|
552
552
|
}
|
|
553
|
-
const
|
|
554
|
-
var at = /* @__PURE__ */ ((
|
|
553
|
+
const pt = new st(), V = K.getLogger("vessel");
|
|
554
|
+
var at = /* @__PURE__ */ ((k) => (k.common = "common", k.container = "container", k))(at || {}), ot = /* @__PURE__ */ ((k) => (k.Ballast = "Ballast", k.Laden = "Laden", k))(ot || {}), nt = /* @__PURE__ */ ((k) => (k.Cp = "CP", k.Perf = "Basis", k.Instruct = "Other", k))(nt || {});
|
|
555
555
|
class H {
|
|
556
556
|
/**
|
|
557
557
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
@@ -568,7 +568,7 @@ class H {
|
|
|
568
568
|
static blockCoefficient(s, t, r, o) {
|
|
569
569
|
let n = Math.round(s / (t * r * o) * 100) / 100;
|
|
570
570
|
n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
|
|
571
|
-
const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = a.map((
|
|
571
|
+
const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = a.map((d) => Math.abs(d - n));
|
|
572
572
|
return a[e.indexOf(Math.min(...e))];
|
|
573
573
|
}
|
|
574
574
|
/**
|
|
@@ -662,18 +662,18 @@ class H {
|
|
|
662
662
|
* @private
|
|
663
663
|
*/
|
|
664
664
|
static assembleProperties(s, t, r, o) {
|
|
665
|
-
var m,
|
|
666
|
-
const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, a = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572,
|
|
665
|
+
var m, g;
|
|
666
|
+
const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, a = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, d = s.deadweight ?? 67035.7773;
|
|
667
667
|
return {
|
|
668
668
|
// @ts-ignore
|
|
669
|
-
tag: ((
|
|
669
|
+
tag: ((g = (m = s == null ? void 0 : s.type) == null ? void 0 : m.toLowerCase()) == null ? void 0 : g.indexOf("container")) > -1 ? "container" : "common",
|
|
670
670
|
lbp: n,
|
|
671
671
|
loadCondition: t,
|
|
672
672
|
draught: a,
|
|
673
673
|
breadthMoulded: e,
|
|
674
674
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
675
675
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
676
|
-
displacement: Math.round((
|
|
676
|
+
displacement: Math.round((d / 1.025 + a * e * n * 0.7) * 1e4) / 1e4,
|
|
677
677
|
// 换算为m/s
|
|
678
678
|
speed: Math.round((r ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
679
679
|
bearing: o || 90
|
|
@@ -690,15 +690,15 @@ class H {
|
|
|
690
690
|
*/
|
|
691
691
|
static async speedLoseAt(s, t, r, o = "", n = 2, a = !1, e = {}) {
|
|
692
692
|
t.velocity && !t.noFactor && a && (s.speed = _.roundPrecision(t.velocity * 1852 / 3600, 6));
|
|
693
|
-
const
|
|
694
|
-
meteo: { ...
|
|
693
|
+
const d = await tt.queryPointFactor(t.lng, t.lat, r.valueOf(), "wind,wave,current,watertemp", o, e), i = H.weatherFactor(s, d), m = H.currentFactor(s.bearing, d == null ? void 0 : d.current, n), g = {
|
|
694
|
+
meteo: { ...d },
|
|
695
695
|
wxFactor: i,
|
|
696
696
|
cFactor: m,
|
|
697
697
|
speed: t.velocity && a ? t.velocity : Math.round((s.speed * 1.943844 + i + m) * 100) / 100,
|
|
698
698
|
eta: r.utc().format("YYYY-MM-DDTHH:mm[Z]"),
|
|
699
699
|
etd: r.utc().format("YYYY-MM-DDTHH:mm[Z]")
|
|
700
700
|
};
|
|
701
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
701
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...g, ...t };
|
|
702
702
|
}
|
|
703
703
|
/**
|
|
704
704
|
* 基于步长计算失速样本
|
|
@@ -712,52 +712,52 @@ class H {
|
|
|
712
712
|
* @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
|
|
713
713
|
* @private
|
|
714
714
|
*/
|
|
715
|
-
static async speedLoseInHoursStep(s, t, r, o, n, a, e = "",
|
|
715
|
+
static async speedLoseInHoursStep(s, t, r, o, n, a, e = "", d = !1, i = {}) {
|
|
716
716
|
t.utc();
|
|
717
|
-
const m = [],
|
|
718
|
-
let
|
|
719
|
-
for (let
|
|
720
|
-
let
|
|
721
|
-
|
|
722
|
-
const
|
|
723
|
-
if (s.bearing = R.calculateBearing(
|
|
724
|
-
|
|
725
|
-
const
|
|
726
|
-
if (o -
|
|
727
|
-
o = o -
|
|
717
|
+
const m = [], g = [];
|
|
718
|
+
let p = 0, f = 0, l, b;
|
|
719
|
+
for (let I = 0; I < a.length - 1; I++) {
|
|
720
|
+
let u = a[I];
|
|
721
|
+
u.distanceFromStart = n + f;
|
|
722
|
+
const c = a[I + 1];
|
|
723
|
+
if (s.bearing = R.calculateBearing(u, c, !c.gcToPrevious), u.bearing = s.bearing, u.suspend && d) {
|
|
724
|
+
u.eta = u.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), u.elapsed = u.elapsed ?? 0;
|
|
725
|
+
const w = u.suspend - u.elapsed;
|
|
726
|
+
if (o - p > w)
|
|
727
|
+
o = o - p - w, t.add(w, "hour"), u.elapsed = u.suspend;
|
|
728
728
|
else {
|
|
729
|
-
const
|
|
730
|
-
|
|
729
|
+
const M = o - p;
|
|
730
|
+
u.elapsed += M, t.add(M, "hour"), o = 0;
|
|
731
731
|
}
|
|
732
|
-
if (V.info(`[%s] suspend ${
|
|
733
|
-
return
|
|
732
|
+
if (V.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${o} hours need to go...`, i.requestId, u), o === 0)
|
|
733
|
+
return u.distanceFromPrevious = f, { etd: t, from: b || u, to: u, next: a.filter((M) => M), wps: m, days: g };
|
|
734
734
|
}
|
|
735
|
-
|
|
736
|
-
const
|
|
737
|
-
let v = Math.ceil(
|
|
738
|
-
if (
|
|
739
|
-
if (
|
|
740
|
-
`[%s] go to %j from %j with ${
|
|
735
|
+
u = await H.speedLoseAt(s, u, t, e, 0, d, i), b = b || u, u.important && m.push(u), t.isSameOrAfter(r) && (g.push(u), r.add(24, "hour"));
|
|
736
|
+
const h = R.calculateDistance(u, c, !c.gcToPrevious);
|
|
737
|
+
let v = Math.ceil(h / b.speed * 1e4) / 1e4;
|
|
738
|
+
if (p + v < o) {
|
|
739
|
+
if (p += v, t.add(v, "hour"), delete a[I], V.info(
|
|
740
|
+
`[%s] go to %j from %j with ${h}nm, and cost ${v} hours`,
|
|
741
741
|
i.requestId,
|
|
742
|
-
{ lat:
|
|
742
|
+
{ lat: c.lat, lng: c.lng },
|
|
743
743
|
{ lat: b.lat, lng: b.lng, etd: b.etd }
|
|
744
|
-
),
|
|
745
|
-
|
|
744
|
+
), f += h, a.filter((w) => w).length <= 1) {
|
|
745
|
+
l = c, l.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), l.distanceFromPrevious = h, l.distanceFromStart = n + f, m.push(l), delete a[I + 1];
|
|
746
746
|
break;
|
|
747
747
|
}
|
|
748
748
|
} else {
|
|
749
|
-
v = o -
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
`[%s] go to %j from %j with ${
|
|
749
|
+
v = o - p, t.add(v, "hour");
|
|
750
|
+
const w = _.roundPrecision(b.speed * v, 4);
|
|
751
|
+
l = R.calculateCoordinate(u, s.bearing, w, "nauticalmiles", !c.gcToPrevious), l.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[I] = l, V.info(
|
|
752
|
+
`[%s] go to %j from %j with ${w}nm, and cost ${v} hours`,
|
|
753
753
|
i.requestId,
|
|
754
|
-
{ lat:
|
|
755
|
-
{ lat:
|
|
756
|
-
),
|
|
754
|
+
{ lat: l.lat, lng: l.lng },
|
|
755
|
+
{ lat: u.lat, lng: u.lng, etd: u.etd }
|
|
756
|
+
), f += w, l.distanceFromPrevious = f, l.distanceFromStart = n + f;
|
|
757
757
|
break;
|
|
758
758
|
}
|
|
759
759
|
}
|
|
760
|
-
return { etd: t, from: b, to:
|
|
760
|
+
return { etd: t, from: b, to: l, next: a.filter((I) => I), wps: m, days: g };
|
|
761
761
|
}
|
|
762
762
|
/**
|
|
763
763
|
* 洋流影响因子
|
|
@@ -778,15 +778,15 @@ class H {
|
|
|
778
778
|
* @param wwc 气象要素
|
|
779
779
|
*/
|
|
780
780
|
static weatherFactor(s, t) {
|
|
781
|
-
var
|
|
781
|
+
var g, p, f, l, b;
|
|
782
782
|
V.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
783
783
|
const r = H.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), o = H.froudeNumber(s.speed, s.lbp), n = H.amendFactor(r, o, s.loadCondition);
|
|
784
|
-
let a = Math.abs(s.bearing % 360 - (((
|
|
784
|
+
let a = Math.abs(s.bearing % 360 - (((g = t == null ? void 0 : t.wind) == null ? void 0 : g.degree) % 360 || 0));
|
|
785
785
|
a = a > 180 ? 360 - a : a;
|
|
786
|
-
const e = H.directionFactor(a, (
|
|
787
|
-
let i = e * n *
|
|
786
|
+
const e = H.directionFactor(a, (p = t == null ? void 0 : t.wind) == null ? void 0 : p.scale), d = H.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (f = t == null ? void 0 : t.wind) == null ? void 0 : f.scale);
|
|
787
|
+
let i = e * n * d / 100 * s.speed;
|
|
788
788
|
i = Math.round(i * 1.943844 * 1e4) / 1e4 * -1;
|
|
789
|
-
const m = H.waveHeightFactor(((b = (
|
|
789
|
+
const m = H.waveHeightFactor(((b = (l = t == null ? void 0 : t.wave) == null ? void 0 : l.sig) == null ? void 0 : b.height) ?? 1);
|
|
790
790
|
return i = i * 0.24 + m * 0.76, V.debug("weather factor = %s", i), Math.round(i * 100) / 100;
|
|
791
791
|
}
|
|
792
792
|
/**
|
|
@@ -800,14 +800,14 @@ class H {
|
|
|
800
800
|
* @param stepHrs 样本步长, 0表示动态计算(6 or 3 hrs)
|
|
801
801
|
* @param useRouteParam
|
|
802
802
|
*/
|
|
803
|
-
static async analyseInstant(s, t, r, o, n, a = "", e = 0,
|
|
803
|
+
static async analyseInstant(s, t, r, o, n, a = "", e = 0, d = !1, i = {}) {
|
|
804
804
|
var E, q, W, z, G;
|
|
805
805
|
const m = y().valueOf();
|
|
806
806
|
s.lng = _.convertToStdLng(s.lng);
|
|
807
|
-
const { route:
|
|
808
|
-
if (((E =
|
|
807
|
+
const { route: g, waypoints: p } = n.points, f = R.calculateSubRoute(s, g);
|
|
808
|
+
if (((E = f[0]) == null ? void 0 : E.length) <= 1)
|
|
809
809
|
return;
|
|
810
|
-
const { v0:
|
|
810
|
+
const { v0: l, label: b } = s.sog ? {
|
|
811
811
|
v0: s.sog,
|
|
812
812
|
label: "Other"
|
|
813
813
|
/* Instruct */
|
|
@@ -815,40 +815,40 @@ class H {
|
|
|
815
815
|
v0: o.speed,
|
|
816
816
|
label: "CP"
|
|
817
817
|
/* Cp */
|
|
818
|
-
},
|
|
818
|
+
}, I = H.assembleProperties(r, o.loadCondition, l, 0), u = p.length ? R.calculateSubWaypoints(s, p) : [], c = {
|
|
819
819
|
from: { ...s },
|
|
820
|
-
route:
|
|
821
|
-
waypoints:
|
|
822
|
-
v0:
|
|
820
|
+
route: f,
|
|
821
|
+
waypoints: u,
|
|
822
|
+
v0: l,
|
|
823
823
|
label: b
|
|
824
|
-
},
|
|
824
|
+
}, h = {
|
|
825
825
|
hours: [],
|
|
826
826
|
days: [],
|
|
827
827
|
wps: []
|
|
828
828
|
};
|
|
829
|
-
e || (R.calculateRouteDistance(
|
|
830
|
-
let v = R.simplifyRouteToCoordinates(
|
|
829
|
+
e || (R.calculateRouteDistance(f) / o.speed <= 72 ? e = 3 : e = 6);
|
|
830
|
+
let v = R.simplifyRouteToCoordinates(f, u, 0), w = 0, M = 0, x = 0, N = 0;
|
|
831
831
|
t = y(t).utc();
|
|
832
832
|
const C = t.clone();
|
|
833
833
|
for (; v.length > 0; ) {
|
|
834
|
-
const F = e - t.hour() % e, $ = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, D = await H.speedLoseInHoursStep(
|
|
835
|
-
(q = D.from) != null && q.speed && (
|
|
834
|
+
const F = e - t.hour() % e, $ = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, D = await H.speedLoseInHoursStep(I, t, C, $, w, v, a, d, i);
|
|
835
|
+
(q = D.from) != null && q.speed && (h.hours.push(D.from), h.wps.push(...D.wps), h.days.push(...D.days)), v = D == null ? void 0 : D.next, v.length || h.hours.push(D == null ? void 0 : D.to), w += ((W = D == null ? void 0 : D.to) == null ? void 0 : W.distanceFromPrevious) ?? 0;
|
|
836
836
|
}
|
|
837
|
-
const
|
|
838
|
-
for (let F = 0; F <
|
|
839
|
-
const $ = y(
|
|
840
|
-
|
|
837
|
+
const j = h.hours;
|
|
838
|
+
for (let F = 0; F < j.length - 1; F++) {
|
|
839
|
+
const $ = y(j[F + 1].eta).diff(j[F].etd, "hour", !0) || 1;
|
|
840
|
+
M += j[F].wxFactor * $, x += j[F].cFactor * $, N += $;
|
|
841
841
|
}
|
|
842
|
-
(z =
|
|
842
|
+
(z = h.wps) == null || z.forEach((F, $) => {
|
|
843
843
|
if ($) {
|
|
844
|
-
const D =
|
|
844
|
+
const D = h.wps[$ - 1], J = F.distanceFromStart - D.distanceFromStart, U = y(F.eta).diff(y(D.etd), "h", !0);
|
|
845
845
|
U < 1 ? F.avgSpd = D.speed : F.avgSpd = Math.round(J / U * 100) / 100;
|
|
846
846
|
}
|
|
847
|
-
}),
|
|
848
|
-
const
|
|
849
|
-
|
|
850
|
-
const O = y().valueOf() - m,
|
|
851
|
-
return V.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", i == null ? void 0 : i.requestId, O,
|
|
847
|
+
}), c.sample = h;
|
|
848
|
+
const T = h.hours.at(-1);
|
|
849
|
+
c.distance = Math.round(T.distanceFromStart * 1e4) / 1e4, c.eta = y(T.eta).toDate(), c.wxFactor = Math.round(M / N * 1e4) / 1e4, c.cFactor = Math.round(x / N * 1e4) / 1e4, c.avgSpeed = Math.round(T.distanceFromStart / N * 1e4) / 1e4, c.totalHrs = Math.round(N * 1e4) / 1e4, c.totalFoCons = Math.round((o == null ? void 0 : o.fo) / 24 * c.totalHrs * 1e3) / 1e3, c.totalDgoCons = Math.round((o == null ? void 0 : o.dgo) / 24 * c.totalHrs * 1e3) / 1e3;
|
|
850
|
+
const O = y().valueOf() - m, Y = ((G = h == null ? void 0 : h.hours) == null ? void 0 : G.length) || 1;
|
|
851
|
+
return V.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", i == null ? void 0 : i.requestId, O, Y, Math.round(O / Y * 1e3) / 1e3), c;
|
|
852
852
|
}
|
|
853
853
|
/**
|
|
854
854
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -861,43 +861,46 @@ class H {
|
|
|
861
861
|
* @param source 气象数据源,GFS or CMEMES, 默认CMEMS
|
|
862
862
|
* @param stepHrs
|
|
863
863
|
*/
|
|
864
|
-
static async analyseInstantWithThreshed(s, t, r, o, n, a, e = "",
|
|
864
|
+
static async analyseInstantWithThreshed(s, t, r, o, n, a, e = "", d = 3, i = !1, m = {}) {
|
|
865
865
|
var x, N, C;
|
|
866
866
|
s.lng = _.convertToStdLng(s.lng);
|
|
867
|
-
const
|
|
868
|
-
if (((x =
|
|
867
|
+
const g = H.assembleProperties(o, n.loadCondition, n.speed, 0), p = R.calculateSubRoute(s, a);
|
|
868
|
+
if (((x = p[0]) == null ? void 0 : x.length) <= 1)
|
|
869
869
|
return;
|
|
870
|
-
let
|
|
871
|
-
|
|
870
|
+
let f = R.simplifyRouteToCoordinates(p, [], 0);
|
|
871
|
+
f.forEach((j) => j.important = !0);
|
|
872
|
+
let l = 0, b = 0, I = 0, u = 0, c;
|
|
873
|
+
const h = {
|
|
872
874
|
hours: [],
|
|
875
|
+
wps: [],
|
|
873
876
|
days: []
|
|
874
877
|
};
|
|
875
|
-
for (t = y(t).utc();
|
|
876
|
-
const
|
|
877
|
-
let
|
|
878
|
-
if (
|
|
879
|
-
|
|
878
|
+
for (t = y(t).utc(); f.length > 0; ) {
|
|
879
|
+
const j = d - t.hour() % d;
|
|
880
|
+
let T = Math.ceil(t.clone().add(j, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
881
|
+
if (T = t.clone().add(T, "h").isAfter(r) ? r.diff(t, "h", !0) * 1e4 / 1e4 : T, T)
|
|
882
|
+
c = await H.speedLoseInHoursStep(g, t, r.clone(), T, l, f, e, i, m), (N = c.from) != null && N.speed && (h.hours.push(c.from), c != null && c.wps && h.wps.push(...c.wps), h.days.push(...c.days)), f = c == null ? void 0 : c.next, f.length || (h.hours.push(c == null ? void 0 : c.to), c != null && c.wps && h.wps.push(...c.wps), h.days.push(c == null ? void 0 : c.to)), l += ((C = c == null ? void 0 : c.to) == null ? void 0 : C.distanceFromPrevious) ?? 0;
|
|
880
883
|
else {
|
|
881
|
-
|
|
884
|
+
c && (h.hours.push(c.to), c != null && c.wps && h.wps.push(...c.wps), h.days.push(c.to));
|
|
882
885
|
break;
|
|
883
886
|
}
|
|
884
887
|
}
|
|
885
|
-
const v =
|
|
886
|
-
for (let
|
|
887
|
-
const
|
|
888
|
-
b += v[
|
|
888
|
+
const v = h.hours;
|
|
889
|
+
for (let j = 0; j < v.length - 1; j++) {
|
|
890
|
+
const T = y(v[j + 1].eta).diff(v[j].etd, "hour", !0);
|
|
891
|
+
b += v[j].wxFactor * T, I += v[j].cFactor * T, u += T;
|
|
889
892
|
}
|
|
890
|
-
const
|
|
893
|
+
const w = h.hours.at(-1);
|
|
891
894
|
return {
|
|
892
|
-
sample:
|
|
893
|
-
distance: Math.round(((
|
|
894
|
-
eta: y(
|
|
895
|
-
wxFactor: Math.round(b /
|
|
896
|
-
cFactor: Math.round(
|
|
897
|
-
avgSpeed: Math.round(((
|
|
898
|
-
totalHrs: Math.round(
|
|
899
|
-
to:
|
|
900
|
-
route: R.generateRouteAccordingToWaypoints(
|
|
895
|
+
sample: h,
|
|
896
|
+
distance: Math.round(((w == null ? void 0 : w.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
897
|
+
eta: y(w == null ? void 0 : w.eta).utc().format(),
|
|
898
|
+
wxFactor: Math.round(b / u * 1e4) / 1e4,
|
|
899
|
+
cFactor: Math.round(I / u * 1e4) / 1e4,
|
|
900
|
+
avgSpeed: Math.round(((w == null ? void 0 : w.distanceFromStart) || 0) / u * 1e4) / 1e4,
|
|
901
|
+
totalHrs: Math.round(u * 1e4) / 1e4,
|
|
902
|
+
to: w,
|
|
903
|
+
route: R.generateRouteAccordingToWaypoints(f)
|
|
901
904
|
};
|
|
902
905
|
}
|
|
903
906
|
}
|
|
@@ -905,13 +908,13 @@ export {
|
|
|
905
908
|
Z as AISImpl,
|
|
906
909
|
st as AlertHelper,
|
|
907
910
|
et as AlertLevel,
|
|
908
|
-
|
|
911
|
+
ft as HifleetImpl,
|
|
909
912
|
ot as LoadCondition,
|
|
910
913
|
gt as MyShipImpl,
|
|
911
914
|
lt as MyVesselImpl,
|
|
912
|
-
|
|
915
|
+
mt as ShipxyImpl,
|
|
913
916
|
H as SpeedHelper,
|
|
914
917
|
nt as SpeedLabel,
|
|
915
918
|
at as VesselTag,
|
|
916
|
-
|
|
919
|
+
pt as alertHelper
|
|
917
920
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(j,w){typeof exports=="object"&&typeof module<"u"?w(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo","@idm-plugin/meteo"],w):(j=typeof globalThis<"u"?globalThis:j||self,w(j["idm-plugin-rabbitmq"]={},j.got,j["@log4js-node/log4js-api"],j.moment,j["@idm-plugin/geo"],j["@idm-plugin/meteo"]))})(this,function(j,w,R,y,x,st){"use strict";var dt=Object.defineProperty;var ut=(j,w,R)=>w in j?dt(j,w,{enumerable:!0,configurable:!0,writable:!0,value:R}):j[w]=R;var _=(j,w,R)=>(ut(j,typeof w!="symbol"?w+"":w,R),R);const D=R.getLogger("vessel");class Z{parseStatus(a){let t,i;switch(a){case 0:t="在航(主机推动)",i="The engine is in use";break;case 1:t="锚泊",i="Anchored";break;case 2:t="失控",i="Not operated";break;case 3:t="操纵受限",i="Limited airworthiness";break;case 4:t="吃水受限",i="Limited by ship's draft";break;case 5:t="靠泊",i="Mooring";break;case 6:t="搁浅",i="Stranded";break;case 7:t="捕捞作业",i="Engaged in fishing";break;case 8:t="靠帆船提供动力",i="Sailing";break;default:t="未定义",i="Undefined"}return{labelCn:t,labelEn:i}}}class at extends Z{constructor(t,i){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await w.post(i,o).json();D.info("[%s] fetch access token from: %s - %j",t.requestId,i,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:y().utc().format()})}async realTimePosition(t,i={}){var f,m,p;(!this.token||y().diff(y(this.token.issuedAt),"seconds")>((f=this.token)==null?void 0:f.expiresIn)-300)&&await this.authToken(i);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(p=this.token)==null?void 0:p.accessToken}`},searchParams:{mmsi:t}};D.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n);const s=await w.get(o,n).json();if(s.code)return D.warn("[%s] fetch realtime position failed: %j",i.requestId,o,{message:s.message,status:s.status,code:s.code}),s;const e=s.data;for(const l in e)!isNaN(e[l])&&Number(e[l])!==1/0&&(e[l]=Number(e[l]));const c=y(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName,imo:e.imo,callSign:e.callsign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:e.eta,destination:e.dest,positionTime:c.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,method:"position",vendor:"myVessel",utc:c.utc().format()}}async trajectory(t,i,o,n,s=!0,e={}){(!this.token||y().diff(y(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const c=await this.realTimePosition(t,e),r=y(i),f=y(o),m=[];for(;f.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),c,n,m,e),r.add(30,"day");return await this.trajectoryIn30Day(t,r,f,c,n,m,e),m}async trajectoryIn30Day(t,i,o,n,s,e,c={}){var u,b,k,d,g;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",f={headers:{Authorization:`${(u=this.token)==null?void 0:u.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};D.info("[%s] fetch trajectory from: %s - %j",c.requestId,r,f);const m=await w.post(r,f).json();if(m.code)return D.warn("[%s] fetch trajectory failed: %j",c.requestId,r,{message:m.message,status:m.status,code:m.code}),m;let p=-1;const l=y(`${(d=(k=m.data)==null?void 0:k[0])==null?void 0:d.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=m.data)==null||g.forEach(h=>{for(const H in h)!isNaN(h[H])&&Number(h[H])!==1/0&&(h[H]=Number(h[H]));const v=y(`${h.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),I=h.eta?y(`${h.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,M=h.status,{labelCn:E,labelEn:q}=this.parseStatus(M),A={mmsi:h.mmsi,imo:n==null?void 0:n.imo,lat:h.lat,lng:h.lon,sog:h.sog,cog:h.cog,hdg:h.hdg,draught:h.draught,status:M,eta:I==null?void 0:I.unix(),destination:h.dest,positionTime:v.unix(),labelCn:E,labelEn:q,method:"trajectory",vendor:"myVessel",utc:v.utc().format()},S=Math.floor(v.diff(l,"minute",!0)/(s||1));S!==p&&(p=S,e.push(A))}),e}}class ot extends Z{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,i={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},s=await w.post(o,n).json();D.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n);const e=s==null?void 0:s.list;if(!e)return D.warn("[%s] fetch realtime position failed: %j",i.requestId,o,s),s;for(const l in e)!isNaN(e[l])&&Number(e[l])!==1/0&&(e[l]=Number(e[l]));e.status=e.sp>3?0:1;const c=e.status,{labelCn:r,labelEn:f}=this.parseStatus(c),m=y(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?y(`${e.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:e.destination,positionTime:m.unix(),utc:m.utc().format(),status:c,labelCn:r,labelEn:f,method:"position",vendor:"hifleet"}}async search(t,i={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let s=await w.post(o,n).json();D.info("[%s] fetch vessel props from: %s - %j",i.requestId,o,n),s instanceof Array&&(s=s[0]);for(const c in s)!isNaN(s[c])&&Number(s[c])!==1/0&&(s[c]=Number(s[c]));const e={mmsi:s.m,name:s.n,imo:s.i,callSign:s.c,length:s.l,breadth:s.b,draught:s.dr};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",s=await w.post(o,n).json(),D.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,o,n),s instanceof Array&&(s=s[0]),s&&(e.deadweight=Number(s.dwt)),e}async trajectory(t,i,o,n,s=!0,e={}){var h,v,I;const c=await this.realTimePosition(t,e);let r=y(i);const f=y(o),m=y();if(s){let M=f.diff(r,"d",!0);M<0?r=f.clone().subtract(40,"d"):M<30?r.subtract(10,"d"):M<60?r.subtract(5,"d"):r=f.clone().subtract(80,"d"),M=m.diff(f,"d",!0),f.add(M>10?240:M*24,"h")}const p={searchParams:{endtime:f.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},l="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",u=await w.get(l,p).json();D.info("[%s] fetch trajectory from: %s - %j",e.requestId,l,p);let b;u&&(b=((v=(h=u.ships)==null?void 0:h.offors)==null?void 0:v.ship)||[],b.length||D.warn("[%s] fetch trajectory failed: %j",e.requestId,u));const k=[];let d=-1;const g=y(`${(I=b==null?void 0:b[0])==null?void 0:I.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const M of b){for(const O in M)!isNaN(M[O])&&Number(M[O])!==1/0&&(M[O]=Number(M[O]));const E=y(`${M.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");M.status=M.sp>4?0:1;const{labelEn:q,labelCn:A}=this.parseStatus(M.status),S={mmsi:M.m,name:M.n,imo:c==null?void 0:c.imo,lat:M.la,lng:M.lo,draught:M.draught,sog:M.sp,cog:M.co,hdg:M.hdg,positionTime:E.unix(),utc:E.utc().format(),status:M.status,labelCn:A,labelEn:q,method:"trajectory",vendor:"hifleet"},H=Math.floor(E.diff(g,"minute",!0)/(n||1));H!==d&&(d=H,k.push(S))}return k}}class nt extends Z{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,i={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",s=await w.get(n,o).json();if(D.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o),(s==null?void 0:s.status)!==0)return s;const e=s.data[0];for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const{labelCn:c,labelEn:r}=await this.parseStatus(e.navistat),f=y.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:f.utc().format(),status:e.navistat,labelEn:r,labelCn:c,method:"position",vendor:"shipxy"}}async trajectory(t,i,o,n,s=!0,e={}){var g;const c=await this.realTimePosition(t,e),r=y(i),f=y(o),m="https://api.shipxy.com/apicall/GetShipTrack",p={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:f.unix()}},l=await w.get(m,p).json();if(D.info("[%s] fetch trajectory from: %s - %j",e.requestId,m,p),(l==null?void 0:l.status)!==0)return l;const u=l==null?void 0:l.points,b=[],k=y.unix((g=u[0])==null?void 0:g.utc);let d=-1;for(const h of u){const v=y.unix(h.utc),I={imo:c==null?void 0:c.imo,mmsi:t,sog:Math.round(h.sog*3600/1e3/1852*100)/100,cog:Math.round(h.cog/100*100)/100,lat:Math.round(h.lat/1e6*1e5)/1e5,lng:Math.round(h.lon/1e6*1e5)/1e5,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"shipxy"},M=Math.floor(v.diff(k,"minute",!0)/(n||1));M!==d&&(d=M,b.push(I))}return b}}class it extends Z{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,i={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",s=await w.post(n,o).json();return D.info("[%s] fetch ship id from: %s - %j",i.requestId,n,o),s.code!=="0"?s:s.data[0].shipId}async getShipInfo(t,i={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",s=await w.post(n,o).json();if(D.info("[%s] fetch ship info from: %s - %j",i.requestId,n,o),s.code!=="0")return s;const e=s.data;let c=e.imo;return t==="407170"&&(c="9198379",D.warn("[%s] ship(%s) imo error: %s, should be %s",i.requestId,t,e.imo,c)),{mmsi:e.mmsi,name:e.shipnameEn,imo:c,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,i={}){const o=await this.getShipId(t,i),n=await this.getShipInfo(o,i),s={headers:{appKey:this.token},json:{shipId:o}},e="https://api3.myships.com/sp/ships/position/latest",c=await w.post(e,s).json();D.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,s);const r=c.data[0];for(const u in r)!isNaN(r[u])&&Number(r[u])!==1/0&&(r[u]=Number(r[u]));const{labelCn:f,labelEn:m}=await this.parseStatus(r.aisNavStatus),p=y.unix(r.posTime);return{...n,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:p.utc().format(),status:r.aisNavStatus,labelEn:m,labelCn:f,method:"position",vendor:"myship"}}async trajectory(t,i,o,n,s=!0,e={}){const c=y(i),r=y(o),f=await this.getShipId(t),m=await this.getShipInfo(f),p=[];for(;r.diff(c,"day",!0)>30;)await this.trajectoryIn30Day(f,c.unix(),c.add(30,"day").unix(),m,t,n,p);return await this.trajectoryIn30Day(f,c.unix(),r.unix(),m,t,n,p),p}async trajectoryIn30Day(t,i,o,n,s,e,c,r={}){var k;const f={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:o}},m="https://api3.myships.com/sp/ships/position/history",p=await w.post(m,f).json();if(D.info("[%s] fetch trajectory from: %s - %j",r.requestId,m,f),p.code!=="0")return D.warn("[%s] invoke myship trajectory failed: %j",r.requestId,p),p;const l=p.data;for(const d in l)!isNaN(l[d])&&Number(l[d])!==1/0&&(l[d]=Number(l[d]));const u=y.unix((k=l[0])==null?void 0:k.posTime);let b=-1;for(const d of l){const g=y.unix(d.posTime),h={imo:n==null?void 0:n.imo,mmsi:s,lat:Math.round(d.lat/1e4/60*1e5)/1e5,lng:Math.round(d.lon/1e4/60*1e5)/1e5,sog:Math.round(d.sog/10*100)/100,cog:Math.round(d.cog/10*100)/100,hdg:Math.round(d.heading*100)/100,rot:Math.round(d.rot*100)/100,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"myship"},v=Math.floor(g.diff(u,"minute",!0)/(e||1));v!==b&&(b=v,c.push(h))}return c}}const K=R.getLogger("vessel");var z=(Y=>(Y.NOTICE="NOTICE",Y.WARN="WARN",Y.HEAVY="HEAVY",Y.SEVERE="SEVERE",Y.ERROR="ERROR",Y.FATAL="FATAL",Y))(z||{});class G{parsePrinciple(a,t={}){var e,c,r;K.info("[%s] parse rule: %s",t.requestId,a);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),o=a.match(i)?(e=a.match(i))==null?void 0:e[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const s={};for(let f=0;f<(n==null?void 0:n.length);f++){const m=(r=(c=n[f].match(i))==null?void 0:c[0])==null?void 0:r.split("],");if(f===0&&!m)s.scope=n[0];else if(m)for(let p=0,l=m.length;p<l;p++){const u=this.parseRule(m[p]);u&&(s[u.level]?u.key?s[u.level][u==null?void 0:u.key]=u:s[u.level]=u:u.key?s[u.level]={[u==null?void 0:u.key]:u}:s[u.level]=u)}}return s}parseRule(a,t={}){var s;K.info("[%s] parse rule: %s",t.requestId,a),a=a.startsWith("[")?a:`[${a}`,a=a.endsWith("]")?a:`${a}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(s=a==null?void 0:a.match(i))==null?void 0:s[0],n=o==null?void 0:o.split(",");if(n)return{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:Number(n[3]),key:n[4]}}checkWeather(a,t,i={}){var u,b,k,d,g,h,v,I,M,E,q,A,S,H,O;let o=0,n=0,s=0,e=0;const c=Math.round(((b=(u=t==null?void 0:t.SEVERE)==null?void 0:u.sigWave)==null?void 0:b.number)*1.6*100)/100,r=(d=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:d.number,f=(h=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:h.number,m=Math.round((((I=(v=t==null?void 0:t.SEVERE)==null?void 0:v.wind)==null?void 0:I.number)+2)*100)/100,p=(E=(M=t==null?void 0:t.SEVERE)==null?void 0:M.wind)==null?void 0:E.number,l=(A=(q=t==null?void 0:t.HEAVY)==null?void 0:q.wind)==null?void 0:A.number;for(let W=0;W<(a==null?void 0:a.length);W++){const T=a[W],L=(H=(S=T==null?void 0:T.meteo)==null?void 0:S.wave)==null?void 0:H.sig,C=(O=T==null?void 0:T.meteo)==null?void 0:O.wind,V=W?y(T.eta).diff(y(a[W-1].eta),"hour",!0):0;e=V>e?V:e,K.info("[%s] check sig.wave: %j",i.requestId,{...L,dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:f}),(L==null?void 0:L.height)>=c?T.isDangerous=!0:(L==null?void 0:L.height)>=r?T.isSevere=!0:(L==null?void 0:L.height)>=f&&(T.isHeavy=!0),K.info("[%s] check wind: %j",i.requestId,{...C,dgThd4Wd:m,svThd4Wd:p,hvThd4Wd:l}),(C==null?void 0:C.scale)>=m?(T.isDangerous=!0,delete T.isSevere,delete T.isHeavy):(C==null?void 0:C.scale)>p?(T.isDangerous||(T.isSevere=!0),delete T.isHeavy):(C==null?void 0:C.scale)===l&&!T.isDangerous&&!T.isSevere&&(T.isHeavy=!0),o+=T.isDangerous?V:0,n+=T.isSevere?V:0,s+=T.isHeavy?V:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,s=Math.round(s*100)/100,e=Math.round(e),{sample:a,dangerous:o,severe:n,heavy:s,step:e<3?3:e,wind:{dgThd4Wd:m,svThd4Wd:p,hvThd4Wd:l},sig:{dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:f}}}}const rt=new G,B=R.getLogger("vessel");var U=(Y=>(Y.common="common",Y.container="container",Y))(U||{}),J=(Y=>(Y.Ballast="Ballast",Y.Laden="Laden",Y))(J||{}),Q=(Y=>(Y.Cp="CP",Y.Perf="Basis",Y.Instruct="Other",Y))(Q||{});class F{static blockCoefficient(a,t,i,o){let n=Math.round(a/(t*i*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const s=[.55,.6,.65,.7,.75,.8,.85],e=s.map(c=>Math.abs(c-n));return s[e.indexOf(Math.min(...e))]}static froudeNumber(a,t,i=9.8){let o=Math.round(Math.sqrt(a*a/(i*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(a,t,i){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let s={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[a];return i==="Laden"&&(s=o[a]),s[0]+s[1]*t+s[2]*Math.pow(t,2)}static directionFactor(a,t=0){let i;return a>30&&a<=60?i=(1.7-.03*Math.pow(t-4,2))/2:a>60&&a<=150?i=(.9-.06*Math.pow(t-6,2))/2:i=(.4-.03*Math.pow(t-8,2))/2,Math.round(i*1e5)/1e5}static vesselTagFactor(a,t,i,o=0){o=o>5?o-.9*(o-5):o;let n;return i==="container"?n=.7*o+Math.pow(o,6.5)/(22*Math.pow(a,2/3)):t==="Ballast"?n=.7*o+Math.pow(o,6.5)/(2.7*Math.pow(a,2/3)):n=.5*o+Math.pow(o,6.5)/(2.7*Math.pow(a,2/3)),n}static waveHeightFactor(a){return a=a<1.25?1.25:a,a=a>6?a-.9*(a-6):a,Math.round((-.144*Math.pow(a,2)+.178*a)*1e4)/1e4}static assembleProperties(a,t,i,o){var f,m;const n=a.lbp??a.length??a.lengthOverall??198.9642,s=a.draught??8,e=a.breadthMoulded??a.breadth??a.breadthExtreme??32.4572,c=a.deadweight??67035.7773;return{tag:((m=(f=a==null?void 0:a.type)==null?void 0:f.toLowerCase())==null?void 0:m.indexOf("container"))>-1?"container":"common",lbp:n,loadCondition:t,draught:s,breadthMoulded:e,displacement:Math.round((c/1.025+s*e*n*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(a,t,i,o="",n=2,s=!1,e={}){t.velocity&&!t.noFactor&&s&&(a.speed=x.LngLatHelper.roundPrecision(t.velocity*1852/3600,6));const c=await st.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",o,e),r=F.weatherFactor(a,c),f=F.currentFactor(a.bearing,c==null?void 0:c.current,n),m={meteo:{...c},wxFactor:r,cFactor:f,speed:t.velocity&&s?t.velocity:Math.round((a.speed*1.943844+r+f)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...m,...t}}static async speedLoseInHoursStep(a,t,i,o,n,s,e="",c=!1,r={}){t.utc();const f=[],m=[];let p=0,l=0,u,b;for(let k=0;k<s.length-1;k++){let d=s[k];d.distanceFromStart=n+l;const g=s[k+1];if(a.bearing=x.LaneHelper.calculateBearing(d,g,!g.gcToPrevious),d.bearing=a.bearing,d.suspend&&c){d.eta=d.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),d.elapsed=d.elapsed??0;const I=d.suspend-d.elapsed;if(o-p>I)o=o-p-I,t.add(I,"hour"),d.elapsed=d.suspend;else{const M=o-p;d.elapsed+=M,t.add(M,"hour"),o=0}if(B.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`,r.requestId,d),o===0)return d.distanceFromPrevious=l,{etd:t,from:b||d,to:d,next:s.filter(M=>M),wps:f,days:m}}d=await F.speedLoseAt(a,d,t,e,0,c,r),b=b||d,d.important&&f.push(d),t.isSameOrAfter(i)&&(m.push(d),i.add(24,"hour"));const h=x.LaneHelper.calculateDistance(d,g,!g.gcToPrevious);let v=Math.ceil(h/b.speed*1e4)/1e4;if(p+v<o){if(p+=v,t.add(v,"hour"),delete s[k],B.info(`[%s] go to %j from %j with ${h}nm, and cost ${v} hours`,r.requestId,{lat:g.lat,lng:g.lng},{lat:b.lat,lng:b.lng,etd:b.etd}),l+=h,s.filter(I=>I).length<=1){u=g,u.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),u.distanceFromPrevious=h,u.distanceFromStart=n+l,f.push(u),delete s[k+1];break}}else{v=o-p,t.add(v,"hour");const I=x.LngLatHelper.roundPrecision(b.speed*v,4);u=x.LaneHelper.calculateCoordinate(d,a.bearing,I,"nauticalmiles",!g.gcToPrevious),u.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),s[k]=u,B.info(`[%s] go to %j from %j with ${I}nm, and cost ${v} hours`,r.requestId,{lat:u.lat,lng:u.lng},{lat:d.lat,lng:d.lng,etd:d.etd}),l+=I,u.distanceFromPrevious=l,u.distanceFromStart=n+l;break}}return{etd:t,from:b,to:u,next:s.filter(k=>k),wps:f,days:m}}static currentFactor(a,t,i=0){const o=(a-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return i&2?n=Math.ceil(n*100)/100:i&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(a,t){var m,p,l,u,b;B.debug("calculate weather factor via: %j",{...a,...t});const i=F.blockCoefficient(a.displacement,a.lbp,a.breadthMoulded,a.draught),o=F.froudeNumber(a.speed,a.lbp),n=F.amendFactor(i,o,a.loadCondition);let s=Math.abs(a.bearing%360-(((m=t==null?void 0:t.wind)==null?void 0:m.degree)%360||0));s=s>180?360-s:s;const e=F.directionFactor(s,(p=t==null?void 0:t.wind)==null?void 0:p.scale),c=F.vesselTagFactor(a.displacement,a.loadCondition,a.tag,(l=t==null?void 0:t.wind)==null?void 0:l.scale);let r=e*n*c/100*a.speed;r=Math.round(r*1.943844*1e4)/1e4*-1;const f=F.waveHeightFactor(((b=(u=t==null?void 0:t.wave)==null?void 0:u.sig)==null?void 0:b.height)??1);return r=r*.24+f*.76,B.debug("weather factor = %s",r),Math.round(r*100)/100}static async analyseInstant(a,t,i,o,n,s="",e=0,c=!1,r={}){var L,C,V,X,tt;const f=y().valueOf();a.lng=x.LngLatHelper.convertToStdLng(a.lng);const{route:m,waypoints:p}=n.points,l=x.LaneHelper.calculateSubRoute(a,m);if(((L=l[0])==null?void 0:L.length)<=1)return;const{v0:u,label:b}=a.sog?{v0:a.sog,label:"Other"}:{v0:o.speed,label:"CP"},k=F.assembleProperties(i,o.loadCondition,u,0),d=p.length?x.LaneHelper.calculateSubWaypoints(a,p):[],g={from:{...a},route:l,waypoints:d,v0:u,label:b},h={hours:[],days:[],wps:[]};e||(x.LaneHelper.calculateRouteDistance(l)/o.speed<=72?e=3:e=6);let v=x.LaneHelper.simplifyRouteToCoordinates(l,d,0),I=0,M=0,E=0,q=0;t=y(t).utc();const A=t.clone();for(;v.length>0;){const P=e-t.hour()%e,$=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,N=await F.speedLoseInHoursStep(k,t,A,$,I,v,s,c,r);(C=N.from)!=null&&C.speed&&(h.hours.push(N.from),h.wps.push(...N.wps),h.days.push(...N.days)),v=N==null?void 0:N.next,v.length||h.hours.push(N==null?void 0:N.to),I+=((V=N==null?void 0:N.to)==null?void 0:V.distanceFromPrevious)??0}const S=h.hours;for(let P=0;P<S.length-1;P++){const $=y(S[P+1].eta).diff(S[P].etd,"hour",!0)||1;M+=S[P].wxFactor*$,E+=S[P].cFactor*$,q+=$}(X=h.wps)==null||X.forEach((P,$)=>{if($){const N=h.wps[$-1],ct=P.distanceFromStart-N.distanceFromStart,et=y(P.eta).diff(y(N.etd),"h",!0);et<1?P.avgSpd=N.speed:P.avgSpd=Math.round(ct/et*100)/100}}),g.sample=h;const H=h.hours.at(-1);g.distance=Math.round(H.distanceFromStart*1e4)/1e4,g.eta=y(H.eta).toDate(),g.wxFactor=Math.round(M/q*1e4)/1e4,g.cFactor=Math.round(E/q*1e4)/1e4,g.avgSpeed=Math.round(H.distanceFromStart/q*1e4)/1e4,g.totalHrs=Math.round(q*1e4)/1e4,g.totalFoCons=Math.round((o==null?void 0:o.fo)/24*g.totalHrs*1e3)/1e3,g.totalDgoCons=Math.round((o==null?void 0:o.dgo)/24*g.totalHrs*1e3)/1e3;const W=y().valueOf()-f,T=((tt=h==null?void 0:h.hours)==null?void 0:tt.length)||1;return B.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",r==null?void 0:r.requestId,W,T,Math.round(W/T*1e3)/1e3),g}static async analyseInstantWithThreshed(a,t,i,o,n,s,e="",c=3,r=!1,f={}){var E,q,A;a.lng=x.LngLatHelper.convertToStdLng(a.lng);const m=F.assembleProperties(o,n.loadCondition,n.speed,0),p=x.LaneHelper.calculateSubRoute(a,s);if(((E=p[0])==null?void 0:E.length)<=1)return;let l=x.LaneHelper.simplifyRouteToCoordinates(p,[],0),u=0,b=0,k=0,d=0,g;const h={hours:[],days:[]};for(t=y(t).utc();l.length>0;){const S=c-t.hour()%c;let H=Math.ceil(t.clone().add(S,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(H=t.clone().add(H,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:H,H)g=await F.speedLoseInHoursStep(m,t,i.clone(),H,u,l,e,r,f),(q=g.from)!=null&&q.speed&&h.hours.push(g.from),l=g==null?void 0:g.next,l.length||(h.hours.push(g==null?void 0:g.to),h.days.push(g.to)),u+=((A=g==null?void 0:g.to)==null?void 0:A.distanceFromPrevious)??0;else{g&&(h.hours.push(g.to),h.days.push(g.to));break}}const v=h.hours;for(let S=0;S<v.length-1;S++){const H=y(v[S+1].eta).diff(v[S].etd,"hour",!0);b+=v[S].wxFactor*H,k+=v[S].cFactor*H,d+=H}const I=h.hours.at(-1);return{sample:h,distance:Math.round(((I==null?void 0:I.distanceFromStart)||0)*1e4)/1e4,eta:y(I==null?void 0:I.eta).utc().format(),wxFactor:Math.round(b/d*1e4)/1e4,cFactor:Math.round(k/d*1e4)/1e4,avgSpeed:Math.round(((I==null?void 0:I.distanceFromStart)||0)/d*1e4)/1e4,totalHrs:Math.round(d*1e4)/1e4,to:I,route:x.LaneHelper.generateRouteAccordingToWaypoints(l)}}}j.AISImpl=Z,j.AlertHelper=G,j.AlertLevel=z,j.HifleetImpl=ot,j.LoadCondition=J,j.MyShipImpl=it,j.MyVesselImpl=at,j.ShipxyImpl=nt,j.SpeedHelper=F,j.SpeedLabel=Q,j.VesselTag=U,j.alertHelper=rt,Object.defineProperty(j,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(j,Y){typeof exports=="object"&&typeof module<"u"?Y(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo","@idm-plugin/meteo"],Y):(j=typeof globalThis<"u"?globalThis:j||self,Y(j["idm-plugin-rabbitmq"]={},j.got,j["@log4js-node/log4js-api"],j.moment,j["@idm-plugin/geo"],j["@idm-plugin/meteo"]))})(this,function(j,Y,R,y,x,st){"use strict";var dt=Object.defineProperty;var ut=(j,Y,R)=>Y in j?dt(j,Y,{enumerable:!0,configurable:!0,writable:!0,value:R}):j[Y]=R;var _=(j,Y,R)=>(ut(j,typeof Y!="symbol"?Y+"":Y,R),R);const D=R.getLogger("vessel");class Z{parseStatus(a){let t,i;switch(a){case 0:t="在航(主机推动)",i="The engine is in use";break;case 1:t="锚泊",i="Anchored";break;case 2:t="失控",i="Not operated";break;case 3:t="操纵受限",i="Limited airworthiness";break;case 4:t="吃水受限",i="Limited by ship's draft";break;case 5:t="靠泊",i="Mooring";break;case 6:t="搁浅",i="Stranded";break;case 7:t="捕捞作业",i="Engaged in fishing";break;case 8:t="靠帆船提供动力",i="Sailing";break;default:t="未定义",i="Undefined"}return{labelCn:t,labelEn:i}}}class at extends Z{constructor(t,i){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await Y.post(i,o).json();D.info("[%s] fetch access token from: %s - %j",t.requestId,i,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:y().utc().format()})}async realTimePosition(t,i={}){var m,g,p;(!this.token||y().diff(y(this.token.issuedAt),"seconds")>((m=this.token)==null?void 0:m.expiresIn)-300)&&await this.authToken(i);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(g=this.token)==null?void 0:g.tokenType} ${(p=this.token)==null?void 0:p.accessToken}`},searchParams:{mmsi:t}};D.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n);const s=await Y.get(o,n).json();if(s.code)return D.warn("[%s] fetch realtime position failed: %j",i.requestId,o,{message:s.message,status:s.status,code:s.code}),s;const e=s.data;for(const f in e)!isNaN(e[f])&&Number(e[f])!==1/0&&(e[f]=Number(e[f]));const d=y(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName,imo:e.imo,callSign:e.callsign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:e.eta,destination:e.dest,positionTime:d.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,i,o,n,s=!0,e={}){(!this.token||y().diff(y(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const d=await this.realTimePosition(t,e),r=y(i),m=y(o),g=[];for(;m.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,n,g,e),r.add(30,"day");return await this.trajectoryIn30Day(t,r,m,d,n,g,e),g}async trajectoryIn30Day(t,i,o,n,s,e,d={}){var l,b,w,u,c;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",m={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};D.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,m);const g=await Y.post(r,m).json();if(g.code)return D.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:g.message,status:g.status,code:g.code}),g;let p=-1;const f=y(`${(u=(w=g.data)==null?void 0:w[0])==null?void 0:u.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(c=g.data)==null||c.forEach(h=>{for(const S in h)!isNaN(h[S])&&Number(h[S])!==1/0&&(h[S]=Number(h[S]));const v=y(`${h.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),I=h.eta?y(`${h.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,M=h.status,{labelCn:E,labelEn:q}=this.parseStatus(M),A={mmsi:h.mmsi,imo:n==null?void 0:n.imo,lat:h.lat,lng:h.lon,sog:h.sog,cog:h.cog,hdg:h.hdg,draught:h.draught,status:M,eta:I==null?void 0:I.unix(),destination:h.dest,positionTime:v.unix(),labelCn:E,labelEn:q,method:"trajectory",vendor:"myVessel",utc:v.utc().format()},H=Math.floor(v.diff(f,"minute",!0)/(s||1));H!==p&&(p=H,e.push(A))}),e}}class ot extends Z{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,i={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},s=await Y.post(o,n).json();D.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n);const e=s==null?void 0:s.list;if(!e)return D.warn("[%s] fetch realtime position failed: %j",i.requestId,o,s),s;for(const f in e)!isNaN(e[f])&&Number(e[f])!==1/0&&(e[f]=Number(e[f]));e.status=e.sp>3?0:1;const d=e.status,{labelCn:r,labelEn:m}=this.parseStatus(d),g=y(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?y(`${e.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:e.destination,positionTime:g.unix(),utc:g.utc().format(),status:d,labelCn:r,labelEn:m,method:"position",vendor:"hifleet"}}async search(t,i={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let s=await Y.post(o,n).json();D.info("[%s] fetch vessel props from: %s - %j",i.requestId,o,n),s instanceof Array&&(s=s[0]);for(const d in s)!isNaN(s[d])&&Number(s[d])!==1/0&&(s[d]=Number(s[d]));const e={mmsi:s.m,name:s.n,imo:s.i,callSign:s.c,length:s.l,breadth:s.b,draught:s.dr};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",s=await Y.post(o,n).json(),D.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,o,n),s instanceof Array&&(s=s[0]),s&&(e.deadweight=Number(s.dwt)),e}async trajectory(t,i,o,n,s=!0,e={}){var h,v,I;const d=await this.realTimePosition(t,e);let r=y(i);const m=y(o),g=y();if(s){let M=m.diff(r,"d",!0);M<0?r=m.clone().subtract(40,"d"):M<30?r.subtract(10,"d"):M<60?r.subtract(5,"d"):r=m.clone().subtract(80,"d"),M=g.diff(m,"d",!0),m.add(M>10?240:M*24,"h")}const p={searchParams:{endtime:m.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},f="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",l=await Y.get(f,p).json();D.info("[%s] fetch trajectory from: %s - %j",e.requestId,f,p);let b;l&&(b=((v=(h=l.ships)==null?void 0:h.offors)==null?void 0:v.ship)||[],b.length||D.warn("[%s] fetch trajectory failed: %j",e.requestId,l));const w=[];let u=-1;const c=y(`${(I=b==null?void 0:b[0])==null?void 0:I.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const M of b){for(const O in M)!isNaN(M[O])&&Number(M[O])!==1/0&&(M[O]=Number(M[O]));const E=y(`${M.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");M.status=M.sp>4?0:1;const{labelEn:q,labelCn:A}=this.parseStatus(M.status),H={mmsi:M.m,name:M.n,imo:d==null?void 0:d.imo,lat:M.la,lng:M.lo,draught:M.draught,sog:M.sp,cog:M.co,hdg:M.hdg,positionTime:E.unix(),utc:E.utc().format(),status:M.status,labelCn:A,labelEn:q,method:"trajectory",vendor:"hifleet"},S=Math.floor(E.diff(c,"minute",!0)/(n||1));S!==u&&(u=S,w.push(H))}return w}}class nt extends Z{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,i={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",s=await Y.get(n,o).json();if(D.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o),(s==null?void 0:s.status)!==0)return s;const e=s.data[0];for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const{labelCn:d,labelEn:r}=await this.parseStatus(e.navistat),m=y.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:m.utc().format(),status:e.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,i,o,n,s=!0,e={}){var c;const d=await this.realTimePosition(t,e),r=y(i),m=y(o),g="https://api.shipxy.com/apicall/GetShipTrack",p={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:m.unix()}},f=await Y.get(g,p).json();if(D.info("[%s] fetch trajectory from: %s - %j",e.requestId,g,p),(f==null?void 0:f.status)!==0)return f;const l=f==null?void 0:f.points,b=[],w=y.unix((c=l[0])==null?void 0:c.utc);let u=-1;for(const h of l){const v=y.unix(h.utc),I={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(h.sog*3600/1e3/1852*100)/100,cog:Math.round(h.cog/100*100)/100,lat:Math.round(h.lat/1e6*1e5)/1e5,lng:Math.round(h.lon/1e6*1e5)/1e5,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"shipxy"},M=Math.floor(v.diff(w,"minute",!0)/(n||1));M!==u&&(u=M,b.push(I))}return b}}class it extends Z{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,i={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",s=await Y.post(n,o).json();return D.info("[%s] fetch ship id from: %s - %j",i.requestId,n,o),s.code!=="0"?s:s.data[0].shipId}async getShipInfo(t,i={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",s=await Y.post(n,o).json();if(D.info("[%s] fetch ship info from: %s - %j",i.requestId,n,o),s.code!=="0")return s;const e=s.data;let d=e.imo;return t==="407170"&&(d="9198379",D.warn("[%s] ship(%s) imo error: %s, should be %s",i.requestId,t,e.imo,d)),{mmsi:e.mmsi,name:e.shipnameEn,imo:d,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,i={}){const o=await this.getShipId(t,i),n=await this.getShipInfo(o,i),s={headers:{appKey:this.token},json:{shipId:o}},e="https://api3.myships.com/sp/ships/position/latest",d=await Y.post(e,s).json();D.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,s);const r=d.data[0];for(const l in r)!isNaN(r[l])&&Number(r[l])!==1/0&&(r[l]=Number(r[l]));const{labelCn:m,labelEn:g}=await this.parseStatus(r.aisNavStatus),p=y.unix(r.posTime);return{...n,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:p.utc().format(),status:r.aisNavStatus,labelEn:g,labelCn:m,method:"position",vendor:"myship"}}async trajectory(t,i,o,n,s=!0,e={}){const d=y(i),r=y(o),m=await this.getShipId(t),g=await this.getShipInfo(m),p=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(m,d.unix(),d.add(30,"day").unix(),g,t,n,p);return await this.trajectoryIn30Day(m,d.unix(),r.unix(),g,t,n,p),p}async trajectoryIn30Day(t,i,o,n,s,e,d,r={}){var w;const m={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:o}},g="https://api3.myships.com/sp/ships/position/history",p=await Y.post(g,m).json();if(D.info("[%s] fetch trajectory from: %s - %j",r.requestId,g,m),p.code!=="0")return D.warn("[%s] invoke myship trajectory failed: %j",r.requestId,p),p;const f=p.data;for(const u in f)!isNaN(f[u])&&Number(f[u])!==1/0&&(f[u]=Number(f[u]));const l=y.unix((w=f[0])==null?void 0:w.posTime);let b=-1;for(const u of f){const c=y.unix(u.posTime),h={imo:n==null?void 0:n.imo,mmsi:s,lat:Math.round(u.lat/1e4/60*1e5)/1e5,lng:Math.round(u.lon/1e4/60*1e5)/1e5,sog:Math.round(u.sog/10*100)/100,cog:Math.round(u.cog/10*100)/100,hdg:Math.round(u.heading*100)/100,rot:Math.round(u.rot*100)/100,positionTime:c.unix(),utc:c.utc().format(),method:"trajectory",vendor:"myship"},v=Math.floor(c.diff(l,"minute",!0)/(e||1));v!==b&&(b=v,d.push(h))}return d}}const K=R.getLogger("vessel");var z=(k=>(k.NOTICE="NOTICE",k.WARN="WARN",k.HEAVY="HEAVY",k.SEVERE="SEVERE",k.ERROR="ERROR",k.FATAL="FATAL",k))(z||{});class G{parsePrinciple(a,t={}){var e,d,r;K.info("[%s] parse rule: %s",t.requestId,a);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),o=a.match(i)?(e=a.match(i))==null?void 0:e[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const s={};for(let m=0;m<(n==null?void 0:n.length);m++){const g=(r=(d=n[m].match(i))==null?void 0:d[0])==null?void 0:r.split("],");if(m===0&&!g)s.scope=n[0];else if(g)for(let p=0,f=g.length;p<f;p++){const l=this.parseRule(g[p]);l&&(s[l.level]?l.key?s[l.level][l==null?void 0:l.key]=l:s[l.level]=l:l.key?s[l.level]={[l==null?void 0:l.key]:l}:s[l.level]=l)}}return s}parseRule(a,t={}){var s;K.info("[%s] parse rule: %s",t.requestId,a),a=a.startsWith("[")?a:`[${a}`,a=a.endsWith("]")?a:`${a}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(s=a==null?void 0:a.match(i))==null?void 0:s[0],n=o==null?void 0:o.split(",");if(n)return{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:Number(n[3]),key:n[4]}}checkWeather(a,t,i={}){var l,b,w,u,c,h,v,I,M,E,q,A,H,S,O;let o=0,n=0,s=0,e=0;const d=Math.round(((b=(l=t==null?void 0:t.SEVERE)==null?void 0:l.sigWave)==null?void 0:b.number)*1.6*100)/100,r=(u=(w=t==null?void 0:t.SEVERE)==null?void 0:w.sigWave)==null?void 0:u.number,m=(h=(c=t==null?void 0:t.HEAVY)==null?void 0:c.sigWave)==null?void 0:h.number,g=Math.round((((I=(v=t==null?void 0:t.SEVERE)==null?void 0:v.wind)==null?void 0:I.number)+2)*100)/100,p=(E=(M=t==null?void 0:t.SEVERE)==null?void 0:M.wind)==null?void 0:E.number,f=(A=(q=t==null?void 0:t.HEAVY)==null?void 0:q.wind)==null?void 0:A.number;for(let W=0;W<(a==null?void 0:a.length);W++){const T=a[W],L=(S=(H=T==null?void 0:T.meteo)==null?void 0:H.wave)==null?void 0:S.sig,C=(O=T==null?void 0:T.meteo)==null?void 0:O.wind,V=W?y(T.eta).diff(y(a[W-1].eta),"hour",!0):0;e=V>e?V:e,K.info("[%s] check sig.wave: %j",i.requestId,{...L,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}),(L==null?void 0:L.height)>=d?T.isDangerous=!0:(L==null?void 0:L.height)>=r?T.isSevere=!0:(L==null?void 0:L.height)>=m&&(T.isHeavy=!0),K.info("[%s] check wind: %j",i.requestId,{...C,dgThd4Wd:g,svThd4Wd:p,hvThd4Wd:f}),(C==null?void 0:C.scale)>=g?(T.isDangerous=!0,delete T.isSevere,delete T.isHeavy):(C==null?void 0:C.scale)>p?(T.isDangerous||(T.isSevere=!0),delete T.isHeavy):(C==null?void 0:C.scale)===f&&!T.isDangerous&&!T.isSevere&&(T.isHeavy=!0),o+=T.isDangerous?V:0,n+=T.isSevere?V:0,s+=T.isHeavy?V:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,s=Math.round(s*100)/100,e=Math.round(e),{sample:a,dangerous:o,severe:n,heavy:s,step:e<3?3:e,wind:{dgThd4Wd:g,svThd4Wd:p,hvThd4Wd:f},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}}}}const rt=new G,B=R.getLogger("vessel");var U=(k=>(k.common="common",k.container="container",k))(U||{}),J=(k=>(k.Ballast="Ballast",k.Laden="Laden",k))(J||{}),Q=(k=>(k.Cp="CP",k.Perf="Basis",k.Instruct="Other",k))(Q||{});class F{static blockCoefficient(a,t,i,o){let n=Math.round(a/(t*i*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const s=[.55,.6,.65,.7,.75,.8,.85],e=s.map(d=>Math.abs(d-n));return s[e.indexOf(Math.min(...e))]}static froudeNumber(a,t,i=9.8){let o=Math.round(Math.sqrt(a*a/(i*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(a,t,i){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let s={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[a];return i==="Laden"&&(s=o[a]),s[0]+s[1]*t+s[2]*Math.pow(t,2)}static directionFactor(a,t=0){let i;return a>30&&a<=60?i=(1.7-.03*Math.pow(t-4,2))/2:a>60&&a<=150?i=(.9-.06*Math.pow(t-6,2))/2:i=(.4-.03*Math.pow(t-8,2))/2,Math.round(i*1e5)/1e5}static vesselTagFactor(a,t,i,o=0){o=o>5?o-.9*(o-5):o;let n;return i==="container"?n=.7*o+Math.pow(o,6.5)/(22*Math.pow(a,2/3)):t==="Ballast"?n=.7*o+Math.pow(o,6.5)/(2.7*Math.pow(a,2/3)):n=.5*o+Math.pow(o,6.5)/(2.7*Math.pow(a,2/3)),n}static waveHeightFactor(a){return a=a<1.25?1.25:a,a=a>6?a-.9*(a-6):a,Math.round((-.144*Math.pow(a,2)+.178*a)*1e4)/1e4}static assembleProperties(a,t,i,o){var m,g;const n=a.lbp??a.length??a.lengthOverall??198.9642,s=a.draught??8,e=a.breadthMoulded??a.breadth??a.breadthExtreme??32.4572,d=a.deadweight??67035.7773;return{tag:((g=(m=a==null?void 0:a.type)==null?void 0:m.toLowerCase())==null?void 0:g.indexOf("container"))>-1?"container":"common",lbp:n,loadCondition:t,draught:s,breadthMoulded:e,displacement:Math.round((d/1.025+s*e*n*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(a,t,i,o="",n=2,s=!1,e={}){t.velocity&&!t.noFactor&&s&&(a.speed=x.LngLatHelper.roundPrecision(t.velocity*1852/3600,6));const d=await st.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",o,e),r=F.weatherFactor(a,d),m=F.currentFactor(a.bearing,d==null?void 0:d.current,n),g={meteo:{...d},wxFactor:r,cFactor:m,speed:t.velocity&&s?t.velocity:Math.round((a.speed*1.943844+r+m)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...g,...t}}static async speedLoseInHoursStep(a,t,i,o,n,s,e="",d=!1,r={}){t.utc();const m=[],g=[];let p=0,f=0,l,b;for(let w=0;w<s.length-1;w++){let u=s[w];u.distanceFromStart=n+f;const c=s[w+1];if(a.bearing=x.LaneHelper.calculateBearing(u,c,!c.gcToPrevious),u.bearing=a.bearing,u.suspend&&d){u.eta=u.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),u.elapsed=u.elapsed??0;const I=u.suspend-u.elapsed;if(o-p>I)o=o-p-I,t.add(I,"hour"),u.elapsed=u.suspend;else{const M=o-p;u.elapsed+=M,t.add(M,"hour"),o=0}if(B.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${o} hours need to go...`,r.requestId,u),o===0)return u.distanceFromPrevious=f,{etd:t,from:b||u,to:u,next:s.filter(M=>M),wps:m,days:g}}u=await F.speedLoseAt(a,u,t,e,0,d,r),b=b||u,u.important&&m.push(u),t.isSameOrAfter(i)&&(g.push(u),i.add(24,"hour"));const h=x.LaneHelper.calculateDistance(u,c,!c.gcToPrevious);let v=Math.ceil(h/b.speed*1e4)/1e4;if(p+v<o){if(p+=v,t.add(v,"hour"),delete s[w],B.info(`[%s] go to %j from %j with ${h}nm, and cost ${v} hours`,r.requestId,{lat:c.lat,lng:c.lng},{lat:b.lat,lng:b.lng,etd:b.etd}),f+=h,s.filter(I=>I).length<=1){l=c,l.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),l.distanceFromPrevious=h,l.distanceFromStart=n+f,m.push(l),delete s[w+1];break}}else{v=o-p,t.add(v,"hour");const I=x.LngLatHelper.roundPrecision(b.speed*v,4);l=x.LaneHelper.calculateCoordinate(u,a.bearing,I,"nauticalmiles",!c.gcToPrevious),l.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),s[w]=l,B.info(`[%s] go to %j from %j with ${I}nm, and cost ${v} hours`,r.requestId,{lat:l.lat,lng:l.lng},{lat:u.lat,lng:u.lng,etd:u.etd}),f+=I,l.distanceFromPrevious=f,l.distanceFromStart=n+f;break}}return{etd:t,from:b,to:l,next:s.filter(w=>w),wps:m,days:g}}static currentFactor(a,t,i=0){const o=(a-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return i&2?n=Math.ceil(n*100)/100:i&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(a,t){var g,p,f,l,b;B.debug("calculate weather factor via: %j",{...a,...t});const i=F.blockCoefficient(a.displacement,a.lbp,a.breadthMoulded,a.draught),o=F.froudeNumber(a.speed,a.lbp),n=F.amendFactor(i,o,a.loadCondition);let s=Math.abs(a.bearing%360-(((g=t==null?void 0:t.wind)==null?void 0:g.degree)%360||0));s=s>180?360-s:s;const e=F.directionFactor(s,(p=t==null?void 0:t.wind)==null?void 0:p.scale),d=F.vesselTagFactor(a.displacement,a.loadCondition,a.tag,(f=t==null?void 0:t.wind)==null?void 0:f.scale);let r=e*n*d/100*a.speed;r=Math.round(r*1.943844*1e4)/1e4*-1;const m=F.waveHeightFactor(((b=(l=t==null?void 0:t.wave)==null?void 0:l.sig)==null?void 0:b.height)??1);return r=r*.24+m*.76,B.debug("weather factor = %s",r),Math.round(r*100)/100}static async analyseInstant(a,t,i,o,n,s="",e=0,d=!1,r={}){var L,C,V,X,tt;const m=y().valueOf();a.lng=x.LngLatHelper.convertToStdLng(a.lng);const{route:g,waypoints:p}=n.points,f=x.LaneHelper.calculateSubRoute(a,g);if(((L=f[0])==null?void 0:L.length)<=1)return;const{v0:l,label:b}=a.sog?{v0:a.sog,label:"Other"}:{v0:o.speed,label:"CP"},w=F.assembleProperties(i,o.loadCondition,l,0),u=p.length?x.LaneHelper.calculateSubWaypoints(a,p):[],c={from:{...a},route:f,waypoints:u,v0:l,label:b},h={hours:[],days:[],wps:[]};e||(x.LaneHelper.calculateRouteDistance(f)/o.speed<=72?e=3:e=6);let v=x.LaneHelper.simplifyRouteToCoordinates(f,u,0),I=0,M=0,E=0,q=0;t=y(t).utc();const A=t.clone();for(;v.length>0;){const P=e-t.hour()%e,$=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,N=await F.speedLoseInHoursStep(w,t,A,$,I,v,s,d,r);(C=N.from)!=null&&C.speed&&(h.hours.push(N.from),h.wps.push(...N.wps),h.days.push(...N.days)),v=N==null?void 0:N.next,v.length||h.hours.push(N==null?void 0:N.to),I+=((V=N==null?void 0:N.to)==null?void 0:V.distanceFromPrevious)??0}const H=h.hours;for(let P=0;P<H.length-1;P++){const $=y(H[P+1].eta).diff(H[P].etd,"hour",!0)||1;M+=H[P].wxFactor*$,E+=H[P].cFactor*$,q+=$}(X=h.wps)==null||X.forEach((P,$)=>{if($){const N=h.wps[$-1],ct=P.distanceFromStart-N.distanceFromStart,et=y(P.eta).diff(y(N.etd),"h",!0);et<1?P.avgSpd=N.speed:P.avgSpd=Math.round(ct/et*100)/100}}),c.sample=h;const S=h.hours.at(-1);c.distance=Math.round(S.distanceFromStart*1e4)/1e4,c.eta=y(S.eta).toDate(),c.wxFactor=Math.round(M/q*1e4)/1e4,c.cFactor=Math.round(E/q*1e4)/1e4,c.avgSpeed=Math.round(S.distanceFromStart/q*1e4)/1e4,c.totalHrs=Math.round(q*1e4)/1e4,c.totalFoCons=Math.round((o==null?void 0:o.fo)/24*c.totalHrs*1e3)/1e3,c.totalDgoCons=Math.round((o==null?void 0:o.dgo)/24*c.totalHrs*1e3)/1e3;const W=y().valueOf()-m,T=((tt=h==null?void 0:h.hours)==null?void 0:tt.length)||1;return B.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",r==null?void 0:r.requestId,W,T,Math.round(W/T*1e3)/1e3),c}static async analyseInstantWithThreshed(a,t,i,o,n,s,e="",d=3,r=!1,m={}){var E,q,A;a.lng=x.LngLatHelper.convertToStdLng(a.lng);const g=F.assembleProperties(o,n.loadCondition,n.speed,0),p=x.LaneHelper.calculateSubRoute(a,s);if(((E=p[0])==null?void 0:E.length)<=1)return;let f=x.LaneHelper.simplifyRouteToCoordinates(p,[],0);f.forEach(H=>H.important=!0);let l=0,b=0,w=0,u=0,c;const h={hours:[],wps:[],days:[]};for(t=y(t).utc();f.length>0;){const H=d-t.hour()%d;let S=Math.ceil(t.clone().add(H,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(S=t.clone().add(S,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:S,S)c=await F.speedLoseInHoursStep(g,t,i.clone(),S,l,f,e,r,m),(q=c.from)!=null&&q.speed&&(h.hours.push(c.from),c!=null&&c.wps&&h.wps.push(...c.wps),h.days.push(...c.days)),f=c==null?void 0:c.next,f.length||(h.hours.push(c==null?void 0:c.to),c!=null&&c.wps&&h.wps.push(...c.wps),h.days.push(c==null?void 0:c.to)),l+=((A=c==null?void 0:c.to)==null?void 0:A.distanceFromPrevious)??0;else{c&&(h.hours.push(c.to),c!=null&&c.wps&&h.wps.push(...c.wps),h.days.push(c.to));break}}const v=h.hours;for(let H=0;H<v.length-1;H++){const S=y(v[H+1].eta).diff(v[H].etd,"hour",!0);b+=v[H].wxFactor*S,w+=v[H].cFactor*S,u+=S}const I=h.hours.at(-1);return{sample:h,distance:Math.round(((I==null?void 0:I.distanceFromStart)||0)*1e4)/1e4,eta:y(I==null?void 0:I.eta).utc().format(),wxFactor:Math.round(b/u*1e4)/1e4,cFactor:Math.round(w/u*1e4)/1e4,avgSpeed:Math.round(((I==null?void 0:I.distanceFromStart)||0)/u*1e4)/1e4,totalHrs:Math.round(u*1e4)/1e4,to:I,route:x.LaneHelper.generateRouteAccordingToWaypoints(f)}}}j.AISImpl=Z,j.AlertHelper=G,j.AlertLevel=z,j.HifleetImpl=ot,j.LoadCondition=J,j.MyShipImpl=it,j.MyVesselImpl=at,j.ShipxyImpl=nt,j.SpeedHelper=F,j.SpeedLabel=Q,j.VesselTag=U,j.alertHelper=rt,Object.defineProperty(j,Symbol.toStringTag,{value:"Module"})});
|