@idm-plugin/geo 1.0.5 → 1.0.7

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.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export * from './lngLat/src/';
2
1
  export * from './tropicals/src/';
2
+ export * from './lane/src';
3
+ export * from './lngLat/src/';
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
- import y from "moment";
1
+ import * as g from "@turf/turf";
2
+ import v from "moment";
2
3
  import "moment-timezone";
3
- import T from "tz-lookup";
4
- import * as N from "@turf/turf";
5
- class u {
4
+ import R from "tz-lookup";
5
+ class l {
6
6
  /**
7
7
  * 基于输入的经度,计算出时区
8
8
  * @param lng
9
9
  * @param lat
10
10
  */
11
11
  static guessTimeZoneOffset(e, t) {
12
- const r = T(t, e), s = y().tz(r).utcOffset();
12
+ const n = R(t, e), s = v().tz(n).utcOffset();
13
13
  return this.roundPrecision(s / 60, 1);
14
14
  }
15
15
  /**
@@ -18,22 +18,22 @@ class u {
18
18
  * @return timezone => +08:30
19
19
  */
20
20
  static prettyTimeZoneOffset(e) {
21
- let t = Math.floor(Math.abs(e)), r = Math.round((Math.abs(e) - t) * 60);
22
- return r = r > 9 ? r : `0${r}`, t = t > 9 ? t : `0${t}`, e > 0 ? `+${t}:${r}` : `-${t}:${r}`;
21
+ let t = Math.floor(Math.abs(e)), n = Math.round((Math.abs(e) - t) * 60);
22
+ return n = n > 9 ? n : `0${n}`, t = t > 9 ? t : `0${t}`, e > 0 ? `+${t}:${n}` : `-${t}:${n}`;
23
23
  }
24
- static lng2pretty(e, t = 6, r = "H°M′") {
25
- e = u.convertToStdLng(e, t);
24
+ static lng2pretty(e, t = 6, n = "H°M′") {
25
+ e = l.convertToStdLng(e, t);
26
26
  let s = "E";
27
- e < 0 && (s = "W"), e = Math.abs(e), r = r.toUpperCase();
28
- let i = e * 3600, o, n, c, m, a, p;
29
- o = i % 3600 % 60, r.indexOf("S") !== -1 && (i = i - o, n = u.padNumber(o, 2, 2)), c = i / 60 % 60, r.indexOf("M") !== -1 && (r.indexOf("S") !== -1 ? m = u.roundPrecision(c, t).toString().padStart(2, "0") : m = u.padNumber(c, 2, 2), i = i - c * 60), a = i / 3600, r.indexOf("M") !== -1 ? p = u.roundPrecision(a, t).toString().padStart(3, "0") : p = u.padNumber(a, 3, 2);
30
- const h = `${r.replace(/S+/gi, n).replace(/M+/gi, m).replace(/H+/gi, p)}${s}`;
27
+ e < 0 && (s = "W"), e = Math.abs(e), n = n.toUpperCase();
28
+ let o = e * 3600, i, r, c, a, d, u;
29
+ i = o % 3600 % 60, n.indexOf("S") !== -1 && (o = o - i, r = l.padNumber(i, 2, 2)), c = o / 60 % 60, n.indexOf("M") !== -1 && (n.indexOf("S") !== -1 ? a = l.roundPrecision(c, t).toString().padStart(2, "0") : a = l.padNumber(c, 2, 2), o = o - c * 60), d = o / 3600, n.indexOf("M") !== -1 ? u = l.roundPrecision(d, t).toString().padStart(3, "0") : u = l.padNumber(d, 3, 2);
30
+ const f = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${s}`;
31
31
  return {
32
32
  direction: s,
33
- degree: u.roundPrecision(a, t),
34
- minute: u.roundPrecision(c, t),
35
- second: u.roundPrecision(o, t),
36
- pretty: h
33
+ degree: l.roundPrecision(d, t),
34
+ minute: l.roundPrecision(c, t),
35
+ second: l.roundPrecision(i, t),
36
+ pretty: f
37
37
  };
38
38
  }
39
39
  /**
@@ -42,71 +42,71 @@ class u {
42
42
  * @param precision 精确度
43
43
  * @param format 格式化
44
44
  */
45
- static lat2pretty(e, t = 6, r = "H°M′") {
45
+ static lat2pretty(e, t = 6, n = "H°M′") {
46
46
  e = e % 180;
47
47
  let s = "N";
48
- e < 0 && (s = "S"), e = Math.abs(e), r = r.toUpperCase();
49
- let i = e * 3600, o, n, c, m, a, p;
50
- o = i % 3600 % 60, r.indexOf("S") !== -1 && (i = i - o, n = u.padNumber(o, 2, 2)), c = i / 60 % 60, r.indexOf("M") !== -1 && (r.indexOf("S") !== -1 ? m = u.roundPrecision(c, t).toString().padStart(2, "0") : m = u.padNumber(c, 2, 2), i = i - c * 60), a = i / 3600, r.indexOf("M") !== -1 ? p = u.roundPrecision(a, t).toString().padStart(2, "0") : p = u.padNumber(a, 2, 2);
51
- const h = `${r.replace(/S+/gi, n).replace(/M+/gi, m).replace(/H+/gi, p)}${s}`;
48
+ e < 0 && (s = "S"), e = Math.abs(e), n = n.toUpperCase();
49
+ let o = e * 3600, i, r, c, a, d, u;
50
+ i = o % 3600 % 60, n.indexOf("S") !== -1 && (o = o - i, r = l.padNumber(i, 2, 2)), c = o / 60 % 60, n.indexOf("M") !== -1 && (n.indexOf("S") !== -1 ? a = l.roundPrecision(c, t).toString().padStart(2, "0") : a = l.padNumber(c, 2, 2), o = o - c * 60), d = o / 3600, n.indexOf("M") !== -1 ? u = l.roundPrecision(d, t).toString().padStart(2, "0") : u = l.padNumber(d, 2, 2);
51
+ const f = `${n.replace(/S+/gi, r).replace(/M+/gi, a).replace(/H+/gi, u)}${s}`;
52
52
  return {
53
53
  direction: s,
54
- degree: u.roundPrecision(a, t),
55
- minute: u.roundPrecision(c, t),
56
- second: u.roundPrecision(o, t),
57
- pretty: h
54
+ degree: l.roundPrecision(d, t),
55
+ minute: l.roundPrecision(c, t),
56
+ second: l.roundPrecision(i, t),
57
+ pretty: f
58
58
  };
59
59
  }
60
60
  static str2Lng(e, t = 6) {
61
- let r;
61
+ let n;
62
62
  if (isNaN(e)) {
63
- e = u.strReplace(e, "LNG");
63
+ e = l.strReplace(e, "LNG");
64
64
  const s = e[e.length - 1].toUpperCase();
65
65
  e = e.substring(0, e.length - 1).trim();
66
- const i = e.split(" ").filter((c) => c !== "").map((c) => Number(c));
67
- let [o, n] = i;
68
- if (o > 360 && !n) {
69
- const c = this.roundPrecision(o / 100, 0);
70
- n = o - c * 100, o = c;
66
+ const o = e.split(" ").filter((c) => c !== "").map((c) => Number(c));
67
+ let [i, r] = o;
68
+ if (i > 360 && !r) {
69
+ const c = this.roundPrecision(i / 100, 0);
70
+ r = i - c * 100, i = c;
71
71
  }
72
- r = o + (n ?? 0) / 60, s === "W" && (r = r * -1);
72
+ n = i + (r ?? 0) / 60, s === "W" && (n = n * -1);
73
73
  } else
74
- r = Number(e);
75
- return u.convertToStdLng(r, t);
74
+ n = Number(e);
75
+ return l.convertToStdLng(n, t);
76
76
  }
77
77
  static str2Lat(e, t = 6) {
78
- let r;
78
+ let n;
79
79
  if (isNaN(e)) {
80
- e = u.strReplace(e, "LAT");
80
+ e = l.strReplace(e, "LAT");
81
81
  const s = e[e.length - 1].toUpperCase();
82
82
  e = e.substring(0, e.length - 1).trim();
83
- const i = e.split(" ").filter((c) => c !== "").map((c) => Number(c));
84
- let [o, n] = i;
85
- if (o > 90 && !n) {
86
- const c = this.roundPrecision(o / 100, 0);
87
- n = o - c * 100, o = c;
83
+ const o = e.split(" ").filter((c) => c !== "").map((c) => Number(c));
84
+ let [i, r] = o;
85
+ if (i > 90 && !r) {
86
+ const c = this.roundPrecision(i / 100, 0);
87
+ r = i - c * 100, i = c;
88
88
  }
89
- r = o + (n ?? 0) / 60, s === "S" && (r = r * -1);
89
+ n = i + (r ?? 0) / 60, s === "S" && (n = n * -1);
90
90
  } else
91
- r = Number(e);
92
- return u.roundPrecision(r, t);
91
+ n = Number(e);
92
+ return l.roundPrecision(n, t);
93
93
  }
94
- static str2LngOrLat(e, t = 6, r = "LAT") {
95
- e = u.strReplace(e, r);
94
+ static str2LngOrLat(e, t = 6, n = "LAT") {
95
+ e = l.strReplace(e, n);
96
96
  const s = e[e.length - 1].toUpperCase();
97
97
  return ["N", "S"].includes(s) ? {
98
- lat: u.str2Lat(e, t)
98
+ lat: l.str2Lat(e, t)
99
99
  } : {
100
- lng: u.str2Lng(e, t)
100
+ lng: l.str2Lng(e, t)
101
101
  };
102
102
  }
103
103
  static convertToStdLng(e, t = 4) {
104
- return e > 180 ? (e = e % 360, e = e > 180 ? e - 360 : e) : e < -180 && (e = e % 360, e = e < -180 ? e + 360 : e), u.roundPrecision(e, t);
104
+ return e > 180 ? (e = e % 360, e = e > 180 ? e - 360 : e) : e < -180 && (e = e % 360, e = e < -180 ? e + 360 : e), l.roundPrecision(e, t);
105
105
  }
106
106
  static roundPrecision(e, t = 4) {
107
107
  if (typeof e == "number") {
108
- const r = Number("1".padEnd(t + 1, "0"));
109
- return Math.round(e * r) / r;
108
+ const n = Number("1".padEnd(t + 1, "0"));
109
+ return Math.round(e * n) / n;
110
110
  }
111
111
  return e;
112
112
  }
@@ -130,12 +130,12 @@ class u {
130
130
  }
131
131
  static strReplace(e, t = "LAT") {
132
132
  e = e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g, "$1 $2").replace(/-/g, " ").replace(/°/, " ").replace(/'/g, " ").replace(/′/g, " ").replace(/"/g, " ").replace(/∼/g, " ").replace(/°/g, " ").replace(/,/g, ".").replace(/^ /g, "").replace(/ $/g, "").trim();
133
- const r = e[e.length - 1].toUpperCase();
134
- if (!["N", "S", "E", "W"].includes(r)) {
135
- const s = e, i = Number(s.split(" ")[0]);
136
- if (isNaN(i))
133
+ const n = e[e.length - 1].toUpperCase();
134
+ if (!["N", "S", "E", "W"].includes(n)) {
135
+ const s = e, o = Number(s.split(" ")[0]);
136
+ if (isNaN(o))
137
137
  throw new Error(`invalid Lat/Lng: ${e}`);
138
- i >= 90 ? e = `${s}E` : i <= -90 ? e = `${s}W` : ["LAN", "LNG"].includes(t == null ? void 0 : t.toUpperCase()) ? e = `${s}${i > 0 ? "E" : "W"}` : e = `${s}${i > 0 ? "N" : "S"}`;
138
+ o >= 90 ? e = `${s}E` : o <= -90 ? e = `${s}W` : ["LAN", "LNG"].includes(t == null ? void 0 : t.toUpperCase()) ? e = `${s}${o > 0 ? "E" : "W"}` : e = `${s}${o > 0 ? "N" : "S"}`;
139
139
  }
140
140
  return e;
141
141
  }
@@ -146,158 +146,690 @@ class u {
146
146
  * @param intPrecision 整数位数
147
147
  * @param dcmPrecision 小数位数
148
148
  */
149
- static padNumber(e, t = 2, r = 2) {
150
- const s = Math.trunc(e).toString().padStart(t, "0"), i = Math.trunc(u.roundPrecision(e - Math.trunc(e), r) * Math.pow(10, r)).toString().padStart(r, "0");
151
- return `${s}.${i}`;
149
+ static padNumber(e, t = 2, n = 2) {
150
+ const s = Math.trunc(e).toString().padStart(t, "0"), o = Math.trunc(l.roundPrecision(e - Math.trunc(e), n) * Math.pow(10, n)).toString().padStart(n, "0");
151
+ return `${s}.${o}`;
152
152
  }
153
153
  }
154
- class x {
154
+ class I {
155
155
  static convert2Geojson(e) {
156
- var r;
157
- const t = N.featureCollection([]);
156
+ var n;
157
+ const t = g.featureCollection([]);
158
158
  for (const s of e) {
159
159
  if (s.forecasts) {
160
- const i = (r = s.history) == null ? void 0 : r[0];
161
- for (const o of s.forecasts) {
162
- const n = [], c = y(o.date).utc(), m = `${s.name}-${o.model}`;
163
- if (i) {
164
- const a = y(i.updated).utc(), p = N.point([i.lng, i.lat], {
165
- model: o.model,
160
+ const o = (n = s.history) == null ? void 0 : n[0];
161
+ for (const i of s.forecasts) {
162
+ const r = [], c = v(i.date).utc(), a = `${s.name}-${i.model}`;
163
+ if (o) {
164
+ const d = v(o.updated).utc(), u = g.point([o.lng, o.lat], {
165
+ model: i.model,
166
166
  name: s.name,
167
- date: a.format(),
167
+ date: d.format(),
168
168
  hour: 0,
169
- format: a.format("MMM-DD/HHmm[Z]"),
170
- pressure: i.pressure > 1e4 ? u.roundPrecision(i.pressure / 100, 0) : u.roundPrecision(i.pressure, 0),
171
- wind: { kts: i.kts, spd: i.speed || i.spd },
172
- category: m,
169
+ format: d.format("MMM-DD/HHmm[Z]"),
170
+ pressure: o.pressure > 1e4 ? l.roundPrecision(o.pressure / 100, 0) : l.roundPrecision(o.pressure, 0),
171
+ wind: { kts: o.kts, spd: o.speed || o.spd },
172
+ category: a,
173
173
  type: "forecast"
174
174
  });
175
- t.features.push(p), n.push(p.geometry.coordinates);
175
+ t.features.push(u), r.push(u.geometry.coordinates);
176
176
  }
177
- for (const a in o == null ? void 0 : o.hours) {
178
- const p = o.hours[a];
179
- p.wind.spd = p.wind.spd || p.wind.speed;
180
- const h = c.clone().add(Number(a), "hour"), l = N.point([p.lng, p.lat], {
181
- model: o.model,
177
+ for (const d in i == null ? void 0 : i.hours) {
178
+ const u = i.hours[d];
179
+ u.wind.spd = u.wind.spd || u.wind.speed;
180
+ const f = c.clone().add(Number(d), "hour"), p = g.point([u.lng, u.lat], {
181
+ model: i.model,
182
182
  name: s.name,
183
- date: h.format(),
184
- hour: Number(a),
185
- format: h.format("MMM-DD/HHmm[Z]"),
186
- pressure: p.pressure > 1e4 ? u.roundPrecision(p.pressure / 100, 0) : u.roundPrecision(p.pressure, 0),
187
- gusts: p.gusts,
188
- wind: p.wind || {},
189
- movement: p.movement,
190
- category: m,
183
+ date: f.format(),
184
+ hour: Number(d),
185
+ format: f.format("MMM-DD/HHmm[Z]"),
186
+ pressure: u.pressure > 1e4 ? l.roundPrecision(u.pressure / 100, 0) : l.roundPrecision(u.pressure, 0),
187
+ gusts: u.gusts,
188
+ wind: u.wind || {},
189
+ movement: u.movement,
190
+ category: a,
191
191
  type: "forecast"
192
192
  });
193
- t.features.push(l), n.push(l.geometry.coordinates);
193
+ t.features.push(p), r.push(p.geometry.coordinates);
194
194
  }
195
- if ((n == null ? void 0 : n.length) > 1) {
196
- const a = N.lineString(u.convertToMonotonicLng2(n), {
197
- date: o.date,
195
+ if ((r == null ? void 0 : r.length) > 1) {
196
+ const d = g.lineString(l.convertToMonotonicLng2(r), {
197
+ date: i.date,
198
198
  id: s.id || s.name,
199
- model: o.model,
199
+ model: i.model,
200
200
  name: s.name,
201
- category: m,
201
+ category: a,
202
202
  type: "forecast"
203
203
  });
204
- t.features.push(a);
204
+ t.features.push(d);
205
205
  }
206
206
  }
207
207
  }
208
208
  if (s.history) {
209
- const i = [];
210
- for (const n of s.history) {
211
- const c = y(n.updated).utc(), m = N.point([n.lng, n.lat], {
209
+ const o = [];
210
+ for (const r of s.history) {
211
+ const c = v(r.updated).utc(), a = g.point([r.lng, r.lat], {
212
212
  name: s.name,
213
213
  date: c.format(),
214
214
  format: c.format("MMM-DD/HHmm[Z]"),
215
- pressure: n.pressure > 1e4 ? u.roundPrecision(n.pressure / 100, 0) : u.roundPrecision(n.pressure, 0),
216
- spd: n.speed || n.spd,
217
- kts: n.kts,
218
- source: n.source,
219
- level: n.type,
215
+ pressure: r.pressure > 1e4 ? l.roundPrecision(r.pressure / 100, 0) : l.roundPrecision(r.pressure, 0),
216
+ spd: r.speed || r.spd,
217
+ kts: r.kts,
218
+ source: r.source,
219
+ level: r.type,
220
220
  type: "history",
221
221
  category: `${s.name}-history`
222
222
  });
223
- t.features.push(m), i.push(m.geometry.coordinates);
223
+ t.features.push(a), o.push(a.geometry.coordinates);
224
224
  }
225
- const o = s.history[0];
226
- if (i.length === 1 && i.push(i[0]), i.length > 1) {
227
- const n = N.lineString(u.convertToMonotonicLng2(i), {
225
+ const i = s.history[0];
226
+ if (o.length === 1 && o.push(o[0]), o.length > 1) {
227
+ const r = g.lineString(l.convertToMonotonicLng2(o), {
228
228
  name: s.name,
229
229
  type: "history",
230
- updated: o == null ? void 0 : o.updated,
231
- pressure: (o == null ? void 0 : o.pressure) > 1e4 ? u.roundPrecision((o == null ? void 0 : o.pressure) / 100, 0) : u.roundPrecision(o == null ? void 0 : o.pressure, 0),
232
- spd: (o == null ? void 0 : o.speed) || (o == null ? void 0 : o.spd),
233
- kts: o == null ? void 0 : o.kts,
234
- source: o == null ? void 0 : o.source,
235
- level: o == null ? void 0 : o.type
230
+ updated: i == null ? void 0 : i.updated,
231
+ pressure: (i == null ? void 0 : i.pressure) > 1e4 ? l.roundPrecision((i == null ? void 0 : i.pressure) / 100, 0) : l.roundPrecision(i == null ? void 0 : i.pressure, 0),
232
+ spd: (i == null ? void 0 : i.speed) || (i == null ? void 0 : i.spd),
233
+ kts: i == null ? void 0 : i.kts,
234
+ source: i == null ? void 0 : i.source,
235
+ level: i == null ? void 0 : i.type
236
236
  });
237
- t.features.push(n);
237
+ t.features.push(r);
238
238
  }
239
239
  }
240
240
  }
241
241
  return t;
242
242
  }
243
243
  static interpolate(e, t = 3) {
244
- var i, o, n, c;
245
- const r = (i = e == null ? void 0 : e.data) == null ? void 0 : i.features.filter((m) => m.geometry.type === "LineString" && m.properties.type === "forecast"), s = [];
246
- for (const m of r) {
247
- const a = m.properties.name, p = m.properties.model, h = y(m.properties.date).utc();
248
- let l = t * 60 - (h.get("hour") * 60 + h.get("minute")) % (t * 60);
249
- const b = (o = e == null ? void 0 : e.data) == null ? void 0 : o.features.filter(
250
- (f) => f.geometry.type === "Point" && f.properties.type === "forecast" && f.properties.category === `${a}-${p}`
244
+ var o, i, r, c;
245
+ const n = (o = e == null ? void 0 : e.data) == null ? void 0 : o.features.filter((a) => a.geometry.type === "LineString" && a.properties.type === "forecast"), s = [];
246
+ for (const a of n) {
247
+ const d = a.properties.name, u = a.properties.model, f = v(a.properties.date).utc();
248
+ let p = t * 60 - (f.get("hour") * 60 + f.get("minute")) % (t * 60);
249
+ const b = (i = e == null ? void 0 : e.data) == null ? void 0 : i.features.filter(
250
+ (m) => m.geometry.type === "Point" && m.properties.type === "forecast" && m.properties.category === `${d}-${u}`
251
251
  );
252
- let M, S = h.clone().add(l, "minute").set({ minute: 0, second: 0, millisecond: 0 });
253
- for (; M = this.pickIndex(b, S), M <= b.length - 1; ) {
254
- if (M > 0) {
255
- const f = b[M], d = M === 0 ? void 0 : b[M - 1], g = (l / 60 - ((n = d == null ? void 0 : d.properties) == null ? void 0 : n.hour)) / (f.properties.hour - ((c = d == null ? void 0 : d.properties) == null ? void 0 : c.hour)), $ = this.computeNumber(d == null ? void 0 : d.geometry.coordinates[0], f.geometry.coordinates[0], g), P = this.computeNumber(d == null ? void 0 : d.geometry.coordinates[1], f.geometry.coordinates[1], g), w = N.point([$, P], {
256
- name: a,
257
- model: p,
258
- category: f == null ? void 0 : f.properties.category,
259
- date: S.format(),
260
- format: S.format("MMM-DD/HHmm[Z]"),
261
- gusts: this.computeNumber(d == null ? void 0 : d.properties.gusts, f.properties.gusts, g),
262
- hour: this.computeNumber(d == null ? void 0 : d.properties.hour, f.properties.hour, g),
263
- movement: this.computeNumber(d == null ? void 0 : d.properties.movement, f.properties.movement, g),
264
- pressure: this.computeNumber(d == null ? void 0 : d.properties.pressure, f.properties.pressure, g),
265
- wind: this.computeNumber(d == null ? void 0 : d.properties.wind, f.properties.wind, g),
252
+ let T, P = f.clone().add(p, "minute").set({ minute: 0, second: 0, millisecond: 0 });
253
+ for (; T = this.pickIndex(b, P), T <= b.length - 1; ) {
254
+ if (T > 0) {
255
+ const m = b[T], h = T === 0 ? void 0 : b[T - 1], S = (p / 60 - ((r = h == null ? void 0 : h.properties) == null ? void 0 : r.hour)) / (m.properties.hour - ((c = h == null ? void 0 : h.properties) == null ? void 0 : c.hour)), M = this.computeNumber(h == null ? void 0 : h.geometry.coordinates[0], m.geometry.coordinates[0], S), N = this.computeNumber(h == null ? void 0 : h.geometry.coordinates[1], m.geometry.coordinates[1], S), C = g.point([M, N], {
256
+ name: d,
257
+ model: u,
258
+ category: m == null ? void 0 : m.properties.category,
259
+ date: P.format(),
260
+ format: P.format("MMM-DD/HHmm[Z]"),
261
+ gusts: this.computeNumber(h == null ? void 0 : h.properties.gusts, m.properties.gusts, S),
262
+ hour: this.computeNumber(h == null ? void 0 : h.properties.hour, m.properties.hour, S),
263
+ movement: this.computeNumber(h == null ? void 0 : h.properties.movement, m.properties.movement, S),
264
+ pressure: this.computeNumber(h == null ? void 0 : h.properties.pressure, m.properties.pressure, S),
265
+ wind: this.computeNumber(h == null ? void 0 : h.properties.wind, m.properties.wind, S),
266
266
  type: "forecast"
267
267
  });
268
- s.push(w);
268
+ s.push(C);
269
269
  }
270
- l += t * 60, S = h.clone().add(l, "minute").set({ minute: 0, second: 0, millisecond: 0 });
270
+ p += t * 60, P = f.clone().add(p, "minute").set({ minute: 0, second: 0, millisecond: 0 });
271
271
  }
272
272
  }
273
273
  return s;
274
274
  }
275
275
  static pickIndex(e, t) {
276
- let r = 0;
276
+ let n = 0;
277
277
  for (const s of e) {
278
- if (y(s.properties.date).isAfter(t))
279
- return r === 0 ? -1 : r;
280
- r++;
278
+ if (v(s.properties.date).isAfter(t))
279
+ return n === 0 ? -1 : n;
280
+ n++;
281
281
  }
282
- return r;
282
+ return n;
283
283
  }
284
- static computeNumber(e, t, r) {
284
+ static computeNumber(e, t, n) {
285
285
  if (e)
286
286
  if (t) {
287
287
  if (isNaN(e) && isNaN(t) && typeof e != "string" && typeof t != "string") {
288
288
  const s = {};
289
- for (const i in e)
290
- s[i] = this.computeNumber(e[i], t[i], r);
289
+ for (const o in e)
290
+ s[o] = this.computeNumber(e[o], t[o], n);
291
291
  return s;
292
292
  }
293
- return Math.round((e + (t - e) * r) * 100) / 100;
293
+ return Math.round((e + (t - e) * n) * 100) / 100;
294
294
  } else
295
295
  return e;
296
296
  else
297
297
  return t;
298
298
  }
299
299
  }
300
+ class W {
301
+ /**
302
+ * 计算方位角
303
+ * @param from 坐标 {lng, lat}
304
+ * @param to 坐标 {lng, lat}
305
+ * @param rhumb true 横向方位角,false 大圆方位角
306
+ * @param precision
307
+ * @returns {number} 单位度
308
+ */
309
+ static calculateBearing(e, t, n = !0, s = 4) {
310
+ const o = g.points([
311
+ [e.lng, e.lat],
312
+ [t.lng, t.lat]
313
+ ]);
314
+ let i;
315
+ return n ? i = g.rhumbBearing(o.features[0], o.features[1]) : i = g.bearing(o.features[0], o.features[1]), i < 0 && (i += 360), l.roundPrecision(i, s);
316
+ }
317
+ /**
318
+ * 计算两点间距离
319
+ * @param from 坐标 {lng, lat}
320
+ * @param to 坐标 {lng, lat}
321
+ * @param rhumb true 横向距离,false 大圆距离
322
+ * @param precision
323
+ * @param units 单位,默认 nm(海里)
324
+ * @returns {number}
325
+ */
326
+ static calculateDistance(e, t, n = !0, s = 4, o = "nauticalmiles") {
327
+ e = { ...e }, t = { ...t }, e.lng = l.convertToStdLng(e.lng, s), t.lng = l.convertToStdLng(t.lng, s);
328
+ const i = g.points([
329
+ [e.lng, e.lat],
330
+ [t.lng, t.lat]
331
+ ]);
332
+ let r;
333
+ return n ? r = g.rhumbDistance(i.features[0], i.features[1], { units: o }) : r = g.distance(i.features[0], i.features[1], { units: o }), l.roundPrecision(r, s);
334
+ }
335
+ /**
336
+ * 计算航线距离
337
+ * @param route [[[lng, lat],[lng, lat]]]
338
+ * @param precision
339
+ * @param units
340
+ */
341
+ static calculateRouteDistance(e, t = 4, n = "nauticalmiles") {
342
+ let s = 0, o;
343
+ for (const i of e)
344
+ for (let r = 0; r < i.length - 1; r++) {
345
+ const c = { lng: i[r][0], lat: i[r][1] };
346
+ r === 0 && o && (s += this.calculateDistance(o, c, !0, t, n));
347
+ const a = { lng: i[r + 1][0], lat: i[r + 1][1] };
348
+ s += this.calculateDistance(c, a, !0, t, n), o = a;
349
+ }
350
+ return l.roundPrecision(s, t);
351
+ }
352
+ /**
353
+ * 计算坐标(基于方位角和距离)
354
+ * @param from 坐标 {lng, lat}
355
+ * @param bearing 方位角,单位度
356
+ * @param distance 距离
357
+ * @param units 单位,默认 nm(海里)
358
+ * @param rhumb
359
+ */
360
+ static calculateCoordinate(e, t, n, s = "nauticalmiles", o = !0) {
361
+ const i = g.point([e.lng, e.lat]);
362
+ let r;
363
+ o ? r = g.rhumbDestination(i, n, t, { units: s }) : r = g.destination(i, n, t, { units: s });
364
+ const c = r.geometry.coordinates;
365
+ return { lng: l.convertToStdLng(c[0], 8), lat: l.roundPrecision(c[1], 8) };
366
+ }
367
+ /**
368
+ * 插值大圆坐标(基于两点方位角和间距)
369
+ * @param from 坐标 {lng, lat}
370
+ * @param to 坐标 {lng, lat}
371
+ * @param spacing 间距
372
+ * @param includeHead true 包含起点 from
373
+ * @param includeTail true 包含终点 to
374
+ * @param units 单位,默认 nm(海里)
375
+ */
376
+ static interpolateCoordinates(e, t, n, s = !0, o = !0, i = "nauticalmiles") {
377
+ const r = [], c = this.calculateBearing(e, t, !1), a = this.calculateDistance(e, t, !1, 8, i);
378
+ s && r.push({ lng: e.lng, lat: e.lat });
379
+ let d = 0;
380
+ for (; d < a; )
381
+ d += n, d < a && r.push(this.calculateCoordinate(e, c, d, i, !1));
382
+ return o && r.push({ lng: t.lng, lat: t.lat }), r;
383
+ }
384
+ /**
385
+ * 分组坐标(如相邻两个坐标经度差超180度,需以180为界将坐标分为两组)
386
+ * @param coordinates [{lng, lat}]
387
+ * @param rhumb
388
+ * @example
389
+ * coordinates: [{lng: 160,lat: 30}, {lng: 170, lat: 40},{lng: -170, lat: 40},{lng: -160, lat: 30}]
390
+ * @return [
391
+ * [[160, 30],[170,40]],
392
+ * [[-170,40],[-160,30]]
393
+ * ]
394
+ */
395
+ static divideAccordingToLng(e, t = !1) {
396
+ if ((e == null ? void 0 : e.length) < 2)
397
+ return [];
398
+ e = this.deduplicateCoordinates(e);
399
+ let n = [];
400
+ const s = [];
401
+ let o, i;
402
+ for (let r = 0; r < e.length - 1; r++) {
403
+ o = l.convertToStdLng(e[r].lng, 8), i = l.convertToStdLng(e[r + 1].lng, 8), n.push([o, e[r].lat]);
404
+ const c = o - i;
405
+ if (Math.abs(c) > 180) {
406
+ const a = l.convertToMonotonicLng2([
407
+ [o, e[r].lat],
408
+ [i, e[r + 1].lat]
409
+ ]);
410
+ let d, u;
411
+ t ? (d = g.lineString(a), u = g.lineString([
412
+ [c > 0 ? 180 : -180, 89],
413
+ [c > 0 ? 180 : -180, -89]
414
+ ])) : (d = g.greatCircle(a[0], a[1]), u = g.greatCircle([c > 0 ? 180 : -180, 89], [c > 0 ? 180 : -180, -89]));
415
+ const f = g.lineIntersect(d, u);
416
+ let p;
417
+ if (f.features.length) {
418
+ const b = g.getCoord(f.features[0]);
419
+ p = l.roundPrecision(b[1], 8);
420
+ } else
421
+ p = e[r].lat;
422
+ c > 0 ? (n.push([180 - 1e-6, p]), s.push([...n]), n = [], n.push([-(180 - 1e-6), p])) : (n.push([-(180 - 1e-6), p]), s.push([...n]), n = [], n.push([180 - 1e-6, p]));
423
+ }
424
+ r === e.length - 2 && n.push([i, e[r + 1].lat]);
425
+ }
426
+ return s.push(n), s;
427
+ }
428
+ /**
429
+ * 去除重复坐标
430
+ * @param route
431
+ */
432
+ static deduplicateRoute(e) {
433
+ const t = [];
434
+ for (const n of e) {
435
+ const s = n.reduce((o, i) => (o.findIndex((r) => r[0] === i[0] && r[1] === i[1]) === -1 && o.push(i), o), []);
436
+ t.push(s);
437
+ }
438
+ return t;
439
+ }
440
+ /**
441
+ * 去除重新坐标
442
+ * @param coordinates
443
+ */
444
+ static deduplicateCoordinates(e) {
445
+ return e.reduce((t, n) => (t.findIndex((s) => s.lat === n.lat && s.lng === n.lng) === -1 && t.push(n), t), []);
446
+ }
447
+ /**
448
+ * 移出坐标
449
+ * @param coordinate {lng, lat}
450
+ * @param route 航线[[[lng, lat],[lng, lat]]]
451
+ */
452
+ static removeCoordinateFromRoute(e, t) {
453
+ e.lng = l.convertToStdLng(e.lng, 8);
454
+ for (const n of t)
455
+ for (let s = n.length - 1; s >= 0; s--)
456
+ l.roundPrecision(n[s][0], 8) === e.lng && l.roundPrecision(n[s][1], 8) === l.roundPrecision(e.lat, 8) && n.splice(s, 1);
457
+ return t;
458
+ }
459
+ /**
460
+ * 移出坐标
461
+ * @param coordinate {lng, lat}
462
+ * @param waypoints [{lat, lng}, {lat, lng}]
463
+ */
464
+ static removeCoordinateFromWaypoints(e, t) {
465
+ e.lng = l.convertToStdLng(e.lng, 8);
466
+ for (let n = t.length - 1; n >= 0; n--)
467
+ l.roundPrecision(t[n].lng, 8) === e.lng && l.roundPrecision(t[n].lat, 8) === l.roundPrecision(e.lat, 8) && t.splice(n, 1);
468
+ return t;
469
+ }
470
+ /**
471
+ * 合并坐标进航线(基于坐标到线段最短距离边合并)
472
+ * @param coordinate 待合并的坐标 {lng, lat}
473
+ * @param route 航线[[[lng, lat],[lng, lat]]]
474
+ * @example
475
+ * coordinate {lng: 122, lat: 35}
476
+ *
477
+ * route: [[[120, 30], [125,40], [130, 37]], [[-150, 40], [-130, 30]]]
478
+ * @return
479
+ * [[[120, 30], [120, 35], [125,40], [130, 37]], [[-150, 40], [-130, 30]]]
480
+ */
481
+ static mergeCoordinateToRoute(e, t) {
482
+ e.lng = l.convertToStdLng(e.lng, 8);
483
+ let n = Number.MAX_VALUE, s = 0, o = 0, i, r;
484
+ return t.forEach((c, a) => {
485
+ for (let d = 0; d < c.length - 1; d++) {
486
+ const u = { lng: c[d][0], lat: c[d][1] }, f = { lng: c[d + 1][0], lat: c[d + 1][1] }, p = this.calculatePointToLineDistance(e, u, f);
487
+ n > p && (n = p, o = d, s = a, i = this.calculateDistance(u, e), r = this.calculateDistance(f, e));
488
+ }
489
+ }), i !== 0 && r !== 0 ? t[s].splice(o + 1, 0, [e.lng, e.lat]) : i === 0 ? t[s].splice(o, 1, [e.lng, e.lat]) : r === 0 && t[s].splice(o + 1, 1, [e.lng, e.lat]), t;
490
+ }
491
+ /**
492
+ * 合并多个waypoints进航线
493
+ * @param waypoints [{lat, lng}, {lat, lng}]
494
+ * @param route 航线 [[[lng, lat],[lng, lat]]]
495
+ */
496
+ static mergeWaypointsToRoute(e, t) {
497
+ for (const n of e)
498
+ t = this.mergeCoordinateToRoute(n, t);
499
+ return t;
500
+ }
501
+ /**
502
+ * 计算区间航线
503
+ * @param from {lng, lat}
504
+ * @param to {lng, lat}
505
+ * @param route [[[lng, lat]]]
506
+ * @return [[[lng, lat]]]
507
+ */
508
+ static calculateRangeRoute(e, t, n) {
509
+ n = this.mergeWaypointsToRoute([e, t], n);
510
+ const s = [];
511
+ let o = 0;
512
+ return n.forEach((i) => {
513
+ if (o === 2)
514
+ return;
515
+ const r = [];
516
+ for (const c of i) {
517
+ if (l.roundPrecision(t.lng, 8) === l.roundPrecision(c[0], 8) && l.roundPrecision(t.lat, 8) === l.roundPrecision(c[1], 8)) {
518
+ r.push(c), o === 0 && r.push([e.lng, e.lat]), o = 2;
519
+ break;
520
+ }
521
+ o === 1 ? r.push(c) : l.roundPrecision(e.lng, 8) === l.roundPrecision(c[0], 8) && l.roundPrecision(e.lat, 8) === l.roundPrecision(c[1], 8) && (o = 1, r.push(c));
522
+ }
523
+ r.length && s.push(r);
524
+ }), s;
525
+ }
526
+ /**
527
+ * 计算from到to之间的航线
528
+ * @param from {lng, lat}
529
+ * @param to {lng, lat}
530
+ * @param route [[[lng, lat]]]
531
+ * @param waypoints
532
+ * @return [{lng, lat}]
533
+ */
534
+ static calculateRangeWaypoints(e, t, n, s = []) {
535
+ const o = this.convertRouteToCoordinates(n, 0), i = this.mergeCoordinatesToWaypoints([e, t, ...s], o), r = i.findIndex(
536
+ (d) => l.roundPrecision(e.lng, 8) === l.roundPrecision(d.lng, 8) && l.roundPrecision(e.lat, 8) === l.roundPrecision(d.lat, 8)
537
+ ), c = i.findIndex(
538
+ (d) => l.roundPrecision(t.lng, 8) === l.roundPrecision(d.lng, 8) && l.roundPrecision(t.lat, 8) === l.roundPrecision(d.lat, 8)
539
+ );
540
+ return i.filter((d, u) => u >= r && u <= c);
541
+ }
542
+ /**
543
+ * 计算坐标到航路上的最短距离
544
+ * @param from
545
+ * @param route
546
+ */
547
+ static calculateMinDistanceToRoute(e, t) {
548
+ let n = Number.MAX_VALUE, s = 0, o = 0;
549
+ return t.forEach((i, r) => {
550
+ for (let c = 0; c < i.length - 1; c++) {
551
+ const a = { lng: i[c][0], lat: i[c][1] }, d = { lng: i[c + 1][0], lat: i[c + 1][1] }, u = this.calculatePointToLineDistance(e, a, d);
552
+ n > u && (n = u, s = c, o = r);
553
+ }
554
+ }), { minDist: n, segIndex: o, minIndex: s };
555
+ }
556
+ /**
557
+ * 计算子航线
558
+ * @param from {lng, lat} 起始位置
559
+ * @param route [[[lng, lat]]] 剩余航线
560
+ * @return [[[lng, lat]]]
561
+ */
562
+ static calculateSubRoute(e, t) {
563
+ const { segIndex: n, minIndex: s } = this.calculateMinDistanceToRoute({ ...e }, t);
564
+ e.lng = l.convertToStdLng(e.lng);
565
+ const o = [];
566
+ let i = !0;
567
+ for (let r = n; r < t.length; r++)
568
+ if (i) {
569
+ const c = [];
570
+ c.push([e.lng, e.lat]);
571
+ for (let a = s + 1; a < t[r].length; a++)
572
+ e.lng === t[r][a][0] && e.lat === t[r][a][1] || c.push(t[r][a]);
573
+ o.push(c), i = !1;
574
+ } else
575
+ o.push([...t[r]]);
576
+ return o;
577
+ }
578
+ /**
579
+ * 计算子途经点
580
+ * @param from {lng, lat} 起始位置
581
+ * @param waypoints [{lng, lat}]
582
+ * @return [{lng, lat}]
583
+ */
584
+ static calculateSubWaypoints(e, t) {
585
+ let n = Number.MAX_VALUE, s = 0;
586
+ for (let i = 0; i < t.length - 1; i++) {
587
+ const r = t[i], c = t[i + 1];
588
+ if (this.calculateDistance(e, r) === 0)
589
+ return t;
590
+ if (this.calculateDistance(e, c) === 0)
591
+ return t.filter((d, u) => u > 0);
592
+ const a = this.calculatePointToLineDistance(e, r, c);
593
+ n > a && (n = a, s = i);
594
+ }
595
+ e.lng = l.convertToStdLng(e.lng);
596
+ const o = [e];
597
+ for (let i = s + 1; i < t.length; i++)
598
+ o.push(t[i]);
599
+ return o;
600
+ }
601
+ /**
602
+ * 计算坐标到以(from, to)横向线上的距离
603
+ * @param coordinate { lng, lat }
604
+ * @param from { lng, lat }
605
+ * @param to { lng, lat }
606
+ * @param options
607
+ */
608
+ static calculatePointToLineDistance(e, t, n, s = { units: "nauticalmiles", method: "geodesic" }) {
609
+ e.lng = l.convertToStdLng(e.lng), t = { ...t }, n = { ...n }, t.lng = l.convertToStdLng(t.lng, 8), n.lng = l.convertToStdLng(n.lng, 8);
610
+ const o = l.convertToMonotonicLng([t, n]);
611
+ t = o[0], n = o[1];
612
+ const i = g.lineString([
613
+ [t.lng, t.lat],
614
+ [n.lng, n.lat]
615
+ ]), r = g.pointToLineDistance(g.point([e.lng, e.lat]), i, s), c = g.pointToLineDistance(g.point([e.lng > 0 ? e.lng - 360 : e.lng + 360, e.lat]), i, s);
616
+ return l.roundPrecision(Math.min(r, c), 6);
617
+ }
618
+ /**
619
+ * 计算途经点的COG, Distance等属性
620
+ * @param waypoints
621
+ * @param route
622
+ */
623
+ static calculateWaypointsPropInRoute(e, t) {
624
+ t = this.mergeWaypointsToRoute(e, t);
625
+ for (let n = 0; n < e.length - 1; n++) {
626
+ const s = e[n], o = e[n + 1], i = this.calculateRangeRoute(s, o, t);
627
+ n === 0 && (s.distanceFromPrevious = 0, s.distanceFromStart = 0), o.distanceFromPrevious = this.calculateRouteDistance(i), o.distanceFromStart = l.roundPrecision((s.distanceFromStart || 0) + o.distanceFromPrevious);
628
+ }
629
+ return e;
630
+ }
631
+ /**
632
+ * @param coordinates [{lng, lat}]
633
+ * @param waypoints [{lng, lat}]
634
+ * @param replace true replace the same waypoint with coordinate
635
+ */
636
+ static mergeCoordinatesToWaypoints(e, t, n = !0) {
637
+ for (const s of e)
638
+ this.mergeCoordinateToWaypoints(s, t, n);
639
+ return t;
640
+ }
641
+ /**
642
+ * 合并坐标进航路途经点
643
+ * @param coordinate 坐标 {lng, lat}
644
+ * @param waypoints 途经点 [{lng, lat}, {lng, lat}]
645
+ *
646
+ * @example
647
+ * coordinate: { lng: 179, lat: 50 }
648
+ * waypoints: [{ lng: 160, lat: 30}, { lng: 170, lat: 40}, {lng: -170, lat: 40}, {lng: -160, lat: 30}]
649
+ * @param replace true replace the same waypoint with coordinate
650
+ * @return
651
+ * [{ lng: 160, lat: 30}, { lng: 170, lat: 40}, {lng: 179, lat: 50}, {lng: -170, lat: 40}, {lng: -160, lat: 30}]
652
+ */
653
+ static mergeCoordinateToWaypoints(e, t, n = !0) {
654
+ e.lng = l.convertToStdLng(e.lng, 8);
655
+ let s = Number.MAX_VALUE, o = 0, i = 0, r = 0;
656
+ for (let c = 0; c < t.length - 1; c++) {
657
+ const a = { lng: t[c].lng, lat: t[c].lat }, d = { lng: t[c + 1].lng, lat: t[c + 1].lat }, u = this.calculatePointToLineDistance(e, a, d);
658
+ s >= u && (s = u, o = c, i = this.calculateDistance(a, e, !1, 6), r = this.calculateDistance(d, e, !1, 6));
659
+ }
660
+ return i !== 0 && r !== 0 ? i < s || i === s && o === 0 ? t.unshift(e) : r < s || r === s && o === t.length - 2 ? t.push(e) : t.splice(o + 1, 0, e) : i === 0 ? n && t.splice(o, 1, e) : r === 0 && n && t.splice(o + 1, 1, e), t.map((c) => (c.lng = l.convertToStdLng(c.lng), c));
661
+ }
662
+ /**
663
+ * 生成航线(基于途经点生成大圆/横向航线,并根据是否跨180度分组)
664
+ * @param waypoints [{lng, lat}, {lng: lat, gcToPrevious: true}]
665
+ * @return [[[lng, lat], [lng, lat]]]
666
+ */
667
+ static generateRouteAccordingToWaypoints(e) {
668
+ const t = [];
669
+ for (let n = 1; n < e.length; n++) {
670
+ const s = e[n - 1], o = e[n];
671
+ if (n === 1 && t.push(s), o.gcToPrevious) {
672
+ const i = this.interpolateCoordinates(s, o, 200, !1, !0, "nauticalmiles");
673
+ t.push(...i);
674
+ } else
675
+ t.push(o);
676
+ }
677
+ return this.divideAccordingToLng(t, !0);
678
+ }
679
+ /**
680
+ * 最近点(从route中找出距离目标点最近的点)
681
+ * @param coordinate 目标点 {lng, lat}
682
+ * @param route [[[lng, lat]]]
683
+ */
684
+ static nearestCoordinateInRoute(e, t) {
685
+ const n = g.point([e.lng, e.lat]), s = [];
686
+ for (const c of t) {
687
+ const a = c.map((d) => g.point(d));
688
+ s.push(...a);
689
+ }
690
+ const o = g.featureCollection(s), i = g.nearestPoint(n, o), r = g.getCoord(i);
691
+ return { lng: r[0], lat: r[1] };
692
+ }
693
+ /**
694
+ * 计算经过方向上的最后一个waypoint
695
+ * @param from
696
+ * @param waypoints
697
+ */
698
+ static calculatePrevWaypoint(e, t) {
699
+ let n = 0;
700
+ this.mergeCoordinateToWaypoints(e, t);
701
+ for (let s = 0; s < t.length - 1; s++) {
702
+ const o = t[s], i = t[s + 1];
703
+ if (this.calculateDistance(e, o) === 0) {
704
+ n = s;
705
+ break;
706
+ }
707
+ if (this.calculateDistance(e, i) === 0) {
708
+ n = s + 1;
709
+ break;
710
+ }
711
+ }
712
+ return t[n === 0 ? 0 : n - 1];
713
+ }
714
+ /**
715
+ * 计算下一个距离单位的坐标及其子航线
716
+ * @param from 起点坐标 {lng, lat}
717
+ * @param distance 航行距离
718
+ * @param route [[[lng, lat]]]
719
+ * @param units
720
+ * @return { coordinate: {lng, lat}, route: [[[lng, lat]]]}
721
+ */
722
+ static calculateNextCoordinateAlongRoute(e, t, n, s = "nauticalmiles") {
723
+ var f;
724
+ const o = e.speed || 12, i = [];
725
+ let r = [], c = !1, a = 0, d = 0, u;
726
+ if (t && n.length ? (i.push(e), n.forEach((p, b) => {
727
+ if (c)
728
+ r.push(p);
729
+ else {
730
+ const T = [];
731
+ let P;
732
+ for (let m = 0; m < p.length; m++)
733
+ if (u)
734
+ T.push(p[m]);
735
+ else {
736
+ P = { lng: p[m][0], lat: p[m][1] };
737
+ const h = this.calculateDistance(e, P, !0, 8, s);
738
+ if (a += h, a < t)
739
+ d += h, i.push(P), e = P;
740
+ else {
741
+ if (d = t, a === t)
742
+ u = P, T.push([u.lng, u.lat]);
743
+ else {
744
+ const S = a - t, M = this.calculateBearing(P, e);
745
+ u = this.calculateCoordinate(P, M, S, s), T.push([u.lng, u.lat]), T.push([P.lng, P.lat]);
746
+ }
747
+ c = !0;
748
+ }
749
+ }
750
+ T.length && r.push(T), b === n.length - 1 && !u && (u = P);
751
+ }
752
+ })) : (r = n, u = { ...e }), u)
753
+ if (i.push(u), u.distanceFromPrevious = d, u.hourFromPrevious = Math.round(d / o * 1e4) / 1e4, ((f = r[0]) == null ? void 0 : f.length) > 1) {
754
+ const p = { lng: r[0][1][0], lat: r[0][1][1] };
755
+ u.bearing = this.calculateBearing(u, p);
756
+ } else
757
+ u.bearing = 0;
758
+ return { coordinate: u, nextRoute: r, prevRoute: i };
759
+ }
760
+ /**
761
+ * 返回最近点及其是否为垂足(最近点不是起点或终点)
762
+ * @param coordinate { lng, lat }
763
+ * @param from {lng, lat}
764
+ * @param to {lng, lat}
765
+ */
766
+ static nearestCoordinateInLine(e, t, n) {
767
+ const s = l.convertToStdLng(e.lng, 6), o = g.point([s, e.lat]), i = l.convertToStdLng(t.lng, 6), r = l.convertToStdLng(n.lng, 6), c = g.lineString([
768
+ [i, t.lat],
769
+ [r, n.lat]
770
+ ]), a = g.nearestPointOnLine(c, o), d = g.getCoord(a), u = l.roundPrecision(d[0], 6), f = l.roundPrecision(d[1], 6);
771
+ return { lng: u, lat: f, inline: !(u === i && f === t.lat) && !(u === r && f === n.lat) };
772
+ }
773
+ /**
774
+ * 将route转coordinate
775
+ * @param route
776
+ * @param distance 临近点过虑
777
+ */
778
+ static convertRouteToCoordinates(e, t = 0) {
779
+ const n = [];
780
+ let s, o;
781
+ return e.forEach((i) => {
782
+ i.forEach((r) => {
783
+ const c = { lng: r[0], lat: r[1] };
784
+ if (!o)
785
+ n.push(c), o = c;
786
+ else if (o.bearing === void 0)
787
+ o.bearing = this.calculateBearing(o, c, !0);
788
+ else {
789
+ const a = this.calculateDistance(s, c, !0);
790
+ a && a >= t && (s.bearing = this.calculateBearing(s, c, !0), n.push(s), o = s);
791
+ }
792
+ s = c;
793
+ });
794
+ }), s && n.push(s), n;
795
+ }
796
+ /**
797
+ * 抽稀(基于转向点)
798
+ * @param route [[lng, lat]]
799
+ * @param waypoints [{ lng, lat, gcToPrevious }]
800
+ * @param distance
801
+ */
802
+ static simplifyRouteToCoordinates(e, t, n = 1) {
803
+ let s = this.convertRouteToCoordinates(e, n);
804
+ return s = this.simplifyGCCoordinates(s, t), s;
805
+ }
806
+ /**
807
+ * 基于大圆标识抽稀
808
+ * @param coordinates
809
+ * @param waypoints
810
+ */
811
+ static simplifyGCCoordinates(e, t) {
812
+ t.forEach((s) => {
813
+ this.mergeCoordinateToWaypoints(s, e);
814
+ });
815
+ for (let s = 1; s < t.length; s++) {
816
+ const o = t[s - 1], i = t[s];
817
+ if (i.gcToPrevious) {
818
+ const r = e.findIndex((a) => a.lng === o.lng && a.lat === o.lat), c = e.findIndex((a) => a.lng === i.lng && a.lat === i.lat);
819
+ for (let a = c - 1; a > r; a--)
820
+ e.splice(a, 1);
821
+ }
822
+ }
823
+ let n = 0;
824
+ for (let s = 1; s < e.length; s++) {
825
+ const o = e[s - 1], i = e[s];
826
+ i.gcToPrevious ? (o.bearing = this.calculateBearing(o, i, !1), i.distanceFromPrevious = this.calculateDistance(o, i, !1)) : (o.bearing = this.calculateBearing(o, i, !0), i.distanceFromPrevious = this.calculateDistance(o, i, !0)), n = l.roundPrecision(n + i.distanceFromPrevious), i.distanceFromStart = n;
827
+ }
828
+ return e.map((s) => (s.lng = l.convertToStdLng(s.lng), s));
829
+ }
830
+ }
300
831
  export {
301
- u as LngLatHelper,
302
- x as TropicalHelper
832
+ W as LaneHelper,
833
+ l as LngLatHelper,
834
+ I as TropicalHelper
303
835
  };
@@ -1 +1 @@
1
- (function(h,g){typeof exports=="object"&&typeof module<"u"?g(exports,require("moment"),require("moment-timezone"),require("tz-lookup"),require("@turf/turf")):typeof define=="function"&&define.amd?define(["exports","moment","moment-timezone","tz-lookup","@turf/turf"],g):(h=typeof globalThis<"u"?globalThis:h||self,g(h["idm-plugin-rabbitmq"]={},h.moment,h["moment-timezone"],h["tz-lookup"],h["@turf/turf"]))})(this,function(h,g,j,T,O){"use strict";function w(b){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(b){for(const t in b)if(t!=="default"){const o=Object.getOwnPropertyDescriptor(b,t);Object.defineProperty(e,t,o.get?o:{enumerable:!0,get:()=>b[t]})}}return e.default=b,Object.freeze(e)}const y=w(O);class s{static guessTimeZoneOffset(e,t){const o=T(t,e),n=g().tz(o).utcOffset();return this.roundPrecision(n/60,1)}static prettyTimeZoneOffset(e){let t=Math.floor(Math.abs(e)),o=Math.round((Math.abs(e)-t)*60);return o=o>9?o:`0${o}`,t=t>9?t:`0${t}`,e>0?`+${t}:${o}`:`-${t}:${o}`}static lng2pretty(e,t=6,o="H°M′"){e=s.convertToStdLng(e,t);let n="E";e<0&&(n="W"),e=Math.abs(e),o=o.toUpperCase();let i=e*3600,r,u,c,m,a,p;r=i%3600%60,o.indexOf("S")!==-1&&(i=i-r,u=s.padNumber(r,2,2)),c=i/60%60,o.indexOf("M")!==-1&&(o.indexOf("S")!==-1?m=s.roundPrecision(c,t).toString().padStart(2,"0"):m=s.padNumber(c,2,2),i=i-c*60),a=i/3600,o.indexOf("M")!==-1?p=s.roundPrecision(a,t).toString().padStart(3,"0"):p=s.padNumber(a,3,2);const l=`${o.replace(/S+/gi,u).replace(/M+/gi,m).replace(/H+/gi,p)}${n}`;return{direction:n,degree:s.roundPrecision(a,t),minute:s.roundPrecision(c,t),second:s.roundPrecision(r,t),pretty:l}}static lat2pretty(e,t=6,o="H°M′"){e=e%180;let n="N";e<0&&(n="S"),e=Math.abs(e),o=o.toUpperCase();let i=e*3600,r,u,c,m,a,p;r=i%3600%60,o.indexOf("S")!==-1&&(i=i-r,u=s.padNumber(r,2,2)),c=i/60%60,o.indexOf("M")!==-1&&(o.indexOf("S")!==-1?m=s.roundPrecision(c,t).toString().padStart(2,"0"):m=s.padNumber(c,2,2),i=i-c*60),a=i/3600,o.indexOf("M")!==-1?p=s.roundPrecision(a,t).toString().padStart(2,"0"):p=s.padNumber(a,2,2);const l=`${o.replace(/S+/gi,u).replace(/M+/gi,m).replace(/H+/gi,p)}${n}`;return{direction:n,degree:s.roundPrecision(a,t),minute:s.roundPrecision(c,t),second:s.roundPrecision(r,t),pretty:l}}static str2Lng(e,t=6){let o;if(isNaN(e)){e=s.strReplace(e,"LNG");const n=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const i=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[r,u]=i;if(r>360&&!u){const c=this.roundPrecision(r/100,0);u=r-c*100,r=c}o=r+(u??0)/60,n==="W"&&(o=o*-1)}else o=Number(e);return s.convertToStdLng(o,t)}static str2Lat(e,t=6){let o;if(isNaN(e)){e=s.strReplace(e,"LAT");const n=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const i=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[r,u]=i;if(r>90&&!u){const c=this.roundPrecision(r/100,0);u=r-c*100,r=c}o=r+(u??0)/60,n==="S"&&(o=o*-1)}else o=Number(e);return s.roundPrecision(o,t)}static str2LngOrLat(e,t=6,o="LAT"){e=s.strReplace(e,o);const n=e[e.length-1].toUpperCase();return["N","S"].includes(n)?{lat:s.str2Lat(e,t)}:{lng:s.str2Lng(e,t)}}static convertToStdLng(e,t=4){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),s.roundPrecision(e,t)}static roundPrecision(e,t=4){if(typeof e=="number"){const o=Number("1".padEnd(t+1,"0"));return Math.round(e*o)/o}return e}static convertToMonotonicLng2(e){for(let t=1;t<e.length;t++)e[t][0]+=Math.round((e[t-1][0]-e[t][0])/360)*360;return e}static convertToMonotonicLng(e){for(let t=1;t<e.length;t++)e[t].lng+=Math.round((e[t-1].lng-e[t].lng)/360)*360;return e}static strReplace(e,t="LAT"){e=e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g,"$1 $2").replace(/-/g," ").replace(/°/," ").replace(/'/g," ").replace(/′/g," ").replace(/"/g," ").replace(/∼/g," ").replace(/°/g," ").replace(/,/g,".").replace(/^ /g,"").replace(/ $/g,"").trim();const o=e[e.length-1].toUpperCase();if(!["N","S","E","W"].includes(o)){const n=e,i=Number(n.split(" ")[0]);if(isNaN(i))throw new Error(`invalid Lat/Lng: ${e}`);i>=90?e=`${n}E`:i<=-90?e=`${n}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${n}${i>0?"E":"W"}`:e=`${n}${i>0?"N":"S"}`}return e}static padNumber(e,t=2,o=2){const n=Math.trunc(e).toString().padStart(t,"0"),i=Math.trunc(s.roundPrecision(e-Math.trunc(e),o)*Math.pow(10,o)).toString().padStart(o,"0");return`${n}.${i}`}}class k{static convert2Geojson(e){var o;const t=y.featureCollection([]);for(const n of e){if(n.forecasts){const i=(o=n.history)==null?void 0:o[0];for(const r of n.forecasts){const u=[],c=g(r.date).utc(),m=`${n.name}-${r.model}`;if(i){const a=g(i.updated).utc(),p=y.point([i.lng,i.lat],{model:r.model,name:n.name,date:a.format(),hour:0,format:a.format("MMM-DD/HHmm[Z]"),pressure:i.pressure>1e4?s.roundPrecision(i.pressure/100,0):s.roundPrecision(i.pressure,0),wind:{kts:i.kts,spd:i.speed||i.spd},category:m,type:"forecast"});t.features.push(p),u.push(p.geometry.coordinates)}for(const a in r==null?void 0:r.hours){const p=r.hours[a];p.wind.spd=p.wind.spd||p.wind.speed;const l=c.clone().add(Number(a),"hour"),M=y.point([p.lng,p.lat],{model:r.model,name:n.name,date:l.format(),hour:Number(a),format:l.format("MMM-DD/HHmm[Z]"),pressure:p.pressure>1e4?s.roundPrecision(p.pressure/100,0):s.roundPrecision(p.pressure,0),gusts:p.gusts,wind:p.wind||{},movement:p.movement,category:m,type:"forecast"});t.features.push(M),u.push(M.geometry.coordinates)}if((u==null?void 0:u.length)>1){const a=y.lineString(s.convertToMonotonicLng2(u),{date:r.date,id:n.id||n.name,model:r.model,name:n.name,category:m,type:"forecast"});t.features.push(a)}}}if(n.history){const i=[];for(const u of n.history){const c=g(u.updated).utc(),m=y.point([u.lng,u.lat],{name:n.name,date:c.format(),format:c.format("MMM-DD/HHmm[Z]"),pressure:u.pressure>1e4?s.roundPrecision(u.pressure/100,0):s.roundPrecision(u.pressure,0),spd:u.speed||u.spd,kts:u.kts,source:u.source,level:u.type,type:"history",category:`${n.name}-history`});t.features.push(m),i.push(m.geometry.coordinates)}const r=n.history[0];if(i.length===1&&i.push(i[0]),i.length>1){const u=y.lineString(s.convertToMonotonicLng2(i),{name:n.name,type:"history",updated:r==null?void 0:r.updated,pressure:(r==null?void 0:r.pressure)>1e4?s.roundPrecision((r==null?void 0:r.pressure)/100,0):s.roundPrecision(r==null?void 0:r.pressure,0),spd:(r==null?void 0:r.speed)||(r==null?void 0:r.spd),kts:r==null?void 0:r.kts,source:r==null?void 0:r.source,level:r==null?void 0:r.type});t.features.push(u)}}}return t}static interpolate(e,t=3){var i,r,u,c;const o=(i=e==null?void 0:e.data)==null?void 0:i.features.filter(m=>m.geometry.type==="LineString"&&m.properties.type==="forecast"),n=[];for(const m of o){const a=m.properties.name,p=m.properties.model,l=g(m.properties.date).utc();let M=t*60-(l.get("hour")*60+l.get("minute"))%(t*60);const P=(r=e==null?void 0:e.data)==null?void 0:r.features.filter(f=>f.geometry.type==="Point"&&f.properties.type==="forecast"&&f.properties.category===`${a}-${p}`);let S,$=l.clone().add(M,"minute").set({minute:0,second:0,millisecond:0});for(;S=this.pickIndex(P,$),S<=P.length-1;){if(S>0){const f=P[S],d=S===0?void 0:P[S-1],N=(M/60-((u=d==null?void 0:d.properties)==null?void 0:u.hour))/(f.properties.hour-((c=d==null?void 0:d.properties)==null?void 0:c.hour)),D=this.computeNumber(d==null?void 0:d.geometry.coordinates[0],f.geometry.coordinates[0],N),z=this.computeNumber(d==null?void 0:d.geometry.coordinates[1],f.geometry.coordinates[1],N),C=y.point([D,z],{name:a,model:p,category:f==null?void 0:f.properties.category,date:$.format(),format:$.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(d==null?void 0:d.properties.gusts,f.properties.gusts,N),hour:this.computeNumber(d==null?void 0:d.properties.hour,f.properties.hour,N),movement:this.computeNumber(d==null?void 0:d.properties.movement,f.properties.movement,N),pressure:this.computeNumber(d==null?void 0:d.properties.pressure,f.properties.pressure,N),wind:this.computeNumber(d==null?void 0:d.properties.wind,f.properties.wind,N),type:"forecast"});n.push(C)}M+=t*60,$=l.clone().add(M,"minute").set({minute:0,second:0,millisecond:0})}}return n}static pickIndex(e,t){let o=0;for(const n of e){if(g(n.properties.date).isAfter(t))return o===0?-1:o;o++}return o}static computeNumber(e,t,o){if(e)if(t){if(isNaN(e)&&isNaN(t)&&typeof e!="string"&&typeof t!="string"){const n={};for(const i in e)n[i]=this.computeNumber(e[i],t[i],o);return n}return Math.round((e+(t-e)*o)*100)/100}else return e;else return t}}h.LngLatHelper=s,h.TropicalHelper=k,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})});
1
+ (function(b,N){typeof exports=="object"&&typeof module<"u"?N(exports,require("@turf/turf"),require("moment"),require("moment-timezone"),require("tz-lookup")):typeof define=="function"&&define.amd?define(["exports","@turf/turf","moment","moment-timezone","tz-lookup"],N):(b=typeof globalThis<"u"?globalThis:b||self,N(b["idm-plugin-rabbitmq"]={},b["@turf/turf"],b.moment,b["moment-timezone"],b["tz-lookup"]))})(this,function(b,N,D,k,R){"use strict";function y(M){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(M){for(const t in M)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(M,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>M[t]})}}return e.default=M,Object.freeze(e)}const g=y(N);class l{static guessTimeZoneOffset(e,t){const n=R(t,e),s=D().tz(n).utcOffset();return this.roundPrecision(s/60,1)}static prettyTimeZoneOffset(e){let t=Math.floor(Math.abs(e)),n=Math.round((Math.abs(e)-t)*60);return n=n>9?n:`0${n}`,t=t>9?t:`0${t}`,e>0?`+${t}:${n}`:`-${t}:${n}`}static lng2pretty(e,t=6,n="H°M′"){e=l.convertToStdLng(e,t);let s="E";e<0&&(s="W"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,i,r,c,u,d,a;i=o%3600%60,n.indexOf("S")!==-1&&(o=o-i,r=l.padNumber(i,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?u=l.roundPrecision(c,t).toString().padStart(2,"0"):u=l.padNumber(c,2,2),o=o-c*60),d=o/3600,n.indexOf("M")!==-1?a=l.roundPrecision(d,t).toString().padStart(3,"0"):a=l.padNumber(d,3,2);const h=`${n.replace(/S+/gi,r).replace(/M+/gi,u).replace(/H+/gi,a)}${s}`;return{direction:s,degree:l.roundPrecision(d,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(i,t),pretty:h}}static lat2pretty(e,t=6,n="H°M′"){e=e%180;let s="N";e<0&&(s="S"),e=Math.abs(e),n=n.toUpperCase();let o=e*3600,i,r,c,u,d,a;i=o%3600%60,n.indexOf("S")!==-1&&(o=o-i,r=l.padNumber(i,2,2)),c=o/60%60,n.indexOf("M")!==-1&&(n.indexOf("S")!==-1?u=l.roundPrecision(c,t).toString().padStart(2,"0"):u=l.padNumber(c,2,2),o=o-c*60),d=o/3600,n.indexOf("M")!==-1?a=l.roundPrecision(d,t).toString().padStart(2,"0"):a=l.padNumber(d,2,2);const h=`${n.replace(/S+/gi,r).replace(/M+/gi,u).replace(/H+/gi,a)}${s}`;return{direction:s,degree:l.roundPrecision(d,t),minute:l.roundPrecision(c,t),second:l.roundPrecision(i,t),pretty:h}}static str2Lng(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LNG");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[i,r]=o;if(i>360&&!r){const c=this.roundPrecision(i/100,0);r=i-c*100,i=c}n=i+(r??0)/60,s==="W"&&(n=n*-1)}else n=Number(e);return l.convertToStdLng(n,t)}static str2Lat(e,t=6){let n;if(isNaN(e)){e=l.strReplace(e,"LAT");const s=e[e.length-1].toUpperCase();e=e.substring(0,e.length-1).trim();const o=e.split(" ").filter(c=>c!=="").map(c=>Number(c));let[i,r]=o;if(i>90&&!r){const c=this.roundPrecision(i/100,0);r=i-c*100,i=c}n=i+(r??0)/60,s==="S"&&(n=n*-1)}else n=Number(e);return l.roundPrecision(n,t)}static str2LngOrLat(e,t=6,n="LAT"){e=l.strReplace(e,n);const s=e[e.length-1].toUpperCase();return["N","S"].includes(s)?{lat:l.str2Lat(e,t)}:{lng:l.str2Lng(e,t)}}static convertToStdLng(e,t=4){return e>180?(e=e%360,e=e>180?e-360:e):e<-180&&(e=e%360,e=e<-180?e+360:e),l.roundPrecision(e,t)}static roundPrecision(e,t=4){if(typeof e=="number"){const n=Number("1".padEnd(t+1,"0"));return Math.round(e*n)/n}return e}static convertToMonotonicLng2(e){for(let t=1;t<e.length;t++)e[t][0]+=Math.round((e[t-1][0]-e[t][0])/360)*360;return e}static convertToMonotonicLng(e){for(let t=1;t<e.length;t++)e[t].lng+=Math.round((e[t-1].lng-e[t].lng)/360)*360;return e}static strReplace(e,t="LAT"){e=e.replace(/([0-9]+)\.([0-9]+\.[0-9]+)/g,"$1 $2").replace(/-/g," ").replace(/°/," ").replace(/'/g," ").replace(/′/g," ").replace(/"/g," ").replace(/∼/g," ").replace(/°/g," ").replace(/,/g,".").replace(/^ /g,"").replace(/ $/g,"").trim();const n=e[e.length-1].toUpperCase();if(!["N","S","E","W"].includes(n)){const s=e,o=Number(s.split(" ")[0]);if(isNaN(o))throw new Error(`invalid Lat/Lng: ${e}`);o>=90?e=`${s}E`:o<=-90?e=`${s}W`:["LAN","LNG"].includes(t==null?void 0:t.toUpperCase())?e=`${s}${o>0?"E":"W"}`:e=`${s}${o>0?"N":"S"}`}return e}static padNumber(e,t=2,n=2){const s=Math.trunc(e).toString().padStart(t,"0"),o=Math.trunc(l.roundPrecision(e-Math.trunc(e),n)*Math.pow(10,n)).toString().padStart(n,"0");return`${s}.${o}`}}class x{static convert2Geojson(e){var n;const t=g.featureCollection([]);for(const s of e){if(s.forecasts){const o=(n=s.history)==null?void 0:n[0];for(const i of s.forecasts){const r=[],c=D(i.date).utc(),u=`${s.name}-${i.model}`;if(o){const d=D(o.updated).utc(),a=g.point([o.lng,o.lat],{model:i.model,name:s.name,date:d.format(),hour:0,format:d.format("MMM-DD/HHmm[Z]"),pressure:o.pressure>1e4?l.roundPrecision(o.pressure/100,0):l.roundPrecision(o.pressure,0),wind:{kts:o.kts,spd:o.speed||o.spd},category:u,type:"forecast"});t.features.push(a),r.push(a.geometry.coordinates)}for(const d in i==null?void 0:i.hours){const a=i.hours[d];a.wind.spd=a.wind.spd||a.wind.speed;const h=c.clone().add(Number(d),"hour"),p=g.point([a.lng,a.lat],{model:i.model,name:s.name,date:h.format(),hour:Number(d),format:h.format("MMM-DD/HHmm[Z]"),pressure:a.pressure>1e4?l.roundPrecision(a.pressure/100,0):l.roundPrecision(a.pressure,0),gusts:a.gusts,wind:a.wind||{},movement:a.movement,category:u,type:"forecast"});t.features.push(p),r.push(p.geometry.coordinates)}if((r==null?void 0:r.length)>1){const d=g.lineString(l.convertToMonotonicLng2(r),{date:i.date,id:s.id||s.name,model:i.model,name:s.name,category:u,type:"forecast"});t.features.push(d)}}}if(s.history){const o=[];for(const r of s.history){const c=D(r.updated).utc(),u=g.point([r.lng,r.lat],{name:s.name,date:c.format(),format:c.format("MMM-DD/HHmm[Z]"),pressure:r.pressure>1e4?l.roundPrecision(r.pressure/100,0):l.roundPrecision(r.pressure,0),spd:r.speed||r.spd,kts:r.kts,source:r.source,level:r.type,type:"history",category:`${s.name}-history`});t.features.push(u),o.push(u.geometry.coordinates)}const i=s.history[0];if(o.length===1&&o.push(o[0]),o.length>1){const r=g.lineString(l.convertToMonotonicLng2(o),{name:s.name,type:"history",updated:i==null?void 0:i.updated,pressure:(i==null?void 0:i.pressure)>1e4?l.roundPrecision((i==null?void 0:i.pressure)/100,0):l.roundPrecision(i==null?void 0:i.pressure,0),spd:(i==null?void 0:i.speed)||(i==null?void 0:i.spd),kts:i==null?void 0:i.kts,source:i==null?void 0:i.source,level:i==null?void 0:i.type});t.features.push(r)}}}return t}static interpolate(e,t=3){var o,i,r,c;const n=(o=e==null?void 0:e.data)==null?void 0:o.features.filter(u=>u.geometry.type==="LineString"&&u.properties.type==="forecast"),s=[];for(const u of n){const d=u.properties.name,a=u.properties.model,h=D(u.properties.date).utc();let p=t*60-(h.get("hour")*60+h.get("minute"))%(t*60);const v=(i=e==null?void 0:e.data)==null?void 0:i.features.filter(m=>m.geometry.type==="Point"&&m.properties.type==="forecast"&&m.properties.category===`${d}-${a}`);let T,P=h.clone().add(p,"minute").set({minute:0,second:0,millisecond:0});for(;T=this.pickIndex(v,P),T<=v.length-1;){if(T>0){const m=v[T],f=T===0?void 0:v[T-1],S=(p/60-((r=f==null?void 0:f.properties)==null?void 0:r.hour))/(m.properties.hour-((c=f==null?void 0:f.properties)==null?void 0:c.hour)),C=this.computeNumber(f==null?void 0:f.geometry.coordinates[0],m.geometry.coordinates[0],S),I=this.computeNumber(f==null?void 0:f.geometry.coordinates[1],m.geometry.coordinates[1],S),W=g.point([C,I],{name:d,model:a,category:m==null?void 0:m.properties.category,date:P.format(),format:P.format("MMM-DD/HHmm[Z]"),gusts:this.computeNumber(f==null?void 0:f.properties.gusts,m.properties.gusts,S),hour:this.computeNumber(f==null?void 0:f.properties.hour,m.properties.hour,S),movement:this.computeNumber(f==null?void 0:f.properties.movement,m.properties.movement,S),pressure:this.computeNumber(f==null?void 0:f.properties.pressure,m.properties.pressure,S),wind:this.computeNumber(f==null?void 0:f.properties.wind,m.properties.wind,S),type:"forecast"});s.push(W)}p+=t*60,P=h.clone().add(p,"minute").set({minute:0,second:0,millisecond:0})}}return s}static pickIndex(e,t){let n=0;for(const s of e){if(D(s.properties.date).isAfter(t))return n===0?-1:n;n++}return n}static computeNumber(e,t,n){if(e)if(t){if(isNaN(e)&&isNaN(t)&&typeof e!="string"&&typeof t!="string"){const s={};for(const o in e)s[o]=this.computeNumber(e[o],t[o],n);return s}return Math.round((e+(t-e)*n)*100)/100}else return e;else return t}}class ${static calculateBearing(e,t,n=!0,s=4){const o=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let i;return n?i=g.rhumbBearing(o.features[0],o.features[1]):i=g.bearing(o.features[0],o.features[1]),i<0&&(i+=360),l.roundPrecision(i,s)}static calculateDistance(e,t,n=!0,s=4,o="nauticalmiles"){e={...e},t={...t},e.lng=l.convertToStdLng(e.lng,s),t.lng=l.convertToStdLng(t.lng,s);const i=g.points([[e.lng,e.lat],[t.lng,t.lat]]);let r;return n?r=g.rhumbDistance(i.features[0],i.features[1],{units:o}):r=g.distance(i.features[0],i.features[1],{units:o}),l.roundPrecision(r,s)}static calculateRouteDistance(e,t=4,n="nauticalmiles"){let s=0,o;for(const i of e)for(let r=0;r<i.length-1;r++){const c={lng:i[r][0],lat:i[r][1]};r===0&&o&&(s+=this.calculateDistance(o,c,!0,t,n));const u={lng:i[r+1][0],lat:i[r+1][1]};s+=this.calculateDistance(c,u,!0,t,n),o=u}return l.roundPrecision(s,t)}static calculateCoordinate(e,t,n,s="nauticalmiles",o=!0){const i=g.point([e.lng,e.lat]);let r;o?r=g.rhumbDestination(i,n,t,{units:s}):r=g.destination(i,n,t,{units:s});const c=r.geometry.coordinates;return{lng:l.convertToStdLng(c[0],8),lat:l.roundPrecision(c[1],8)}}static interpolateCoordinates(e,t,n,s=!0,o=!0,i="nauticalmiles"){const r=[],c=this.calculateBearing(e,t,!1),u=this.calculateDistance(e,t,!1,8,i);s&&r.push({lng:e.lng,lat:e.lat});let d=0;for(;d<u;)d+=n,d<u&&r.push(this.calculateCoordinate(e,c,d,i,!1));return o&&r.push({lng:t.lng,lat:t.lat}),r}static divideAccordingToLng(e,t=!1){if((e==null?void 0:e.length)<2)return[];e=this.deduplicateCoordinates(e);let n=[];const s=[];let o,i;for(let r=0;r<e.length-1;r++){o=l.convertToStdLng(e[r].lng,8),i=l.convertToStdLng(e[r+1].lng,8),n.push([o,e[r].lat]);const c=o-i;if(Math.abs(c)>180){const u=l.convertToMonotonicLng2([[o,e[r].lat],[i,e[r+1].lat]]);let d,a;t?(d=g.lineString(u),a=g.lineString([[c>0?180:-180,89],[c>0?180:-180,-89]])):(d=g.greatCircle(u[0],u[1]),a=g.greatCircle([c>0?180:-180,89],[c>0?180:-180,-89]));const h=g.lineIntersect(d,a);let p;if(h.features.length){const v=g.getCoord(h.features[0]);p=l.roundPrecision(v[1],8)}else p=e[r].lat;c>0?(n.push([180-1e-6,p]),s.push([...n]),n=[],n.push([-(180-1e-6),p])):(n.push([-(180-1e-6),p]),s.push([...n]),n=[],n.push([180-1e-6,p]))}r===e.length-2&&n.push([i,e[r+1].lat])}return s.push(n),s}static deduplicateRoute(e){const t=[];for(const n of e){const s=n.reduce((o,i)=>(o.findIndex(r=>r[0]===i[0]&&r[1]===i[1])===-1&&o.push(i),o),[]);t.push(s)}return t}static deduplicateCoordinates(e){return e.reduce((t,n)=>(t.findIndex(s=>s.lat===n.lat&&s.lng===n.lng)===-1&&t.push(n),t),[])}static removeCoordinateFromRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);for(const n of t)for(let s=n.length-1;s>=0;s--)l.roundPrecision(n[s][0],8)===e.lng&&l.roundPrecision(n[s][1],8)===l.roundPrecision(e.lat,8)&&n.splice(s,1);return t}static removeCoordinateFromWaypoints(e,t){e.lng=l.convertToStdLng(e.lng,8);for(let n=t.length-1;n>=0;n--)l.roundPrecision(t[n].lng,8)===e.lng&&l.roundPrecision(t[n].lat,8)===l.roundPrecision(e.lat,8)&&t.splice(n,1);return t}static mergeCoordinateToRoute(e,t){e.lng=l.convertToStdLng(e.lng,8);let n=Number.MAX_VALUE,s=0,o=0,i,r;return t.forEach((c,u)=>{for(let d=0;d<c.length-1;d++){const a={lng:c[d][0],lat:c[d][1]},h={lng:c[d+1][0],lat:c[d+1][1]},p=this.calculatePointToLineDistance(e,a,h);n>p&&(n=p,o=d,s=u,i=this.calculateDistance(a,e),r=this.calculateDistance(h,e))}}),i!==0&&r!==0?t[s].splice(o+1,0,[e.lng,e.lat]):i===0?t[s].splice(o,1,[e.lng,e.lat]):r===0&&t[s].splice(o+1,1,[e.lng,e.lat]),t}static mergeWaypointsToRoute(e,t){for(const n of e)t=this.mergeCoordinateToRoute(n,t);return t}static calculateRangeRoute(e,t,n){n=this.mergeWaypointsToRoute([e,t],n);const s=[];let o=0;return n.forEach(i=>{if(o===2)return;const r=[];for(const c of i){if(l.roundPrecision(t.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(c[1],8)){r.push(c),o===0&&r.push([e.lng,e.lat]),o=2;break}o===1?r.push(c):l.roundPrecision(e.lng,8)===l.roundPrecision(c[0],8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(c[1],8)&&(o=1,r.push(c))}r.length&&s.push(r)}),s}static calculateRangeWaypoints(e,t,n,s=[]){const o=this.convertRouteToCoordinates(n,0),i=this.mergeCoordinatesToWaypoints([e,t,...s],o),r=i.findIndex(d=>l.roundPrecision(e.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(e.lat,8)===l.roundPrecision(d.lat,8)),c=i.findIndex(d=>l.roundPrecision(t.lng,8)===l.roundPrecision(d.lng,8)&&l.roundPrecision(t.lat,8)===l.roundPrecision(d.lat,8));return i.filter((d,a)=>a>=r&&a<=c)}static calculateMinDistanceToRoute(e,t){let n=Number.MAX_VALUE,s=0,o=0;return t.forEach((i,r)=>{for(let c=0;c<i.length-1;c++){const u={lng:i[c][0],lat:i[c][1]},d={lng:i[c+1][0],lat:i[c+1][1]},a=this.calculatePointToLineDistance(e,u,d);n>a&&(n=a,s=c,o=r)}}),{minDist:n,segIndex:o,minIndex:s}}static calculateSubRoute(e,t){const{segIndex:n,minIndex:s}=this.calculateMinDistanceToRoute({...e},t);e.lng=l.convertToStdLng(e.lng);const o=[];let i=!0;for(let r=n;r<t.length;r++)if(i){const c=[];c.push([e.lng,e.lat]);for(let u=s+1;u<t[r].length;u++)e.lng===t[r][u][0]&&e.lat===t[r][u][1]||c.push(t[r][u]);o.push(c),i=!1}else o.push([...t[r]]);return o}static calculateSubWaypoints(e,t){let n=Number.MAX_VALUE,s=0;for(let i=0;i<t.length-1;i++){const r=t[i],c=t[i+1];if(this.calculateDistance(e,r)===0)return t;if(this.calculateDistance(e,c)===0)return t.filter((d,a)=>a>0);const u=this.calculatePointToLineDistance(e,r,c);n>u&&(n=u,s=i)}e.lng=l.convertToStdLng(e.lng);const o=[e];for(let i=s+1;i<t.length;i++)o.push(t[i]);return o}static calculatePointToLineDistance(e,t,n,s={units:"nauticalmiles",method:"geodesic"}){e.lng=l.convertToStdLng(e.lng),t={...t},n={...n},t.lng=l.convertToStdLng(t.lng,8),n.lng=l.convertToStdLng(n.lng,8);const o=l.convertToMonotonicLng([t,n]);t=o[0],n=o[1];const i=g.lineString([[t.lng,t.lat],[n.lng,n.lat]]),r=g.pointToLineDistance(g.point([e.lng,e.lat]),i,s),c=g.pointToLineDistance(g.point([e.lng>0?e.lng-360:e.lng+360,e.lat]),i,s);return l.roundPrecision(Math.min(r,c),6)}static calculateWaypointsPropInRoute(e,t){t=this.mergeWaypointsToRoute(e,t);for(let n=0;n<e.length-1;n++){const s=e[n],o=e[n+1],i=this.calculateRangeRoute(s,o,t);n===0&&(s.distanceFromPrevious=0,s.distanceFromStart=0),o.distanceFromPrevious=this.calculateRouteDistance(i),o.distanceFromStart=l.roundPrecision((s.distanceFromStart||0)+o.distanceFromPrevious)}return e}static mergeCoordinatesToWaypoints(e,t,n=!0){for(const s of e)this.mergeCoordinateToWaypoints(s,t,n);return t}static mergeCoordinateToWaypoints(e,t,n=!0){e.lng=l.convertToStdLng(e.lng,8);let s=Number.MAX_VALUE,o=0,i=0,r=0;for(let c=0;c<t.length-1;c++){const u={lng:t[c].lng,lat:t[c].lat},d={lng:t[c+1].lng,lat:t[c+1].lat},a=this.calculatePointToLineDistance(e,u,d);s>=a&&(s=a,o=c,i=this.calculateDistance(u,e,!1,6),r=this.calculateDistance(d,e,!1,6))}return i!==0&&r!==0?i<s||i===s&&o===0?t.unshift(e):r<s||r===s&&o===t.length-2?t.push(e):t.splice(o+1,0,e):i===0?n&&t.splice(o,1,e):r===0&&n&&t.splice(o+1,1,e),t.map(c=>(c.lng=l.convertToStdLng(c.lng),c))}static generateRouteAccordingToWaypoints(e){const t=[];for(let n=1;n<e.length;n++){const s=e[n-1],o=e[n];if(n===1&&t.push(s),o.gcToPrevious){const i=this.interpolateCoordinates(s,o,200,!1,!0,"nauticalmiles");t.push(...i)}else t.push(o)}return this.divideAccordingToLng(t,!0)}static nearestCoordinateInRoute(e,t){const n=g.point([e.lng,e.lat]),s=[];for(const c of t){const u=c.map(d=>g.point(d));s.push(...u)}const o=g.featureCollection(s),i=g.nearestPoint(n,o),r=g.getCoord(i);return{lng:r[0],lat:r[1]}}static calculatePrevWaypoint(e,t){let n=0;this.mergeCoordinateToWaypoints(e,t);for(let s=0;s<t.length-1;s++){const o=t[s],i=t[s+1];if(this.calculateDistance(e,o)===0){n=s;break}if(this.calculateDistance(e,i)===0){n=s+1;break}}return t[n===0?0:n-1]}static calculateNextCoordinateAlongRoute(e,t,n,s="nauticalmiles"){var h;const o=e.speed||12,i=[];let r=[],c=!1,u=0,d=0,a;if(t&&n.length?(i.push(e),n.forEach((p,v)=>{if(c)r.push(p);else{const T=[];let P;for(let m=0;m<p.length;m++)if(a)T.push(p[m]);else{P={lng:p[m][0],lat:p[m][1]};const f=this.calculateDistance(e,P,!0,8,s);if(u+=f,u<t)d+=f,i.push(P),e=P;else{if(d=t,u===t)a=P,T.push([a.lng,a.lat]);else{const S=u-t,C=this.calculateBearing(P,e);a=this.calculateCoordinate(P,C,S,s),T.push([a.lng,a.lat]),T.push([P.lng,P.lat])}c=!0}}T.length&&r.push(T),v===n.length-1&&!a&&(a=P)}})):(r=n,a={...e}),a)if(i.push(a),a.distanceFromPrevious=d,a.hourFromPrevious=Math.round(d/o*1e4)/1e4,((h=r[0])==null?void 0:h.length)>1){const p={lng:r[0][1][0],lat:r[0][1][1]};a.bearing=this.calculateBearing(a,p)}else a.bearing=0;return{coordinate:a,nextRoute:r,prevRoute:i}}static nearestCoordinateInLine(e,t,n){const s=l.convertToStdLng(e.lng,6),o=g.point([s,e.lat]),i=l.convertToStdLng(t.lng,6),r=l.convertToStdLng(n.lng,6),c=g.lineString([[i,t.lat],[r,n.lat]]),u=g.nearestPointOnLine(c,o),d=g.getCoord(u),a=l.roundPrecision(d[0],6),h=l.roundPrecision(d[1],6);return{lng:a,lat:h,inline:!(a===i&&h===t.lat)&&!(a===r&&h===n.lat)}}static convertRouteToCoordinates(e,t=0){const n=[];let s,o;return e.forEach(i=>{i.forEach(r=>{const c={lng:r[0],lat:r[1]};if(!o)n.push(c),o=c;else if(o.bearing===void 0)o.bearing=this.calculateBearing(o,c,!0);else{const u=this.calculateDistance(s,c,!0);u&&u>=t&&(s.bearing=this.calculateBearing(s,c,!0),n.push(s),o=s)}s=c})}),s&&n.push(s),n}static simplifyRouteToCoordinates(e,t,n=1){let s=this.convertRouteToCoordinates(e,n);return s=this.simplifyGCCoordinates(s,t),s}static simplifyGCCoordinates(e,t){t.forEach(s=>{this.mergeCoordinateToWaypoints(s,e)});for(let s=1;s<t.length;s++){const o=t[s-1],i=t[s];if(i.gcToPrevious){const r=e.findIndex(u=>u.lng===o.lng&&u.lat===o.lat),c=e.findIndex(u=>u.lng===i.lng&&u.lat===i.lat);for(let u=c-1;u>r;u--)e.splice(u,1)}}let n=0;for(let s=1;s<e.length;s++){const o=e[s-1],i=e[s];i.gcToPrevious?(o.bearing=this.calculateBearing(o,i,!1),i.distanceFromPrevious=this.calculateDistance(o,i,!1)):(o.bearing=this.calculateBearing(o,i,!0),i.distanceFromPrevious=this.calculateDistance(o,i,!0)),n=l.roundPrecision(n+i.distanceFromPrevious),i.distanceFromStart=n}return e.map(s=>(s.lng=l.convertToStdLng(s.lng),s))}}b.LaneHelper=$,b.LngLatHelper=l,b.TropicalHelper=x,Object.defineProperty(b,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,263 @@
1
+ /**
2
+ * 坐标
3
+ */
4
+ export interface Coordinate {
5
+ lng: number;
6
+ lat: number;
7
+ distanceFromPrevious?: number;
8
+ distanceFromStart?: number;
9
+ gcToPrevious?: boolean;
10
+ speed?: number;
11
+ sog?: number;
12
+ hourFromPrevious?: number;
13
+ bearing?: number;
14
+ important?: boolean;
15
+ suspend?: number;
16
+ velocity?: number;
17
+ }
18
+ export declare class LaneHelper {
19
+ /**
20
+ * 计算方位角
21
+ * @param from 坐标 {lng, lat}
22
+ * @param to 坐标 {lng, lat}
23
+ * @param rhumb true 横向方位角,false 大圆方位角
24
+ * @param precision
25
+ * @returns {number} 单位度
26
+ */
27
+ static calculateBearing(from: Coordinate, to: Coordinate, rhumb?: boolean, precision?: number): number;
28
+ /**
29
+ * 计算两点间距离
30
+ * @param from 坐标 {lng, lat}
31
+ * @param to 坐标 {lng, lat}
32
+ * @param rhumb true 横向距离,false 大圆距离
33
+ * @param precision
34
+ * @param units 单位,默认 nm(海里)
35
+ * @returns {number}
36
+ */
37
+ static calculateDistance(from: Coordinate, to: Coordinate, rhumb?: boolean, precision?: number, units?: string): number;
38
+ /**
39
+ * 计算航线距离
40
+ * @param route [[[lng, lat],[lng, lat]]]
41
+ * @param precision
42
+ * @param units
43
+ */
44
+ static calculateRouteDistance(route: number[][][], precision?: number, units?: string): number;
45
+ /**
46
+ * 计算坐标(基于方位角和距离)
47
+ * @param from 坐标 {lng, lat}
48
+ * @param bearing 方位角,单位度
49
+ * @param distance 距离
50
+ * @param units 单位,默认 nm(海里)
51
+ * @param rhumb
52
+ */
53
+ static calculateCoordinate(from: Coordinate, bearing: number, distance: number, units?: any, rhumb?: boolean): {
54
+ lng: number;
55
+ lat: number;
56
+ };
57
+ /**
58
+ * 插值大圆坐标(基于两点方位角和间距)
59
+ * @param from 坐标 {lng, lat}
60
+ * @param to 坐标 {lng, lat}
61
+ * @param spacing 间距
62
+ * @param includeHead true 包含起点 from
63
+ * @param includeTail true 包含终点 to
64
+ * @param units 单位,默认 nm(海里)
65
+ */
66
+ static interpolateCoordinates(from: Coordinate, to: Coordinate, spacing: number, includeHead?: boolean, includeTail?: boolean, units?: string): {
67
+ lng: number;
68
+ lat: number;
69
+ }[];
70
+ /**
71
+ * 分组坐标(如相邻两个坐标经度差超180度,需以180为界将坐标分为两组)
72
+ * @param coordinates [{lng, lat}]
73
+ * @param rhumb
74
+ * @example
75
+ * coordinates: [{lng: 160,lat: 30}, {lng: 170, lat: 40},{lng: -170, lat: 40},{lng: -160, lat: 30}]
76
+ * @return [
77
+ * [[160, 30],[170,40]],
78
+ * [[-170,40],[-160,30]]
79
+ * ]
80
+ */
81
+ static divideAccordingToLng(coordinates: Array<Coordinate>, rhumb?: boolean): number[][][];
82
+ /**
83
+ * 去除重复坐标
84
+ * @param route
85
+ */
86
+ static deduplicateRoute(route: number[][][]): any;
87
+ /**
88
+ * 去除重新坐标
89
+ * @param coordinates
90
+ */
91
+ static deduplicateCoordinates(coordinates: Array<Coordinate>): Array<Coordinate>;
92
+ /**
93
+ * 移出坐标
94
+ * @param coordinate {lng, lat}
95
+ * @param route 航线[[[lng, lat],[lng, lat]]]
96
+ */
97
+ static removeCoordinateFromRoute(coordinate: Coordinate, route: number[][][]): number[][][];
98
+ /**
99
+ * 移出坐标
100
+ * @param coordinate {lng, lat}
101
+ * @param waypoints [{lat, lng}, {lat, lng}]
102
+ */
103
+ static removeCoordinateFromWaypoints(coordinate: Coordinate, waypoints: Coordinate[]): Coordinate[];
104
+ /**
105
+ * 合并坐标进航线(基于坐标到线段最短距离边合并)
106
+ * @param coordinate 待合并的坐标 {lng, lat}
107
+ * @param route 航线[[[lng, lat],[lng, lat]]]
108
+ * @example
109
+ * coordinate {lng: 122, lat: 35}
110
+ *
111
+ * route: [[[120, 30], [125,40], [130, 37]], [[-150, 40], [-130, 30]]]
112
+ * @return
113
+ * [[[120, 30], [120, 35], [125,40], [130, 37]], [[-150, 40], [-130, 30]]]
114
+ */
115
+ static mergeCoordinateToRoute(coordinate: Coordinate, route: number[][][]): number[][][];
116
+ /**
117
+ * 合并多个waypoints进航线
118
+ * @param waypoints [{lat, lng}, {lat, lng}]
119
+ * @param route 航线 [[[lng, lat],[lng, lat]]]
120
+ */
121
+ static mergeWaypointsToRoute(waypoints: Coordinate[], route: number[][][]): number[][][];
122
+ /**
123
+ * 计算区间航线
124
+ * @param from {lng, lat}
125
+ * @param to {lng, lat}
126
+ * @param route [[[lng, lat]]]
127
+ * @return [[[lng, lat]]]
128
+ */
129
+ static calculateRangeRoute(from: Coordinate, to: Coordinate, route: number[][][]): number[][][];
130
+ /**
131
+ * 计算from到to之间的航线
132
+ * @param from {lng, lat}
133
+ * @param to {lng, lat}
134
+ * @param route [[[lng, lat]]]
135
+ * @param waypoints
136
+ * @return [{lng, lat}]
137
+ */
138
+ static calculateRangeWaypoints(from: Coordinate, to: Coordinate, route: number[][][], waypoints?: Coordinate[]): any[];
139
+ /**
140
+ * 计算坐标到航路上的最短距离
141
+ * @param from
142
+ * @param route
143
+ */
144
+ static calculateMinDistanceToRoute(from: Coordinate, route: number[][][]): {
145
+ minDist: number;
146
+ segIndex: number;
147
+ minIndex: number;
148
+ };
149
+ /**
150
+ * 计算子航线
151
+ * @param from {lng, lat} 起始位置
152
+ * @param route [[[lng, lat]]] 剩余航线
153
+ * @return [[[lng, lat]]]
154
+ */
155
+ static calculateSubRoute(from: Coordinate, route: number[][][]): number[][][];
156
+ /**
157
+ * 计算子途经点
158
+ * @param from {lng, lat} 起始位置
159
+ * @param waypoints [{lng, lat}]
160
+ * @return [{lng, lat}]
161
+ */
162
+ static calculateSubWaypoints(from: Coordinate, waypoints: Coordinate[]): Coordinate[];
163
+ /**
164
+ * 计算坐标到以(from, to)横向线上的距离
165
+ * @param coordinate { lng, lat }
166
+ * @param from { lng, lat }
167
+ * @param to { lng, lat }
168
+ * @param options
169
+ */
170
+ static calculatePointToLineDistance(coordinate: Coordinate, from: Coordinate, to: Coordinate, options?: {
171
+ units: any;
172
+ method: any;
173
+ }): number;
174
+ /**
175
+ * 计算途经点的COG, Distance等属性
176
+ * @param waypoints
177
+ * @param route
178
+ */
179
+ static calculateWaypointsPropInRoute(waypoints: Coordinate[], route: number[][][]): Coordinate[];
180
+ /**
181
+ * @param coordinates [{lng, lat}]
182
+ * @param waypoints [{lng, lat}]
183
+ * @param replace true replace the same waypoint with coordinate
184
+ */
185
+ static mergeCoordinatesToWaypoints(coordinates: Coordinate[], waypoints: Coordinate[], replace?: boolean): Coordinate[];
186
+ /**
187
+ * 合并坐标进航路途经点
188
+ * @param coordinate 坐标 {lng, lat}
189
+ * @param waypoints 途经点 [{lng, lat}, {lng, lat}]
190
+ *
191
+ * @example
192
+ * coordinate: { lng: 179, lat: 50 }
193
+ * waypoints: [{ lng: 160, lat: 30}, { lng: 170, lat: 40}, {lng: -170, lat: 40}, {lng: -160, lat: 30}]
194
+ * @param replace true replace the same waypoint with coordinate
195
+ * @return
196
+ * [{ lng: 160, lat: 30}, { lng: 170, lat: 40}, {lng: 179, lat: 50}, {lng: -170, lat: 40}, {lng: -160, lat: 30}]
197
+ */
198
+ static mergeCoordinateToWaypoints(coordinate: Coordinate, waypoints: Coordinate[], replace?: boolean): Coordinate[];
199
+ /**
200
+ * 生成航线(基于途经点生成大圆/横向航线,并根据是否跨180度分组)
201
+ * @param waypoints [{lng, lat}, {lng: lat, gcToPrevious: true}]
202
+ * @return [[[lng, lat], [lng, lat]]]
203
+ */
204
+ static generateRouteAccordingToWaypoints(waypoints: Coordinate[]): number[][][];
205
+ /**
206
+ * 最近点(从route中找出距离目标点最近的点)
207
+ * @param coordinate 目标点 {lng, lat}
208
+ * @param route [[[lng, lat]]]
209
+ */
210
+ static nearestCoordinateInRoute(coordinate: Coordinate, route: number[][][]): {
211
+ lng: number;
212
+ lat: number;
213
+ };
214
+ /**
215
+ * 计算经过方向上的最后一个waypoint
216
+ * @param from
217
+ * @param waypoints
218
+ */
219
+ static calculatePrevWaypoint(from: Coordinate, waypoints: Coordinate[]): Coordinate;
220
+ /**
221
+ * 计算下一个距离单位的坐标及其子航线
222
+ * @param from 起点坐标 {lng, lat}
223
+ * @param distance 航行距离
224
+ * @param route [[[lng, lat]]]
225
+ * @param units
226
+ * @return { coordinate: {lng, lat}, route: [[[lng, lat]]]}
227
+ */
228
+ static calculateNextCoordinateAlongRoute(from: Coordinate, distance: number, route: number[][][], units?: string): {
229
+ coordinate: Coordinate | undefined;
230
+ nextRoute: number[][][];
231
+ prevRoute: Coordinate[];
232
+ };
233
+ /**
234
+ * 返回最近点及其是否为垂足(最近点不是起点或终点)
235
+ * @param coordinate { lng, lat }
236
+ * @param from {lng, lat}
237
+ * @param to {lng, lat}
238
+ */
239
+ static nearestCoordinateInLine(coordinate: Coordinate, from: Coordinate, to: Coordinate): {
240
+ lng: number;
241
+ lat: number;
242
+ inline: boolean;
243
+ };
244
+ /**
245
+ * 将route转coordinate
246
+ * @param route
247
+ * @param distance 临近点过虑
248
+ */
249
+ static convertRouteToCoordinates(route: number[][][], distance?: number): Coordinate[];
250
+ /**
251
+ * 抽稀(基于转向点)
252
+ * @param route [[lng, lat]]
253
+ * @param waypoints [{ lng, lat, gcToPrevious }]
254
+ * @param distance
255
+ */
256
+ static simplifyRouteToCoordinates(route: number[][][], waypoints: Coordinate[], distance?: number): Coordinate[];
257
+ /**
258
+ * 基于大圆标识抽稀
259
+ * @param coordinates
260
+ * @param waypoints
261
+ */
262
+ static simplifyGCCoordinates(coordinates: Coordinate[], waypoints: Coordinate[]): Coordinate[];
263
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/geo",
3
3
  "private": false,
4
- "version": "1.0.5",
4
+ "version": "1.0.7",
5
5
  "description": "idm plugin for geo",
6
6
  "type": "module",
7
7
  "keywords": [