@idm-plugin/vessel 3.4.1 → 3.4.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 +562 -562
- package/dist/index.umd.cjs +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
var ht = Object.defineProperty;
|
|
2
2
|
var lt = (E, s, t) => s in E ? ht(E, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : E[s] = t;
|
|
3
3
|
var U = (E, s, t) => (lt(E, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
|
-
import
|
|
4
|
+
import B from "got";
|
|
5
5
|
import ct from "@log4js-node/log4js-api";
|
|
6
|
-
import
|
|
7
|
-
import { LngLatHelper as z, LaneHelper as
|
|
6
|
+
import v from "moment";
|
|
7
|
+
import { LngLatHelper as z, LaneHelper as V } from "@idm-plugin/geo2";
|
|
8
8
|
import { MeteoHelper2 as mt } from "@idm-plugin/meteo2";
|
|
9
|
-
import { Meteo2Assist as
|
|
10
|
-
let
|
|
9
|
+
import { Meteo2Assist as rt } from "@idm-plugin/meteo";
|
|
10
|
+
let y;
|
|
11
11
|
try {
|
|
12
|
-
|
|
12
|
+
y = ct.getLogger("vessel");
|
|
13
13
|
} catch {
|
|
14
14
|
} finally {
|
|
15
15
|
}
|
|
16
|
-
class
|
|
16
|
+
class at {
|
|
17
17
|
/**
|
|
18
18
|
* 解析AIS状态码
|
|
19
19
|
* @param status
|
|
@@ -54,7 +54,7 @@ class st {
|
|
|
54
54
|
return { labelCn: t, labelEn: a };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class Tt extends at {
|
|
58
58
|
constructor(t, a) {
|
|
59
59
|
super();
|
|
60
60
|
U(this, "clientId");
|
|
@@ -69,19 +69,19 @@ class Ft extends st {
|
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
}, n = await
|
|
73
|
-
|
|
72
|
+
}, n = await B.post(a, i).json();
|
|
73
|
+
y == null || y.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
|
* 模糊查询
|
|
@@ -89,20 +89,20 @@ class Ft extends st {
|
|
|
89
89
|
* @param options
|
|
90
90
|
*/
|
|
91
91
|
async suggest(t, a = {}) {
|
|
92
|
-
var e,
|
|
92
|
+
var e, r;
|
|
93
93
|
await this.checkToken(a);
|
|
94
94
|
const i = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy", n = {
|
|
95
95
|
headers: {
|
|
96
|
-
Authorization: `${(e = this.token) == null ? void 0 : e.tokenType} ${(
|
|
96
|
+
Authorization: `${(e = this.token) == null ? void 0 : e.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
97
97
|
},
|
|
98
98
|
json: {
|
|
99
99
|
kw: t,
|
|
100
100
|
recordNum: a.ps || 10
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
|
|
104
|
-
const o = await
|
|
105
|
-
return o.status !== 200 ? (
|
|
103
|
+
y == null || y.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, i, n);
|
|
104
|
+
const o = await B.post(i, n).json();
|
|
105
|
+
return o.status !== 200 ? (y == null || y.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), []) : (o.data || []).map((h) => ({
|
|
106
106
|
mmsi: h.mmsi,
|
|
107
107
|
name: h.nameEn,
|
|
108
108
|
nameCn: h.nameCn,
|
|
@@ -120,80 +120,80 @@ class Ft extends st {
|
|
|
120
120
|
* @param options
|
|
121
121
|
*/
|
|
122
122
|
async search(t, a = {}) {
|
|
123
|
-
var
|
|
123
|
+
var d, h;
|
|
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: `${(d = this.token) == null ? void 0 : d.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
|
|
128
128
|
},
|
|
129
129
|
searchParams: o
|
|
130
130
|
};
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
if (
|
|
134
|
-
return
|
|
131
|
+
y == null || y.info("[%s] fetch vessel from: %s - %j", a.requestId, n, e);
|
|
132
|
+
const r = await B.get(n, e).json();
|
|
133
|
+
if (r.status !== 200)
|
|
134
|
+
return y == null || y.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 c = r.data;
|
|
137
|
+
if (c)
|
|
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: c.mmsi,
|
|
140
|
+
imo: Number.isNaN(c.imo) ? null : Number(c.imo),
|
|
141
|
+
callSign: c.callsign,
|
|
142
|
+
name: c.nameEn,
|
|
143
|
+
nameCn: c.nameCn,
|
|
144
|
+
type: c.vesselTypeNameEn,
|
|
145
|
+
flagName: c.flagCtry,
|
|
146
|
+
clasz: c.classSociety,
|
|
147
|
+
dateOfBuild: c.buildYearMonth,
|
|
148
|
+
deadweight: c.dwt,
|
|
149
|
+
grossTonnage: c.grt,
|
|
150
|
+
netTonnage: c.net,
|
|
151
|
+
teu: c.teu,
|
|
152
|
+
length: c.length,
|
|
153
|
+
breadth: c.width,
|
|
154
|
+
height: c.height,
|
|
155
|
+
draught: c.draught,
|
|
156
|
+
speed: c.speed,
|
|
157
|
+
passengerCapacity: c.passengercapacity,
|
|
158
158
|
vendor: "myvessel",
|
|
159
|
-
raw:
|
|
159
|
+
raw: c
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
162
|
return {};
|
|
163
163
|
}
|
|
164
164
|
async archives(t, a = {}) {
|
|
165
|
-
var e,
|
|
165
|
+
var e, r;
|
|
166
166
|
await this.checkToken(a);
|
|
167
167
|
const i = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch", n = {
|
|
168
168
|
headers: {
|
|
169
|
-
Authorization: `${(e = this.token) == null ? void 0 : e.tokenType} ${(
|
|
169
|
+
Authorization: `${(e = this.token) == null ? void 0 : e.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
170
170
|
},
|
|
171
171
|
json: {
|
|
172
172
|
mmsiList: typeof t == "number" ? [t] : t
|
|
173
173
|
}
|
|
174
174
|
};
|
|
175
|
-
|
|
176
|
-
const o = await
|
|
177
|
-
return o.status !== 200 ? (
|
|
175
|
+
y == null || y.info("[%s] fetch vessel archive from: %s - %j", a.requestId, i, n);
|
|
176
|
+
const o = await B.post(i, n).json();
|
|
177
|
+
return o.status !== 200 ? (y == null || y.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
|
|
180
|
+
var r, d;
|
|
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: `${(
|
|
184
|
+
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(d = this.token) == null ? void 0 : d.accessToken}`
|
|
185
185
|
},
|
|
186
186
|
searchParams: { mmsi: t }
|
|
187
187
|
};
|
|
188
|
-
|
|
189
|
-
const o = await
|
|
188
|
+
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
|
|
189
|
+
const o = await B.get(i, n).json();
|
|
190
190
|
if (o.code)
|
|
191
|
-
return
|
|
191
|
+
return y == null || y.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
193
|
for (const h in e)
|
|
194
194
|
!isNaN(e[h]) && Number(e[h]) !== 1 / 0 && (e[h] = Number(e[h]));
|
|
195
195
|
if (e) {
|
|
196
|
-
const h =
|
|
196
|
+
const h = 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,7 +208,7 @@ class Ft extends st {
|
|
|
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
213
|
positionTime: h.unix(),
|
|
214
214
|
status: e.status,
|
|
@@ -229,11 +229,11 @@ class Ft extends st {
|
|
|
229
229
|
return {};
|
|
230
230
|
}
|
|
231
231
|
async calculateRoute(t, a, i = {}) {
|
|
232
|
-
var
|
|
232
|
+
var r, d;
|
|
233
233
|
await this.checkToken(i);
|
|
234
234
|
const n = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", o = {
|
|
235
235
|
headers: {
|
|
236
|
-
Authorization: `${(
|
|
236
|
+
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(d = this.token) == null ? void 0 : d.accessToken}`
|
|
237
237
|
},
|
|
238
238
|
json: {
|
|
239
239
|
startPoint: {
|
|
@@ -249,22 +249,22 @@ class Ft extends st {
|
|
|
249
249
|
withECA: i.withECA || !1
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
|
-
|
|
253
|
-
const e = await
|
|
254
|
-
return e.status !== 200 ? (
|
|
252
|
+
y == null || y.info("[%s] fetch route from: %s - %j", i.requestId, n, o);
|
|
253
|
+
const e = await B.post(n, o).json();
|
|
254
|
+
return e.status !== 200 ? (y == null || y.warn("[%s] fetch route failed: %j", i.requestId, { message: e.message, status: e.status, code: e.code }), {}) : e.data;
|
|
255
255
|
}
|
|
256
256
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
257
257
|
await this.checkToken(e);
|
|
258
|
-
const
|
|
259
|
-
for (; h.diff(
|
|
260
|
-
await this.trajectoryIn30Day(t,
|
|
261
|
-
return await this.trajectoryIn30Day(t,
|
|
258
|
+
const r = await this.realTimePosition(t, e), d = v(a), h = v(i), c = [];
|
|
259
|
+
for (; h.diff(d, "day", !0) > 30; )
|
|
260
|
+
await this.trajectoryIn30Day(t, d, d.clone().add(30, "day"), r, n, c, e), d.add(30, "day");
|
|
261
|
+
return await this.trajectoryIn30Day(t, d, h, r, n, c, e), c;
|
|
262
262
|
}
|
|
263
|
-
async trajectoryIn30Day(t, a, i, n, o, e,
|
|
264
|
-
var
|
|
265
|
-
const
|
|
263
|
+
async trajectoryIn30Day(t, a, i, n, o, e, r = {}) {
|
|
264
|
+
var b, j, T, g, p;
|
|
265
|
+
const d = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
|
|
266
266
|
headers: {
|
|
267
|
-
Authorization: `${(
|
|
267
|
+
Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(j = this.token) == null ? void 0 : j.accessToken}`
|
|
268
268
|
},
|
|
269
269
|
json: {
|
|
270
270
|
mmsi: t,
|
|
@@ -272,39 +272,39 @@ class Ft extends st {
|
|
|
272
272
|
endTime: i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
273
273
|
}
|
|
274
274
|
};
|
|
275
|
-
|
|
276
|
-
const
|
|
277
|
-
if (
|
|
278
|
-
return
|
|
279
|
-
let
|
|
280
|
-
const
|
|
281
|
-
return (
|
|
282
|
-
for (const
|
|
283
|
-
!isNaN(
|
|
284
|
-
const
|
|
285
|
-
mmsi:
|
|
275
|
+
y == null || y.info("[%s] fetch trajectory from: %s - %j", r.requestId, d, h);
|
|
276
|
+
const c = await B.post(d, h).json();
|
|
277
|
+
if (c.code)
|
|
278
|
+
return y == null || y.warn("[%s] fetch trajectory failed: %j", r.requestId, d, { message: c.message, status: c.status, code: c.code }), c;
|
|
279
|
+
let M = -1;
|
|
280
|
+
const w = v(`${(g = (T = c.data) == null ? void 0 : T[0]) == null ? void 0 : g.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
281
|
+
return (p = c.data) == null || p.forEach((f) => {
|
|
282
|
+
for (const H in f)
|
|
283
|
+
!isNaN(f[H]) && Number(f[H]) !== 1 / 0 && (f[H] = Number(f[H]));
|
|
284
|
+
const u = v(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), l = f.status, { labelCn: m, labelEn: I } = this.parseStatus(l), k = {
|
|
285
|
+
mmsi: f.mmsi,
|
|
286
286
|
imo: n == null ? void 0 : n.imo,
|
|
287
|
-
lat:
|
|
288
|
-
lng:
|
|
289
|
-
sog:
|
|
290
|
-
cog:
|
|
291
|
-
hdg:
|
|
292
|
-
draught:
|
|
293
|
-
status:
|
|
294
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(
|
|
295
|
-
destination:
|
|
296
|
-
positionTime:
|
|
297
|
-
labelCn:
|
|
298
|
-
labelEn:
|
|
287
|
+
lat: f.lat,
|
|
288
|
+
lng: f.lon,
|
|
289
|
+
sog: f.sog,
|
|
290
|
+
cog: f.cog,
|
|
291
|
+
hdg: f.hdg,
|
|
292
|
+
draught: f.draught,
|
|
293
|
+
status: l,
|
|
294
|
+
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
|
+
destination: f.dest,
|
|
296
|
+
positionTime: u.unix(),
|
|
297
|
+
labelCn: m,
|
|
298
|
+
labelEn: I,
|
|
299
299
|
method: "trajectory",
|
|
300
300
|
vendor: "myVessel",
|
|
301
|
-
utc:
|
|
302
|
-
},
|
|
303
|
-
|
|
301
|
+
utc: u.utc().format()
|
|
302
|
+
}, F = Math.floor(u.diff(w, "minute", !0) / (o || 1));
|
|
303
|
+
F !== M && (M = F, e.push(k));
|
|
304
304
|
}), e;
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
|
-
class
|
|
307
|
+
class Ft extends at {
|
|
308
308
|
constructor(t) {
|
|
309
309
|
super();
|
|
310
310
|
U(this, "token");
|
|
@@ -316,15 +316,15 @@ class Et extends st {
|
|
|
316
316
|
mmsi: t,
|
|
317
317
|
usertoken: this.token
|
|
318
318
|
}
|
|
319
|
-
}, o = await
|
|
320
|
-
|
|
319
|
+
}, o = await B.post(i, n).json();
|
|
320
|
+
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
|
|
321
321
|
const e = o == null ? void 0 : o.list;
|
|
322
322
|
if (!e)
|
|
323
|
-
return
|
|
324
|
-
for (const
|
|
325
|
-
!isNaN(e[
|
|
323
|
+
return y == null || y.warn("[%s] fetch realtime position failed: %j", a.requestId, i, o), o;
|
|
324
|
+
for (const w in e)
|
|
325
|
+
!isNaN(e[w]) && Number(e[w]) !== 1 / 0 && (e[w] = Number(e[w]));
|
|
326
326
|
e.status = e.sp > 3 ? 0 : 1;
|
|
327
|
-
const
|
|
327
|
+
const r = e.status, { labelCn: d, labelEn: h } = this.parseStatus(r), c = v(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
328
328
|
return {
|
|
329
329
|
mmsi: e.m,
|
|
330
330
|
name: e.n,
|
|
@@ -339,16 +339,16 @@ class Et extends st {
|
|
|
339
339
|
cog: e.co,
|
|
340
340
|
hdg: e.h,
|
|
341
341
|
rot: isNaN(e.rot) ? 0 : e.rot,
|
|
342
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ?
|
|
342
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? v.utc(e.eta).format() : void 0,
|
|
343
343
|
destination: e.destination,
|
|
344
344
|
vesselType: e.type,
|
|
345
345
|
dwt: e.dwt,
|
|
346
346
|
build: e.buildyear,
|
|
347
347
|
flag: e.fn,
|
|
348
|
-
positionTime:
|
|
349
|
-
utc:
|
|
350
|
-
status:
|
|
351
|
-
labelCn:
|
|
348
|
+
positionTime: c.unix(),
|
|
349
|
+
utc: c.utc().format(),
|
|
350
|
+
status: r,
|
|
351
|
+
labelCn: d,
|
|
352
352
|
labelEn: h,
|
|
353
353
|
method: "position",
|
|
354
354
|
vendor: "hifleet"
|
|
@@ -366,10 +366,10 @@ class Et extends st {
|
|
|
366
366
|
Host: "www.hifleet.com"
|
|
367
367
|
}
|
|
368
368
|
};
|
|
369
|
-
let o = await
|
|
370
|
-
|
|
371
|
-
for (const
|
|
372
|
-
!isNaN(o[
|
|
369
|
+
let o = await B.post(i, n).json();
|
|
370
|
+
y == null || y.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]);
|
|
371
|
+
for (const r in o)
|
|
372
|
+
!isNaN(o[r]) && Number(o[r]) !== 1 / 0 && (o[r] = Number(o[r]));
|
|
373
373
|
const e = {
|
|
374
374
|
mmsi: o.m,
|
|
375
375
|
name: o.n,
|
|
@@ -380,7 +380,7 @@ class Et extends st {
|
|
|
380
380
|
draught: o.dr,
|
|
381
381
|
type: o.t
|
|
382
382
|
};
|
|
383
|
-
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await
|
|
383
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(), y == null || y.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
384
|
}
|
|
385
385
|
async suggest(t, a = {}) {
|
|
386
386
|
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
|
|
@@ -392,71 +392,71 @@ class Et extends st {
|
|
|
392
392
|
Origin: "https://www.hifleet.com",
|
|
393
393
|
Host: "www.hifleet.com"
|
|
394
394
|
}
|
|
395
|
-
}, o = await
|
|
396
|
-
|
|
395
|
+
}, o = await B.post(i, n).json();
|
|
396
|
+
y == null || y.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, n);
|
|
397
397
|
const e = [];
|
|
398
|
-
for (const
|
|
398
|
+
for (const r of o)
|
|
399
399
|
e.push({
|
|
400
|
-
mmsi: !
|
|
401
|
-
name:
|
|
402
|
-
callSign:
|
|
403
|
-
imo: !
|
|
404
|
-
score:
|
|
400
|
+
mmsi: !r.mmsi || isNaN(r.mmsi) ? null : Number(r.mmsi),
|
|
401
|
+
name: r.name,
|
|
402
|
+
callSign: r.callsign,
|
|
403
|
+
imo: !r.imo || isNaN(r.imo) ? null : Number(r.imo),
|
|
404
|
+
score: r._score
|
|
405
405
|
});
|
|
406
|
-
return e.sort((
|
|
406
|
+
return e.sort((r, d) => d.score - r.score), e;
|
|
407
407
|
}
|
|
408
408
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
409
|
-
var
|
|
410
|
-
const
|
|
411
|
-
let
|
|
412
|
-
const h =
|
|
409
|
+
var f, u, l;
|
|
410
|
+
const r = await this.realTimePosition(t, e);
|
|
411
|
+
let d = v(a);
|
|
412
|
+
const h = v(i), c = v();
|
|
413
413
|
if (o) {
|
|
414
|
-
let
|
|
415
|
-
|
|
414
|
+
let m = h.diff(d, "d", !0);
|
|
415
|
+
m < 0 ? d = h.clone().subtract(40, "d") : m < 30 ? d.subtract(10, "d") : m < 60 ? d.subtract(5, "d") : d = h.clone().subtract(80, "d"), m = c.diff(h, "d", !0), h.add(m > 10 ? 240 : m * 24, "h");
|
|
416
416
|
}
|
|
417
|
-
const
|
|
417
|
+
const M = {
|
|
418
418
|
searchParams: {
|
|
419
419
|
endtime: h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
420
|
-
starttime:
|
|
420
|
+
starttime: d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
421
421
|
mmsi: t,
|
|
422
422
|
usertoken: this.token
|
|
423
423
|
}
|
|
424
|
-
},
|
|
425
|
-
|
|
424
|
+
}, w = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await B.get(w, M).json();
|
|
425
|
+
y == null || y.info("[%s] fetch trajectory from: %s - %j", e.requestId, w, M);
|
|
426
426
|
let j;
|
|
427
|
-
|
|
428
|
-
const
|
|
429
|
-
let
|
|
430
|
-
const
|
|
431
|
-
for (const
|
|
432
|
-
for (const A in
|
|
433
|
-
!isNaN(
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
const { labelEn:
|
|
437
|
-
mmsi:
|
|
438
|
-
name:
|
|
439
|
-
imo:
|
|
440
|
-
lat:
|
|
441
|
-
lng:
|
|
442
|
-
draught:
|
|
443
|
-
sog:
|
|
444
|
-
cog:
|
|
445
|
-
hdg:
|
|
446
|
-
positionTime:
|
|
447
|
-
utc:
|
|
448
|
-
status:
|
|
449
|
-
labelCn:
|
|
450
|
-
labelEn:
|
|
427
|
+
b && (j = ((u = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : u.ship) || [], j.length || y == null || y.warn("[%s] fetch trajectory failed: %j", e.requestId, b));
|
|
428
|
+
const T = [];
|
|
429
|
+
let g = -1;
|
|
430
|
+
const p = v(`${(l = j == null ? void 0 : j[0]) == null ? void 0 : l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
431
|
+
for (const m of j) {
|
|
432
|
+
for (const A in m)
|
|
433
|
+
!isNaN(m[A]) && Number(m[A]) !== 1 / 0 && (m[A] = Number(m[A]));
|
|
434
|
+
const I = v(`${m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
435
|
+
m.status = m.sp > 4 ? 0 : 1;
|
|
436
|
+
const { labelEn: k, labelCn: F } = this.parseStatus(m.status), H = {
|
|
437
|
+
mmsi: m.m,
|
|
438
|
+
name: m.n,
|
|
439
|
+
imo: r == null ? void 0 : r.imo,
|
|
440
|
+
lat: m.la,
|
|
441
|
+
lng: m.lo,
|
|
442
|
+
draught: m.draught,
|
|
443
|
+
sog: m.sp,
|
|
444
|
+
cog: m.co,
|
|
445
|
+
hdg: m.hdg,
|
|
446
|
+
positionTime: I.unix(),
|
|
447
|
+
utc: I.utc().format(),
|
|
448
|
+
status: m.status,
|
|
449
|
+
labelCn: F,
|
|
450
|
+
labelEn: k,
|
|
451
451
|
method: "trajectory",
|
|
452
452
|
vendor: "hifleet"
|
|
453
|
-
},
|
|
454
|
-
|
|
453
|
+
}, x = Math.floor(I.diff(p, "minute", !0) / (n || 1));
|
|
454
|
+
x !== g && (g = x, T.push(H));
|
|
455
455
|
}
|
|
456
|
-
return
|
|
456
|
+
return T;
|
|
457
457
|
}
|
|
458
458
|
}
|
|
459
|
-
class
|
|
459
|
+
class Et extends at {
|
|
460
460
|
constructor(t) {
|
|
461
461
|
super();
|
|
462
462
|
U(this, "token");
|
|
@@ -469,13 +469,13 @@ class Nt extends st {
|
|
|
469
469
|
k: this.token,
|
|
470
470
|
enc: 1
|
|
471
471
|
}
|
|
472
|
-
}, n = "https://api.shipxy.com/apicall/GetSingleShip", o = await
|
|
473
|
-
if (
|
|
472
|
+
}, n = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(n, i).json();
|
|
473
|
+
if (y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, i), (o == null ? void 0 : o.status) !== 0)
|
|
474
474
|
return o;
|
|
475
475
|
const e = o.data[0];
|
|
476
|
-
for (const
|
|
477
|
-
!isNaN(e[
|
|
478
|
-
const { labelCn:
|
|
476
|
+
for (const M in e)
|
|
477
|
+
!isNaN(e[M]) && Number(e[M]) !== 1 / 0 && (e[M] = Number(e[M]));
|
|
478
|
+
const { labelCn: r, labelEn: d } = await this.parseStatus(e.navistat), h = v.unix(e.lasttime);
|
|
479
479
|
return {
|
|
480
480
|
mmsi: e.ShipID,
|
|
481
481
|
name: e.name,
|
|
@@ -493,47 +493,47 @@ class Nt extends st {
|
|
|
493
493
|
positionTime: e.lasttime,
|
|
494
494
|
utc: h.utc().format(),
|
|
495
495
|
status: e.navistat,
|
|
496
|
-
labelEn:
|
|
497
|
-
labelCn:
|
|
496
|
+
labelEn: d,
|
|
497
|
+
labelCn: r,
|
|
498
498
|
method: "position",
|
|
499
499
|
vendor: "shipxy"
|
|
500
500
|
};
|
|
501
501
|
}
|
|
502
502
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
503
|
-
var
|
|
504
|
-
const
|
|
503
|
+
var p;
|
|
504
|
+
const r = await this.realTimePosition(t, e), d = v(a), h = v(i), c = "https://api.shipxy.com/apicall/GetShipTrack", M = {
|
|
505
505
|
searchParams: {
|
|
506
506
|
id: t,
|
|
507
507
|
k: this.token,
|
|
508
508
|
enc: 1,
|
|
509
509
|
cut: 0,
|
|
510
|
-
btm:
|
|
510
|
+
btm: d.unix(),
|
|
511
511
|
etm: h.unix()
|
|
512
512
|
}
|
|
513
|
-
},
|
|
514
|
-
if (
|
|
515
|
-
return
|
|
516
|
-
const
|
|
517
|
-
let
|
|
518
|
-
for (const
|
|
519
|
-
const
|
|
520
|
-
imo:
|
|
513
|
+
}, w = await B.get(c, M).json();
|
|
514
|
+
if (y == null || y.info("[%s] fetch trajectory from: %s - %j", e.requestId, c, M), (w == null ? void 0 : w.status) !== 0)
|
|
515
|
+
return w;
|
|
516
|
+
const b = w == null ? void 0 : w.points, j = [], T = v.unix((p = b[0]) == null ? void 0 : p.utc);
|
|
517
|
+
let g = -1;
|
|
518
|
+
for (const f of b) {
|
|
519
|
+
const u = v.unix(f.utc), l = {
|
|
520
|
+
imo: r == null ? void 0 : r.imo,
|
|
521
521
|
mmsi: t,
|
|
522
|
-
sog: Math.round(
|
|
523
|
-
cog: Math.round(
|
|
524
|
-
lat: Math.round(
|
|
525
|
-
lng: Math.round(
|
|
526
|
-
positionTime:
|
|
527
|
-
utc:
|
|
522
|
+
sog: Math.round(f.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
523
|
+
cog: Math.round(f.cog / 100 * 100) / 100,
|
|
524
|
+
lat: Math.round(f.lat / 1e6 * 1e5) / 1e5,
|
|
525
|
+
lng: Math.round(f.lon / 1e6 * 1e5) / 1e5,
|
|
526
|
+
positionTime: u.unix(),
|
|
527
|
+
utc: u.utc().format(),
|
|
528
528
|
method: "trajectory",
|
|
529
529
|
vendor: "shipxy"
|
|
530
|
-
},
|
|
531
|
-
|
|
530
|
+
}, m = Math.floor(u.diff(T, "minute", !0) / (n || 1));
|
|
531
|
+
m !== g && (g = m, j.push(l));
|
|
532
532
|
}
|
|
533
533
|
return j;
|
|
534
534
|
}
|
|
535
535
|
}
|
|
536
|
-
class
|
|
536
|
+
class xt extends at {
|
|
537
537
|
constructor(t) {
|
|
538
538
|
super();
|
|
539
539
|
U(this, "token");
|
|
@@ -547,8 +547,8 @@ class Tt extends st {
|
|
|
547
547
|
json: {
|
|
548
548
|
mmsiList: t
|
|
549
549
|
}
|
|
550
|
-
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await
|
|
551
|
-
return
|
|
550
|
+
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await B.post(n, i).json();
|
|
551
|
+
return y == null || y.info("[%s] fetch ship id from: %s - %j", a.requestId, n, i), o.code !== "0" ? o : o.data[0].shipId;
|
|
552
552
|
}
|
|
553
553
|
async getShipInfo(t, a = {}) {
|
|
554
554
|
const i = {
|
|
@@ -558,15 +558,15 @@ class Tt extends st {
|
|
|
558
558
|
json: {
|
|
559
559
|
shipId: t
|
|
560
560
|
}
|
|
561
|
-
}, n = "https://api3.myships.com/sp/ships/aissta", o = await
|
|
562
|
-
if (
|
|
561
|
+
}, n = "https://api3.myships.com/sp/ships/aissta", o = await B.post(n, i).json();
|
|
562
|
+
if (y == null || y.info("[%s] fetch ship info from: %s - %j", a.requestId, n, i), o.code !== "0")
|
|
563
563
|
return o;
|
|
564
564
|
const e = o.data;
|
|
565
|
-
let
|
|
566
|
-
return t === "407170" && (
|
|
565
|
+
let r = e.imo;
|
|
566
|
+
return t === "407170" && (r = "9198379", y == null || y.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, e.imo, r)), {
|
|
567
567
|
mmsi: e.mmsi,
|
|
568
568
|
name: e.shipnameEn,
|
|
569
|
-
imo:
|
|
569
|
+
imo: r,
|
|
570
570
|
callSign: e.callSign,
|
|
571
571
|
length: e.length,
|
|
572
572
|
width: e.breadth,
|
|
@@ -581,38 +581,38 @@ class Tt extends st {
|
|
|
581
581
|
json: {
|
|
582
582
|
shipId: i
|
|
583
583
|
}
|
|
584
|
-
}, e = "https://api3.myships.com/sp/ships/position/latest",
|
|
585
|
-
|
|
586
|
-
const
|
|
587
|
-
for (const
|
|
588
|
-
!isNaN(
|
|
589
|
-
const { labelCn: h, labelEn:
|
|
584
|
+
}, e = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(e, o).json();
|
|
585
|
+
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, e, o);
|
|
586
|
+
const d = r.data[0];
|
|
587
|
+
for (const b in d)
|
|
588
|
+
!isNaN(d[b]) && Number(d[b]) !== 1 / 0 && (d[b] = Number(d[b]));
|
|
589
|
+
const { labelCn: h, labelEn: c } = await this.parseStatus(d.aisNavStatus), M = v.unix(d.posTime);
|
|
590
590
|
return {
|
|
591
591
|
...n,
|
|
592
592
|
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:
|
|
593
|
+
lat: Math.round(d.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
594
|
+
lng: Math.round(d.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
595
|
+
sog: Math.round(d.sog / 10 * 100) / 100,
|
|
596
|
+
cog: Math.round(d.cog / 10 * 100) / 100,
|
|
597
|
+
hdg: Math.round(d.heading * 100) / 100,
|
|
598
|
+
rot: Math.round(d.rot * 100) / 100,
|
|
599
|
+
positionTime: d.posTime,
|
|
600
|
+
utc: M.utc().format(),
|
|
601
|
+
status: d.aisNavStatus,
|
|
602
|
+
labelEn: c,
|
|
603
603
|
labelCn: h,
|
|
604
604
|
method: "position",
|
|
605
605
|
vendor: "myship"
|
|
606
606
|
};
|
|
607
607
|
}
|
|
608
608
|
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
609
|
-
const
|
|
610
|
-
for (;
|
|
611
|
-
await this.trajectoryIn30Day(h,
|
|
612
|
-
return await this.trajectoryIn30Day(h,
|
|
609
|
+
const r = v(a), d = v(i), h = await this.getShipId(t), c = await this.getShipInfo(h), M = [];
|
|
610
|
+
for (; d.diff(r, "day", !0) > 30; )
|
|
611
|
+
await this.trajectoryIn30Day(h, r.unix(), r.add(30, "day").unix(), c, t, n, M);
|
|
612
|
+
return await this.trajectoryIn30Day(h, r.unix(), d.unix(), c, t, n, M), M;
|
|
613
613
|
}
|
|
614
|
-
async trajectoryIn30Day(t, a, i, n, o, e,
|
|
615
|
-
var
|
|
614
|
+
async trajectoryIn30Day(t, a, i, n, o, e, r, d = {}) {
|
|
615
|
+
var T;
|
|
616
616
|
const h = {
|
|
617
617
|
headers: {
|
|
618
618
|
appKey: this.token
|
|
@@ -622,32 +622,32 @@ class Tt extends st {
|
|
|
622
622
|
startTime: a,
|
|
623
623
|
endTime: i
|
|
624
624
|
}
|
|
625
|
-
},
|
|
626
|
-
if (
|
|
627
|
-
return
|
|
628
|
-
const
|
|
629
|
-
for (const
|
|
630
|
-
!isNaN(
|
|
631
|
-
const
|
|
625
|
+
}, c = "https://api3.myships.com/sp/ships/position/history", M = await B.post(c, h).json();
|
|
626
|
+
if (y == null || y.info("[%s] fetch trajectory from: %s - %j", d.requestId, c, h), M.code !== "0")
|
|
627
|
+
return y == null || y.warn("[%s] invoke myship trajectory failed: %j", d.requestId, M), M;
|
|
628
|
+
const w = M.data;
|
|
629
|
+
for (const g in w)
|
|
630
|
+
!isNaN(w[g]) && Number(w[g]) !== 1 / 0 && (w[g] = Number(w[g]));
|
|
631
|
+
const b = v.unix((T = w[0]) == null ? void 0 : T.posTime);
|
|
632
632
|
let j = -1;
|
|
633
|
-
for (const
|
|
634
|
-
const
|
|
633
|
+
for (const g of w) {
|
|
634
|
+
const p = v.unix(g.posTime), f = {
|
|
635
635
|
imo: n == null ? void 0 : n.imo,
|
|
636
636
|
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:
|
|
637
|
+
lat: Math.round(g.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
638
|
+
lng: Math.round(g.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
639
|
+
sog: Math.round(g.sog / 10 * 100) / 100,
|
|
640
|
+
cog: Math.round(g.cog / 10 * 100) / 100,
|
|
641
|
+
hdg: Math.round(g.heading * 100) / 100,
|
|
642
|
+
rot: Math.round(g.rot * 100) / 100,
|
|
643
|
+
positionTime: p.unix(),
|
|
644
|
+
utc: p.utc().format(),
|
|
645
645
|
method: "trajectory",
|
|
646
646
|
vendor: "myship"
|
|
647
|
-
},
|
|
648
|
-
|
|
647
|
+
}, u = Math.floor(p.diff(b, "minute", !0) / (e || 1));
|
|
648
|
+
u !== j && (j = u, r.push(f));
|
|
649
649
|
}
|
|
650
|
-
return
|
|
650
|
+
return r;
|
|
651
651
|
}
|
|
652
652
|
}
|
|
653
653
|
let _;
|
|
@@ -667,20 +667,20 @@ class yt {
|
|
|
667
667
|
* @param options
|
|
668
668
|
*/
|
|
669
669
|
parsePrinciple(s, t = {}) {
|
|
670
|
-
var e,
|
|
670
|
+
var e, r, d;
|
|
671
671
|
_ == null || _.debug("[%s] parse rule: %s", t.requestId, s);
|
|
672
672
|
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
673
|
if (!n)
|
|
674
674
|
return;
|
|
675
675
|
const o = {};
|
|
676
676
|
for (let h = 0; h < (n == null ? void 0 : n.length); h++) {
|
|
677
|
-
const
|
|
678
|
-
if (h === 0 && !
|
|
677
|
+
const c = (d = (r = n[h].match(a)) == null ? void 0 : r[0]) == null ? void 0 : d.split("],");
|
|
678
|
+
if (h === 0 && !c)
|
|
679
679
|
o.scope = n[0];
|
|
680
|
-
else if (
|
|
681
|
-
for (let
|
|
682
|
-
const
|
|
683
|
-
|
|
680
|
+
else if (c)
|
|
681
|
+
for (let M = 0, w = c.length; M < w; M++) {
|
|
682
|
+
const b = this.parseRule(c[M]);
|
|
683
|
+
b && (o[b.level] ? b.key ? o[b.level][b == null ? void 0 : b.key] = b : o[b.level] = b : b.key ? o[b.level] = { [b == null ? void 0 : b.key]: b } : o[b.level] = b);
|
|
684
684
|
}
|
|
685
685
|
}
|
|
686
686
|
return o;
|
|
@@ -713,17 +713,17 @@ class yt {
|
|
|
713
713
|
* @param options
|
|
714
714
|
*/
|
|
715
715
|
checkWeather(s, t, a = {}) {
|
|
716
|
-
var
|
|
716
|
+
var b, j, T, g, p, f, u, l, m, I, k, F, H, x, A;
|
|
717
717
|
let i = 0, n = 0, o = 0, e = 0;
|
|
718
|
-
const
|
|
719
|
-
for (let
|
|
720
|
-
const
|
|
721
|
-
e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...
|
|
718
|
+
const r = Math.round(((j = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, d = (g = (T = t == null ? void 0 : t.SEVERE) == null ? void 0 : T.sigWave) == null ? void 0 : g.number, h = (f = (p = t == null ? void 0 : t.HEAVY) == null ? void 0 : p.sigWave) == null ? void 0 : f.number, c = Math.round((((l = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : l.number) + 2) * 100) / 100, M = (I = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.wind) == null ? void 0 : I.number, w = (F = (k = t == null ? void 0 : t.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : F.number;
|
|
719
|
+
for (let D = 0; D < (s == null ? void 0 : s.length); D++) {
|
|
720
|
+
const N = s[D], Y = (x = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wave) == null ? void 0 : x.sig, L = (A = N == null ? void 0 : N.meteo) == null ? void 0 : A.wind, J = D ? v(N.eta).diff(v(s[D - 1].eta), "hour", !0) : 0;
|
|
721
|
+
e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...Y, dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h }), (Y == null ? void 0 : Y.height) >= r ? N.isDangerous = !0 : (Y == null ? void 0 : Y.height) >= d ? N.isSevere = !0 : (Y == null ? void 0 : Y.height) >= h && (N.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...L, dgThd4Wd: c, svThd4Wd: M, hvThd4Wd: w }), (L == null ? void 0 : L.scale) >= c ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (L == null ? void 0 : L.scale) > M ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (L == null ? void 0 : L.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
722
|
}
|
|
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:
|
|
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: c, svThd4Wd: M, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h } };
|
|
724
724
|
}
|
|
725
725
|
}
|
|
726
|
-
const
|
|
726
|
+
const Nt = new yt();
|
|
727
727
|
let C;
|
|
728
728
|
try {
|
|
729
729
|
C = ct.getLogger("vessel");
|
|
@@ -732,7 +732,7 @@ try {
|
|
|
732
732
|
}
|
|
733
733
|
const Mt = new mt("", !0);
|
|
734
734
|
var bt = /* @__PURE__ */ ((E) => (E.common = "common", E.container = "container", E.tugs = "tugs", E))(bt || {}), gt = /* @__PURE__ */ ((E) => (E.Ballast = "Ballast", E.Laden = "Laden", E))(gt || {}), vt = /* @__PURE__ */ ((E) => (E.Cp = "CP", E.Perf = "Basis", E.Instruct = "Other", E))(vt || {});
|
|
735
|
-
class
|
|
735
|
+
class R {
|
|
736
736
|
/**
|
|
737
737
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
738
738
|
* 方形系数(block coefficient)
|
|
@@ -748,7 +748,7 @@ class O {
|
|
|
748
748
|
static blockCoefficient(s, t, a, i) {
|
|
749
749
|
let n = Math.round(s / (t * a * i) * 100) / 100;
|
|
750
750
|
n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
|
|
751
|
-
const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = o.map((
|
|
751
|
+
const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = o.map((r) => Math.abs(r - n));
|
|
752
752
|
return o[e.indexOf(Math.min(...e))];
|
|
753
753
|
}
|
|
754
754
|
/**
|
|
@@ -845,17 +845,17 @@ class O {
|
|
|
845
845
|
* @private
|
|
846
846
|
*/
|
|
847
847
|
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,
|
|
848
|
+
var M;
|
|
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, d = ((M = s == null ? void 0 : s.type) == null ? void 0 : M.toLowerCase()) || "common";
|
|
850
850
|
return {
|
|
851
|
-
tag:
|
|
851
|
+
tag: d.indexOf("container") > -1 ? "container" : d.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
852
852
|
lbp: n,
|
|
853
853
|
loadCondition: t,
|
|
854
854
|
draught: o,
|
|
855
855
|
breadthMoulded: e,
|
|
856
856
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
857
857
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
858
|
-
displacement: Math.round((
|
|
858
|
+
displacement: Math.round((r / 1.025 + o * e * n * 0.7) * 1e4) / 1e4,
|
|
859
859
|
// 换算为m/s
|
|
860
860
|
speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
861
861
|
bearing: i || 90
|
|
@@ -872,41 +872,41 @@ class O {
|
|
|
872
872
|
* @param useRouteParam true 启用设置速度
|
|
873
873
|
* @param options
|
|
874
874
|
*/
|
|
875
|
-
static async speedLoseAt(s, t, a, i = "", n = 2, o = !0, e = !1,
|
|
876
|
-
let
|
|
875
|
+
static async speedLoseAt(s, t, a, i = "", n = 2, o = !0, e = !1, r = {}) {
|
|
876
|
+
let d;
|
|
877
877
|
if (t.velocity && e && (s.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
|
|
878
878
|
let h;
|
|
879
879
|
try {
|
|
880
880
|
i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
|
|
881
|
-
const { weatherModels:
|
|
882
|
-
...
|
|
881
|
+
const { weatherModels: b, marineModels: j } = await rt.autoPickMeteoModel(i), T = await Mt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
|
|
882
|
+
...r,
|
|
883
883
|
pastDays: 1,
|
|
884
884
|
forecastDays: 1,
|
|
885
|
-
weatherModels:
|
|
885
|
+
weatherModels: b,
|
|
886
886
|
marineModels: j
|
|
887
|
-
}), [
|
|
888
|
-
h =
|
|
889
|
-
} catch (
|
|
890
|
-
C.warn("[%s] meteo2 spot(%j) forecast failed: %s",
|
|
887
|
+
}), [g] = rt.pickHourly(T, a);
|
|
888
|
+
h = rt.toLegacy(g);
|
|
889
|
+
} catch (b) {
|
|
890
|
+
C.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: i }, b);
|
|
891
891
|
}
|
|
892
|
-
const
|
|
893
|
-
|
|
892
|
+
const c = R.currentFactor(s.bearing, h == null ? void 0 : h.current, n), M = R.weatherFactor(s, h, c), w = Math.round((s.speed * 1.943844 + M + c) * 100) / 100;
|
|
893
|
+
d = {
|
|
894
894
|
meteo: { ...h },
|
|
895
|
-
wxFactor:
|
|
896
|
-
cFactor:
|
|
897
|
-
speed: t.velocity && e ? t.velocity :
|
|
895
|
+
wxFactor: M,
|
|
896
|
+
cFactor: c,
|
|
897
|
+
speed: t.velocity && e ? t.velocity : w < 0 ? 1 : w,
|
|
898
898
|
eta: a.utc().format(),
|
|
899
899
|
etd: a.utc().format()
|
|
900
900
|
};
|
|
901
901
|
} else
|
|
902
|
-
|
|
902
|
+
d = {
|
|
903
903
|
wxFactor: 0,
|
|
904
904
|
cFactor: 0,
|
|
905
905
|
speed: t.velocity && e ? t.velocity : Math.round(s.speed * 1.943844 * 100) / 100,
|
|
906
906
|
eta: a.utc().format(),
|
|
907
907
|
etd: a.utc().format()
|
|
908
908
|
};
|
|
909
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
909
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...d, ...t };
|
|
910
910
|
}
|
|
911
911
|
/**
|
|
912
912
|
* 基于步长计算失速样本
|
|
@@ -922,53 +922,53 @@ class O {
|
|
|
922
922
|
* @param options
|
|
923
923
|
* @private
|
|
924
924
|
*/
|
|
925
|
-
static async speedLoseInHoursStep(s, t, a, i, n, o, e = "",
|
|
925
|
+
static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", r = !0, d = !1, h = {}) {
|
|
926
926
|
t.utc();
|
|
927
|
-
const
|
|
928
|
-
let
|
|
929
|
-
for (let
|
|
930
|
-
let
|
|
931
|
-
|
|
932
|
-
const
|
|
933
|
-
if (s.bearing =
|
|
934
|
-
|
|
935
|
-
const k =
|
|
936
|
-
if (i -
|
|
937
|
-
i = i -
|
|
927
|
+
const c = t.clone().add(14, "days"), M = [], w = [], b = [];
|
|
928
|
+
let j = 0, T = 0, g, p;
|
|
929
|
+
for (let f = 0; f < o.length - 1; f++) {
|
|
930
|
+
let u = o[f];
|
|
931
|
+
u.distanceFromStart = Math.round((n + T) * 1e3) / 1e3;
|
|
932
|
+
const l = o[f + 1];
|
|
933
|
+
if (s.bearing = V.calculateBearing(u, l, !l.gcToPrevious), u.bearing = s.bearing, u.suspend && d) {
|
|
934
|
+
u.eta = u.eta || t.utc().format(), u.elapsed = u.elapsed ?? 0;
|
|
935
|
+
const k = u.suspend - u.elapsed;
|
|
936
|
+
if (i - j > k)
|
|
937
|
+
i = i - j - k, t.add(k, "hour"), u.elapsed = u.suspend;
|
|
938
938
|
else {
|
|
939
|
-
const
|
|
940
|
-
|
|
939
|
+
const F = i - j;
|
|
940
|
+
u.elapsed += F, t.add(F, "hour"), i = 0;
|
|
941
941
|
}
|
|
942
|
-
if (C == null || C.info(`[%s] suspend ${
|
|
943
|
-
return
|
|
942
|
+
if (C == null || C.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`, h.requestId, u), i === 0)
|
|
943
|
+
return u.distanceFromPrevious = T, { etd: t, from: p || u, to: u, next: o.filter((F) => F), wps: M, days: w, all: b };
|
|
944
944
|
} else
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
const m =
|
|
948
|
-
let
|
|
949
|
-
if (
|
|
950
|
-
if (
|
|
951
|
-
`[%s] go to %j from %j with ${m}nm, and cost ${
|
|
945
|
+
u.suspend = 0;
|
|
946
|
+
r = t.isAfter(c) ? !1 : r, u = await R.speedLoseAt(s, u, t, e, 0, r, d, h), b.push(u), p = p || u, u.important && M.push(u), t.isSameOrAfter(a) && (w.push(u), a.add(24, "hour"));
|
|
947
|
+
const m = V.calculateDistance(u, l, !l.gcToPrevious);
|
|
948
|
+
let I = Math.round(m / p.speed * 1e5) / 1e5;
|
|
949
|
+
if (j + I < i) {
|
|
950
|
+
if (j += I, t.add(I, "hour"), delete o[f], C == null || C.debug(
|
|
951
|
+
`[%s] go to %j from %j with ${m}nm, and cost ${I} hours`,
|
|
952
952
|
h.requestId,
|
|
953
|
-
{ lat:
|
|
954
|
-
{ lat:
|
|
955
|
-
),
|
|
956
|
-
|
|
953
|
+
{ lat: l.lat, lng: l.lng },
|
|
954
|
+
{ lat: p.lat, lng: p.lng, etd: p.etd }
|
|
955
|
+
), T += m, o.filter((k) => k).length <= 1) {
|
|
956
|
+
g = l, g.eta = t.utc().format(), g.distanceFromPrevious = m, g.distanceFromStart = Math.round((n + T) * 1e4) / 1e4, M.push(g), b.push(g), delete o[f + 1];
|
|
957
957
|
break;
|
|
958
958
|
}
|
|
959
959
|
} else {
|
|
960
|
-
|
|
961
|
-
const k = z.roundPrecision(
|
|
962
|
-
|
|
963
|
-
`[%s] go to %j from %j with ${k}nm, and cost ${
|
|
960
|
+
I = i - j, t.add(I, "hour");
|
|
961
|
+
const k = z.roundPrecision(p.speed * I, 5);
|
|
962
|
+
g = V.calculateCoordinate(u, s.bearing, k, "nauticalmiles", !l.gcToPrevious), g.eta = t.utc().format(), o[f] = g, C == null || C.debug(
|
|
963
|
+
`[%s] go to %j from %j with ${k}nm, and cost ${I} hours`,
|
|
964
964
|
h.requestId,
|
|
965
|
-
{ lat:
|
|
966
|
-
{ lat:
|
|
967
|
-
),
|
|
965
|
+
{ lat: g.lat, lng: g.lng },
|
|
966
|
+
{ lat: u.lat, lng: u.lng, etd: u.etd }
|
|
967
|
+
), T += k, g.distanceFromPrevious = Math.round(T * 1e4) / 1e4, g.distanceFromStart = Math.round((n + T) * 1e4) / 1e4;
|
|
968
968
|
break;
|
|
969
969
|
}
|
|
970
970
|
}
|
|
971
|
-
return { etd: t, from:
|
|
971
|
+
return { etd: t, from: p, to: g, next: o.filter((f) => f), wps: M, days: w, all: b };
|
|
972
972
|
}
|
|
973
973
|
/**
|
|
974
974
|
* 洋流影响因子
|
|
@@ -990,16 +990,16 @@ class O {
|
|
|
990
990
|
* @param cFactor 洋流因子
|
|
991
991
|
*/
|
|
992
992
|
static weatherFactor(s, t, a = 0) {
|
|
993
|
-
var
|
|
993
|
+
var w, b, j, T, g, p, f;
|
|
994
994
|
C == null || C.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
995
|
-
const i =
|
|
996
|
-
let
|
|
997
|
-
|
|
998
|
-
const
|
|
999
|
-
let
|
|
1000
|
-
|
|
1001
|
-
const
|
|
1002
|
-
return C == null || C.debug("wave wx factor = %d",
|
|
995
|
+
const i = R.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = R.froudeNumber(s.speed - n, s.lbp), e = R.amendFactor(i, o, s.loadCondition);
|
|
996
|
+
let r = Math.abs(s.bearing % 360 - (((w = t == null ? void 0 : t.wind) == null ? void 0 : w.degree) % 360 || 0));
|
|
997
|
+
r = r > 180 ? 360 - r : r;
|
|
998
|
+
const d = R.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), h = R.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (j = t == null ? void 0 : t.wind) == null ? void 0 : j.kts);
|
|
999
|
+
let c = d * e * h / 100 * (s.speed - n);
|
|
1000
|
+
c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), C == null || C.debug("wind wx factor = %d", c), r = Math.abs(s.bearing % 360 - (((g = (T = t == null ? void 0 : t.wave) == null ? void 0 : T.sig) == null ? void 0 : g.degree) % 360 || 0)), r = r > 180 ? 360 - r : r;
|
|
1001
|
+
const M = R.waveHeightFactor(((f = (p = t == null ? void 0 : t.wave) == null ? void 0 : p.sig) == null ? void 0 : f.height) ?? 1, r);
|
|
1002
|
+
return C == null || C.debug("wave wx factor = %d", M), c = Math.abs(c) > Math.abs(M) ? c : c * 0.3 + M * 0.7, C == null || C.debug("weather factor = %d", c), c = Math.abs(c) > 3 ? 3 * (Math.abs(c) / c) + Math.abs(c) / c * (Math.abs(c) - 2) * 0.1 : c, Math.round((c || 0) * 100) / 100;
|
|
1003
1003
|
}
|
|
1004
1004
|
/**
|
|
1005
1005
|
* 全程失速分析(走完航程)
|
|
@@ -1014,14 +1014,14 @@ class O {
|
|
|
1014
1014
|
* @param useRouteParam
|
|
1015
1015
|
* @param options
|
|
1016
1016
|
*/
|
|
1017
|
-
static async analyseInstant(s, t, a, i, n, o = "", e = 0,
|
|
1018
|
-
var K, G, X, Q, Z,
|
|
1019
|
-
const
|
|
1017
|
+
static async analyseInstant(s, t, a, i, n, o = "", e = 0, r = !0, d = !1, h = {}) {
|
|
1018
|
+
var K, G, X, Q, Z, $, tt;
|
|
1019
|
+
const c = v().valueOf();
|
|
1020
1020
|
s.lng = z.convertToStdLng(s.lng);
|
|
1021
|
-
const { route:
|
|
1022
|
-
if (((K =
|
|
1021
|
+
const { route: M, waypoints: w } = n.points, b = V.calculateSubRoute(s, M);
|
|
1022
|
+
if (((K = b[0]) == null ? void 0 : K.length) <= 1)
|
|
1023
1023
|
return;
|
|
1024
|
-
const { v0: j, label:
|
|
1024
|
+
const { v0: j, label: T } = s.sog ? {
|
|
1025
1025
|
v0: s.sog,
|
|
1026
1026
|
label: s.label || "Other"
|
|
1027
1027
|
/* Instruct */
|
|
@@ -1029,66 +1029,67 @@ class O {
|
|
|
1029
1029
|
v0: i.speed,
|
|
1030
1030
|
label: "CP"
|
|
1031
1031
|
/* Cp */
|
|
1032
|
-
},
|
|
1033
|
-
|
|
1034
|
-
const
|
|
1032
|
+
}, g = R.assembleProperties(a, i.loadCondition, j, 0), p = w.length ? V.calculateSubWaypoints(s, w) : [];
|
|
1033
|
+
p.forEach((q) => q.important = !0);
|
|
1034
|
+
const f = {
|
|
1035
1035
|
from: { ...s },
|
|
1036
|
-
route:
|
|
1037
|
-
waypoints:
|
|
1036
|
+
route: b,
|
|
1037
|
+
waypoints: p,
|
|
1038
1038
|
v0: j,
|
|
1039
|
-
label:
|
|
1040
|
-
},
|
|
1039
|
+
label: T
|
|
1040
|
+
}, u = {
|
|
1041
1041
|
hours: [],
|
|
1042
1042
|
days: [],
|
|
1043
|
-
wps: []
|
|
1043
|
+
wps: [],
|
|
1044
|
+
all: []
|
|
1044
1045
|
};
|
|
1045
|
-
e || (
|
|
1046
|
-
let
|
|
1047
|
-
t =
|
|
1048
|
-
const
|
|
1049
|
-
for (;
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1046
|
+
e || (V.calculateRouteDistance(b) / i.speed <= 72 ? e = 3 : e = 6);
|
|
1047
|
+
let l = V.simplifyRouteToCoordinates(b, p, 0), m = 0, I = 0, k = 0, F = 0;
|
|
1048
|
+
t = v(t).utc();
|
|
1049
|
+
const H = t.clone();
|
|
1050
|
+
for (; l.length > 0; ) {
|
|
1051
|
+
const q = e - t.hour() % e, W = Math.ceil(t.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, S = await R.speedLoseInHoursStep(
|
|
1052
|
+
g,
|
|
1052
1053
|
t,
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
l,
|
|
1054
|
+
H,
|
|
1055
|
+
W,
|
|
1056
1056
|
m,
|
|
1057
|
+
l,
|
|
1057
1058
|
o,
|
|
1058
|
-
|
|
1059
|
-
|
|
1059
|
+
r,
|
|
1060
|
+
d,
|
|
1060
1061
|
h
|
|
1061
1062
|
);
|
|
1062
|
-
if ((G =
|
|
1063
|
-
const
|
|
1064
|
-
|
|
1063
|
+
if (u.all.push(...S.all), (G = S.from) != null && G.speed && (u.hours.push(S.from), u.wps.push(...S.wps), u.days.push(...S.days)), l = S == null ? void 0 : S.next, !l.length) {
|
|
1064
|
+
const O = await R.speedLoseAt(g, S.to, v(S.to.eta), o, 0, r, d, h);
|
|
1065
|
+
O.bearing = g.bearing, u.hours.push(O), u.all.push(O);
|
|
1065
1066
|
}
|
|
1066
|
-
|
|
1067
|
+
m += Math.round((((X = S == null ? void 0 : S.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
1067
1068
|
}
|
|
1068
|
-
const
|
|
1069
|
-
for (let
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1069
|
+
const x = u.hours;
|
|
1070
|
+
for (let q = 0; q < x.length - 1; q++) {
|
|
1071
|
+
const W = v(x[q + 1].eta).diff(x[q].etd, "hour", !0) || 1;
|
|
1072
|
+
I += (x[q].wxFactor || 0) * W, k += (x[q].cFactor || 0) * W, F += W;
|
|
1072
1073
|
}
|
|
1073
|
-
(Q =
|
|
1074
|
-
|
|
1075
|
-
const
|
|
1076
|
-
if (
|
|
1077
|
-
const
|
|
1078
|
-
|
|
1074
|
+
(Q = u.wps) == null || Q.forEach((q, W) => {
|
|
1075
|
+
q.positionTime = v.utc(q.etd || q.eta).unix();
|
|
1076
|
+
const S = u.wps[W - 1];
|
|
1077
|
+
if (S) {
|
|
1078
|
+
const O = q.distanceFromStart - S.distanceFromStart, P = v(q.eta || q.etd).diff(v(S.etd || S.eta), "h", !0);
|
|
1079
|
+
q.avgSpd = Math.round(O / P * 100) / 100, S.bearing = V.calculateBearing(S, q);
|
|
1079
1080
|
}
|
|
1080
|
-
}),
|
|
1081
|
-
const A =
|
|
1082
|
-
|
|
1083
|
-
const { distanceInECA:
|
|
1084
|
-
|
|
1081
|
+
}), u.wps = (Z = u.wps) == null ? void 0 : Z.reduce((q, W) => (q.some((S) => Math.round(S.positionTime / 60) === Math.round(W.positionTime / 60)) || q.push(W), q), []), u.all = ($ = u.all) == null ? void 0 : $.reduce((q, W) => (W.positionTime = v.utc(W.etd || W.eta).unix(), q.some((S) => Math.round(S.positionTime / 60) === Math.round(W.positionTime / 60)) || q.push(W), q), []), f.sample = u;
|
|
1082
|
+
const A = u.hours.at(0), D = u.hours.at(-1);
|
|
1083
|
+
f.distance = Math.round(D.distanceFromStart * 1e3) / 1e3, f.etd = v(A.eta).utc().format(), f.eta = v(D.eta).utc().format(), f.wxFactor = Math.round(I / F * 1e3) / 1e3, f.cFactor = Math.round(k / F * 1e3) / 1e3, f.avgSpeed = Math.round(D.distanceFromStart / F * 1e3) / 1e3, f.totalHrs = Math.round(F * 1e3) / 1e3;
|
|
1084
|
+
const { distanceInECA: N, hoursInECA: Y, totalDgoConsInECA: L, eca: J } = await this.calculateECA(f, i, h), et = z.roundPrecision(i.fo / 24 * (F - Y), 3), nt = z.roundPrecision(i.dgo / 24 * F, 3);
|
|
1085
|
+
f.extend = {
|
|
1085
1086
|
eca: J,
|
|
1086
|
-
distanceInECA:
|
|
1087
|
-
hoursInECA:
|
|
1088
|
-
totalDgoConsInECA:
|
|
1089
|
-
},
|
|
1090
|
-
const
|
|
1091
|
-
return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId,
|
|
1087
|
+
distanceInECA: N,
|
|
1088
|
+
hoursInECA: Y,
|
|
1089
|
+
totalDgoConsInECA: L
|
|
1090
|
+
}, f.totalFoCons = et < 0 ? 0 : et, f.totalDgoCons = nt;
|
|
1091
|
+
const st = v().valueOf() - c, it = ((tt = u == null ? void 0 : u.hours) == null ? void 0 : tt.length) || 1;
|
|
1092
|
+
return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, st, it, Math.round(st / it * 1e3) / 1e3), f;
|
|
1092
1093
|
}
|
|
1093
1094
|
/**
|
|
1094
1095
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -1105,11 +1106,11 @@ class O {
|
|
|
1105
1106
|
* @param useRouteParam
|
|
1106
1107
|
* @param options
|
|
1107
1108
|
*/
|
|
1108
|
-
static async analyseInstantWithThreshed(s, t, a, i, n, o, e,
|
|
1109
|
-
var X, Q, Z, $,
|
|
1110
|
-
const
|
|
1109
|
+
static async analyseInstantWithThreshed(s, t, a, i, n, o, e, r = "", d = 3, h = !0, c = !1, M = {}) {
|
|
1110
|
+
var X, Q, Z, $, tt, q, W;
|
|
1111
|
+
const w = v().valueOf();
|
|
1111
1112
|
s.lng = z.convertToStdLng(s.lng);
|
|
1112
|
-
const { v0:
|
|
1113
|
+
const { v0: b, label: j } = s.sog ? {
|
|
1113
1114
|
v0: s.sog,
|
|
1114
1115
|
label: s.label || "Other"
|
|
1115
1116
|
/* Instruct */
|
|
@@ -1117,66 +1118,65 @@ class O {
|
|
|
1117
1118
|
v0: n.speed,
|
|
1118
1119
|
label: "CP"
|
|
1119
1120
|
/* Cp */
|
|
1120
|
-
},
|
|
1121
|
-
if (((X =
|
|
1121
|
+
}, T = R.assembleProperties(i, n.loadCondition, b, 0), g = V.calculateSubRoute(s, o);
|
|
1122
|
+
if (((X = g[0]) == null ? void 0 : X.length) <= 1)
|
|
1122
1123
|
return;
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
let
|
|
1126
|
-
const
|
|
1124
|
+
const p = e.length ? V.calculateSubWaypoints(s, e) : [];
|
|
1125
|
+
p.forEach((S) => S.important = !0);
|
|
1126
|
+
let f = V.simplifyRouteToCoordinates(g, p, 0), u = 0, l = 0, m = 0, I = 0;
|
|
1127
|
+
const k = {
|
|
1127
1128
|
hours: [],
|
|
1128
1129
|
wps: [],
|
|
1129
|
-
days: []
|
|
1130
|
+
days: [],
|
|
1131
|
+
all: []
|
|
1130
1132
|
};
|
|
1131
|
-
t =
|
|
1132
|
-
const
|
|
1133
|
-
for (;
|
|
1134
|
-
const
|
|
1135
|
-
let
|
|
1136
|
-
|
|
1137
|
-
const
|
|
1138
|
-
if ((Q =
|
|
1133
|
+
t = v(t).utc();
|
|
1134
|
+
const F = t.clone();
|
|
1135
|
+
for (; f.length > 0; ) {
|
|
1136
|
+
const S = d - t.hour() % d;
|
|
1137
|
+
let O = Math.ceil(t.clone().add(S, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
1138
|
+
O = t.clone().add(O, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : O;
|
|
1139
|
+
const P = await R.speedLoseInHoursStep(T, t, F, O, u, f, r, h, c, M);
|
|
1140
|
+
if (k.all.push(...P.all), (Q = P.from) != null && Q.speed && (k.hours.push(P.from), P != null && P.wps && k.wps.push(...P.wps), k.days.push(...P.days)), f = P == null ? void 0 : P.next, f.length || k.hours.push(P == null ? void 0 : P.to), u += Math.round((((Z = P == null ? void 0 : P.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !O)
|
|
1139
1141
|
break;
|
|
1140
1142
|
}
|
|
1141
|
-
|
|
1142
|
-
const
|
|
1143
|
-
if (
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1146
|
-
const ut = W.calculateBearing(H, F);
|
|
1147
|
-
H.bearing = ut;
|
|
1143
|
+
k.wps = ($ = k.wps) == null ? void 0 : $.reduce((S, O) => (S.some((P) => Math.round(v(P.etd).unix() / 60) === Math.round(v(O.etd).unix() / 60)) || S.push(O), S), []), k.all = (tt = k.all) == null ? void 0 : tt.reduce((S, O) => (O.positionTime = v.utc(O.etd || O.eta).unix(), S.some((P) => Math.round(v(P.etd).unix() / 60) === Math.round(v(O.etd).unix() / 60)) || S.push(O), S), []), (q = k.wps) == null || q.forEach((S, O) => {
|
|
1144
|
+
const P = k.wps[O - 1];
|
|
1145
|
+
if (P) {
|
|
1146
|
+
const dt = S.distanceFromStart - P.distanceFromStart, ut = v(S.eta || S.etd).diff(v(P.etd || P.eta), "h", !0);
|
|
1147
|
+
S.avgSpd = Math.round(dt / ut * 100) / 100, P.bearing = V.calculateBearing(P, S);
|
|
1148
1148
|
}
|
|
1149
1149
|
});
|
|
1150
|
-
const
|
|
1151
|
-
for (let
|
|
1152
|
-
const
|
|
1153
|
-
|
|
1150
|
+
const H = k.hours;
|
|
1151
|
+
for (let S = 0; S < H.length - 1; S++) {
|
|
1152
|
+
const O = v(H[S + 1].eta).diff(H[S].etd, "hour", !0);
|
|
1153
|
+
l += H[S].wxFactor * O, m += H[S].cFactor * O, I += O;
|
|
1154
1154
|
}
|
|
1155
|
-
const
|
|
1156
|
-
sample:
|
|
1155
|
+
const x = k.hours.at(0), A = k.hours.at(-1), D = await V.calculateRangeRoute(x, A, g), N = await V.calculateRangeWaypoints(x, A, g, p), Y = {
|
|
1156
|
+
sample: k,
|
|
1157
1157
|
distance: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1158
1158
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1159
|
-
etd:
|
|
1160
|
-
eta:
|
|
1161
|
-
wxFactor: Math.round(
|
|
1162
|
-
cFactor: Math.round(
|
|
1163
|
-
avgSpeed: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) /
|
|
1164
|
-
totalHrs: Math.round(
|
|
1165
|
-
from:
|
|
1159
|
+
etd: v(x.eta).utc().format(),
|
|
1160
|
+
eta: v(A == null ? void 0 : A.eta).utc().format(),
|
|
1161
|
+
wxFactor: Math.round(l / I * 1e3) / 1e3,
|
|
1162
|
+
cFactor: Math.round(m / I * 1e3) / 1e3,
|
|
1163
|
+
avgSpeed: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) / I * 1e3) / 1e3,
|
|
1164
|
+
totalHrs: Math.round(I * 1e3) / 1e3,
|
|
1165
|
+
from: x,
|
|
1166
1166
|
to: A,
|
|
1167
|
-
route:
|
|
1168
|
-
waypoints:
|
|
1169
|
-
v0:
|
|
1167
|
+
route: D,
|
|
1168
|
+
waypoints: N,
|
|
1169
|
+
v0: b,
|
|
1170
1170
|
label: j
|
|
1171
|
-
}, { distanceInECA:
|
|
1172
|
-
|
|
1173
|
-
eca:
|
|
1174
|
-
distanceInECA:
|
|
1171
|
+
}, { distanceInECA: L, hoursInECA: J, totalDgoConsInECA: et, eca: nt } = await this.calculateECA(Y, n, M), ot = z.roundPrecision(n.fo / 24 * (I - J), 3), st = z.roundPrecision(n.dgo / 24 * I, 3);
|
|
1172
|
+
Y.extend = {
|
|
1173
|
+
eca: nt,
|
|
1174
|
+
distanceInECA: L,
|
|
1175
1175
|
hoursInECA: J,
|
|
1176
|
-
totalDgoConsInECA:
|
|
1177
|
-
},
|
|
1178
|
-
const K =
|
|
1179
|
-
return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",
|
|
1176
|
+
totalDgoConsInECA: et
|
|
1177
|
+
}, Y.totalDgoCons = st, Y.totalFoCons = ot < 0 ? 0 : ot;
|
|
1178
|
+
const K = v().valueOf() - w, G = ((W = k == null ? void 0 : k.hours) == null ? void 0 : W.length) || 1;
|
|
1179
|
+
return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", M == null ? void 0 : M.requestId, K, G, Math.round(K / G * 1e3) / 1e3), Y;
|
|
1180
1180
|
}
|
|
1181
1181
|
/**
|
|
1182
1182
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1194,58 +1194,58 @@ class O {
|
|
|
1194
1194
|
* @param options
|
|
1195
1195
|
*/
|
|
1196
1196
|
static async analyseCost(s, t, a, i, n = {}) {
|
|
1197
|
-
var
|
|
1198
|
-
const o =
|
|
1197
|
+
var g, p;
|
|
1198
|
+
const o = v().valueOf(), e = [];
|
|
1199
1199
|
s.speedStep = s.speedStep || 3, s.alterStep = s.alterStep ?? 1;
|
|
1200
|
-
const
|
|
1201
|
-
let
|
|
1202
|
-
a.forEach((
|
|
1203
|
-
const
|
|
1204
|
-
|
|
1205
|
-
}),
|
|
1206
|
-
const h =
|
|
1207
|
-
let
|
|
1208
|
-
for (const
|
|
1209
|
-
const
|
|
1200
|
+
const r = V.calculateRouteDistance(i.route);
|
|
1201
|
+
let d = 0;
|
|
1202
|
+
a.forEach((f) => {
|
|
1203
|
+
const u = Math.ceil(r / f.speed / 24);
|
|
1204
|
+
d = d < u ? u : d;
|
|
1205
|
+
}), d = d * 1.3;
|
|
1206
|
+
const h = v.utc(s.etd).add(d ?? 14, "day");
|
|
1207
|
+
let c = 1;
|
|
1208
|
+
for (const f of a) {
|
|
1209
|
+
const u = JSON.parse(JSON.stringify(i.route)), l = JSON.parse(JSON.stringify(i.waypoints)), m = await R.analyseInstantWithThreshed(
|
|
1210
1210
|
{ lat: s.lat, lng: s.lng },
|
|
1211
1211
|
s.etd,
|
|
1212
1212
|
h,
|
|
1213
1213
|
t,
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1214
|
+
f,
|
|
1215
|
+
u,
|
|
1216
|
+
l,
|
|
1217
1217
|
s.meteoVendor,
|
|
1218
1218
|
s.speedStep,
|
|
1219
1219
|
s.useMeteo,
|
|
1220
1220
|
s.useRouteParam,
|
|
1221
1221
|
n
|
|
1222
1222
|
);
|
|
1223
|
-
|
|
1224
|
-
cost:
|
|
1225
|
-
hire:
|
|
1226
|
-
bunker:
|
|
1227
|
-
distance:
|
|
1228
|
-
hours:
|
|
1229
|
-
cp: `${
|
|
1230
|
-
})),
|
|
1223
|
+
m && (await R.calculateCost(m, f, s, n), e.push(m), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, c, s.etd, h.format(), {
|
|
1224
|
+
cost: m.cost.total,
|
|
1225
|
+
hire: m.cost.hire,
|
|
1226
|
+
bunker: m.cost.bunker,
|
|
1227
|
+
distance: m.distance,
|
|
1228
|
+
hours: m.totalHrs,
|
|
1229
|
+
cp: `${f.speed}/${f.fo}/${f.dgo}`
|
|
1230
|
+
})), c++;
|
|
1231
1231
|
}
|
|
1232
|
-
e.sort((
|
|
1233
|
-
const
|
|
1234
|
-
if (
|
|
1235
|
-
const
|
|
1236
|
-
let
|
|
1237
|
-
|
|
1238
|
-
let
|
|
1239
|
-
for (;
|
|
1240
|
-
const A = await
|
|
1241
|
-
if (
|
|
1232
|
+
e.sort((f, u) => f.cost.total - u.cost.total);
|
|
1233
|
+
const M = e.at(0), w = e.at(1), b = [];
|
|
1234
|
+
if (b.push({ combined: !1, speeds: [M], cost: (g = M.cost) == null ? void 0 : g.total }), w) {
|
|
1235
|
+
const f = M.cost.cp, u = w.cost.cp, l = v(M.eta), m = v(M.etd), I = l.diff(m, "days", !0);
|
|
1236
|
+
let k = Math.ceil(I / 2);
|
|
1237
|
+
k = k > 7 ? 7 : k < s.alterStep ? s.alterStep : k;
|
|
1238
|
+
let F = 2, H = { combined: !1, speeds: [w], cost: (p = w.cost) == null ? void 0 : p.total }, x;
|
|
1239
|
+
for (; k >= s.alterStep; ) {
|
|
1240
|
+
const A = await R.combinedAnalyse(s, t, h, [f, u], i, k, { ...n, level: F });
|
|
1241
|
+
if (H.cost > A.cost ? x ? (x == null ? void 0 : x.cost) > A.cost && (x = A) : (x = H, H = A) : (!x || (x == null ? void 0 : x.cost) > A.cost) && (x = A), k <= s.alterStep)
|
|
1242
1242
|
break;
|
|
1243
|
-
|
|
1243
|
+
k = Math.ceil(k / 2), F += 1;
|
|
1244
1244
|
}
|
|
1245
|
-
|
|
1245
|
+
b.push(H), x && b.push(x);
|
|
1246
1246
|
}
|
|
1247
|
-
const
|
|
1248
|
-
return C == null || C.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId,
|
|
1247
|
+
const T = v().valueOf() - o;
|
|
1248
|
+
return C == null || C.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, T), b.sort((f, u) => f.cost - u.cost);
|
|
1249
1249
|
}
|
|
1250
1250
|
/**
|
|
1251
1251
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1259,22 +1259,22 @@ class O {
|
|
|
1259
1259
|
*/
|
|
1260
1260
|
static async combinedAnalyse(s, t, a, i, n, o, e = {}) {
|
|
1261
1261
|
e.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", e.requestId, e.level, o);
|
|
1262
|
-
const
|
|
1262
|
+
const r = await R.alternateAnalyse(s, t, a, i, 0, n, o, e), d = r.reduce((u, l) => u + l.cost.total, 0), h = r.reduce((u, l) => u + l.cost.hire, 0), c = r.reduce((u, l) => u + l.cost.bunker, 0), M = r.reduce((u, l) => u + l.distance, 0), w = r.reduce((u, l) => u + l.totalHrs, 0);
|
|
1263
1263
|
C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j", e.requestId, e.level, {
|
|
1264
|
-
cost:
|
|
1264
|
+
cost: d,
|
|
1265
1265
|
hire: h,
|
|
1266
|
-
bunker:
|
|
1267
|
-
distance:
|
|
1268
|
-
hours:
|
|
1266
|
+
bunker: c,
|
|
1267
|
+
distance: M,
|
|
1268
|
+
hours: w
|
|
1269
1269
|
});
|
|
1270
|
-
const
|
|
1270
|
+
const b = await R.alternateAnalyse(s, t, a, i, 1, n, o, e), j = b.reduce((u, l) => u + l.cost.total, 0), T = b.reduce((u, l) => u + l.cost.hire, 0), g = b.reduce((u, l) => u + l.cost.bunker, 0), p = b.reduce((u, l) => u + l.distance, 0), f = b.reduce((u, l) => u + l.totalHrs, 0);
|
|
1271
1271
|
return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j", e.requestId, e.level, {
|
|
1272
1272
|
cost: j,
|
|
1273
|
-
hire:
|
|
1274
|
-
bunker:
|
|
1275
|
-
distance:
|
|
1276
|
-
hours:
|
|
1277
|
-
}),
|
|
1273
|
+
hire: T,
|
|
1274
|
+
bunker: g,
|
|
1275
|
+
distance: p,
|
|
1276
|
+
hours: f
|
|
1277
|
+
}), d < j ? { combined: !0, cost: Math.round(d * 1e3) / 1e3, speeds: r, step: o } : { combined: !0, cost: Math.round(j * 1e3) / 1e3, speeds: b, step: o };
|
|
1278
1278
|
}
|
|
1279
1279
|
/**
|
|
1280
1280
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1287,48 +1287,48 @@ class O {
|
|
|
1287
1287
|
* @param step 步长,7,4,2,1
|
|
1288
1288
|
* @param options
|
|
1289
1289
|
*/
|
|
1290
|
-
static async alternateAnalyse(s, t, a, i, n, o, e,
|
|
1291
|
-
var
|
|
1292
|
-
let
|
|
1293
|
-
const h = { lat: s.lat, lng: s.lng },
|
|
1294
|
-
for (;
|
|
1295
|
-
const
|
|
1290
|
+
static async alternateAnalyse(s, t, a, i, n, o, e, r = {}) {
|
|
1291
|
+
var M, w;
|
|
1292
|
+
let d = v.utc(s.etd);
|
|
1293
|
+
const h = { lat: s.lat, lng: s.lng }, c = [];
|
|
1294
|
+
for (; d.isBefore(a); ) {
|
|
1295
|
+
const b = d.clone().utc().add(e, "day"), j = JSON.parse(JSON.stringify(o.route)), T = JSON.parse(JSON.stringify(o.waypoints)), g = i[n], p = await R.analyseInstantWithThreshed(
|
|
1296
1296
|
h,
|
|
1297
|
-
|
|
1298
|
-
|
|
1297
|
+
d.utc().format(),
|
|
1298
|
+
b,
|
|
1299
1299
|
t,
|
|
1300
|
-
|
|
1300
|
+
g,
|
|
1301
1301
|
j,
|
|
1302
|
-
|
|
1302
|
+
T,
|
|
1303
1303
|
s.meteoVendor,
|
|
1304
1304
|
s.speedStep,
|
|
1305
1305
|
s.useMeteo,
|
|
1306
1306
|
s.useRouteParam,
|
|
1307
|
-
|
|
1307
|
+
r
|
|
1308
1308
|
);
|
|
1309
|
-
|
|
1309
|
+
p && (await R.calculateCost(p, g, s, r), C == null || C.info(
|
|
1310
1310
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1311
|
+
r.requestId,
|
|
1312
|
+
r.level,
|
|
1313
|
+
r.counter,
|
|
1314
|
+
d.utc().format(),
|
|
1315
|
+
b.utc().format(),
|
|
1316
1316
|
{
|
|
1317
|
-
cost:
|
|
1318
|
-
hire:
|
|
1319
|
-
bunker:
|
|
1320
|
-
distance:
|
|
1321
|
-
hours:
|
|
1322
|
-
cp: `${
|
|
1317
|
+
cost: p.cost.total,
|
|
1318
|
+
hire: p.cost.hire,
|
|
1319
|
+
bunker: p.cost.bunker,
|
|
1320
|
+
distance: p.distance,
|
|
1321
|
+
hours: p.totalHrs,
|
|
1322
|
+
cp: `${g.speed}/${g.fo}/${g.dgo}`
|
|
1323
1323
|
}
|
|
1324
|
-
)),
|
|
1325
|
-
const
|
|
1326
|
-
if (
|
|
1327
|
-
h.lat =
|
|
1324
|
+
)), r.counter = r.counter + 1;
|
|
1325
|
+
const f = (w = (M = p == null ? void 0 : p.sample) == null ? void 0 : M.hours) == null ? void 0 : w.at(-1);
|
|
1326
|
+
if (f)
|
|
1327
|
+
h.lat = f.lat, h.lng = f.lng, d = v(f.eta), c.push(p), n = n ? 0 : 1;
|
|
1328
1328
|
else
|
|
1329
1329
|
break;
|
|
1330
1330
|
}
|
|
1331
|
-
return
|
|
1331
|
+
return c;
|
|
1332
1332
|
}
|
|
1333
1333
|
/**
|
|
1334
1334
|
* 计算Speed的cost
|
|
@@ -1340,11 +1340,11 @@ class O {
|
|
|
1340
1340
|
static async calculateCost(s, t, a, i = {}) {
|
|
1341
1341
|
var n;
|
|
1342
1342
|
if (s) {
|
|
1343
|
-
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3,
|
|
1343
|
+
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3, r = Math.round(s.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, d = Math.round((s.totalDgoCons + (((n = s.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
|
|
1344
1344
|
s.cost = {
|
|
1345
|
-
total: Math.round((e +
|
|
1345
|
+
total: Math.round((e + r + d) * 1e3) / 1e3,
|
|
1346
1346
|
hire: e,
|
|
1347
|
-
bunker: Math.round((
|
|
1347
|
+
bunker: Math.round((r + d) * 1e3) / 1e3,
|
|
1348
1348
|
cp: t
|
|
1349
1349
|
};
|
|
1350
1350
|
}
|
|
@@ -1355,16 +1355,16 @@ class O {
|
|
|
1355
1355
|
*
|
|
1356
1356
|
*/
|
|
1357
1357
|
static async calculateECA(s, t, a = {}) {
|
|
1358
|
-
var
|
|
1359
|
-
const i = await
|
|
1358
|
+
var r, d, h, c;
|
|
1359
|
+
const i = await V.intersectInECA((s == null ? void 0 : s.route) || []);
|
|
1360
1360
|
let n = 0, o = 0, e = 0;
|
|
1361
|
-
(
|
|
1362
|
-
|
|
1361
|
+
(d = (r = s == null ? void 0 : s.sample) == null ? void 0 : r.wps) == null || d.forEach((M) => {
|
|
1362
|
+
M.positionTime = v.utc(M.etd || M.eta).unix();
|
|
1363
1363
|
});
|
|
1364
|
-
for (const
|
|
1365
|
-
n +=
|
|
1366
|
-
const
|
|
1367
|
-
|
|
1364
|
+
for (const M of i) {
|
|
1365
|
+
n += M.distance;
|
|
1366
|
+
const w = await V.deadReckoningTime((h = M.waypoints) == null ? void 0 : h.at(0), s.sample.all || s.sample.wps), b = await V.deadReckoningTime((c = M.waypoints) == null ? void 0 : c.at(-1), s.sample.all || s.sample.wps);
|
|
1367
|
+
M.in = w, M.out = b, M.totalHrs = z.roundPrecision((b.positionTime - w.positionTime) / 3600, 3), M.totalDgoCons = z.roundPrecision(t.fo / 24 * M.totalHrs, 3), o += M.totalHrs, e += M.totalDgoCons;
|
|
1368
1368
|
}
|
|
1369
1369
|
return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3), e = z.roundPrecision(e, 3), {
|
|
1370
1370
|
distanceInECA: n,
|
|
@@ -1379,55 +1379,55 @@ class O {
|
|
|
1379
1379
|
* @param options
|
|
1380
1380
|
*/
|
|
1381
1381
|
static async mergeSpeeds(s, t = {}) {
|
|
1382
|
-
var
|
|
1382
|
+
var f, u;
|
|
1383
1383
|
const a = {
|
|
1384
1384
|
hours: [],
|
|
1385
1385
|
wps: [],
|
|
1386
1386
|
days: []
|
|
1387
|
-
}, i = s.reduce((
|
|
1388
|
-
var
|
|
1389
|
-
return
|
|
1390
|
-
}, 0), o = s.reduce((
|
|
1391
|
-
var
|
|
1392
|
-
return
|
|
1393
|
-
}, 0),
|
|
1394
|
-
var
|
|
1395
|
-
return
|
|
1396
|
-
}, 0),
|
|
1397
|
-
let
|
|
1398
|
-
for (const
|
|
1399
|
-
|
|
1400
|
-
const
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
}),
|
|
1404
|
-
|
|
1405
|
-
}),
|
|
1406
|
-
|
|
1407
|
-
})),
|
|
1408
|
-
const
|
|
1409
|
-
|
|
1410
|
-
var
|
|
1411
|
-
((
|
|
1412
|
-
}),
|
|
1413
|
-
var
|
|
1414
|
-
((
|
|
1415
|
-
}),
|
|
1416
|
-
var
|
|
1417
|
-
((
|
|
1387
|
+
}, i = s.reduce((l, m) => l + m.distance, 0), n = s.reduce((l, m) => {
|
|
1388
|
+
var I;
|
|
1389
|
+
return l + (((I = m.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1390
|
+
}, 0), o = s.reduce((l, m) => l + m.totalHrs, 0), e = s.reduce((l, m) => {
|
|
1391
|
+
var I;
|
|
1392
|
+
return l + (((I = m.extend) == null ? void 0 : I.hoursInECA) || 0);
|
|
1393
|
+
}, 0), r = s.reduce((l, m) => {
|
|
1394
|
+
var I;
|
|
1395
|
+
return l + (((I = m.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1396
|
+
}, 0), d = s.reduce((l, m) => l + m.wxFactor * m.totalHrs / o, 0), h = s.reduce((l, m) => l + m.cFactor * m.totalHrs / o, 0), c = s.reduce((l, m) => l + m.totalFoCons, 0), M = s.reduce((l, m) => l + m.totalDgoCons, 0), w = s.reduce((l, m) => l + m.cost.total, 0), b = s.reduce((l, m) => l + m.cost.hire, 0), j = s.reduce((l, m) => l + m.cost.bunker, 0), T = [], g = [];
|
|
1397
|
+
let p;
|
|
1398
|
+
for (const l of s) {
|
|
1399
|
+
g.push(...((f = l.extend) == null ? void 0 : f.eca) || []);
|
|
1400
|
+
const m = l.sample.hours, I = l.sample.wps, k = l.sample.days, F = m.at(0);
|
|
1401
|
+
p && (F.distanceFromPrevious = p.distanceFromPrevious, F.distanceFromStart = p.distanceFromStart, m.forEach((D, N) => {
|
|
1402
|
+
N && (D.distanceFromStart = D.distanceFromStart + p.distanceFromStart);
|
|
1403
|
+
}), I.at(0).distanceFromPrevious = p.distanceFromPrevious, I.at(0).distanceFromStart = p.distanceFromStart, I.forEach((D, N) => {
|
|
1404
|
+
N && (D.distanceFromStart = D.distanceFromStart + p.distanceFromStart);
|
|
1405
|
+
}), k.at(0).distanceFromPrevious = p.distanceFromPrevious, k.at(0).distanceFromStart = p.distanceFromStart, k.forEach((D, N) => {
|
|
1406
|
+
N && (D.distanceFromStart = D.distanceFromStart + p.distanceFromStart);
|
|
1407
|
+
})), F.cp = l.cost.cp;
|
|
1408
|
+
const H = [l.etd, l.eta], x = T.findIndex((D) => D.id === F.cp.id);
|
|
1409
|
+
x === -1 ? (F.cp.segment = [H], T.push(F.cp)) : T[x].segment.push(H), m.forEach((D) => {
|
|
1410
|
+
var Y;
|
|
1411
|
+
((Y = a.hours) == null ? void 0 : Y.findIndex((L) => L.eta === D.eta)) === -1 && a.hours.push(D);
|
|
1412
|
+
}), I.forEach((D) => {
|
|
1413
|
+
var Y;
|
|
1414
|
+
((Y = a.wps) == null ? void 0 : Y.findIndex((L) => L.eta === D.eta)) === -1 && a.wps.push(D);
|
|
1415
|
+
}), k.forEach((D) => {
|
|
1416
|
+
var Y;
|
|
1417
|
+
((Y = a == null ? void 0 : a.days) == null ? void 0 : Y.findIndex((L) => L.eta === D.eta)) === -1 && a.days.push(D);
|
|
1418
1418
|
});
|
|
1419
|
-
const A = (
|
|
1420
|
-
A === -1 ? a.wps.push(
|
|
1419
|
+
const A = (u = a.wps) == null ? void 0 : u.findIndex((D) => D.eta === F.eta);
|
|
1420
|
+
A === -1 ? a.wps.push(F) : a.wps[A] = F, p = m.at(-1);
|
|
1421
1421
|
}
|
|
1422
|
-
return a.wps.sort((
|
|
1423
|
-
|
|
1424
|
-
}), a.wps.forEach((
|
|
1425
|
-
const
|
|
1426
|
-
if (
|
|
1427
|
-
const
|
|
1428
|
-
|
|
1429
|
-
const
|
|
1430
|
-
|
|
1422
|
+
return a.wps.sort((l, m) => {
|
|
1423
|
+
v(l.etd).unix() - v(m.etd).unix();
|
|
1424
|
+
}), a.wps.forEach((l, m) => {
|
|
1425
|
+
const I = a.wps[m - 1];
|
|
1426
|
+
if (I) {
|
|
1427
|
+
const k = l.distanceFromStart - (I.distanceFromStart || 0), F = v(l.eta || l.etd).diff(v(I.etd || I.eta), "hour", !0), H = Math.round(k / F * 100) / 100;
|
|
1428
|
+
l.avgSpd = H;
|
|
1429
|
+
const x = V.calculateBearing(I, l);
|
|
1430
|
+
I.bearing = x;
|
|
1431
1431
|
}
|
|
1432
1432
|
}), {
|
|
1433
1433
|
sample: a,
|
|
@@ -1440,37 +1440,37 @@ class O {
|
|
|
1440
1440
|
distance: Math.round(i * 1e3) / 1e3,
|
|
1441
1441
|
totalHrs: Math.round(o * 1e3) / 1e3,
|
|
1442
1442
|
avgSpeed: Math.round(i / o * 1e3) / 1e3,
|
|
1443
|
-
wxFactor: Math.round(
|
|
1443
|
+
wxFactor: Math.round(d * 1e3) / 1e3,
|
|
1444
1444
|
cFactor: Math.round(h * 1e3) / 1e3,
|
|
1445
|
-
totalFoCons: Math.round(
|
|
1446
|
-
totalDgoCons: Math.round(
|
|
1445
|
+
totalFoCons: Math.round(c * 1e3) / 1e3,
|
|
1446
|
+
totalDgoCons: Math.round(M * 1e3) / 1e3,
|
|
1447
1447
|
cost: {
|
|
1448
|
-
total: Math.round(
|
|
1449
|
-
hire: Math.round(
|
|
1448
|
+
total: Math.round(w * 1e3) / 1e3,
|
|
1449
|
+
hire: Math.round(b * 1e3) / 1e3,
|
|
1450
1450
|
bunker: Math.round(j * 1e3) / 1e3
|
|
1451
1451
|
},
|
|
1452
1452
|
extend: {
|
|
1453
|
-
cps:
|
|
1454
|
-
eca:
|
|
1453
|
+
cps: T,
|
|
1454
|
+
eca: g,
|
|
1455
1455
|
distanceInECA: Math.round(n * 1e3) / 1e3,
|
|
1456
1456
|
hoursInECA: Math.round(e * 1e3) / 1e3,
|
|
1457
|
-
totalDgoConsInECA: Math.round(
|
|
1457
|
+
totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
|
|
1458
1458
|
speeds: s
|
|
1459
1459
|
}
|
|
1460
1460
|
};
|
|
1461
1461
|
}
|
|
1462
1462
|
}
|
|
1463
1463
|
export {
|
|
1464
|
-
|
|
1464
|
+
at as AISImpl,
|
|
1465
1465
|
yt as AlertHelper,
|
|
1466
1466
|
ft as AlertLevel,
|
|
1467
|
-
|
|
1467
|
+
Ft as HifleetImpl,
|
|
1468
1468
|
gt as LoadCondition,
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1469
|
+
xt as MyShipImpl,
|
|
1470
|
+
Tt as MyVesselImpl,
|
|
1471
|
+
Et as ShipxyImpl,
|
|
1472
|
+
R as SpeedHelper,
|
|
1473
1473
|
vt as SpeedLabel,
|
|
1474
1474
|
bt as VesselTag,
|
|
1475
|
-
|
|
1475
|
+
Nt as alertHelper
|
|
1476
1476
|
};
|