@idm-plugin/vessel 1.2.4 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +323 -322
- package/dist/index.umd.cjs +1 -1
- package/dist/speed/src/index.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
var tt = Object.defineProperty;
|
|
2
|
-
var et = (
|
|
3
|
-
var Z = (
|
|
4
|
-
import
|
|
2
|
+
var et = (k, s, t) => s in k ? tt(k, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : k[s] = t;
|
|
3
|
+
var Z = (k, s, t) => (et(k, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
|
+
import C from "got";
|
|
5
5
|
import z from "@log4js-node/log4js-api";
|
|
6
6
|
import b from "moment";
|
|
7
|
-
import { LngLatHelper as B, LaneHelper as
|
|
7
|
+
import { LngLatHelper as B, LaneHelper as O } from "@idm-plugin/geo";
|
|
8
8
|
import { MeteoHelper as st } from "@idm-plugin/meteo";
|
|
9
|
-
let
|
|
9
|
+
let l;
|
|
10
10
|
try {
|
|
11
|
-
|
|
11
|
+
l = z.getLogger("vessel");
|
|
12
12
|
} catch {
|
|
13
13
|
} finally {
|
|
14
14
|
}
|
|
@@ -68,8 +68,8 @@ class mt extends K {
|
|
|
68
68
|
client_secret: this.clientSecret,
|
|
69
69
|
grant_type: "client_credentials"
|
|
70
70
|
}
|
|
71
|
-
}, n = await
|
|
72
|
-
|
|
71
|
+
}, n = await C.post(i, o).json();
|
|
72
|
+
l == null || l.info("[%s] fetch access token from: %s - %j", t.requestId, i, n), n.error || (this.token = {
|
|
73
73
|
accessToken: n.access_token,
|
|
74
74
|
tokenType: n.token_type,
|
|
75
75
|
expiresIn: n.expires_in,
|
|
@@ -79,21 +79,21 @@ class mt extends K {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
async realTimePosition(t, i = {}) {
|
|
82
|
-
var
|
|
83
|
-
(!this.token || b().diff(b(this.token.issuedAt), "seconds") > ((
|
|
82
|
+
var c, h, y;
|
|
83
|
+
(!this.token || b().diff(b(this.token.issuedAt), "seconds") > ((c = this.token) == null ? void 0 : c.expiresIn) - 300) && await this.authToken(i);
|
|
84
84
|
const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
|
|
85
85
|
headers: {
|
|
86
|
-
Authorization: `${(
|
|
86
|
+
Authorization: `${(h = this.token) == null ? void 0 : h.tokenType} ${(y = this.token) == null ? void 0 : y.accessToken}`
|
|
87
87
|
},
|
|
88
88
|
searchParams: { mmsi: t }
|
|
89
89
|
};
|
|
90
|
-
|
|
91
|
-
const a = await
|
|
90
|
+
l == null || l.info("[%s] fetch realtime position from: %s - %j", i.requestId, o, n);
|
|
91
|
+
const a = await C.get(o, n).json();
|
|
92
92
|
if (a.code)
|
|
93
|
-
return
|
|
93
|
+
return l == null || l.warn("[%s] fetch realtime position failed: %j", i.requestId, o, { message: a.message, status: a.status, code: a.code }), a;
|
|
94
94
|
const e = a.data;
|
|
95
|
-
for (const
|
|
96
|
-
!isNaN(e[
|
|
95
|
+
for (const M in e)
|
|
96
|
+
!isNaN(e[M]) && Number(e[M]) !== 1 / 0 && (e[M] = Number(e[M]));
|
|
97
97
|
const d = b(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
98
98
|
return {
|
|
99
99
|
mmsi: e.mmsi,
|
|
@@ -122,16 +122,16 @@ class mt extends K {
|
|
|
122
122
|
}
|
|
123
123
|
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
124
124
|
(!this.token || b().diff(b(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
|
|
125
|
-
const d = await this.realTimePosition(t, e),
|
|
126
|
-
for (;
|
|
127
|
-
await this.trajectoryIn30Day(t,
|
|
128
|
-
return await this.trajectoryIn30Day(t,
|
|
125
|
+
const d = await this.realTimePosition(t, e), r = b(i), c = b(o), h = [];
|
|
126
|
+
for (; c.diff(r, "day", !0) > 30; )
|
|
127
|
+
await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), d, n, h, e), r.add(30, "day");
|
|
128
|
+
return await this.trajectoryIn30Day(t, r, c, d, n, h, e), h;
|
|
129
129
|
}
|
|
130
130
|
async trajectoryIn30Day(t, i, o, n, a, e, d = {}) {
|
|
131
|
-
var
|
|
132
|
-
const
|
|
131
|
+
var f, Y, j, w, g;
|
|
132
|
+
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", c = {
|
|
133
133
|
headers: {
|
|
134
|
-
Authorization: `${(
|
|
134
|
+
Authorization: `${(f = this.token) == null ? void 0 : f.tokenType} ${(Y = this.token) == null ? void 0 : Y.accessToken}`
|
|
135
135
|
},
|
|
136
136
|
json: {
|
|
137
137
|
mmsi: t,
|
|
@@ -139,35 +139,35 @@ class mt extends K {
|
|
|
139
139
|
endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
140
140
|
}
|
|
141
141
|
};
|
|
142
|
-
|
|
143
|
-
const
|
|
144
|
-
if (
|
|
145
|
-
return
|
|
146
|
-
let
|
|
147
|
-
const
|
|
148
|
-
return (
|
|
149
|
-
for (const
|
|
150
|
-
!isNaN(
|
|
151
|
-
const
|
|
152
|
-
mmsi:
|
|
142
|
+
l == null || l.info("[%s] fetch trajectory from: %s - %j", d.requestId, r, c);
|
|
143
|
+
const h = await C.post(r, c).json();
|
|
144
|
+
if (h.code)
|
|
145
|
+
return l == null || l.warn("[%s] fetch trajectory failed: %j", d.requestId, r, { message: h.message, status: h.status, code: h.code }), h;
|
|
146
|
+
let y = -1;
|
|
147
|
+
const M = b(`${(w = (j = h.data) == null ? void 0 : j[0]) == null ? void 0 : w.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
148
|
+
return (g = h.data) == null || g.forEach((m) => {
|
|
149
|
+
for (const N in m)
|
|
150
|
+
!isNaN(m[N]) && Number(m[N]) !== 1 / 0 && (m[N] = Number(m[N]));
|
|
151
|
+
const v = b(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), p = m.eta ? b(`${m.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, u = m.status, { labelCn: S, labelEn: W } = this.parseStatus(u), T = {
|
|
152
|
+
mmsi: m.mmsi,
|
|
153
153
|
imo: n == null ? void 0 : n.imo,
|
|
154
|
-
lat:
|
|
155
|
-
lng:
|
|
156
|
-
sog:
|
|
157
|
-
cog:
|
|
158
|
-
hdg:
|
|
159
|
-
draught:
|
|
160
|
-
status:
|
|
161
|
-
eta:
|
|
162
|
-
destination:
|
|
163
|
-
positionTime:
|
|
164
|
-
labelCn:
|
|
154
|
+
lat: m.lat,
|
|
155
|
+
lng: m.lon,
|
|
156
|
+
sog: m.sog,
|
|
157
|
+
cog: m.cog,
|
|
158
|
+
hdg: m.hdg,
|
|
159
|
+
draught: m.draught,
|
|
160
|
+
status: u,
|
|
161
|
+
eta: p == null ? void 0 : p.unix(),
|
|
162
|
+
destination: m.dest,
|
|
163
|
+
positionTime: v.unix(),
|
|
164
|
+
labelCn: S,
|
|
165
165
|
labelEn: W,
|
|
166
166
|
method: "trajectory",
|
|
167
167
|
vendor: "myVessel",
|
|
168
|
-
utc:
|
|
169
|
-
},
|
|
170
|
-
|
|
168
|
+
utc: v.utc().format()
|
|
169
|
+
}, L = Math.floor(v.diff(M, "minute", !0) / (a || 1));
|
|
170
|
+
L !== y && (y = L, e.push(T));
|
|
171
171
|
}), e;
|
|
172
172
|
}
|
|
173
173
|
}
|
|
@@ -183,15 +183,15 @@ class pt extends K {
|
|
|
183
183
|
mmsi: t,
|
|
184
184
|
usertoken: this.token
|
|
185
185
|
}
|
|
186
|
-
}, a = await
|
|
187
|
-
|
|
186
|
+
}, a = await C.post(o, n).json();
|
|
187
|
+
l == null || l.info("[%s] fetch realtime position from: %s - %j", i.requestId, o, n);
|
|
188
188
|
const e = a == null ? void 0 : a.list;
|
|
189
189
|
if (!e)
|
|
190
|
-
return
|
|
191
|
-
for (const
|
|
192
|
-
!isNaN(e[
|
|
190
|
+
return l == null || l.warn("[%s] fetch realtime position failed: %j", i.requestId, o, a), a;
|
|
191
|
+
for (const M in e)
|
|
192
|
+
!isNaN(e[M]) && Number(e[M]) !== 1 / 0 && (e[M] = Number(e[M]));
|
|
193
193
|
e.status = e.sp > 3 ? 0 : 1;
|
|
194
|
-
const d = e.status, { labelCn:
|
|
194
|
+
const d = e.status, { labelCn: r, labelEn: c } = this.parseStatus(d), h = b(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
195
195
|
return {
|
|
196
196
|
mmsi: e.m,
|
|
197
197
|
name: e.n,
|
|
@@ -208,11 +208,11 @@ class pt extends K {
|
|
|
208
208
|
rot: isNaN(e.rot) ? 0 : e.rot,
|
|
209
209
|
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? b(`${e.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
|
|
210
210
|
destination: e.destination,
|
|
211
|
-
positionTime:
|
|
212
|
-
utc:
|
|
211
|
+
positionTime: h.unix(),
|
|
212
|
+
utc: h.utc().format(),
|
|
213
213
|
status: d,
|
|
214
|
-
labelCn:
|
|
215
|
-
labelEn:
|
|
214
|
+
labelCn: r,
|
|
215
|
+
labelEn: c,
|
|
216
216
|
method: "position",
|
|
217
217
|
vendor: "hifleet"
|
|
218
218
|
};
|
|
@@ -229,8 +229,8 @@ class pt extends K {
|
|
|
229
229
|
Host: "www.hifleet.com"
|
|
230
230
|
}
|
|
231
231
|
};
|
|
232
|
-
let a = await
|
|
233
|
-
|
|
232
|
+
let a = await C.post(o, n).json();
|
|
233
|
+
l == null || l.info("[%s] fetch vessel props from: %s - %j", i.requestId, o, n), a instanceof Array && (a = a[0]);
|
|
234
234
|
for (const d in a)
|
|
235
235
|
!isNaN(a[d]) && Number(a[d]) !== 1 / 0 && (a[d] = Number(a[d]));
|
|
236
236
|
const e = {
|
|
@@ -242,57 +242,57 @@ class pt extends K {
|
|
|
242
242
|
breadth: a.b,
|
|
243
243
|
draught: a.dr
|
|
244
244
|
};
|
|
245
|
-
return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await
|
|
245
|
+
return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await C.post(o, n).json(), l == null || l.info("[%s] fetch vessel dead weight from: %s - %j", i.requestId, o, n), a instanceof Array && (a = a[0]), a && (e.deadweight = Number(a.dwt)), e;
|
|
246
246
|
}
|
|
247
247
|
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
248
|
-
var
|
|
248
|
+
var m, v, p;
|
|
249
249
|
const d = await this.realTimePosition(t, e);
|
|
250
|
-
let
|
|
251
|
-
const
|
|
250
|
+
let r = b(i);
|
|
251
|
+
const c = b(o), h = b();
|
|
252
252
|
if (a) {
|
|
253
|
-
let
|
|
254
|
-
|
|
253
|
+
let u = c.diff(r, "d", !0);
|
|
254
|
+
u < 0 ? r = c.clone().subtract(40, "d") : u < 30 ? r.subtract(10, "d") : u < 60 ? r.subtract(5, "d") : r = c.clone().subtract(80, "d"), u = h.diff(c, "d", !0), c.add(u > 10 ? 240 : u * 24, "h");
|
|
255
255
|
}
|
|
256
|
-
const
|
|
256
|
+
const y = {
|
|
257
257
|
searchParams: {
|
|
258
|
-
endtime:
|
|
259
|
-
starttime:
|
|
258
|
+
endtime: c.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
259
|
+
starttime: r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
260
260
|
mmsi: t,
|
|
261
261
|
usertoken: this.token
|
|
262
262
|
}
|
|
263
|
-
},
|
|
264
|
-
|
|
265
|
-
let
|
|
266
|
-
|
|
267
|
-
const
|
|
268
|
-
let
|
|
269
|
-
const
|
|
270
|
-
for (const
|
|
271
|
-
for (const
|
|
272
|
-
!isNaN(
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
const { labelEn: W, labelCn:
|
|
276
|
-
mmsi:
|
|
277
|
-
name:
|
|
263
|
+
}, M = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", f = await C.get(M, y).json();
|
|
264
|
+
l == null || l.info("[%s] fetch trajectory from: %s - %j", e.requestId, M, y);
|
|
265
|
+
let Y;
|
|
266
|
+
f && (Y = ((v = (m = f.ships) == null ? void 0 : m.offors) == null ? void 0 : v.ship) || [], Y.length || l == null || l.warn("[%s] fetch trajectory failed: %j", e.requestId, f));
|
|
267
|
+
const j = [];
|
|
268
|
+
let w = -1;
|
|
269
|
+
const g = b(`${(p = Y == null ? void 0 : Y[0]) == null ? void 0 : p.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
270
|
+
for (const u of Y) {
|
|
271
|
+
for (const R in u)
|
|
272
|
+
!isNaN(u[R]) && Number(u[R]) !== 1 / 0 && (u[R] = Number(u[R]));
|
|
273
|
+
const S = b(`${u.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
274
|
+
u.status = u.sp > 4 ? 0 : 1;
|
|
275
|
+
const { labelEn: W, labelCn: T } = this.parseStatus(u.status), L = {
|
|
276
|
+
mmsi: u.m,
|
|
277
|
+
name: u.n,
|
|
278
278
|
imo: d == null ? void 0 : d.imo,
|
|
279
|
-
lat:
|
|
280
|
-
lng:
|
|
281
|
-
draught:
|
|
282
|
-
sog:
|
|
283
|
-
cog:
|
|
284
|
-
hdg:
|
|
285
|
-
positionTime:
|
|
286
|
-
utc:
|
|
287
|
-
status:
|
|
288
|
-
labelCn:
|
|
279
|
+
lat: u.la,
|
|
280
|
+
lng: u.lo,
|
|
281
|
+
draught: u.draught,
|
|
282
|
+
sog: u.sp,
|
|
283
|
+
cog: u.co,
|
|
284
|
+
hdg: u.hdg,
|
|
285
|
+
positionTime: S.unix(),
|
|
286
|
+
utc: S.utc().format(),
|
|
287
|
+
status: u.status,
|
|
288
|
+
labelCn: T,
|
|
289
289
|
labelEn: W,
|
|
290
290
|
method: "trajectory",
|
|
291
291
|
vendor: "hifleet"
|
|
292
|
-
},
|
|
293
|
-
|
|
292
|
+
}, N = Math.floor(S.diff(g, "minute", !0) / (n || 1));
|
|
293
|
+
N !== w && (w = N, j.push(L));
|
|
294
294
|
}
|
|
295
|
-
return
|
|
295
|
+
return j;
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
class Mt extends K {
|
|
@@ -308,13 +308,13 @@ class Mt extends K {
|
|
|
308
308
|
k: this.token,
|
|
309
309
|
enc: 1
|
|
310
310
|
}
|
|
311
|
-
}, n = "https://api.shipxy.com/apicall/GetSingleShip", a = await
|
|
312
|
-
if (
|
|
311
|
+
}, n = "https://api.shipxy.com/apicall/GetSingleShip", a = await C.get(n, o).json();
|
|
312
|
+
if (l == null || l.info("[%s] fetch realtime position from: %s - %j", i.requestId, n, o), (a == null ? void 0 : a.status) !== 0)
|
|
313
313
|
return a;
|
|
314
314
|
const e = a.data[0];
|
|
315
|
-
for (const
|
|
316
|
-
!isNaN(e[
|
|
317
|
-
const { labelCn: d, labelEn:
|
|
315
|
+
for (const y in e)
|
|
316
|
+
!isNaN(e[y]) && Number(e[y]) !== 1 / 0 && (e[y] = Number(e[y]));
|
|
317
|
+
const { labelCn: d, labelEn: r } = await this.parseStatus(e.navistat), c = b.unix(e.lasttime);
|
|
318
318
|
return {
|
|
319
319
|
mmsi: e.ShipID,
|
|
320
320
|
name: e.name,
|
|
@@ -330,46 +330,46 @@ class Mt extends K {
|
|
|
330
330
|
hdg: Math.round(e.hdg / 100 * 100) / 100,
|
|
331
331
|
rot: Math.round(e.rot / 100 * 100) / 100,
|
|
332
332
|
positionTime: e.lasttime,
|
|
333
|
-
utc:
|
|
333
|
+
utc: c.utc().format(),
|
|
334
334
|
status: e.navistat,
|
|
335
|
-
labelEn:
|
|
335
|
+
labelEn: r,
|
|
336
336
|
labelCn: d,
|
|
337
337
|
method: "position",
|
|
338
338
|
vendor: "shipxy"
|
|
339
339
|
};
|
|
340
340
|
}
|
|
341
341
|
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
342
|
-
var
|
|
343
|
-
const d = await this.realTimePosition(t, e),
|
|
342
|
+
var g;
|
|
343
|
+
const d = await this.realTimePosition(t, e), r = b(i), c = b(o), h = "https://api.shipxy.com/apicall/GetShipTrack", y = {
|
|
344
344
|
searchParams: {
|
|
345
345
|
id: t,
|
|
346
346
|
k: this.token,
|
|
347
347
|
enc: 1,
|
|
348
348
|
cut: 0,
|
|
349
|
-
btm:
|
|
350
|
-
etm:
|
|
349
|
+
btm: r.unix(),
|
|
350
|
+
etm: c.unix()
|
|
351
351
|
}
|
|
352
|
-
},
|
|
353
|
-
if (
|
|
354
|
-
return
|
|
355
|
-
const
|
|
356
|
-
let
|
|
357
|
-
for (const
|
|
358
|
-
const
|
|
352
|
+
}, M = await C.get(h, y).json();
|
|
353
|
+
if (l == null || l.info("[%s] fetch trajectory from: %s - %j", e.requestId, h, y), (M == null ? void 0 : M.status) !== 0)
|
|
354
|
+
return M;
|
|
355
|
+
const f = M == null ? void 0 : M.points, Y = [], j = b.unix((g = f[0]) == null ? void 0 : g.utc);
|
|
356
|
+
let w = -1;
|
|
357
|
+
for (const m of f) {
|
|
358
|
+
const v = b.unix(m.utc), p = {
|
|
359
359
|
imo: d == null ? void 0 : d.imo,
|
|
360
360
|
mmsi: t,
|
|
361
|
-
sog: Math.round(
|
|
362
|
-
cog: Math.round(
|
|
363
|
-
lat: Math.round(
|
|
364
|
-
lng: Math.round(
|
|
365
|
-
positionTime:
|
|
366
|
-
utc:
|
|
361
|
+
sog: Math.round(m.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
362
|
+
cog: Math.round(m.cog / 100 * 100) / 100,
|
|
363
|
+
lat: Math.round(m.lat / 1e6 * 1e5) / 1e5,
|
|
364
|
+
lng: Math.round(m.lon / 1e6 * 1e5) / 1e5,
|
|
365
|
+
positionTime: v.unix(),
|
|
366
|
+
utc: v.utc().format(),
|
|
367
367
|
method: "trajectory",
|
|
368
368
|
vendor: "shipxy"
|
|
369
|
-
},
|
|
370
|
-
|
|
369
|
+
}, u = Math.floor(v.diff(j, "minute", !0) / (n || 1));
|
|
370
|
+
u !== w && (w = u, Y.push(p));
|
|
371
371
|
}
|
|
372
|
-
return
|
|
372
|
+
return Y;
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
375
|
class yt extends K {
|
|
@@ -386,8 +386,8 @@ class yt extends K {
|
|
|
386
386
|
json: {
|
|
387
387
|
mmsiList: t
|
|
388
388
|
}
|
|
389
|
-
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await
|
|
390
|
-
return
|
|
389
|
+
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await C.post(n, o).json();
|
|
390
|
+
return l == null || l.info("[%s] fetch ship id from: %s - %j", i.requestId, n, o), a.code !== "0" ? a : a.data[0].shipId;
|
|
391
391
|
}
|
|
392
392
|
async getShipInfo(t, i = {}) {
|
|
393
393
|
const o = {
|
|
@@ -397,12 +397,12 @@ class yt extends K {
|
|
|
397
397
|
json: {
|
|
398
398
|
shipId: t
|
|
399
399
|
}
|
|
400
|
-
}, n = "https://api3.myships.com/sp/ships/aissta", a = await
|
|
401
|
-
if (
|
|
400
|
+
}, n = "https://api3.myships.com/sp/ships/aissta", a = await C.post(n, o).json();
|
|
401
|
+
if (l == null || l.info("[%s] fetch ship info from: %s - %j", i.requestId, n, o), a.code !== "0")
|
|
402
402
|
return a;
|
|
403
403
|
const e = a.data;
|
|
404
404
|
let d = e.imo;
|
|
405
|
-
return t === "407170" && (d = "9198379",
|
|
405
|
+
return t === "407170" && (d = "9198379", l == null || l.warn("[%s] ship(%s) imo error: %s, should be %s", i.requestId, t, e.imo, d)), {
|
|
406
406
|
mmsi: e.mmsi,
|
|
407
407
|
name: e.shipnameEn,
|
|
408
408
|
imo: d,
|
|
@@ -420,39 +420,39 @@ class yt extends K {
|
|
|
420
420
|
json: {
|
|
421
421
|
shipId: o
|
|
422
422
|
}
|
|
423
|
-
}, e = "https://api3.myships.com/sp/ships/position/latest", d = await
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
for (const
|
|
427
|
-
!isNaN(
|
|
428
|
-
const { labelCn:
|
|
423
|
+
}, e = "https://api3.myships.com/sp/ships/position/latest", d = await C.post(e, a).json();
|
|
424
|
+
l == null || l.info("[%s] fetch realtime position from: %s - %j", i.requestId, e, a);
|
|
425
|
+
const r = d.data[0];
|
|
426
|
+
for (const f in r)
|
|
427
|
+
!isNaN(r[f]) && Number(r[f]) !== 1 / 0 && (r[f] = Number(r[f]));
|
|
428
|
+
const { labelCn: c, labelEn: h } = await this.parseStatus(r.aisNavStatus), y = b.unix(r.posTime);
|
|
429
429
|
return {
|
|
430
430
|
...n,
|
|
431
431
|
mmsi: t,
|
|
432
|
-
lat: Math.round(
|
|
433
|
-
lng: Math.round(
|
|
434
|
-
sog: Math.round(
|
|
435
|
-
cog: Math.round(
|
|
436
|
-
hdg: Math.round(
|
|
437
|
-
rot: Math.round(
|
|
438
|
-
positionTime:
|
|
439
|
-
utc:
|
|
440
|
-
status:
|
|
441
|
-
labelEn:
|
|
442
|
-
labelCn:
|
|
432
|
+
lat: Math.round(r.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
433
|
+
lng: Math.round(r.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
434
|
+
sog: Math.round(r.sog / 10 * 100) / 100,
|
|
435
|
+
cog: Math.round(r.cog / 10 * 100) / 100,
|
|
436
|
+
hdg: Math.round(r.heading * 100) / 100,
|
|
437
|
+
rot: Math.round(r.rot * 100) / 100,
|
|
438
|
+
positionTime: r.posTime,
|
|
439
|
+
utc: y.utc().format(),
|
|
440
|
+
status: r.aisNavStatus,
|
|
441
|
+
labelEn: h,
|
|
442
|
+
labelCn: c,
|
|
443
443
|
method: "position",
|
|
444
444
|
vendor: "myship"
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
447
|
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
448
|
-
const d = b(i),
|
|
449
|
-
for (;
|
|
450
|
-
await this.trajectoryIn30Day(
|
|
451
|
-
return await this.trajectoryIn30Day(
|
|
452
|
-
}
|
|
453
|
-
async trajectoryIn30Day(t, i, o, n, a, e, d,
|
|
454
|
-
var
|
|
455
|
-
const
|
|
448
|
+
const d = b(i), r = b(o), c = await this.getShipId(t), h = await this.getShipInfo(c), y = [];
|
|
449
|
+
for (; r.diff(d, "day", !0) > 30; )
|
|
450
|
+
await this.trajectoryIn30Day(c, d.unix(), d.add(30, "day").unix(), h, t, n, y);
|
|
451
|
+
return await this.trajectoryIn30Day(c, d.unix(), r.unix(), h, t, n, y), y;
|
|
452
|
+
}
|
|
453
|
+
async trajectoryIn30Day(t, i, o, n, a, e, d, r = {}) {
|
|
454
|
+
var j;
|
|
455
|
+
const c = {
|
|
456
456
|
headers: {
|
|
457
457
|
appKey: this.token
|
|
458
458
|
},
|
|
@@ -461,41 +461,41 @@ class yt extends K {
|
|
|
461
461
|
startTime: i,
|
|
462
462
|
endTime: o
|
|
463
463
|
}
|
|
464
|
-
},
|
|
465
|
-
if (
|
|
466
|
-
return
|
|
467
|
-
const
|
|
468
|
-
for (const
|
|
469
|
-
!isNaN(
|
|
470
|
-
const
|
|
471
|
-
let
|
|
472
|
-
for (const
|
|
473
|
-
const
|
|
464
|
+
}, h = "https://api3.myships.com/sp/ships/position/history", y = await C.post(h, c).json();
|
|
465
|
+
if (l == null || l.info("[%s] fetch trajectory from: %s - %j", r.requestId, h, c), y.code !== "0")
|
|
466
|
+
return l == null || l.warn("[%s] invoke myship trajectory failed: %j", r.requestId, y), y;
|
|
467
|
+
const M = y.data;
|
|
468
|
+
for (const w in M)
|
|
469
|
+
!isNaN(M[w]) && Number(M[w]) !== 1 / 0 && (M[w] = Number(M[w]));
|
|
470
|
+
const f = b.unix((j = M[0]) == null ? void 0 : j.posTime);
|
|
471
|
+
let Y = -1;
|
|
472
|
+
for (const w of M) {
|
|
473
|
+
const g = b.unix(w.posTime), m = {
|
|
474
474
|
imo: n == null ? void 0 : n.imo,
|
|
475
475
|
mmsi: a,
|
|
476
|
-
lat: Math.round(
|
|
477
|
-
lng: Math.round(
|
|
478
|
-
sog: Math.round(
|
|
479
|
-
cog: Math.round(
|
|
480
|
-
hdg: Math.round(
|
|
481
|
-
rot: Math.round(
|
|
482
|
-
positionTime:
|
|
483
|
-
utc:
|
|
476
|
+
lat: Math.round(w.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
477
|
+
lng: Math.round(w.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
478
|
+
sog: Math.round(w.sog / 10 * 100) / 100,
|
|
479
|
+
cog: Math.round(w.cog / 10 * 100) / 100,
|
|
480
|
+
hdg: Math.round(w.heading * 100) / 100,
|
|
481
|
+
rot: Math.round(w.rot * 100) / 100,
|
|
482
|
+
positionTime: g.unix(),
|
|
483
|
+
utc: g.utc().format(),
|
|
484
484
|
method: "trajectory",
|
|
485
485
|
vendor: "myship"
|
|
486
|
-
},
|
|
487
|
-
|
|
486
|
+
}, v = Math.floor(g.diff(f, "minute", !0) / (e || 1));
|
|
487
|
+
v !== Y && (Y = v, d.push(m));
|
|
488
488
|
}
|
|
489
489
|
return d;
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
|
-
let
|
|
492
|
+
let P;
|
|
493
493
|
try {
|
|
494
|
-
|
|
494
|
+
P = z.getLogger("vessel");
|
|
495
495
|
} catch {
|
|
496
496
|
} finally {
|
|
497
497
|
}
|
|
498
|
-
var at = /* @__PURE__ */ ((
|
|
498
|
+
var at = /* @__PURE__ */ ((k) => (k.NOTICE = "NOTICE", k.WARN = "WARN", k.HEAVY = "HEAVY", k.SEVERE = "SEVERE", k.ERROR = "ERROR", k.FATAL = "FATAL", k))(at || {});
|
|
499
499
|
class ot {
|
|
500
500
|
/**
|
|
501
501
|
* 解析告警规则, 多规则场景
|
|
@@ -506,20 +506,20 @@ class ot {
|
|
|
506
506
|
* @param options
|
|
507
507
|
*/
|
|
508
508
|
parsePrinciple(s, t = {}) {
|
|
509
|
-
var e, d,
|
|
510
|
-
|
|
509
|
+
var e, d, r;
|
|
510
|
+
P == null || P.info("[%s] parse rule: %s", t.requestId, s);
|
|
511
511
|
const i = new RegExp("(?<=\\[)(.+)(?=])", "g"), o = s.match(i) ? (e = s.match(i)) == null ? void 0 : e[0] : void 0, n = o == null ? void 0 : o.split(";");
|
|
512
512
|
if (!n)
|
|
513
513
|
return;
|
|
514
514
|
const a = {};
|
|
515
|
-
for (let
|
|
516
|
-
const
|
|
517
|
-
if (
|
|
515
|
+
for (let c = 0; c < (n == null ? void 0 : n.length); c++) {
|
|
516
|
+
const h = (r = (d = n[c].match(i)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
|
|
517
|
+
if (c === 0 && !h)
|
|
518
518
|
a.scope = n[0];
|
|
519
|
-
else if (
|
|
520
|
-
for (let
|
|
521
|
-
const
|
|
522
|
-
|
|
519
|
+
else if (h)
|
|
520
|
+
for (let y = 0, M = h.length; y < M; y++) {
|
|
521
|
+
const f = this.parseRule(h[y]);
|
|
522
|
+
f && (a[f.level] ? f.key ? a[f.level][f == null ? void 0 : f.key] = f : a[f.level] = f : f.key ? a[f.level] = { [f == null ? void 0 : f.key]: f } : a[f.level] = f);
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
525
|
return a;
|
|
@@ -532,7 +532,7 @@ class ot {
|
|
|
532
532
|
*/
|
|
533
533
|
parseRule(s, t = {}) {
|
|
534
534
|
var a;
|
|
535
|
-
|
|
535
|
+
P == null || P.info("[%s] parse rule: %s", t.requestId, s), s = s.startsWith("[") ? s : `[${s}`, s = s.endsWith("]") ? s : `${s}]`;
|
|
536
536
|
const i = new RegExp("(?<=\\[)(.+?)(?=])", "g"), o = (a = s == null ? void 0 : s.match(i)) == null ? void 0 : a[0], n = o == null ? void 0 : o.split(",");
|
|
537
537
|
if (n)
|
|
538
538
|
return {
|
|
@@ -550,14 +550,14 @@ class ot {
|
|
|
550
550
|
* @param options
|
|
551
551
|
*/
|
|
552
552
|
checkWeather(s, t, i = {}) {
|
|
553
|
-
var
|
|
553
|
+
var f, Y, j, w, g, m, v, p, u, S, W, T, L, N, R;
|
|
554
554
|
let o = 0, n = 0, a = 0, e = 0;
|
|
555
|
-
const d = Math.round(((
|
|
556
|
-
for (let
|
|
557
|
-
const
|
|
558
|
-
e = _ > e ? _ : e,
|
|
555
|
+
const d = Math.round(((Y = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.sigWave) == null ? void 0 : Y.number) * 1.6 * 100) / 100, r = (w = (j = t == null ? void 0 : t.SEVERE) == null ? void 0 : j.sigWave) == null ? void 0 : w.number, c = (m = (g = t == null ? void 0 : t.HEAVY) == null ? void 0 : g.sigWave) == null ? void 0 : m.number, h = Math.round((((p = (v = t == null ? void 0 : t.SEVERE) == null ? void 0 : v.wind) == null ? void 0 : p.number) + 2) * 100) / 100, y = (S = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : S.number, M = (T = (W = t == null ? void 0 : t.HEAVY) == null ? void 0 : W.wind) == null ? void 0 : T.number;
|
|
556
|
+
for (let A = 0; A < (s == null ? void 0 : s.length); A++) {
|
|
557
|
+
const I = s[A], D = (N = (L = I == null ? void 0 : I.meteo) == null ? void 0 : L.wave) == null ? void 0 : N.sig, q = (R = I == null ? void 0 : I.meteo) == null ? void 0 : R.wind, _ = A ? b(I.eta).diff(b(s[A - 1].eta), "hour", !0) : 0;
|
|
558
|
+
e = _ > e ? _ : e, P == null || P.info("[%s] check sig.wave: %j", i.requestId, { ...D, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: c }), (D == null ? void 0 : D.height) >= d ? I.isDangerous = !0 : (D == null ? void 0 : D.height) >= r ? I.isSevere = !0 : (D == null ? void 0 : D.height) >= c && (I.isHeavy = !0), P == null || P.info("[%s] check wind: %j", i.requestId, { ...q, dgThd4Wd: h, svThd4Wd: y, hvThd4Wd: M }), (q == null ? void 0 : q.scale) >= h ? (I.isDangerous = !0, delete I.isSevere, delete I.isHeavy) : (q == null ? void 0 : q.scale) > y ? (I.isDangerous || (I.isSevere = !0), delete I.isHeavy) : (q == null ? void 0 : q.scale) === M && !I.isDangerous && !I.isSevere && (I.isHeavy = !0), o += I.isDangerous ? _ : 0, n += I.isSevere ? _ : 0, a += I.isHeavy ? _ : 0;
|
|
559
559
|
}
|
|
560
|
-
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:
|
|
560
|
+
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: h, svThd4Wd: y, hvThd4Wd: M }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: c } };
|
|
561
561
|
}
|
|
562
562
|
}
|
|
563
563
|
const gt = new ot();
|
|
@@ -567,8 +567,8 @@ try {
|
|
|
567
567
|
} catch {
|
|
568
568
|
} finally {
|
|
569
569
|
}
|
|
570
|
-
var nt = /* @__PURE__ */ ((
|
|
571
|
-
class
|
|
570
|
+
var nt = /* @__PURE__ */ ((k) => (k.common = "common", k.container = "container", k))(nt || {}), it = /* @__PURE__ */ ((k) => (k.Ballast = "Ballast", k.Laden = "Laden", k))(it || {}), rt = /* @__PURE__ */ ((k) => (k.Cp = "CP", k.Perf = "Basis", k.Instruct = "Other", k))(rt || {});
|
|
571
|
+
class E {
|
|
572
572
|
/**
|
|
573
573
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
574
574
|
* 方形系数(block coefficient)
|
|
@@ -678,11 +678,11 @@ class q {
|
|
|
678
678
|
* @private
|
|
679
679
|
*/
|
|
680
680
|
static assembleProperties(s, t, i, o) {
|
|
681
|
-
var
|
|
681
|
+
var c, h;
|
|
682
682
|
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;
|
|
683
683
|
return {
|
|
684
684
|
// @ts-ignore
|
|
685
|
-
tag: ((
|
|
685
|
+
tag: ((h = (c = s == null ? void 0 : s.type) == null ? void 0 : c.toLowerCase()) == null ? void 0 : h.indexOf("container")) > -1 ? "container" : "common",
|
|
686
686
|
lbp: n,
|
|
687
687
|
loadCondition: t,
|
|
688
688
|
draught: a,
|
|
@@ -706,26 +706,26 @@ class q {
|
|
|
706
706
|
* @param useRouteParam true 启用设置速度
|
|
707
707
|
*/
|
|
708
708
|
static async speedLoseAt(s, t, i, o = "", n = 2, a = !0, e = !1, d = {}) {
|
|
709
|
-
let
|
|
709
|
+
let r;
|
|
710
710
|
if (t.velocity && e && (s.speed = B.roundPrecision(t.velocity * 1852 / 3600, 6)), a) {
|
|
711
|
-
const
|
|
712
|
-
|
|
713
|
-
meteo: { ...
|
|
714
|
-
wxFactor:
|
|
715
|
-
cFactor:
|
|
716
|
-
speed: t.velocity && e ? t.velocity : Math.round((s.speed * 1.943844 +
|
|
711
|
+
const c = await st.queryPointFactor(t.lng, t.lat, i.valueOf(), "wind,wave,current,watertemp", o, d), h = E.weatherFactor(s, c), y = E.currentFactor(s.bearing, c == null ? void 0 : c.current, n);
|
|
712
|
+
r = {
|
|
713
|
+
meteo: { ...c },
|
|
714
|
+
wxFactor: h,
|
|
715
|
+
cFactor: y,
|
|
716
|
+
speed: t.velocity && e ? t.velocity : Math.round((s.speed * 1.943844 + h + y) * 100) / 100,
|
|
717
717
|
eta: i.utc().format("YYYY-MM-DDTHH:mm[Z]"),
|
|
718
718
|
etd: i.utc().format("YYYY-MM-DDTHH:mm[Z]")
|
|
719
719
|
};
|
|
720
720
|
} else
|
|
721
|
-
|
|
721
|
+
r = {
|
|
722
722
|
wxFactor: 0,
|
|
723
723
|
cFactor: 0,
|
|
724
724
|
speed: t.velocity && e ? t.velocity : Math.round((s.speed * 1.943844 + 0 + 0) * 100) / 100,
|
|
725
725
|
eta: i.utc().format("YYYY-MM-DDTHH:mm[Z]"),
|
|
726
726
|
etd: i.utc().format("YYYY-MM-DDTHH:mm[Z]")
|
|
727
727
|
};
|
|
728
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
728
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...r, ...t };
|
|
729
729
|
}
|
|
730
730
|
/**
|
|
731
731
|
* 基于步长计算失速样本
|
|
@@ -740,52 +740,52 @@ class q {
|
|
|
740
740
|
* @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
|
|
741
741
|
* @private
|
|
742
742
|
*/
|
|
743
|
-
static async speedLoseInHoursStep(s, t, i, o, n, a, e = "", d = !0,
|
|
743
|
+
static async speedLoseInHoursStep(s, t, i, o, n, a, e = "", d = !0, r = !1, c = {}) {
|
|
744
744
|
t.utc();
|
|
745
|
-
const
|
|
746
|
-
let
|
|
747
|
-
for (let
|
|
748
|
-
let
|
|
749
|
-
|
|
750
|
-
const
|
|
751
|
-
if (s.bearing =
|
|
752
|
-
|
|
753
|
-
const
|
|
754
|
-
if (o -
|
|
755
|
-
o = o -
|
|
745
|
+
const h = [], y = [];
|
|
746
|
+
let M = 0, f = 0, Y, j;
|
|
747
|
+
for (let w = 0; w < a.length - 1; w++) {
|
|
748
|
+
let g = a[w];
|
|
749
|
+
g.distanceFromStart = n + f;
|
|
750
|
+
const m = a[w + 1];
|
|
751
|
+
if (s.bearing = O.calculateBearing(g, m, !m.gcToPrevious), g.bearing = s.bearing, g.suspend && r) {
|
|
752
|
+
g.eta = g.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), g.elapsed = g.elapsed ?? 0;
|
|
753
|
+
const u = g.suspend - g.elapsed;
|
|
754
|
+
if (o - M > u)
|
|
755
|
+
o = o - M - u, t.add(u, "hour"), g.elapsed = g.suspend;
|
|
756
756
|
else {
|
|
757
|
-
const
|
|
758
|
-
|
|
757
|
+
const S = o - M;
|
|
758
|
+
g.elapsed += S, t.add(S, "hour"), o = 0;
|
|
759
759
|
}
|
|
760
|
-
if (H == null || H.info(`[%s] suspend ${
|
|
761
|
-
return
|
|
760
|
+
if (H == null || H.info(`[%s] suspend ${g.elapsed} hours at %j, and remain ${o} hours need to go...`, c.requestId, g), o === 0)
|
|
761
|
+
return g.distanceFromPrevious = f, { etd: t, from: j || g, to: g, next: a.filter((S) => S), wps: h, days: y };
|
|
762
762
|
}
|
|
763
|
-
|
|
764
|
-
const
|
|
765
|
-
let
|
|
766
|
-
if (
|
|
767
|
-
if (
|
|
768
|
-
`[%s] go to %j from %j with ${
|
|
769
|
-
|
|
770
|
-
{ lat:
|
|
771
|
-
{ lat:
|
|
772
|
-
),
|
|
773
|
-
|
|
763
|
+
g = await E.speedLoseAt(s, g, t, e, 0, d, r, c), j = j || g, g.important && h.push(g), t.isSameOrAfter(i) && (y.push(g), i.add(24, "hour"));
|
|
764
|
+
const v = O.calculateDistance(g, m, !m.gcToPrevious);
|
|
765
|
+
let p = Math.ceil(v / j.speed * 1e4) / 1e4;
|
|
766
|
+
if (M + p < o) {
|
|
767
|
+
if (M += p, t.add(p, "hour"), delete a[w], H == null || H.info(
|
|
768
|
+
`[%s] go to %j from %j with ${v}nm, and cost ${p} hours`,
|
|
769
|
+
c.requestId,
|
|
770
|
+
{ lat: m.lat, lng: m.lng },
|
|
771
|
+
{ lat: j.lat, lng: j.lng, etd: j.etd }
|
|
772
|
+
), f += v, a.filter((u) => u).length <= 1) {
|
|
773
|
+
Y = m, Y.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), Y.distanceFromPrevious = v, Y.distanceFromStart = n + f, h.push(Y), delete a[w + 1];
|
|
774
774
|
break;
|
|
775
775
|
}
|
|
776
776
|
} else {
|
|
777
|
-
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
`[%s] go to %j from %j with ${
|
|
781
|
-
|
|
782
|
-
{ lat:
|
|
783
|
-
{ lat:
|
|
784
|
-
),
|
|
777
|
+
p = o - M, t.add(p, "hour");
|
|
778
|
+
const u = B.roundPrecision(j.speed * p, 4);
|
|
779
|
+
Y = O.calculateCoordinate(g, s.bearing, u, "nauticalmiles", !m.gcToPrevious), Y.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[w] = Y, H == null || H.info(
|
|
780
|
+
`[%s] go to %j from %j with ${u}nm, and cost ${p} hours`,
|
|
781
|
+
c.requestId,
|
|
782
|
+
{ lat: Y.lat, lng: Y.lng },
|
|
783
|
+
{ lat: g.lat, lng: g.lng, etd: g.etd }
|
|
784
|
+
), f += u, Y.distanceFromPrevious = f, Y.distanceFromStart = n + f;
|
|
785
785
|
break;
|
|
786
786
|
}
|
|
787
787
|
}
|
|
788
|
-
return { etd: t, from:
|
|
788
|
+
return { etd: t, from: j, to: Y, next: a.filter((w) => w), wps: h, days: y };
|
|
789
789
|
}
|
|
790
790
|
/**
|
|
791
791
|
* 洋流影响因子
|
|
@@ -806,16 +806,16 @@ class q {
|
|
|
806
806
|
* @param wwc 气象要素
|
|
807
807
|
*/
|
|
808
808
|
static weatherFactor(s, t) {
|
|
809
|
-
var
|
|
809
|
+
var h, y, M, f, Y;
|
|
810
810
|
H == null || H.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
811
|
-
const i =
|
|
812
|
-
let a = Math.abs(s.bearing % 360 - (((
|
|
811
|
+
const i = E.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), o = E.froudeNumber(s.speed, s.lbp), n = E.amendFactor(i, o, s.loadCondition);
|
|
812
|
+
let a = Math.abs(s.bearing % 360 - (((h = t == null ? void 0 : t.wind) == null ? void 0 : h.degree) % 360 || 0));
|
|
813
813
|
a = a > 180 ? 360 - a : a;
|
|
814
|
-
const e =
|
|
815
|
-
let
|
|
816
|
-
|
|
817
|
-
const
|
|
818
|
-
return
|
|
814
|
+
const e = E.directionFactor(a, (y = t == null ? void 0 : t.wind) == null ? void 0 : y.scale), d = E.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (M = t == null ? void 0 : t.wind) == null ? void 0 : M.scale);
|
|
815
|
+
let r = e * n * d / 100 * s.speed;
|
|
816
|
+
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1;
|
|
817
|
+
const c = E.waveHeightFactor(((Y = (f = t == null ? void 0 : t.wave) == null ? void 0 : f.sig) == null ? void 0 : Y.height) ?? 1);
|
|
818
|
+
return r = r * 0.24 + c * 0.76, H == null || H.debug("weather factor = %s", r), Math.round(r * 100) / 100;
|
|
819
819
|
}
|
|
820
820
|
/**
|
|
821
821
|
* 全程失速分析(走完航程)
|
|
@@ -829,14 +829,14 @@ class q {
|
|
|
829
829
|
* @param useMeteo true 启用气象分析
|
|
830
830
|
* @param useRouteParam
|
|
831
831
|
*/
|
|
832
|
-
static async analyseInstant(s, t, i, o, n, a = "", e = 0, d = !0,
|
|
832
|
+
static async analyseInstant(s, t, i, o, n, a = "", e = 0, d = !0, r = !1, c = {}) {
|
|
833
833
|
var _, G, U, J, Q;
|
|
834
|
-
const
|
|
834
|
+
const h = b().valueOf();
|
|
835
835
|
s.lng = B.convertToStdLng(s.lng);
|
|
836
|
-
const { route:
|
|
837
|
-
if (((_ =
|
|
836
|
+
const { route: y, waypoints: M } = n.points, f = O.calculateSubRoute(s, y);
|
|
837
|
+
if (((_ = f[0]) == null ? void 0 : _.length) <= 1)
|
|
838
838
|
return;
|
|
839
|
-
const { v0:
|
|
839
|
+
const { v0: Y, label: j } = s.sog ? {
|
|
840
840
|
v0: s.sog,
|
|
841
841
|
label: "Other"
|
|
842
842
|
/* Instruct */
|
|
@@ -844,51 +844,51 @@ class q {
|
|
|
844
844
|
v0: o.speed,
|
|
845
845
|
label: "CP"
|
|
846
846
|
/* Cp */
|
|
847
|
-
},
|
|
847
|
+
}, w = E.assembleProperties(i, o.loadCondition, Y, 0), g = M.length ? O.calculateSubWaypoints(s, M) : [], m = {
|
|
848
848
|
from: { ...s },
|
|
849
|
-
route:
|
|
850
|
-
waypoints:
|
|
851
|
-
v0:
|
|
852
|
-
label:
|
|
853
|
-
},
|
|
849
|
+
route: f,
|
|
850
|
+
waypoints: g,
|
|
851
|
+
v0: Y,
|
|
852
|
+
label: j
|
|
853
|
+
}, v = {
|
|
854
854
|
hours: [],
|
|
855
855
|
days: [],
|
|
856
856
|
wps: []
|
|
857
857
|
};
|
|
858
|
-
e || (
|
|
859
|
-
let
|
|
858
|
+
e || (O.calculateRouteDistance(f) / o.speed <= 72 ? e = 3 : e = 6);
|
|
859
|
+
let p = O.simplifyRouteToCoordinates(f, g, 0), u = 0, S = 0, W = 0, T = 0;
|
|
860
860
|
t = b(t).utc();
|
|
861
|
-
const
|
|
862
|
-
for (;
|
|
863
|
-
const
|
|
864
|
-
|
|
861
|
+
const L = t.clone();
|
|
862
|
+
for (; p.length > 0; ) {
|
|
863
|
+
const F = e - t.hour() % e, V = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, x = await E.speedLoseInHoursStep(
|
|
864
|
+
w,
|
|
865
865
|
t,
|
|
866
|
-
|
|
866
|
+
L,
|
|
867
867
|
V,
|
|
868
|
-
|
|
869
|
-
|
|
868
|
+
u,
|
|
869
|
+
p,
|
|
870
870
|
a,
|
|
871
871
|
d,
|
|
872
|
-
|
|
873
|
-
|
|
872
|
+
r,
|
|
873
|
+
c
|
|
874
874
|
);
|
|
875
|
-
(G = x.from) != null && G.speed && (
|
|
875
|
+
(G = x.from) != null && G.speed && (v.hours.push(x.from), v.wps.push(...x.wps), v.days.push(...x.days)), p = x == null ? void 0 : x.next, p.length || v.hours.push(x == null ? void 0 : x.to), u += ((U = x == null ? void 0 : x.to) == null ? void 0 : U.distanceFromPrevious) ?? 0;
|
|
876
876
|
}
|
|
877
|
-
const
|
|
878
|
-
for (let
|
|
879
|
-
const V = b(
|
|
880
|
-
|
|
877
|
+
const N = v.hours;
|
|
878
|
+
for (let F = 0; F < N.length - 1; F++) {
|
|
879
|
+
const V = b(N[F + 1].eta).diff(N[F].etd, "hour", !0) || 1;
|
|
880
|
+
S += N[F].wxFactor || 0 * V, W += N[F].cFactor || 0 * V, T += V;
|
|
881
881
|
}
|
|
882
|
-
(J =
|
|
882
|
+
(J = v.wps) == null || J.forEach((F, V) => {
|
|
883
883
|
if (V) {
|
|
884
|
-
const x =
|
|
885
|
-
X < 1 ?
|
|
884
|
+
const x = v.wps[V - 1], $ = F.distanceFromStart - x.distanceFromStart, X = b(F.eta).diff(b(x.etd), "h", !0);
|
|
885
|
+
X < 1 ? F.avgSpd = x.speed : F.avgSpd = Math.round($ / X * 100) / 100;
|
|
886
886
|
}
|
|
887
|
-
}),
|
|
888
|
-
const
|
|
889
|
-
|
|
890
|
-
const
|
|
891
|
-
return H == null || H.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",
|
|
887
|
+
}), m.sample = v;
|
|
888
|
+
const R = v.hours.at(0), A = v.hours.at(-1);
|
|
889
|
+
m.distance = Math.round(A.distanceFromStart * 1e4) / 1e4, m.etd = b(R.eta).utc().format(), m.eta = b(A.eta).utc().format(), m.wxFactor = Math.round(S / T * 1e4) / 1e4, m.cFactor = Math.round(W / T * 1e4) / 1e4, m.avgSpeed = Math.round(A.distanceFromStart / T * 1e4) / 1e4, m.totalHrs = Math.round(T * 1e4) / 1e4, m.totalFoCons = Math.round((o == null ? void 0 : o.fo) / 24 * m.totalHrs * 1e3) / 1e3, m.totalDgoCons = Math.round((o == null ? void 0 : o.dgo) / 24 * m.totalHrs * 1e3) / 1e3;
|
|
890
|
+
const D = b().valueOf() - h, q = ((Q = v == null ? void 0 : v.hours) == null ? void 0 : Q.length) || 1;
|
|
891
|
+
return H == null || H.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", c == null ? void 0 : c.requestId, D, q, Math.round(D / q * 1e3) / 1e3), m;
|
|
892
892
|
}
|
|
893
893
|
/**
|
|
894
894
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -903,59 +903,60 @@ class q {
|
|
|
903
903
|
* @param useMeteo true 启用气象分析
|
|
904
904
|
* @param useRouteParam
|
|
905
905
|
*/
|
|
906
|
-
static async analyseInstantWithThreshed(s, t, i, o, n, a, e = "",
|
|
907
|
-
var
|
|
906
|
+
static async analyseInstantWithThreshed(s, t, i, o, n, a, e, d = "", r = 3, c = !0, h = !1, y = {}) {
|
|
907
|
+
var N, R, A;
|
|
908
908
|
s.lng = B.convertToStdLng(s.lng);
|
|
909
|
-
const M =
|
|
910
|
-
if (((
|
|
909
|
+
const M = E.assembleProperties(o, n.loadCondition, n.speed, 0), f = O.calculateSubRoute(s, a);
|
|
910
|
+
if (((N = f[0]) == null ? void 0 : N.length) <= 1)
|
|
911
911
|
return;
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
912
|
+
const Y = e.length ? O.calculateSubWaypoints(s, e) : [];
|
|
913
|
+
let j = O.simplifyRouteToCoordinates(f, Y, 0);
|
|
914
|
+
j.forEach((I) => I.important = !0);
|
|
915
|
+
let w = 0, g = 0, m = 0, v = 0, p;
|
|
916
|
+
const u = {
|
|
916
917
|
hours: [],
|
|
917
918
|
wps: [],
|
|
918
919
|
days: []
|
|
919
920
|
};
|
|
920
|
-
for (t = b(t).utc();
|
|
921
|
-
const
|
|
922
|
-
let
|
|
923
|
-
if (
|
|
924
|
-
|
|
921
|
+
for (t = b(t).utc(); j.length > 0; ) {
|
|
922
|
+
const I = r - t.hour() % r;
|
|
923
|
+
let D = Math.ceil(t.clone().add(I, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
924
|
+
if (D = t.clone().add(D, "h").isAfter(i) ? i.diff(t, "h", !0) * 1e4 / 1e4 : D, D)
|
|
925
|
+
p = await E.speedLoseInHoursStep(
|
|
925
926
|
M,
|
|
926
927
|
t,
|
|
927
928
|
i.clone(),
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
929
|
+
D,
|
|
930
|
+
w,
|
|
931
|
+
j,
|
|
932
|
+
d,
|
|
932
933
|
c,
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
), (
|
|
934
|
+
h,
|
|
935
|
+
y
|
|
936
|
+
), (R = p.from) != null && R.speed && (u.hours.push(p.from), p != null && p.wps && u.wps.push(...p.wps), u.days.push(...p.days)), j = p == null ? void 0 : p.next, j.length || (u.hours.push(p == null ? void 0 : p.to), p != null && p.wps && u.wps.push(...p.wps), u.days.push(p == null ? void 0 : p.to)), w += ((A = p == null ? void 0 : p.to) == null ? void 0 : A.distanceFromPrevious) ?? 0;
|
|
936
937
|
else {
|
|
937
|
-
|
|
938
|
+
p && (u.hours.push(p.to), p != null && p.wps && u.wps.push(...p.wps), u.days.push(p.to));
|
|
938
939
|
break;
|
|
939
940
|
}
|
|
940
941
|
}
|
|
941
|
-
const
|
|
942
|
-
for (let
|
|
943
|
-
const
|
|
944
|
-
|
|
942
|
+
const S = u.hours;
|
|
943
|
+
for (let I = 0; I < S.length - 1; I++) {
|
|
944
|
+
const D = b(S[I + 1].eta).diff(S[I].etd, "hour", !0);
|
|
945
|
+
g += S[I].wxFactor * D, m += S[I].cFactor * D, v += D;
|
|
945
946
|
}
|
|
946
|
-
const
|
|
947
|
+
const W = u.hours.at(0), T = u.hours.at(-1);
|
|
947
948
|
return {
|
|
948
|
-
sample:
|
|
949
|
-
distance: Math.round(((
|
|
949
|
+
sample: u,
|
|
950
|
+
distance: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
950
951
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
951
|
-
etd: b(
|
|
952
|
-
eta: b(
|
|
953
|
-
wxFactor: Math.round(
|
|
954
|
-
cFactor: Math.round(
|
|
955
|
-
avgSpeed: Math.round(((
|
|
956
|
-
totalHrs: Math.round(
|
|
957
|
-
to:
|
|
958
|
-
route:
|
|
952
|
+
etd: b(W.eta).utc().format(),
|
|
953
|
+
eta: b(T == null ? void 0 : T.eta).utc().format(),
|
|
954
|
+
wxFactor: Math.round(g / v * 1e4) / 1e4,
|
|
955
|
+
cFactor: Math.round(m / v * 1e4) / 1e4,
|
|
956
|
+
avgSpeed: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) / v * 1e4) / 1e4,
|
|
957
|
+
totalHrs: Math.round(v * 1e4) / 1e4,
|
|
958
|
+
to: T,
|
|
959
|
+
route: O.generateRouteAccordingToWaypoints(j)
|
|
959
960
|
};
|
|
960
961
|
}
|
|
961
962
|
}
|
|
@@ -968,7 +969,7 @@ export {
|
|
|
968
969
|
yt as MyShipImpl,
|
|
969
970
|
mt as MyVesselImpl,
|
|
970
971
|
Mt as ShipxyImpl,
|
|
971
|
-
|
|
972
|
+
E as SpeedHelper,
|
|
972
973
|
rt as SpeedLabel,
|
|
973
974
|
nt as VesselTag,
|
|
974
975
|
gt as alertHelper
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(j,T){typeof exports=="object"&&typeof module<"u"?T(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"],T):(j=typeof globalThis<"u"?globalThis:j||self,T(j["idm-plugin-rabbitmq"]={},j.got,j["@log4js-node/log4js-api"],j.moment,j["@idm-plugin/geo"],j["@idm-plugin/meteo"]))})(this,function(j,T,_,v,P,nt){"use strict";var ht=Object.defineProperty;var lt=(j,T,_)=>T in j?ht(j,T,{enumerable:!0,configurable:!0,writable:!0,value:_}):j[T]=_;var K=(j,T,_)=>(lt(j,typeof T!="symbol"?T+"":T,_),_);let l;try{l=_.getLogger("vessel")}catch{}finally{}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 ot extends z{constructor(t,i){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",n={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await T.post(i,n).json();l==null||l.info("[%s] fetch access token from: %s - %j",t.requestId,i,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:v().utc().format()})}async realTimePosition(t,i={}){var u,f,y;(!this.token||v().diff(v(this.token.issuedAt),"seconds")>((u=this.token)==null?void 0:u.expiresIn)-300)&&await this.authToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(y=this.token)==null?void 0:y.accessToken}`},searchParams:{mmsi:t}};l==null||l.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const s=await T.get(n,o).json();if(s.code)return l==null||l.warn("[%s] fetch realtime position failed: %j",i.requestId,n,{message:s.message,status:s.status,code:s.code}),s;const e=s.data;for(const m in e)!isNaN(e[m])&&Number(e[m])!==1/0&&(e[m]=Number(e[m]));const d=v(`${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,n,o,s=!0,e={}){(!this.token||v().diff(v(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const d=await this.realTimePosition(t,e),c=v(i),u=v(n),f=[];for(;u.diff(c,"day",!0)>30;)await this.trajectoryIn30Day(t,c,c.clone().add(30,"day"),d,o,f,e),c.add(30,"day");return await this.trajectoryIn30Day(t,c,u,d,o,f,e),f}async trajectoryIn30Day(t,i,n,o,s,e,d={}){var h,g,k,Y,p;const c="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(h=this.token)==null?void 0:h.tokenType} ${(g=this.token)==null?void 0:g.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};l==null||l.info("[%s] fetch trajectory from: %s - %j",d.requestId,c,u);const f=await T.post(c,u).json();if(f.code)return l==null||l.warn("[%s] fetch trajectory failed: %j",d.requestId,c,{message:f.message,status:f.status,code:f.code}),f;let y=-1;const m=v(`${(Y=(k=f.data)==null?void 0:k[0])==null?void 0:Y.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(p=f.data)==null||p.forEach(r=>{for(const F in r)!isNaN(r[F])&&Number(r[F])!==1/0&&(r[F]=Number(r[F]));const M=v(`${r.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),I=r.eta?v(`${r.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,b=r.status,{labelCn:H,labelEn:V}=this.parseStatus(b),L={mmsi:r.mmsi,imo:o==null?void 0:o.imo,lat:r.lat,lng:r.lon,sog:r.sog,cog:r.cog,hdg:r.hdg,draught:r.draught,status:b,eta:I==null?void 0:I.unix(),destination:r.dest,positionTime:M.unix(),labelCn:H,labelEn:V,method:"trajectory",vendor:"myVessel",utc:M.utc().format()},W=Math.floor(M.diff(m,"minute",!0)/(s||1));W!==y&&(y=W,e.push(L))}),e}}class it extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:t,usertoken:this.token}},s=await T.post(n,o).json();l==null||l.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const e=s==null?void 0:s.list;if(!e)return l==null||l.warn("[%s] fetch realtime position failed: %j",i.requestId,n,s),s;for(const m in e)!isNaN(e[m])&&Number(e[m])!==1/0&&(e[m]=Number(e[m]));e.status=e.sp>3?0:1;const d=e.status,{labelCn:c,labelEn:u}=this.parseStatus(d),f=v(`${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)?v(`${e.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:e.destination,positionTime:f.unix(),utc:f.utc().format(),status:d,labelCn:c,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,i={}){let n="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let s=await T.post(n,o).json();l==null||l.info("[%s] fetch vessel props from: %s - %j",i.requestId,n,o),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 n="https://www.hifleet.com/hifleetapi/sameShipSearch.do",s=await T.post(n,o).json(),l==null||l.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,n,o),s instanceof Array&&(s=s[0]),s&&(e.deadweight=Number(s.dwt)),e}async trajectory(t,i,n,o,s=!0,e={}){var r,M,I;const d=await this.realTimePosition(t,e);let c=v(i);const u=v(n),f=v();if(s){let b=u.diff(c,"d",!0);b<0?c=u.clone().subtract(40,"d"):b<30?c.subtract(10,"d"):b<60?c.subtract(5,"d"):c=u.clone().subtract(80,"d"),b=f.diff(u,"d",!0),u.add(b>10?240:b*24,"h")}const y={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:c.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},m="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",h=await T.get(m,y).json();l==null||l.info("[%s] fetch trajectory from: %s - %j",e.requestId,m,y);let g;h&&(g=((M=(r=h.ships)==null?void 0:r.offors)==null?void 0:M.ship)||[],g.length||l==null||l.warn("[%s] fetch trajectory failed: %j",e.requestId,h));const k=[];let Y=-1;const p=v(`${(I=g==null?void 0:g[0])==null?void 0:I.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const b of g){for(const D in b)!isNaN(b[D])&&Number(b[D])!==1/0&&(b[D]=Number(b[D]));const H=v(`${b.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");b.status=b.sp>4?0:1;const{labelEn:V,labelCn:L}=this.parseStatus(b.status),W={mmsi:b.m,name:b.n,imo:d==null?void 0:d.imo,lat:b.la,lng:b.lo,draught:b.draught,sog:b.sp,cog:b.co,hdg:b.hdg,positionTime:H.unix(),utc:H.utc().format(),status:b.status,labelCn:L,labelEn:V,method:"trajectory",vendor:"hifleet"},F=Math.floor(H.diff(p,"minute",!0)/(o||1));F!==Y&&(Y=F,k.push(W))}return k}}class rt extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n={searchParams:{id:t,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",s=await T.get(o,n).json();if(l==null||l.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n),(s==null?void 0:s.status)!==0)return s;const e=s.data[0];for(const y in e)!isNaN(e[y])&&Number(e[y])!==1/0&&(e[y]=Number(e[y]));const{labelCn:d,labelEn:c}=await this.parseStatus(e.navistat),u=v.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:u.utc().format(),status:e.navistat,labelEn:c,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,i,n,o,s=!0,e={}){var p;const d=await this.realTimePosition(t,e),c=v(i),u=v(n),f="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:c.unix(),etm:u.unix()}},m=await T.get(f,y).json();if(l==null||l.info("[%s] fetch trajectory from: %s - %j",e.requestId,f,y),(m==null?void 0:m.status)!==0)return m;const h=m==null?void 0:m.points,g=[],k=v.unix((p=h[0])==null?void 0:p.utc);let Y=-1;for(const r of h){const M=v.unix(r.utc),I={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(r.sog*3600/1e3/1852*100)/100,cog:Math.round(r.cog/100*100)/100,lat:Math.round(r.lat/1e6*1e5)/1e5,lng:Math.round(r.lon/1e6*1e5)/1e5,positionTime:M.unix(),utc:M.utc().format(),method:"trajectory",vendor:"shipxy"},b=Math.floor(M.diff(k,"minute",!0)/(o||1));b!==Y&&(Y=b,g.push(I))}return g}}class ct extends z{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,i={}){const n={headers:{appKey:this.token},json:{mmsiList:t}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",s=await T.post(o,n).json();return l==null||l.info("[%s] fetch ship id from: %s - %j",i.requestId,o,n),s.code!=="0"?s:s.data[0].shipId}async getShipInfo(t,i={}){const n={headers:{appKey:this.token},json:{shipId:t}},o="https://api3.myships.com/sp/ships/aissta",s=await T.post(o,n).json();if(l==null||l.info("[%s] fetch ship info from: %s - %j",i.requestId,o,n),s.code!=="0")return s;const e=s.data;let d=e.imo;return t==="407170"&&(d="9198379",l==null||l.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 n=await this.getShipId(t,i),o=await this.getShipInfo(n,i),s={headers:{appKey:this.token},json:{shipId:n}},e="https://api3.myships.com/sp/ships/position/latest",d=await T.post(e,s).json();l==null||l.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,s);const c=d.data[0];for(const h in c)!isNaN(c[h])&&Number(c[h])!==1/0&&(c[h]=Number(c[h]));const{labelCn:u,labelEn:f}=await this.parseStatus(c.aisNavStatus),y=v.unix(c.posTime);return{...o,mmsi:t,lat:Math.round(c.lat/1e4/60*1e5)/1e5,lng:Math.round(c.lon/1e4/60*1e5)/1e5,sog:Math.round(c.sog/10*100)/100,cog:Math.round(c.cog/10*100)/100,hdg:Math.round(c.heading*100)/100,rot:Math.round(c.rot*100)/100,positionTime:c.posTime,utc:y.utc().format(),status:c.aisNavStatus,labelEn:f,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,i,n,o,s=!0,e={}){const d=v(i),c=v(n),u=await this.getShipId(t),f=await this.getShipInfo(u),y=[];for(;c.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(u,d.unix(),d.add(30,"day").unix(),f,t,o,y);return await this.trajectoryIn30Day(u,d.unix(),c.unix(),f,t,o,y),y}async trajectoryIn30Day(t,i,n,o,s,e,d,c={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:n}},f="https://api3.myships.com/sp/ships/position/history",y=await T.post(f,u).json();if(l==null||l.info("[%s] fetch trajectory from: %s - %j",c.requestId,f,u),y.code!=="0")return l==null||l.warn("[%s] invoke myship trajectory failed: %j",c.requestId,y),y;const m=y.data;for(const Y in m)!isNaN(m[Y])&&Number(m[Y])!==1/0&&(m[Y]=Number(m[Y]));const h=v.unix((k=m[0])==null?void 0:k.posTime);let g=-1;for(const Y of m){const p=v.unix(Y.posTime),r={imo:o==null?void 0:o.imo,mmsi:s,lat:Math.round(Y.lat/1e4/60*1e5)/1e5,lng:Math.round(Y.lon/1e4/60*1e5)/1e5,sog:Math.round(Y.sog/10*100)/100,cog:Math.round(Y.cog/10*100)/100,hdg:Math.round(Y.heading*100)/100,rot:Math.round(Y.rot*100)/100,positionTime:p.unix(),utc:p.utc().format(),method:"trajectory",vendor:"myship"},M=Math.floor(p.diff(h,"minute",!0)/(e||1));M!==g&&(g=M,d.push(r))}return d}}let A;try{A=_.getLogger("vessel")}catch{}finally{}var G=(w=>(w.NOTICE="NOTICE",w.WARN="WARN",w.HEAVY="HEAVY",w.SEVERE="SEVERE",w.ERROR="ERROR",w.FATAL="FATAL",w))(G||{});class U{parsePrinciple(a,t={}){var e,d,c;A==null||A.info("[%s] parse rule: %s",t.requestId,a);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),n=a.match(i)?(e=a.match(i))==null?void 0:e[0]:void 0,o=n==null?void 0:n.split(";");if(!o)return;const s={};for(let u=0;u<(o==null?void 0:o.length);u++){const f=(c=(d=o[u].match(i))==null?void 0:d[0])==null?void 0:c.split("],");if(u===0&&!f)s.scope=o[0];else if(f)for(let y=0,m=f.length;y<m;y++){const h=this.parseRule(f[y]);h&&(s[h.level]?h.key?s[h.level][h==null?void 0:h.key]=h:s[h.level]=h:h.key?s[h.level]={[h==null?void 0:h.key]:h}:s[h.level]=h)}}return s}parseRule(a,t={}){var s;A==null||A.info("[%s] parse rule: %s",t.requestId,a),a=a.startsWith("[")?a:`[${a}`,a=a.endsWith("]")?a:`${a}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),n=(s=a==null?void 0:a.match(i))==null?void 0:s[0],o=n==null?void 0:n.split(",");if(o)return{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:Number(o[3]),key:o[4]}}checkWeather(a,t,i={}){var h,g,k,Y,p,r,M,I,b,H,V,L,W,F,D;let n=0,o=0,s=0,e=0;const d=Math.round(((g=(h=t==null?void 0:t.SEVERE)==null?void 0:h.sigWave)==null?void 0:g.number)*1.6*100)/100,c=(Y=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:Y.number,u=(r=(p=t==null?void 0:t.HEAVY)==null?void 0:p.sigWave)==null?void 0:r.number,f=Math.round((((I=(M=t==null?void 0:t.SEVERE)==null?void 0:M.wind)==null?void 0:I.number)+2)*100)/100,y=(H=(b=t==null?void 0:t.SEVERE)==null?void 0:b.wind)==null?void 0:H.number,m=(L=(V=t==null?void 0:t.HEAVY)==null?void 0:V.wind)==null?void 0:L.number;for(let q=0;q<(a==null?void 0:a.length);q++){const S=a[q],R=(F=(W=S==null?void 0:S.meteo)==null?void 0:W.wave)==null?void 0:F.sig,O=(D=S==null?void 0:S.meteo)==null?void 0:D.wind,B=q?v(S.eta).diff(v(a[q-1].eta),"hour",!0):0;e=B>e?B:e,A==null||A.info("[%s] check sig.wave: %j",i.requestId,{...R,dgThd4Wv:d,svThd4Wv:c,hvThd4Wv:u}),(R==null?void 0:R.height)>=d?S.isDangerous=!0:(R==null?void 0:R.height)>=c?S.isSevere=!0:(R==null?void 0:R.height)>=u&&(S.isHeavy=!0),A==null||A.info("[%s] check wind: %j",i.requestId,{...O,dgThd4Wd:f,svThd4Wd:y,hvThd4Wd:m}),(O==null?void 0:O.scale)>=f?(S.isDangerous=!0,delete S.isSevere,delete S.isHeavy):(O==null?void 0:O.scale)>y?(S.isDangerous||(S.isSevere=!0),delete S.isHeavy):(O==null?void 0:O.scale)===m&&!S.isDangerous&&!S.isSevere&&(S.isHeavy=!0),n+=S.isDangerous?B:0,o+=S.isSevere?B:0,s+=S.isHeavy?B:0}return n=Math.round(n*100)/100,o=Math.round(o*100)/100,s=Math.round(s*100)/100,e=Math.round(e),{sample:a,dangerous:n,severe:o,heavy:s,step:e<3?3:e,wind:{dgThd4Wd:f,svThd4Wd:y,hvThd4Wd:m},sig:{dgThd4Wv:d,svThd4Wv:c,hvThd4Wv:u}}}}const dt=new U;let N;try{N=_.getLogger("vessel")}catch{}finally{}var J=(w=>(w.common="common",w.container="container",w))(J||{}),Q=(w=>(w.Ballast="Ballast",w.Laden="Laden",w))(Q||{}),X=(w=>(w.Cp="CP",w.Perf="Basis",w.Instruct="Other",w))(X||{});class E{static blockCoefficient(a,t,i,n){let o=Math.round(a/(t*i*n)*100)/100;o=o<.55?.55:o>.85?.85:o;const s=[.55,.6,.65,.7,.75,.8,.85],e=s.map(d=>Math.abs(d-o));return s[e.indexOf(Math.min(...e))]}static froudeNumber(a,t,i=9.8){let n=Math.round(Math.sqrt(a*a/(i*t))*100)/100;return n=n<.05?.05:n>.3?.3:n,n}static amendFactor(a,t,i){const n={.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=n[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,n=0){n=n>5?n-.9*(n-5):n;let o;return i==="container"?o=.7*n+Math.pow(n,6.5)/(22*Math.pow(a,2/3)):t==="Ballast"?o=.7*n+Math.pow(n,6.5)/(2.7*Math.pow(a,2/3)):o=.5*n+Math.pow(n,6.5)/(2.7*Math.pow(a,2/3)),o}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,n){var u,f;const o=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:((f=(u=a==null?void 0:a.type)==null?void 0:u.toLowerCase())==null?void 0:f.indexOf("container"))>-1?"container":"common",lbp:o,loadCondition:t,draught:s,breadthMoulded:e,displacement:Math.round((d/1.025+s*e*o*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:n||90}}static async speedLoseAt(a,t,i,n="",o=2,s=!0,e=!1,d={}){let c;if(t.velocity&&e&&(a.speed=P.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),s){const u=await nt.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",n,d),f=E.weatherFactor(a,u),y=E.currentFactor(a.bearing,u==null?void 0:u.current,o);c={meteo:{...u},wxFactor:f,cFactor:y,speed:t.velocity&&e?t.velocity:Math.round((a.speed*1.943844+f+y)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")}}else c={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round((a.speed*1.943844+0+0)*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,{...c,...t}}static async speedLoseInHoursStep(a,t,i,n,o,s,e="",d=!0,c=!1,u={}){t.utc();const f=[],y=[];let m=0,h=0,g,k;for(let Y=0;Y<s.length-1;Y++){let p=s[Y];p.distanceFromStart=o+h;const r=s[Y+1];if(a.bearing=P.LaneHelper.calculateBearing(p,r,!r.gcToPrevious),p.bearing=a.bearing,p.suspend&&c){p.eta=p.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),p.elapsed=p.elapsed??0;const b=p.suspend-p.elapsed;if(n-m>b)n=n-m-b,t.add(b,"hour"),p.elapsed=p.suspend;else{const H=n-m;p.elapsed+=H,t.add(H,"hour"),n=0}if(N==null||N.info(`[%s] suspend ${p.elapsed} hours at %j, and remain ${n} hours need to go...`,u.requestId,p),n===0)return p.distanceFromPrevious=h,{etd:t,from:k||p,to:p,next:s.filter(H=>H),wps:f,days:y}}p=await E.speedLoseAt(a,p,t,e,0,d,c,u),k=k||p,p.important&&f.push(p),t.isSameOrAfter(i)&&(y.push(p),i.add(24,"hour"));const M=P.LaneHelper.calculateDistance(p,r,!r.gcToPrevious);let I=Math.ceil(M/k.speed*1e4)/1e4;if(m+I<n){if(m+=I,t.add(I,"hour"),delete s[Y],N==null||N.info(`[%s] go to %j from %j with ${M}nm, and cost ${I} hours`,u.requestId,{lat:r.lat,lng:r.lng},{lat:k.lat,lng:k.lng,etd:k.etd}),h+=M,s.filter(b=>b).length<=1){g=r,g.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),g.distanceFromPrevious=M,g.distanceFromStart=o+h,f.push(g),delete s[Y+1];break}}else{I=n-m,t.add(I,"hour");const b=P.LngLatHelper.roundPrecision(k.speed*I,4);g=P.LaneHelper.calculateCoordinate(p,a.bearing,b,"nauticalmiles",!r.gcToPrevious),g.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),s[Y]=g,N==null||N.info(`[%s] go to %j from %j with ${b}nm, and cost ${I} hours`,u.requestId,{lat:g.lat,lng:g.lng},{lat:p.lat,lng:p.lng,etd:p.etd}),h+=b,g.distanceFromPrevious=h,g.distanceFromStart=o+h;break}}return{etd:t,from:k,to:g,next:s.filter(Y=>Y),wps:f,days:y}}static currentFactor(a,t,i=0){const n=(a-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(n)===Math.PI/2)return 0;let o=((t==null?void 0:t.kts)||0)*Math.cos(n);return i&2?o=Math.ceil(o*100)/100:i&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(a,t){var f,y,m,h,g;N==null||N.debug("calculate weather factor via: %j",{...a,...t});const i=E.blockCoefficient(a.displacement,a.lbp,a.breadthMoulded,a.draught),n=E.froudeNumber(a.speed,a.lbp),o=E.amendFactor(i,n,a.loadCondition);let s=Math.abs(a.bearing%360-(((f=t==null?void 0:t.wind)==null?void 0:f.degree)%360||0));s=s>180?360-s:s;const e=E.directionFactor(s,(y=t==null?void 0:t.wind)==null?void 0:y.scale),d=E.vesselTagFactor(a.displacement,a.loadCondition,a.tag,(m=t==null?void 0:t.wind)==null?void 0:m.scale);let c=e*o*d/100*a.speed;c=Math.round(c*1.943844*1e4)/1e4*-1;const u=E.waveHeightFactor(((g=(h=t==null?void 0:t.wave)==null?void 0:h.sig)==null?void 0:g.height)??1);return c=c*.24+u*.76,N==null||N.debug("weather factor = %s",c),Math.round(c*100)/100}static async analyseInstant(a,t,i,n,o,s="",e=0,d=!0,c=!1,u={}){var B,$,tt,et,st;const f=v().valueOf();a.lng=P.LngLatHelper.convertToStdLng(a.lng);const{route:y,waypoints:m}=o.points,h=P.LaneHelper.calculateSubRoute(a,y);if(((B=h[0])==null?void 0:B.length)<=1)return;const{v0:g,label:k}=a.sog?{v0:a.sog,label:"Other"}:{v0:n.speed,label:"CP"},Y=E.assembleProperties(i,n.loadCondition,g,0),p=m.length?P.LaneHelper.calculateSubWaypoints(a,m):[],r={from:{...a},route:h,waypoints:p,v0:g,label:k},M={hours:[],days:[],wps:[]};e||(P.LaneHelper.calculateRouteDistance(h)/n.speed<=72?e=3:e=6);let I=P.LaneHelper.simplifyRouteToCoordinates(h,p,0),b=0,H=0,V=0,L=0;t=v(t).utc();const W=t.clone();for(;I.length>0;){const C=e-t.hour()%e,Z=Math.ceil(t.clone().add(C,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,x=await E.speedLoseInHoursStep(Y,t,W,Z,b,I,s,d,c,u);($=x.from)!=null&&$.speed&&(M.hours.push(x.from),M.wps.push(...x.wps),M.days.push(...x.days)),I=x==null?void 0:x.next,I.length||M.hours.push(x==null?void 0:x.to),b+=((tt=x==null?void 0:x.to)==null?void 0:tt.distanceFromPrevious)??0}const F=M.hours;for(let C=0;C<F.length-1;C++){const Z=v(F[C+1].eta).diff(F[C].etd,"hour",!0)||1;H+=F[C].wxFactor||0*Z,V+=F[C].cFactor||0*Z,L+=Z}(et=M.wps)==null||et.forEach((C,Z)=>{if(Z){const x=M.wps[Z-1],ut=C.distanceFromStart-x.distanceFromStart,at=v(C.eta).diff(v(x.etd),"h",!0);at<1?C.avgSpd=x.speed:C.avgSpd=Math.round(ut/at*100)/100}}),r.sample=M;const D=M.hours.at(0),q=M.hours.at(-1);r.distance=Math.round(q.distanceFromStart*1e4)/1e4,r.etd=v(D.eta).utc().format(),r.eta=v(q.eta).utc().format(),r.wxFactor=Math.round(H/L*1e4)/1e4,r.cFactor=Math.round(V/L*1e4)/1e4,r.avgSpeed=Math.round(q.distanceFromStart/L*1e4)/1e4,r.totalHrs=Math.round(L*1e4)/1e4,r.totalFoCons=Math.round((n==null?void 0:n.fo)/24*r.totalHrs*1e3)/1e3,r.totalDgoCons=Math.round((n==null?void 0:n.dgo)/24*r.totalHrs*1e3)/1e3;const R=v().valueOf()-f,O=((st=M==null?void 0:M.hours)==null?void 0:st.length)||1;return N==null||N.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,R,O,Math.round(R/O*1e3)/1e3),r}static async analyseInstantWithThreshed(a,t,i,n,o,s,e="",d=3,c=!0,u=!1,f={}){var L,W,F;a.lng=P.LngLatHelper.convertToStdLng(a.lng);const y=E.assembleProperties(n,o.loadCondition,o.speed,0),m=P.LaneHelper.calculateSubRoute(a,s);if(((L=m[0])==null?void 0:L.length)<=1)return;let h=P.LaneHelper.simplifyRouteToCoordinates(m,[],0);h.forEach(D=>D.important=!0);let g=0,k=0,Y=0,p=0,r;const M={hours:[],wps:[],days:[]};for(t=v(t).utc();h.length>0;){const D=d-t.hour()%d;let q=Math.ceil(t.clone().add(D,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(q=t.clone().add(q,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:q,q)r=await E.speedLoseInHoursStep(y,t,i.clone(),q,g,h,e,c,u,f),(W=r.from)!=null&&W.speed&&(M.hours.push(r.from),r!=null&&r.wps&&M.wps.push(...r.wps),M.days.push(...r.days)),h=r==null?void 0:r.next,h.length||(M.hours.push(r==null?void 0:r.to),r!=null&&r.wps&&M.wps.push(...r.wps),M.days.push(r==null?void 0:r.to)),g+=((F=r==null?void 0:r.to)==null?void 0:F.distanceFromPrevious)??0;else{r&&(M.hours.push(r.to),r!=null&&r.wps&&M.wps.push(...r.wps),M.days.push(r.to));break}}const I=M.hours;for(let D=0;D<I.length-1;D++){const q=v(I[D+1].eta).diff(I[D].etd,"hour",!0);k+=I[D].wxFactor*q,Y+=I[D].cFactor*q,p+=q}const b=M.hours.at(0),H=M.hours.at(-1);return{sample:M,distance:Math.round(((H==null?void 0:H.distanceFromStart)||0)*1e4)/1e4,etd:v(b.eta).utc().format(),eta:v(H==null?void 0:H.eta).utc().format(),wxFactor:Math.round(k/p*1e4)/1e4,cFactor:Math.round(Y/p*1e4)/1e4,avgSpeed:Math.round(((H==null?void 0:H.distanceFromStart)||0)/p*1e4)/1e4,totalHrs:Math.round(p*1e4)/1e4,to:H,route:P.LaneHelper.generateRouteAccordingToWaypoints(h)}}}j.AISImpl=z,j.AlertHelper=U,j.AlertLevel=G,j.HifleetImpl=it,j.LoadCondition=Q,j.MyShipImpl=ct,j.MyVesselImpl=ot,j.ShipxyImpl=rt,j.SpeedHelper=E,j.SpeedLabel=X,j.VesselTag=J,j.alertHelper=dt,Object.defineProperty(j,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(H,T){typeof exports=="object"&&typeof module<"u"?T(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"],T):(H=typeof globalThis<"u"?globalThis:H||self,T(H["idm-plugin-rabbitmq"]={},H.got,H["@log4js-node/log4js-api"],H.moment,H["@idm-plugin/geo"],H["@idm-plugin/meteo"]))})(this,function(H,T,_,v,E,nt){"use strict";var ht=Object.defineProperty;var lt=(H,T,_)=>T in H?ht(H,T,{enumerable:!0,configurable:!0,writable:!0,value:_}):H[T]=_;var K=(H,T,_)=>(lt(H,typeof T!="symbol"?T+"":T,_),_);let h;try{h=_.getLogger("vessel")}catch{}finally{}class z{parseStatus(s){let t,i;switch(s){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 ot extends z{constructor(t,i){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",n={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await T.post(i,n).json();h==null||h.info("[%s] fetch access token from: %s - %j",t.requestId,i,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:v().utc().format()})}async realTimePosition(t,i={}){var c,l,M;(!this.token||v().diff(v(this.token.issuedAt),"seconds")>((c=this.token)==null?void 0:c.expiresIn)-300)&&await this.authToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(M=this.token)==null?void 0:M.accessToken}`},searchParams:{mmsi:t}};h==null||h.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const a=await T.get(n,o).json();if(a.code)return h==null||h.warn("[%s] fetch realtime position failed: %j",i.requestId,n,{message:a.message,status:a.status,code:a.code}),a;const e=a.data;for(const y in e)!isNaN(e[y])&&Number(e[y])!==1/0&&(e[y]=Number(e[y]));const d=v(`${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,n,o,a=!0,e={}){(!this.token||v().diff(v(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const d=await this.realTimePosition(t,e),r=v(i),c=v(n),l=[];for(;c.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,o,l,e),r.add(30,"day");return await this.trajectoryIn30Day(t,r,c,d,o,l,e),l}async trajectoryIn30Day(t,i,n,o,a,e,d={}){var f,Y,w,I,b;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",c={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(Y=this.token)==null?void 0:Y.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};h==null||h.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,c);const l=await T.post(r,c).json();if(l.code)return h==null||h.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:l.message,status:l.status,code:l.code}),l;let M=-1;const y=v(`${(I=(w=l.data)==null?void 0:w[0])==null?void 0:I.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(b=l.data)==null||b.forEach(m=>{for(const q in m)!isNaN(m[q])&&Number(m[q])!==1/0&&(m[q]=Number(m[q]));const g=v(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),p=m.eta?v(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,u=m.status,{labelCn:N,labelEn:W}=this.parseStatus(u),S={mmsi:m.mmsi,imo:o==null?void 0:o.imo,lat:m.lat,lng:m.lon,sog:m.sog,cog:m.cog,hdg:m.hdg,draught:m.draught,status:u,eta:p==null?void 0:p.unix(),destination:m.dest,positionTime:g.unix(),labelCn:N,labelEn:W,method:"trajectory",vendor:"myVessel",utc:g.utc().format()},V=Math.floor(g.diff(y,"minute",!0)/(a||1));V!==M&&(M=V,e.push(S))}),e}}class it extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:t,usertoken:this.token}},a=await T.post(n,o).json();h==null||h.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const e=a==null?void 0:a.list;if(!e)return h==null||h.warn("[%s] fetch realtime position failed: %j",i.requestId,n,a),a;for(const y in e)!isNaN(e[y])&&Number(e[y])!==1/0&&(e[y]=Number(e[y]));e.status=e.sp>3?0:1;const d=e.status,{labelCn:r,labelEn:c}=this.parseStatus(d),l=v(`${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)?v(`${e.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:e.destination,positionTime:l.unix(),utc:l.utc().format(),status:d,labelCn:r,labelEn:c,method:"position",vendor:"hifleet"}}async search(t,i={}){let n="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await T.post(n,o).json();h==null||h.info("[%s] fetch vessel props from: %s - %j",i.requestId,n,o),a instanceof Array&&(a=a[0]);for(const d in a)!isNaN(a[d])&&Number(a[d])!==1/0&&(a[d]=Number(a[d]));const e={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr};return n="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await T.post(n,o).json(),h==null||h.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,n,o),a instanceof Array&&(a=a[0]),a&&(e.deadweight=Number(a.dwt)),e}async trajectory(t,i,n,o,a=!0,e={}){var m,g,p;const d=await this.realTimePosition(t,e);let r=v(i);const c=v(n),l=v();if(a){let u=c.diff(r,"d",!0);u<0?r=c.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=c.clone().subtract(80,"d"),u=l.diff(c,"d",!0),c.add(u>10?240:u*24,"h")}const M={searchParams:{endtime:c.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}},y="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await T.get(y,M).json();h==null||h.info("[%s] fetch trajectory from: %s - %j",e.requestId,y,M);let Y;f&&(Y=((g=(m=f.ships)==null?void 0:m.offors)==null?void 0:g.ship)||[],Y.length||h==null||h.warn("[%s] fetch trajectory failed: %j",e.requestId,f));const w=[];let I=-1;const b=v(`${(p=Y==null?void 0:Y[0])==null?void 0:p.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of Y){for(const R in u)!isNaN(u[R])&&Number(u[R])!==1/0&&(u[R]=Number(u[R]));const N=v(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:W,labelCn:S}=this.parseStatus(u.status),V={mmsi:u.m,name:u.n,imo:d==null?void 0:d.imo,lat:u.la,lng:u.lo,draught:u.draught,sog:u.sp,cog:u.co,hdg:u.hdg,positionTime:N.unix(),utc:N.utc().format(),status:u.status,labelCn:S,labelEn:W,method:"trajectory",vendor:"hifleet"},q=Math.floor(N.diff(b,"minute",!0)/(o||1));q!==I&&(I=q,w.push(V))}return w}}class rt extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n={searchParams:{id:t,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",a=await T.get(o,n).json();if(h==null||h.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n),(a==null?void 0:a.status)!==0)return a;const e=a.data[0];for(const M in e)!isNaN(e[M])&&Number(e[M])!==1/0&&(e[M]=Number(e[M]));const{labelCn:d,labelEn:r}=await this.parseStatus(e.navistat),c=v.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:c.utc().format(),status:e.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,i,n,o,a=!0,e={}){var b;const d=await this.realTimePosition(t,e),r=v(i),c=v(n),l="https://api.shipxy.com/apicall/GetShipTrack",M={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:c.unix()}},y=await T.get(l,M).json();if(h==null||h.info("[%s] fetch trajectory from: %s - %j",e.requestId,l,M),(y==null?void 0:y.status)!==0)return y;const f=y==null?void 0:y.points,Y=[],w=v.unix((b=f[0])==null?void 0:b.utc);let I=-1;for(const m of f){const g=v.unix(m.utc),p={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(m.sog*3600/1e3/1852*100)/100,cog:Math.round(m.cog/100*100)/100,lat:Math.round(m.lat/1e6*1e5)/1e5,lng:Math.round(m.lon/1e6*1e5)/1e5,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(g.diff(w,"minute",!0)/(o||1));u!==I&&(I=u,Y.push(p))}return Y}}class ct extends z{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,i={}){const n={headers:{appKey:this.token},json:{mmsiList:t}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await T.post(o,n).json();return h==null||h.info("[%s] fetch ship id from: %s - %j",i.requestId,o,n),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,i={}){const n={headers:{appKey:this.token},json:{shipId:t}},o="https://api3.myships.com/sp/ships/aissta",a=await T.post(o,n).json();if(h==null||h.info("[%s] fetch ship info from: %s - %j",i.requestId,o,n),a.code!=="0")return a;const e=a.data;let d=e.imo;return t==="407170"&&(d="9198379",h==null||h.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 n=await this.getShipId(t,i),o=await this.getShipInfo(n,i),a={headers:{appKey:this.token},json:{shipId:n}},e="https://api3.myships.com/sp/ships/position/latest",d=await T.post(e,a).json();h==null||h.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,a);const r=d.data[0];for(const f in r)!isNaN(r[f])&&Number(r[f])!==1/0&&(r[f]=Number(r[f]));const{labelCn:c,labelEn:l}=await this.parseStatus(r.aisNavStatus),M=v.unix(r.posTime);return{...o,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:M.utc().format(),status:r.aisNavStatus,labelEn:l,labelCn:c,method:"position",vendor:"myship"}}async trajectory(t,i,n,o,a=!0,e={}){const d=v(i),r=v(n),c=await this.getShipId(t),l=await this.getShipInfo(c),M=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(c,d.unix(),d.add(30,"day").unix(),l,t,o,M);return await this.trajectoryIn30Day(c,d.unix(),r.unix(),l,t,o,M),M}async trajectoryIn30Day(t,i,n,o,a,e,d,r={}){var w;const c={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:n}},l="https://api3.myships.com/sp/ships/position/history",M=await T.post(l,c).json();if(h==null||h.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,c),M.code!=="0")return h==null||h.warn("[%s] invoke myship trajectory failed: %j",r.requestId,M),M;const y=M.data;for(const I in y)!isNaN(y[I])&&Number(y[I])!==1/0&&(y[I]=Number(y[I]));const f=v.unix((w=y[0])==null?void 0:w.posTime);let Y=-1;for(const I of y){const b=v.unix(I.posTime),m={imo:o==null?void 0:o.imo,mmsi:a,lat:Math.round(I.lat/1e4/60*1e5)/1e5,lng:Math.round(I.lon/1e4/60*1e5)/1e5,sog:Math.round(I.sog/10*100)/100,cog:Math.round(I.cog/10*100)/100,hdg:Math.round(I.heading*100)/100,rot:Math.round(I.rot*100)/100,positionTime:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"myship"},g=Math.floor(b.diff(f,"minute",!0)/(e||1));g!==Y&&(Y=g,d.push(m))}return d}}let C;try{C=_.getLogger("vessel")}catch{}finally{}var G=(k=>(k.NOTICE="NOTICE",k.WARN="WARN",k.HEAVY="HEAVY",k.SEVERE="SEVERE",k.ERROR="ERROR",k.FATAL="FATAL",k))(G||{});class U{parsePrinciple(s,t={}){var e,d,r;C==null||C.info("[%s] parse rule: %s",t.requestId,s);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),n=s.match(i)?(e=s.match(i))==null?void 0:e[0]:void 0,o=n==null?void 0:n.split(";");if(!o)return;const a={};for(let c=0;c<(o==null?void 0:o.length);c++){const l=(r=(d=o[c].match(i))==null?void 0:d[0])==null?void 0:r.split("],");if(c===0&&!l)a.scope=o[0];else if(l)for(let M=0,y=l.length;M<y;M++){const f=this.parseRule(l[M]);f&&(a[f.level]?f.key?a[f.level][f==null?void 0:f.key]=f:a[f.level]=f:f.key?a[f.level]={[f==null?void 0:f.key]:f}:a[f.level]=f)}}return a}parseRule(s,t={}){var a;C==null||C.info("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),n=(a=s==null?void 0:s.match(i))==null?void 0:a[0],o=n==null?void 0:n.split(",");if(o)return{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:Number(o[3]),key:o[4]}}checkWeather(s,t,i={}){var f,Y,w,I,b,m,g,p,u,N,W,S,V,q,R;let n=0,o=0,a=0,e=0;const d=Math.round(((Y=(f=t==null?void 0:t.SEVERE)==null?void 0:f.sigWave)==null?void 0:Y.number)*1.6*100)/100,r=(I=(w=t==null?void 0:t.SEVERE)==null?void 0:w.sigWave)==null?void 0:I.number,c=(m=(b=t==null?void 0:t.HEAVY)==null?void 0:b.sigWave)==null?void 0:m.number,l=Math.round((((p=(g=t==null?void 0:t.SEVERE)==null?void 0:g.wind)==null?void 0:p.number)+2)*100)/100,M=(N=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:N.number,y=(S=(W=t==null?void 0:t.HEAVY)==null?void 0:W.wind)==null?void 0:S.number;for(let O=0;O<(s==null?void 0:s.length);O++){const j=s[O],D=(q=(V=j==null?void 0:j.meteo)==null?void 0:V.wave)==null?void 0:q.sig,A=(R=j==null?void 0:j.meteo)==null?void 0:R.wind,B=O?v(j.eta).diff(v(s[O-1].eta),"hour",!0):0;e=B>e?B:e,C==null||C.info("[%s] check sig.wave: %j",i.requestId,{...D,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:c}),(D==null?void 0:D.height)>=d?j.isDangerous=!0:(D==null?void 0:D.height)>=r?j.isSevere=!0:(D==null?void 0:D.height)>=c&&(j.isHeavy=!0),C==null||C.info("[%s] check wind: %j",i.requestId,{...A,dgThd4Wd:l,svThd4Wd:M,hvThd4Wd:y}),(A==null?void 0:A.scale)>=l?(j.isDangerous=!0,delete j.isSevere,delete j.isHeavy):(A==null?void 0:A.scale)>M?(j.isDangerous||(j.isSevere=!0),delete j.isHeavy):(A==null?void 0:A.scale)===y&&!j.isDangerous&&!j.isSevere&&(j.isHeavy=!0),n+=j.isDangerous?B:0,o+=j.isSevere?B:0,a+=j.isHeavy?B:0}return n=Math.round(n*100)/100,o=Math.round(o*100)/100,a=Math.round(a*100)/100,e=Math.round(e),{sample:s,dangerous:n,severe:o,heavy:a,step:e<3?3:e,wind:{dgThd4Wd:l,svThd4Wd:M,hvThd4Wd:y},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:c}}}}const dt=new U;let F;try{F=_.getLogger("vessel")}catch{}finally{}var J=(k=>(k.common="common",k.container="container",k))(J||{}),Q=(k=>(k.Ballast="Ballast",k.Laden="Laden",k))(Q||{}),X=(k=>(k.Cp="CP",k.Perf="Basis",k.Instruct="Other",k))(X||{});class L{static blockCoefficient(s,t,i,n){let o=Math.round(s/(t*i*n)*100)/100;o=o<.55?.55:o>.85?.85:o;const a=[.55,.6,.65,.7,.75,.8,.85],e=a.map(d=>Math.abs(d-o));return a[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,i=9.8){let n=Math.round(Math.sqrt(s*s/(i*t))*100)/100;return n=n<.05?.05:n>.3?.3:n,n}static amendFactor(s,t,i){const n={.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 a={.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]}[s];return i==="Laden"&&(a=n[s]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(s,t=0){let i;return s>30&&s<=60?i=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=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(s,t,i,n=0){n=n>5?n-.9*(n-5):n;let o;return i==="container"?o=.7*n+Math.pow(n,6.5)/(22*Math.pow(s,2/3)):t==="Ballast"?o=.7*n+Math.pow(n,6.5)/(2.7*Math.pow(s,2/3)):o=.5*n+Math.pow(n,6.5)/(2.7*Math.pow(s,2/3)),o}static waveHeightFactor(s){return s=s<1.25?1.25:s,s=s>6?s-.9*(s-6):s,Math.round((-.144*Math.pow(s,2)+.178*s)*1e4)/1e4}static assembleProperties(s,t,i,n){var c,l;const o=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;return{tag:((l=(c=s==null?void 0:s.type)==null?void 0:c.toLowerCase())==null?void 0:l.indexOf("container"))>-1?"container":"common",lbp:o,loadCondition:t,draught:a,breadthMoulded:e,displacement:Math.round((d/1.025+a*e*o*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:n||90}}static async speedLoseAt(s,t,i,n="",o=2,a=!0,e=!1,d={}){let r;if(t.velocity&&e&&(s.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){const c=await nt.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",n,d),l=L.weatherFactor(s,c),M=L.currentFactor(s.bearing,c==null?void 0:c.current,o);r={meteo:{...c},wxFactor:l,cFactor:M,speed:t.velocity&&e?t.velocity:Math.round((s.speed*1.943844+l+M)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round((s.speed*1.943844+0+0)*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,{...r,...t}}static async speedLoseInHoursStep(s,t,i,n,o,a,e="",d=!0,r=!1,c={}){t.utc();const l=[],M=[];let y=0,f=0,Y,w;for(let I=0;I<a.length-1;I++){let b=a[I];b.distanceFromStart=o+f;const m=a[I+1];if(s.bearing=E.LaneHelper.calculateBearing(b,m,!m.gcToPrevious),b.bearing=s.bearing,b.suspend&&r){b.eta=b.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),b.elapsed=b.elapsed??0;const u=b.suspend-b.elapsed;if(n-y>u)n=n-y-u,t.add(u,"hour"),b.elapsed=b.suspend;else{const N=n-y;b.elapsed+=N,t.add(N,"hour"),n=0}if(F==null||F.info(`[%s] suspend ${b.elapsed} hours at %j, and remain ${n} hours need to go...`,c.requestId,b),n===0)return b.distanceFromPrevious=f,{etd:t,from:w||b,to:b,next:a.filter(N=>N),wps:l,days:M}}b=await L.speedLoseAt(s,b,t,e,0,d,r,c),w=w||b,b.important&&l.push(b),t.isSameOrAfter(i)&&(M.push(b),i.add(24,"hour"));const g=E.LaneHelper.calculateDistance(b,m,!m.gcToPrevious);let p=Math.ceil(g/w.speed*1e4)/1e4;if(y+p<n){if(y+=p,t.add(p,"hour"),delete a[I],F==null||F.info(`[%s] go to %j from %j with ${g}nm, and cost ${p} hours`,c.requestId,{lat:m.lat,lng:m.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),f+=g,a.filter(u=>u).length<=1){Y=m,Y.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),Y.distanceFromPrevious=g,Y.distanceFromStart=o+f,l.push(Y),delete a[I+1];break}}else{p=n-y,t.add(p,"hour");const u=E.LngLatHelper.roundPrecision(w.speed*p,4);Y=E.LaneHelper.calculateCoordinate(b,s.bearing,u,"nauticalmiles",!m.gcToPrevious),Y.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),a[I]=Y,F==null||F.info(`[%s] go to %j from %j with ${u}nm, and cost ${p} hours`,c.requestId,{lat:Y.lat,lng:Y.lng},{lat:b.lat,lng:b.lng,etd:b.etd}),f+=u,Y.distanceFromPrevious=f,Y.distanceFromStart=o+f;break}}return{etd:t,from:w,to:Y,next:a.filter(I=>I),wps:l,days:M}}static currentFactor(s,t,i=0){const n=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(n)===Math.PI/2)return 0;let o=((t==null?void 0:t.kts)||0)*Math.cos(n);return i&2?o=Math.ceil(o*100)/100:i&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(s,t){var l,M,y,f,Y;F==null||F.debug("calculate weather factor via: %j",{...s,...t});const i=L.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=L.froudeNumber(s.speed,s.lbp),o=L.amendFactor(i,n,s.loadCondition);let a=Math.abs(s.bearing%360-(((l=t==null?void 0:t.wind)==null?void 0:l.degree)%360||0));a=a>180?360-a:a;const e=L.directionFactor(a,(M=t==null?void 0:t.wind)==null?void 0:M.scale),d=L.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(y=t==null?void 0:t.wind)==null?void 0:y.scale);let r=e*o*d/100*s.speed;r=Math.round(r*1.943844*1e4)/1e4*-1;const c=L.waveHeightFactor(((Y=(f=t==null?void 0:t.wave)==null?void 0:f.sig)==null?void 0:Y.height)??1);return r=r*.24+c*.76,F==null||F.debug("weather factor = %s",r),Math.round(r*100)/100}static async analyseInstant(s,t,i,n,o,a="",e=0,d=!0,r=!1,c={}){var B,$,tt,et,st;const l=v().valueOf();s.lng=E.LngLatHelper.convertToStdLng(s.lng);const{route:M,waypoints:y}=o.points,f=E.LaneHelper.calculateSubRoute(s,M);if(((B=f[0])==null?void 0:B.length)<=1)return;const{v0:Y,label:w}=s.sog?{v0:s.sog,label:"Other"}:{v0:n.speed,label:"CP"},I=L.assembleProperties(i,n.loadCondition,Y,0),b=y.length?E.LaneHelper.calculateSubWaypoints(s,y):[],m={from:{...s},route:f,waypoints:b,v0:Y,label:w},g={hours:[],days:[],wps:[]};e||(E.LaneHelper.calculateRouteDistance(f)/n.speed<=72?e=3:e=6);let p=E.LaneHelper.simplifyRouteToCoordinates(f,b,0),u=0,N=0,W=0,S=0;t=v(t).utc();const V=t.clone();for(;p.length>0;){const P=e-t.hour()%e,Z=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,x=await L.speedLoseInHoursStep(I,t,V,Z,u,p,a,d,r,c);($=x.from)!=null&&$.speed&&(g.hours.push(x.from),g.wps.push(...x.wps),g.days.push(...x.days)),p=x==null?void 0:x.next,p.length||g.hours.push(x==null?void 0:x.to),u+=((tt=x==null?void 0:x.to)==null?void 0:tt.distanceFromPrevious)??0}const q=g.hours;for(let P=0;P<q.length-1;P++){const Z=v(q[P+1].eta).diff(q[P].etd,"hour",!0)||1;N+=q[P].wxFactor||0*Z,W+=q[P].cFactor||0*Z,S+=Z}(et=g.wps)==null||et.forEach((P,Z)=>{if(Z){const x=g.wps[Z-1],ut=P.distanceFromStart-x.distanceFromStart,at=v(P.eta).diff(v(x.etd),"h",!0);at<1?P.avgSpd=x.speed:P.avgSpd=Math.round(ut/at*100)/100}}),m.sample=g;const R=g.hours.at(0),O=g.hours.at(-1);m.distance=Math.round(O.distanceFromStart*1e4)/1e4,m.etd=v(R.eta).utc().format(),m.eta=v(O.eta).utc().format(),m.wxFactor=Math.round(N/S*1e4)/1e4,m.cFactor=Math.round(W/S*1e4)/1e4,m.avgSpeed=Math.round(O.distanceFromStart/S*1e4)/1e4,m.totalHrs=Math.round(S*1e4)/1e4,m.totalFoCons=Math.round((n==null?void 0:n.fo)/24*m.totalHrs*1e3)/1e3,m.totalDgoCons=Math.round((n==null?void 0:n.dgo)/24*m.totalHrs*1e3)/1e3;const D=v().valueOf()-l,A=((st=g==null?void 0:g.hours)==null?void 0:st.length)||1;return F==null||F.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",c==null?void 0:c.requestId,D,A,Math.round(D/A*1e3)/1e3),m}static async analyseInstantWithThreshed(s,t,i,n,o,a,e,d="",r=3,c=!0,l=!1,M={}){var q,R,O;s.lng=E.LngLatHelper.convertToStdLng(s.lng);const y=L.assembleProperties(n,o.loadCondition,o.speed,0),f=E.LaneHelper.calculateSubRoute(s,a);if(((q=f[0])==null?void 0:q.length)<=1)return;const Y=e.length?E.LaneHelper.calculateSubWaypoints(s,e):[];let w=E.LaneHelper.simplifyRouteToCoordinates(f,Y,0);w.forEach(j=>j.important=!0);let I=0,b=0,m=0,g=0,p;const u={hours:[],wps:[],days:[]};for(t=v(t).utc();w.length>0;){const j=r-t.hour()%r;let D=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(D=t.clone().add(D,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:D,D)p=await L.speedLoseInHoursStep(y,t,i.clone(),D,I,w,d,c,l,M),(R=p.from)!=null&&R.speed&&(u.hours.push(p.from),p!=null&&p.wps&&u.wps.push(...p.wps),u.days.push(...p.days)),w=p==null?void 0:p.next,w.length||(u.hours.push(p==null?void 0:p.to),p!=null&&p.wps&&u.wps.push(...p.wps),u.days.push(p==null?void 0:p.to)),I+=((O=p==null?void 0:p.to)==null?void 0:O.distanceFromPrevious)??0;else{p&&(u.hours.push(p.to),p!=null&&p.wps&&u.wps.push(...p.wps),u.days.push(p.to));break}}const N=u.hours;for(let j=0;j<N.length-1;j++){const D=v(N[j+1].eta).diff(N[j].etd,"hour",!0);b+=N[j].wxFactor*D,m+=N[j].cFactor*D,g+=D}const W=u.hours.at(0),S=u.hours.at(-1);return{sample:u,distance:Math.round(((S==null?void 0:S.distanceFromStart)||0)*1e4)/1e4,etd:v(W.eta).utc().format(),eta:v(S==null?void 0:S.eta).utc().format(),wxFactor:Math.round(b/g*1e4)/1e4,cFactor:Math.round(m/g*1e4)/1e4,avgSpeed:Math.round(((S==null?void 0:S.distanceFromStart)||0)/g*1e4)/1e4,totalHrs:Math.round(g*1e4)/1e4,to:S,route:E.LaneHelper.generateRouteAccordingToWaypoints(w)}}}H.AISImpl=z,H.AlertHelper=U,H.AlertLevel=G,H.HifleetImpl=it,H.LoadCondition=Q,H.MyShipImpl=ct,H.MyVesselImpl=ot,H.ShipxyImpl=rt,H.SpeedHelper=L,H.SpeedLabel=X,H.VesselTag=J,H.alertHelper=dt,Object.defineProperty(H,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -205,7 +205,7 @@ export declare class SpeedHelper {
|
|
|
205
205
|
speed: number;
|
|
206
206
|
fo: number;
|
|
207
207
|
dgo: number;
|
|
208
|
-
}, route: number[][][], source?: string, stepHrs?: number, useMeteo?: boolean, useRouteParam?: boolean, options?: {
|
|
208
|
+
}, route: number[][][], waypoints: any[], source?: string, stepHrs?: number, useMeteo?: boolean, useRouteParam?: boolean, options?: {
|
|
209
209
|
requestId?: string;
|
|
210
210
|
}): Promise<{
|
|
211
211
|
sample: any;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idm-plugin/vessel",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.6",
|
|
5
5
|
"description": "idm plugin for vessel",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"keywords": [
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"release": "yarn build && yarn publish --access public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@idm-plugin/geo": "^1.
|
|
30
|
+
"@idm-plugin/geo": "^1.3.0",
|
|
31
31
|
"@idm-plugin/meteo": "^0.0.2",
|
|
32
32
|
"@log4js-node/log4js-api": "^1.0.2",
|
|
33
33
|
"got": "11",
|