@idm-plugin/vessel 2.3.4 → 2.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +568 -563
- package/dist/index.umd.cjs +1 -1
- package/dist/speed/src/index.d.ts +4 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
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 V from "got";
|
|
5
5
|
import ct from "@log4js-node/log4js-api";
|
|
6
|
-
import
|
|
7
|
-
import { LngLatHelper as
|
|
6
|
+
import p from "moment";
|
|
7
|
+
import { LngLatHelper as z, LaneHelper as L } from "@idm-plugin/geo2";
|
|
8
8
|
import { MeteoHelper2 as mt } from "@idm-plugin/meteo2";
|
|
9
9
|
import { Meteo2Assist as it } from "@idm-plugin/meteo";
|
|
10
10
|
let f;
|
|
@@ -69,19 +69,19 @@ class Ft extends st {
|
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
},
|
|
73
|
-
f == null || f.info("[%s] fetch access token from: %s - %j", t.requestId, a,
|
|
74
|
-
accessToken:
|
|
75
|
-
tokenType:
|
|
76
|
-
expiresIn:
|
|
77
|
-
scope:
|
|
78
|
-
jti:
|
|
79
|
-
issuedAt:
|
|
72
|
+
}, n = await V.post(a, i).json();
|
|
73
|
+
f == null || f.info("[%s] fetch access token from: %s - %j", t.requestId, a, n), n.error || (this.token = {
|
|
74
|
+
accessToken: n.access_token,
|
|
75
|
+
tokenType: n.token_type,
|
|
76
|
+
expiresIn: n.expires_in,
|
|
77
|
+
scope: n.scope,
|
|
78
|
+
jti: n.jti,
|
|
79
|
+
issuedAt: p().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async checkToken(t = {}) {
|
|
83
83
|
var a;
|
|
84
|
-
return (!this.token ||
|
|
84
|
+
return (!this.token || p().diff(p(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,29 +89,29 @@ class Ft extends st {
|
|
|
89
89
|
* @param options
|
|
90
90
|
*/
|
|
91
91
|
async suggest(t, a = {}) {
|
|
92
|
-
var e,
|
|
92
|
+
var e, c;
|
|
93
93
|
await this.checkToken(a);
|
|
94
|
-
const i = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",
|
|
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} ${(c = this.token) == null ? void 0 : c.accessToken}`
|
|
97
97
|
},
|
|
98
98
|
json: {
|
|
99
99
|
kw: t,
|
|
100
100
|
recordNum: a.ps || 10
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
f == null || f.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, i,
|
|
104
|
-
const
|
|
105
|
-
return
|
|
106
|
-
mmsi:
|
|
107
|
-
name:
|
|
108
|
-
nameCn:
|
|
109
|
-
imo: Number.isNaN(
|
|
110
|
-
callSign:
|
|
111
|
-
type:
|
|
112
|
-
flagName:
|
|
103
|
+
f == null || f.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, i, n);
|
|
104
|
+
const o = await V.post(i, n).json();
|
|
105
|
+
return o.status !== 200 ? (f == null || f.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), []) : (o.data || []).map((h) => ({
|
|
106
|
+
mmsi: h.mmsi,
|
|
107
|
+
name: h.nameEn,
|
|
108
|
+
nameCn: h.nameCn,
|
|
109
|
+
imo: Number.isNaN(h.imo) ? null : Number(h.imo),
|
|
110
|
+
callSign: h.callsign,
|
|
111
|
+
type: h.vesselTypeNameEn,
|
|
112
|
+
flagName: h.flagCtry,
|
|
113
113
|
vendor: "myvessel",
|
|
114
|
-
raw:
|
|
114
|
+
raw: h
|
|
115
115
|
}));
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
@@ -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
|
-
const i = /^\d{7}$/.test(t.toString()),
|
|
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
|
-
searchParams:
|
|
129
|
+
searchParams: o
|
|
130
130
|
};
|
|
131
|
-
f == null || f.info("[%s] fetch vessel from: %s - %j", a.requestId,
|
|
132
|
-
const
|
|
133
|
-
if (
|
|
134
|
-
return f == null || f.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message:
|
|
131
|
+
f == null || f.info("[%s] fetch vessel from: %s - %j", a.requestId, n, e);
|
|
132
|
+
const c = await V.get(n, e).json();
|
|
133
|
+
if (c.status !== 200)
|
|
134
|
+
return f == null || f.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: c.message, status: c.status, code: c.code }), {};
|
|
135
135
|
{
|
|
136
|
-
const
|
|
137
|
-
if (
|
|
136
|
+
const u = c.data;
|
|
137
|
+
if (u)
|
|
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: u.mmsi,
|
|
140
|
+
imo: Number.isNaN(u.imo) ? null : Number(u.imo),
|
|
141
|
+
callSign: u.callsign,
|
|
142
|
+
name: u.nameEn,
|
|
143
|
+
nameCn: u.nameCn,
|
|
144
|
+
type: u.vesselTypeNameEn,
|
|
145
|
+
flagName: u.flagCtry,
|
|
146
|
+
clasz: u.classSociety,
|
|
147
|
+
dateOfBuild: u.buildYearMonth,
|
|
148
|
+
deadweight: u.dwt,
|
|
149
|
+
grossTonnage: u.grt,
|
|
150
|
+
netTonnage: u.net,
|
|
151
|
+
teu: u.teu,
|
|
152
|
+
length: u.length,
|
|
153
|
+
breadth: u.width,
|
|
154
|
+
height: u.height,
|
|
155
|
+
draught: u.draught,
|
|
156
|
+
speed: u.speed,
|
|
157
|
+
passengerCapacity: u.passengercapacity,
|
|
158
158
|
vendor: "myvessel",
|
|
159
|
-
raw:
|
|
159
|
+
raw: u
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
162
|
return {};
|
|
163
163
|
}
|
|
164
164
|
async archives(t, a = {}) {
|
|
165
|
-
var e,
|
|
165
|
+
var e, c;
|
|
166
166
|
await this.checkToken(a);
|
|
167
|
-
const i = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",
|
|
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} ${(c = this.token) == null ? void 0 : c.accessToken}`
|
|
170
170
|
},
|
|
171
171
|
json: {
|
|
172
172
|
mmsiList: typeof t == "number" ? [t] : t
|
|
173
173
|
}
|
|
174
174
|
};
|
|
175
|
-
f == null || f.info("[%s] fetch vessel archive from: %s - %j", a.requestId, i,
|
|
176
|
-
const
|
|
177
|
-
return
|
|
175
|
+
f == null || f.info("[%s] fetch vessel archive from: %s - %j", a.requestId, i, n);
|
|
176
|
+
const o = await V.post(i, n).json();
|
|
177
|
+
return o.status !== 200 ? (f == null || f.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 c, d;
|
|
181
181
|
await this.checkToken(a);
|
|
182
|
-
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",
|
|
182
|
+
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
|
|
183
183
|
headers: {
|
|
184
|
-
Authorization: `${(
|
|
184
|
+
Authorization: `${(c = this.token) == null ? void 0 : c.tokenType} ${(d = this.token) == null ? void 0 : d.accessToken}`
|
|
185
185
|
},
|
|
186
186
|
searchParams: { mmsi: t }
|
|
187
187
|
};
|
|
188
|
-
f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId, i,
|
|
189
|
-
const
|
|
190
|
-
if (
|
|
191
|
-
return f == null || f.warn("[%s] fetch realtime position failed: %j", a.requestId, { message:
|
|
192
|
-
const e =
|
|
193
|
-
for (const
|
|
194
|
-
!isNaN(e[
|
|
188
|
+
f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
|
|
189
|
+
const o = await V.get(i, n).json();
|
|
190
|
+
if (o.code)
|
|
191
|
+
return f == null || f.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), o;
|
|
192
|
+
const e = o.data;
|
|
193
|
+
for (const h in e)
|
|
194
|
+
!isNaN(e[h]) && Number(e[h]) !== 1 / 0 && (e[h] = Number(e[h]));
|
|
195
195
|
if (e) {
|
|
196
|
-
const
|
|
196
|
+
const h = p(`${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 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) ? p.utc(e.eta).format() : void 0,
|
|
212
212
|
destination: e.dest,
|
|
213
|
-
positionTime:
|
|
213
|
+
positionTime: h.unix(),
|
|
214
214
|
status: e.status,
|
|
215
215
|
labelCn: e.statusNameCn,
|
|
216
216
|
labelEn: e.statusNameEn,
|
|
@@ -223,17 +223,17 @@ class Ft extends st {
|
|
|
223
223
|
net: e.net,
|
|
224
224
|
method: "position",
|
|
225
225
|
vendor: "myVessel",
|
|
226
|
-
utc:
|
|
226
|
+
utc: h.utc().format()
|
|
227
227
|
};
|
|
228
228
|
} else
|
|
229
229
|
return {};
|
|
230
230
|
}
|
|
231
231
|
async calculateRoute(t, a, i = {}) {
|
|
232
|
-
var
|
|
232
|
+
var c, d;
|
|
233
233
|
await this.checkToken(i);
|
|
234
|
-
const
|
|
234
|
+
const n = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", o = {
|
|
235
235
|
headers: {
|
|
236
|
-
Authorization: `${(
|
|
236
|
+
Authorization: `${(c = this.token) == null ? void 0 : c.tokenType} ${(d = this.token) == null ? void 0 : d.accessToken}`
|
|
237
237
|
},
|
|
238
238
|
json: {
|
|
239
239
|
startPoint: {
|
|
@@ -249,20 +249,20 @@ class Ft extends st {
|
|
|
249
249
|
withECA: i.withECA || !1
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
|
-
f == null || f.info("[%s] fetch route from: %s - %j", i.requestId,
|
|
253
|
-
const e = await
|
|
252
|
+
f == null || f.info("[%s] fetch route from: %s - %j", i.requestId, n, o);
|
|
253
|
+
const e = await V.post(n, o).json();
|
|
254
254
|
return e.status !== 200 ? (f == null || f.warn("[%s] fetch route failed: %j", i.requestId, { message: e.message, status: e.status, code: e.code }), {}) : e.data;
|
|
255
255
|
}
|
|
256
|
-
async trajectory(t, a, i,
|
|
256
|
+
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
257
257
|
await this.checkToken(e);
|
|
258
|
-
const
|
|
259
|
-
for (;
|
|
260
|
-
await this.trajectoryIn30Day(t,
|
|
261
|
-
return await this.trajectoryIn30Day(t,
|
|
258
|
+
const c = await this.realTimePosition(t, e), d = p(a), h = p(i), u = [];
|
|
259
|
+
for (; h.diff(d, "day", !0) > 30; )
|
|
260
|
+
await this.trajectoryIn30Day(t, d, d.clone().add(30, "day"), c, n, u, e), d.add(30, "day");
|
|
261
|
+
return await this.trajectoryIn30Day(t, d, h, c, n, u, e), u;
|
|
262
262
|
}
|
|
263
|
-
async trajectoryIn30Day(t, a, i,
|
|
264
|
-
var M, j, I,
|
|
265
|
-
const
|
|
263
|
+
async trajectoryIn30Day(t, a, i, n, o, e, c = {}) {
|
|
264
|
+
var M, j, I, w, g;
|
|
265
|
+
const d = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
|
|
266
266
|
headers: {
|
|
267
267
|
Authorization: `${(M = this.token) == null ? void 0 : M.tokenType} ${(j = this.token) == null ? void 0 : j.accessToken}`
|
|
268
268
|
},
|
|
@@ -272,34 +272,34 @@ class Ft extends st {
|
|
|
272
272
|
endTime: i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
273
273
|
}
|
|
274
274
|
};
|
|
275
|
-
f == null || f.info("[%s] fetch trajectory from: %s - %j",
|
|
276
|
-
const
|
|
277
|
-
if (
|
|
278
|
-
return f == null || f.warn("[%s] fetch trajectory failed: %j",
|
|
275
|
+
f == null || f.info("[%s] fetch trajectory from: %s - %j", c.requestId, d, h);
|
|
276
|
+
const u = await V.post(d, h).json();
|
|
277
|
+
if (u.code)
|
|
278
|
+
return f == null || f.warn("[%s] fetch trajectory failed: %j", c.requestId, d, { message: u.message, status: u.status, code: u.code }), u;
|
|
279
279
|
let y = -1;
|
|
280
|
-
const
|
|
281
|
-
return (
|
|
282
|
-
for (const P in
|
|
283
|
-
!isNaN(
|
|
284
|
-
const
|
|
285
|
-
mmsi:
|
|
286
|
-
imo:
|
|
287
|
-
lat:
|
|
288
|
-
lng:
|
|
289
|
-
sog:
|
|
290
|
-
cog:
|
|
291
|
-
hdg:
|
|
292
|
-
draught:
|
|
280
|
+
const v = p(`${(w = (I = u.data) == null ? void 0 : I[0]) == null ? void 0 : w.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
281
|
+
return (g = u.data) == null || g.forEach((r) => {
|
|
282
|
+
for (const P in r)
|
|
283
|
+
!isNaN(r[P]) && Number(r[P]) !== 1 / 0 && (r[P] = Number(r[P]));
|
|
284
|
+
const b = p(`${r.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), m = r.status, { labelCn: l, labelEn: k } = this.parseStatus(m), S = {
|
|
285
|
+
mmsi: r.mmsi,
|
|
286
|
+
imo: n == null ? void 0 : n.imo,
|
|
287
|
+
lat: r.lat,
|
|
288
|
+
lng: r.lon,
|
|
289
|
+
sog: r.sog,
|
|
290
|
+
cog: r.cog,
|
|
291
|
+
hdg: r.hdg,
|
|
292
|
+
draught: r.draught,
|
|
293
293
|
status: m,
|
|
294
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(
|
|
295
|
-
destination:
|
|
296
|
-
positionTime:
|
|
297
|
-
labelCn:
|
|
294
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(r.eta) ? p(`${r.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
|
|
295
|
+
destination: r.dest,
|
|
296
|
+
positionTime: b.unix(),
|
|
297
|
+
labelCn: l,
|
|
298
298
|
labelEn: k,
|
|
299
299
|
method: "trajectory",
|
|
300
300
|
vendor: "myVessel",
|
|
301
|
-
utc:
|
|
302
|
-
}, D = Math.floor(
|
|
301
|
+
utc: b.utc().format()
|
|
302
|
+
}, D = Math.floor(b.diff(v, "minute", !0) / (o || 1));
|
|
303
303
|
D !== y && (y = D, e.push(S));
|
|
304
304
|
}), e;
|
|
305
305
|
}
|
|
@@ -311,20 +311,20 @@ class Et extends st {
|
|
|
311
311
|
this.token = t;
|
|
312
312
|
}
|
|
313
313
|
async realTimePosition(t, a = {}) {
|
|
314
|
-
const i = "https://api.hifleet.com/position/position/get/token",
|
|
314
|
+
const i = "https://api.hifleet.com/position/position/get/token", n = {
|
|
315
315
|
searchParams: {
|
|
316
316
|
mmsi: t,
|
|
317
317
|
usertoken: this.token
|
|
318
318
|
}
|
|
319
|
-
},
|
|
320
|
-
f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId, i,
|
|
321
|
-
const e =
|
|
319
|
+
}, o = await V.post(i, n).json();
|
|
320
|
+
f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
|
|
321
|
+
const e = o == null ? void 0 : o.list;
|
|
322
322
|
if (!e)
|
|
323
|
-
return f == null || f.warn("[%s] fetch realtime position failed: %j", a.requestId, i,
|
|
324
|
-
for (const
|
|
325
|
-
!isNaN(e[
|
|
323
|
+
return f == null || f.warn("[%s] fetch realtime position failed: %j", a.requestId, i, o), o;
|
|
324
|
+
for (const v in e)
|
|
325
|
+
!isNaN(e[v]) && Number(e[v]) !== 1 / 0 && (e[v] = Number(e[v]));
|
|
326
326
|
e.status = e.sp > 3 ? 0 : 1;
|
|
327
|
-
const
|
|
327
|
+
const c = e.status, { labelCn: d, labelEn: h } = this.parseStatus(c), u = p(`${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,24 +339,24 @@ 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) ? p.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:
|
|
352
|
-
labelEn:
|
|
348
|
+
positionTime: u.unix(),
|
|
349
|
+
utc: u.utc().format(),
|
|
350
|
+
status: c,
|
|
351
|
+
labelCn: d,
|
|
352
|
+
labelEn: h,
|
|
353
353
|
method: "position",
|
|
354
354
|
vendor: "hifleet"
|
|
355
355
|
};
|
|
356
356
|
}
|
|
357
357
|
async search(t, a = {}) {
|
|
358
358
|
let i = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
359
|
-
const
|
|
359
|
+
const n = {
|
|
360
360
|
searchParams: {
|
|
361
361
|
keyword: t
|
|
362
362
|
},
|
|
@@ -366,24 +366,24 @@ class Et extends st {
|
|
|
366
366
|
Host: "www.hifleet.com"
|
|
367
367
|
}
|
|
368
368
|
};
|
|
369
|
-
let
|
|
370
|
-
f == null || f.info("[%s] fetch vessel props from: %s - %j", a.requestId, i,
|
|
371
|
-
for (const
|
|
372
|
-
!isNaN(
|
|
369
|
+
let o = await V.post(i, n).json();
|
|
370
|
+
f == null || f.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]);
|
|
371
|
+
for (const c in o)
|
|
372
|
+
!isNaN(o[c]) && Number(o[c]) !== 1 / 0 && (o[c] = Number(o[c]));
|
|
373
373
|
const e = {
|
|
374
|
-
mmsi:
|
|
375
|
-
name:
|
|
376
|
-
imo:
|
|
377
|
-
callSign:
|
|
378
|
-
length:
|
|
379
|
-
breadth:
|
|
380
|
-
draught:
|
|
381
|
-
type:
|
|
374
|
+
mmsi: o.m,
|
|
375
|
+
name: o.n,
|
|
376
|
+
imo: o.i,
|
|
377
|
+
callSign: o.c,
|
|
378
|
+
length: o.l,
|
|
379
|
+
breadth: o.b,
|
|
380
|
+
draught: o.dr,
|
|
381
|
+
type: o.t
|
|
382
382
|
};
|
|
383
|
-
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do",
|
|
383
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await V.post(i, n).json(), f == null || f.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
|
-
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do",
|
|
386
|
+
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
|
|
387
387
|
searchParams: {
|
|
388
388
|
q: t
|
|
389
389
|
},
|
|
@@ -392,66 +392,66 @@ class Et extends st {
|
|
|
392
392
|
Origin: "https://www.hifleet.com",
|
|
393
393
|
Host: "www.hifleet.com"
|
|
394
394
|
}
|
|
395
|
-
},
|
|
396
|
-
f == null || f.info("[%s] suggest vessel props from: %s - %j", a.requestId, i,
|
|
395
|
+
}, o = await V.post(i, n).json();
|
|
396
|
+
f == null || f.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, n);
|
|
397
397
|
const e = [];
|
|
398
|
-
for (const
|
|
398
|
+
for (const c of o)
|
|
399
399
|
e.push({
|
|
400
|
-
mmsi: !
|
|
401
|
-
name:
|
|
402
|
-
callSign:
|
|
403
|
-
imo: !
|
|
404
|
-
score:
|
|
400
|
+
mmsi: !c.mmsi || isNaN(c.mmsi) ? null : Number(c.mmsi),
|
|
401
|
+
name: c.name,
|
|
402
|
+
callSign: c.callsign,
|
|
403
|
+
imo: !c.imo || isNaN(c.imo) ? null : Number(c.imo),
|
|
404
|
+
score: c._score
|
|
405
405
|
});
|
|
406
|
-
return e.sort((
|
|
406
|
+
return e.sort((c, d) => d.score - c.score), e;
|
|
407
407
|
}
|
|
408
|
-
async trajectory(t, a, i,
|
|
409
|
-
var
|
|
410
|
-
const
|
|
411
|
-
let
|
|
412
|
-
const
|
|
413
|
-
if (
|
|
414
|
-
let
|
|
415
|
-
|
|
408
|
+
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
409
|
+
var r, b, m;
|
|
410
|
+
const c = await this.realTimePosition(t, e);
|
|
411
|
+
let d = p(a);
|
|
412
|
+
const h = p(i), u = p();
|
|
413
|
+
if (o) {
|
|
414
|
+
let l = h.diff(d, "d", !0);
|
|
415
|
+
l < 0 ? d = h.clone().subtract(40, "d") : l < 30 ? d.subtract(10, "d") : l < 60 ? d.subtract(5, "d") : d = h.clone().subtract(80, "d"), l = u.diff(h, "d", !0), h.add(l > 10 ? 240 : l * 24, "h");
|
|
416
416
|
}
|
|
417
417
|
const y = {
|
|
418
418
|
searchParams: {
|
|
419
|
-
endtime:
|
|
420
|
-
starttime:
|
|
419
|
+
endtime: h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
|
|
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
|
-
f == null || f.info("[%s] fetch trajectory from: %s - %j", e.requestId,
|
|
424
|
+
}, v = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", M = await V.get(v, y).json();
|
|
425
|
+
f == null || f.info("[%s] fetch trajectory from: %s - %j", e.requestId, v, y);
|
|
426
426
|
let j;
|
|
427
|
-
M && (j = ((
|
|
427
|
+
M && (j = ((b = (r = M.ships) == null ? void 0 : r.offors) == null ? void 0 : b.ship) || [], j.length || f == null || f.warn("[%s] fetch trajectory failed: %j", e.requestId, M));
|
|
428
428
|
const I = [];
|
|
429
|
-
let
|
|
430
|
-
const
|
|
431
|
-
for (const
|
|
432
|
-
for (const A in
|
|
433
|
-
!isNaN(
|
|
434
|
-
const k =
|
|
435
|
-
|
|
436
|
-
const { labelEn: S, labelCn: D } = this.parseStatus(
|
|
437
|
-
mmsi:
|
|
438
|
-
name:
|
|
439
|
-
imo:
|
|
440
|
-
lat:
|
|
441
|
-
lng:
|
|
442
|
-
draught:
|
|
443
|
-
sog:
|
|
444
|
-
cog:
|
|
445
|
-
hdg:
|
|
429
|
+
let w = -1;
|
|
430
|
+
const g = p(`${(m = j == null ? void 0 : j[0]) == null ? void 0 : m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
431
|
+
for (const l of j) {
|
|
432
|
+
for (const A in l)
|
|
433
|
+
!isNaN(l[A]) && Number(l[A]) !== 1 / 0 && (l[A] = Number(l[A]));
|
|
434
|
+
const k = p(`${l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
435
|
+
l.status = l.sp > 4 ? 0 : 1;
|
|
436
|
+
const { labelEn: S, labelCn: D } = this.parseStatus(l.status), P = {
|
|
437
|
+
mmsi: l.m,
|
|
438
|
+
name: l.n,
|
|
439
|
+
imo: c == null ? void 0 : c.imo,
|
|
440
|
+
lat: l.la,
|
|
441
|
+
lng: l.lo,
|
|
442
|
+
draught: l.draught,
|
|
443
|
+
sog: l.sp,
|
|
444
|
+
cog: l.co,
|
|
445
|
+
hdg: l.hdg,
|
|
446
446
|
positionTime: k.unix(),
|
|
447
447
|
utc: k.utc().format(),
|
|
448
|
-
status:
|
|
448
|
+
status: l.status,
|
|
449
449
|
labelCn: D,
|
|
450
450
|
labelEn: S,
|
|
451
451
|
method: "trajectory",
|
|
452
452
|
vendor: "hifleet"
|
|
453
|
-
}, N = Math.floor(k.diff(
|
|
454
|
-
N !==
|
|
453
|
+
}, N = Math.floor(k.diff(g, "minute", !0) / (n || 1));
|
|
454
|
+
N !== w && (w = N, I.push(P));
|
|
455
455
|
}
|
|
456
456
|
return I;
|
|
457
457
|
}
|
|
@@ -469,13 +469,13 @@ class Nt extends st {
|
|
|
469
469
|
k: this.token,
|
|
470
470
|
enc: 1
|
|
471
471
|
}
|
|
472
|
-
},
|
|
473
|
-
if (f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
474
|
-
return
|
|
475
|
-
const e =
|
|
472
|
+
}, n = "https://api.shipxy.com/apicall/GetSingleShip", o = await V.get(n, i).json();
|
|
473
|
+
if (f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, i), (o == null ? void 0 : o.status) !== 0)
|
|
474
|
+
return o;
|
|
475
|
+
const e = o.data[0];
|
|
476
476
|
for (const y in e)
|
|
477
477
|
!isNaN(e[y]) && Number(e[y]) !== 1 / 0 && (e[y] = Number(e[y]));
|
|
478
|
-
const { labelCn:
|
|
478
|
+
const { labelCn: c, labelEn: d } = await this.parseStatus(e.navistat), h = p.unix(e.lasttime);
|
|
479
479
|
return {
|
|
480
480
|
mmsi: e.ShipID,
|
|
481
481
|
name: e.name,
|
|
@@ -491,44 +491,44 @@ class Nt extends st {
|
|
|
491
491
|
hdg: Math.round(e.hdg / 100 * 100) / 100,
|
|
492
492
|
rot: Math.round(e.rot / 100 * 100) / 100,
|
|
493
493
|
positionTime: e.lasttime,
|
|
494
|
-
utc:
|
|
494
|
+
utc: h.utc().format(),
|
|
495
495
|
status: e.navistat,
|
|
496
|
-
labelEn:
|
|
497
|
-
labelCn:
|
|
496
|
+
labelEn: d,
|
|
497
|
+
labelCn: c,
|
|
498
498
|
method: "position",
|
|
499
499
|
vendor: "shipxy"
|
|
500
500
|
};
|
|
501
501
|
}
|
|
502
|
-
async trajectory(t, a, i,
|
|
503
|
-
var
|
|
504
|
-
const
|
|
502
|
+
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
503
|
+
var g;
|
|
504
|
+
const c = await this.realTimePosition(t, e), d = p(a), h = p(i), u = "https://api.shipxy.com/apicall/GetShipTrack", y = {
|
|
505
505
|
searchParams: {
|
|
506
506
|
id: t,
|
|
507
507
|
k: this.token,
|
|
508
508
|
enc: 1,
|
|
509
509
|
cut: 0,
|
|
510
|
-
btm:
|
|
511
|
-
etm:
|
|
510
|
+
btm: d.unix(),
|
|
511
|
+
etm: h.unix()
|
|
512
512
|
}
|
|
513
|
-
},
|
|
514
|
-
if (f == null || f.info("[%s] fetch trajectory from: %s - %j", e.requestId,
|
|
515
|
-
return
|
|
516
|
-
const M =
|
|
517
|
-
let
|
|
518
|
-
for (const
|
|
519
|
-
const
|
|
520
|
-
imo:
|
|
513
|
+
}, v = await V.get(u, y).json();
|
|
514
|
+
if (f == null || f.info("[%s] fetch trajectory from: %s - %j", e.requestId, u, y), (v == null ? void 0 : v.status) !== 0)
|
|
515
|
+
return v;
|
|
516
|
+
const M = v == null ? void 0 : v.points, j = [], I = p.unix((g = M[0]) == null ? void 0 : g.utc);
|
|
517
|
+
let w = -1;
|
|
518
|
+
for (const r of M) {
|
|
519
|
+
const b = p.unix(r.utc), m = {
|
|
520
|
+
imo: c == null ? void 0 : c.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(r.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
523
|
+
cog: Math.round(r.cog / 100 * 100) / 100,
|
|
524
|
+
lat: Math.round(r.lat / 1e6 * 1e5) / 1e5,
|
|
525
|
+
lng: Math.round(r.lon / 1e6 * 1e5) / 1e5,
|
|
526
|
+
positionTime: b.unix(),
|
|
527
|
+
utc: b.utc().format(),
|
|
528
528
|
method: "trajectory",
|
|
529
529
|
vendor: "shipxy"
|
|
530
|
-
},
|
|
531
|
-
|
|
530
|
+
}, l = Math.floor(b.diff(I, "minute", !0) / (n || 1));
|
|
531
|
+
l !== w && (w = l, j.push(m));
|
|
532
532
|
}
|
|
533
533
|
return j;
|
|
534
534
|
}
|
|
@@ -547,8 +547,8 @@ class Tt extends st {
|
|
|
547
547
|
json: {
|
|
548
548
|
mmsiList: t
|
|
549
549
|
}
|
|
550
|
-
},
|
|
551
|
-
return f == null || f.info("[%s] fetch ship id from: %s - %j", a.requestId,
|
|
550
|
+
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await V.post(n, i).json();
|
|
551
|
+
return f == null || f.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
|
-
},
|
|
562
|
-
if (f == null || f.info("[%s] fetch ship info from: %s - %j", a.requestId,
|
|
563
|
-
return
|
|
564
|
-
const e =
|
|
565
|
-
let
|
|
566
|
-
return t === "407170" && (
|
|
561
|
+
}, n = "https://api3.myships.com/sp/ships/aissta", o = await V.post(n, i).json();
|
|
562
|
+
if (f == null || f.info("[%s] fetch ship info from: %s - %j", a.requestId, n, i), o.code !== "0")
|
|
563
|
+
return o;
|
|
564
|
+
const e = o.data;
|
|
565
|
+
let c = e.imo;
|
|
566
|
+
return t === "407170" && (c = "9198379", f == null || f.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, e.imo, c)), {
|
|
567
567
|
mmsi: e.mmsi,
|
|
568
568
|
name: e.shipnameEn,
|
|
569
|
-
imo:
|
|
569
|
+
imo: c,
|
|
570
570
|
callSign: e.callSign,
|
|
571
571
|
length: e.length,
|
|
572
572
|
width: e.breadth,
|
|
@@ -574,46 +574,46 @@ class Tt extends st {
|
|
|
574
574
|
};
|
|
575
575
|
}
|
|
576
576
|
async realTimePosition(t, a = {}) {
|
|
577
|
-
const i = await this.getShipId(t, a),
|
|
577
|
+
const i = await this.getShipId(t, a), n = await this.getShipInfo(i, a), o = {
|
|
578
578
|
headers: {
|
|
579
579
|
appKey: this.token
|
|
580
580
|
},
|
|
581
581
|
json: {
|
|
582
582
|
shipId: i
|
|
583
583
|
}
|
|
584
|
-
}, e = "https://api3.myships.com/sp/ships/position/latest",
|
|
585
|
-
f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId, e,
|
|
586
|
-
const
|
|
587
|
-
for (const M in
|
|
588
|
-
!isNaN(
|
|
589
|
-
const { labelCn:
|
|
584
|
+
}, e = "https://api3.myships.com/sp/ships/position/latest", c = await V.post(e, o).json();
|
|
585
|
+
f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId, e, o);
|
|
586
|
+
const d = c.data[0];
|
|
587
|
+
for (const M in d)
|
|
588
|
+
!isNaN(d[M]) && Number(d[M]) !== 1 / 0 && (d[M] = Number(d[M]));
|
|
589
|
+
const { labelCn: h, labelEn: u } = await this.parseStatus(d.aisNavStatus), y = p.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:
|
|
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
600
|
utc: y.utc().format(),
|
|
601
|
-
status:
|
|
602
|
-
labelEn:
|
|
603
|
-
labelCn:
|
|
601
|
+
status: d.aisNavStatus,
|
|
602
|
+
labelEn: u,
|
|
603
|
+
labelCn: h,
|
|
604
604
|
method: "position",
|
|
605
605
|
vendor: "myship"
|
|
606
606
|
};
|
|
607
607
|
}
|
|
608
|
-
async trajectory(t, a, i,
|
|
609
|
-
const
|
|
610
|
-
for (;
|
|
611
|
-
await this.trajectoryIn30Day(
|
|
612
|
-
return await this.trajectoryIn30Day(
|
|
608
|
+
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
609
|
+
const c = p(a), d = p(i), h = await this.getShipId(t), u = await this.getShipInfo(h), y = [];
|
|
610
|
+
for (; d.diff(c, "day", !0) > 30; )
|
|
611
|
+
await this.trajectoryIn30Day(h, c.unix(), c.add(30, "day").unix(), u, t, n, y);
|
|
612
|
+
return await this.trajectoryIn30Day(h, c.unix(), d.unix(), u, t, n, y), y;
|
|
613
613
|
}
|
|
614
|
-
async trajectoryIn30Day(t, a, i,
|
|
614
|
+
async trajectoryIn30Day(t, a, i, n, o, e, c, d = {}) {
|
|
615
615
|
var I;
|
|
616
|
-
const
|
|
616
|
+
const h = {
|
|
617
617
|
headers: {
|
|
618
618
|
appKey: this.token
|
|
619
619
|
},
|
|
@@ -622,37 +622,37 @@ class Tt extends st {
|
|
|
622
622
|
startTime: a,
|
|
623
623
|
endTime: i
|
|
624
624
|
}
|
|
625
|
-
},
|
|
626
|
-
if (f == null || f.info("[%s] fetch trajectory from: %s - %j",
|
|
627
|
-
return f == null || f.warn("[%s] invoke myship trajectory failed: %j",
|
|
628
|
-
const
|
|
629
|
-
for (const
|
|
630
|
-
!isNaN(
|
|
631
|
-
const M =
|
|
625
|
+
}, u = "https://api3.myships.com/sp/ships/position/history", y = await V.post(u, h).json();
|
|
626
|
+
if (f == null || f.info("[%s] fetch trajectory from: %s - %j", d.requestId, u, h), y.code !== "0")
|
|
627
|
+
return f == null || f.warn("[%s] invoke myship trajectory failed: %j", d.requestId, y), y;
|
|
628
|
+
const v = y.data;
|
|
629
|
+
for (const w in v)
|
|
630
|
+
!isNaN(v[w]) && Number(v[w]) !== 1 / 0 && (v[w] = Number(v[w]));
|
|
631
|
+
const M = p.unix((I = v[0]) == null ? void 0 : I.posTime);
|
|
632
632
|
let j = -1;
|
|
633
|
-
for (const
|
|
634
|
-
const
|
|
635
|
-
imo:
|
|
636
|
-
mmsi:
|
|
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:
|
|
633
|
+
for (const w of v) {
|
|
634
|
+
const g = p.unix(w.posTime), r = {
|
|
635
|
+
imo: n == null ? void 0 : n.imo,
|
|
636
|
+
mmsi: o,
|
|
637
|
+
lat: Math.round(w.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
638
|
+
lng: Math.round(w.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
639
|
+
sog: Math.round(w.sog / 10 * 100) / 100,
|
|
640
|
+
cog: Math.round(w.cog / 10 * 100) / 100,
|
|
641
|
+
hdg: Math.round(w.heading * 100) / 100,
|
|
642
|
+
rot: Math.round(w.rot * 100) / 100,
|
|
643
|
+
positionTime: g.unix(),
|
|
644
|
+
utc: g.utc().format(),
|
|
645
645
|
method: "trajectory",
|
|
646
646
|
vendor: "myship"
|
|
647
|
-
},
|
|
648
|
-
|
|
647
|
+
}, b = Math.floor(g.diff(M, "minute", !0) / (e || 1));
|
|
648
|
+
b !== j && (j = b, c.push(r));
|
|
649
649
|
}
|
|
650
|
-
return
|
|
650
|
+
return c;
|
|
651
651
|
}
|
|
652
652
|
}
|
|
653
|
-
let
|
|
653
|
+
let _;
|
|
654
654
|
try {
|
|
655
|
-
|
|
655
|
+
_ = ct.getLogger("vessel");
|
|
656
656
|
} catch {
|
|
657
657
|
} finally {
|
|
658
658
|
}
|
|
@@ -667,23 +667,23 @@ class yt {
|
|
|
667
667
|
* @param options
|
|
668
668
|
*/
|
|
669
669
|
parsePrinciple(s, t = {}) {
|
|
670
|
-
var e,
|
|
671
|
-
|
|
672
|
-
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = s.match(a) ? (e = s.match(a)) == null ? void 0 : e[0] : void 0,
|
|
673
|
-
if (!
|
|
670
|
+
var e, c, d;
|
|
671
|
+
_ == null || _.debug("[%s] parse rule: %s", t.requestId, s);
|
|
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
|
+
if (!n)
|
|
674
674
|
return;
|
|
675
|
-
const
|
|
676
|
-
for (let
|
|
677
|
-
const
|
|
678
|
-
if (
|
|
679
|
-
|
|
680
|
-
else if (
|
|
681
|
-
for (let y = 0,
|
|
682
|
-
const M = this.parseRule(
|
|
683
|
-
M && (
|
|
675
|
+
const o = {};
|
|
676
|
+
for (let h = 0; h < (n == null ? void 0 : n.length); h++) {
|
|
677
|
+
const u = (d = (c = n[h].match(a)) == null ? void 0 : c[0]) == null ? void 0 : d.split("],");
|
|
678
|
+
if (h === 0 && !u)
|
|
679
|
+
o.scope = n[0];
|
|
680
|
+
else if (u)
|
|
681
|
+
for (let y = 0, v = u.length; y < v; y++) {
|
|
682
|
+
const M = this.parseRule(u[y]);
|
|
683
|
+
M && (o[M.level] ? M.key ? o[M.level][M == null ? void 0 : M.key] = M : o[M.level] = M : M.key ? o[M.level] = { [M == null ? void 0 : M.key]: M } : o[M.level] = M);
|
|
684
684
|
}
|
|
685
685
|
}
|
|
686
|
-
return
|
|
686
|
+
return o;
|
|
687
687
|
}
|
|
688
688
|
/**
|
|
689
689
|
* 解析单一告警规则
|
|
@@ -692,17 +692,17 @@ class yt {
|
|
|
692
692
|
* @param options
|
|
693
693
|
*/
|
|
694
694
|
parseRule(s, t = {}) {
|
|
695
|
-
var
|
|
696
|
-
|
|
697
|
-
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (
|
|
698
|
-
if (
|
|
699
|
-
let e =
|
|
695
|
+
var o;
|
|
696
|
+
_ == null || _.debug("[%s] parse rule: %s", t.requestId, s), s = s.startsWith("[") ? s : `[${s}`, s = s.endsWith("]") ? s : `${s}]`;
|
|
697
|
+
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (o = s == null ? void 0 : s.match(a)) == null ? void 0 : o[0], n = i == null ? void 0 : i.split(",");
|
|
698
|
+
if (n) {
|
|
699
|
+
let e = n[3] === "Number.MAX_VALUE" ? 100 : Number(n[3]);
|
|
700
700
|
return e = isNaN(e) ? 1 : e, {
|
|
701
|
-
operator:
|
|
702
|
-
number: Number.isNaN(Number(
|
|
703
|
-
level:
|
|
701
|
+
operator: n[0],
|
|
702
|
+
number: Number.isNaN(Number(n[1])) ? n[1] : Number(n[1]),
|
|
703
|
+
level: n[2],
|
|
704
704
|
time: e,
|
|
705
|
-
key:
|
|
705
|
+
key: n[4]
|
|
706
706
|
};
|
|
707
707
|
}
|
|
708
708
|
}
|
|
@@ -713,14 +713,14 @@ class yt {
|
|
|
713
713
|
* @param options
|
|
714
714
|
*/
|
|
715
715
|
checkWeather(s, t, a = {}) {
|
|
716
|
-
var M, j, I,
|
|
717
|
-
let i = 0,
|
|
718
|
-
const
|
|
716
|
+
var M, j, I, w, g, r, b, m, l, k, S, D, P, N, A;
|
|
717
|
+
let i = 0, n = 0, o = 0, e = 0;
|
|
718
|
+
const c = Math.round(((j = (M = t == null ? void 0 : t.SEVERE) == null ? void 0 : M.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, d = (w = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : w.number, h = (r = (g = t == null ? void 0 : t.HEAVY) == null ? void 0 : g.sigWave) == null ? void 0 : r.number, u = Math.round((((m = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.wind) == null ? void 0 : m.number) + 2) * 100) / 100, y = (k = (l = t == null ? void 0 : t.SEVERE) == null ? void 0 : l.wind) == null ? void 0 : k.number, v = (D = (S = t == null ? void 0 : t.HEAVY) == null ? void 0 : S.wind) == null ? void 0 : D.number;
|
|
719
719
|
for (let x = 0; x < (s == null ? void 0 : s.length); x++) {
|
|
720
|
-
const T = s[x], q = (N = (P = T == null ? void 0 : T.meteo) == null ? void 0 : P.wave) == null ? void 0 : N.sig, R = (A = T == null ? void 0 : T.meteo) == null ? void 0 : A.wind, J = x ?
|
|
721
|
-
e = J > e ? J : e,
|
|
720
|
+
const T = s[x], q = (N = (P = T == null ? void 0 : T.meteo) == null ? void 0 : P.wave) == null ? void 0 : N.sig, R = (A = T == null ? void 0 : T.meteo) == null ? void 0 : A.wind, J = x ? p(T.eta).diff(p(s[x - 1].eta), "hour", !0) : 0;
|
|
721
|
+
e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...q, dgThd4Wv: c, svThd4Wv: d, hvThd4Wv: h }), (q == null ? void 0 : q.height) >= c ? T.isDangerous = !0 : (q == null ? void 0 : q.height) >= d ? T.isSevere = !0 : (q == null ? void 0 : q.height) >= h && (T.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: u, svThd4Wd: y, hvThd4Wd: v }), (R == null ? void 0 : R.scale) >= u ? (T.isDangerous = !0, delete T.isSevere, delete T.isHeavy) : (R == null ? void 0 : R.scale) > y ? (T.isDangerous || (T.isSevere = !0), delete T.isHeavy) : (R == null ? void 0 : R.scale) === v && !T.isDangerous && !T.isSevere && (T.isHeavy = !0), i += T.isDangerous ? J : 0, n += T.isSevere ? J : 0, o += T.isHeavy ? J : 0;
|
|
722
722
|
}
|
|
723
|
-
return i = Math.round(i * 100) / 100,
|
|
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: u, svThd4Wd: y, hvThd4Wd: v }, sig: { dgThd4Wv: c, svThd4Wv: d, hvThd4Wv: h } };
|
|
724
724
|
}
|
|
725
725
|
}
|
|
726
726
|
const xt = new yt();
|
|
@@ -731,7 +731,7 @@ try {
|
|
|
731
731
|
} finally {
|
|
732
732
|
}
|
|
733
733
|
const Mt = new mt("", !0);
|
|
734
|
-
var
|
|
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
735
|
class O {
|
|
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
|
|
@@ -746,10 +746,10 @@ class O {
|
|
|
746
746
|
* @return [0.55, 0.85]
|
|
747
747
|
*/
|
|
748
748
|
static blockCoefficient(s, t, a, i) {
|
|
749
|
-
let
|
|
750
|
-
|
|
751
|
-
const
|
|
752
|
-
return
|
|
749
|
+
let n = Math.round(s / (t * a * i) * 100) / 100;
|
|
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((c) => Math.abs(c - n));
|
|
752
|
+
return o[e.indexOf(Math.min(...e))];
|
|
753
753
|
}
|
|
754
754
|
/**
|
|
755
755
|
* @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
|
|
@@ -783,7 +783,7 @@ class O {
|
|
|
783
783
|
0.8: [2.6, -13.1, -15.1],
|
|
784
784
|
0.85: [3.1, -18.7, 28]
|
|
785
785
|
};
|
|
786
|
-
let
|
|
786
|
+
let o = {
|
|
787
787
|
0.55: [1.7, -1.4, -7.4],
|
|
788
788
|
0.6: [2.2, -2.5, -9.7],
|
|
789
789
|
0.65: [2.6, -3.7, -11.6],
|
|
@@ -792,7 +792,7 @@ class O {
|
|
|
792
792
|
0.8: [3, -16.3, -21.6],
|
|
793
793
|
0.85: [3.4, -20.9, 31.8]
|
|
794
794
|
}[s];
|
|
795
|
-
return a === "Laden" && (
|
|
795
|
+
return a === "Laden" && (o = i[s]), o[0] + o[1] * t + o[2] * Math.pow(t, 2);
|
|
796
796
|
}
|
|
797
797
|
/**
|
|
798
798
|
* 失速方向因子
|
|
@@ -817,13 +817,13 @@ class O {
|
|
|
817
817
|
* @param displacement 排水量,m^3
|
|
818
818
|
* @param loadCondition
|
|
819
819
|
* @param tag
|
|
820
|
-
* @param bn
|
|
820
|
+
* // @param bn
|
|
821
|
+
* @param kts
|
|
821
822
|
* @private
|
|
822
823
|
*/
|
|
823
|
-
static vesselTagFactor(s, t, a, i
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
return a === "container" ? o = 0.7 * i + Math.pow(i, 6.5) / (22 * Math.pow(s, 2 / 3)) : t === "Ballast" ? o = 0.7 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(s, 2 / 3)) : o = 0.5 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(s, 2 / 3)), o;
|
|
824
|
+
static vesselTagFactor(s, t, a, i) {
|
|
825
|
+
let n;
|
|
826
|
+
return a === "container" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (22 * Math.pow(s, 2 / 3)) : t === "Ballast" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (2.7 * Math.pow(s, 2 / 3)) : n = 0.5 * i / 2 + Math.pow(i, 3) / (2.7 * Math.pow(s, 2 / 3)), n;
|
|
827
827
|
}
|
|
828
828
|
/**
|
|
829
829
|
* 浪高影响因子
|
|
@@ -845,16 +845,16 @@ class O {
|
|
|
845
845
|
*/
|
|
846
846
|
static assembleProperties(s, t, a, i) {
|
|
847
847
|
var y;
|
|
848
|
-
const
|
|
848
|
+
const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, o = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, c = s.deadweight ?? 67035.7773, d = ((y = s == null ? void 0 : s.type) == null ? void 0 : y.toLowerCase()) || "common";
|
|
849
849
|
return {
|
|
850
|
-
tag:
|
|
851
|
-
lbp:
|
|
850
|
+
tag: d.indexOf("container") > -1 ? "container" : d.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
851
|
+
lbp: n,
|
|
852
852
|
loadCondition: t,
|
|
853
|
-
draught:
|
|
853
|
+
draught: o,
|
|
854
854
|
breadthMoulded: e,
|
|
855
855
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
856
856
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
857
|
-
displacement: Math.round((
|
|
857
|
+
displacement: Math.round((c / 1.025 + o * e * n * 0.7) * 1e4) / 1e4,
|
|
858
858
|
// 换算为m/s
|
|
859
859
|
speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
860
860
|
bearing: i || 90
|
|
@@ -871,41 +871,41 @@ class O {
|
|
|
871
871
|
* @param useRouteParam true 启用设置速度
|
|
872
872
|
* @param options
|
|
873
873
|
*/
|
|
874
|
-
static async speedLoseAt(s, t, a, i = "",
|
|
875
|
-
let
|
|
876
|
-
if (t.velocity && e && (s.speed =
|
|
877
|
-
let
|
|
874
|
+
static async speedLoseAt(s, t, a, i = "", n = 2, o = !0, e = !1, c = {}) {
|
|
875
|
+
let d;
|
|
876
|
+
if (t.velocity && e && (s.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
|
|
877
|
+
let h;
|
|
878
878
|
try {
|
|
879
879
|
i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
|
|
880
880
|
const { weatherModels: M, marineModels: j } = await it.autoPickMeteoModel(i), I = await Mt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
|
|
881
|
-
...
|
|
881
|
+
...c,
|
|
882
882
|
pastDays: 1,
|
|
883
883
|
forecastDays: 1,
|
|
884
884
|
weatherModels: M,
|
|
885
885
|
marineModels: j
|
|
886
|
-
}), [
|
|
887
|
-
|
|
886
|
+
}), [w] = it.pickHourly(I, a);
|
|
887
|
+
h = it.toLegacy(w);
|
|
888
888
|
} catch (M) {
|
|
889
|
-
C.warn("[%s] meteo2 spot(%j) forecast failed: %s",
|
|
889
|
+
C.warn("[%s] meteo2 spot(%j) forecast failed: %s", c.requestId, { ...t, eta: a.utc().format(), source: i }, M);
|
|
890
890
|
}
|
|
891
|
-
const
|
|
892
|
-
|
|
893
|
-
meteo: { ...
|
|
894
|
-
wxFactor:
|
|
895
|
-
cFactor:
|
|
896
|
-
speed: t.velocity && e ? t.velocity :
|
|
891
|
+
const u = O.currentFactor(s.bearing, h == null ? void 0 : h.current, n), y = O.weatherFactor(s, h, u), v = Math.round(s.speed * 1.943844 * 100) / 100;
|
|
892
|
+
d = {
|
|
893
|
+
meteo: { ...h },
|
|
894
|
+
wxFactor: y,
|
|
895
|
+
cFactor: u,
|
|
896
|
+
speed: t.velocity && e ? t.velocity : v < 0 ? 1 : v,
|
|
897
897
|
eta: a.utc().format(),
|
|
898
898
|
etd: a.utc().format()
|
|
899
899
|
};
|
|
900
900
|
} else
|
|
901
|
-
|
|
901
|
+
d = {
|
|
902
902
|
wxFactor: 0,
|
|
903
903
|
cFactor: 0,
|
|
904
|
-
speed: t.velocity && e ? t.velocity : Math.round(
|
|
904
|
+
speed: t.velocity && e ? t.velocity : Math.round(s.speed * 1.943844 * 100) / 100,
|
|
905
905
|
eta: a.utc().format(),
|
|
906
906
|
etd: a.utc().format()
|
|
907
907
|
};
|
|
908
|
-
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...
|
|
908
|
+
return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...d, ...t };
|
|
909
909
|
}
|
|
910
910
|
/**
|
|
911
911
|
* 基于步长计算失速样本
|
|
@@ -921,53 +921,53 @@ class O {
|
|
|
921
921
|
* @param options
|
|
922
922
|
* @private
|
|
923
923
|
*/
|
|
924
|
-
static async speedLoseInHoursStep(s, t, a, i,
|
|
924
|
+
static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", c = !0, d = !1, h = {}) {
|
|
925
925
|
t.utc();
|
|
926
|
-
const
|
|
927
|
-
let M = 0, j = 0, I,
|
|
928
|
-
for (let
|
|
929
|
-
let
|
|
930
|
-
|
|
931
|
-
const
|
|
932
|
-
if (s.bearing =
|
|
933
|
-
|
|
934
|
-
const k =
|
|
926
|
+
const u = t.clone().add(14, "days"), y = [], v = [];
|
|
927
|
+
let M = 0, j = 0, I, w;
|
|
928
|
+
for (let g = 0; g < o.length - 1; g++) {
|
|
929
|
+
let r = o[g];
|
|
930
|
+
r.distanceFromStart = Math.round((n + j) * 1e3) / 1e3;
|
|
931
|
+
const b = o[g + 1];
|
|
932
|
+
if (s.bearing = L.calculateBearing(r, b, !b.gcToPrevious), r.bearing = s.bearing, r.suspend && d) {
|
|
933
|
+
r.eta = r.eta || t.utc().format(), r.elapsed = r.elapsed ?? 0;
|
|
934
|
+
const k = r.suspend - r.elapsed;
|
|
935
935
|
if (i - M > k)
|
|
936
|
-
i = i - M - k, t.add(k, "hour"),
|
|
936
|
+
i = i - M - k, t.add(k, "hour"), r.elapsed = r.suspend;
|
|
937
937
|
else {
|
|
938
938
|
const S = i - M;
|
|
939
|
-
|
|
939
|
+
r.elapsed += S, t.add(S, "hour"), i = 0;
|
|
940
940
|
}
|
|
941
|
-
if (C == null || C.info(`[%s] suspend ${
|
|
942
|
-
return
|
|
941
|
+
if (C == null || C.info(`[%s] suspend ${r.elapsed} hours at %j, and remain ${i} hours need to go...`, h.requestId, r), i === 0)
|
|
942
|
+
return r.distanceFromPrevious = j, { etd: t, from: w || r, to: r, next: o.filter((S) => S), wps: y, days: v };
|
|
943
943
|
} else
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
const m =
|
|
947
|
-
let
|
|
948
|
-
if (M +
|
|
949
|
-
if (M +=
|
|
950
|
-
`[%s] go to %j from %j with ${m}nm, and cost ${
|
|
951
|
-
|
|
952
|
-
{ lat:
|
|
953
|
-
{ lat:
|
|
954
|
-
), j += m,
|
|
955
|
-
I =
|
|
944
|
+
r.suspend = 0;
|
|
945
|
+
c = t.isAfter(u) ? !1 : c, r = await O.speedLoseAt(s, r, t, e, 0, c, d, h), w = w || r, r.important && y.push(r), t.isSameOrAfter(a) && (v.push(r), a.add(24, "hour"));
|
|
946
|
+
const m = L.calculateDistance(r, b, !b.gcToPrevious);
|
|
947
|
+
let l = Math.round(m / w.speed * 1e5) / 1e5;
|
|
948
|
+
if (M + l < i) {
|
|
949
|
+
if (M += l, t.add(l, "hour"), delete o[g], C == null || C.debug(
|
|
950
|
+
`[%s] go to %j from %j with ${m}nm, and cost ${l} hours`,
|
|
951
|
+
h.requestId,
|
|
952
|
+
{ lat: b.lat, lng: b.lng },
|
|
953
|
+
{ lat: w.lat, lng: w.lng, etd: w.etd }
|
|
954
|
+
), j += m, o.filter((k) => k).length <= 1) {
|
|
955
|
+
I = b, I.eta = t.utc().format(), I.distanceFromPrevious = m, I.distanceFromStart = Math.round((n + j) * 1e4) / 1e4, y.push(I), delete o[g + 1];
|
|
956
956
|
break;
|
|
957
957
|
}
|
|
958
958
|
} else {
|
|
959
|
-
|
|
960
|
-
const k =
|
|
961
|
-
I =
|
|
962
|
-
`[%s] go to %j from %j with ${k}nm, and cost ${
|
|
963
|
-
|
|
959
|
+
l = i - M, t.add(l, "hour");
|
|
960
|
+
const k = z.roundPrecision(w.speed * l, 5);
|
|
961
|
+
I = L.calculateCoordinate(r, s.bearing, k, "nauticalmiles", !b.gcToPrevious), I.eta = t.utc().format(), o[g] = I, C == null || C.debug(
|
|
962
|
+
`[%s] go to %j from %j with ${k}nm, and cost ${l} hours`,
|
|
963
|
+
h.requestId,
|
|
964
964
|
{ lat: I.lat, lng: I.lng },
|
|
965
|
-
{ lat:
|
|
966
|
-
), j += k, I.distanceFromPrevious = Math.round(j * 1e4) / 1e4, I.distanceFromStart = Math.round((
|
|
965
|
+
{ lat: r.lat, lng: r.lng, etd: r.etd }
|
|
966
|
+
), j += k, I.distanceFromPrevious = Math.round(j * 1e4) / 1e4, I.distanceFromStart = Math.round((n + j) * 1e4) / 1e4;
|
|
967
967
|
break;
|
|
968
968
|
}
|
|
969
969
|
}
|
|
970
|
-
return { etd: t, from:
|
|
970
|
+
return { etd: t, from: w, to: I, next: o.filter((g) => g), wps: y, days: v };
|
|
971
971
|
}
|
|
972
972
|
/**
|
|
973
973
|
* 洋流影响因子
|
|
@@ -979,25 +979,26 @@ class O {
|
|
|
979
979
|
const i = (s - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
980
980
|
if (Math.abs(i) === Math.PI / 2)
|
|
981
981
|
return 0;
|
|
982
|
-
let
|
|
983
|
-
return a & 2 ?
|
|
982
|
+
let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(i);
|
|
983
|
+
return a & 2 ? n = Math.ceil(n * 100) / 100 : a & 1 ? n = Math.floor(n * 100) / 100 : n = Math.round(n * 100) / 100, Math.abs(n) > 5 ? 0 : n;
|
|
984
984
|
}
|
|
985
985
|
/**
|
|
986
986
|
* 风浪影响因子
|
|
987
987
|
* @param props 船舶档案
|
|
988
988
|
* @param wwc 气象要素
|
|
989
|
+
* @param cFactor 洋流因子
|
|
989
990
|
*/
|
|
990
|
-
static weatherFactor(s, t) {
|
|
991
|
-
var
|
|
991
|
+
static weatherFactor(s, t, a = 0) {
|
|
992
|
+
var v, M, j, I, w, g, r;
|
|
992
993
|
C == null || C.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
993
|
-
const
|
|
994
|
-
let
|
|
995
|
-
|
|
996
|
-
const
|
|
997
|
-
let
|
|
998
|
-
|
|
999
|
-
const
|
|
1000
|
-
return C == null || C.debug("wave wx factor = %d",
|
|
994
|
+
const i = O.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = O.froudeNumber(s.speed - n, s.lbp), e = O.amendFactor(i, o, s.loadCondition);
|
|
995
|
+
let c = Math.abs(s.bearing % 360 - (((v = t == null ? void 0 : t.wind) == null ? void 0 : v.degree) % 360 || 0));
|
|
996
|
+
c = c > 180 ? 360 - c : c;
|
|
997
|
+
const d = O.directionFactor(c, (M = t == null ? void 0 : t.wind) == null ? void 0 : M.scale), h = O.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (j = t == null ? void 0 : t.wind) == null ? void 0 : j.kts);
|
|
998
|
+
let u = d * e * h / 100 * (s.speed - n);
|
|
999
|
+
u = Math.round(u * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(u) > 1 && (u = u / (Math.abs(Math.round(u)) + 1)), C == null || C.debug("wind wx factor = %d", u), c = Math.abs(s.bearing % 360 - (((w = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : w.degree) % 360 || 0));
|
|
1000
|
+
const y = O.waveHeightFactor(((r = (g = t == null ? void 0 : t.wave) == null ? void 0 : g.sig) == null ? void 0 : r.height) ?? 1, c);
|
|
1001
|
+
return C == null || C.debug("wave wx factor = %d", y), u = Math.abs(u) > Math.abs(y) ? u : u * 0.3 + y * 0.7, C == null || C.debug("weather factor = %d", u), u = Math.abs(u) > 3 ? 3 * (Math.abs(u) / u) + Math.abs(u) / u * (Math.abs(u) - 2) * 0.1 : u, Math.round((u || 0) * 100) / 100;
|
|
1001
1002
|
}
|
|
1002
1003
|
/**
|
|
1003
1004
|
* 全程失速分析(走完航程)
|
|
@@ -1012,11 +1013,11 @@ class O {
|
|
|
1012
1013
|
* @param useRouteParam
|
|
1013
1014
|
* @param options
|
|
1014
1015
|
*/
|
|
1015
|
-
static async analyseInstant(s, t, a, i,
|
|
1016
|
+
static async analyseInstant(s, t, a, i, n, o = "", e = 0, c = !0, d = !1, h = {}) {
|
|
1016
1017
|
var K, G, X, Q, Z, $;
|
|
1017
|
-
const
|
|
1018
|
-
s.lng =
|
|
1019
|
-
const { route: y, waypoints:
|
|
1018
|
+
const u = p().valueOf();
|
|
1019
|
+
s.lng = z.convertToStdLng(s.lng);
|
|
1020
|
+
const { route: y, waypoints: v } = n.points, M = L.calculateSubRoute(s, y);
|
|
1020
1021
|
if (((K = M[0]) == null ? void 0 : K.length) <= 1)
|
|
1021
1022
|
return;
|
|
1022
1023
|
const { v0: j, label: I } = s.sog ? {
|
|
@@ -1027,62 +1028,66 @@ class O {
|
|
|
1027
1028
|
v0: i.speed,
|
|
1028
1029
|
label: "CP"
|
|
1029
1030
|
/* Cp */
|
|
1030
|
-
},
|
|
1031
|
-
|
|
1032
|
-
const
|
|
1031
|
+
}, w = O.assembleProperties(a, i.loadCondition, j, 0), g = v.length ? L.calculateSubWaypoints(s, v) : [];
|
|
1032
|
+
g.forEach((Y) => Y.important = !0);
|
|
1033
|
+
const r = {
|
|
1033
1034
|
from: { ...s },
|
|
1034
1035
|
route: M,
|
|
1035
|
-
waypoints:
|
|
1036
|
+
waypoints: g,
|
|
1036
1037
|
v0: j,
|
|
1037
1038
|
label: I
|
|
1038
|
-
},
|
|
1039
|
+
}, b = {
|
|
1039
1040
|
hours: [],
|
|
1040
1041
|
days: [],
|
|
1041
1042
|
wps: []
|
|
1042
1043
|
};
|
|
1043
|
-
e || (
|
|
1044
|
-
let m =
|
|
1045
|
-
t =
|
|
1044
|
+
e || (L.calculateRouteDistance(M) / i.speed <= 72 ? e = 3 : e = 6);
|
|
1045
|
+
let m = L.simplifyRouteToCoordinates(M, g, 0), l = 0, k = 0, S = 0, D = 0;
|
|
1046
|
+
t = p(t).utc();
|
|
1046
1047
|
const P = t.clone();
|
|
1047
1048
|
for (; m.length > 0; ) {
|
|
1048
1049
|
const Y = e - t.hour() % e, B = Math.ceil(t.clone().add(Y, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, F = await O.speedLoseInHoursStep(
|
|
1049
|
-
|
|
1050
|
+
w,
|
|
1050
1051
|
t,
|
|
1051
1052
|
P,
|
|
1052
1053
|
B,
|
|
1053
|
-
|
|
1054
|
+
l,
|
|
1054
1055
|
m,
|
|
1055
|
-
|
|
1056
|
-
r,
|
|
1056
|
+
o,
|
|
1057
1057
|
c,
|
|
1058
|
-
|
|
1058
|
+
d,
|
|
1059
|
+
h
|
|
1059
1060
|
);
|
|
1060
|
-
(G = F.from) != null && G.speed && (
|
|
1061
|
+
if ((G = F.from) != null && G.speed && (b.hours.push(F.from), b.wps.push(...F.wps), b.days.push(...F.days)), m = F == null ? void 0 : F.next, !m.length) {
|
|
1062
|
+
const W = await O.speedLoseAt(w, F.to, F.to.eta, o, 0, c, d, h);
|
|
1063
|
+
b.hours.push(W);
|
|
1064
|
+
}
|
|
1065
|
+
l += Math.round((((X = F == null ? void 0 : F.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
1061
1066
|
}
|
|
1062
|
-
const N =
|
|
1067
|
+
const N = b.hours;
|
|
1063
1068
|
for (let Y = 0; Y < N.length - 1; Y++) {
|
|
1064
|
-
const B =
|
|
1069
|
+
const B = p(N[Y + 1].eta).diff(N[Y].etd, "hour", !0) || 1;
|
|
1065
1070
|
k += (N[Y].wxFactor || 0) * B, S += (N[Y].cFactor || 0) * B, D += B;
|
|
1066
1071
|
}
|
|
1067
|
-
(Q =
|
|
1068
|
-
Y.positionTime =
|
|
1069
|
-
const F =
|
|
1072
|
+
(Q = b.wps) == null || Q.forEach((Y, B) => {
|
|
1073
|
+
Y.positionTime = p.utc(Y.etd || Y.eta).unix();
|
|
1074
|
+
const F = b.wps[B - 1];
|
|
1070
1075
|
if (F) {
|
|
1071
|
-
const
|
|
1072
|
-
Y.avgSpd = Math.round(
|
|
1076
|
+
const W = Y.distanceFromStart - F.distanceFromStart, H = p(Y.eta || Y.etd).diff(p(F.etd || F.eta), "h", !0);
|
|
1077
|
+
Y.avgSpd = Math.round(W / H * 100) / 100, F.bearing = L.calculateBearing(F, Y);
|
|
1073
1078
|
}
|
|
1074
|
-
}),
|
|
1075
|
-
const A =
|
|
1076
|
-
|
|
1077
|
-
const { distanceInECA: T, hoursInECA: q, totalDgoConsInECA: R, eca: J } = await this.calculateECA(
|
|
1078
|
-
|
|
1079
|
+
}), b.wps = (Z = b.wps) == null ? void 0 : Z.reduce((Y, B) => (Y.some((F) => Math.round(F.positionTime / 60) === Math.round(B.positionTime / 60)) || Y.push(B), Y), []), r.sample = b;
|
|
1080
|
+
const A = b.hours.at(0), x = b.hours.at(-1);
|
|
1081
|
+
r.distance = Math.round(x.distanceFromStart * 1e3) / 1e3, r.etd = p(A.eta).utc().format(), r.eta = p(x.eta).utc().format(), r.wxFactor = Math.round(k / D * 1e3) / 1e3, r.cFactor = Math.round(S / D * 1e3) / 1e3, r.avgSpeed = Math.round(x.distanceFromStart / D * 1e3) / 1e3, r.totalHrs = Math.round(D * 1e3) / 1e3;
|
|
1082
|
+
const { distanceInECA: T, hoursInECA: q, totalDgoConsInECA: R, eca: J } = await this.calculateECA(r, i, h), tt = z.roundPrecision(i.fo / 24 * (D - q), 3), at = z.roundPrecision(i.dgo / 24 * D, 3);
|
|
1083
|
+
r.extend = {
|
|
1079
1084
|
eca: J,
|
|
1080
1085
|
distanceInECA: T,
|
|
1081
1086
|
hoursInECA: q,
|
|
1082
1087
|
totalDgoConsInECA: R
|
|
1083
|
-
},
|
|
1084
|
-
const et =
|
|
1085
|
-
return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",
|
|
1088
|
+
}, r.totalFoCons = tt < 0 ? 0 : tt, r.totalDgoCons = at;
|
|
1089
|
+
const et = p().valueOf() - u, ot = (($ = b == null ? void 0 : b.hours) == null ? void 0 : $.length) || 1;
|
|
1090
|
+
return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, et, ot, Math.round(et / ot * 1e3) / 1e3), r;
|
|
1086
1091
|
}
|
|
1087
1092
|
/**
|
|
1088
1093
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -1099,61 +1104,61 @@ class O {
|
|
|
1099
1104
|
* @param useRouteParam
|
|
1100
1105
|
* @param options
|
|
1101
1106
|
*/
|
|
1102
|
-
static async analyseInstantWithThreshed(s, t, a, i,
|
|
1107
|
+
static async analyseInstantWithThreshed(s, t, a, i, n, o, e, c = "", d = 3, h = !0, u = !1, y = {}) {
|
|
1103
1108
|
var X, Q, Z, $, Y, B;
|
|
1104
|
-
const
|
|
1105
|
-
s.lng =
|
|
1109
|
+
const v = p().valueOf();
|
|
1110
|
+
s.lng = z.convertToStdLng(s.lng);
|
|
1106
1111
|
const { v0: M, label: j } = s.sog ? {
|
|
1107
1112
|
v0: s.sog,
|
|
1108
1113
|
label: s.label || "Other"
|
|
1109
1114
|
/* Instruct */
|
|
1110
1115
|
} : {
|
|
1111
|
-
v0:
|
|
1116
|
+
v0: n.speed,
|
|
1112
1117
|
label: "CP"
|
|
1113
1118
|
/* Cp */
|
|
1114
|
-
}, I = O.assembleProperties(i,
|
|
1115
|
-
if (((X =
|
|
1119
|
+
}, I = O.assembleProperties(i, n.loadCondition, M, 0), w = L.calculateSubRoute(s, o);
|
|
1120
|
+
if (((X = w[0]) == null ? void 0 : X.length) <= 1)
|
|
1116
1121
|
return;
|
|
1117
|
-
const
|
|
1118
|
-
|
|
1119
|
-
let
|
|
1122
|
+
const g = e.length ? L.calculateSubWaypoints(s, e) : [];
|
|
1123
|
+
g.forEach((F) => F.important = !0);
|
|
1124
|
+
let r = L.simplifyRouteToCoordinates(w, g, 0), b = 0, m = 0, l = 0, k = 0;
|
|
1120
1125
|
const S = {
|
|
1121
1126
|
hours: [],
|
|
1122
1127
|
wps: [],
|
|
1123
1128
|
days: []
|
|
1124
1129
|
};
|
|
1125
|
-
t =
|
|
1130
|
+
t = p(t).utc();
|
|
1126
1131
|
const D = t.clone();
|
|
1127
|
-
for (;
|
|
1128
|
-
const F =
|
|
1129
|
-
let
|
|
1130
|
-
|
|
1131
|
-
const H = await O.speedLoseInHoursStep(I, t, D,
|
|
1132
|
-
if ((Q = H.from) != null && Q.speed && (S.hours.push(H.from), H != null && H.wps && S.wps.push(...H.wps), S.days.push(...H.days)),
|
|
1132
|
+
for (; r.length > 0; ) {
|
|
1133
|
+
const F = d - t.hour() % d;
|
|
1134
|
+
let W = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
1135
|
+
W = t.clone().add(W, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : W;
|
|
1136
|
+
const H = await O.speedLoseInHoursStep(I, t, D, W, b, r, c, h, u, y);
|
|
1137
|
+
if ((Q = H.from) != null && Q.speed && (S.hours.push(H.from), H != null && H.wps && S.wps.push(...H.wps), S.days.push(...H.days)), r = H == null ? void 0 : H.next, r.length || S.hours.push(H == null ? void 0 : H.to), b += Math.round((((Z = H == null ? void 0 : H.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !W)
|
|
1133
1138
|
break;
|
|
1134
1139
|
}
|
|
1135
|
-
S.wps = ($ = S.wps) == null ? void 0 : $.reduce((F,
|
|
1136
|
-
const H = S.wps[
|
|
1140
|
+
S.wps = ($ = S.wps) == null ? void 0 : $.reduce((F, W) => (F.some((H) => Math.round(p(H.etd).unix() / 60) === Math.round(p(W.etd).unix() / 60)) || F.push(W), F), []), (Y = S.wps) == null || Y.forEach((F, W) => {
|
|
1141
|
+
const H = S.wps[W - 1];
|
|
1137
1142
|
if (H) {
|
|
1138
|
-
const rt = F.distanceFromStart - H.distanceFromStart, dt =
|
|
1143
|
+
const rt = F.distanceFromStart - H.distanceFromStart, dt = p(F.eta || F.etd).diff(p(H.etd || H.eta), "h", !0);
|
|
1139
1144
|
F.avgSpd = Math.round(rt / dt * 100) / 100;
|
|
1140
|
-
const ut =
|
|
1145
|
+
const ut = L.calculateBearing(H, F);
|
|
1141
1146
|
H.bearing = ut;
|
|
1142
1147
|
}
|
|
1143
1148
|
});
|
|
1144
1149
|
const P = S.hours;
|
|
1145
1150
|
for (let F = 0; F < P.length - 1; F++) {
|
|
1146
|
-
const
|
|
1147
|
-
m += P[F].wxFactor *
|
|
1151
|
+
const W = p(P[F + 1].eta).diff(P[F].etd, "hour", !0);
|
|
1152
|
+
m += P[F].wxFactor * W, l += P[F].cFactor * W, k += W;
|
|
1148
1153
|
}
|
|
1149
|
-
const N = S.hours.at(0), A = S.hours.at(-1), x = await
|
|
1154
|
+
const N = S.hours.at(0), A = S.hours.at(-1), x = await L.calculateRangeRoute(N, A, w), T = await L.calculateRangeWaypoints(N, A, w, g), q = {
|
|
1150
1155
|
sample: S,
|
|
1151
1156
|
distance: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1152
1157
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1153
|
-
etd:
|
|
1154
|
-
eta:
|
|
1158
|
+
etd: p(N.eta).utc().format(),
|
|
1159
|
+
eta: p(A == null ? void 0 : A.eta).utc().format(),
|
|
1155
1160
|
wxFactor: Math.round(m / k * 1e3) / 1e3,
|
|
1156
|
-
cFactor: Math.round(
|
|
1161
|
+
cFactor: Math.round(l / k * 1e3) / 1e3,
|
|
1157
1162
|
avgSpeed: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) / k * 1e3) / 1e3,
|
|
1158
1163
|
totalHrs: Math.round(k * 1e3) / 1e3,
|
|
1159
1164
|
from: N,
|
|
@@ -1162,14 +1167,14 @@ class O {
|
|
|
1162
1167
|
waypoints: T,
|
|
1163
1168
|
v0: M,
|
|
1164
1169
|
label: j
|
|
1165
|
-
}, { distanceInECA: R, hoursInECA: J, totalDgoConsInECA: tt, eca: at } = await this.calculateECA(q,
|
|
1170
|
+
}, { distanceInECA: R, hoursInECA: J, totalDgoConsInECA: tt, eca: at } = await this.calculateECA(q, n, y), nt = z.roundPrecision(n.fo / 24 * (k - J), 3), et = z.roundPrecision(n.dgo / 24 * k, 3);
|
|
1166
1171
|
q.extend = {
|
|
1167
1172
|
eca: at,
|
|
1168
1173
|
distanceInECA: R,
|
|
1169
1174
|
hoursInECA: J,
|
|
1170
1175
|
totalDgoConsInECA: tt
|
|
1171
1176
|
}, q.totalDgoCons = et, q.totalFoCons = nt < 0 ? 0 : nt;
|
|
1172
|
-
const K =
|
|
1177
|
+
const K = p().valueOf() - v, G = ((B = S == null ? void 0 : S.hours) == null ? void 0 : B.length) || 1;
|
|
1173
1178
|
return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", y == null ? void 0 : y.requestId, K, G, Math.round(K / G * 1e3) / 1e3), q;
|
|
1174
1179
|
}
|
|
1175
1180
|
/**
|
|
@@ -1187,59 +1192,59 @@ class O {
|
|
|
1187
1192
|
* @param lane 基础航线(重要转向点)
|
|
1188
1193
|
* @param options
|
|
1189
1194
|
*/
|
|
1190
|
-
static async analyseCost(s, t, a, i,
|
|
1191
|
-
var
|
|
1192
|
-
const
|
|
1195
|
+
static async analyseCost(s, t, a, i, n = {}) {
|
|
1196
|
+
var w, g;
|
|
1197
|
+
const o = p().valueOf(), e = [];
|
|
1193
1198
|
s.speedStep = s.speedStep || 3, s.alterStep = s.alterStep ?? 1;
|
|
1194
|
-
const
|
|
1195
|
-
let
|
|
1196
|
-
a.forEach((
|
|
1197
|
-
const
|
|
1198
|
-
|
|
1199
|
-
}),
|
|
1200
|
-
const
|
|
1201
|
-
let
|
|
1202
|
-
for (const
|
|
1203
|
-
const
|
|
1199
|
+
const c = L.calculateRouteDistance(i.route);
|
|
1200
|
+
let d = 0;
|
|
1201
|
+
a.forEach((r) => {
|
|
1202
|
+
const b = Math.ceil(c / r.speed / 24);
|
|
1203
|
+
d = d < b ? b : d;
|
|
1204
|
+
}), d = d * 1.3;
|
|
1205
|
+
const h = p.utc(s.etd).add(d ?? 14, "day");
|
|
1206
|
+
let u = 1;
|
|
1207
|
+
for (const r of a) {
|
|
1208
|
+
const b = JSON.parse(JSON.stringify(i.route)), m = JSON.parse(JSON.stringify(i.waypoints)), l = await O.analyseInstantWithThreshed(
|
|
1204
1209
|
{ lat: s.lat, lng: s.lng },
|
|
1205
1210
|
s.etd,
|
|
1206
|
-
|
|
1211
|
+
h,
|
|
1207
1212
|
t,
|
|
1208
|
-
|
|
1209
|
-
|
|
1213
|
+
r,
|
|
1214
|
+
b,
|
|
1210
1215
|
m,
|
|
1211
1216
|
s.meteoVendor,
|
|
1212
1217
|
s.speedStep,
|
|
1213
1218
|
s.useMeteo,
|
|
1214
1219
|
s.useRouteParam,
|
|
1215
|
-
|
|
1220
|
+
n
|
|
1216
1221
|
);
|
|
1217
|
-
|
|
1218
|
-
cost:
|
|
1219
|
-
hire:
|
|
1220
|
-
bunker:
|
|
1221
|
-
distance:
|
|
1222
|
-
hours:
|
|
1223
|
-
cp: `${
|
|
1224
|
-
})),
|
|
1222
|
+
l && (await O.calculateCost(l, r, s, n), e.push(l), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, u, s.etd, h.format(), {
|
|
1223
|
+
cost: l.cost.total,
|
|
1224
|
+
hire: l.cost.hire,
|
|
1225
|
+
bunker: l.cost.bunker,
|
|
1226
|
+
distance: l.distance,
|
|
1227
|
+
hours: l.totalHrs,
|
|
1228
|
+
cp: `${r.speed}/${r.fo}/${r.dgo}`
|
|
1229
|
+
})), u++;
|
|
1225
1230
|
}
|
|
1226
|
-
e.sort((
|
|
1227
|
-
const y = e.at(0),
|
|
1228
|
-
if (M.push({ combined: !1, speeds: [y], cost: (
|
|
1229
|
-
const
|
|
1231
|
+
e.sort((r, b) => r.cost.total - b.cost.total);
|
|
1232
|
+
const y = e.at(0), v = e.at(1), M = [];
|
|
1233
|
+
if (M.push({ combined: !1, speeds: [y], cost: (w = y.cost) == null ? void 0 : w.total }), v) {
|
|
1234
|
+
const r = y.cost.cp, b = v.cost.cp, m = p(y.eta), l = p(y.etd), k = m.diff(l, "days", !0);
|
|
1230
1235
|
let S = Math.ceil(k / 2);
|
|
1231
1236
|
S = S > 7 ? 7 : S < s.alterStep ? s.alterStep : S;
|
|
1232
|
-
let D = 2, P = { combined: !1, speeds: [
|
|
1237
|
+
let D = 2, P = { combined: !1, speeds: [v], cost: (g = v.cost) == null ? void 0 : g.total }, N;
|
|
1233
1238
|
for (; S >= s.alterStep; ) {
|
|
1234
|
-
const A = await O.combinedAnalyse(s, t,
|
|
1239
|
+
const A = await O.combinedAnalyse(s, t, h, [r, b], i, S, { ...n, level: D });
|
|
1235
1240
|
if (P.cost > A.cost ? N ? (N == null ? void 0 : N.cost) > A.cost && (N = A) : (N = P, P = A) : (!N || (N == null ? void 0 : N.cost) > A.cost) && (N = A), S <= s.alterStep)
|
|
1236
1241
|
break;
|
|
1237
1242
|
S = Math.ceil(S / 2), D += 1;
|
|
1238
1243
|
}
|
|
1239
1244
|
M.push(P), N && M.push(N);
|
|
1240
1245
|
}
|
|
1241
|
-
const I =
|
|
1242
|
-
return C == null || C.info("[%s] analyse elapsed: %d ms",
|
|
1246
|
+
const I = p().valueOf() - o;
|
|
1247
|
+
return C == null || C.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, I), M.sort((r, b) => r.cost - b.cost);
|
|
1243
1248
|
}
|
|
1244
1249
|
/**
|
|
1245
1250
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1251,24 +1256,24 @@ class O {
|
|
|
1251
1256
|
* @param step 步长,7,4,2,1
|
|
1252
1257
|
* @param options
|
|
1253
1258
|
*/
|
|
1254
|
-
static async combinedAnalyse(s, t, a, i,
|
|
1255
|
-
e.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", e.requestId, e.level,
|
|
1256
|
-
const
|
|
1259
|
+
static async combinedAnalyse(s, t, a, i, n, o, e = {}) {
|
|
1260
|
+
e.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", e.requestId, e.level, o);
|
|
1261
|
+
const c = await O.alternateAnalyse(s, t, a, i, 0, n, o, e), d = c.reduce((b, m) => b + m.cost.total, 0), h = c.reduce((b, m) => b + m.cost.hire, 0), u = c.reduce((b, m) => b + m.cost.bunker, 0), y = c.reduce((b, m) => b + m.distance, 0), v = c.reduce((b, m) => b + m.totalHrs, 0);
|
|
1257
1262
|
C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j", e.requestId, e.level, {
|
|
1258
|
-
cost:
|
|
1259
|
-
hire:
|
|
1260
|
-
bunker:
|
|
1263
|
+
cost: d,
|
|
1264
|
+
hire: h,
|
|
1265
|
+
bunker: u,
|
|
1261
1266
|
distance: y,
|
|
1262
|
-
hours:
|
|
1267
|
+
hours: v
|
|
1263
1268
|
});
|
|
1264
|
-
const M = await O.alternateAnalyse(s, t, a, i, 1,
|
|
1269
|
+
const M = await O.alternateAnalyse(s, t, a, i, 1, n, o, e), j = M.reduce((b, m) => b + m.cost.total, 0), I = M.reduce((b, m) => b + m.cost.hire, 0), w = M.reduce((b, m) => b + m.cost.bunker, 0), g = M.reduce((b, m) => b + m.distance, 0), r = M.reduce((b, m) => b + m.totalHrs, 0);
|
|
1265
1270
|
return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j", e.requestId, e.level, {
|
|
1266
1271
|
cost: j,
|
|
1267
1272
|
hire: I,
|
|
1268
|
-
bunker:
|
|
1269
|
-
distance:
|
|
1270
|
-
hours:
|
|
1271
|
-
}),
|
|
1273
|
+
bunker: w,
|
|
1274
|
+
distance: g,
|
|
1275
|
+
hours: r
|
|
1276
|
+
}), d < j ? { combined: !0, cost: Math.round(d * 1e3) / 1e3, speeds: c, step: o } : { combined: !0, cost: Math.round(j * 1e3) / 1e3, speeds: M, step: o };
|
|
1272
1277
|
}
|
|
1273
1278
|
/**
|
|
1274
1279
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1281,48 +1286,48 @@ class O {
|
|
|
1281
1286
|
* @param step 步长,7,4,2,1
|
|
1282
1287
|
* @param options
|
|
1283
1288
|
*/
|
|
1284
|
-
static async alternateAnalyse(s, t, a, i,
|
|
1285
|
-
var y,
|
|
1286
|
-
let
|
|
1287
|
-
const
|
|
1288
|
-
for (;
|
|
1289
|
-
const M =
|
|
1290
|
-
|
|
1291
|
-
|
|
1289
|
+
static async alternateAnalyse(s, t, a, i, n, o, e, c = {}) {
|
|
1290
|
+
var y, v;
|
|
1291
|
+
let d = p.utc(s.etd);
|
|
1292
|
+
const h = { lat: s.lat, lng: s.lng }, u = [];
|
|
1293
|
+
for (; d.isBefore(a); ) {
|
|
1294
|
+
const M = d.clone().utc().add(e, "day"), j = JSON.parse(JSON.stringify(o.route)), I = JSON.parse(JSON.stringify(o.waypoints)), w = i[n], g = await O.analyseInstantWithThreshed(
|
|
1295
|
+
h,
|
|
1296
|
+
d.utc().format(),
|
|
1292
1297
|
M,
|
|
1293
1298
|
t,
|
|
1294
|
-
|
|
1299
|
+
w,
|
|
1295
1300
|
j,
|
|
1296
1301
|
I,
|
|
1297
1302
|
s.meteoVendor,
|
|
1298
1303
|
s.speedStep,
|
|
1299
1304
|
s.useMeteo,
|
|
1300
1305
|
s.useRouteParam,
|
|
1301
|
-
|
|
1306
|
+
c
|
|
1302
1307
|
);
|
|
1303
|
-
|
|
1308
|
+
g && (await O.calculateCost(g, w, s, c), C == null || C.info(
|
|
1304
1309
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1310
|
+
c.requestId,
|
|
1311
|
+
c.level,
|
|
1312
|
+
c.counter,
|
|
1313
|
+
d.utc().format(),
|
|
1309
1314
|
M.utc().format(),
|
|
1310
1315
|
{
|
|
1311
|
-
cost:
|
|
1312
|
-
hire:
|
|
1313
|
-
bunker:
|
|
1314
|
-
distance:
|
|
1315
|
-
hours:
|
|
1316
|
-
cp: `${
|
|
1316
|
+
cost: g.cost.total,
|
|
1317
|
+
hire: g.cost.hire,
|
|
1318
|
+
bunker: g.cost.bunker,
|
|
1319
|
+
distance: g.distance,
|
|
1320
|
+
hours: g.totalHrs,
|
|
1321
|
+
cp: `${w.speed}/${w.fo}/${w.dgo}`
|
|
1317
1322
|
}
|
|
1318
|
-
)),
|
|
1319
|
-
const
|
|
1320
|
-
if (
|
|
1321
|
-
|
|
1323
|
+
)), c.counter = c.counter + 1;
|
|
1324
|
+
const r = (v = (y = g == null ? void 0 : g.sample) == null ? void 0 : y.hours) == null ? void 0 : v.at(-1);
|
|
1325
|
+
if (r)
|
|
1326
|
+
h.lat = r.lat, h.lng = r.lng, d = p(r.eta), u.push(g), n = n ? 0 : 1;
|
|
1322
1327
|
else
|
|
1323
1328
|
break;
|
|
1324
1329
|
}
|
|
1325
|
-
return
|
|
1330
|
+
return u;
|
|
1326
1331
|
}
|
|
1327
1332
|
/**
|
|
1328
1333
|
* 计算Speed的cost
|
|
@@ -1332,13 +1337,13 @@ class O {
|
|
|
1332
1337
|
* @param options
|
|
1333
1338
|
*/
|
|
1334
1339
|
static async calculateCost(s, t, a, i = {}) {
|
|
1335
|
-
var
|
|
1340
|
+
var n;
|
|
1336
1341
|
if (s) {
|
|
1337
|
-
const
|
|
1342
|
+
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, c = 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;
|
|
1338
1343
|
s.cost = {
|
|
1339
|
-
total: Math.round((e +
|
|
1344
|
+
total: Math.round((e + c + d) * 1e3) / 1e3,
|
|
1340
1345
|
hire: e,
|
|
1341
|
-
bunker: Math.round((
|
|
1346
|
+
bunker: Math.round((c + d) * 1e3) / 1e3,
|
|
1342
1347
|
cp: t
|
|
1343
1348
|
};
|
|
1344
1349
|
}
|
|
@@ -1349,20 +1354,20 @@ class O {
|
|
|
1349
1354
|
*
|
|
1350
1355
|
*/
|
|
1351
1356
|
static async calculateECA(s, t, a = {}) {
|
|
1352
|
-
var
|
|
1353
|
-
const i = await
|
|
1354
|
-
let
|
|
1355
|
-
(
|
|
1356
|
-
y.positionTime =
|
|
1357
|
+
var c, d, h, u;
|
|
1358
|
+
const i = await L.intersectInECA((s == null ? void 0 : s.route) || []);
|
|
1359
|
+
let n = 0, o = 0, e = 0;
|
|
1360
|
+
(d = (c = s == null ? void 0 : s.sample) == null ? void 0 : c.wps) == null || d.forEach((y) => {
|
|
1361
|
+
y.positionTime = p.utc(y.etd || y.eta).unix();
|
|
1357
1362
|
});
|
|
1358
1363
|
for (const y of i) {
|
|
1359
|
-
|
|
1360
|
-
const
|
|
1361
|
-
y.in =
|
|
1364
|
+
n += y.distance;
|
|
1365
|
+
const v = await L.deadReckoningTime((h = y.waypoints) == null ? void 0 : h.at(0), s.sample.wps), M = await L.deadReckoningTime((u = y.waypoints) == null ? void 0 : u.at(-1), s.sample.wps);
|
|
1366
|
+
y.in = v, y.out = M, y.totalHrs = z.roundPrecision((M.positionTime - v.positionTime) / 3600, 3), y.totalDgoCons = z.roundPrecision(t.fo / 24 * y.totalHrs, 3), o += y.totalHrs, e += y.totalDgoCons;
|
|
1362
1367
|
}
|
|
1363
|
-
return
|
|
1364
|
-
distanceInECA:
|
|
1365
|
-
hoursInECA:
|
|
1368
|
+
return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3), e = z.roundPrecision(e, 3), {
|
|
1369
|
+
distanceInECA: n,
|
|
1370
|
+
hoursInECA: o,
|
|
1366
1371
|
totalDgoConsInECA: e,
|
|
1367
1372
|
eca: i
|
|
1368
1373
|
};
|
|
@@ -1373,34 +1378,34 @@ class O {
|
|
|
1373
1378
|
* @param options
|
|
1374
1379
|
*/
|
|
1375
1380
|
static async mergeSpeeds(s, t = {}) {
|
|
1376
|
-
var
|
|
1381
|
+
var r, b;
|
|
1377
1382
|
const a = {
|
|
1378
1383
|
hours: [],
|
|
1379
1384
|
wps: [],
|
|
1380
1385
|
days: []
|
|
1381
|
-
}, i = s.reduce((m,
|
|
1386
|
+
}, i = s.reduce((m, l) => m + l.distance, 0), n = s.reduce((m, l) => {
|
|
1382
1387
|
var k;
|
|
1383
|
-
return m + (((k =
|
|
1384
|
-
}, 0),
|
|
1388
|
+
return m + (((k = l.extend) == null ? void 0 : k.distanceInECA) || 0);
|
|
1389
|
+
}, 0), o = s.reduce((m, l) => m + l.totalHrs, 0), e = s.reduce((m, l) => {
|
|
1385
1390
|
var k;
|
|
1386
|
-
return m + (((k =
|
|
1387
|
-
}, 0),
|
|
1391
|
+
return m + (((k = l.extend) == null ? void 0 : k.hoursInECA) || 0);
|
|
1392
|
+
}, 0), c = s.reduce((m, l) => {
|
|
1388
1393
|
var k;
|
|
1389
|
-
return m + (((k =
|
|
1390
|
-
}, 0),
|
|
1391
|
-
let
|
|
1394
|
+
return m + (((k = l.extend) == null ? void 0 : k.totalDgoConsInECA) || 0);
|
|
1395
|
+
}, 0), d = s.reduce((m, l) => m + l.wxFactor * l.totalHrs / o, 0), h = s.reduce((m, l) => m + l.cFactor * l.totalHrs / o, 0), u = s.reduce((m, l) => m + l.totalFoCons, 0), y = s.reduce((m, l) => m + l.totalDgoCons, 0), v = s.reduce((m, l) => m + l.cost.total, 0), M = s.reduce((m, l) => m + l.cost.hire, 0), j = s.reduce((m, l) => m + l.cost.bunker, 0), I = [], w = [];
|
|
1396
|
+
let g;
|
|
1392
1397
|
for (const m of s) {
|
|
1393
|
-
|
|
1394
|
-
const
|
|
1395
|
-
|
|
1396
|
-
T && (x.distanceFromStart = x.distanceFromStart +
|
|
1397
|
-
}), k.at(0).distanceFromPrevious =
|
|
1398
|
-
T && (x.distanceFromStart = x.distanceFromStart +
|
|
1399
|
-
}), S.at(0).distanceFromPrevious =
|
|
1400
|
-
T && (x.distanceFromStart = x.distanceFromStart +
|
|
1398
|
+
w.push(...((r = m.extend) == null ? void 0 : r.eca) || []);
|
|
1399
|
+
const l = m.sample.hours, k = m.sample.wps, S = m.sample.days, D = l.at(0);
|
|
1400
|
+
g && (D.distanceFromPrevious = g.distanceFromPrevious, D.distanceFromStart = g.distanceFromStart, l.forEach((x, T) => {
|
|
1401
|
+
T && (x.distanceFromStart = x.distanceFromStart + g.distanceFromStart);
|
|
1402
|
+
}), k.at(0).distanceFromPrevious = g.distanceFromPrevious, k.at(0).distanceFromStart = g.distanceFromStart, k.forEach((x, T) => {
|
|
1403
|
+
T && (x.distanceFromStart = x.distanceFromStart + g.distanceFromStart);
|
|
1404
|
+
}), S.at(0).distanceFromPrevious = g.distanceFromPrevious, S.at(0).distanceFromStart = g.distanceFromStart, S.forEach((x, T) => {
|
|
1405
|
+
T && (x.distanceFromStart = x.distanceFromStart + g.distanceFromStart);
|
|
1401
1406
|
})), D.cp = m.cost.cp;
|
|
1402
1407
|
const P = [m.etd, m.eta], N = I.findIndex((x) => x.id === D.cp.id);
|
|
1403
|
-
N === -1 ? (D.cp.segment = [P], I.push(D.cp)) : I[N].segment.push(P),
|
|
1408
|
+
N === -1 ? (D.cp.segment = [P], I.push(D.cp)) : I[N].segment.push(P), l.forEach((x) => {
|
|
1404
1409
|
var q;
|
|
1405
1410
|
((q = a.hours) == null ? void 0 : q.findIndex((R) => R.eta === x.eta)) === -1 && a.hours.push(x);
|
|
1406
1411
|
}), k.forEach((x) => {
|
|
@@ -1410,17 +1415,17 @@ class O {
|
|
|
1410
1415
|
var q;
|
|
1411
1416
|
((q = a == null ? void 0 : a.days) == null ? void 0 : q.findIndex((R) => R.eta === x.eta)) === -1 && a.days.push(x);
|
|
1412
1417
|
});
|
|
1413
|
-
const A = (
|
|
1414
|
-
A === -1 ? a.wps.push(D) : a.wps[A] = D,
|
|
1418
|
+
const A = (b = a.wps) == null ? void 0 : b.findIndex((x) => x.eta === D.eta);
|
|
1419
|
+
A === -1 ? a.wps.push(D) : a.wps[A] = D, g = l.at(-1);
|
|
1415
1420
|
}
|
|
1416
|
-
return a.wps.sort((m,
|
|
1417
|
-
|
|
1418
|
-
}), a.wps.forEach((m,
|
|
1419
|
-
const k = a.wps[
|
|
1421
|
+
return a.wps.sort((m, l) => {
|
|
1422
|
+
p(m.etd).unix() - p(l.etd).unix();
|
|
1423
|
+
}), a.wps.forEach((m, l) => {
|
|
1424
|
+
const k = a.wps[l - 1];
|
|
1420
1425
|
if (k) {
|
|
1421
|
-
const S = m.distanceFromStart - (k.distanceFromStart || 0), D =
|
|
1426
|
+
const S = m.distanceFromStart - (k.distanceFromStart || 0), D = p(m.eta || m.etd).diff(p(k.etd || k.eta), "hour", !0), P = Math.round(S / D * 100) / 100;
|
|
1422
1427
|
m.avgSpd = P;
|
|
1423
|
-
const N =
|
|
1428
|
+
const N = L.calculateBearing(k, m);
|
|
1424
1429
|
k.bearing = N;
|
|
1425
1430
|
}
|
|
1426
1431
|
}), {
|
|
@@ -1432,23 +1437,23 @@ class O {
|
|
|
1432
1437
|
v0: s.at(0).v0,
|
|
1433
1438
|
label: "Combined",
|
|
1434
1439
|
distance: Math.round(i * 1e3) / 1e3,
|
|
1435
|
-
totalHrs: Math.round(
|
|
1436
|
-
avgSpeed: Math.round(i /
|
|
1437
|
-
wxFactor: Math.round(
|
|
1438
|
-
cFactor: Math.round(
|
|
1439
|
-
totalFoCons: Math.round(
|
|
1440
|
+
totalHrs: Math.round(o * 1e3) / 1e3,
|
|
1441
|
+
avgSpeed: Math.round(i / o * 1e3) / 1e3,
|
|
1442
|
+
wxFactor: Math.round(d * 1e3) / 1e3,
|
|
1443
|
+
cFactor: Math.round(h * 1e3) / 1e3,
|
|
1444
|
+
totalFoCons: Math.round(u * 1e3) / 1e3,
|
|
1440
1445
|
totalDgoCons: Math.round(y * 1e3) / 1e3,
|
|
1441
1446
|
cost: {
|
|
1442
|
-
total: Math.round(
|
|
1447
|
+
total: Math.round(v * 1e3) / 1e3,
|
|
1443
1448
|
hire: Math.round(M * 1e3) / 1e3,
|
|
1444
1449
|
bunker: Math.round(j * 1e3) / 1e3
|
|
1445
1450
|
},
|
|
1446
1451
|
extend: {
|
|
1447
1452
|
cps: I,
|
|
1448
|
-
eca:
|
|
1449
|
-
distanceInECA: Math.round(
|
|
1453
|
+
eca: w,
|
|
1454
|
+
distanceInECA: Math.round(n * 1e3) / 1e3,
|
|
1450
1455
|
hoursInECA: Math.round(e * 1e3) / 1e3,
|
|
1451
|
-
totalDgoConsInECA: Math.round(
|
|
1456
|
+
totalDgoConsInECA: Math.round(c * 1e3) / 1e3,
|
|
1452
1457
|
speeds: s
|
|
1453
1458
|
}
|
|
1454
1459
|
};
|
|
@@ -1459,12 +1464,12 @@ export {
|
|
|
1459
1464
|
yt as AlertHelper,
|
|
1460
1465
|
ft as AlertLevel,
|
|
1461
1466
|
Et as HifleetImpl,
|
|
1462
|
-
|
|
1467
|
+
gt as LoadCondition,
|
|
1463
1468
|
Tt as MyShipImpl,
|
|
1464
1469
|
Ft as MyVesselImpl,
|
|
1465
1470
|
Nt as ShipxyImpl,
|
|
1466
1471
|
O as SpeedHelper,
|
|
1467
1472
|
vt as SpeedLabel,
|
|
1468
|
-
|
|
1473
|
+
bt as VesselTag,
|
|
1469
1474
|
xt as alertHelper
|
|
1470
1475
|
};
|