@idm-plugin/vessel 1.2.1 → 1.2.3
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 +439 -386
- package/dist/index.umd.cjs +1 -1
- package/dist/speed/src/index.d.ts +7 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,95 +1,100 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import { LngLatHelper as
|
|
8
|
-
import { MeteoHelper as
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
var $ = Object.defineProperty;
|
|
2
|
+
var tt = (w, s, t) => s in w ? $(w, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : w[s] = t;
|
|
3
|
+
var _ = (w, s, t) => (tt(w, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
|
+
import R from "got";
|
|
5
|
+
import z from "@log4js-node/log4js-api";
|
|
6
|
+
import v from "moment";
|
|
7
|
+
import { LngLatHelper as B, LaneHelper as W } from "@idm-plugin/geo";
|
|
8
|
+
import { MeteoHelper as et } from "@idm-plugin/meteo";
|
|
9
|
+
let m;
|
|
10
|
+
try {
|
|
11
|
+
m = z.getLogger("vessel");
|
|
12
|
+
} catch {
|
|
13
|
+
} finally {
|
|
14
|
+
}
|
|
15
|
+
class K {
|
|
11
16
|
/**
|
|
12
17
|
* 解析AIS状态码
|
|
13
18
|
* @param status
|
|
14
19
|
*/
|
|
15
20
|
parseStatus(s) {
|
|
16
|
-
let t,
|
|
21
|
+
let t, i;
|
|
17
22
|
switch (s) {
|
|
18
23
|
case 0:
|
|
19
|
-
t = "在航(主机推动)",
|
|
24
|
+
t = "在航(主机推动)", i = "The engine is in use";
|
|
20
25
|
break;
|
|
21
26
|
case 1:
|
|
22
|
-
t = "锚泊",
|
|
27
|
+
t = "锚泊", i = "Anchored";
|
|
23
28
|
break;
|
|
24
29
|
case 2:
|
|
25
|
-
t = "失控",
|
|
30
|
+
t = "失控", i = "Not operated";
|
|
26
31
|
break;
|
|
27
32
|
case 3:
|
|
28
|
-
t = "操纵受限",
|
|
33
|
+
t = "操纵受限", i = "Limited airworthiness";
|
|
29
34
|
break;
|
|
30
35
|
case 4:
|
|
31
|
-
t = "吃水受限",
|
|
36
|
+
t = "吃水受限", i = "Limited by ship's draft";
|
|
32
37
|
break;
|
|
33
38
|
case 5:
|
|
34
|
-
t = "靠泊",
|
|
39
|
+
t = "靠泊", i = "Mooring";
|
|
35
40
|
break;
|
|
36
41
|
case 6:
|
|
37
|
-
t = "搁浅",
|
|
42
|
+
t = "搁浅", i = "Stranded";
|
|
38
43
|
break;
|
|
39
44
|
case 7:
|
|
40
|
-
t = "捕捞作业",
|
|
45
|
+
t = "捕捞作业", i = "Engaged in fishing";
|
|
41
46
|
break;
|
|
42
47
|
case 8:
|
|
43
|
-
t = "靠帆船提供动力",
|
|
48
|
+
t = "靠帆船提供动力", i = "Sailing";
|
|
44
49
|
break;
|
|
45
50
|
default:
|
|
46
|
-
t = "未定义",
|
|
51
|
+
t = "未定义", i = "Undefined";
|
|
47
52
|
}
|
|
48
|
-
return { labelCn: t, labelEn:
|
|
53
|
+
return { labelCn: t, labelEn: i };
|
|
49
54
|
}
|
|
50
55
|
}
|
|
51
|
-
class
|
|
52
|
-
constructor(t,
|
|
56
|
+
class ft extends K {
|
|
57
|
+
constructor(t, i) {
|
|
53
58
|
super();
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.clientId = t, this.clientSecret =
|
|
59
|
+
_(this, "clientId");
|
|
60
|
+
_(this, "clientSecret");
|
|
61
|
+
_(this, "token");
|
|
62
|
+
this.clientId = t, this.clientSecret = i;
|
|
58
63
|
}
|
|
59
64
|
async authToken(t = {}) {
|
|
60
|
-
const
|
|
65
|
+
const i = "https://svc.data.myvessel.cn/ada/oauth/token", o = {
|
|
61
66
|
searchParams: {
|
|
62
67
|
client_id: this.clientId,
|
|
63
68
|
client_secret: this.clientSecret,
|
|
64
69
|
grant_type: "client_credentials"
|
|
65
70
|
}
|
|
66
|
-
}, n = await
|
|
67
|
-
|
|
71
|
+
}, n = await R.post(i, o).json();
|
|
72
|
+
m == null || m.info("[%s] fetch access token from: %s - %j", t.requestId, i, n), n.error || (this.token = {
|
|
68
73
|
accessToken: n.access_token,
|
|
69
74
|
tokenType: n.token_type,
|
|
70
75
|
expiresIn: n.expires_in,
|
|
71
76
|
scope: n.scope,
|
|
72
77
|
jti: n.jti,
|
|
73
|
-
issuedAt:
|
|
78
|
+
issuedAt: v().utc().format()
|
|
74
79
|
});
|
|
75
80
|
}
|
|
76
|
-
async realTimePosition(t,
|
|
77
|
-
var
|
|
78
|
-
(!this.token ||
|
|
81
|
+
async realTimePosition(t, i = {}) {
|
|
82
|
+
var u, l, y;
|
|
83
|
+
(!this.token || v().diff(v(this.token.issuedAt), "seconds") > ((u = this.token) == null ? void 0 : u.expiresIn) - 300) && await this.authToken(i);
|
|
79
84
|
const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
|
|
80
85
|
headers: {
|
|
81
|
-
Authorization: `${(
|
|
86
|
+
Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(y = this.token) == null ? void 0 : y.accessToken}`
|
|
82
87
|
},
|
|
83
88
|
searchParams: { mmsi: t }
|
|
84
89
|
};
|
|
85
|
-
|
|
86
|
-
const a = await
|
|
90
|
+
m == null || m.info("[%s] fetch realtime position from: %s - %j", i.requestId, o, n);
|
|
91
|
+
const a = await R.get(o, n).json();
|
|
87
92
|
if (a.code)
|
|
88
|
-
return
|
|
93
|
+
return m == null || m.warn("[%s] fetch realtime position failed: %j", i.requestId, o, { message: a.message, status: a.status, code: a.code }), a;
|
|
89
94
|
const e = a.data;
|
|
90
|
-
for (const
|
|
91
|
-
!isNaN(e[
|
|
92
|
-
const d =
|
|
95
|
+
for (const p in e)
|
|
96
|
+
!isNaN(e[p]) && Number(e[p]) !== 1 / 0 && (e[p] = Number(e[p]));
|
|
97
|
+
const d = v(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
93
98
|
return {
|
|
94
99
|
mmsi: e.mmsi,
|
|
95
100
|
name: e.vesselName,
|
|
@@ -115,78 +120,78 @@ class lt extends Z {
|
|
|
115
120
|
utc: d.utc().format()
|
|
116
121
|
};
|
|
117
122
|
}
|
|
118
|
-
async trajectory(t,
|
|
119
|
-
(!this.token ||
|
|
120
|
-
const d = await this.realTimePosition(t, e),
|
|
121
|
-
for (;
|
|
122
|
-
await this.trajectoryIn30Day(t,
|
|
123
|
-
return await this.trajectoryIn30Day(t,
|
|
123
|
+
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
124
|
+
(!this.token || v().diff(v(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
|
|
125
|
+
const d = await this.realTimePosition(t, e), c = v(i), u = v(o), l = [];
|
|
126
|
+
for (; u.diff(c, "day", !0) > 30; )
|
|
127
|
+
await this.trajectoryIn30Day(t, c, c.clone().add(30, "day"), d, n, l, e), c.add(30, "day");
|
|
128
|
+
return await this.trajectoryIn30Day(t, c, u, d, n, l, e), l;
|
|
124
129
|
}
|
|
125
|
-
async trajectoryIn30Day(t,
|
|
126
|
-
var
|
|
127
|
-
const
|
|
130
|
+
async trajectoryIn30Day(t, i, o, n, a, e, d = {}) {
|
|
131
|
+
var h, b, I, Y, M;
|
|
132
|
+
const c = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", u = {
|
|
128
133
|
headers: {
|
|
129
|
-
Authorization: `${(
|
|
134
|
+
Authorization: `${(h = this.token) == null ? void 0 : h.tokenType} ${(b = this.token) == null ? void 0 : b.accessToken}`
|
|
130
135
|
},
|
|
131
136
|
json: {
|
|
132
137
|
mmsi: t,
|
|
133
|
-
startTime:
|
|
138
|
+
startTime: i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
|
|
134
139
|
endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
135
140
|
}
|
|
136
141
|
};
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
if (
|
|
140
|
-
return
|
|
141
|
-
let
|
|
142
|
-
const
|
|
143
|
-
return (
|
|
144
|
-
for (const
|
|
145
|
-
!isNaN(
|
|
146
|
-
const
|
|
147
|
-
mmsi:
|
|
142
|
+
m == null || m.info("[%s] fetch trajectory from: %s - %j", d.requestId, c, u);
|
|
143
|
+
const l = await R.post(c, u).json();
|
|
144
|
+
if (l.code)
|
|
145
|
+
return m == null || m.warn("[%s] fetch trajectory failed: %j", d.requestId, c, { message: l.message, status: l.status, code: l.code }), l;
|
|
146
|
+
let y = -1;
|
|
147
|
+
const p = v(`${(Y = (I = l.data) == null ? void 0 : I[0]) == null ? void 0 : Y.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
148
|
+
return (M = l.data) == null || M.forEach((r) => {
|
|
149
|
+
for (const j in r)
|
|
150
|
+
!isNaN(r[j]) && Number(r[j]) !== 1 / 0 && (r[j] = Number(r[j]));
|
|
151
|
+
const g = v(`${r.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), k = r.eta ? v(`${r.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, f = r.status, { labelCn: N, labelEn: A } = this.parseStatus(f), x = {
|
|
152
|
+
mmsi: r.mmsi,
|
|
148
153
|
imo: n == null ? void 0 : n.imo,
|
|
149
|
-
lat:
|
|
150
|
-
lng:
|
|
151
|
-
sog:
|
|
152
|
-
cog:
|
|
153
|
-
hdg:
|
|
154
|
-
draught:
|
|
155
|
-
status:
|
|
156
|
-
eta:
|
|
157
|
-
destination:
|
|
158
|
-
positionTime:
|
|
159
|
-
labelCn:
|
|
160
|
-
labelEn:
|
|
154
|
+
lat: r.lat,
|
|
155
|
+
lng: r.lon,
|
|
156
|
+
sog: r.sog,
|
|
157
|
+
cog: r.cog,
|
|
158
|
+
hdg: r.hdg,
|
|
159
|
+
draught: r.draught,
|
|
160
|
+
status: f,
|
|
161
|
+
eta: k == null ? void 0 : k.unix(),
|
|
162
|
+
destination: r.dest,
|
|
163
|
+
positionTime: g.unix(),
|
|
164
|
+
labelCn: N,
|
|
165
|
+
labelEn: A,
|
|
161
166
|
method: "trajectory",
|
|
162
167
|
vendor: "myVessel",
|
|
163
|
-
utc:
|
|
164
|
-
},
|
|
165
|
-
|
|
168
|
+
utc: g.utc().format()
|
|
169
|
+
}, O = Math.floor(g.diff(p, "minute", !0) / (a || 1));
|
|
170
|
+
O !== y && (y = O, e.push(x));
|
|
166
171
|
}), e;
|
|
167
172
|
}
|
|
168
173
|
}
|
|
169
|
-
class
|
|
174
|
+
class mt extends K {
|
|
170
175
|
constructor(t) {
|
|
171
176
|
super();
|
|
172
|
-
|
|
177
|
+
_(this, "token");
|
|
173
178
|
this.token = t;
|
|
174
179
|
}
|
|
175
|
-
async realTimePosition(t,
|
|
180
|
+
async realTimePosition(t, i = {}) {
|
|
176
181
|
const o = "https://api.hifleet.com/position/position/get/token", n = {
|
|
177
182
|
searchParams: {
|
|
178
183
|
mmsi: t,
|
|
179
184
|
usertoken: this.token
|
|
180
185
|
}
|
|
181
|
-
}, a = await
|
|
182
|
-
|
|
186
|
+
}, a = await R.post(o, n).json();
|
|
187
|
+
m == null || m.info("[%s] fetch realtime position from: %s - %j", i.requestId, o, n);
|
|
183
188
|
const e = a == null ? void 0 : a.list;
|
|
184
189
|
if (!e)
|
|
185
|
-
return
|
|
186
|
-
for (const
|
|
187
|
-
!isNaN(e[
|
|
190
|
+
return m == null || m.warn("[%s] fetch realtime position failed: %j", i.requestId, o, a), a;
|
|
191
|
+
for (const p in e)
|
|
192
|
+
!isNaN(e[p]) && Number(e[p]) !== 1 / 0 && (e[p] = Number(e[p]));
|
|
188
193
|
e.status = e.sp > 3 ? 0 : 1;
|
|
189
|
-
const d = e.status, { labelCn:
|
|
194
|
+
const d = e.status, { labelCn: c, labelEn: u } = this.parseStatus(d), l = v(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
190
195
|
return {
|
|
191
196
|
mmsi: e.m,
|
|
192
197
|
name: e.n,
|
|
@@ -201,18 +206,18 @@ class ft extends Z {
|
|
|
201
206
|
cog: e.co,
|
|
202
207
|
hdg: e.h,
|
|
203
208
|
rot: isNaN(e.rot) ? 0 : e.rot,
|
|
204
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ?
|
|
209
|
+
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,
|
|
205
210
|
destination: e.destination,
|
|
206
|
-
positionTime:
|
|
207
|
-
utc:
|
|
211
|
+
positionTime: l.unix(),
|
|
212
|
+
utc: l.utc().format(),
|
|
208
213
|
status: d,
|
|
209
|
-
labelCn:
|
|
210
|
-
labelEn:
|
|
214
|
+
labelCn: c,
|
|
215
|
+
labelEn: u,
|
|
211
216
|
method: "position",
|
|
212
217
|
vendor: "hifleet"
|
|
213
218
|
};
|
|
214
219
|
}
|
|
215
|
-
async search(t,
|
|
220
|
+
async search(t, i = {}) {
|
|
216
221
|
let o = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
217
222
|
const n = {
|
|
218
223
|
searchParams: {
|
|
@@ -224,8 +229,8 @@ class ft extends Z {
|
|
|
224
229
|
Host: "www.hifleet.com"
|
|
225
230
|
}
|
|
226
231
|
};
|
|
227
|
-
let a = await
|
|
228
|
-
|
|
232
|
+
let a = await R.post(o, n).json();
|
|
233
|
+
m == null || m.info("[%s] fetch vessel props from: %s - %j", i.requestId, o, n), a instanceof Array && (a = a[0]);
|
|
229
234
|
for (const d in a)
|
|
230
235
|
!isNaN(a[d]) && Number(a[d]) !== 1 / 0 && (a[d] = Number(a[d]));
|
|
231
236
|
const e = {
|
|
@@ -237,79 +242,79 @@ class ft extends Z {
|
|
|
237
242
|
breadth: a.b,
|
|
238
243
|
draught: a.dr
|
|
239
244
|
};
|
|
240
|
-
return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await
|
|
245
|
+
return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await R.post(o, n).json(), m == null || m.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;
|
|
241
246
|
}
|
|
242
|
-
async trajectory(t,
|
|
243
|
-
var
|
|
247
|
+
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
248
|
+
var r, g, k;
|
|
244
249
|
const d = await this.realTimePosition(t, e);
|
|
245
|
-
let
|
|
246
|
-
const
|
|
250
|
+
let c = v(i);
|
|
251
|
+
const u = v(o), l = v();
|
|
247
252
|
if (a) {
|
|
248
|
-
let
|
|
249
|
-
|
|
253
|
+
let f = u.diff(c, "d", !0);
|
|
254
|
+
f < 0 ? c = u.clone().subtract(40, "d") : f < 30 ? c.subtract(10, "d") : f < 60 ? c.subtract(5, "d") : c = u.clone().subtract(80, "d"), f = l.diff(u, "d", !0), u.add(f > 10 ? 240 : f * 24, "h");
|
|
250
255
|
}
|
|
251
|
-
const
|
|
256
|
+
const y = {
|
|
252
257
|
searchParams: {
|
|
253
|
-
endtime:
|
|
254
|
-
starttime:
|
|
258
|
+
endtime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
259
|
+
starttime: c.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
255
260
|
mmsi: t,
|
|
256
261
|
usertoken: this.token
|
|
257
262
|
}
|
|
258
|
-
},
|
|
259
|
-
|
|
263
|
+
}, p = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", h = await R.get(p, y).json();
|
|
264
|
+
m == null || m.info("[%s] fetch trajectory from: %s - %j", e.requestId, p, y);
|
|
260
265
|
let b;
|
|
261
|
-
|
|
266
|
+
h && (b = ((g = (r = h.ships) == null ? void 0 : r.offors) == null ? void 0 : g.ship) || [], b.length || m == null || m.warn("[%s] fetch trajectory failed: %j", e.requestId, h));
|
|
262
267
|
const I = [];
|
|
263
|
-
let
|
|
264
|
-
const
|
|
265
|
-
for (const
|
|
266
|
-
for (const
|
|
267
|
-
!isNaN(
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
const { labelEn:
|
|
271
|
-
mmsi:
|
|
272
|
-
name:
|
|
268
|
+
let Y = -1;
|
|
269
|
+
const M = v(`${(k = b == null ? void 0 : b[0]) == null ? void 0 : k.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
270
|
+
for (const f of b) {
|
|
271
|
+
for (const D in f)
|
|
272
|
+
!isNaN(f[D]) && Number(f[D]) !== 1 / 0 && (f[D] = Number(f[D]));
|
|
273
|
+
const N = v(`${f.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
274
|
+
f.status = f.sp > 4 ? 0 : 1;
|
|
275
|
+
const { labelEn: A, labelCn: x } = this.parseStatus(f.status), O = {
|
|
276
|
+
mmsi: f.m,
|
|
277
|
+
name: f.n,
|
|
273
278
|
imo: d == null ? void 0 : d.imo,
|
|
274
|
-
lat:
|
|
275
|
-
lng:
|
|
276
|
-
draught:
|
|
277
|
-
sog:
|
|
278
|
-
cog:
|
|
279
|
-
hdg:
|
|
280
|
-
positionTime:
|
|
281
|
-
utc:
|
|
282
|
-
status:
|
|
283
|
-
labelCn:
|
|
284
|
-
labelEn:
|
|
279
|
+
lat: f.la,
|
|
280
|
+
lng: f.lo,
|
|
281
|
+
draught: f.draught,
|
|
282
|
+
sog: f.sp,
|
|
283
|
+
cog: f.co,
|
|
284
|
+
hdg: f.hdg,
|
|
285
|
+
positionTime: N.unix(),
|
|
286
|
+
utc: N.utc().format(),
|
|
287
|
+
status: f.status,
|
|
288
|
+
labelCn: x,
|
|
289
|
+
labelEn: A,
|
|
285
290
|
method: "trajectory",
|
|
286
291
|
vendor: "hifleet"
|
|
287
|
-
},
|
|
288
|
-
|
|
292
|
+
}, j = Math.floor(N.diff(M, "minute", !0) / (n || 1));
|
|
293
|
+
j !== Y && (Y = j, I.push(O));
|
|
289
294
|
}
|
|
290
295
|
return I;
|
|
291
296
|
}
|
|
292
297
|
}
|
|
293
|
-
class
|
|
298
|
+
class pt extends K {
|
|
294
299
|
constructor(t) {
|
|
295
300
|
super();
|
|
296
|
-
|
|
301
|
+
_(this, "token");
|
|
297
302
|
this.token = t;
|
|
298
303
|
}
|
|
299
|
-
async realTimePosition(t,
|
|
304
|
+
async realTimePosition(t, i = {}) {
|
|
300
305
|
const o = {
|
|
301
306
|
searchParams: {
|
|
302
307
|
id: t,
|
|
303
308
|
k: this.token,
|
|
304
309
|
enc: 1
|
|
305
310
|
}
|
|
306
|
-
}, n = "https://api.shipxy.com/apicall/GetSingleShip", a = await
|
|
307
|
-
if (
|
|
311
|
+
}, n = "https://api.shipxy.com/apicall/GetSingleShip", a = await R.get(n, o).json();
|
|
312
|
+
if (m == null || m.info("[%s] fetch realtime position from: %s - %j", i.requestId, n, o), (a == null ? void 0 : a.status) !== 0)
|
|
308
313
|
return a;
|
|
309
314
|
const e = a.data[0];
|
|
310
|
-
for (const
|
|
311
|
-
!isNaN(e[
|
|
312
|
-
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: c } = await this.parseStatus(e.navistat), u = v.unix(e.lasttime);
|
|
313
318
|
return {
|
|
314
319
|
mmsi: e.ShipID,
|
|
315
320
|
name: e.name,
|
|
@@ -325,55 +330,55 @@ class mt extends Z {
|
|
|
325
330
|
hdg: Math.round(e.hdg / 100 * 100) / 100,
|
|
326
331
|
rot: Math.round(e.rot / 100 * 100) / 100,
|
|
327
332
|
positionTime: e.lasttime,
|
|
328
|
-
utc:
|
|
333
|
+
utc: u.utc().format(),
|
|
329
334
|
status: e.navistat,
|
|
330
|
-
labelEn:
|
|
335
|
+
labelEn: c,
|
|
331
336
|
labelCn: d,
|
|
332
337
|
method: "position",
|
|
333
338
|
vendor: "shipxy"
|
|
334
339
|
};
|
|
335
340
|
}
|
|
336
|
-
async trajectory(t,
|
|
337
|
-
var
|
|
338
|
-
const d = await this.realTimePosition(t, e),
|
|
341
|
+
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
342
|
+
var M;
|
|
343
|
+
const d = await this.realTimePosition(t, e), c = v(i), u = v(o), l = "https://api.shipxy.com/apicall/GetShipTrack", y = {
|
|
339
344
|
searchParams: {
|
|
340
345
|
id: t,
|
|
341
346
|
k: this.token,
|
|
342
347
|
enc: 1,
|
|
343
348
|
cut: 0,
|
|
344
|
-
btm:
|
|
345
|
-
etm:
|
|
349
|
+
btm: c.unix(),
|
|
350
|
+
etm: u.unix()
|
|
346
351
|
}
|
|
347
|
-
},
|
|
348
|
-
if (
|
|
349
|
-
return
|
|
350
|
-
const
|
|
351
|
-
let
|
|
352
|
-
for (const
|
|
353
|
-
const
|
|
352
|
+
}, p = await R.get(l, y).json();
|
|
353
|
+
if (m == null || m.info("[%s] fetch trajectory from: %s - %j", e.requestId, l, y), (p == null ? void 0 : p.status) !== 0)
|
|
354
|
+
return p;
|
|
355
|
+
const h = p == null ? void 0 : p.points, b = [], I = v.unix((M = h[0]) == null ? void 0 : M.utc);
|
|
356
|
+
let Y = -1;
|
|
357
|
+
for (const r of h) {
|
|
358
|
+
const g = v.unix(r.utc), k = {
|
|
354
359
|
imo: d == null ? void 0 : d.imo,
|
|
355
360
|
mmsi: t,
|
|
356
|
-
sog: Math.round(
|
|
357
|
-
cog: Math.round(
|
|
358
|
-
lat: Math.round(
|
|
359
|
-
lng: Math.round(
|
|
360
|
-
positionTime:
|
|
361
|
-
utc:
|
|
361
|
+
sog: Math.round(r.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
362
|
+
cog: Math.round(r.cog / 100 * 100) / 100,
|
|
363
|
+
lat: Math.round(r.lat / 1e6 * 1e5) / 1e5,
|
|
364
|
+
lng: Math.round(r.lon / 1e6 * 1e5) / 1e5,
|
|
365
|
+
positionTime: g.unix(),
|
|
366
|
+
utc: g.utc().format(),
|
|
362
367
|
method: "trajectory",
|
|
363
368
|
vendor: "shipxy"
|
|
364
|
-
},
|
|
365
|
-
|
|
369
|
+
}, f = Math.floor(g.diff(I, "minute", !0) / (n || 1));
|
|
370
|
+
f !== Y && (Y = f, b.push(k));
|
|
366
371
|
}
|
|
367
372
|
return b;
|
|
368
373
|
}
|
|
369
374
|
}
|
|
370
|
-
class
|
|
375
|
+
class Mt extends K {
|
|
371
376
|
constructor(t) {
|
|
372
377
|
super();
|
|
373
|
-
|
|
378
|
+
_(this, "token");
|
|
374
379
|
this.token = t;
|
|
375
380
|
}
|
|
376
|
-
async getShipId(t,
|
|
381
|
+
async getShipId(t, i = {}) {
|
|
377
382
|
const o = {
|
|
378
383
|
headers: {
|
|
379
384
|
appKey: this.token
|
|
@@ -381,10 +386,10 @@ class gt extends Z {
|
|
|
381
386
|
json: {
|
|
382
387
|
mmsiList: t
|
|
383
388
|
}
|
|
384
|
-
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await
|
|
385
|
-
return
|
|
389
|
+
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await R.post(n, o).json();
|
|
390
|
+
return m == null || m.info("[%s] fetch ship id from: %s - %j", i.requestId, n, o), a.code !== "0" ? a : a.data[0].shipId;
|
|
386
391
|
}
|
|
387
|
-
async getShipInfo(t,
|
|
392
|
+
async getShipInfo(t, i = {}) {
|
|
388
393
|
const o = {
|
|
389
394
|
headers: {
|
|
390
395
|
appKey: this.token
|
|
@@ -392,12 +397,12 @@ class gt extends Z {
|
|
|
392
397
|
json: {
|
|
393
398
|
shipId: t
|
|
394
399
|
}
|
|
395
|
-
}, n = "https://api3.myships.com/sp/ships/aissta", a = await
|
|
396
|
-
if (
|
|
400
|
+
}, n = "https://api3.myships.com/sp/ships/aissta", a = await R.post(n, o).json();
|
|
401
|
+
if (m == null || m.info("[%s] fetch ship info from: %s - %j", i.requestId, n, o), a.code !== "0")
|
|
397
402
|
return a;
|
|
398
403
|
const e = a.data;
|
|
399
404
|
let d = e.imo;
|
|
400
|
-
return t === "407170" && (d = "9198379",
|
|
405
|
+
return t === "407170" && (d = "9198379", m == null || m.warn("[%s] ship(%s) imo error: %s, should be %s", i.requestId, t, e.imo, d)), {
|
|
401
406
|
mmsi: e.mmsi,
|
|
402
407
|
name: e.shipnameEn,
|
|
403
408
|
imo: d,
|
|
@@ -407,86 +412,91 @@ class gt extends Z {
|
|
|
407
412
|
draught: (e.draught || 100) / 10
|
|
408
413
|
};
|
|
409
414
|
}
|
|
410
|
-
async realTimePosition(t,
|
|
411
|
-
const o = await this.getShipId(t,
|
|
415
|
+
async realTimePosition(t, i = {}) {
|
|
416
|
+
const o = await this.getShipId(t, i), n = await this.getShipInfo(o, i), a = {
|
|
412
417
|
headers: {
|
|
413
418
|
appKey: this.token
|
|
414
419
|
},
|
|
415
420
|
json: {
|
|
416
421
|
shipId: o
|
|
417
422
|
}
|
|
418
|
-
}, e = "https://api3.myships.com/sp/ships/position/latest", d = await
|
|
419
|
-
|
|
420
|
-
const
|
|
421
|
-
for (const
|
|
422
|
-
!isNaN(
|
|
423
|
-
const { labelCn:
|
|
423
|
+
}, e = "https://api3.myships.com/sp/ships/position/latest", d = await R.post(e, a).json();
|
|
424
|
+
m == null || m.info("[%s] fetch realtime position from: %s - %j", i.requestId, e, a);
|
|
425
|
+
const c = d.data[0];
|
|
426
|
+
for (const h in c)
|
|
427
|
+
!isNaN(c[h]) && Number(c[h]) !== 1 / 0 && (c[h] = Number(c[h]));
|
|
428
|
+
const { labelCn: u, labelEn: l } = await this.parseStatus(c.aisNavStatus), y = v.unix(c.posTime);
|
|
424
429
|
return {
|
|
425
430
|
...n,
|
|
426
431
|
mmsi: t,
|
|
427
|
-
lat: Math.round(
|
|
428
|
-
lng: Math.round(
|
|
429
|
-
sog: Math.round(
|
|
430
|
-
cog: Math.round(
|
|
431
|
-
hdg: Math.round(
|
|
432
|
-
rot: Math.round(
|
|
433
|
-
positionTime:
|
|
434
|
-
utc:
|
|
435
|
-
status:
|
|
436
|
-
labelEn:
|
|
437
|
-
labelCn:
|
|
432
|
+
lat: Math.round(c.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
433
|
+
lng: Math.round(c.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
434
|
+
sog: Math.round(c.sog / 10 * 100) / 100,
|
|
435
|
+
cog: Math.round(c.cog / 10 * 100) / 100,
|
|
436
|
+
hdg: Math.round(c.heading * 100) / 100,
|
|
437
|
+
rot: Math.round(c.rot * 100) / 100,
|
|
438
|
+
positionTime: c.posTime,
|
|
439
|
+
utc: y.utc().format(),
|
|
440
|
+
status: c.aisNavStatus,
|
|
441
|
+
labelEn: l,
|
|
442
|
+
labelCn: u,
|
|
438
443
|
method: "position",
|
|
439
444
|
vendor: "myship"
|
|
440
445
|
};
|
|
441
446
|
}
|
|
442
|
-
async trajectory(t,
|
|
443
|
-
const d =
|
|
444
|
-
for (;
|
|
445
|
-
await this.trajectoryIn30Day(
|
|
446
|
-
return await this.trajectoryIn30Day(
|
|
447
|
+
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
448
|
+
const d = v(i), c = v(o), u = await this.getShipId(t), l = await this.getShipInfo(u), y = [];
|
|
449
|
+
for (; c.diff(d, "day", !0) > 30; )
|
|
450
|
+
await this.trajectoryIn30Day(u, d.unix(), d.add(30, "day").unix(), l, t, n, y);
|
|
451
|
+
return await this.trajectoryIn30Day(u, d.unix(), c.unix(), l, t, n, y), y;
|
|
447
452
|
}
|
|
448
|
-
async trajectoryIn30Day(t,
|
|
453
|
+
async trajectoryIn30Day(t, i, o, n, a, e, d, c = {}) {
|
|
449
454
|
var I;
|
|
450
|
-
const
|
|
455
|
+
const u = {
|
|
451
456
|
headers: {
|
|
452
457
|
appKey: this.token
|
|
453
458
|
},
|
|
454
459
|
json: {
|
|
455
460
|
shipId: t,
|
|
456
|
-
startTime:
|
|
461
|
+
startTime: i,
|
|
457
462
|
endTime: o
|
|
458
463
|
}
|
|
459
|
-
},
|
|
460
|
-
if (
|
|
461
|
-
return
|
|
462
|
-
const
|
|
463
|
-
for (const
|
|
464
|
-
!isNaN(
|
|
465
|
-
const
|
|
464
|
+
}, l = "https://api3.myships.com/sp/ships/position/history", y = await R.post(l, u).json();
|
|
465
|
+
if (m == null || m.info("[%s] fetch trajectory from: %s - %j", c.requestId, l, u), y.code !== "0")
|
|
466
|
+
return m == null || m.warn("[%s] invoke myship trajectory failed: %j", c.requestId, y), y;
|
|
467
|
+
const p = y.data;
|
|
468
|
+
for (const Y in p)
|
|
469
|
+
!isNaN(p[Y]) && Number(p[Y]) !== 1 / 0 && (p[Y] = Number(p[Y]));
|
|
470
|
+
const h = v.unix((I = p[0]) == null ? void 0 : I.posTime);
|
|
466
471
|
let b = -1;
|
|
467
|
-
for (const
|
|
468
|
-
const
|
|
472
|
+
for (const Y of p) {
|
|
473
|
+
const M = v.unix(Y.posTime), r = {
|
|
469
474
|
imo: n == null ? void 0 : n.imo,
|
|
470
475
|
mmsi: a,
|
|
471
|
-
lat: Math.round(
|
|
472
|
-
lng: Math.round(
|
|
473
|
-
sog: Math.round(
|
|
474
|
-
cog: Math.round(
|
|
475
|
-
hdg: Math.round(
|
|
476
|
-
rot: Math.round(
|
|
477
|
-
positionTime:
|
|
478
|
-
utc:
|
|
476
|
+
lat: Math.round(Y.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
477
|
+
lng: Math.round(Y.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
478
|
+
sog: Math.round(Y.sog / 10 * 100) / 100,
|
|
479
|
+
cog: Math.round(Y.cog / 10 * 100) / 100,
|
|
480
|
+
hdg: Math.round(Y.heading * 100) / 100,
|
|
481
|
+
rot: Math.round(Y.rot * 100) / 100,
|
|
482
|
+
positionTime: M.unix(),
|
|
483
|
+
utc: M.utc().format(),
|
|
479
484
|
method: "trajectory",
|
|
480
485
|
vendor: "myship"
|
|
481
|
-
},
|
|
482
|
-
|
|
486
|
+
}, g = Math.floor(M.diff(h, "minute", !0) / (e || 1));
|
|
487
|
+
g !== b && (b = g, d.push(r));
|
|
483
488
|
}
|
|
484
489
|
return d;
|
|
485
490
|
}
|
|
486
491
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
492
|
+
let C;
|
|
493
|
+
try {
|
|
494
|
+
C = z.getLogger("vessel");
|
|
495
|
+
} catch {
|
|
496
|
+
} finally {
|
|
497
|
+
}
|
|
498
|
+
var st = /* @__PURE__ */ ((w) => (w.NOTICE = "NOTICE", w.WARN = "WARN", w.HEAVY = "HEAVY", w.SEVERE = "SEVERE", w.ERROR = "ERROR", w.FATAL = "FATAL", w))(st || {});
|
|
499
|
+
class at {
|
|
490
500
|
/**
|
|
491
501
|
* 解析告警规则, 多规则场景
|
|
492
502
|
* @param rule
|
|
@@ -496,20 +506,20 @@ class st {
|
|
|
496
506
|
* @param options
|
|
497
507
|
*/
|
|
498
508
|
parsePrinciple(s, t = {}) {
|
|
499
|
-
var e, d,
|
|
500
|
-
|
|
501
|
-
const
|
|
509
|
+
var e, d, c;
|
|
510
|
+
C == null || C.info("[%s] parse rule: %s", t.requestId, s);
|
|
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(";");
|
|
502
512
|
if (!n)
|
|
503
513
|
return;
|
|
504
514
|
const a = {};
|
|
505
|
-
for (let
|
|
506
|
-
const
|
|
507
|
-
if (
|
|
515
|
+
for (let u = 0; u < (n == null ? void 0 : n.length); u++) {
|
|
516
|
+
const l = (c = (d = n[u].match(i)) == null ? void 0 : d[0]) == null ? void 0 : c.split("],");
|
|
517
|
+
if (u === 0 && !l)
|
|
508
518
|
a.scope = n[0];
|
|
509
|
-
else if (
|
|
510
|
-
for (let
|
|
511
|
-
const
|
|
512
|
-
|
|
519
|
+
else if (l)
|
|
520
|
+
for (let y = 0, p = l.length; y < p; y++) {
|
|
521
|
+
const h = this.parseRule(l[y]);
|
|
522
|
+
h && (a[h.level] ? h.key ? a[h.level][h == null ? void 0 : h.key] = h : a[h.level] = h : h.key ? a[h.level] = { [h == null ? void 0 : h.key]: h } : a[h.level] = h);
|
|
513
523
|
}
|
|
514
524
|
}
|
|
515
525
|
return a;
|
|
@@ -522,8 +532,8 @@ class st {
|
|
|
522
532
|
*/
|
|
523
533
|
parseRule(s, t = {}) {
|
|
524
534
|
var a;
|
|
525
|
-
|
|
526
|
-
const
|
|
535
|
+
C == null || C.info("[%s] parse rule: %s", t.requestId, s), s = s.startsWith("[") ? s : `[${s}`, s = s.endsWith("]") ? s : `${s}]`;
|
|
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(",");
|
|
527
537
|
if (n)
|
|
528
538
|
return {
|
|
529
539
|
operator: n[0],
|
|
@@ -539,20 +549,26 @@ class st {
|
|
|
539
549
|
* @param principle 告警规则
|
|
540
550
|
* @param options
|
|
541
551
|
*/
|
|
542
|
-
checkWeather(s, t,
|
|
543
|
-
var
|
|
552
|
+
checkWeather(s, t, i = {}) {
|
|
553
|
+
var h, b, I, Y, M, r, g, k, f, N, A, x, O, j, D;
|
|
544
554
|
let o = 0, n = 0, a = 0, e = 0;
|
|
545
|
-
const d = Math.round(((b = (
|
|
546
|
-
for (let
|
|
547
|
-
const
|
|
548
|
-
e =
|
|
555
|
+
const d = Math.round(((b = (h = t == null ? void 0 : t.SEVERE) == null ? void 0 : h.sigWave) == null ? void 0 : b.number) * 1.6 * 100) / 100, c = (Y = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : Y.number, u = (r = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.sigWave) == null ? void 0 : r.number, l = Math.round((((k = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.wind) == null ? void 0 : k.number) + 2) * 100) / 100, y = (N = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.wind) == null ? void 0 : N.number, p = (x = (A = t == null ? void 0 : t.HEAVY) == null ? void 0 : A.wind) == null ? void 0 : x.number;
|
|
556
|
+
for (let Z = 0; Z < (s == null ? void 0 : s.length); Z++) {
|
|
557
|
+
const T = s[Z], q = (j = (O = T == null ? void 0 : T.meteo) == null ? void 0 : O.wave) == null ? void 0 : j.sig, P = (D = T == null ? void 0 : T.meteo) == null ? void 0 : D.wind, V = Z ? v(T.eta).diff(v(s[Z - 1].eta), "hour", !0) : 0;
|
|
558
|
+
e = V > e ? V : e, C == null || C.info("[%s] check sig.wave: %j", i.requestId, { ...q, dgThd4Wv: d, svThd4Wv: c, hvThd4Wv: u }), (q == null ? void 0 : q.height) >= d ? T.isDangerous = !0 : (q == null ? void 0 : q.height) >= c ? T.isSevere = !0 : (q == null ? void 0 : q.height) >= u && (T.isHeavy = !0), C == null || C.info("[%s] check wind: %j", i.requestId, { ...P, dgThd4Wd: l, svThd4Wd: y, hvThd4Wd: p }), (P == null ? void 0 : P.scale) >= l ? (T.isDangerous = !0, delete T.isSevere, delete T.isHeavy) : (P == null ? void 0 : P.scale) > y ? (T.isDangerous || (T.isSevere = !0), delete T.isHeavy) : (P == null ? void 0 : P.scale) === p && !T.isDangerous && !T.isSevere && (T.isHeavy = !0), o += T.isDangerous ? V : 0, n += T.isSevere ? V : 0, a += T.isHeavy ? V : 0;
|
|
549
559
|
}
|
|
550
|
-
return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, a = Math.round(a * 100) / 100, e = Math.round(e), { sample: s, dangerous: o, severe: n, heavy: a, step: e < 3 ? 3 : e, wind: { dgThd4Wd:
|
|
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: l, svThd4Wd: y, hvThd4Wd: p }, sig: { dgThd4Wv: d, svThd4Wv: c, hvThd4Wv: u } };
|
|
551
561
|
}
|
|
552
562
|
}
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
563
|
+
const yt = new at();
|
|
564
|
+
let S;
|
|
565
|
+
try {
|
|
566
|
+
S = z.getLogger("vessel");
|
|
567
|
+
} catch {
|
|
568
|
+
} finally {
|
|
569
|
+
}
|
|
570
|
+
var ot = /* @__PURE__ */ ((w) => (w.common = "common", w.container = "container", w))(ot || {}), nt = /* @__PURE__ */ ((w) => (w.Ballast = "Ballast", w.Laden = "Laden", w))(nt || {}), it = /* @__PURE__ */ ((w) => (w.Cp = "CP", w.Perf = "Basis", w.Instruct = "Other", w))(it || {});
|
|
571
|
+
class E {
|
|
556
572
|
/**
|
|
557
573
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
558
574
|
* 方形系数(block coefficient)
|
|
@@ -565,8 +581,8 @@ class H {
|
|
|
565
581
|
* @param draught 吃水 m
|
|
566
582
|
* @return [0.55, 0.85]
|
|
567
583
|
*/
|
|
568
|
-
static blockCoefficient(s, t,
|
|
569
|
-
let n = Math.round(s / (t *
|
|
584
|
+
static blockCoefficient(s, t, i, o) {
|
|
585
|
+
let n = Math.round(s / (t * i * o) * 100) / 100;
|
|
570
586
|
n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
|
|
571
587
|
const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = a.map((d) => Math.abs(d - n));
|
|
572
588
|
return a[e.indexOf(Math.min(...e))];
|
|
@@ -582,8 +598,8 @@ class H {
|
|
|
582
598
|
* @param g 重力加速度 9.80 m/s^2
|
|
583
599
|
* @return [0.05, 0.30]
|
|
584
600
|
*/
|
|
585
|
-
static froudeNumber(s, t,
|
|
586
|
-
let o = Math.round(Math.sqrt(s * s / (
|
|
601
|
+
static froudeNumber(s, t, i = 9.8) {
|
|
602
|
+
let o = Math.round(Math.sqrt(s * s / (i * t)) * 100) / 100;
|
|
587
603
|
return o = o < 0.05 ? 0.05 : o > 0.3 ? 0.3 : o, o;
|
|
588
604
|
}
|
|
589
605
|
/**
|
|
@@ -593,7 +609,7 @@ class H {
|
|
|
593
609
|
* @param loadCondition
|
|
594
610
|
* @private
|
|
595
611
|
*/
|
|
596
|
-
static amendFactor(s, t,
|
|
612
|
+
static amendFactor(s, t, i) {
|
|
597
613
|
const o = {
|
|
598
614
|
0.55: [1.7, -1.4, -7.4],
|
|
599
615
|
0.6: [2.2, -2.5, -9.7],
|
|
@@ -612,7 +628,7 @@ class H {
|
|
|
612
628
|
0.8: [3, -16.3, -21.6],
|
|
613
629
|
0.85: [3.4, -20.9, 31.8]
|
|
614
630
|
}[s];
|
|
615
|
-
return
|
|
631
|
+
return i === "Laden" && (a = o[s]), a[0] + a[1] * t + a[2] * Math.pow(t, 2);
|
|
616
632
|
}
|
|
617
633
|
/**
|
|
618
634
|
* 失速方向因子
|
|
@@ -626,8 +642,8 @@ class H {
|
|
|
626
642
|
* @private
|
|
627
643
|
*/
|
|
628
644
|
static directionFactor(s, t = 0) {
|
|
629
|
-
let
|
|
630
|
-
return s > 30 && s <= 60 ?
|
|
645
|
+
let i;
|
|
646
|
+
return s > 30 && s <= 60 ? i = (1.7 - 0.03 * Math.pow(t - 4, 2)) / 2 : s > 60 && s <= 150 ? i = (0.9 - 0.06 * Math.pow(t - 6, 2)) / 2 : i = (0.4 - 0.03 * Math.pow(t - 8, 2)) / 2, Math.round(i * 1e5) / 1e5;
|
|
631
647
|
}
|
|
632
648
|
/**
|
|
633
649
|
* 失速船型因子
|
|
@@ -640,10 +656,10 @@ class H {
|
|
|
640
656
|
* @param bn
|
|
641
657
|
* @private
|
|
642
658
|
*/
|
|
643
|
-
static vesselTagFactor(s, t,
|
|
659
|
+
static vesselTagFactor(s, t, i, o = 0) {
|
|
644
660
|
o = o > 5 ? o - 0.9 * (o - 5) : o;
|
|
645
661
|
let n;
|
|
646
|
-
return
|
|
662
|
+
return i === "container" ? n = 0.7 * o + Math.pow(o, 6.5) / (22 * Math.pow(s, 2 / 3)) : t === "Ballast" ? n = 0.7 * o + Math.pow(o, 6.5) / (2.7 * Math.pow(s, 2 / 3)) : n = 0.5 * o + Math.pow(o, 6.5) / (2.7 * Math.pow(s, 2 / 3)), n;
|
|
647
663
|
}
|
|
648
664
|
/**
|
|
649
665
|
* 浪高影响因子
|
|
@@ -661,12 +677,12 @@ class H {
|
|
|
661
677
|
* @param bearing 方位角
|
|
662
678
|
* @private
|
|
663
679
|
*/
|
|
664
|
-
static assembleProperties(s, t,
|
|
665
|
-
var
|
|
680
|
+
static assembleProperties(s, t, i, o) {
|
|
681
|
+
var u, l;
|
|
666
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;
|
|
667
683
|
return {
|
|
668
684
|
// @ts-ignore
|
|
669
|
-
tag: ((
|
|
685
|
+
tag: ((l = (u = s == null ? void 0 : s.type) == null ? void 0 : u.toLowerCase()) == null ? void 0 : l.indexOf("container")) > -1 ? "container" : "common",
|
|
670
686
|
lbp: n,
|
|
671
687
|
loadCondition: t,
|
|
672
688
|
draught: a,
|
|
@@ -675,7 +691,7 @@ class H {
|
|
|
675
691
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
676
692
|
displacement: Math.round((d / 1.025 + a * e * n * 0.7) * 1e4) / 1e4,
|
|
677
693
|
// 换算为m/s
|
|
678
|
-
speed: Math.round((
|
|
694
|
+
speed: Math.round((i ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
679
695
|
bearing: o || 90
|
|
680
696
|
};
|
|
681
697
|
}
|
|
@@ -686,19 +702,30 @@ class H {
|
|
|
686
702
|
* @param eta 位置时间
|
|
687
703
|
* @param source [CMEMS, GFS, Other]
|
|
688
704
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
705
|
+
* @param useMeteo true 启用气象分析
|
|
689
706
|
* @param useRouteParam true 启用设置速度
|
|
690
707
|
*/
|
|
691
|
-
static async speedLoseAt(s, t,
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
708
|
+
static async speedLoseAt(s, t, i, o = "", n = 2, a = !0, e = !1, d = {}) {
|
|
709
|
+
let c;
|
|
710
|
+
if (t.velocity && e && (s.speed = B.roundPrecision(t.velocity * 1852 / 3600, 6)), a) {
|
|
711
|
+
const u = await et.queryPointFactor(t.lng, t.lat, i.valueOf(), "wind,wave,current,watertemp", o, d), l = E.weatherFactor(s, u), y = E.currentFactor(s.bearing, u == null ? void 0 : u.current, n);
|
|
712
|
+
c = {
|
|
713
|
+
meteo: { ...u },
|
|
714
|
+
wxFactor: l,
|
|
715
|
+
cFactor: y,
|
|
716
|
+
speed: t.velocity && e ? t.velocity : Math.round((s.speed * 1.943844 + l + y) * 100) / 100,
|
|
717
|
+
eta: i.utc().format("YYYY-MM-DDTHH:mm[Z]"),
|
|
718
|
+
etd: i.utc().format("YYYY-MM-DDTHH:mm[Z]")
|
|
719
|
+
};
|
|
720
|
+
} else
|
|
721
|
+
c = {
|
|
722
|
+
wxFactor: 0,
|
|
723
|
+
cFactor: 0,
|
|
724
|
+
speed: t.velocity && e ? t.velocity : Math.round((s.speed * 1.943844 + 0 + 0) * 100) / 100,
|
|
725
|
+
eta: i.utc().format("YYYY-MM-DDTHH:mm[Z]"),
|
|
726
|
+
etd: i.utc().format("YYYY-MM-DDTHH:mm[Z]")
|
|
727
|
+
};
|
|
728
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...c, ...t };
|
|
702
729
|
}
|
|
703
730
|
/**
|
|
704
731
|
* 基于步长计算失速样本
|
|
@@ -709,55 +736,56 @@ class H {
|
|
|
709
736
|
* @param distanceFromStart 与最开始起点的距离
|
|
710
737
|
* @param keypoints 剩下的航路点
|
|
711
738
|
* @param source 气象数据源: CMEMS / GFS
|
|
739
|
+
* @param useMeteo true 启用气象分析
|
|
712
740
|
* @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
|
|
713
741
|
* @private
|
|
714
742
|
*/
|
|
715
|
-
static async speedLoseInHoursStep(s, t,
|
|
743
|
+
static async speedLoseInHoursStep(s, t, i, o, n, a, e = "", d = !0, c = !1, u = {}) {
|
|
716
744
|
t.utc();
|
|
717
|
-
const
|
|
718
|
-
let p = 0,
|
|
719
|
-
for (let
|
|
720
|
-
let
|
|
721
|
-
|
|
722
|
-
const
|
|
723
|
-
if (s.bearing =
|
|
724
|
-
|
|
725
|
-
const
|
|
726
|
-
if (o - p >
|
|
727
|
-
o = o - p -
|
|
745
|
+
const l = [], y = [];
|
|
746
|
+
let p = 0, h = 0, b, I;
|
|
747
|
+
for (let Y = 0; Y < a.length - 1; Y++) {
|
|
748
|
+
let M = a[Y];
|
|
749
|
+
M.distanceFromStart = n + h;
|
|
750
|
+
const r = a[Y + 1];
|
|
751
|
+
if (s.bearing = W.calculateBearing(M, r, !r.gcToPrevious), M.bearing = s.bearing, M.suspend && c) {
|
|
752
|
+
M.eta = M.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), M.elapsed = M.elapsed ?? 0;
|
|
753
|
+
const f = M.suspend - M.elapsed;
|
|
754
|
+
if (o - p > f)
|
|
755
|
+
o = o - p - f, t.add(f, "hour"), M.elapsed = M.suspend;
|
|
728
756
|
else {
|
|
729
|
-
const
|
|
730
|
-
|
|
757
|
+
const N = o - p;
|
|
758
|
+
M.elapsed += N, t.add(N, "hour"), o = 0;
|
|
731
759
|
}
|
|
732
|
-
if (
|
|
733
|
-
return
|
|
760
|
+
if (S == null || S.info(`[%s] suspend ${M.elapsed} hours at %j, and remain ${o} hours need to go...`, u.requestId, M), o === 0)
|
|
761
|
+
return M.distanceFromPrevious = h, { etd: t, from: I || M, to: M, next: a.filter((N) => N), wps: l, days: y };
|
|
734
762
|
}
|
|
735
|
-
|
|
736
|
-
const
|
|
737
|
-
let
|
|
738
|
-
if (p +
|
|
739
|
-
if (p +=
|
|
740
|
-
`[%s] go to %j from %j with ${
|
|
741
|
-
|
|
742
|
-
{ lat:
|
|
743
|
-
{ lat:
|
|
744
|
-
),
|
|
745
|
-
|
|
763
|
+
M = await E.speedLoseAt(s, M, t, e, 0, d, c, u), I = I || M, M.important && l.push(M), t.isSameOrAfter(i) && (y.push(M), i.add(24, "hour"));
|
|
764
|
+
const g = W.calculateDistance(M, r, !r.gcToPrevious);
|
|
765
|
+
let k = Math.ceil(g / I.speed * 1e4) / 1e4;
|
|
766
|
+
if (p + k < o) {
|
|
767
|
+
if (p += k, t.add(k, "hour"), delete a[Y], S == null || S.info(
|
|
768
|
+
`[%s] go to %j from %j with ${g}nm, and cost ${k} hours`,
|
|
769
|
+
u.requestId,
|
|
770
|
+
{ lat: r.lat, lng: r.lng },
|
|
771
|
+
{ lat: I.lat, lng: I.lng, etd: I.etd }
|
|
772
|
+
), h += g, a.filter((f) => f).length <= 1) {
|
|
773
|
+
b = r, b.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), b.distanceFromPrevious = g, b.distanceFromStart = n + h, l.push(b), delete a[Y + 1];
|
|
746
774
|
break;
|
|
747
775
|
}
|
|
748
776
|
} else {
|
|
749
|
-
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
`[%s] go to %j from %j with ${
|
|
753
|
-
|
|
754
|
-
{ lat:
|
|
755
|
-
{ lat:
|
|
756
|
-
),
|
|
777
|
+
k = o - p, t.add(k, "hour");
|
|
778
|
+
const f = B.roundPrecision(I.speed * k, 4);
|
|
779
|
+
b = W.calculateCoordinate(M, s.bearing, f, "nauticalmiles", !r.gcToPrevious), b.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[Y] = b, S == null || S.info(
|
|
780
|
+
`[%s] go to %j from %j with ${f}nm, and cost ${k} hours`,
|
|
781
|
+
u.requestId,
|
|
782
|
+
{ lat: b.lat, lng: b.lng },
|
|
783
|
+
{ lat: M.lat, lng: M.lng, etd: M.etd }
|
|
784
|
+
), h += f, b.distanceFromPrevious = h, b.distanceFromStart = n + h;
|
|
757
785
|
break;
|
|
758
786
|
}
|
|
759
787
|
}
|
|
760
|
-
return { etd: t, from:
|
|
788
|
+
return { etd: t, from: I, to: b, next: a.filter((Y) => Y), wps: l, days: y };
|
|
761
789
|
}
|
|
762
790
|
/**
|
|
763
791
|
* 洋流影响因子
|
|
@@ -765,12 +793,12 @@ class H {
|
|
|
765
793
|
* @param current 洋流要素
|
|
766
794
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
767
795
|
*/
|
|
768
|
-
static currentFactor(s, t,
|
|
796
|
+
static currentFactor(s, t, i = 0) {
|
|
769
797
|
const o = (s - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
770
798
|
if (Math.abs(o) === Math.PI / 2)
|
|
771
799
|
return 0;
|
|
772
800
|
let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(o);
|
|
773
|
-
return
|
|
801
|
+
return i & 2 ? n = Math.ceil(n * 100) / 100 : i & 1 ? n = Math.floor(n * 100) / 100 : n = Math.round(n * 100) / 100, Math.abs(n) > 5 ? 0 : n;
|
|
774
802
|
}
|
|
775
803
|
/**
|
|
776
804
|
* 风浪影响因子
|
|
@@ -778,16 +806,16 @@ class H {
|
|
|
778
806
|
* @param wwc 气象要素
|
|
779
807
|
*/
|
|
780
808
|
static weatherFactor(s, t) {
|
|
781
|
-
var
|
|
782
|
-
|
|
783
|
-
const
|
|
784
|
-
let a = Math.abs(s.bearing % 360 - (((
|
|
809
|
+
var l, y, p, h, b;
|
|
810
|
+
S == null || S.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
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 - (((l = t == null ? void 0 : t.wind) == null ? void 0 : l.degree) % 360 || 0));
|
|
785
813
|
a = a > 180 ? 360 - a : a;
|
|
786
|
-
const e =
|
|
787
|
-
let
|
|
788
|
-
|
|
789
|
-
const
|
|
790
|
-
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, (p = t == null ? void 0 : t.wind) == null ? void 0 : p.scale);
|
|
815
|
+
let c = e * n * d / 100 * s.speed;
|
|
816
|
+
c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1;
|
|
817
|
+
const u = E.waveHeightFactor(((b = (h = t == null ? void 0 : t.wave) == null ? void 0 : h.sig) == null ? void 0 : b.height) ?? 1);
|
|
818
|
+
return c = c * 0.24 + u * 0.76, S == null || S.debug("weather factor = %s", c), Math.round(c * 100) / 100;
|
|
791
819
|
}
|
|
792
820
|
/**
|
|
793
821
|
* 全程失速分析(走完航程)
|
|
@@ -798,16 +826,17 @@ class H {
|
|
|
798
826
|
* @param lane 航线 { points: { route, waypoints }}
|
|
799
827
|
* @param source 气象数据源,GFS or CMEMES, 默认CMEMS
|
|
800
828
|
* @param stepHrs 样本步长, 0表示动态计算(6 or 3 hrs)
|
|
829
|
+
* @param useMeteo true 启用气象分析
|
|
801
830
|
* @param useRouteParam
|
|
802
831
|
*/
|
|
803
|
-
static async analyseInstant(s, t,
|
|
804
|
-
var
|
|
805
|
-
const
|
|
806
|
-
s.lng =
|
|
807
|
-
const { route:
|
|
808
|
-
if (((
|
|
832
|
+
static async analyseInstant(s, t, i, o, n, a = "", e = 0, d = !0, c = !1, u = {}) {
|
|
833
|
+
var P, V, G, U, J;
|
|
834
|
+
const l = v().valueOf();
|
|
835
|
+
s.lng = B.convertToStdLng(s.lng);
|
|
836
|
+
const { route: y, waypoints: p } = n.points, h = W.calculateSubRoute(s, y);
|
|
837
|
+
if (((P = h[0]) == null ? void 0 : P.length) <= 1)
|
|
809
838
|
return;
|
|
810
|
-
const { v0:
|
|
839
|
+
const { v0: b, label: I } = s.sog ? {
|
|
811
840
|
v0: s.sog,
|
|
812
841
|
label: "Other"
|
|
813
842
|
/* Instruct */
|
|
@@ -815,40 +844,51 @@ class H {
|
|
|
815
844
|
v0: o.speed,
|
|
816
845
|
label: "CP"
|
|
817
846
|
/* Cp */
|
|
818
|
-
},
|
|
847
|
+
}, Y = E.assembleProperties(i, o.loadCondition, b, 0), M = p.length ? W.calculateSubWaypoints(s, p) : [], r = {
|
|
819
848
|
from: { ...s },
|
|
820
|
-
route:
|
|
821
|
-
waypoints:
|
|
822
|
-
v0:
|
|
823
|
-
label:
|
|
824
|
-
},
|
|
849
|
+
route: h,
|
|
850
|
+
waypoints: M,
|
|
851
|
+
v0: b,
|
|
852
|
+
label: I
|
|
853
|
+
}, g = {
|
|
825
854
|
hours: [],
|
|
826
855
|
days: [],
|
|
827
856
|
wps: []
|
|
828
857
|
};
|
|
829
|
-
e || (
|
|
830
|
-
let
|
|
831
|
-
t =
|
|
832
|
-
const
|
|
833
|
-
for (;
|
|
834
|
-
const F = e - t.hour() % e,
|
|
835
|
-
|
|
858
|
+
e || (W.calculateRouteDistance(h) / o.speed <= 72 ? e = 3 : e = 6);
|
|
859
|
+
let k = W.simplifyRouteToCoordinates(h, M, 0), f = 0, N = 0, A = 0, x = 0;
|
|
860
|
+
t = v(t).utc();
|
|
861
|
+
const O = t.clone();
|
|
862
|
+
for (; k.length > 0; ) {
|
|
863
|
+
const F = e - t.hour() % e, L = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, H = await E.speedLoseInHoursStep(
|
|
864
|
+
Y,
|
|
865
|
+
t,
|
|
866
|
+
O,
|
|
867
|
+
L,
|
|
868
|
+
f,
|
|
869
|
+
k,
|
|
870
|
+
a,
|
|
871
|
+
d,
|
|
872
|
+
c,
|
|
873
|
+
u
|
|
874
|
+
);
|
|
875
|
+
(V = H.from) != null && V.speed && (g.hours.push(H.from), g.wps.push(...H.wps), g.days.push(...H.days)), k = H == null ? void 0 : H.next, k.length || g.hours.push(H == null ? void 0 : H.to), f += ((G = H == null ? void 0 : H.to) == null ? void 0 : G.distanceFromPrevious) ?? 0;
|
|
836
876
|
}
|
|
837
|
-
const j =
|
|
877
|
+
const j = g.hours;
|
|
838
878
|
for (let F = 0; F < j.length - 1; F++) {
|
|
839
|
-
const
|
|
840
|
-
|
|
879
|
+
const L = v(j[F + 1].eta).diff(j[F].etd, "hour", !0) || 1;
|
|
880
|
+
N += j[F].wxFactor || 0 * L, A += j[F].cFactor || 0 * L, x += L;
|
|
841
881
|
}
|
|
842
|
-
(
|
|
843
|
-
if (
|
|
844
|
-
const
|
|
845
|
-
|
|
882
|
+
(U = g.wps) == null || U.forEach((F, L) => {
|
|
883
|
+
if (L) {
|
|
884
|
+
const H = g.wps[L - 1], X = F.distanceFromStart - H.distanceFromStart, Q = v(F.eta).diff(v(H.etd), "h", !0);
|
|
885
|
+
Q < 1 ? F.avgSpd = H.speed : F.avgSpd = Math.round(X / Q * 100) / 100;
|
|
846
886
|
}
|
|
847
|
-
}),
|
|
848
|
-
const
|
|
849
|
-
|
|
850
|
-
const
|
|
851
|
-
return
|
|
887
|
+
}), r.sample = g;
|
|
888
|
+
const D = g.hours.at(-1);
|
|
889
|
+
r.distance = Math.round(D.distanceFromStart * 1e4) / 1e4, r.eta = v(D.eta).toDate(), r.wxFactor = Math.round(N / x * 1e4) / 1e4, r.cFactor = Math.round(A / x * 1e4) / 1e4, r.avgSpeed = Math.round(D.distanceFromStart / x * 1e4) / 1e4, r.totalHrs = Math.round(x * 1e4) / 1e4, r.totalFoCons = Math.round((o == null ? void 0 : o.fo) / 24 * r.totalHrs * 1e3) / 1e3, r.totalDgoCons = Math.round((o == null ? void 0 : o.dgo) / 24 * r.totalHrs * 1e3) / 1e3;
|
|
890
|
+
const T = v().valueOf() - l, q = ((J = g == null ? void 0 : g.hours) == null ? void 0 : J.length) || 1;
|
|
891
|
+
return S == null || S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", u == null ? void 0 : u.requestId, T, q, Math.round(T / q * 1e3) / 1e3), r;
|
|
852
892
|
}
|
|
853
893
|
/**
|
|
854
894
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -860,61 +900,74 @@ class H {
|
|
|
860
900
|
* @param route 航路[[[lng, lat]]]
|
|
861
901
|
* @param source 气象数据源,GFS or CMEMES, 默认CMEMS
|
|
862
902
|
* @param stepHrs
|
|
903
|
+
* @param useMeteo true 启用气象分析
|
|
904
|
+
* @param useRouteParam
|
|
863
905
|
*/
|
|
864
|
-
static async analyseInstantWithThreshed(s, t,
|
|
865
|
-
var
|
|
866
|
-
s.lng =
|
|
867
|
-
const
|
|
868
|
-
if (((
|
|
906
|
+
static async analyseInstantWithThreshed(s, t, i, o, n, a, e = "", d = 3, c = !0, u = !1, l = {}) {
|
|
907
|
+
var A, x, O;
|
|
908
|
+
s.lng = B.convertToStdLng(s.lng);
|
|
909
|
+
const y = E.assembleProperties(o, n.loadCondition, n.speed, 0), p = W.calculateSubRoute(s, a);
|
|
910
|
+
if (((A = p[0]) == null ? void 0 : A.length) <= 1)
|
|
869
911
|
return;
|
|
870
|
-
let
|
|
871
|
-
|
|
872
|
-
let
|
|
873
|
-
const
|
|
912
|
+
let h = W.simplifyRouteToCoordinates(p, [], 0);
|
|
913
|
+
h.forEach((j) => j.important = !0);
|
|
914
|
+
let b = 0, I = 0, Y = 0, M = 0, r;
|
|
915
|
+
const g = {
|
|
874
916
|
hours: [],
|
|
875
917
|
wps: [],
|
|
876
918
|
days: []
|
|
877
919
|
};
|
|
878
|
-
for (t =
|
|
920
|
+
for (t = v(t).utc(); h.length > 0; ) {
|
|
879
921
|
const j = d - t.hour() % d;
|
|
880
|
-
let
|
|
881
|
-
if (
|
|
882
|
-
|
|
922
|
+
let D = Math.ceil(t.clone().add(j, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
923
|
+
if (D = t.clone().add(D, "h").isAfter(i) ? i.diff(t, "h", !0) * 1e4 / 1e4 : D, D)
|
|
924
|
+
r = await E.speedLoseInHoursStep(
|
|
925
|
+
y,
|
|
926
|
+
t,
|
|
927
|
+
i.clone(),
|
|
928
|
+
D,
|
|
929
|
+
b,
|
|
930
|
+
h,
|
|
931
|
+
e,
|
|
932
|
+
c,
|
|
933
|
+
u,
|
|
934
|
+
l
|
|
935
|
+
), (x = r.from) != null && x.speed && (g.hours.push(r.from), r != null && r.wps && g.wps.push(...r.wps), g.days.push(...r.days)), h = r == null ? void 0 : r.next, h.length || (g.hours.push(r == null ? void 0 : r.to), r != null && r.wps && g.wps.push(...r.wps), g.days.push(r == null ? void 0 : r.to)), b += ((O = r == null ? void 0 : r.to) == null ? void 0 : O.distanceFromPrevious) ?? 0;
|
|
883
936
|
else {
|
|
884
|
-
|
|
937
|
+
r && (g.hours.push(r.to), r != null && r.wps && g.wps.push(...r.wps), g.days.push(r.to));
|
|
885
938
|
break;
|
|
886
939
|
}
|
|
887
940
|
}
|
|
888
|
-
const
|
|
889
|
-
for (let j = 0; j <
|
|
890
|
-
const
|
|
891
|
-
|
|
941
|
+
const k = g.hours;
|
|
942
|
+
for (let j = 0; j < k.length - 1; j++) {
|
|
943
|
+
const D = v(k[j + 1].eta).diff(k[j].etd, "hour", !0);
|
|
944
|
+
I += k[j].wxFactor * D, Y += k[j].cFactor * D, M += D;
|
|
892
945
|
}
|
|
893
|
-
const
|
|
946
|
+
const f = g.hours.at(-1);
|
|
894
947
|
return {
|
|
895
|
-
sample:
|
|
896
|
-
distance: Math.round(((
|
|
897
|
-
eta:
|
|
898
|
-
wxFactor: Math.round(
|
|
899
|
-
cFactor: Math.round(
|
|
900
|
-
avgSpeed: Math.round(((
|
|
901
|
-
totalHrs: Math.round(
|
|
902
|
-
to:
|
|
903
|
-
route:
|
|
948
|
+
sample: g,
|
|
949
|
+
distance: Math.round(((f == null ? void 0 : f.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
950
|
+
eta: v(f == null ? void 0 : f.eta).utc().format(),
|
|
951
|
+
wxFactor: Math.round(I / M * 1e4) / 1e4,
|
|
952
|
+
cFactor: Math.round(Y / M * 1e4) / 1e4,
|
|
953
|
+
avgSpeed: Math.round(((f == null ? void 0 : f.distanceFromStart) || 0) / M * 1e4) / 1e4,
|
|
954
|
+
totalHrs: Math.round(M * 1e4) / 1e4,
|
|
955
|
+
to: f,
|
|
956
|
+
route: W.generateRouteAccordingToWaypoints(h)
|
|
904
957
|
};
|
|
905
958
|
}
|
|
906
959
|
}
|
|
907
960
|
export {
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
961
|
+
K as AISImpl,
|
|
962
|
+
at as AlertHelper,
|
|
963
|
+
st as AlertLevel,
|
|
964
|
+
mt as HifleetImpl,
|
|
965
|
+
nt as LoadCondition,
|
|
966
|
+
Mt as MyShipImpl,
|
|
967
|
+
ft as MyVesselImpl,
|
|
968
|
+
pt as ShipxyImpl,
|
|
969
|
+
E as SpeedHelper,
|
|
970
|
+
it as SpeedLabel,
|
|
971
|
+
ot as VesselTag,
|
|
972
|
+
yt as alertHelper
|
|
920
973
|
};
|