@idm-plugin/geo 2.0.2 → 2.0.4

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 CHANGED
@@ -1,4 +1,4 @@
1
- import * as N from "@turf/turf";
1
+ import * as S from "@turf/turf";
2
2
  import u from "moment";
3
3
  import j from "@log4js-node/log4js-api";
4
4
  var n0 = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
@@ -31,7 +31,7 @@ var x = { exports: {} };
31
31
  U = U / 60, E = R(e.charCodeAt(n)), t += E * U;
32
32
  return t * Z;
33
33
  }
34
- function f(o) {
34
+ function N(o) {
35
35
  for (var n = 0; n < o.length; n++)
36
36
  o[n] = T(o[n]);
37
37
  }
@@ -40,7 +40,7 @@ var x = { exports: {} };
40
40
  o[X] = Math.round((o[X - 1] || 0) + o[X] * 6e4);
41
41
  o[n - 1] = 1 / 0;
42
42
  }
43
- function S(o, n) {
43
+ function f(o, n) {
44
44
  var X = [], L;
45
45
  for (L = 0; L < n.length; L++)
46
46
  X[L] = o[n[L]];
@@ -48,10 +48,10 @@ var x = { exports: {} };
48
48
  }
49
49
  function s(o) {
50
50
  var n = o.split("|"), X = n[2].split(" "), L = n[3].split(""), e = n[4].split(" ");
51
- return f(X), f(L), f(e), i(e, L.length), {
51
+ return N(X), N(L), N(e), i(e, L.length), {
52
52
  name: n[0],
53
- abbrs: S(n[1].split(" "), L),
54
- offsets: S(X, L),
53
+ abbrs: f(n[1].split(" "), L),
54
+ offsets: f(X, L),
55
55
  untils: e,
56
56
  population: n[5] | 0
57
57
  };
@@ -134,7 +134,7 @@ var x = { exports: {} };
134
134
  }
135
135
  function b0(o, n) {
136
136
  var X, L;
137
- for (f(n), X = 0; X < n.length; X++)
137
+ for (N(n), X = 0; X < n.length; X++)
138
138
  L = n[X], A[L] = A[L] || {}, A[L][o] = !0;
139
139
  }
140
140
  function p0(o) {
@@ -1135,8 +1135,8 @@ const L0 = "2025b", T0 = [
1135
1135
  links: i0,
1136
1136
  countries: e0
1137
1137
  };
1138
- var f0 = R0;
1139
- f0.tz.load(N0);
1138
+ var S0 = R0;
1139
+ S0.tz.load(N0);
1140
1140
  var M0 = { exports: {} };
1141
1141
  (function(m) {
1142
1142
  function M(z, b) {
@@ -1152,8 +1152,8 @@ var M0 = { exports: {} };
1152
1152
  }
1153
1153
  m.exports = M;
1154
1154
  })(M0);
1155
- var S0 = M0.exports;
1156
- const r0 = /* @__PURE__ */ X0(S0);
1155
+ var f0 = M0.exports;
1156
+ const r0 = /* @__PURE__ */ X0(f0);
1157
1157
  class a {
1158
1158
  /**
1159
1159
  * 基于输入的经度,计算出时区
@@ -1308,6 +1308,75 @@ class a {
1308
1308
  return p >= 1 ? c : b > 0 ? `${c}.${Math.trunc(p * Math.pow(10, b)).toString().padStart(b, "0")}` : c;
1309
1309
  }
1310
1310
  }
1311
+ class B0 {
1312
+ static json2Str(M) {
1313
+ const z = M.type ? M.type[0].toUpperCase() : "A";
1314
+ return `${M.lat}|${M.lng}|${M.positionTime}|${M.sog}|${M.cog}|${M.hdg}|${M.draught}|${z}|${JSON.stringify(M.meteo || {})}|${M.vendor}|${M.deleted}`;
1315
+ }
1316
+ static str2Json(M) {
1317
+ const [z, b, p, c, O, A, W, q, Y, d, R] = M.split("|");
1318
+ return {
1319
+ lat: Number(z),
1320
+ lng: Number(b),
1321
+ positionTime: Number(p),
1322
+ sog: Number(c),
1323
+ cog: Number(O),
1324
+ hdg: Number(A),
1325
+ //@ts-ignore
1326
+ draught: isNaN(W) ? null : Number(W),
1327
+ type: q,
1328
+ important: q !== "A",
1329
+ meteo: Y ? JSON.parse(Y) : void 0,
1330
+ vendor: d,
1331
+ deleted: R === "true"
1332
+ };
1333
+ }
1334
+ static inspectStoppages(M, z = 1, b = !0) {
1335
+ const p = M.at(0).positionTime < M.at(-1).positionTime;
1336
+ p || M.sort((W, q) => W.positionTime - q.positionTime);
1337
+ const c = [];
1338
+ let O, A;
1339
+ for (let W = 0; W < M.length - 1; W++) {
1340
+ const q = M[W];
1341
+ if (!(b && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(q.type))) {
1342
+ for (let Y = W + 1; Y < M.length; Y++) {
1343
+ const d = M[Y - 1], R = M[Y];
1344
+ if (b && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(q.type))
1345
+ continue;
1346
+ const T = R.positionTime - d.positionTime;
1347
+ if (r.calculateDistance(R, d, !0, 4) / (T / 3600) < z)
1348
+ O || (O = q), Y === M.length - 1 && (A = R, W = Y);
1349
+ else {
1350
+ O && (A = M[Y - 1], W = Y);
1351
+ break;
1352
+ }
1353
+ }
1354
+ if ((A == null ? void 0 : A.positionTime) > (O == null ? void 0 : O.positionTime) && O) {
1355
+ const Y = {
1356
+ start: {
1357
+ lat: O.lat,
1358
+ lng: O.lng,
1359
+ sog: O.sog,
1360
+ positionTime: O.positionTime,
1361
+ utc: u.unix(O.positionTime).utc().format()
1362
+ },
1363
+ end: {
1364
+ lat: A.lat,
1365
+ lng: A.lng,
1366
+ sog: A.sog,
1367
+ positionTime: A.positionTime,
1368
+ utc: u.unix(A.positionTime).utc().format()
1369
+ },
1370
+ duration: A.positionTime - O.positionTime
1371
+ }, d = M.filter((T) => T.positionTime >= Y.start.positionTime && T.positionTime <= Y.end.positionTime), R = r.divideAccordingToLng(d);
1372
+ Y.distance = r.calculateRouteDistance(R), Y.hours = Math.round(Y.duration / 3600 * 10) / 10, Y.avgSog = Math.round(Y.distance / Y.hours * 10) / 10, c.push(Y);
1373
+ }
1374
+ O = void 0, A = void 0;
1375
+ }
1376
+ }
1377
+ return p || M.sort((W, q) => q.positionTime - W.positionTime), c;
1378
+ }
1379
+ }
1311
1380
  let Q;
1312
1381
  try {
1313
1382
  Q = j.getLogger("meteo");
@@ -1324,12 +1393,12 @@ class r {
1324
1393
  * @returns {number} 单位度
1325
1394
  */
1326
1395
  static calculateBearing(M, z, b = !0, p = 4) {
1327
- const c = N.points([
1396
+ const c = S.points([
1328
1397
  [M.lng, M.lat],
1329
1398
  [z.lng, z.lat]
1330
1399
  ]);
1331
1400
  let O;
1332
- return b ? O = N.rhumbBearing(c.features[0], c.features[1]) : O = N.bearing(c.features[0], c.features[1]), O < 0 && (O += 360), a.roundPrecision(O, p);
1401
+ return b ? O = S.rhumbBearing(c.features[0], c.features[1]) : O = S.bearing(c.features[0], c.features[1]), O < 0 && (O += 360), a.roundPrecision(O, p);
1333
1402
  }
1334
1403
  /**
1335
1404
  * 计算两点间距离
@@ -1342,12 +1411,12 @@ class r {
1342
1411
  */
1343
1412
  static calculateDistance(M, z, b = !0, p = 4, c = "nauticalmiles") {
1344
1413
  M = { ...M }, z = { ...z }, M.lng = a.convertToStdLng(M.lng, p), z.lng = a.convertToStdLng(z.lng, p);
1345
- const O = N.points([
1414
+ const O = S.points([
1346
1415
  [M.lng, M.lat],
1347
1416
  [z.lng, z.lat]
1348
1417
  ]);
1349
1418
  let A;
1350
- return b ? A = N.rhumbDistance(O.features[0], O.features[1], { units: c }) : A = N.distance(O.features[0], O.features[1], { units: c }), a.roundPrecision(A, p);
1419
+ return b ? A = S.rhumbDistance(O.features[0], O.features[1], { units: c }) : A = S.distance(O.features[0], O.features[1], { units: c }), a.roundPrecision(A, p);
1351
1420
  }
1352
1421
  /**
1353
1422
  * 计算航线距离
@@ -1375,9 +1444,9 @@ class r {
1375
1444
  * @param rhumb
1376
1445
  */
1377
1446
  static calculateCoordinate(M, z, b, p = "nauticalmiles", c = !0) {
1378
- const O = N.point([M.lng, M.lat]);
1447
+ const O = S.point([M.lng, M.lat]);
1379
1448
  let A;
1380
- c ? A = N.rhumbDestination(O, b, z, { units: p }) : A = N.destination(O, b, z, { units: p });
1449
+ c ? A = S.rhumbDestination(O, b, z, { units: p }) : A = S.destination(O, b, z, { units: p });
1381
1450
  const W = A.geometry.coordinates;
1382
1451
  return { lng: a.convertToStdLng(W[0], 8), lat: a.roundPrecision(W[1], 8) };
1383
1452
  }
@@ -1426,18 +1495,18 @@ class r {
1426
1495
  [A, M[W + 1].lat]
1427
1496
  ]);
1428
1497
  let d, R;
1429
- z ? (d = N.lineString(Y), R = N.lineString([
1498
+ z ? (d = S.lineString(Y), R = S.lineString([
1430
1499
  [q > 0 ? 180 : -180, 89],
1431
1500
  [q > 0 ? 180 : -180, -89]
1432
- ])) : (d = N.greatCircle(Y[0], Y[1]), R = N.greatCircle([q > 0 ? 180 : -180, 89], [q > 0 ? 180 : -180, -89]));
1433
- const T = N.lineIntersect(d, R);
1434
- let f;
1501
+ ])) : (d = S.greatCircle(Y[0], Y[1]), R = S.greatCircle([q > 0 ? 180 : -180, 89], [q > 0 ? 180 : -180, -89]));
1502
+ const T = S.lineIntersect(d, R);
1503
+ let N;
1435
1504
  if (T.features.length) {
1436
- const i = N.getCoord(T.features[0]);
1437
- f = a.roundPrecision(i[1], 8);
1505
+ const i = S.getCoord(T.features[0]);
1506
+ N = a.roundPrecision(i[1], 8);
1438
1507
  } else
1439
- f = M[W].lat;
1440
- q > 0 ? (p.push([180 - 1e-6, f]), c.push([...p]), p = [], p.push([-(180 - 1e-6), f])) : (p.push([-(180 - 1e-6), f]), c.push([...p]), p = [], p.push([180 - 1e-6, f]));
1508
+ N = M[W].lat;
1509
+ q > 0 ? (p.push([180 - 1e-6, N]), c.push([...p]), p = [], p.push([-(180 - 1e-6), N])) : (p.push([-(180 - 1e-6), N]), c.push([...p]), p = [], p.push([180 - 1e-6, N]));
1441
1510
  }
1442
1511
  W === M.length - 2 && p.push([A, M[W + 1].lat]);
1443
1512
  }
@@ -1648,10 +1717,10 @@ class r {
1648
1717
  M.lng = a.convertToStdLng(M.lng, 8), z = { ...z }, b = { ...b }, z.lng = a.convertToStdLng(z.lng, 8), b.lng = a.convertToStdLng(b.lng, 8);
1649
1718
  const c = a.convertToMonotonicLng([z, b]);
1650
1719
  z = c[0], b = c[1];
1651
- const O = N.lineString([
1720
+ const O = S.lineString([
1652
1721
  [z.lng, z.lat],
1653
1722
  [b.lng, b.lat]
1654
- ]), A = N.pointToLineDistance(N.point([M.lng, M.lat]), O, p), W = N.pointToLineDistance(N.point([M.lng > 0 ? M.lng - 360 : M.lng + 360, M.lat]), O, p);
1723
+ ]), A = S.pointToLineDistance(S.point([M.lng, M.lat]), O, p), W = S.pointToLineDistance(S.point([M.lng > 0 ? M.lng - 360 : M.lng + 360, M.lat]), O, p);
1655
1724
  return a.roundPrecision(Math.min(A, W), 6);
1656
1725
  }
1657
1726
  /**
@@ -1704,7 +1773,7 @@ class r {
1704
1773
  return z.map((W, q) => {
1705
1774
  W.lng = a.convertToStdLng(W.lng);
1706
1775
  const Y = z[q + 1];
1707
- if (Y && (W.bearing || ((W.positionTime || 0) > (Y.positionTime || 0) ? W.bearing = this.calculateBearing(Y, W, !0) : W.bearing = this.calculateBearing(W, Y, !0)), W.cog = W.cog || W.bearing, !W.sog && W.positionTime && Y.positionTime)) {
1776
+ if (Y && ((W.bearing === null || W.bearing === void 0) && ((W.positionTime || 0) > (Y.positionTime || 0) ? W.bearing = this.calculateBearing(Y, W, !0) : W.bearing = this.calculateBearing(W, Y, !0)), W.cog = W.cog || W.bearing, !W.sog && W.positionTime && Y.positionTime)) {
1708
1777
  const d = this.calculateDistance(W, Y, !0), R = Math.abs(Y.positionTime - W.positionTime) / 3600;
1709
1778
  W.sog = a.roundPrecision(d / R, 2);
1710
1779
  }
@@ -1736,7 +1805,7 @@ class r {
1736
1805
  * @param route [[[lng, lat]]]
1737
1806
  */
1738
1807
  static nearestCoordinateInRoute(M, z) {
1739
- const b = N.point([M.lng, M.lat]), c = this.convertRouteToCoordinates(z).map((q) => [q.lng, q.lat]), O = N.lineString(c), A = N.nearestPointOnLine(O, b), W = N.getCoord(A);
1808
+ const b = S.point([M.lng, M.lat]), c = this.convertRouteToCoordinates(z).map((q) => [q.lng, q.lat]), O = S.lineString(c), A = S.nearestPointOnLine(O, b), W = S.getCoord(A);
1740
1809
  return { lng: a.roundPrecision(W[0], 8), lat: a.roundPrecision(W[1], 8) };
1741
1810
  }
1742
1811
  /**
@@ -1772,31 +1841,31 @@ class r {
1772
1841
  var R;
1773
1842
  const c = M.speed || 12, O = [];
1774
1843
  let A = [], W = !1, q = 0, Y = 0, d;
1775
- if (z && b.length ? (O.push(M), b.forEach((T, f) => {
1844
+ if (z && b.length ? (O.push(M), b.forEach((T, N) => {
1776
1845
  if (W)
1777
1846
  A.push(T);
1778
1847
  else {
1779
1848
  const i = [];
1780
- let S;
1849
+ let f;
1781
1850
  for (let s = 0; s < T.length; s++)
1782
1851
  if (d)
1783
1852
  i.push(T[s]);
1784
1853
  else {
1785
- S = { lng: T[s][0], lat: T[s][1] };
1786
- const P = this.calculateDistance(M, S, !0, 8, p);
1854
+ f = { lng: T[s][0], lat: T[s][1] };
1855
+ const P = this.calculateDistance(M, f, !0, 8, p);
1787
1856
  if (q += P, q < z)
1788
- Y += P, P && O.push(S), M = S;
1857
+ Y += P, P && O.push(f), M = f;
1789
1858
  else {
1790
1859
  if (Y = z, q === z)
1791
- d = S, i.push([d.lng, d.lat]);
1860
+ d = f, i.push([d.lng, d.lat]);
1792
1861
  else {
1793
- const l = q - z, B = this.calculateBearing(S, M);
1794
- d = this.calculateCoordinate(S, B, l, p), i.push([d.lng, d.lat]), i.push([S.lng, S.lat]);
1862
+ const l = q - z, B = this.calculateBearing(f, M);
1863
+ d = this.calculateCoordinate(f, B, l, p), i.push([d.lng, d.lat]), i.push([f.lng, f.lat]);
1795
1864
  }
1796
1865
  W = !0;
1797
1866
  }
1798
1867
  }
1799
- i.length && A.push(i), f === b.length - 1 && !d && (d = S);
1868
+ i.length && A.push(i), N === b.length - 1 && !d && (d = f);
1800
1869
  }
1801
1870
  })) : (A = b, d = { ...M }), d)
1802
1871
  if (O.push(d), d.distanceFromPrevious = Math.round(Y * 1e4) / 1e4, d.hourFromPrevious = Math.round(Y / c * 1e4) / 1e4, ((R = A[0]) == null ? void 0 : R.length) > 1) {
@@ -1813,10 +1882,10 @@ class r {
1813
1882
  * @param to {lng, lat}
1814
1883
  */
1815
1884
  static nearestCoordinateInLine(M, z, b) {
1816
- const p = a.convertToStdLng(M.lng, 6), c = N.point([p, M.lat]), O = a.convertToStdLng(z.lng, 6), A = a.convertToStdLng(b.lng, 6), W = N.lineString([
1885
+ const p = a.convertToStdLng(M.lng, 6), c = S.point([p, M.lat]), O = a.convertToStdLng(z.lng, 6), A = a.convertToStdLng(b.lng, 6), W = S.lineString([
1817
1886
  [O, z.lat],
1818
1887
  [A, b.lat]
1819
- ]), q = N.nearestPointOnLine(W, c), Y = N.getCoord(q), d = a.roundPrecision(Y[0], 6), R = a.roundPrecision(Y[1], 6);
1888
+ ]), q = S.nearestPointOnLine(W, c), Y = S.getCoord(q), d = a.roundPrecision(Y[0], 6), R = a.roundPrecision(Y[1], 6);
1820
1889
  return { lng: d, lat: R, inline: !(d === O && R === z.lat) && !(d === A && R === b.lat) };
1821
1890
  }
1822
1891
  /**
@@ -1832,7 +1901,7 @@ class r {
1832
1901
  const W = { lng: a.roundPrecision(A[0], 8), lat: a.roundPrecision(A[1], 8) };
1833
1902
  if (!c)
1834
1903
  b.push(W), c = W;
1835
- else if (c.bearing === void 0)
1904
+ else if (c.bearing === void 0 || c.bearing === null)
1836
1905
  c.bearing = this.calculateBearing(c, W, !0);
1837
1906
  else {
1838
1907
  const q = this.calculateDistance(p, W, !0);
@@ -1885,10 +1954,10 @@ class r {
1885
1954
  for (const A of M)
1886
1955
  for (const W of A)
1887
1956
  z.push(W);
1888
- const b = N.featureCollection([]), p = a.convertToMonotonicLng2(z);
1957
+ const b = S.featureCollection([]), p = a.convertToMonotonicLng2(z);
1889
1958
  for (const A of p)
1890
- b.features.push(N.point(A));
1891
- const O = N.center(b).geometry.coordinates;
1959
+ b.features.push(S.point(A));
1960
+ const O = S.center(b).geometry.coordinates;
1892
1961
  return { lng: a.convertToStdLng(O[0], 8), lat: a.roundPrecision(O[1], 8) };
1893
1962
  }
1894
1963
  /**
@@ -1908,8 +1977,8 @@ class r {
1908
1977
  for (const c of M)
1909
1978
  for (const O of c)
1910
1979
  z.push(O);
1911
- const b = a.convertToMonotonicLng2(z), p = N.lineString(b);
1912
- return N.bbox(p);
1980
+ const b = a.convertToMonotonicLng2(z), p = S.lineString(b);
1981
+ return S.bbox(p);
1913
1982
  }
1914
1983
  /**
1915
1984
  * 计算BBox
@@ -1931,8 +2000,8 @@ class r {
1931
2000
  const O = M[c - 1], A = M[c], W = M[c + 1];
1932
2001
  let q = !1, Y = !1;
1933
2002
  if ((O.velocity || O.suspend || O.important || O.pilot || c === 1) && (q = !0, p.push(O)), A.gcToPrevious && (q || (q = !0, p.push(O)), Y = !0, p.push(A), c++), W) {
1934
- const d = r.calculateDistance(O, A, !0), R = r.calculateDistance(A, W, !0), T = r.calculateDistance(O, W, !0), f = (Math.pow(d, 2) + Math.pow(R, 2) - Math.pow(T, 2)) / (2 * d * R);
1935
- Math.round(Math.acos(f) * 180 / Math.PI) < b && T > z && !Y && (p.push(A), c++);
2003
+ const d = r.calculateDistance(O, A, !0), R = r.calculateDistance(A, W, !0), T = r.calculateDistance(O, W, !0), N = (Math.pow(d, 2) + Math.pow(R, 2) - Math.pow(T, 2)) / (2 * d * R);
2004
+ Math.round(Math.acos(N) * 180 / Math.PI) < b && T > z && !Y && (p.push(A), c++);
1936
2005
  }
1937
2006
  if (c >= M.length - 1) {
1938
2007
  const d = M.at(-1);
@@ -2031,6 +2100,7 @@ class r {
2031
2100
  /**
2032
2101
  * 路径摘要
2033
2102
  * @param coordinates 已排序的坐标
2103
+ * @param slowSpd 排出停航时间
2034
2104
  * @return {
2035
2105
  * begin: string, // 开始时间
2036
2106
  * end: string, // 结束时间
@@ -2039,15 +2109,21 @@ class r {
2039
2109
  * avgSpeed: number // 平均航速,单位节
2040
2110
  * }
2041
2111
  */
2042
- static coordinatesSummary(M) {
2112
+ static coordinatesSummary(M, z = 3) {
2043
2113
  if (M.length > 1) {
2044
- const z = M[0], b = M[M.length - 1], p = (z == null ? void 0 : z.positionTime) < (b == null ? void 0 : b.positionTime) ? u.unix(z == null ? void 0 : z.positionTime) : u.unix(b == null ? void 0 : b.positionTime), c = (z == null ? void 0 : z.positionTime) > (b == null ? void 0 : b.positionTime) ? u.unix(z == null ? void 0 : z.positionTime) : u.unix(b == null ? void 0 : b.positionTime), O = Math.round(c.diff(p, "hours", !0) * 100) / 100, A = this.generateRouteAccordingToWaypoints(M, !0, !0), W = this.calculateRouteDistance(A), q = O ? Math.round(W / O * 100) / 100 : 0;
2114
+ const b = M[0], p = M[M.length - 1], c = (b == null ? void 0 : b.positionTime) < (p == null ? void 0 : p.positionTime) ? u.unix(b == null ? void 0 : b.positionTime) : u.unix(p == null ? void 0 : p.positionTime), O = (b == null ? void 0 : b.positionTime) > (p == null ? void 0 : p.positionTime) ? u.unix(b == null ? void 0 : b.positionTime) : u.unix(p == null ? void 0 : p.positionTime), A = Math.round(O.diff(c, "hours", !0) * 100) / 100, W = this.generateRouteAccordingToWaypoints(M, !0, !0), q = this.calculateRouteDistance(W), d = B0.inspectStoppages(M, z).reduce(
2115
+ (T, N) => (T.duration += N.duration, T.distance += N.distance, T),
2116
+ { hours: 0, distance: 0, spd: 0, duration: 0 }
2117
+ );
2118
+ d.hours = Math.round(d.duration / 3600 * 100) / 100, d.distance = Math.round(d.distance * 100) / 100, d.spd = d.hours ? Math.round(d.distance / d.hours * 100) / 100 : 0;
2119
+ const R = A ? Math.round(q / (A - d.hours) * 100) / 100 : 0;
2045
2120
  return {
2046
- begin: p.utc().format(),
2047
- end: c.utc().format(),
2048
- distance: W,
2049
- hours: O,
2050
- avgSpeed: q
2121
+ begin: c.utc().format(),
2122
+ end: O.utc().format(),
2123
+ distance: q,
2124
+ hours: A - d.hours,
2125
+ avgSpeed: R,
2126
+ stoppage: d
2051
2127
  };
2052
2128
  }
2053
2129
  return {
@@ -2074,13 +2150,13 @@ class r {
2074
2150
  const b = z.sample.hours.at(0), p = u.utc(M), c = u.utc(z.eta), O = p.isAfter(c) ? c : p;
2075
2151
  let A = z.sample.hours.find((T) => T.eta === O.format());
2076
2152
  if (!A) {
2077
- const T = z.sample.hours.filter((G) => u.utc(G.eta).isBefore(O)).at(-1), f = this.calculateSubRoute(T, z.route);
2078
- A = (R = this.calculateNextCoordinateAlongRoute(T, T.speed * O.diff(u(T.etd), "hours", !0), f)) == null ? void 0 : R.coordinate;
2079
- const { cFactor: i, cog: S, wxFactor: s, meteo: P } = T, l = Math.round(A.distanceFromPrevious * 1e4) / 1e4, B = Math.round((l + T.distanceFromStart) * 1e4) / 1e4;
2153
+ const T = z.sample.hours.filter((G) => u.utc(G.eta).isBefore(O)).at(-1), N = this.calculateSubRoute(T, z.route);
2154
+ A = (R = this.calculateNextCoordinateAlongRoute(T, T.speed * O.diff(u(T.etd), "hours", !0), N)) == null ? void 0 : R.coordinate;
2155
+ const { cFactor: i, cog: f, wxFactor: s, meteo: P } = T, l = Math.round(A.distanceFromPrevious * 1e4) / 1e4, B = Math.round((l + T.distanceFromStart) * 1e4) / 1e4;
2080
2156
  A = {
2081
2157
  ...A,
2082
2158
  cFactor: i,
2083
- cog: S,
2159
+ cog: f,
2084
2160
  speed: T.speed,
2085
2161
  wxFactor: s,
2086
2162
  distanceFromStart: B,
@@ -2136,14 +2212,14 @@ try {
2136
2212
  } catch {
2137
2213
  } finally {
2138
2214
  }
2139
- class t0 {
2215
+ class V0 {
2140
2216
  /**
2141
2217
  * 将原始数据转换为geojson
2142
2218
  * @param raw
2143
2219
  */
2144
2220
  static convert2Geojson(M) {
2145
2221
  var b, p, c;
2146
- const z = N.featureCollection([]);
2222
+ const z = S.featureCollection([]);
2147
2223
  for (const O of M) {
2148
2224
  const A = (b = O.history) == null ? void 0 : b[0];
2149
2225
  if (O.forecasts) {
@@ -2152,25 +2228,25 @@ class t0 {
2152
2228
  let q;
2153
2229
  const Y = [], d = [], R = u(W.date).utc(), T = `${O.name}-${W.model}`;
2154
2230
  for (const i in W == null ? void 0 : W.hours) {
2155
- const S = W.hours[i];
2156
- q = q || S;
2157
- const s = R.clone().add(Number(i), "hour"), P = N.point([S.lng, S.lat], {
2231
+ const f = W.hours[i];
2232
+ q = q || f;
2233
+ const s = R.clone().add(Number(i), "hour"), P = S.point([f.lng, f.lat], {
2158
2234
  model: W.model,
2159
2235
  name: O.name,
2160
2236
  nameCn: O.nameCn,
2161
2237
  date: s.format(),
2162
2238
  hour: Number(i),
2163
2239
  format: s.format("MMM-DD/HHmm[Z]"),
2164
- pressure: S.pressure > 1e4 ? a.roundPrecision(S.pressure / 100, 0) : a.roundPrecision(S.pressure, 0),
2165
- gusts: S.gusts,
2166
- wind: S.wind || {},
2167
- movement: S.movement,
2240
+ pressure: f.pressure > 1e4 ? a.roundPrecision(f.pressure / 100, 0) : a.roundPrecision(f.pressure, 0),
2241
+ gusts: f.gusts,
2242
+ wind: f.wind || {},
2243
+ movement: f.movement,
2168
2244
  category: T,
2169
2245
  type: "forecast"
2170
2246
  });
2171
2247
  d.push(P), Y.push(P.geometry.coordinates);
2172
2248
  }
2173
- const f = {
2249
+ const N = {
2174
2250
  kts: void 0,
2175
2251
  deg: void 0
2176
2252
  };
@@ -2178,9 +2254,9 @@ class t0 {
2178
2254
  const i = u(A.updated).utc();
2179
2255
  if (q) {
2180
2256
  const s = r.calculateDistance(A, q), P = u(q.utc || q.updated).diff(i, "h", !0);
2181
- f.kts = Math.round(s / P * 100) / 100, f.deg = r.calculateBearing(A, q, !0, 0);
2257
+ N.kts = Math.round(s / P * 100) / 100, N.deg = r.calculateBearing(A, q, !0, 0);
2182
2258
  }
2183
- const S = N.point([A.lng, A.lat], {
2259
+ const f = S.point([A.lng, A.lat], {
2184
2260
  model: W.model,
2185
2261
  name: O.name,
2186
2262
  nameCn: O.nameCn,
@@ -2189,23 +2265,23 @@ class t0 {
2189
2265
  format: i.format("MMM-DD/HHmm[Z]"),
2190
2266
  pressure: A.pressure > 1e4 ? a.roundPrecision((A == null ? void 0 : A.pressure) / 100, 0) : a.roundPrecision(A.pressure, 0),
2191
2267
  wind: A.wind,
2192
- movement: f,
2268
+ movement: N,
2193
2269
  category: T,
2194
2270
  type: "forecast",
2195
2271
  important: !0
2196
2272
  // 第一个预报点为重要点
2197
2273
  });
2198
- d.unshift(S), Y.unshift(S.geometry.coordinates);
2274
+ d.unshift(f), Y.unshift(f.geometry.coordinates);
2199
2275
  }
2200
2276
  if (z.features.push(...d), (Y == null ? void 0 : Y.length) > 1) {
2201
- const i = N.lineString(a.convertToMonotonicLng2(Y), {
2277
+ const i = S.lineString(a.convertToMonotonicLng2(Y), {
2202
2278
  date: (A == null ? void 0 : A.updated) || (R == null ? void 0 : R.format()),
2203
2279
  id: O.id || O.name,
2204
2280
  model: W.model,
2205
2281
  name: O.name,
2206
2282
  category: T,
2207
2283
  type: "forecast",
2208
- movement: f
2284
+ movement: N
2209
2285
  });
2210
2286
  z.features.push(i);
2211
2287
  }
@@ -2214,9 +2290,9 @@ class t0 {
2214
2290
  if (z.features.sort((W, q) => W.properties.type === "forecast" && q.properties.type === "forecast" && W.geometry.type === "Point" && q.geometry.type === "Point" ? u(W.properties.date).valueOf() - u(q.properties.date).valueOf() : 0), (p = O.history) != null && p.length) {
2215
2291
  const W = [], q = u(A == null ? void 0 : A.updated).utc(), Y = u((c = O.history) == null ? void 0 : c.at(-1).updated).utc(), d = q.diff(Y, "h") % 24 > 2 ? 24 : 12;
2216
2292
  for (const R of O.history) {
2217
- const T = u(R.updated).utc(), f = T.isSameOrBefore(q) || T.isSame(Y);
2218
- f && q.add(-d, "h");
2219
- const i = N.point([R.lng, R.lat], {
2293
+ const T = u(R.updated).utc(), N = T.isSameOrBefore(q) || T.isSame(Y);
2294
+ N && q.add(-d, "h");
2295
+ const i = S.point([R.lng, R.lat], {
2220
2296
  name: O.name,
2221
2297
  nameCn: O.nameCn,
2222
2298
  date: T.format(),
@@ -2228,12 +2304,12 @@ class t0 {
2228
2304
  category: `${O.name}-history`,
2229
2305
  wind: R.wind,
2230
2306
  movement: R.movement,
2231
- important: f
2307
+ important: N
2232
2308
  });
2233
2309
  z.features.push(i), W.push(i.geometry.coordinates);
2234
2310
  }
2235
2311
  if (W.length === 1 && W.push(W[0]), W.length > 1) {
2236
- const R = N.lineString(a.convertToMonotonicLng2(W), {
2312
+ const R = S.lineString(a.convertToMonotonicLng2(W), {
2237
2313
  name: O.name,
2238
2314
  type: "history",
2239
2315
  updated: A == null ? void 0 : A.updated,
@@ -2256,15 +2332,15 @@ class t0 {
2256
2332
  var c, O, A, W;
2257
2333
  const b = (c = M == null ? void 0 : M.data) == null ? void 0 : c.features.filter((q) => q.geometry.type === "LineString" && q.properties.type === "forecast"), p = [];
2258
2334
  for (const q of b) {
2259
- const Y = q.properties.name, d = q.properties.model, R = q.properties.showCircle, T = q.properties.disabled, f = u(q.properties.date).utc();
2335
+ const Y = q.properties.name, d = q.properties.model, R = q.properties.showCircle, T = q.properties.disabled, N = u(q.properties.date).utc();
2260
2336
  let i = z * 60;
2261
- const S = (O = M == null ? void 0 : M.data) == null ? void 0 : O.features.filter(
2337
+ const f = (O = M == null ? void 0 : M.data) == null ? void 0 : O.features.filter(
2262
2338
  (l) => l.geometry.type === "Point" && l.properties.type === "forecast" && l.properties.category === `${Y}-${d}`
2263
2339
  );
2264
- let s, P = f.clone().add(i, "minute").set({ minute: 0, second: 0, millisecond: 0 });
2265
- for (; s = this.pickIndex(S, P), s <= S.length - 1; ) {
2340
+ let s, P = N.clone().add(i, "minute").set({ minute: 0, second: 0, millisecond: 0 });
2341
+ for (; s = this.pickIndex(f, P), s <= f.length - 1; ) {
2266
2342
  if (s > 0) {
2267
- const l = S[s], B = s === 0 ? void 0 : S[s - 1], G = (i / 60 - ((A = B == null ? void 0 : B.properties) == null ? void 0 : A.hour)) / (l.properties.hour - ((W = B == null ? void 0 : B.properties) == null ? void 0 : W.hour)), H = this.computeNumber(B == null ? void 0 : B.geometry.coordinates[0], l.geometry.coordinates[0], G), F = this.computeNumber(B == null ? void 0 : B.geometry.coordinates[1], l.geometry.coordinates[1], G), $ = N.point([H, F], {
2343
+ const l = f[s], B = s === 0 ? void 0 : f[s - 1], G = (i / 60 - ((A = B == null ? void 0 : B.properties) == null ? void 0 : A.hour)) / (l.properties.hour - ((W = B == null ? void 0 : B.properties) == null ? void 0 : W.hour)), H = this.computeNumber(B == null ? void 0 : B.geometry.coordinates[0], l.geometry.coordinates[0], G), F = this.computeNumber(B == null ? void 0 : B.geometry.coordinates[1], l.geometry.coordinates[1], G), $ = S.point([H, F], {
2268
2344
  name: Y,
2269
2345
  model: d,
2270
2346
  category: l == null ? void 0 : l.properties.category,
@@ -2281,7 +2357,7 @@ class t0 {
2281
2357
  });
2282
2358
  p.push($);
2283
2359
  }
2284
- i += z * 60, P = f.clone().add(i, "minute").set({ minute: 0, second: 0, millisecond: 0 });
2360
+ i += z * 60, P = N.clone().add(i, "minute").set({ minute: 0, second: 0, millisecond: 0 });
2285
2361
  }
2286
2362
  }
2287
2363
  return p;
@@ -2311,9 +2387,9 @@ class t0 {
2311
2387
  const { t1: c, t2: O, hr: A, hours: W } = this.tropicalCenterTwin(z, 24, p);
2312
2388
  if (c && O) {
2313
2389
  if (!p.debug) {
2314
- const f = r.calculateDistance(M, c), i = r.calculateDistance(M, O);
2315
- if (f > 2 * b && i > 2 * b)
2316
- return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", p.requestId, f, i, {
2390
+ const N = r.calculateDistance(M, c), i = r.calculateDistance(M, O);
2391
+ if (N > 2 * b && i > 2 * b)
2392
+ return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need diversion: %j", p.requestId, N, i, {
2317
2393
  from: M,
2318
2394
  t1: c,
2319
2395
  t2: O,
@@ -2350,9 +2426,9 @@ class t0 {
2350
2426
  const { t1: c, t2: O, hr: A, hours: W } = this.tropicalCenterTwin(z, 24, p);
2351
2427
  if (c && O) {
2352
2428
  if (!p.debug) {
2353
- const T = r.calculateDistance(M, c), f = r.calculateDistance(M, O);
2354
- if (T > 2 * b && f > 2 * b)
2355
- return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", p.requestId, T, f, {
2429
+ const T = r.calculateDistance(M, c), N = r.calculateDistance(M, O);
2430
+ if (T > 2 * b && N > 2 * b)
2431
+ return I == null || I.info("[%s] the distance between from and t1(%d) and t2(%d) is enough, no need drifting: %j", p.requestId, T, N, {
2356
2432
  from: M,
2357
2433
  t1: c,
2358
2434
  t2: O,
@@ -2373,7 +2449,7 @@ class t0 {
2373
2449
  * @private
2374
2450
  */
2375
2451
  static tropicalCenterTwin(M, z = 24, b = {}) {
2376
- var Y, d, R, T, f;
2452
+ var Y, d, R, T, N;
2377
2453
  let p = {};
2378
2454
  (Y = M.forecasts) == null || Y.forEach((i) => {
2379
2455
  p = { ...i.hours, ...p };
@@ -2381,7 +2457,7 @@ class t0 {
2381
2457
  const c = ((d = M == null ? void 0 : M.history) == null ? void 0 : d[0]) || (p == null ? void 0 : p[(R = Object.keys(p)) == null ? void 0 : R[0]]);
2382
2458
  I == null || I.info("[%s] the first tropical center: %j", b.requestId, c);
2383
2459
  let O = (T = Object.keys(p || {}).filter((i) => Number(i) <= (z < 0 ? 24 : z))) == null ? void 0 : T.at(-1);
2384
- O || (O = (f = Object.keys(p || {}).filter((i) => Number(i) <= (z < 0 ? 24 : 2 * z))) == null ? void 0 : f.at(-1));
2460
+ O || (O = (N = Object.keys(p || {}).filter((i) => Number(i) <= (z < 0 ? 24 : 2 * z))) == null ? void 0 : N.at(-1));
2385
2461
  const A = p == null ? void 0 : p[O || -1];
2386
2462
  I == null || I.info("[%s] the second tropical center: %j in %d hrs", b.requestId, A, O);
2387
2463
  const W = Object.keys(p || {}).filter((i) => Number(i) <= Number(O)), q = { 0: c };
@@ -2414,78 +2490,9 @@ class t0 {
2414
2490
  return z;
2415
2491
  }
2416
2492
  }
2417
- class V0 {
2418
- static json2Str(M) {
2419
- const z = M.type ? M.type[0].toUpperCase() : "A";
2420
- return `${M.lat}|${M.lng}|${M.positionTime}|${M.sog}|${M.cog}|${M.hdg}|${M.draught}|${z}|${JSON.stringify(M.meteo || {})}|${M.vendor}|${M.deleted}`;
2421
- }
2422
- static str2Json(M) {
2423
- const [z, b, p, c, O, A, W, q, Y, d, R] = M.split("|");
2424
- return {
2425
- lat: Number(z),
2426
- lng: Number(b),
2427
- positionTime: Number(p),
2428
- sog: Number(c),
2429
- cog: Number(O),
2430
- hdg: Number(A),
2431
- //@ts-ignore
2432
- draught: isNaN(W) ? null : Number(W),
2433
- type: q,
2434
- important: q !== "A",
2435
- meteo: Y ? JSON.parse(Y) : void 0,
2436
- vendor: d,
2437
- deleted: R === "true"
2438
- };
2439
- }
2440
- static inspectStoppages(M, z = 1, b = !0) {
2441
- const p = M.at(0).positionTime < M.at(-1).positionTime;
2442
- p || M.sort((W, q) => W.positionTime - q.positionTime);
2443
- const c = [];
2444
- let O, A;
2445
- for (let W = 0; W < M.length - 1; W++) {
2446
- const q = M[W];
2447
- if (!(b && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(q.type))) {
2448
- for (let Y = W + 1; Y < M.length; Y++) {
2449
- const d = M[Y - 1], R = M[Y];
2450
- if (b && ["N", "B", "E", "NOON", "BOSP", "EOSP"].includes(q.type))
2451
- continue;
2452
- const T = R.positionTime - d.positionTime;
2453
- if (r.calculateDistance(R, d, !0, 4) / (T / 3600) < z)
2454
- O || (O = q), Y === M.length - 1 && (A = R, W = Y);
2455
- else {
2456
- O && (A = M[Y - 1], W = Y);
2457
- break;
2458
- }
2459
- }
2460
- if ((A == null ? void 0 : A.positionTime) > (O == null ? void 0 : O.positionTime) && O) {
2461
- const Y = {
2462
- start: {
2463
- lat: O.lat,
2464
- lng: O.lng,
2465
- sog: O.sog,
2466
- positionTime: O.positionTime,
2467
- utc: u.unix(O.positionTime).utc().format()
2468
- },
2469
- end: {
2470
- lat: A.lat,
2471
- lng: A.lng,
2472
- sog: A.sog,
2473
- positionTime: A.positionTime,
2474
- utc: u.unix(A.positionTime).utc().format()
2475
- },
2476
- duration: A.positionTime - O.positionTime
2477
- }, d = M.filter((T) => T.positionTime >= Y.start.positionTime && T.positionTime <= Y.end.positionTime), R = r.divideAccordingToLng(d);
2478
- Y.distance = r.calculateRouteDistance(R), Y.hours = Math.round(Y.duration / 3600 * 10) / 10, Y.avgSog = Math.round(Y.distance / Y.hours * 10) / 10, c.push(Y);
2479
- }
2480
- O = void 0, A = void 0;
2481
- }
2482
- }
2483
- return p || M.sort((W, q) => q.positionTime - W.positionTime), c;
2484
- }
2485
- }
2486
2493
  export {
2487
- V0 as AisHelper,
2494
+ B0 as AisHelper,
2488
2495
  r as LaneHelper,
2489
2496
  a as LngLatHelper,
2490
- t0 as TropicalHelper
2497
+ V0 as TropicalHelper
2491
2498
  };