@idm-plugin/vessel 3.4.5 → 3.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ais/src/index.d.ts +11 -2
- package/dist/index.js +584 -503
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
var mt = Object.defineProperty;
|
|
2
|
-
var ft = (
|
|
3
|
-
var
|
|
2
|
+
var ft = (x, s, t) => s in x ? mt(x, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : x[s] = t;
|
|
3
|
+
var K = (x, s, t) => (ft(x, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
4
|
import B from "got";
|
|
5
5
|
import ut from "@log4js-node/log4js-api";
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
6
|
+
import v from "moment";
|
|
7
|
+
import { LaneHelper as V, LngLatHelper as z } from "@idm-plugin/geo2";
|
|
8
8
|
import { MeteoHelper2 as yt } from "@idm-plugin/meteo2";
|
|
9
9
|
import { Meteo2Assist as dt } from "@idm-plugin/meteo";
|
|
10
|
-
let
|
|
10
|
+
let M;
|
|
11
11
|
try {
|
|
12
|
-
|
|
12
|
+
M = ut.getLogger("vessel");
|
|
13
13
|
} catch {
|
|
14
14
|
} finally {
|
|
15
15
|
}
|
|
@@ -54,12 +54,12 @@ class nt {
|
|
|
54
54
|
return { labelCn: t, labelEn: a };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class Ft extends nt {
|
|
58
58
|
constructor(t, a) {
|
|
59
59
|
super();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
K(this, "clientId");
|
|
61
|
+
K(this, "clientSecret");
|
|
62
|
+
K(this, "token");
|
|
63
63
|
this.clientId = t, this.clientSecret = a;
|
|
64
64
|
}
|
|
65
65
|
async authToken(t = {}) {
|
|
@@ -70,18 +70,18 @@ class Et extends nt {
|
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
72
|
}, n = await B.post(a, i).json();
|
|
73
|
-
|
|
73
|
+
M == null || M.info("[%s] fetch access token from: %s - %j", t.requestId, a, n), n.error || (this.token = {
|
|
74
74
|
accessToken: n.access_token,
|
|
75
75
|
tokenType: n.token_type,
|
|
76
76
|
expiresIn: n.expires_in,
|
|
77
77
|
scope: n.scope,
|
|
78
78
|
jti: n.jti,
|
|
79
|
-
issuedAt:
|
|
79
|
+
issuedAt: v().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async checkToken(t = {}) {
|
|
83
83
|
var a;
|
|
84
|
-
return (!this.token ||
|
|
84
|
+
return (!this.token || v().diff(v(this.token.issuedAt), "seconds") > (((a = this.token) == null ? void 0 : a.expiresIn) || 0) - 300) && await this.authToken(t), this.token;
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* 模糊查询
|
|
@@ -100,18 +100,18 @@ class Et extends nt {
|
|
|
100
100
|
recordNum: a.ps || 10
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
|
|
103
|
+
M == null || M.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, i, n);
|
|
104
104
|
const o = await B.post(i, n).json();
|
|
105
|
-
return o.status !== 200 ? (
|
|
106
|
-
mmsi:
|
|
107
|
-
name:
|
|
108
|
-
nameCn:
|
|
109
|
-
imo: Number.isNaN(
|
|
110
|
-
callSign:
|
|
111
|
-
type:
|
|
112
|
-
flagName:
|
|
105
|
+
return o.status !== 200 ? (M == null || M.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), []) : (o.data || []).map((l) => ({
|
|
106
|
+
mmsi: l.mmsi,
|
|
107
|
+
name: l.nameEn,
|
|
108
|
+
nameCn: l.nameCn,
|
|
109
|
+
imo: Number.isNaN(l.imo) ? null : Number(l.imo),
|
|
110
|
+
callSign: l.callsign,
|
|
111
|
+
type: l.vesselTypeNameEn,
|
|
112
|
+
flagName: l.flagCtry,
|
|
113
113
|
vendor: "myvessel",
|
|
114
|
-
raw:
|
|
114
|
+
raw: l
|
|
115
115
|
}));
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
@@ -120,43 +120,43 @@ class Et extends nt {
|
|
|
120
120
|
* @param options
|
|
121
121
|
*/
|
|
122
122
|
async search(t, a = {}) {
|
|
123
|
-
var
|
|
123
|
+
var u, l;
|
|
124
124
|
await this.checkToken(a);
|
|
125
125
|
const i = /^\d{7}$/.test(t.toString()), n = i ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", o = i ? { imo: t } : { mmsi: t }, e = {
|
|
126
126
|
headers: {
|
|
127
|
-
Authorization: `${(
|
|
127
|
+
Authorization: `${(u = this.token) == null ? void 0 : u.tokenType} ${(l = this.token) == null ? void 0 : l.accessToken}`
|
|
128
128
|
},
|
|
129
129
|
searchParams: o
|
|
130
130
|
};
|
|
131
|
-
|
|
131
|
+
M == null || M.info("[%s] fetch vessel from: %s - %j", a.requestId, n, e);
|
|
132
132
|
const r = await B.get(n, e).json();
|
|
133
133
|
if (r.status !== 200)
|
|
134
|
-
return
|
|
134
|
+
return M == null || M.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
|
|
135
135
|
{
|
|
136
|
-
const
|
|
137
|
-
if (
|
|
136
|
+
const d = r.data;
|
|
137
|
+
if (d)
|
|
138
138
|
return {
|
|
139
|
-
mmsi:
|
|
140
|
-
imo: Number.isNaN(
|
|
141
|
-
callSign:
|
|
142
|
-
name:
|
|
143
|
-
nameCn:
|
|
144
|
-
type:
|
|
145
|
-
flagName:
|
|
146
|
-
clasz:
|
|
147
|
-
dateOfBuild:
|
|
148
|
-
deadweight:
|
|
149
|
-
grossTonnage:
|
|
150
|
-
netTonnage:
|
|
151
|
-
teu:
|
|
152
|
-
length:
|
|
153
|
-
breadth:
|
|
154
|
-
height:
|
|
155
|
-
draught:
|
|
156
|
-
speed:
|
|
157
|
-
passengerCapacity:
|
|
139
|
+
mmsi: d.mmsi,
|
|
140
|
+
imo: Number.isNaN(d.imo) ? null : Number(d.imo),
|
|
141
|
+
callSign: d.callsign,
|
|
142
|
+
name: d.nameEn,
|
|
143
|
+
nameCn: d.nameCn,
|
|
144
|
+
type: d.vesselTypeNameEn,
|
|
145
|
+
flagName: d.flagCtry,
|
|
146
|
+
clasz: d.classSociety,
|
|
147
|
+
dateOfBuild: d.buildYearMonth,
|
|
148
|
+
deadweight: d.dwt,
|
|
149
|
+
grossTonnage: d.grt,
|
|
150
|
+
netTonnage: d.net,
|
|
151
|
+
teu: d.teu,
|
|
152
|
+
length: d.length,
|
|
153
|
+
breadth: d.width,
|
|
154
|
+
height: d.height,
|
|
155
|
+
draught: d.draught,
|
|
156
|
+
speed: d.speed,
|
|
157
|
+
passengerCapacity: d.passengercapacity,
|
|
158
158
|
vendor: "myvessel",
|
|
159
|
-
raw:
|
|
159
|
+
raw: d
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
162
|
return {};
|
|
@@ -172,28 +172,28 @@ class Et extends nt {
|
|
|
172
172
|
mmsiList: typeof t == "number" ? [t] : t
|
|
173
173
|
}
|
|
174
174
|
};
|
|
175
|
-
|
|
175
|
+
M == null || M.info("[%s] fetch vessel archive from: %s - %j", a.requestId, i, n);
|
|
176
176
|
const o = await B.post(i, n).json();
|
|
177
|
-
return o.status !== 200 ? (
|
|
177
|
+
return o.status !== 200 ? (M == null || M.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), {}) : o.data;
|
|
178
178
|
}
|
|
179
179
|
async realTimePosition(t, a = {}) {
|
|
180
|
-
var r,
|
|
180
|
+
var r, u;
|
|
181
181
|
await this.checkToken(a);
|
|
182
182
|
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
|
|
183
183
|
headers: {
|
|
184
|
-
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(
|
|
184
|
+
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(u = this.token) == null ? void 0 : u.accessToken}`
|
|
185
185
|
},
|
|
186
186
|
searchParams: { mmsi: t }
|
|
187
187
|
};
|
|
188
|
-
|
|
188
|
+
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
|
|
189
189
|
const o = await B.get(i, n).json();
|
|
190
190
|
if (o.code)
|
|
191
|
-
return
|
|
191
|
+
return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), o;
|
|
192
192
|
const e = o.data;
|
|
193
|
-
for (const
|
|
194
|
-
!isNaN(e[
|
|
193
|
+
for (const l in e)
|
|
194
|
+
!isNaN(e[l]) && Number(e[l]) !== 1 / 0 && (e[l] = Number(e[l]));
|
|
195
195
|
if (e) {
|
|
196
|
-
const
|
|
196
|
+
const l = v(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
197
197
|
return {
|
|
198
198
|
mmsi: e.mmsi,
|
|
199
199
|
name: e.vesselName || e.aisVesselName,
|
|
@@ -208,9 +208,9 @@ class Et extends nt {
|
|
|
208
208
|
cog: e.cog,
|
|
209
209
|
hdg: e.hdg,
|
|
210
210
|
rot: e.rot,
|
|
211
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ?
|
|
211
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? v.utc(e.eta).format() : void 0,
|
|
212
212
|
destination: e.dest,
|
|
213
|
-
positionTime:
|
|
213
|
+
positionTime: l.unix(),
|
|
214
214
|
status: e.status,
|
|
215
215
|
labelCn: e.statusNameCn,
|
|
216
216
|
labelEn: e.statusNameEn,
|
|
@@ -223,17 +223,26 @@ class Et extends nt {
|
|
|
223
223
|
net: e.net,
|
|
224
224
|
method: "position",
|
|
225
225
|
vendor: "myVessel",
|
|
226
|
-
utc:
|
|
226
|
+
utc: l.utc().format()
|
|
227
227
|
};
|
|
228
228
|
} else
|
|
229
229
|
return {};
|
|
230
230
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
/**
|
|
232
|
+
* @param from 始发点坐标 { lng, lat }
|
|
233
|
+
* @param to 目的点坐标 { lng, lat }
|
|
234
|
+
* @param crossMonths 规划月份 [1,...,12]
|
|
235
|
+
* @param excludeNodes 排除关键节点, [node.code]
|
|
236
|
+
* @param excludeSeas 排除水域, [sea.code]
|
|
237
|
+
* @param options { requiretId: '请求ID', useAIModel: '启用AI算法', withECA: '是否计算低硫区航行距离', withSpecial: '是否计算穿越的特战区列表和海盗区列表', draught: '最大吃水' }
|
|
238
|
+
*/
|
|
239
|
+
async calculateRoute(t, a, i, n, o, e = {}) {
|
|
240
|
+
var y, w, g;
|
|
241
|
+
const r = v();
|
|
242
|
+
await this.checkToken(e);
|
|
243
|
+
const u = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", l = {
|
|
235
244
|
headers: {
|
|
236
|
-
Authorization: `${(
|
|
245
|
+
Authorization: `${(y = this.token) == null ? void 0 : y.tokenType} ${(w = this.token) == null ? void 0 : w.accessToken}`
|
|
237
246
|
},
|
|
238
247
|
json: {
|
|
239
248
|
startPoint: {
|
|
@@ -244,27 +253,99 @@ class Et extends nt {
|
|
|
244
253
|
lon: a.lng,
|
|
245
254
|
lat: a.lat
|
|
246
255
|
},
|
|
247
|
-
maxDraught:
|
|
248
|
-
useAIModel:
|
|
249
|
-
withECA:
|
|
256
|
+
maxDraught: e.draught || 10,
|
|
257
|
+
useAIModel: e.useAIModel || !1,
|
|
258
|
+
withECA: e.withECA || !1,
|
|
259
|
+
withSpecialRegion: e.withSpecial || !1
|
|
250
260
|
}
|
|
251
261
|
};
|
|
252
|
-
|
|
253
|
-
const
|
|
254
|
-
|
|
262
|
+
i != null && i.length && (l.json.crossMonthList = i), n != null && n.length && (l.json.excludeNodes = n), o != null && o.length && (l.json.excludeSeaAreas = o), M == null || M.info("[%s] fetch route from: %s - %j", e.requestId, u, l);
|
|
263
|
+
const d = await B.post(u, l).json();
|
|
264
|
+
if (d.status !== 200)
|
|
265
|
+
return M == null || M.warn("[%s] fetch route failed: %j", e.requestId, { message: d.message, status: d.status, code: d.code }), {};
|
|
266
|
+
{
|
|
267
|
+
const k = {
|
|
268
|
+
status: "Success",
|
|
269
|
+
nodes: [],
|
|
270
|
+
seas: [],
|
|
271
|
+
regions: [],
|
|
272
|
+
waypoints: [],
|
|
273
|
+
route: [],
|
|
274
|
+
distance: 0,
|
|
275
|
+
memo: ""
|
|
276
|
+
}, { nodes: E, seas: b, tracks: p, specialRegions: f } = d.data;
|
|
277
|
+
k.nodes = E == null ? void 0 : E.map((c) => ({
|
|
278
|
+
code: c.nodeCode,
|
|
279
|
+
nameEn: c.nameEn,
|
|
280
|
+
nameCn: c.nameCn,
|
|
281
|
+
// 中心
|
|
282
|
+
center: {
|
|
283
|
+
lat: Math.round(c.lat * 1e6) / 1e6,
|
|
284
|
+
lng: Math.round(c.lon * 1e6) / 1e6
|
|
285
|
+
},
|
|
286
|
+
// 起点
|
|
287
|
+
start: {
|
|
288
|
+
lat: Math.round(c.startLat * 1e6) / 1e6,
|
|
289
|
+
lng: Math.round(c.startLon * 1e6) / 1e6
|
|
290
|
+
},
|
|
291
|
+
// 终点
|
|
292
|
+
end: {
|
|
293
|
+
lat: Math.round(c.endLat * 1e6) / 1e6,
|
|
294
|
+
lng: Math.round(c.endLat * 1e6) / 1e6
|
|
295
|
+
},
|
|
296
|
+
// 是否为不可避开关键节点
|
|
297
|
+
isKey: c.isKeyNode,
|
|
298
|
+
// 重要枢纽节点
|
|
299
|
+
isHub: c.isHubNode
|
|
300
|
+
})), k.seas = b == null ? void 0 : b.map((c) => ({
|
|
301
|
+
code: c.mrgidSea,
|
|
302
|
+
nameEn: c.nameEn,
|
|
303
|
+
nameCn: c.nameCn,
|
|
304
|
+
center: {
|
|
305
|
+
lat: Math.round(c.centerLat * 1e6) / 1e6,
|
|
306
|
+
lng: Math.round(c.centerLon * 1e6) / 1e6
|
|
307
|
+
},
|
|
308
|
+
min: {
|
|
309
|
+
lat: Math.round(c.minLat * 1e6) / 1e6,
|
|
310
|
+
lng: Math.round(c.minLon * 1e6) / 1e6
|
|
311
|
+
},
|
|
312
|
+
max: {
|
|
313
|
+
lat: Math.round(c.maxLat * 1e6) / 1e6,
|
|
314
|
+
lng: Math.round(c.maxLon * 1e6) / 1e6
|
|
315
|
+
},
|
|
316
|
+
level: c.mapLevel
|
|
317
|
+
})), f == null || f.map((c) => {
|
|
318
|
+
c.regionLength && k.regions.push({
|
|
319
|
+
type: c.regionType,
|
|
320
|
+
distance: c.regionLength,
|
|
321
|
+
rows: c.regions.map((I) => ({
|
|
322
|
+
code: I.regionCode,
|
|
323
|
+
nameCn: I.nameCn,
|
|
324
|
+
nameEn: I.nameEn,
|
|
325
|
+
type: I.regionType,
|
|
326
|
+
distance: I.length
|
|
327
|
+
}))
|
|
328
|
+
});
|
|
329
|
+
}), k.waypoints = p == null ? void 0 : p.map((c) => ({
|
|
330
|
+
lat: Math.round(c.lat * 1e5) / 1e5,
|
|
331
|
+
lng: Math.round(c.lon * 1e5) / 1e5
|
|
332
|
+
})), (g = k.waypoints) != null && g.length && (k.waypoints = V.simplifyCoordinates(k.waypoints), k.route = V.divideAccordingToLng(k.waypoints), k.distance = V.calculateRouteDistance(k.route));
|
|
333
|
+
const m = v().diff(r, "second");
|
|
334
|
+
return k.memo = `time cost: ${m}s`, M.info("[%s] calculate route cost: %d seconds", e.requestId, m), k;
|
|
335
|
+
}
|
|
255
336
|
}
|
|
256
337
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
257
338
|
await this.checkToken(e);
|
|
258
|
-
const r = await this.realTimePosition(t, e),
|
|
259
|
-
for (;
|
|
260
|
-
await this.trajectoryIn30Day(t,
|
|
261
|
-
return await this.trajectoryIn30Day(t,
|
|
339
|
+
const r = await this.realTimePosition(t, e), u = v(a), l = v(i), d = [];
|
|
340
|
+
for (; l.diff(u, "day", !0) > 30; )
|
|
341
|
+
await this.trajectoryIn30Day(t, u, u.clone().add(30, "day"), r, n, d, e), u.add(30, "day");
|
|
342
|
+
return await this.trajectoryIn30Day(t, u, l, r, n, d, e), d;
|
|
262
343
|
}
|
|
263
344
|
async trajectoryIn30Day(t, a, i, n, o, e, r = {}) {
|
|
264
|
-
var
|
|
265
|
-
const
|
|
345
|
+
var g, k, E, b, p;
|
|
346
|
+
const u = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", l = {
|
|
266
347
|
headers: {
|
|
267
|
-
Authorization: `${(
|
|
348
|
+
Authorization: `${(g = this.token) == null ? void 0 : g.tokenType} ${(k = this.token) == null ? void 0 : k.accessToken}`
|
|
268
349
|
},
|
|
269
350
|
json: {
|
|
270
351
|
mmsi: t,
|
|
@@ -272,16 +353,16 @@ class Et extends nt {
|
|
|
272
353
|
endTime: i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
273
354
|
}
|
|
274
355
|
};
|
|
275
|
-
|
|
276
|
-
const
|
|
277
|
-
if (
|
|
278
|
-
return
|
|
279
|
-
let
|
|
280
|
-
const w =
|
|
281
|
-
return (
|
|
356
|
+
M == null || M.info("[%s] fetch trajectory from: %s - %j", r.requestId, u, l);
|
|
357
|
+
const d = await B.post(u, l).json();
|
|
358
|
+
if (d.code)
|
|
359
|
+
return M == null || M.warn("[%s] fetch trajectory failed: %j", r.requestId, u, { message: d.message, status: d.status, code: d.code }), d;
|
|
360
|
+
let y = -1;
|
|
361
|
+
const w = v(`${(b = (E = d.data) == null ? void 0 : E[0]) == null ? void 0 : b.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
362
|
+
return (p = d.data) == null || p.forEach((f) => {
|
|
282
363
|
for (const q in f)
|
|
283
364
|
!isNaN(f[q]) && Number(f[q]) !== 1 / 0 && (f[q] = Number(f[q]));
|
|
284
|
-
const
|
|
365
|
+
const h = v(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), m = f.status, { labelCn: c, labelEn: I } = this.parseStatus(m), C = {
|
|
285
366
|
mmsi: f.mmsi,
|
|
286
367
|
imo: n == null ? void 0 : n.imo,
|
|
287
368
|
lat: f.lat,
|
|
@@ -290,24 +371,24 @@ class Et extends nt {
|
|
|
290
371
|
cog: f.cog,
|
|
291
372
|
hdg: f.hdg,
|
|
292
373
|
draught: f.draught,
|
|
293
|
-
status:
|
|
294
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta) ?
|
|
374
|
+
status: m,
|
|
375
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta) ? v(`${f.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
|
|
295
376
|
destination: f.dest,
|
|
296
|
-
positionTime:
|
|
297
|
-
labelCn:
|
|
377
|
+
positionTime: h.unix(),
|
|
378
|
+
labelCn: c,
|
|
298
379
|
labelEn: I,
|
|
299
380
|
method: "trajectory",
|
|
300
381
|
vendor: "myVessel",
|
|
301
|
-
utc:
|
|
302
|
-
},
|
|
303
|
-
|
|
382
|
+
utc: h.utc().format()
|
|
383
|
+
}, F = Math.floor(h.diff(w, "minute", !0) / (o || 1));
|
|
384
|
+
F !== y && (y = F, e.push(C));
|
|
304
385
|
}), e;
|
|
305
386
|
}
|
|
306
387
|
}
|
|
307
|
-
class
|
|
388
|
+
class Nt extends nt {
|
|
308
389
|
constructor(t) {
|
|
309
390
|
super();
|
|
310
|
-
|
|
391
|
+
K(this, "token");
|
|
311
392
|
this.token = t;
|
|
312
393
|
}
|
|
313
394
|
async realTimePosition(t, a = {}) {
|
|
@@ -317,14 +398,14 @@ class xt extends nt {
|
|
|
317
398
|
usertoken: this.token
|
|
318
399
|
}
|
|
319
400
|
}, o = await B.post(i, n).json();
|
|
320
|
-
|
|
401
|
+
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
|
|
321
402
|
const e = o == null ? void 0 : o.list;
|
|
322
403
|
if (!e)
|
|
323
|
-
return
|
|
404
|
+
return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, i, o), o;
|
|
324
405
|
for (const w in e)
|
|
325
406
|
!isNaN(e[w]) && Number(e[w]) !== 1 / 0 && (e[w] = Number(e[w]));
|
|
326
407
|
e.status = e.sp > 3 ? 0 : 1;
|
|
327
|
-
const r = e.status, { labelCn:
|
|
408
|
+
const r = e.status, { labelCn: u, labelEn: l } = this.parseStatus(r), d = v(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
328
409
|
return {
|
|
329
410
|
mmsi: e.m,
|
|
330
411
|
name: e.n,
|
|
@@ -339,17 +420,17 @@ class xt extends nt {
|
|
|
339
420
|
cog: e.co,
|
|
340
421
|
hdg: e.h,
|
|
341
422
|
rot: isNaN(e.rot) ? 0 : e.rot,
|
|
342
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ?
|
|
423
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? v.utc(e.eta).format() : void 0,
|
|
343
424
|
destination: e.destination,
|
|
344
425
|
vesselType: e.type,
|
|
345
426
|
dwt: e.dwt,
|
|
346
427
|
build: e.buildyear,
|
|
347
428
|
flag: e.fn,
|
|
348
|
-
positionTime:
|
|
349
|
-
utc:
|
|
429
|
+
positionTime: d.unix(),
|
|
430
|
+
utc: d.utc().format(),
|
|
350
431
|
status: r,
|
|
351
|
-
labelCn:
|
|
352
|
-
labelEn:
|
|
432
|
+
labelCn: u,
|
|
433
|
+
labelEn: l,
|
|
353
434
|
method: "position",
|
|
354
435
|
vendor: "hifleet"
|
|
355
436
|
};
|
|
@@ -367,7 +448,7 @@ class xt extends nt {
|
|
|
367
448
|
}
|
|
368
449
|
};
|
|
369
450
|
let o = await B.post(i, n).json();
|
|
370
|
-
|
|
451
|
+
M == null || M.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]);
|
|
371
452
|
for (const r in o)
|
|
372
453
|
!isNaN(o[r]) && Number(o[r]) !== 1 / 0 && (o[r] = Number(o[r]));
|
|
373
454
|
const e = {
|
|
@@ -380,7 +461,7 @@ class xt extends nt {
|
|
|
380
461
|
draught: o.dr,
|
|
381
462
|
type: o.t
|
|
382
463
|
};
|
|
383
|
-
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(),
|
|
464
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(), M == null || M.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]), o && (e.deadweight = Number(o.dwt)), e;
|
|
384
465
|
}
|
|
385
466
|
async suggest(t, a = {}) {
|
|
386
467
|
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
|
|
@@ -393,7 +474,7 @@ class xt extends nt {
|
|
|
393
474
|
Host: "www.hifleet.com"
|
|
394
475
|
}
|
|
395
476
|
}, o = await B.post(i, n).json();
|
|
396
|
-
|
|
477
|
+
M == null || M.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, n);
|
|
397
478
|
const e = [];
|
|
398
479
|
for (const r of o)
|
|
399
480
|
e.push({
|
|
@@ -403,63 +484,63 @@ class xt extends nt {
|
|
|
403
484
|
imo: !r.imo || isNaN(r.imo) ? null : Number(r.imo),
|
|
404
485
|
score: r._score
|
|
405
486
|
});
|
|
406
|
-
return e.sort((r,
|
|
487
|
+
return e.sort((r, u) => u.score - r.score), e;
|
|
407
488
|
}
|
|
408
489
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
409
|
-
var f,
|
|
490
|
+
var f, h, m;
|
|
410
491
|
const r = await this.realTimePosition(t, e);
|
|
411
|
-
let
|
|
412
|
-
const
|
|
492
|
+
let u = v(a);
|
|
493
|
+
const l = v(i), d = v();
|
|
413
494
|
if (o) {
|
|
414
|
-
let
|
|
415
|
-
|
|
495
|
+
let c = l.diff(u, "d", !0);
|
|
496
|
+
c < 0 ? u = l.clone().subtract(40, "d") : c < 30 ? u.subtract(10, "d") : c < 60 ? u.subtract(5, "d") : u = l.clone().subtract(80, "d"), c = d.diff(l, "d", !0), l.add(c > 10 ? 240 : c * 24, "h");
|
|
416
497
|
}
|
|
417
|
-
const
|
|
498
|
+
const y = {
|
|
418
499
|
searchParams: {
|
|
419
|
-
endtime:
|
|
420
|
-
starttime:
|
|
500
|
+
endtime: l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
501
|
+
starttime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
421
502
|
mmsi: t,
|
|
422
503
|
usertoken: this.token
|
|
423
504
|
}
|
|
424
|
-
}, w = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",
|
|
425
|
-
|
|
426
|
-
let
|
|
427
|
-
|
|
428
|
-
const
|
|
429
|
-
let
|
|
430
|
-
const
|
|
431
|
-
for (const
|
|
432
|
-
for (const H in
|
|
433
|
-
!isNaN(
|
|
434
|
-
const I =
|
|
435
|
-
|
|
436
|
-
const { labelEn:
|
|
437
|
-
mmsi:
|
|
438
|
-
name:
|
|
505
|
+
}, w = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", g = await B.get(w, y).json();
|
|
506
|
+
M == null || M.info("[%s] fetch trajectory from: %s - %j", e.requestId, w, y);
|
|
507
|
+
let k;
|
|
508
|
+
g && (k = ((h = (f = g.ships) == null ? void 0 : f.offors) == null ? void 0 : h.ship) || [], k.length || M == null || M.warn("[%s] fetch trajectory failed: %j", e.requestId, g));
|
|
509
|
+
const E = [];
|
|
510
|
+
let b = -1;
|
|
511
|
+
const p = v(`${(m = k == null ? void 0 : k[0]) == null ? void 0 : m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
512
|
+
for (const c of k) {
|
|
513
|
+
for (const H in c)
|
|
514
|
+
!isNaN(c[H]) && Number(c[H]) !== 1 / 0 && (c[H] = Number(c[H]));
|
|
515
|
+
const I = v(`${c.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
516
|
+
c.status = c.sp > 4 ? 0 : 1;
|
|
517
|
+
const { labelEn: C, labelCn: F } = this.parseStatus(c.status), q = {
|
|
518
|
+
mmsi: c.m,
|
|
519
|
+
name: c.n,
|
|
439
520
|
imo: r == null ? void 0 : r.imo,
|
|
440
|
-
lat:
|
|
441
|
-
lng:
|
|
442
|
-
draught:
|
|
443
|
-
sog:
|
|
444
|
-
cog:
|
|
445
|
-
hdg:
|
|
521
|
+
lat: c.la,
|
|
522
|
+
lng: c.lo,
|
|
523
|
+
draught: c.draught,
|
|
524
|
+
sog: c.sp,
|
|
525
|
+
cog: c.co,
|
|
526
|
+
hdg: c.hdg,
|
|
446
527
|
positionTime: I.unix(),
|
|
447
528
|
utc: I.utc().format(),
|
|
448
|
-
status:
|
|
449
|
-
labelCn:
|
|
450
|
-
labelEn:
|
|
529
|
+
status: c.status,
|
|
530
|
+
labelCn: F,
|
|
531
|
+
labelEn: C,
|
|
451
532
|
method: "trajectory",
|
|
452
533
|
vendor: "hifleet"
|
|
453
|
-
}, D = Math.floor(I.diff(
|
|
454
|
-
D !==
|
|
534
|
+
}, D = Math.floor(I.diff(p, "minute", !0) / (n || 1));
|
|
535
|
+
D !== b && (b = D, E.push(q));
|
|
455
536
|
}
|
|
456
|
-
return
|
|
537
|
+
return E;
|
|
457
538
|
}
|
|
458
539
|
}
|
|
459
|
-
class
|
|
540
|
+
class xt extends nt {
|
|
460
541
|
constructor(t) {
|
|
461
542
|
super();
|
|
462
|
-
|
|
543
|
+
K(this, "token");
|
|
463
544
|
this.token = t;
|
|
464
545
|
}
|
|
465
546
|
async realTimePosition(t, a = {}) {
|
|
@@ -470,12 +551,12 @@ class Nt extends nt {
|
|
|
470
551
|
enc: 1
|
|
471
552
|
}
|
|
472
553
|
}, n = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(n, i).json();
|
|
473
|
-
if (
|
|
554
|
+
if (M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, i), (o == null ? void 0 : o.status) !== 0)
|
|
474
555
|
return o;
|
|
475
556
|
const e = o.data[0];
|
|
476
|
-
for (const
|
|
477
|
-
!isNaN(e[
|
|
478
|
-
const { labelCn: r, labelEn:
|
|
557
|
+
for (const y in e)
|
|
558
|
+
!isNaN(e[y]) && Number(e[y]) !== 1 / 0 && (e[y] = Number(e[y]));
|
|
559
|
+
const { labelCn: r, labelEn: u } = await this.parseStatus(e.navistat), l = v.unix(e.lasttime);
|
|
479
560
|
return {
|
|
480
561
|
mmsi: e.ShipID,
|
|
481
562
|
name: e.name,
|
|
@@ -491,52 +572,52 @@ class Nt extends nt {
|
|
|
491
572
|
hdg: Math.round(e.hdg / 100 * 100) / 100,
|
|
492
573
|
rot: Math.round(e.rot / 100 * 100) / 100,
|
|
493
574
|
positionTime: e.lasttime,
|
|
494
|
-
utc:
|
|
575
|
+
utc: l.utc().format(),
|
|
495
576
|
status: e.navistat,
|
|
496
|
-
labelEn:
|
|
577
|
+
labelEn: u,
|
|
497
578
|
labelCn: r,
|
|
498
579
|
method: "position",
|
|
499
580
|
vendor: "shipxy"
|
|
500
581
|
};
|
|
501
582
|
}
|
|
502
583
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
503
|
-
var
|
|
504
|
-
const r = await this.realTimePosition(t, e),
|
|
584
|
+
var p;
|
|
585
|
+
const r = await this.realTimePosition(t, e), u = v(a), l = v(i), d = "https://api.shipxy.com/apicall/GetShipTrack", y = {
|
|
505
586
|
searchParams: {
|
|
506
587
|
id: t,
|
|
507
588
|
k: this.token,
|
|
508
589
|
enc: 1,
|
|
509
590
|
cut: 0,
|
|
510
|
-
btm:
|
|
511
|
-
etm:
|
|
591
|
+
btm: u.unix(),
|
|
592
|
+
etm: l.unix()
|
|
512
593
|
}
|
|
513
|
-
}, w = await B.get(
|
|
514
|
-
if (
|
|
594
|
+
}, w = await B.get(d, y).json();
|
|
595
|
+
if (M == null || M.info("[%s] fetch trajectory from: %s - %j", e.requestId, d, y), (w == null ? void 0 : w.status) !== 0)
|
|
515
596
|
return w;
|
|
516
|
-
const
|
|
517
|
-
let
|
|
518
|
-
for (const f of
|
|
519
|
-
const
|
|
597
|
+
const g = w == null ? void 0 : w.points, k = [], E = v.unix((p = g[0]) == null ? void 0 : p.utc);
|
|
598
|
+
let b = -1;
|
|
599
|
+
for (const f of g) {
|
|
600
|
+
const h = v.unix(f.utc), m = {
|
|
520
601
|
imo: r == null ? void 0 : r.imo,
|
|
521
602
|
mmsi: t,
|
|
522
603
|
sog: Math.round(f.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
523
604
|
cog: Math.round(f.cog / 100 * 100) / 100,
|
|
524
605
|
lat: Math.round(f.lat / 1e6 * 1e5) / 1e5,
|
|
525
606
|
lng: Math.round(f.lon / 1e6 * 1e5) / 1e5,
|
|
526
|
-
positionTime:
|
|
527
|
-
utc:
|
|
607
|
+
positionTime: h.unix(),
|
|
608
|
+
utc: h.utc().format(),
|
|
528
609
|
method: "trajectory",
|
|
529
610
|
vendor: "shipxy"
|
|
530
|
-
},
|
|
531
|
-
|
|
611
|
+
}, c = Math.floor(h.diff(E, "minute", !0) / (n || 1));
|
|
612
|
+
c !== b && (b = c, k.push(m));
|
|
532
613
|
}
|
|
533
|
-
return
|
|
614
|
+
return k;
|
|
534
615
|
}
|
|
535
616
|
}
|
|
536
617
|
class Dt extends nt {
|
|
537
618
|
constructor(t) {
|
|
538
619
|
super();
|
|
539
|
-
|
|
620
|
+
K(this, "token");
|
|
540
621
|
this.token = t;
|
|
541
622
|
}
|
|
542
623
|
async getShipId(t, a = {}) {
|
|
@@ -548,7 +629,7 @@ class Dt extends nt {
|
|
|
548
629
|
mmsiList: t
|
|
549
630
|
}
|
|
550
631
|
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await B.post(n, i).json();
|
|
551
|
-
return
|
|
632
|
+
return M == null || M.info("[%s] fetch ship id from: %s - %j", a.requestId, n, i), o.code !== "0" ? o : o.data[0].shipId;
|
|
552
633
|
}
|
|
553
634
|
async getShipInfo(t, a = {}) {
|
|
554
635
|
const i = {
|
|
@@ -559,11 +640,11 @@ class Dt extends nt {
|
|
|
559
640
|
shipId: t
|
|
560
641
|
}
|
|
561
642
|
}, n = "https://api3.myships.com/sp/ships/aissta", o = await B.post(n, i).json();
|
|
562
|
-
if (
|
|
643
|
+
if (M == null || M.info("[%s] fetch ship info from: %s - %j", a.requestId, n, i), o.code !== "0")
|
|
563
644
|
return o;
|
|
564
645
|
const e = o.data;
|
|
565
646
|
let r = e.imo;
|
|
566
|
-
return t === "407170" && (r = "9198379",
|
|
647
|
+
return t === "407170" && (r = "9198379", M == null || M.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, e.imo, r)), {
|
|
567
648
|
mmsi: e.mmsi,
|
|
568
649
|
name: e.shipnameEn,
|
|
569
650
|
imo: r,
|
|
@@ -582,38 +663,38 @@ class Dt extends nt {
|
|
|
582
663
|
shipId: i
|
|
583
664
|
}
|
|
584
665
|
}, e = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(e, o).json();
|
|
585
|
-
|
|
586
|
-
const
|
|
587
|
-
for (const
|
|
588
|
-
!isNaN(
|
|
589
|
-
const { labelCn:
|
|
666
|
+
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, e, o);
|
|
667
|
+
const u = r.data[0];
|
|
668
|
+
for (const g in u)
|
|
669
|
+
!isNaN(u[g]) && Number(u[g]) !== 1 / 0 && (u[g] = Number(u[g]));
|
|
670
|
+
const { labelCn: l, labelEn: d } = await this.parseStatus(u.aisNavStatus), y = v.unix(u.posTime);
|
|
590
671
|
return {
|
|
591
672
|
...n,
|
|
592
673
|
mmsi: t,
|
|
593
|
-
lat: Math.round(
|
|
594
|
-
lng: Math.round(
|
|
595
|
-
sog: Math.round(
|
|
596
|
-
cog: Math.round(
|
|
597
|
-
hdg: Math.round(
|
|
598
|
-
rot: Math.round(
|
|
599
|
-
positionTime:
|
|
600
|
-
utc:
|
|
601
|
-
status:
|
|
602
|
-
labelEn:
|
|
603
|
-
labelCn:
|
|
674
|
+
lat: Math.round(u.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
675
|
+
lng: Math.round(u.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
676
|
+
sog: Math.round(u.sog / 10 * 100) / 100,
|
|
677
|
+
cog: Math.round(u.cog / 10 * 100) / 100,
|
|
678
|
+
hdg: Math.round(u.heading * 100) / 100,
|
|
679
|
+
rot: Math.round(u.rot * 100) / 100,
|
|
680
|
+
positionTime: u.posTime,
|
|
681
|
+
utc: y.utc().format(),
|
|
682
|
+
status: u.aisNavStatus,
|
|
683
|
+
labelEn: d,
|
|
684
|
+
labelCn: l,
|
|
604
685
|
method: "position",
|
|
605
686
|
vendor: "myship"
|
|
606
687
|
};
|
|
607
688
|
}
|
|
608
689
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
609
|
-
const r =
|
|
610
|
-
for (;
|
|
611
|
-
await this.trajectoryIn30Day(
|
|
612
|
-
return await this.trajectoryIn30Day(
|
|
690
|
+
const r = v(a), u = v(i), l = await this.getShipId(t), d = await this.getShipInfo(l), y = [];
|
|
691
|
+
for (; u.diff(r, "day", !0) > 30; )
|
|
692
|
+
await this.trajectoryIn30Day(l, r.unix(), r.add(30, "day").unix(), d, t, n, y);
|
|
693
|
+
return await this.trajectoryIn30Day(l, r.unix(), u.unix(), d, t, n, y), y;
|
|
613
694
|
}
|
|
614
|
-
async trajectoryIn30Day(t, a, i, n, o, e, r,
|
|
615
|
-
var
|
|
616
|
-
const
|
|
695
|
+
async trajectoryIn30Day(t, a, i, n, o, e, r, u = {}) {
|
|
696
|
+
var E;
|
|
697
|
+
const l = {
|
|
617
698
|
headers: {
|
|
618
699
|
appKey: this.token
|
|
619
700
|
},
|
|
@@ -622,30 +703,30 @@ class Dt extends nt {
|
|
|
622
703
|
startTime: a,
|
|
623
704
|
endTime: i
|
|
624
705
|
}
|
|
625
|
-
},
|
|
626
|
-
if (
|
|
627
|
-
return
|
|
628
|
-
const w =
|
|
629
|
-
for (const
|
|
630
|
-
!isNaN(w[
|
|
631
|
-
const
|
|
632
|
-
let
|
|
633
|
-
for (const
|
|
634
|
-
const
|
|
706
|
+
}, d = "https://api3.myships.com/sp/ships/position/history", y = await B.post(d, l).json();
|
|
707
|
+
if (M == null || M.info("[%s] fetch trajectory from: %s - %j", u.requestId, d, l), y.code !== "0")
|
|
708
|
+
return M == null || M.warn("[%s] invoke myship trajectory failed: %j", u.requestId, y), y;
|
|
709
|
+
const w = y.data;
|
|
710
|
+
for (const b in w)
|
|
711
|
+
!isNaN(w[b]) && Number(w[b]) !== 1 / 0 && (w[b] = Number(w[b]));
|
|
712
|
+
const g = v.unix((E = w[0]) == null ? void 0 : E.posTime);
|
|
713
|
+
let k = -1;
|
|
714
|
+
for (const b of w) {
|
|
715
|
+
const p = v.unix(b.posTime), f = {
|
|
635
716
|
imo: n == null ? void 0 : n.imo,
|
|
636
717
|
mmsi: o,
|
|
637
|
-
lat: Math.round(
|
|
638
|
-
lng: Math.round(
|
|
639
|
-
sog: Math.round(
|
|
640
|
-
cog: Math.round(
|
|
641
|
-
hdg: Math.round(
|
|
642
|
-
rot: Math.round(
|
|
643
|
-
positionTime:
|
|
644
|
-
utc:
|
|
718
|
+
lat: Math.round(b.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
719
|
+
lng: Math.round(b.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
720
|
+
sog: Math.round(b.sog / 10 * 100) / 100,
|
|
721
|
+
cog: Math.round(b.cog / 10 * 100) / 100,
|
|
722
|
+
hdg: Math.round(b.heading * 100) / 100,
|
|
723
|
+
rot: Math.round(b.rot * 100) / 100,
|
|
724
|
+
positionTime: p.unix(),
|
|
725
|
+
utc: p.utc().format(),
|
|
645
726
|
method: "trajectory",
|
|
646
727
|
vendor: "myship"
|
|
647
|
-
},
|
|
648
|
-
|
|
728
|
+
}, h = Math.floor(p.diff(g, "minute", !0) / (e || 1));
|
|
729
|
+
h !== k && (k = h, r.push(f));
|
|
649
730
|
}
|
|
650
731
|
return r;
|
|
651
732
|
}
|
|
@@ -656,8 +737,8 @@ try {
|
|
|
656
737
|
} catch {
|
|
657
738
|
} finally {
|
|
658
739
|
}
|
|
659
|
-
var Mt = /* @__PURE__ */ ((
|
|
660
|
-
class
|
|
740
|
+
var Mt = /* @__PURE__ */ ((x) => (x.NOTICE = "NOTICE", x.WARN = "WARN", x.HEAVY = "HEAVY", x.SEVERE = "SEVERE", x.ERROR = "ERROR", x.FATAL = "FATAL", x))(Mt || {});
|
|
741
|
+
class gt {
|
|
661
742
|
/**
|
|
662
743
|
* 解析告警规则, 多规则场景
|
|
663
744
|
* @param rule
|
|
@@ -667,20 +748,20 @@ class bt {
|
|
|
667
748
|
* @param options
|
|
668
749
|
*/
|
|
669
750
|
parsePrinciple(s, t = {}) {
|
|
670
|
-
var e, r,
|
|
751
|
+
var e, r, u;
|
|
671
752
|
_ == null || _.debug("[%s] parse rule: %s", t.requestId, s);
|
|
672
753
|
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = s.match(a) ? (e = s.match(a)) == null ? void 0 : e[0] : void 0, n = i == null ? void 0 : i.split(";");
|
|
673
754
|
if (!n)
|
|
674
755
|
return;
|
|
675
756
|
const o = {};
|
|
676
|
-
for (let
|
|
677
|
-
const
|
|
678
|
-
if (
|
|
757
|
+
for (let l = 0; l < (n == null ? void 0 : n.length); l++) {
|
|
758
|
+
const d = (u = (r = n[l].match(a)) == null ? void 0 : r[0]) == null ? void 0 : u.split("],");
|
|
759
|
+
if (l === 0 && !d)
|
|
679
760
|
o.scope = n[0];
|
|
680
|
-
else if (
|
|
681
|
-
for (let
|
|
682
|
-
const
|
|
683
|
-
|
|
761
|
+
else if (d)
|
|
762
|
+
for (let y = 0, w = d.length; y < w; y++) {
|
|
763
|
+
const g = this.parseRule(d[y]);
|
|
764
|
+
g && (o[g.level] ? g.key ? o[g.level][g == null ? void 0 : g.key] = g : o[g.level] = g : g.key ? o[g.level] = { [g == null ? void 0 : g.key]: g } : o[g.level] = g);
|
|
684
765
|
}
|
|
685
766
|
}
|
|
686
767
|
return o;
|
|
@@ -713,25 +794,25 @@ class bt {
|
|
|
713
794
|
* @param options
|
|
714
795
|
*/
|
|
715
796
|
checkWeather(s, t, a = {}) {
|
|
716
|
-
var
|
|
797
|
+
var g, k, E, b, p, f, h, m, c, I, C, F, q, D, H;
|
|
717
798
|
let i = 0, n = 0, o = 0, e = 0;
|
|
718
|
-
const r = Math.round(((
|
|
799
|
+
const r = Math.round(((k = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.sigWave) == null ? void 0 : k.number) * 1.6 * 100) / 100, u = (b = (E = t == null ? void 0 : t.SEVERE) == null ? void 0 : E.sigWave) == null ? void 0 : b.number, l = (f = (p = t == null ? void 0 : t.HEAVY) == null ? void 0 : p.sigWave) == null ? void 0 : f.number, d = Math.round((((m = (h = t == null ? void 0 : t.SEVERE) == null ? void 0 : h.wind) == null ? void 0 : m.number) + 2) * 100) / 100, y = (I = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : I.number, w = (F = (C = t == null ? void 0 : t.HEAVY) == null ? void 0 : C.wind) == null ? void 0 : F.number;
|
|
719
800
|
for (let T = 0; T < (s == null ? void 0 : s.length); T++) {
|
|
720
|
-
const
|
|
721
|
-
e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...
|
|
801
|
+
const N = s[T], L = (D = (q = N == null ? void 0 : N.meteo) == null ? void 0 : q.wave) == null ? void 0 : D.sig, O = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wind, J = T ? v(N.eta).diff(v(s[T - 1].eta), "hour", !0) : 0;
|
|
802
|
+
e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...L, dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l }), (L == null ? void 0 : L.height) >= r ? N.isDangerous = !0 : (L == null ? void 0 : L.height) >= u ? N.isSevere = !0 : (L == null ? void 0 : L.height) >= l && (N.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...O, dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }), (O == null ? void 0 : O.scale) >= d ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (O == null ? void 0 : O.scale) > y ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (O == null ? void 0 : O.scale) === w && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? J : 0, n += N.isSevere ? J : 0, o += N.isHeavy ? J : 0;
|
|
722
803
|
}
|
|
723
|
-
return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, e = Math.round(e), { sample: s, dangerous: i, severe: n, heavy: o, step: e < 3 ? 3 : e, wind: { dgThd4Wd:
|
|
804
|
+
return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, e = Math.round(e), { sample: s, dangerous: i, severe: n, heavy: o, step: e < 3 ? 3 : e, wind: { dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l } };
|
|
724
805
|
}
|
|
725
806
|
}
|
|
726
|
-
const At = new
|
|
727
|
-
let
|
|
807
|
+
const At = new gt();
|
|
808
|
+
let j;
|
|
728
809
|
try {
|
|
729
|
-
|
|
810
|
+
j = ut.getLogger("vessel");
|
|
730
811
|
} catch {
|
|
731
812
|
} finally {
|
|
732
813
|
}
|
|
733
|
-
const
|
|
734
|
-
var pt = /* @__PURE__ */ ((
|
|
814
|
+
const bt = new yt("", !0);
|
|
815
|
+
var pt = /* @__PURE__ */ ((x) => (x.common = "common", x.container = "container", x.tugs = "tugs", x))(pt || {}), vt = /* @__PURE__ */ ((x) => (x.Ballast = "Ballast", x.Laden = "Laden", x))(vt || {}), wt = /* @__PURE__ */ ((x) => (x.Cp = "CP", x.Perf = "Basis", x.Instruct = "Other", x))(wt || {});
|
|
735
816
|
class W {
|
|
736
817
|
/**
|
|
737
818
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
@@ -845,10 +926,10 @@ class W {
|
|
|
845
926
|
* @private
|
|
846
927
|
*/
|
|
847
928
|
static assembleProperties(s, t, a, i) {
|
|
848
|
-
var
|
|
849
|
-
const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, o = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, r = s.deadweight ?? 67035.7773,
|
|
929
|
+
var y;
|
|
930
|
+
const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, o = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, r = s.deadweight ?? 67035.7773, u = ((y = s == null ? void 0 : s.type) == null ? void 0 : y.toLowerCase()) || "common";
|
|
850
931
|
return {
|
|
851
|
-
tag:
|
|
932
|
+
tag: u.indexOf("container") > -1 ? "container" : u.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
852
933
|
lbp: n,
|
|
853
934
|
loadCondition: t,
|
|
854
935
|
draught: o,
|
|
@@ -873,40 +954,40 @@ class W {
|
|
|
873
954
|
* @param options
|
|
874
955
|
*/
|
|
875
956
|
static async speedLoseAt(s, t, a, i = "", n = 2, o = !0, e = !1, r = {}) {
|
|
876
|
-
let
|
|
957
|
+
let u;
|
|
877
958
|
if (t.velocity && e && (s.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
|
|
878
|
-
let
|
|
959
|
+
let l;
|
|
879
960
|
try {
|
|
880
961
|
i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
|
|
881
|
-
const { weatherModels:
|
|
962
|
+
const { weatherModels: g, marineModels: k } = await dt.autoPickMeteoModel(i), E = await bt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
|
|
882
963
|
...r,
|
|
883
964
|
pastDays: 1,
|
|
884
965
|
forecastDays: 1,
|
|
885
|
-
weatherModels:
|
|
886
|
-
marineModels:
|
|
887
|
-
}), [
|
|
888
|
-
|
|
889
|
-
} catch (
|
|
890
|
-
|
|
966
|
+
weatherModels: g,
|
|
967
|
+
marineModels: k
|
|
968
|
+
}), [b] = dt.pickHourly(E, a);
|
|
969
|
+
l = dt.toLegacy(b);
|
|
970
|
+
} catch (g) {
|
|
971
|
+
j.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: i }, g);
|
|
891
972
|
}
|
|
892
|
-
const
|
|
893
|
-
|
|
894
|
-
meteo: { ...
|
|
895
|
-
wxFactor:
|
|
896
|
-
cFactor:
|
|
973
|
+
const d = W.currentFactor(s.bearing, l == null ? void 0 : l.current, n), y = W.weatherFactor(s, l, d), w = Math.round((s.speed * 1.943844 + y + d) * 100) / 100;
|
|
974
|
+
u = {
|
|
975
|
+
meteo: { ...l },
|
|
976
|
+
wxFactor: y,
|
|
977
|
+
cFactor: d,
|
|
897
978
|
speed: t.velocity && e ? t.velocity : w < 0 ? 1 : w,
|
|
898
979
|
eta: a.utc().format(),
|
|
899
980
|
etd: a.utc().format()
|
|
900
981
|
};
|
|
901
982
|
} else
|
|
902
|
-
|
|
983
|
+
u = {
|
|
903
984
|
wxFactor: 0,
|
|
904
985
|
cFactor: 0,
|
|
905
986
|
speed: t.velocity && e ? t.velocity : Math.round(s.speed * 1.943844 * 100) / 100,
|
|
906
987
|
eta: a.utc().format(),
|
|
907
988
|
etd: a.utc().format()
|
|
908
989
|
};
|
|
909
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
990
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...u, ...t };
|
|
910
991
|
}
|
|
911
992
|
/**
|
|
912
993
|
* 基于步长计算失速样本
|
|
@@ -922,53 +1003,53 @@ class W {
|
|
|
922
1003
|
* @param options
|
|
923
1004
|
* @private
|
|
924
1005
|
*/
|
|
925
|
-
static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", r = !0,
|
|
1006
|
+
static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", r = !0, u = !1, l = {}) {
|
|
926
1007
|
t.utc();
|
|
927
|
-
const
|
|
928
|
-
let
|
|
1008
|
+
const d = t.clone().add(14, "days"), y = [], w = [], g = [];
|
|
1009
|
+
let k = 0, E = 0, b, p;
|
|
929
1010
|
for (let f = 0; f < o.length - 1; f++) {
|
|
930
|
-
let
|
|
931
|
-
|
|
932
|
-
const
|
|
933
|
-
if (s.bearing = V.calculateBearing(
|
|
934
|
-
|
|
935
|
-
const
|
|
936
|
-
if (i -
|
|
937
|
-
i = i -
|
|
1011
|
+
let h = o[f];
|
|
1012
|
+
h.distanceFromStart = Math.round((n + E) * 1e3) / 1e3;
|
|
1013
|
+
const m = o[f + 1];
|
|
1014
|
+
if (s.bearing = V.calculateBearing(h, m, !m.gcToPrevious), h.bearing = s.bearing, h.suspend && u) {
|
|
1015
|
+
h.eta = h.eta || t.utc().format(), h.elapsed = h.elapsed ?? 0;
|
|
1016
|
+
const C = h.suspend - h.elapsed;
|
|
1017
|
+
if (i - k > C)
|
|
1018
|
+
i = i - k - C, t.add(C, "hour"), h.elapsed = h.suspend;
|
|
938
1019
|
else {
|
|
939
|
-
const
|
|
940
|
-
|
|
1020
|
+
const F = i - k;
|
|
1021
|
+
h.elapsed += F, t.add(F, "hour"), i = 0;
|
|
941
1022
|
}
|
|
942
|
-
if (
|
|
943
|
-
return
|
|
1023
|
+
if (j == null || j.info(`[%s] suspend ${h.elapsed} hours at %j, and remain ${i} hours need to go...`, l.requestId, h), i === 0)
|
|
1024
|
+
return h.distanceFromPrevious = E, { etd: t, from: p || h, to: h, next: o.filter((F) => F), wps: y, days: w, all: g };
|
|
944
1025
|
} else
|
|
945
|
-
|
|
946
|
-
r = t.isAfter(
|
|
947
|
-
const
|
|
948
|
-
let I = Math.round(
|
|
949
|
-
if (
|
|
950
|
-
if (
|
|
951
|
-
`[%s] go to %j from %j with ${
|
|
952
|
-
|
|
953
|
-
{ lat:
|
|
954
|
-
{ lat:
|
|
955
|
-
),
|
|
956
|
-
|
|
1026
|
+
h.suspend = 0;
|
|
1027
|
+
r = t.isAfter(d) ? !1 : r, h = await W.speedLoseAt(s, h, t, e, 0, r, u, l), g.push(h), p = p || h, h.important && y.push(h), t.isSameOrAfter(a) && (w.push(h), a.add(24, "hour"));
|
|
1028
|
+
const c = V.calculateDistance(h, m, !m.gcToPrevious);
|
|
1029
|
+
let I = Math.round(c / p.speed * 1e5) / 1e5;
|
|
1030
|
+
if (k + I < i) {
|
|
1031
|
+
if (k += I, t.add(I, "hour"), delete o[f], j == null || j.debug(
|
|
1032
|
+
`[%s] go to %j from %j with ${c}nm, and cost ${I} hours`,
|
|
1033
|
+
l.requestId,
|
|
1034
|
+
{ lat: m.lat, lng: m.lng },
|
|
1035
|
+
{ lat: p.lat, lng: p.lng, etd: p.etd }
|
|
1036
|
+
), E += c, o.filter((C) => C).length <= 1) {
|
|
1037
|
+
b = m, b.eta = t.utc().format(), b.distanceFromPrevious = c, b.distanceFromStart = Math.round((n + E) * 1e4) / 1e4, y.push(b), g.push(b), delete o[f + 1];
|
|
957
1038
|
break;
|
|
958
1039
|
}
|
|
959
1040
|
} else {
|
|
960
|
-
I = i -
|
|
961
|
-
const
|
|
962
|
-
|
|
963
|
-
`[%s] go to %j from %j with ${
|
|
964
|
-
|
|
965
|
-
{ lat:
|
|
966
|
-
{ lat:
|
|
967
|
-
),
|
|
1041
|
+
I = i - k, t.add(I, "hour");
|
|
1042
|
+
const C = z.roundPrecision(p.speed * I, 5);
|
|
1043
|
+
b = V.calculateCoordinate(h, s.bearing, C, "nauticalmiles", !m.gcToPrevious), b.eta = t.utc().format(), o[f] = b, j == null || j.debug(
|
|
1044
|
+
`[%s] go to %j from %j with ${C}nm, and cost ${I} hours`,
|
|
1045
|
+
l.requestId,
|
|
1046
|
+
{ lat: b.lat, lng: b.lng },
|
|
1047
|
+
{ lat: h.lat, lng: h.lng, etd: h.etd }
|
|
1048
|
+
), E += C, b.distanceFromPrevious = Math.round(E * 1e4) / 1e4, b.distanceFromStart = Math.round((n + E) * 1e4) / 1e4;
|
|
968
1049
|
break;
|
|
969
1050
|
}
|
|
970
1051
|
}
|
|
971
|
-
return { etd: t, from:
|
|
1052
|
+
return { etd: t, from: p, to: b, next: o.filter((f) => f), wps: y, days: w, all: g };
|
|
972
1053
|
}
|
|
973
1054
|
/**
|
|
974
1055
|
* 洋流影响因子
|
|
@@ -990,16 +1071,16 @@ class W {
|
|
|
990
1071
|
* @param cFactor 洋流因子
|
|
991
1072
|
*/
|
|
992
1073
|
static weatherFactor(s, t, a = 0) {
|
|
993
|
-
var w,
|
|
994
|
-
|
|
1074
|
+
var w, g, k, E, b, p, f;
|
|
1075
|
+
j == null || j.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
995
1076
|
const i = W.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = W.froudeNumber(s.speed - n, s.lbp), e = W.amendFactor(i, o, s.loadCondition);
|
|
996
1077
|
let r = Math.abs(s.bearing % 360 - (((w = t == null ? void 0 : t.wind) == null ? void 0 : w.degree) % 360 || 0));
|
|
997
1078
|
r = r > 180 ? 360 - r : r;
|
|
998
|
-
const
|
|
999
|
-
let
|
|
1000
|
-
|
|
1001
|
-
const
|
|
1002
|
-
return
|
|
1079
|
+
const u = W.directionFactor(r, (g = t == null ? void 0 : t.wind) == null ? void 0 : g.scale), l = W.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.kts);
|
|
1080
|
+
let d = u * e * l / 100 * (s.speed - n);
|
|
1081
|
+
d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), j == null || j.debug("wind wx factor = %d", d), r = Math.abs(s.bearing % 360 - (((b = (E = t == null ? void 0 : t.wave) == null ? void 0 : E.sig) == null ? void 0 : b.degree) % 360 || 0)), r = r > 180 ? 360 - r : r;
|
|
1082
|
+
const y = W.waveHeightFactor(((f = (p = t == null ? void 0 : t.wave) == null ? void 0 : p.sig) == null ? void 0 : f.height) ?? 1, r);
|
|
1083
|
+
return j == null || j.debug("wave wx factor = %d", y), d = Math.abs(d) > Math.abs(y) ? d : d * 0.3 + y * 0.7, j == null || j.debug("weather factor = %d", d), d = Math.abs(d) > 3 ? 3 * (Math.abs(d) / d) + Math.abs(d) / d * (Math.abs(d) - 2) * 0.1 : d, Math.round((d || 0) * 100) / 100;
|
|
1003
1084
|
}
|
|
1004
1085
|
/**
|
|
1005
1086
|
* 全程失速分析(走完航程)
|
|
@@ -1014,14 +1095,14 @@ class W {
|
|
|
1014
1095
|
* @param useRouteParam
|
|
1015
1096
|
* @param options
|
|
1016
1097
|
*/
|
|
1017
|
-
static async analyseInstant(s, t, a, i, n, o = "", e = 0, r = !0,
|
|
1018
|
-
var
|
|
1019
|
-
const
|
|
1098
|
+
static async analyseInstant(s, t, a, i, n, o = "", e = 0, r = !0, u = !1, l = {}) {
|
|
1099
|
+
var U, G, X, Q, Z, $, tt;
|
|
1100
|
+
const d = v().valueOf();
|
|
1020
1101
|
s.lng = z.convertToStdLng(s.lng);
|
|
1021
|
-
const { route:
|
|
1022
|
-
if (((
|
|
1102
|
+
const { route: y, waypoints: w } = n.points, g = V.calculateSubRoute(s, y);
|
|
1103
|
+
if (((U = g[0]) == null ? void 0 : U.length) <= 1)
|
|
1023
1104
|
return;
|
|
1024
|
-
const { v0:
|
|
1105
|
+
const { v0: k, label: E } = s.sog ? {
|
|
1025
1106
|
v0: s.sog,
|
|
1026
1107
|
label: s.label || "Other"
|
|
1027
1108
|
/* Instruct */
|
|
@@ -1029,69 +1110,69 @@ class W {
|
|
|
1029
1110
|
v0: i.speed,
|
|
1030
1111
|
label: "CP"
|
|
1031
1112
|
/* Cp */
|
|
1032
|
-
},
|
|
1033
|
-
|
|
1113
|
+
}, b = W.assembleProperties(a, i.loadCondition, k, 0), p = w.length ? V.calculateSubWaypoints(s, w) : [];
|
|
1114
|
+
p.forEach((A) => A.important = !0);
|
|
1034
1115
|
const f = {
|
|
1035
1116
|
from: { ...s },
|
|
1036
|
-
route:
|
|
1037
|
-
waypoints:
|
|
1038
|
-
v0:
|
|
1039
|
-
label:
|
|
1040
|
-
},
|
|
1117
|
+
route: g,
|
|
1118
|
+
waypoints: p,
|
|
1119
|
+
v0: k,
|
|
1120
|
+
label: E
|
|
1121
|
+
}, h = {
|
|
1041
1122
|
hours: [],
|
|
1042
1123
|
days: [],
|
|
1043
1124
|
wps: [],
|
|
1044
1125
|
all: []
|
|
1045
1126
|
};
|
|
1046
|
-
e || (V.calculateRouteDistance(
|
|
1047
|
-
let
|
|
1048
|
-
t =
|
|
1127
|
+
e || (V.calculateRouteDistance(g) / i.speed <= 72 ? e = 3 : e = 6);
|
|
1128
|
+
let m = V.simplifyRouteToCoordinates(g, p, 0), c = 0, I = 0, C = 0, F = 0;
|
|
1129
|
+
t = v(t).utc();
|
|
1049
1130
|
const q = t.clone();
|
|
1050
|
-
for (;
|
|
1051
|
-
const A = e - t.hour() % e,
|
|
1052
|
-
|
|
1131
|
+
for (; m.length > 0; ) {
|
|
1132
|
+
const A = e - t.hour() % e, R = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, S = await W.speedLoseInHoursStep(
|
|
1133
|
+
b,
|
|
1053
1134
|
t,
|
|
1054
1135
|
q,
|
|
1055
|
-
|
|
1136
|
+
R,
|
|
1137
|
+
c,
|
|
1056
1138
|
m,
|
|
1057
|
-
l,
|
|
1058
1139
|
o,
|
|
1059
1140
|
r,
|
|
1060
|
-
|
|
1061
|
-
|
|
1141
|
+
u,
|
|
1142
|
+
l
|
|
1062
1143
|
);
|
|
1063
|
-
if (
|
|
1064
|
-
const Y = await W.speedLoseAt(
|
|
1065
|
-
Y.bearing =
|
|
1144
|
+
if (h.all.push(...S.all), (G = S.from) != null && G.speed && (h.hours.push(S.from), h.wps.push(...S.wps), h.days.push(...S.days)), m = S == null ? void 0 : S.next, !m.length) {
|
|
1145
|
+
const Y = await W.speedLoseAt(b, S.to, v(S.to.eta), o, 0, r, u, l);
|
|
1146
|
+
Y.bearing = b.bearing, h.hours.push(Y), h.all.push(Y);
|
|
1066
1147
|
}
|
|
1067
|
-
|
|
1148
|
+
c += Math.round((((X = S == null ? void 0 : S.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
1068
1149
|
}
|
|
1069
|
-
const D =
|
|
1150
|
+
const D = h.hours;
|
|
1070
1151
|
for (let A = 0; A < D.length - 1; A++) {
|
|
1071
|
-
const
|
|
1072
|
-
I += (D[A].wxFactor || 0) *
|
|
1152
|
+
const R = v(D[A + 1].eta).diff(D[A].etd, "hour", !0) || 1;
|
|
1153
|
+
I += (D[A].wxFactor || 0) * R, C += (D[A].cFactor || 0) * R, F += R;
|
|
1073
1154
|
}
|
|
1074
|
-
const H = D.reduce((A,
|
|
1075
|
-
(Q =
|
|
1076
|
-
A.positionTime =
|
|
1077
|
-
const S =
|
|
1155
|
+
const H = D.reduce((A, R) => A + (R.suspend || 0), 0);
|
|
1156
|
+
(Q = h.wps) == null || Q.forEach((A, R) => {
|
|
1157
|
+
A.positionTime = v.utc(A.etd || A.eta).unix();
|
|
1158
|
+
const S = h.wps[R - 1];
|
|
1078
1159
|
if (S) {
|
|
1079
|
-
const Y = A.distanceFromStart - S.distanceFromStart, P =
|
|
1160
|
+
const Y = A.distanceFromStart - S.distanceFromStart, P = v(A.eta || A.etd).diff(v(S.etd || S.eta), "h", !0);
|
|
1080
1161
|
A.avgSpd = Math.round(Y / P * 100) / 100, S.bearing = V.calculateBearing(S, A);
|
|
1081
1162
|
}
|
|
1082
|
-
}),
|
|
1083
|
-
const T =
|
|
1084
|
-
f.distance = Math.round(
|
|
1085
|
-
const
|
|
1163
|
+
}), h.wps = (Z = h.wps) == null ? void 0 : Z.reduce((A, R) => (A.some((S) => Math.round(S.positionTime / 60) === Math.round(R.positionTime / 60)) || A.push(R), A), []), h.all = ($ = h.all) == null ? void 0 : $.reduce((A, R) => (R.positionTime = v.utc(R.etd || R.eta).unix(), A.some((S) => Math.round(S.positionTime / 60) === Math.round(R.positionTime / 60)) || A.push(R), A), []), f.sample = h;
|
|
1164
|
+
const T = h.hours.at(0), N = h.hours.at(-1);
|
|
1165
|
+
f.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, f.etd = v(T.eta).utc().format(), f.eta = v(N.eta).utc().format(), f.wxFactor = Math.round(I / F * 1e3) / 1e3, f.cFactor = Math.round(C / F * 1e3) / 1e3, f.avgSpeed = Math.round(N.distanceFromStart / F * 1e3) / 1e3, f.totalHrs = Math.round(F * 1e3) / 1e3, f.suspend = Math.round(H * 1e3) / 1e3;
|
|
1166
|
+
const L = z.roundPrecision(i.dgo / 24 * H, 3), { distanceInECA: O, hoursInECA: J, totalDgoConsInECA: ot, eca: et } = await this.calculateECA(f, i, l), st = z.roundPrecision(i.fo / 24 * (F - J), 3), it = z.roundPrecision(i.dgo / 24 * F + L, 3);
|
|
1086
1167
|
f.extend = {
|
|
1087
1168
|
eca: et,
|
|
1088
|
-
distanceInECA:
|
|
1169
|
+
distanceInECA: O,
|
|
1089
1170
|
hoursInECA: J,
|
|
1090
1171
|
totalDgoConsInECA: ot,
|
|
1091
|
-
totalDgoConsInSuspend:
|
|
1172
|
+
totalDgoConsInSuspend: L
|
|
1092
1173
|
}, f.totalFoCons = st < 0 ? 0 : st, f.totalDgoCons = it;
|
|
1093
|
-
const at =
|
|
1094
|
-
return
|
|
1174
|
+
const at = v().valueOf() - d, ct = ((tt = h == null ? void 0 : h.hours) == null ? void 0 : tt.length) || 1;
|
|
1175
|
+
return j == null || j.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, at, ct, Math.round(at / ct * 1e3) / 1e3), f;
|
|
1095
1176
|
}
|
|
1096
1177
|
/**
|
|
1097
1178
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -1108,11 +1189,11 @@ class W {
|
|
|
1108
1189
|
* @param useRouteParam
|
|
1109
1190
|
* @param options
|
|
1110
1191
|
*/
|
|
1111
|
-
static async analyseInstantWithThreshed(s, t, a, i, n, o, e, r = "",
|
|
1112
|
-
var X, Q, Z, $, tt, A,
|
|
1113
|
-
const w =
|
|
1192
|
+
static async analyseInstantWithThreshed(s, t, a, i, n, o, e, r = "", u = 3, l = !0, d = !1, y = {}) {
|
|
1193
|
+
var X, Q, Z, $, tt, A, R;
|
|
1194
|
+
const w = v().valueOf();
|
|
1114
1195
|
s.lng = z.convertToStdLng(s.lng);
|
|
1115
|
-
const { v0:
|
|
1196
|
+
const { v0: g, label: k } = s.sog ? {
|
|
1116
1197
|
v0: s.sog,
|
|
1117
1198
|
label: s.label || "Other"
|
|
1118
1199
|
/* Instruct */
|
|
@@ -1120,67 +1201,67 @@ class W {
|
|
|
1120
1201
|
v0: n.speed,
|
|
1121
1202
|
label: "CP"
|
|
1122
1203
|
/* Cp */
|
|
1123
|
-
},
|
|
1124
|
-
if (((X =
|
|
1204
|
+
}, E = W.assembleProperties(i, n.loadCondition, g, 0), b = V.calculateSubRoute(s, o);
|
|
1205
|
+
if (((X = b[0]) == null ? void 0 : X.length) <= 1)
|
|
1125
1206
|
return;
|
|
1126
|
-
const
|
|
1127
|
-
|
|
1128
|
-
let f = V.simplifyRouteToCoordinates(
|
|
1129
|
-
const
|
|
1207
|
+
const p = e.length ? V.calculateSubWaypoints(s, e) : [];
|
|
1208
|
+
p.forEach((S) => S.important = !0);
|
|
1209
|
+
let f = V.simplifyRouteToCoordinates(b, p, 0), h = 0, m = 0, c = 0, I = 0;
|
|
1210
|
+
const C = {
|
|
1130
1211
|
hours: [],
|
|
1131
1212
|
wps: [],
|
|
1132
1213
|
days: [],
|
|
1133
1214
|
all: []
|
|
1134
1215
|
};
|
|
1135
|
-
t =
|
|
1136
|
-
const
|
|
1216
|
+
t = v(t).utc();
|
|
1217
|
+
const F = t.clone();
|
|
1137
1218
|
for (; f.length > 0; ) {
|
|
1138
|
-
const S =
|
|
1219
|
+
const S = u - t.hour() % u;
|
|
1139
1220
|
let Y = Math.ceil(t.clone().add(S, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
1140
1221
|
Y = t.clone().add(Y, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : Y;
|
|
1141
|
-
const P = await W.speedLoseInHoursStep(
|
|
1142
|
-
if (
|
|
1222
|
+
const P = await W.speedLoseInHoursStep(E, t, F, Y, h, f, r, l, d, y);
|
|
1223
|
+
if (C.all.push(...P.all), (Q = P.from) != null && Q.speed && (C.hours.push(P.from), P != null && P.wps && C.wps.push(...P.wps), C.days.push(...P.days)), f = P == null ? void 0 : P.next, f.length || C.hours.push(P == null ? void 0 : P.to), h += Math.round((((Z = P == null ? void 0 : P.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !Y)
|
|
1143
1224
|
break;
|
|
1144
1225
|
}
|
|
1145
|
-
|
|
1146
|
-
const P =
|
|
1226
|
+
C.wps = ($ = C.wps) == null ? void 0 : $.reduce((S, Y) => (S.some((P) => Math.round(v(P.etd).unix() / 60) === Math.round(v(Y.etd).unix() / 60)) || S.push(Y), S), []), C.all = (tt = C.all) == null ? void 0 : tt.reduce((S, Y) => (Y.positionTime = v.utc(Y.etd || Y.eta).unix(), S.some((P) => Math.round(v(P.etd).unix() / 60) === Math.round(v(Y.etd).unix() / 60)) || S.push(Y), S), []), (A = C.wps) == null || A.forEach((S, Y) => {
|
|
1227
|
+
const P = C.wps[Y - 1];
|
|
1147
1228
|
if (P) {
|
|
1148
|
-
const ht = S.distanceFromStart - P.distanceFromStart, lt =
|
|
1229
|
+
const ht = S.distanceFromStart - P.distanceFromStart, lt = v(S.eta || S.etd).diff(v(P.etd || P.eta), "h", !0);
|
|
1149
1230
|
S.avgSpd = Math.round(ht / lt * 100) / 100, P.bearing = V.calculateBearing(P, S);
|
|
1150
1231
|
}
|
|
1151
1232
|
});
|
|
1152
|
-
const q =
|
|
1233
|
+
const q = C.hours;
|
|
1153
1234
|
for (let S = 0; S < q.length - 1; S++) {
|
|
1154
|
-
const Y =
|
|
1155
|
-
|
|
1235
|
+
const Y = v(q[S + 1].eta).diff(q[S].etd, "hour", !0);
|
|
1236
|
+
m += q[S].wxFactor * Y, c += q[S].cFactor * Y, I += Y;
|
|
1156
1237
|
}
|
|
1157
|
-
const D = q.reduce((S, Y) => S + (Y.suspend || 0), 0), H =
|
|
1158
|
-
sample:
|
|
1238
|
+
const D = q.reduce((S, Y) => S + (Y.suspend || 0), 0), H = C.hours.at(0), T = C.hours.at(-1), N = await V.calculateRangeRoute(H, T, b), L = await V.calculateRangeWaypoints(H, T, b, p), O = {
|
|
1239
|
+
sample: C,
|
|
1159
1240
|
distance: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1160
1241
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1161
|
-
etd:
|
|
1162
|
-
eta:
|
|
1163
|
-
wxFactor: Math.round(
|
|
1164
|
-
cFactor: Math.round(
|
|
1242
|
+
etd: v(H.eta).utc().format(),
|
|
1243
|
+
eta: v(T == null ? void 0 : T.eta).utc().format(),
|
|
1244
|
+
wxFactor: Math.round(m / I * 1e3) / 1e3,
|
|
1245
|
+
cFactor: Math.round(c / I * 1e3) / 1e3,
|
|
1165
1246
|
avgSpeed: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) / I * 1e3) / 1e3,
|
|
1166
1247
|
totalHrs: Math.round(I * 1e3) / 1e3,
|
|
1167
1248
|
suspend: Math.round(D * 1e3) / 1e3,
|
|
1168
1249
|
from: H,
|
|
1169
1250
|
to: T,
|
|
1170
|
-
route:
|
|
1171
|
-
waypoints:
|
|
1172
|
-
v0:
|
|
1173
|
-
label:
|
|
1174
|
-
}, J = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: et, totalDgoConsInECA: st, eca: it } = await this.calculateECA(
|
|
1175
|
-
|
|
1251
|
+
route: N,
|
|
1252
|
+
waypoints: L,
|
|
1253
|
+
v0: g,
|
|
1254
|
+
label: k
|
|
1255
|
+
}, J = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: et, totalDgoConsInECA: st, eca: it } = await this.calculateECA(O, n, y), rt = z.roundPrecision(n.fo / 24 * (I - et), 3), at = z.roundPrecision(n.dgo / 24 * I + J, 3);
|
|
1256
|
+
O.extend = {
|
|
1176
1257
|
eca: it,
|
|
1177
1258
|
distanceInECA: ot,
|
|
1178
1259
|
hoursInECA: et,
|
|
1179
1260
|
totalDgoConsInECA: st,
|
|
1180
1261
|
totalDgoConsInSuspend: J
|
|
1181
|
-
},
|
|
1182
|
-
const
|
|
1183
|
-
return
|
|
1262
|
+
}, O.totalDgoCons = at, O.totalFoCons = rt < 0 ? 0 : rt;
|
|
1263
|
+
const U = v().valueOf() - w, G = ((R = C == null ? void 0 : C.hours) == null ? void 0 : R.length) || 1;
|
|
1264
|
+
return j == null || j.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", y == null ? void 0 : y.requestId, U, G, Math.round(U / G * 1e3) / 1e3), O;
|
|
1184
1265
|
}
|
|
1185
1266
|
/**
|
|
1186
1267
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1198,58 +1279,58 @@ class W {
|
|
|
1198
1279
|
* @param options
|
|
1199
1280
|
*/
|
|
1200
1281
|
static async analyseCost(s, t, a, i, n = {}) {
|
|
1201
|
-
var
|
|
1202
|
-
const o =
|
|
1282
|
+
var b, p;
|
|
1283
|
+
const o = v().valueOf(), e = [];
|
|
1203
1284
|
s.speedStep = s.speedStep || 3, s.alterStep = s.alterStep ?? 1;
|
|
1204
1285
|
const r = V.calculateRouteDistance(i.route);
|
|
1205
|
-
let
|
|
1286
|
+
let u = 0;
|
|
1206
1287
|
a.forEach((f) => {
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
}),
|
|
1210
|
-
const
|
|
1211
|
-
let
|
|
1288
|
+
const h = Math.ceil(r / f.speed / 24);
|
|
1289
|
+
u = u < h ? h : u;
|
|
1290
|
+
}), u = u * 1.3;
|
|
1291
|
+
const l = v.utc(s.etd).add(u ?? 14, "day");
|
|
1292
|
+
let d = 1;
|
|
1212
1293
|
for (const f of a) {
|
|
1213
|
-
const
|
|
1294
|
+
const h = JSON.parse(JSON.stringify(i.route)), m = JSON.parse(JSON.stringify(i.waypoints)), c = await W.analyseInstantWithThreshed(
|
|
1214
1295
|
{ lat: s.lat, lng: s.lng },
|
|
1215
1296
|
s.etd,
|
|
1216
|
-
|
|
1297
|
+
l,
|
|
1217
1298
|
t,
|
|
1218
1299
|
f,
|
|
1219
|
-
|
|
1220
|
-
|
|
1300
|
+
h,
|
|
1301
|
+
m,
|
|
1221
1302
|
s.meteoVendor,
|
|
1222
1303
|
s.speedStep,
|
|
1223
1304
|
s.useMeteo,
|
|
1224
1305
|
s.useRouteParam,
|
|
1225
1306
|
n
|
|
1226
1307
|
);
|
|
1227
|
-
|
|
1228
|
-
cost:
|
|
1229
|
-
hire:
|
|
1230
|
-
bunker:
|
|
1231
|
-
distance:
|
|
1232
|
-
hours:
|
|
1308
|
+
c && (await W.calculateCost(c, f, s, n), e.push(c), j == null || j.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, d, s.etd, l.format(), {
|
|
1309
|
+
cost: c.cost.total,
|
|
1310
|
+
hire: c.cost.hire,
|
|
1311
|
+
bunker: c.cost.bunker,
|
|
1312
|
+
distance: c.distance,
|
|
1313
|
+
hours: c.totalHrs,
|
|
1233
1314
|
cp: `${f.speed}/${f.fo}/${f.dgo}`
|
|
1234
|
-
})),
|
|
1315
|
+
})), d++;
|
|
1235
1316
|
}
|
|
1236
|
-
e.sort((f,
|
|
1237
|
-
const
|
|
1238
|
-
if (
|
|
1239
|
-
const f =
|
|
1240
|
-
let
|
|
1241
|
-
|
|
1242
|
-
let
|
|
1243
|
-
for (;
|
|
1244
|
-
const H = await W.combinedAnalyse(s, t,
|
|
1245
|
-
if (q.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = q, q = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H),
|
|
1317
|
+
e.sort((f, h) => f.cost.total - h.cost.total);
|
|
1318
|
+
const y = e.at(0), w = e.at(1), g = [];
|
|
1319
|
+
if (g.push({ combined: !1, speeds: [y], cost: (b = y.cost) == null ? void 0 : b.total }), w) {
|
|
1320
|
+
const f = y.cost.cp, h = w.cost.cp, m = v(y.eta), c = v(y.etd), I = m.diff(c, "days", !0);
|
|
1321
|
+
let C = Math.ceil(I / 2);
|
|
1322
|
+
C = C > 7 ? 7 : C < s.alterStep ? s.alterStep : C;
|
|
1323
|
+
let F = 2, q = { combined: !1, speeds: [w], cost: (p = w.cost) == null ? void 0 : p.total }, D;
|
|
1324
|
+
for (; C >= s.alterStep; ) {
|
|
1325
|
+
const H = await W.combinedAnalyse(s, t, l, [f, h], i, C, { ...n, level: F });
|
|
1326
|
+
if (q.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = q, q = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), C <= s.alterStep)
|
|
1246
1327
|
break;
|
|
1247
|
-
|
|
1328
|
+
C = Math.ceil(C / 2), F += 1;
|
|
1248
1329
|
}
|
|
1249
|
-
|
|
1330
|
+
g.push(q), D && g.push(D);
|
|
1250
1331
|
}
|
|
1251
|
-
const
|
|
1252
|
-
return
|
|
1332
|
+
const E = v().valueOf() - o;
|
|
1333
|
+
return j == null || j.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, E), g.sort((f, h) => f.cost - h.cost);
|
|
1253
1334
|
}
|
|
1254
1335
|
/**
|
|
1255
1336
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1262,23 +1343,23 @@ class W {
|
|
|
1262
1343
|
* @param options
|
|
1263
1344
|
*/
|
|
1264
1345
|
static async combinedAnalyse(s, t, a, i, n, o, e = {}) {
|
|
1265
|
-
e.counter = 1,
|
|
1266
|
-
const r = await W.alternateAnalyse(s, t, a, i, 0, n, o, e),
|
|
1267
|
-
|
|
1268
|
-
cost:
|
|
1269
|
-
hire:
|
|
1270
|
-
bunker:
|
|
1271
|
-
distance:
|
|
1346
|
+
e.counter = 1, j == null || j.info("[%s][L%d] analyse with alternate cp in every %d days", e.requestId, e.level, o);
|
|
1347
|
+
const r = await W.alternateAnalyse(s, t, a, i, 0, n, o, e), u = r.reduce((h, m) => h + m.cost.total, 0), l = r.reduce((h, m) => h + m.cost.hire, 0), d = r.reduce((h, m) => h + m.cost.bunker, 0), y = r.reduce((h, m) => h + m.distance, 0), w = r.reduce((h, m) => h + m.totalHrs, 0);
|
|
1348
|
+
j == null || j.info("[%s][L%d] cost with cpa/cpb turn: %j", e.requestId, e.level, {
|
|
1349
|
+
cost: u,
|
|
1350
|
+
hire: l,
|
|
1351
|
+
bunker: d,
|
|
1352
|
+
distance: y,
|
|
1272
1353
|
hours: w
|
|
1273
1354
|
});
|
|
1274
|
-
const
|
|
1275
|
-
return
|
|
1276
|
-
cost:
|
|
1277
|
-
hire:
|
|
1278
|
-
bunker:
|
|
1279
|
-
distance:
|
|
1355
|
+
const g = await W.alternateAnalyse(s, t, a, i, 1, n, o, e), k = g.reduce((h, m) => h + m.cost.total, 0), E = g.reduce((h, m) => h + m.cost.hire, 0), b = g.reduce((h, m) => h + m.cost.bunker, 0), p = g.reduce((h, m) => h + m.distance, 0), f = g.reduce((h, m) => h + m.totalHrs, 0);
|
|
1356
|
+
return j == null || j.info("[%s][L%d] cost with cpb/cpa turn: %j", e.requestId, e.level, {
|
|
1357
|
+
cost: k,
|
|
1358
|
+
hire: E,
|
|
1359
|
+
bunker: b,
|
|
1360
|
+
distance: p,
|
|
1280
1361
|
hours: f
|
|
1281
|
-
}),
|
|
1362
|
+
}), u < k ? { combined: !0, cost: Math.round(u * 1e3) / 1e3, speeds: r, step: o } : { combined: !0, cost: Math.round(k * 1e3) / 1e3, speeds: g, step: o };
|
|
1282
1363
|
}
|
|
1283
1364
|
/**
|
|
1284
1365
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1292,47 +1373,47 @@ class W {
|
|
|
1292
1373
|
* @param options
|
|
1293
1374
|
*/
|
|
1294
1375
|
static async alternateAnalyse(s, t, a, i, n, o, e, r = {}) {
|
|
1295
|
-
var
|
|
1296
|
-
let
|
|
1297
|
-
const
|
|
1298
|
-
for (;
|
|
1299
|
-
const
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
b,
|
|
1303
|
-
t,
|
|
1376
|
+
var y, w;
|
|
1377
|
+
let u = v.utc(s.etd);
|
|
1378
|
+
const l = { lat: s.lat, lng: s.lng }, d = [];
|
|
1379
|
+
for (; u.isBefore(a); ) {
|
|
1380
|
+
const g = u.clone().utc().add(e, "day"), k = JSON.parse(JSON.stringify(o.route)), E = JSON.parse(JSON.stringify(o.waypoints)), b = i[n], p = await W.analyseInstantWithThreshed(
|
|
1381
|
+
l,
|
|
1382
|
+
u.utc().format(),
|
|
1304
1383
|
g,
|
|
1305
|
-
|
|
1306
|
-
|
|
1384
|
+
t,
|
|
1385
|
+
b,
|
|
1386
|
+
k,
|
|
1387
|
+
E,
|
|
1307
1388
|
s.meteoVendor,
|
|
1308
1389
|
s.speedStep,
|
|
1309
1390
|
s.useMeteo,
|
|
1310
1391
|
s.useRouteParam,
|
|
1311
1392
|
r
|
|
1312
1393
|
);
|
|
1313
|
-
|
|
1394
|
+
p && (await W.calculateCost(p, b, s, r), j == null || j.info(
|
|
1314
1395
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1315
1396
|
r.requestId,
|
|
1316
1397
|
r.level,
|
|
1317
1398
|
r.counter,
|
|
1318
|
-
|
|
1319
|
-
|
|
1399
|
+
u.utc().format(),
|
|
1400
|
+
g.utc().format(),
|
|
1320
1401
|
{
|
|
1321
|
-
cost:
|
|
1322
|
-
hire:
|
|
1323
|
-
bunker:
|
|
1324
|
-
distance:
|
|
1325
|
-
hours:
|
|
1326
|
-
cp: `${
|
|
1402
|
+
cost: p.cost.total,
|
|
1403
|
+
hire: p.cost.hire,
|
|
1404
|
+
bunker: p.cost.bunker,
|
|
1405
|
+
distance: p.distance,
|
|
1406
|
+
hours: p.totalHrs,
|
|
1407
|
+
cp: `${b.speed}/${b.fo}/${b.dgo}`
|
|
1327
1408
|
}
|
|
1328
1409
|
)), r.counter = r.counter + 1;
|
|
1329
|
-
const f = (w = (
|
|
1410
|
+
const f = (w = (y = p == null ? void 0 : p.sample) == null ? void 0 : y.hours) == null ? void 0 : w.at(-1);
|
|
1330
1411
|
if (f)
|
|
1331
|
-
|
|
1412
|
+
l.lat = f.lat, l.lng = f.lng, u = v(f.eta), d.push(p), n = n ? 0 : 1;
|
|
1332
1413
|
else
|
|
1333
1414
|
break;
|
|
1334
1415
|
}
|
|
1335
|
-
return
|
|
1416
|
+
return d;
|
|
1336
1417
|
}
|
|
1337
1418
|
/**
|
|
1338
1419
|
* 计算Speed的cost
|
|
@@ -1344,12 +1425,12 @@ class W {
|
|
|
1344
1425
|
static async calculateCost(s, t, a, i = {}) {
|
|
1345
1426
|
var n;
|
|
1346
1427
|
if (s) {
|
|
1347
|
-
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round((a.dailyHire || 0) * (s.suspend || 0) / 24 * 1e3) / 1e3, r = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3 + e,
|
|
1428
|
+
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round((a.dailyHire || 0) * (s.suspend || 0) / 24 * 1e3) / 1e3, r = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3 + e, u = Math.round(s.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, l = Math.round((s.totalDgoCons + (((n = s.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
|
|
1348
1429
|
s.cost = {
|
|
1349
|
-
total: Math.round((r +
|
|
1430
|
+
total: Math.round((r + u + l) * 1e3) / 1e3,
|
|
1350
1431
|
hire: Math.round(r * 1e3) / 1e3,
|
|
1351
1432
|
suspendHire: e,
|
|
1352
|
-
bunker: Math.round((
|
|
1433
|
+
bunker: Math.round((u + l) * 1e3) / 1e3,
|
|
1353
1434
|
cp: t
|
|
1354
1435
|
};
|
|
1355
1436
|
}
|
|
@@ -1360,16 +1441,16 @@ class W {
|
|
|
1360
1441
|
*
|
|
1361
1442
|
*/
|
|
1362
1443
|
static async calculateECA(s, t, a = {}) {
|
|
1363
|
-
var r,
|
|
1444
|
+
var r, u, l, d;
|
|
1364
1445
|
const i = await V.intersectInECA((s == null ? void 0 : s.route) || []);
|
|
1365
1446
|
let n = 0, o = 0, e = 0;
|
|
1366
|
-
(
|
|
1367
|
-
|
|
1447
|
+
(u = (r = s == null ? void 0 : s.sample) == null ? void 0 : r.wps) == null || u.forEach((y) => {
|
|
1448
|
+
y.positionTime = v.utc(y.etd || y.eta).unix();
|
|
1368
1449
|
});
|
|
1369
|
-
for (const
|
|
1370
|
-
n +=
|
|
1371
|
-
const w = await V.deadReckoningTime((
|
|
1372
|
-
|
|
1450
|
+
for (const y of i) {
|
|
1451
|
+
n += y.distance;
|
|
1452
|
+
const w = await V.deadReckoningTime((l = y.waypoints) == null ? void 0 : l.at(0), s.sample.all || s.sample.wps), g = await V.deadReckoningTime((d = y.waypoints) == null ? void 0 : d.at(-1), s.sample.all || s.sample.wps);
|
|
1453
|
+
y.in = w, y.out = g, y.totalHrs = z.roundPrecision((g.positionTime - w.positionTime) / 3600, 3), y.totalDgoCons = z.roundPrecision(t.fo / 24 * y.totalHrs, 3), o += y.totalHrs, e += y.totalDgoCons;
|
|
1373
1454
|
}
|
|
1374
1455
|
return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3), e = z.roundPrecision(e, 3), {
|
|
1375
1456
|
distanceInECA: n,
|
|
@@ -1384,54 +1465,54 @@ class W {
|
|
|
1384
1465
|
* @param options
|
|
1385
1466
|
*/
|
|
1386
1467
|
static async mergeSpeeds(s, t = {}) {
|
|
1387
|
-
var f,
|
|
1468
|
+
var f, h;
|
|
1388
1469
|
const a = {
|
|
1389
1470
|
hours: [],
|
|
1390
1471
|
wps: [],
|
|
1391
1472
|
days: []
|
|
1392
|
-
}, i = s.reduce((
|
|
1473
|
+
}, i = s.reduce((m, c) => m + c.distance, 0), n = s.reduce((m, c) => {
|
|
1393
1474
|
var I;
|
|
1394
|
-
return
|
|
1395
|
-
}, 0), o = s.reduce((
|
|
1475
|
+
return m + (((I = c.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1476
|
+
}, 0), o = s.reduce((m, c) => m + c.totalHrs, 0), e = s.reduce((m, c) => {
|
|
1396
1477
|
var I;
|
|
1397
|
-
return
|
|
1398
|
-
}, 0), r = s.reduce((
|
|
1478
|
+
return m + (((I = c.extend) == null ? void 0 : I.hoursInECA) || 0);
|
|
1479
|
+
}, 0), r = s.reduce((m, c) => {
|
|
1399
1480
|
var I;
|
|
1400
|
-
return
|
|
1401
|
-
}, 0),
|
|
1402
|
-
let
|
|
1403
|
-
for (const
|
|
1404
|
-
|
|
1405
|
-
const
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
}), I.at(0).distanceFromPrevious =
|
|
1409
|
-
|
|
1410
|
-
}),
|
|
1411
|
-
|
|
1412
|
-
})),
|
|
1413
|
-
const q = [
|
|
1414
|
-
D === -1 ? (
|
|
1415
|
-
var
|
|
1416
|
-
((
|
|
1481
|
+
return m + (((I = c.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1482
|
+
}, 0), u = s.reduce((m, c) => m + c.wxFactor * c.totalHrs / o, 0), l = s.reduce((m, c) => m + c.cFactor * c.totalHrs / o, 0), d = s.reduce((m, c) => m + c.totalFoCons, 0), y = s.reduce((m, c) => m + c.totalDgoCons, 0), w = s.reduce((m, c) => m + c.cost.total, 0), g = s.reduce((m, c) => m + c.cost.hire, 0), k = s.reduce((m, c) => m + c.cost.bunker, 0), E = [], b = [];
|
|
1483
|
+
let p;
|
|
1484
|
+
for (const m of s) {
|
|
1485
|
+
b.push(...((f = m.extend) == null ? void 0 : f.eca) || []);
|
|
1486
|
+
const c = m.sample.hours, I = m.sample.wps, C = m.sample.days, F = c.at(0);
|
|
1487
|
+
p && (F.distanceFromPrevious = p.distanceFromPrevious, F.distanceFromStart = p.distanceFromStart, c.forEach((T, N) => {
|
|
1488
|
+
N && (T.distanceFromStart = T.distanceFromStart + p.distanceFromStart);
|
|
1489
|
+
}), I.at(0).distanceFromPrevious = p.distanceFromPrevious, I.at(0).distanceFromStart = p.distanceFromStart, I.forEach((T, N) => {
|
|
1490
|
+
N && (T.distanceFromStart = T.distanceFromStart + p.distanceFromStart);
|
|
1491
|
+
}), C.at(0).distanceFromPrevious = p.distanceFromPrevious, C.at(0).distanceFromStart = p.distanceFromStart, C.forEach((T, N) => {
|
|
1492
|
+
N && (T.distanceFromStart = T.distanceFromStart + p.distanceFromStart);
|
|
1493
|
+
})), F.cp = m.cost.cp;
|
|
1494
|
+
const q = [m.etd, m.eta], D = E.findIndex((T) => T.id === F.cp.id);
|
|
1495
|
+
D === -1 ? (F.cp.segment = [q], E.push(F.cp)) : E[D].segment.push(q), c.forEach((T) => {
|
|
1496
|
+
var L;
|
|
1497
|
+
((L = a.hours) == null ? void 0 : L.findIndex((O) => O.eta === T.eta)) === -1 && a.hours.push(T);
|
|
1417
1498
|
}), I.forEach((T) => {
|
|
1418
|
-
var
|
|
1419
|
-
((
|
|
1420
|
-
}),
|
|
1421
|
-
var
|
|
1422
|
-
((
|
|
1499
|
+
var L;
|
|
1500
|
+
((L = a.wps) == null ? void 0 : L.findIndex((O) => O.eta === T.eta)) === -1 && a.wps.push(T);
|
|
1501
|
+
}), C.forEach((T) => {
|
|
1502
|
+
var L;
|
|
1503
|
+
((L = a == null ? void 0 : a.days) == null ? void 0 : L.findIndex((O) => O.eta === T.eta)) === -1 && a.days.push(T);
|
|
1423
1504
|
});
|
|
1424
|
-
const H = (
|
|
1425
|
-
H === -1 ? a.wps.push(
|
|
1505
|
+
const H = (h = a.wps) == null ? void 0 : h.findIndex((T) => T.eta === F.eta);
|
|
1506
|
+
H === -1 ? a.wps.push(F) : a.wps[H] = F, p = c.at(-1);
|
|
1426
1507
|
}
|
|
1427
|
-
return a.wps.sort((
|
|
1428
|
-
|
|
1429
|
-
}), a.wps.forEach((
|
|
1430
|
-
const I = a.wps[
|
|
1508
|
+
return a.wps.sort((m, c) => {
|
|
1509
|
+
v(m.etd).unix() - v(c.etd).unix();
|
|
1510
|
+
}), a.wps.forEach((m, c) => {
|
|
1511
|
+
const I = a.wps[c - 1];
|
|
1431
1512
|
if (I) {
|
|
1432
|
-
const
|
|
1433
|
-
|
|
1434
|
-
const D = V.calculateBearing(I,
|
|
1513
|
+
const C = m.distanceFromStart - (I.distanceFromStart || 0), F = v(m.eta || m.etd).diff(v(I.etd || I.eta), "hour", !0), q = Math.round(C / F * 100) / 100;
|
|
1514
|
+
m.avgSpd = q;
|
|
1515
|
+
const D = V.calculateBearing(I, m);
|
|
1435
1516
|
I.bearing = D;
|
|
1436
1517
|
}
|
|
1437
1518
|
}), {
|
|
@@ -1445,18 +1526,18 @@ class W {
|
|
|
1445
1526
|
distance: Math.round(i * 1e3) / 1e3,
|
|
1446
1527
|
totalHrs: Math.round(o * 1e3) / 1e3,
|
|
1447
1528
|
avgSpeed: Math.round(i / o * 1e3) / 1e3,
|
|
1448
|
-
wxFactor: Math.round(
|
|
1449
|
-
cFactor: Math.round(
|
|
1450
|
-
totalFoCons: Math.round(
|
|
1451
|
-
totalDgoCons: Math.round(
|
|
1529
|
+
wxFactor: Math.round(u * 1e3) / 1e3,
|
|
1530
|
+
cFactor: Math.round(l * 1e3) / 1e3,
|
|
1531
|
+
totalFoCons: Math.round(d * 1e3) / 1e3,
|
|
1532
|
+
totalDgoCons: Math.round(y * 1e3) / 1e3,
|
|
1452
1533
|
cost: {
|
|
1453
1534
|
total: Math.round(w * 1e3) / 1e3,
|
|
1454
|
-
hire: Math.round(
|
|
1455
|
-
bunker: Math.round(
|
|
1535
|
+
hire: Math.round(g * 1e3) / 1e3,
|
|
1536
|
+
bunker: Math.round(k * 1e3) / 1e3
|
|
1456
1537
|
},
|
|
1457
1538
|
extend: {
|
|
1458
|
-
cps:
|
|
1459
|
-
eca:
|
|
1539
|
+
cps: E,
|
|
1540
|
+
eca: b,
|
|
1460
1541
|
distanceInECA: Math.round(n * 1e3) / 1e3,
|
|
1461
1542
|
hoursInECA: Math.round(e * 1e3) / 1e3,
|
|
1462
1543
|
totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
|
|
@@ -1467,13 +1548,13 @@ class W {
|
|
|
1467
1548
|
}
|
|
1468
1549
|
export {
|
|
1469
1550
|
nt as AISImpl,
|
|
1470
|
-
|
|
1551
|
+
gt as AlertHelper,
|
|
1471
1552
|
Mt as AlertLevel,
|
|
1472
|
-
|
|
1553
|
+
Nt as HifleetImpl,
|
|
1473
1554
|
vt as LoadCondition,
|
|
1474
1555
|
Dt as MyShipImpl,
|
|
1475
|
-
|
|
1476
|
-
|
|
1556
|
+
Ft as MyVesselImpl,
|
|
1557
|
+
xt as ShipxyImpl,
|
|
1477
1558
|
W as SpeedHelper,
|
|
1478
1559
|
wt as SpeedLabel,
|
|
1479
1560
|
pt as VesselTag,
|