@idm-plugin/vessel 1.2.1 → 1.2.2
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 +349 -333
- package/dist/index.umd.cjs +1 -1
- 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
|
|
1
|
+
var X = Object.defineProperty;
|
|
2
|
+
var $ = (k, s, t) => s in k ? X(k, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : k[s] = t;
|
|
3
|
+
var B = (k, s, t) => ($(k, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
|
+
import R from "got";
|
|
5
|
+
import z from "@log4js-node/log4js-api";
|
|
6
|
+
import b from "moment";
|
|
7
|
+
import { LngLatHelper as Z, LaneHelper as O } from "@idm-plugin/geo";
|
|
8
8
|
import { MeteoHelper as tt } from "@idm-plugin/meteo";
|
|
9
|
-
|
|
10
|
-
|
|
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 lt extends
|
|
52
|
-
constructor(t,
|
|
56
|
+
class lt extends K {
|
|
57
|
+
constructor(t, i) {
|
|
53
58
|
super();
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.clientId = t, this.clientSecret =
|
|
59
|
+
B(this, "clientId");
|
|
60
|
+
B(this, "clientSecret");
|
|
61
|
+
B(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: b().utc().format()
|
|
74
79
|
});
|
|
75
80
|
}
|
|
76
|
-
async realTimePosition(t,
|
|
77
|
-
var
|
|
78
|
-
(!this.token ||
|
|
81
|
+
async realTimePosition(t, i = {}) {
|
|
82
|
+
var p, M, y;
|
|
83
|
+
(!this.token || b().diff(b(this.token.issuedAt), "seconds") > ((p = this.token) == null ? void 0 : p.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: `${(M = this.token) == null ? void 0 : M.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
95
|
for (const f in e)
|
|
91
96
|
!isNaN(e[f]) && Number(e[f]) !== 1 / 0 && (e[f] = Number(e[f]));
|
|
92
|
-
const d =
|
|
97
|
+
const d = b(`${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,35 +120,35 @@ 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 || b().diff(b(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
|
|
125
|
+
const d = await this.realTimePosition(t, e), r = b(i), p = b(o), M = [];
|
|
126
|
+
for (; p.diff(r, "day", !0) > 30; )
|
|
127
|
+
await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), d, n, M, e), r.add(30, "day");
|
|
128
|
+
return await this.trajectoryIn30Day(t, r, p, d, n, M, e), M;
|
|
124
129
|
}
|
|
125
|
-
async trajectoryIn30Day(t,
|
|
126
|
-
var l,
|
|
127
|
-
const
|
|
130
|
+
async trajectoryIn30Day(t, i, o, n, a, e, d = {}) {
|
|
131
|
+
var l, v, Y, u, c;
|
|
132
|
+
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", p = {
|
|
128
133
|
headers: {
|
|
129
|
-
Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(
|
|
134
|
+
Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(v = this.token) == null ? void 0 : v.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 f =
|
|
143
|
-
return (c =
|
|
144
|
-
for (const
|
|
145
|
-
!isNaN(h[
|
|
146
|
-
const
|
|
142
|
+
m == null || m.info("[%s] fetch trajectory from: %s - %j", d.requestId, r, p);
|
|
143
|
+
const M = await R.post(r, p).json();
|
|
144
|
+
if (M.code)
|
|
145
|
+
return m == null || m.warn("[%s] fetch trajectory failed: %j", d.requestId, r, { message: M.message, status: M.status, code: M.code }), M;
|
|
146
|
+
let y = -1;
|
|
147
|
+
const f = b(`${(u = (Y = M.data) == null ? void 0 : Y[0]) == null ? void 0 : u.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
148
|
+
return (c = M.data) == null || c.forEach((h) => {
|
|
149
|
+
for (const S in h)
|
|
150
|
+
!isNaN(h[S]) && Number(h[S]) !== 1 / 0 && (h[S] = Number(h[S]));
|
|
151
|
+
const w = b(`${h.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), I = h.eta ? b(`${h.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, g = h.status, { labelCn: F, labelEn: x } = this.parseStatus(g), A = {
|
|
147
152
|
mmsi: h.mmsi,
|
|
148
153
|
imo: n == null ? void 0 : n.imo,
|
|
149
154
|
lat: h.lat,
|
|
@@ -152,41 +157,41 @@ class lt extends Z {
|
|
|
152
157
|
cog: h.cog,
|
|
153
158
|
hdg: h.hdg,
|
|
154
159
|
draught: h.draught,
|
|
155
|
-
status:
|
|
156
|
-
eta:
|
|
160
|
+
status: g,
|
|
161
|
+
eta: I == null ? void 0 : I.unix(),
|
|
157
162
|
destination: h.dest,
|
|
158
|
-
positionTime:
|
|
159
|
-
labelCn:
|
|
160
|
-
labelEn:
|
|
163
|
+
positionTime: w.unix(),
|
|
164
|
+
labelCn: F,
|
|
165
|
+
labelEn: x,
|
|
161
166
|
method: "trajectory",
|
|
162
167
|
vendor: "myVessel",
|
|
163
|
-
utc:
|
|
164
|
-
},
|
|
165
|
-
|
|
168
|
+
utc: w.utc().format()
|
|
169
|
+
}, T = Math.floor(w.diff(f, "minute", !0) / (a || 1));
|
|
170
|
+
T !== y && (y = T, e.push(A));
|
|
166
171
|
}), e;
|
|
167
172
|
}
|
|
168
173
|
}
|
|
169
|
-
class ft extends
|
|
174
|
+
class ft extends K {
|
|
170
175
|
constructor(t) {
|
|
171
176
|
super();
|
|
172
|
-
|
|
177
|
+
B(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
|
|
190
|
+
return m == null || m.warn("[%s] fetch realtime position failed: %j", i.requestId, o, a), a;
|
|
186
191
|
for (const f in e)
|
|
187
192
|
!isNaN(e[f]) && Number(e[f]) !== 1 / 0 && (e[f] = Number(e[f]));
|
|
188
193
|
e.status = e.sp > 3 ? 0 : 1;
|
|
189
|
-
const d = e.status, { labelCn:
|
|
194
|
+
const d = e.status, { labelCn: r, labelEn: p } = this.parseStatus(d), M = b(`${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) ? b(`${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: M.unix(),
|
|
212
|
+
utc: M.utc().format(),
|
|
208
213
|
status: d,
|
|
209
|
-
labelCn:
|
|
210
|
-
labelEn:
|
|
214
|
+
labelCn: r,
|
|
215
|
+
labelEn: p,
|
|
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 h,
|
|
247
|
+
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
248
|
+
var h, w, I;
|
|
244
249
|
const d = await this.realTimePosition(t, e);
|
|
245
|
-
let
|
|
246
|
-
const
|
|
250
|
+
let r = b(i);
|
|
251
|
+
const p = b(o), M = b();
|
|
247
252
|
if (a) {
|
|
248
|
-
let
|
|
249
|
-
|
|
253
|
+
let g = p.diff(r, "d", !0);
|
|
254
|
+
g < 0 ? r = p.clone().subtract(40, "d") : g < 30 ? r.subtract(10, "d") : g < 60 ? r.subtract(5, "d") : r = p.clone().subtract(80, "d"), g = M.diff(p, "d", !0), p.add(g > 10 ? 240 : g * 24, "h");
|
|
250
255
|
}
|
|
251
|
-
const
|
|
256
|
+
const y = {
|
|
252
257
|
searchParams: {
|
|
253
|
-
endtime:
|
|
254
|
-
starttime:
|
|
258
|
+
endtime: p.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
259
|
+
starttime: r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
255
260
|
mmsi: t,
|
|
256
261
|
usertoken: this.token
|
|
257
262
|
}
|
|
258
|
-
}, f = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", l = await
|
|
259
|
-
|
|
260
|
-
let
|
|
261
|
-
l && (
|
|
262
|
-
const
|
|
263
|
+
}, f = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", l = await R.get(f, y).json();
|
|
264
|
+
m == null || m.info("[%s] fetch trajectory from: %s - %j", e.requestId, f, y);
|
|
265
|
+
let v;
|
|
266
|
+
l && (v = ((w = (h = l.ships) == null ? void 0 : h.offors) == null ? void 0 : w.ship) || [], v.length || m == null || m.warn("[%s] fetch trajectory failed: %j", e.requestId, l));
|
|
267
|
+
const Y = [];
|
|
263
268
|
let u = -1;
|
|
264
|
-
const c =
|
|
265
|
-
for (const
|
|
266
|
-
for (const
|
|
267
|
-
!isNaN(
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
const { labelEn:
|
|
271
|
-
mmsi:
|
|
272
|
-
name:
|
|
269
|
+
const c = b(`${(I = v == null ? void 0 : v[0]) == null ? void 0 : I.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
270
|
+
for (const g of v) {
|
|
271
|
+
for (const L in g)
|
|
272
|
+
!isNaN(g[L]) && Number(g[L]) !== 1 / 0 && (g[L] = Number(g[L]));
|
|
273
|
+
const F = b(`${g.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
274
|
+
g.status = g.sp > 4 ? 0 : 1;
|
|
275
|
+
const { labelEn: x, labelCn: A } = this.parseStatus(g.status), T = {
|
|
276
|
+
mmsi: g.m,
|
|
277
|
+
name: g.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: g.la,
|
|
280
|
+
lng: g.lo,
|
|
281
|
+
draught: g.draught,
|
|
282
|
+
sog: g.sp,
|
|
283
|
+
cog: g.co,
|
|
284
|
+
hdg: g.hdg,
|
|
285
|
+
positionTime: F.unix(),
|
|
286
|
+
utc: F.utc().format(),
|
|
287
|
+
status: g.status,
|
|
288
|
+
labelCn: A,
|
|
289
|
+
labelEn: x,
|
|
285
290
|
method: "trajectory",
|
|
286
291
|
vendor: "hifleet"
|
|
287
|
-
},
|
|
288
|
-
|
|
292
|
+
}, S = Math.floor(F.diff(c, "minute", !0) / (n || 1));
|
|
293
|
+
S !== u && (u = S, Y.push(T));
|
|
289
294
|
}
|
|
290
|
-
return
|
|
295
|
+
return Y;
|
|
291
296
|
}
|
|
292
297
|
}
|
|
293
|
-
class mt extends
|
|
298
|
+
class mt extends K {
|
|
294
299
|
constructor(t) {
|
|
295
300
|
super();
|
|
296
|
-
|
|
301
|
+
B(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: r } = await this.parseStatus(e.navistat), p = b.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: p.utc().format(),
|
|
329
334
|
status: e.navistat,
|
|
330
|
-
labelEn:
|
|
335
|
+
labelEn: r,
|
|
331
336
|
labelCn: d,
|
|
332
337
|
method: "position",
|
|
333
338
|
vendor: "shipxy"
|
|
334
339
|
};
|
|
335
340
|
}
|
|
336
|
-
async trajectory(t,
|
|
341
|
+
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
337
342
|
var c;
|
|
338
|
-
const d = await this.realTimePosition(t, e),
|
|
343
|
+
const d = await this.realTimePosition(t, e), r = b(i), p = b(o), M = "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: r.unix(),
|
|
350
|
+
etm: p.unix()
|
|
346
351
|
}
|
|
347
|
-
}, f = await
|
|
348
|
-
if (
|
|
352
|
+
}, f = await R.get(M, y).json();
|
|
353
|
+
if (m == null || m.info("[%s] fetch trajectory from: %s - %j", e.requestId, M, y), (f == null ? void 0 : f.status) !== 0)
|
|
349
354
|
return f;
|
|
350
|
-
const l = f == null ? void 0 : f.points,
|
|
355
|
+
const l = f == null ? void 0 : f.points, v = [], Y = b.unix((c = l[0]) == null ? void 0 : c.utc);
|
|
351
356
|
let u = -1;
|
|
352
357
|
for (const h of l) {
|
|
353
|
-
const
|
|
358
|
+
const w = b.unix(h.utc), I = {
|
|
354
359
|
imo: d == null ? void 0 : d.imo,
|
|
355
360
|
mmsi: t,
|
|
356
361
|
sog: Math.round(h.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
357
362
|
cog: Math.round(h.cog / 100 * 100) / 100,
|
|
358
363
|
lat: Math.round(h.lat / 1e6 * 1e5) / 1e5,
|
|
359
364
|
lng: Math.round(h.lon / 1e6 * 1e5) / 1e5,
|
|
360
|
-
positionTime:
|
|
361
|
-
utc:
|
|
365
|
+
positionTime: w.unix(),
|
|
366
|
+
utc: w.utc().format(),
|
|
362
367
|
method: "trajectory",
|
|
363
368
|
vendor: "shipxy"
|
|
364
|
-
},
|
|
365
|
-
|
|
369
|
+
}, g = Math.floor(w.diff(Y, "minute", !0) / (n || 1));
|
|
370
|
+
g !== u && (u = g, v.push(I));
|
|
366
371
|
}
|
|
367
|
-
return
|
|
372
|
+
return v;
|
|
368
373
|
}
|
|
369
374
|
}
|
|
370
|
-
class
|
|
375
|
+
class pt extends K {
|
|
371
376
|
constructor(t) {
|
|
372
377
|
super();
|
|
373
|
-
|
|
378
|
+
B(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,65 +412,65 @@ 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 l in
|
|
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 r = d.data[0];
|
|
426
|
+
for (const l in r)
|
|
427
|
+
!isNaN(r[l]) && Number(r[l]) !== 1 / 0 && (r[l] = Number(r[l]));
|
|
428
|
+
const { labelCn: p, labelEn: M } = await this.parseStatus(r.aisNavStatus), y = b.unix(r.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(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: M,
|
|
442
|
+
labelCn: p,
|
|
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 = b(i), r = b(o), p = await this.getShipId(t), M = await this.getShipInfo(p), y = [];
|
|
449
|
+
for (; r.diff(d, "day", !0) > 30; )
|
|
450
|
+
await this.trajectoryIn30Day(p, d.unix(), d.add(30, "day").unix(), M, t, n, y);
|
|
451
|
+
return await this.trajectoryIn30Day(p, d.unix(), r.unix(), M, t, n, y), y;
|
|
447
452
|
}
|
|
448
|
-
async trajectoryIn30Day(t,
|
|
449
|
-
var
|
|
450
|
-
const
|
|
453
|
+
async trajectoryIn30Day(t, i, o, n, a, e, d, r = {}) {
|
|
454
|
+
var Y;
|
|
455
|
+
const p = {
|
|
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 f =
|
|
464
|
+
}, M = "https://api3.myships.com/sp/ships/position/history", y = await R.post(M, p).json();
|
|
465
|
+
if (m == null || m.info("[%s] fetch trajectory from: %s - %j", r.requestId, M, p), y.code !== "0")
|
|
466
|
+
return m == null || m.warn("[%s] invoke myship trajectory failed: %j", r.requestId, y), y;
|
|
467
|
+
const f = y.data;
|
|
463
468
|
for (const u in f)
|
|
464
469
|
!isNaN(f[u]) && Number(f[u]) !== 1 / 0 && (f[u] = Number(f[u]));
|
|
465
|
-
const l =
|
|
466
|
-
let
|
|
470
|
+
const l = b.unix((Y = f[0]) == null ? void 0 : Y.posTime);
|
|
471
|
+
let v = -1;
|
|
467
472
|
for (const u of f) {
|
|
468
|
-
const c =
|
|
473
|
+
const c = b.unix(u.posTime), h = {
|
|
469
474
|
imo: n == null ? void 0 : n.imo,
|
|
470
475
|
mmsi: a,
|
|
471
476
|
lat: Math.round(u.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
@@ -478,13 +483,18 @@ class gt extends Z {
|
|
|
478
483
|
utc: c.utc().format(),
|
|
479
484
|
method: "trajectory",
|
|
480
485
|
vendor: "myship"
|
|
481
|
-
},
|
|
482
|
-
|
|
486
|
+
}, w = Math.floor(c.diff(l, "minute", !0) / (e || 1));
|
|
487
|
+
w !== v && (v = w, d.push(h));
|
|
483
488
|
}
|
|
484
489
|
return d;
|
|
485
490
|
}
|
|
486
491
|
}
|
|
487
|
-
|
|
492
|
+
let C;
|
|
493
|
+
try {
|
|
494
|
+
C = z.getLogger("vessel");
|
|
495
|
+
} catch {
|
|
496
|
+
} finally {
|
|
497
|
+
}
|
|
488
498
|
var et = /* @__PURE__ */ ((k) => (k.NOTICE = "NOTICE", k.WARN = "WARN", k.HEAVY = "HEAVY", k.SEVERE = "SEVERE", k.ERROR = "ERROR", k.FATAL = "FATAL", k))(et || {});
|
|
489
499
|
class st {
|
|
490
500
|
/**
|
|
@@ -496,19 +506,19 @@ class st {
|
|
|
496
506
|
* @param options
|
|
497
507
|
*/
|
|
498
508
|
parsePrinciple(s, t = {}) {
|
|
499
|
-
var e, d,
|
|
500
|
-
|
|
501
|
-
const
|
|
509
|
+
var e, d, r;
|
|
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 p = 0; p < (n == null ? void 0 : n.length); p++) {
|
|
516
|
+
const M = (r = (d = n[p].match(i)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
|
|
517
|
+
if (p === 0 && !M)
|
|
508
518
|
a.scope = n[0];
|
|
509
|
-
else if (
|
|
510
|
-
for (let
|
|
511
|
-
const l = this.parseRule(
|
|
519
|
+
else if (M)
|
|
520
|
+
for (let y = 0, f = M.length; y < f; y++) {
|
|
521
|
+
const l = this.parseRule(M[y]);
|
|
512
522
|
l && (a[l.level] ? l.key ? a[l.level][l == null ? void 0 : l.key] = l : a[l.level] = l : l.key ? a[l.level] = { [l == null ? void 0 : l.key]: l } : a[l.level] = l);
|
|
513
523
|
}
|
|
514
524
|
}
|
|
@@ -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 l,
|
|
552
|
+
checkWeather(s, t, i = {}) {
|
|
553
|
+
var l, v, Y, u, c, h, w, I, g, F, x, A, T, S, L;
|
|
544
554
|
let o = 0, n = 0, a = 0, e = 0;
|
|
545
|
-
const d = Math.round(((
|
|
546
|
-
for (let
|
|
547
|
-
const
|
|
548
|
-
e =
|
|
555
|
+
const d = Math.round(((v = (l = t == null ? void 0 : t.SEVERE) == null ? void 0 : l.sigWave) == null ? void 0 : v.number) * 1.6 * 100) / 100, r = (u = (Y = t == null ? void 0 : t.SEVERE) == null ? void 0 : Y.sigWave) == null ? void 0 : u.number, p = (h = (c = t == null ? void 0 : t.HEAVY) == null ? void 0 : c.sigWave) == null ? void 0 : h.number, M = Math.round((((I = (w = t == null ? void 0 : t.SEVERE) == null ? void 0 : w.wind) == null ? void 0 : I.number) + 2) * 100) / 100, y = (F = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.wind) == null ? void 0 : F.number, f = (A = (x = t == null ? void 0 : t.HEAVY) == null ? void 0 : x.wind) == null ? void 0 : A.number;
|
|
556
|
+
for (let V = 0; V < (s == null ? void 0 : s.length); V++) {
|
|
557
|
+
const j = s[V], q = (S = (T = j == null ? void 0 : j.meteo) == null ? void 0 : T.wave) == null ? void 0 : S.sig, P = (L = j == null ? void 0 : j.meteo) == null ? void 0 : L.wind, _ = V ? b(j.eta).diff(b(s[V - 1].eta), "hour", !0) : 0;
|
|
558
|
+
e = _ > e ? _ : e, C == null || C.info("[%s] check sig.wave: %j", i.requestId, { ...q, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: p }), (q == null ? void 0 : q.height) >= d ? j.isDangerous = !0 : (q == null ? void 0 : q.height) >= r ? j.isSevere = !0 : (q == null ? void 0 : q.height) >= p && (j.isHeavy = !0), C == null || C.info("[%s] check wind: %j", i.requestId, { ...P, dgThd4Wd: M, svThd4Wd: y, hvThd4Wd: f }), (P == null ? void 0 : P.scale) >= M ? (j.isDangerous = !0, delete j.isSevere, delete j.isHeavy) : (P == null ? void 0 : P.scale) > y ? (j.isDangerous || (j.isSevere = !0), delete j.isHeavy) : (P == null ? void 0 : P.scale) === f && !j.isDangerous && !j.isSevere && (j.isHeavy = !0), o += j.isDangerous ? _ : 0, n += j.isSevere ? _ : 0, a += j.isHeavy ? _ : 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: M, svThd4Wd: y, hvThd4Wd: f }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: p } };
|
|
551
561
|
}
|
|
552
562
|
}
|
|
553
|
-
const
|
|
563
|
+
const Mt = new st();
|
|
564
|
+
let D;
|
|
565
|
+
try {
|
|
566
|
+
D = z.getLogger("vessel");
|
|
567
|
+
} catch {
|
|
568
|
+
} finally {
|
|
569
|
+
}
|
|
554
570
|
var at = /* @__PURE__ */ ((k) => (k.common = "common", k.container = "container", k))(at || {}), ot = /* @__PURE__ */ ((k) => (k.Ballast = "Ballast", k.Laden = "Laden", k))(ot || {}), nt = /* @__PURE__ */ ((k) => (k.Cp = "CP", k.Perf = "Basis", k.Instruct = "Other", k))(nt || {});
|
|
555
|
-
class
|
|
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 p, M;
|
|
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: ((M = (p = s == null ? void 0 : s.type) == null ? void 0 : p.toLowerCase()) == null ? void 0 : M.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
|
}
|
|
@@ -688,17 +704,17 @@ class H {
|
|
|
688
704
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
689
705
|
* @param useRouteParam true 启用设置速度
|
|
690
706
|
*/
|
|
691
|
-
static async speedLoseAt(s, t,
|
|
692
|
-
t.velocity && !t.noFactor && a && (s.speed =
|
|
693
|
-
const d = await tt.queryPointFactor(t.lng, t.lat,
|
|
707
|
+
static async speedLoseAt(s, t, i, o = "", n = 2, a = !1, e = {}) {
|
|
708
|
+
t.velocity && !t.noFactor && a && (s.speed = Z.roundPrecision(t.velocity * 1852 / 3600, 6));
|
|
709
|
+
const d = await tt.queryPointFactor(t.lng, t.lat, i.valueOf(), "wind,wave,current,watertemp", o, e), r = E.weatherFactor(s, d), p = E.currentFactor(s.bearing, d == null ? void 0 : d.current, n), M = {
|
|
694
710
|
meteo: { ...d },
|
|
695
|
-
wxFactor:
|
|
696
|
-
cFactor:
|
|
697
|
-
speed: t.velocity && a ? t.velocity : Math.round((s.speed * 1.943844 +
|
|
698
|
-
eta:
|
|
699
|
-
etd:
|
|
711
|
+
wxFactor: r,
|
|
712
|
+
cFactor: p,
|
|
713
|
+
speed: t.velocity && a ? t.velocity : Math.round((s.speed * 1.943844 + r + p) * 100) / 100,
|
|
714
|
+
eta: i.utc().format("YYYY-MM-DDTHH:mm[Z]"),
|
|
715
|
+
etd: i.utc().format("YYYY-MM-DDTHH:mm[Z]")
|
|
700
716
|
};
|
|
701
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
717
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...M, ...t };
|
|
702
718
|
}
|
|
703
719
|
/**
|
|
704
720
|
* 基于步长计算失速样本
|
|
@@ -712,52 +728,52 @@ class H {
|
|
|
712
728
|
* @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
|
|
713
729
|
* @private
|
|
714
730
|
*/
|
|
715
|
-
static async speedLoseInHoursStep(s, t,
|
|
731
|
+
static async speedLoseInHoursStep(s, t, i, o, n, a, e = "", d = !1, r = {}) {
|
|
716
732
|
t.utc();
|
|
717
|
-
const
|
|
718
|
-
let
|
|
719
|
-
for (let
|
|
720
|
-
let u = a[
|
|
733
|
+
const p = [], M = [];
|
|
734
|
+
let y = 0, f = 0, l, v;
|
|
735
|
+
for (let Y = 0; Y < a.length - 1; Y++) {
|
|
736
|
+
let u = a[Y];
|
|
721
737
|
u.distanceFromStart = n + f;
|
|
722
|
-
const c = a[
|
|
723
|
-
if (s.bearing =
|
|
738
|
+
const c = a[Y + 1];
|
|
739
|
+
if (s.bearing = O.calculateBearing(u, c, !c.gcToPrevious), u.bearing = s.bearing, u.suspend && d) {
|
|
724
740
|
u.eta = u.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), u.elapsed = u.elapsed ?? 0;
|
|
725
|
-
const
|
|
726
|
-
if (o -
|
|
727
|
-
o = o -
|
|
741
|
+
const I = u.suspend - u.elapsed;
|
|
742
|
+
if (o - y > I)
|
|
743
|
+
o = o - y - I, t.add(I, "hour"), u.elapsed = u.suspend;
|
|
728
744
|
else {
|
|
729
|
-
const
|
|
730
|
-
u.elapsed +=
|
|
745
|
+
const g = o - y;
|
|
746
|
+
u.elapsed += g, t.add(g, "hour"), o = 0;
|
|
731
747
|
}
|
|
732
|
-
if (
|
|
733
|
-
return u.distanceFromPrevious = f, { etd: t, from:
|
|
748
|
+
if (D == null || D.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${o} hours need to go...`, r.requestId, u), o === 0)
|
|
749
|
+
return u.distanceFromPrevious = f, { etd: t, from: v || u, to: u, next: a.filter((g) => g), wps: p, days: M };
|
|
734
750
|
}
|
|
735
|
-
u = await
|
|
736
|
-
const h =
|
|
737
|
-
let
|
|
738
|
-
if (
|
|
739
|
-
if (
|
|
740
|
-
`[%s] go to %j from %j with ${h}nm, and cost ${
|
|
741
|
-
|
|
751
|
+
u = await E.speedLoseAt(s, u, t, e, 0, d, r), v = v || u, u.important && p.push(u), t.isSameOrAfter(i) && (M.push(u), i.add(24, "hour"));
|
|
752
|
+
const h = O.calculateDistance(u, c, !c.gcToPrevious);
|
|
753
|
+
let w = Math.ceil(h / v.speed * 1e4) / 1e4;
|
|
754
|
+
if (y + w < o) {
|
|
755
|
+
if (y += w, t.add(w, "hour"), delete a[Y], D == null || D.info(
|
|
756
|
+
`[%s] go to %j from %j with ${h}nm, and cost ${w} hours`,
|
|
757
|
+
r.requestId,
|
|
742
758
|
{ lat: c.lat, lng: c.lng },
|
|
743
|
-
{ lat:
|
|
744
|
-
), f += h, a.filter((
|
|
745
|
-
l = c, l.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), l.distanceFromPrevious = h, l.distanceFromStart = n + f,
|
|
759
|
+
{ lat: v.lat, lng: v.lng, etd: v.etd }
|
|
760
|
+
), f += h, a.filter((I) => I).length <= 1) {
|
|
761
|
+
l = c, l.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), l.distanceFromPrevious = h, l.distanceFromStart = n + f, p.push(l), delete a[Y + 1];
|
|
746
762
|
break;
|
|
747
763
|
}
|
|
748
764
|
} else {
|
|
749
|
-
|
|
750
|
-
const
|
|
751
|
-
l =
|
|
752
|
-
`[%s] go to %j from %j with ${
|
|
753
|
-
|
|
765
|
+
w = o - y, t.add(w, "hour");
|
|
766
|
+
const I = Z.roundPrecision(v.speed * w, 4);
|
|
767
|
+
l = O.calculateCoordinate(u, s.bearing, I, "nauticalmiles", !c.gcToPrevious), l.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[Y] = l, D == null || D.info(
|
|
768
|
+
`[%s] go to %j from %j with ${I}nm, and cost ${w} hours`,
|
|
769
|
+
r.requestId,
|
|
754
770
|
{ lat: l.lat, lng: l.lng },
|
|
755
771
|
{ lat: u.lat, lng: u.lng, etd: u.etd }
|
|
756
|
-
), f +=
|
|
772
|
+
), f += I, l.distanceFromPrevious = f, l.distanceFromStart = n + f;
|
|
757
773
|
break;
|
|
758
774
|
}
|
|
759
775
|
}
|
|
760
|
-
return { etd: t, from:
|
|
776
|
+
return { etd: t, from: v, to: l, next: a.filter((Y) => Y), wps: p, days: M };
|
|
761
777
|
}
|
|
762
778
|
/**
|
|
763
779
|
* 洋流影响因子
|
|
@@ -765,12 +781,12 @@ class H {
|
|
|
765
781
|
* @param current 洋流要素
|
|
766
782
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
767
783
|
*/
|
|
768
|
-
static currentFactor(s, t,
|
|
784
|
+
static currentFactor(s, t, i = 0) {
|
|
769
785
|
const o = (s - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
770
786
|
if (Math.abs(o) === Math.PI / 2)
|
|
771
787
|
return 0;
|
|
772
788
|
let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(o);
|
|
773
|
-
return
|
|
789
|
+
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
790
|
}
|
|
775
791
|
/**
|
|
776
792
|
* 风浪影响因子
|
|
@@ -778,16 +794,16 @@ class H {
|
|
|
778
794
|
* @param wwc 气象要素
|
|
779
795
|
*/
|
|
780
796
|
static weatherFactor(s, t) {
|
|
781
|
-
var
|
|
782
|
-
|
|
783
|
-
const
|
|
784
|
-
let a = Math.abs(s.bearing % 360 - (((
|
|
797
|
+
var M, y, f, l, v;
|
|
798
|
+
D == null || D.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
799
|
+
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);
|
|
800
|
+
let a = Math.abs(s.bearing % 360 - (((M = t == null ? void 0 : t.wind) == null ? void 0 : M.degree) % 360 || 0));
|
|
785
801
|
a = a > 180 ? 360 - a : a;
|
|
786
|
-
const e =
|
|
787
|
-
let
|
|
788
|
-
|
|
789
|
-
const
|
|
790
|
-
return
|
|
802
|
+
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, (f = t == null ? void 0 : t.wind) == null ? void 0 : f.scale);
|
|
803
|
+
let r = e * n * d / 100 * s.speed;
|
|
804
|
+
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1;
|
|
805
|
+
const p = E.waveHeightFactor(((v = (l = t == null ? void 0 : t.wave) == null ? void 0 : l.sig) == null ? void 0 : v.height) ?? 1);
|
|
806
|
+
return r = r * 0.24 + p * 0.76, D == null || D.debug("weather factor = %s", r), Math.round(r * 100) / 100;
|
|
791
807
|
}
|
|
792
808
|
/**
|
|
793
809
|
* 全程失速分析(走完航程)
|
|
@@ -800,14 +816,14 @@ class H {
|
|
|
800
816
|
* @param stepHrs 样本步长, 0表示动态计算(6 or 3 hrs)
|
|
801
817
|
* @param useRouteParam
|
|
802
818
|
*/
|
|
803
|
-
static async analyseInstant(s, t,
|
|
804
|
-
var
|
|
805
|
-
const
|
|
806
|
-
s.lng =
|
|
807
|
-
const { route:
|
|
808
|
-
if (((
|
|
819
|
+
static async analyseInstant(s, t, i, o, n, a = "", e = 0, d = !1, r = {}) {
|
|
820
|
+
var q, P, _, G, U;
|
|
821
|
+
const p = b().valueOf();
|
|
822
|
+
s.lng = Z.convertToStdLng(s.lng);
|
|
823
|
+
const { route: M, waypoints: y } = n.points, f = O.calculateSubRoute(s, M);
|
|
824
|
+
if (((q = f[0]) == null ? void 0 : q.length) <= 1)
|
|
809
825
|
return;
|
|
810
|
-
const { v0: l, label:
|
|
826
|
+
const { v0: l, label: v } = s.sog ? {
|
|
811
827
|
v0: s.sog,
|
|
812
828
|
label: "Other"
|
|
813
829
|
/* Instruct */
|
|
@@ -815,40 +831,40 @@ class H {
|
|
|
815
831
|
v0: o.speed,
|
|
816
832
|
label: "CP"
|
|
817
833
|
/* Cp */
|
|
818
|
-
},
|
|
834
|
+
}, Y = E.assembleProperties(i, o.loadCondition, l, 0), u = y.length ? O.calculateSubWaypoints(s, y) : [], c = {
|
|
819
835
|
from: { ...s },
|
|
820
836
|
route: f,
|
|
821
837
|
waypoints: u,
|
|
822
838
|
v0: l,
|
|
823
|
-
label:
|
|
839
|
+
label: v
|
|
824
840
|
}, h = {
|
|
825
841
|
hours: [],
|
|
826
842
|
days: [],
|
|
827
843
|
wps: []
|
|
828
844
|
};
|
|
829
|
-
e || (
|
|
830
|
-
let
|
|
831
|
-
t =
|
|
832
|
-
const
|
|
833
|
-
for (;
|
|
834
|
-
const
|
|
835
|
-
(
|
|
845
|
+
e || (O.calculateRouteDistance(f) / o.speed <= 72 ? e = 3 : e = 6);
|
|
846
|
+
let w = O.simplifyRouteToCoordinates(f, u, 0), I = 0, g = 0, F = 0, x = 0;
|
|
847
|
+
t = b(t).utc();
|
|
848
|
+
const A = t.clone();
|
|
849
|
+
for (; w.length > 0; ) {
|
|
850
|
+
const H = e - t.hour() % e, W = Math.ceil(t.clone().add(H, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, N = await E.speedLoseInHoursStep(Y, t, A, W, I, w, a, d, r);
|
|
851
|
+
(P = N.from) != null && P.speed && (h.hours.push(N.from), h.wps.push(...N.wps), h.days.push(...N.days)), w = N == null ? void 0 : N.next, w.length || h.hours.push(N == null ? void 0 : N.to), I += ((_ = N == null ? void 0 : N.to) == null ? void 0 : _.distanceFromPrevious) ?? 0;
|
|
836
852
|
}
|
|
837
|
-
const
|
|
838
|
-
for (let
|
|
839
|
-
const
|
|
840
|
-
|
|
853
|
+
const T = h.hours;
|
|
854
|
+
for (let H = 0; H < T.length - 1; H++) {
|
|
855
|
+
const W = b(T[H + 1].eta).diff(T[H].etd, "hour", !0) || 1;
|
|
856
|
+
g += T[H].wxFactor * W, F += T[H].cFactor * W, x += W;
|
|
841
857
|
}
|
|
842
|
-
(
|
|
843
|
-
if (
|
|
844
|
-
const
|
|
845
|
-
|
|
858
|
+
(G = h.wps) == null || G.forEach((H, W) => {
|
|
859
|
+
if (W) {
|
|
860
|
+
const N = h.wps[W - 1], Q = H.distanceFromStart - N.distanceFromStart, J = b(H.eta).diff(b(N.etd), "h", !0);
|
|
861
|
+
J < 1 ? H.avgSpd = N.speed : H.avgSpd = Math.round(Q / J * 100) / 100;
|
|
846
862
|
}
|
|
847
863
|
}), c.sample = h;
|
|
848
|
-
const
|
|
849
|
-
c.distance = Math.round(
|
|
850
|
-
const
|
|
851
|
-
return
|
|
864
|
+
const S = h.hours.at(-1);
|
|
865
|
+
c.distance = Math.round(S.distanceFromStart * 1e4) / 1e4, c.eta = b(S.eta).toDate(), c.wxFactor = Math.round(g / x * 1e4) / 1e4, c.cFactor = Math.round(F / x * 1e4) / 1e4, c.avgSpeed = Math.round(S.distanceFromStart / x * 1e4) / 1e4, c.totalHrs = Math.round(x * 1e4) / 1e4, c.totalFoCons = Math.round((o == null ? void 0 : o.fo) / 24 * c.totalHrs * 1e3) / 1e3, c.totalDgoCons = Math.round((o == null ? void 0 : o.dgo) / 24 * c.totalHrs * 1e3) / 1e3;
|
|
866
|
+
const V = b().valueOf() - p, j = ((U = h == null ? void 0 : h.hours) == null ? void 0 : U.length) || 1;
|
|
867
|
+
return D == null || D.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", r == null ? void 0 : r.requestId, V, j, Math.round(V / j * 1e3) / 1e3), c;
|
|
852
868
|
}
|
|
853
869
|
/**
|
|
854
870
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -861,60 +877,60 @@ class H {
|
|
|
861
877
|
* @param source 气象数据源,GFS or CMEMES, 默认CMEMS
|
|
862
878
|
* @param stepHrs
|
|
863
879
|
*/
|
|
864
|
-
static async analyseInstantWithThreshed(s, t,
|
|
865
|
-
var
|
|
866
|
-
s.lng =
|
|
867
|
-
const
|
|
868
|
-
if (((
|
|
880
|
+
static async analyseInstantWithThreshed(s, t, i, o, n, a, e = "", d = 3, r = !1, p = {}) {
|
|
881
|
+
var F, x, A;
|
|
882
|
+
s.lng = Z.convertToStdLng(s.lng);
|
|
883
|
+
const M = E.assembleProperties(o, n.loadCondition, n.speed, 0), y = O.calculateSubRoute(s, a);
|
|
884
|
+
if (((F = y[0]) == null ? void 0 : F.length) <= 1)
|
|
869
885
|
return;
|
|
870
|
-
let f =
|
|
871
|
-
f.forEach((
|
|
872
|
-
let l = 0,
|
|
886
|
+
let f = O.simplifyRouteToCoordinates(y, [], 0);
|
|
887
|
+
f.forEach((T) => T.important = !0);
|
|
888
|
+
let l = 0, v = 0, Y = 0, u = 0, c;
|
|
873
889
|
const h = {
|
|
874
890
|
hours: [],
|
|
875
891
|
wps: [],
|
|
876
892
|
days: []
|
|
877
893
|
};
|
|
878
|
-
for (t =
|
|
879
|
-
const
|
|
880
|
-
let
|
|
881
|
-
if (
|
|
882
|
-
c = await
|
|
894
|
+
for (t = b(t).utc(); f.length > 0; ) {
|
|
895
|
+
const T = d - t.hour() % d;
|
|
896
|
+
let S = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
897
|
+
if (S = t.clone().add(S, "h").isAfter(i) ? i.diff(t, "h", !0) * 1e4 / 1e4 : S, S)
|
|
898
|
+
c = await E.speedLoseInHoursStep(M, t, i.clone(), S, l, f, e, r, p), (x = c.from) != null && x.speed && (h.hours.push(c.from), c != null && c.wps && h.wps.push(...c.wps), h.days.push(...c.days)), f = c == null ? void 0 : c.next, f.length || (h.hours.push(c == null ? void 0 : c.to), c != null && c.wps && h.wps.push(...c.wps), h.days.push(c == null ? void 0 : c.to)), l += ((A = c == null ? void 0 : c.to) == null ? void 0 : A.distanceFromPrevious) ?? 0;
|
|
883
899
|
else {
|
|
884
900
|
c && (h.hours.push(c.to), c != null && c.wps && h.wps.push(...c.wps), h.days.push(c.to));
|
|
885
901
|
break;
|
|
886
902
|
}
|
|
887
903
|
}
|
|
888
|
-
const
|
|
889
|
-
for (let
|
|
890
|
-
const
|
|
891
|
-
|
|
904
|
+
const w = h.hours;
|
|
905
|
+
for (let T = 0; T < w.length - 1; T++) {
|
|
906
|
+
const S = b(w[T + 1].eta).diff(w[T].etd, "hour", !0);
|
|
907
|
+
v += w[T].wxFactor * S, Y += w[T].cFactor * S, u += S;
|
|
892
908
|
}
|
|
893
|
-
const
|
|
909
|
+
const I = h.hours.at(-1);
|
|
894
910
|
return {
|
|
895
911
|
sample: h,
|
|
896
|
-
distance: Math.round(((
|
|
897
|
-
eta:
|
|
898
|
-
wxFactor: Math.round(
|
|
899
|
-
cFactor: Math.round(
|
|
900
|
-
avgSpeed: Math.round(((
|
|
912
|
+
distance: Math.round(((I == null ? void 0 : I.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
913
|
+
eta: b(I == null ? void 0 : I.eta).utc().format(),
|
|
914
|
+
wxFactor: Math.round(v / u * 1e4) / 1e4,
|
|
915
|
+
cFactor: Math.round(Y / u * 1e4) / 1e4,
|
|
916
|
+
avgSpeed: Math.round(((I == null ? void 0 : I.distanceFromStart) || 0) / u * 1e4) / 1e4,
|
|
901
917
|
totalHrs: Math.round(u * 1e4) / 1e4,
|
|
902
|
-
to:
|
|
903
|
-
route:
|
|
918
|
+
to: I,
|
|
919
|
+
route: O.generateRouteAccordingToWaypoints(f)
|
|
904
920
|
};
|
|
905
921
|
}
|
|
906
922
|
}
|
|
907
923
|
export {
|
|
908
|
-
|
|
924
|
+
K as AISImpl,
|
|
909
925
|
st as AlertHelper,
|
|
910
926
|
et as AlertLevel,
|
|
911
927
|
ft as HifleetImpl,
|
|
912
928
|
ot as LoadCondition,
|
|
913
|
-
|
|
929
|
+
pt as MyShipImpl,
|
|
914
930
|
lt as MyVesselImpl,
|
|
915
931
|
mt as ShipxyImpl,
|
|
916
|
-
|
|
932
|
+
E as SpeedHelper,
|
|
917
933
|
nt as SpeedLabel,
|
|
918
934
|
at as VesselTag,
|
|
919
|
-
|
|
935
|
+
Mt as alertHelper
|
|
920
936
|
};
|