@3clear/basegis 0.1.0

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.
@@ -0,0 +1,2204 @@
1
+ import { f as c, s as f, R as w } from "./result-D03zgqh0.js";
2
+ import G from "leaflet";
3
+ function se(i) {
4
+ return !!(i && typeof i.getMapInstance == "function" && typeof i.drawPoint == "function" && typeof i.drawLine == "function" && typeof i.drawPolygon == "function" && typeof i.drawText == "function" && typeof i.addMarker == "function" && typeof i.clearGraphics == "function");
5
+ }
6
+ class Be {
7
+ constructor(e = {}) {
8
+ this.baseGIS = null, this.items = [], this.loadedCount = 0, (e.mapCore || e.baseGIS) && this.mount(e.mapCore || e.baseGIS);
9
+ }
10
+ mount(e) {
11
+ return se(e) ? (this.baseGIS = e, f(null, "GraphicGroupController mounted with BaseGIS.")) : c(
12
+ "GraphicGroupController mount requires BaseGIS instance.",
13
+ "INVALID_MOUNT_TARGET"
14
+ );
15
+ }
16
+ resolveBaseGIS() {
17
+ var e, t;
18
+ return this.baseGIS ? (t = (e = this.baseGIS).getMapInstance) != null && t.call(e) ? f(null, "BaseGIS is ready.") : c(
19
+ "Map instance is not ready. Please call mapCore.init() first.",
20
+ "NOT_INITIALIZED"
21
+ ) : c("GraphicGroupController has not been mounted.", "NOT_MOUNTED");
22
+ }
23
+ drawItem(e = {}) {
24
+ switch (e.type) {
25
+ case "point":
26
+ return this.baseGIS.drawPoint(e);
27
+ case "line":
28
+ return this.baseGIS.drawLine(e);
29
+ case "polygon":
30
+ return this.baseGIS.drawPolygon(e);
31
+ case "text":
32
+ return this.baseGIS.drawText(e);
33
+ case "marker":
34
+ return this.baseGIS.addMarker(e);
35
+ default:
36
+ return c(`Unsupported graphic type "${e.type}".`, "INVALID_GRAPHIC_TYPE");
37
+ }
38
+ }
39
+ load(e = [], t = {}) {
40
+ const s = this.resolveBaseGIS();
41
+ if (!s.success)
42
+ return s;
43
+ if (!Array.isArray(e) || e.length === 0)
44
+ return c("Graphic item list is empty.", "INVALID_ITEMS");
45
+ t.clearBeforeLoad !== !1 && this.baseGIS.clearGraphics(), this.items = e, this.loadedCount = 0;
46
+ const n = e.map((r) => {
47
+ const o = this.drawItem(r);
48
+ return o != null && o.success && (this.loadedCount += 1), {
49
+ type: r.type,
50
+ id: r.id || "",
51
+ success: !!(o != null && o.success),
52
+ message: (o == null ? void 0 : o.message) || ""
53
+ };
54
+ });
55
+ return f(
56
+ {
57
+ total: e.length,
58
+ loadedCount: this.loadedCount,
59
+ results: n
60
+ },
61
+ `Graphic group loaded: ${this.loadedCount}/${e.length}.`
62
+ );
63
+ }
64
+ clear() {
65
+ const e = this.resolveBaseGIS();
66
+ if (!e.success)
67
+ return e;
68
+ const t = this.baseGIS.clearGraphics();
69
+ return t.success && (this.loadedCount = 0), t;
70
+ }
71
+ getState() {
72
+ return {
73
+ mounted: !!this.baseGIS,
74
+ total: this.items.length,
75
+ loadedCount: this.loadedCount,
76
+ items: this.items
77
+ };
78
+ }
79
+ }
80
+ function O(i = {}) {
81
+ return Array.isArray(i) || Array.isArray(i == null ? void 0 : i.features) ? { contours: i } : i || {};
82
+ }
83
+ function $(i = {}) {
84
+ const e = O(i);
85
+ return ["contours", "isolines", "isoline", "lines", "data", "items"].some(
86
+ (t) => Object.prototype.hasOwnProperty.call(e, t)
87
+ );
88
+ }
89
+ function ie(i) {
90
+ return !!(i && typeof i.getEngineType == "function" && typeof i.getMapInstance == "function" && typeof i.upsertContourLayer == "function" && typeof i.updateContourLayer == "function" && typeof i.showContourLayer == "function" && typeof i.hideContourLayer == "function" && typeof i.removeContourLayer == "function" && typeof i.clearContourLayer == "function" && typeof i.getContourLayerState == "function");
91
+ }
92
+ function re(i = {}) {
93
+ const { mapCore: e, baseGIS: t, ...s } = i;
94
+ return s;
95
+ }
96
+ class ne {
97
+ constructor(e = {}) {
98
+ const t = re(e), s = t.contourLayerId || t.layerId || t.id || "contour-default";
99
+ this.options = {
100
+ layerId: s,
101
+ visible: t.visible ?? !0
102
+ }, this.defaultPayload = {
103
+ ...t,
104
+ layerId: s,
105
+ visible: this.options.visible
106
+ }, this.baseGIS = null, this.currentPayload = null, this.layerType = "unknown", this.visible = this.options.visible, this.currentState = {
107
+ layerId: s,
108
+ sourceCount: 0,
109
+ levelCount: 0,
110
+ lineCount: 0,
111
+ visible: this.visible,
112
+ destroyed: !0
113
+ }, (e.mapCore || e.baseGIS) && this.mount(e.mapCore || e.baseGIS);
114
+ }
115
+ mount(e) {
116
+ var t, s;
117
+ return ie(e) ? (this.baseGIS = e, f(
118
+ { engineType: ((s = (t = this.baseGIS).getEngineType) == null ? void 0 : s.call(t)) || "unknown" },
119
+ "ContourLayerController mounted with BaseGIS."
120
+ )) : c(
121
+ "ContourLayerController mount requires BaseGIS instance.",
122
+ "INVALID_MOUNT_TARGET"
123
+ );
124
+ }
125
+ resolveBaseGIS() {
126
+ var e, t;
127
+ return this.baseGIS ? (t = (e = this.baseGIS).getMapInstance) != null && t.call(e) ? f(null, "BaseGIS is ready.") : c(
128
+ "Map instance is not ready. Please call mapCore.init() first.",
129
+ "NOT_INITIALIZED"
130
+ ) : c("ContourLayerController has not been mounted.", "NOT_MOUNTED");
131
+ }
132
+ getLayerId(e = {}) {
133
+ var t;
134
+ return typeof e == "string" && e ? e : (e == null ? void 0 : e.contourLayerId) || (e == null ? void 0 : e.layerId) || (e == null ? void 0 : e.id) || ((t = this.currentPayload) == null ? void 0 : t.layerId) || this.options.layerId;
135
+ }
136
+ buildPayload(e = {}) {
137
+ const t = O(e), s = this.getLayerId(t);
138
+ return {
139
+ ...this.defaultPayload,
140
+ ...t,
141
+ layerId: s,
142
+ visible: typeof t.visible == "boolean" ? t.visible : this.visible
143
+ };
144
+ }
145
+ syncStateFromResult(e) {
146
+ var s;
147
+ const t = ((s = e == null ? void 0 : e.data) == null ? void 0 : s.state) || (e == null ? void 0 : e.data) || null;
148
+ !t || typeof t != "object" || (this.currentState = {
149
+ ...this.currentState,
150
+ ...t
151
+ }, typeof t.visible == "boolean" && (this.visible = t.visible));
152
+ }
153
+ async load(e = {}, t = {}) {
154
+ var o;
155
+ const s = this.resolveBaseGIS();
156
+ if (!s.success)
157
+ return s;
158
+ const n = this.buildPayload({
159
+ ...O(e),
160
+ ...O(t)
161
+ });
162
+ if (!$(n))
163
+ return c(
164
+ "Contour layer requires contours, isolines, lines, data or items.",
165
+ "INVALID_CONTOUR_SOURCE"
166
+ );
167
+ const r = await this.baseGIS.upsertContourLayer(n);
168
+ return r.success && (this.currentPayload = n, this.visible = n.visible !== !1, this.layerType = ((o = r == null ? void 0 : r.data) == null ? void 0 : o.layerType) || this.layerType, this.syncStateFromResult(r)), r;
169
+ }
170
+ upsert(e = {}, t = {}) {
171
+ return this.load(e, t);
172
+ }
173
+ async update(e = {}) {
174
+ var r;
175
+ const t = this.resolveBaseGIS();
176
+ if (!t.success)
177
+ return t;
178
+ const s = {
179
+ ...this.currentPayload || this.defaultPayload,
180
+ ...O(e)
181
+ };
182
+ if (!this.currentPayload && !$(s))
183
+ return c("Contour layer has not been loaded.", "NOT_LOADED");
184
+ const n = await this.baseGIS.updateContourLayer(s);
185
+ return n.success && (this.currentPayload = s, this.visible = s.visible !== !1, this.layerType = ((r = n == null ? void 0 : n.data) == null ? void 0 : r.layerType) || this.layerType, this.syncStateFromResult(n)), n;
186
+ }
187
+ setConfig(e = {}) {
188
+ return this.update(e);
189
+ }
190
+ show(e = {}) {
191
+ const t = this.resolveBaseGIS();
192
+ if (!t.success)
193
+ return t;
194
+ const s = this.baseGIS.showContourLayer({
195
+ ...e,
196
+ layerId: this.getLayerId(e)
197
+ });
198
+ return s.success && (this.visible = !0, this.syncStateFromResult(s)), s;
199
+ }
200
+ hide(e = {}) {
201
+ const t = this.resolveBaseGIS();
202
+ if (!t.success)
203
+ return t;
204
+ const s = this.baseGIS.hideContourLayer({
205
+ ...e,
206
+ layerId: this.getLayerId(e)
207
+ });
208
+ return s.success && (this.visible = !1, this.syncStateFromResult(s)), s;
209
+ }
210
+ toggle(e) {
211
+ return typeof e == "boolean" ? e ? this.show() : this.hide() : this.visible ? this.hide() : this.show();
212
+ }
213
+ clear(e = {}) {
214
+ const t = this.resolveBaseGIS();
215
+ if (!t.success)
216
+ return t;
217
+ const s = this.baseGIS.clearContourLayer({
218
+ ...e,
219
+ layerId: this.getLayerId(e)
220
+ });
221
+ return s.success && (this.currentPayload = this.currentPayload ? {
222
+ ...this.currentPayload,
223
+ contours: [],
224
+ isolines: [],
225
+ isoline: [],
226
+ lines: []
227
+ } : null, this.syncStateFromResult(s)), s;
228
+ }
229
+ refreshState(e = {}) {
230
+ const t = this.resolveBaseGIS();
231
+ if (!t.success)
232
+ return t;
233
+ const s = this.baseGIS.getContourLayerState({
234
+ ...e,
235
+ layerId: this.getLayerId(e)
236
+ });
237
+ return s.success && this.syncStateFromResult(s), s;
238
+ }
239
+ destroy(e = {}) {
240
+ if (!this.resolveBaseGIS().success)
241
+ return this.currentPayload = null, this.layerType = "unknown", this.currentState = {
242
+ ...this.currentState,
243
+ sourceCount: 0,
244
+ levelCount: 0,
245
+ lineCount: 0,
246
+ destroyed: !0
247
+ }, f(null, "Contour layer controller destroyed (local state only).");
248
+ const s = this.baseGIS.removeContourLayer({
249
+ ...e,
250
+ layerId: this.getLayerId(e)
251
+ });
252
+ return this.currentPayload = null, this.layerType = "unknown", this.currentState = {
253
+ ...this.currentState,
254
+ sourceCount: 0,
255
+ levelCount: 0,
256
+ lineCount: 0,
257
+ destroyed: !0
258
+ }, s.success ? f(null, "Contour layer controller destroyed.") : s;
259
+ }
260
+ removeLayer(e = {}) {
261
+ return this.destroy(e);
262
+ }
263
+ getState() {
264
+ var e, t, s, n, r, o, a;
265
+ if ((t = (e = this.baseGIS) == null ? void 0 : e.getMapInstance) != null && t.call(e) && this.currentPayload) {
266
+ const l = (n = (s = this.baseGIS).getContourLayerState) == null ? void 0 : n.call(s, {
267
+ layerId: this.currentPayload.layerId || this.options.layerId
268
+ });
269
+ l != null && l.success && this.syncStateFromResult(l);
270
+ }
271
+ return {
272
+ mounted: !!this.baseGIS,
273
+ engineType: ((o = (r = this.baseGIS) == null ? void 0 : r.getEngineType) == null ? void 0 : o.call(r)) || "unknown",
274
+ layerType: this.layerType,
275
+ visible: this.visible,
276
+ layerId: ((a = this.currentPayload) == null ? void 0 : a.layerId) || this.options.layerId,
277
+ payload: this.currentPayload,
278
+ ...this.currentState
279
+ };
280
+ }
281
+ }
282
+ function P(i, e = 0) {
283
+ const t = Number(i);
284
+ return Number.isFinite(t) ? t : e;
285
+ }
286
+ function k(i, e = {
287
+ startLon: 73,
288
+ startLat: 18,
289
+ endLon: 135,
290
+ endLat: 54
291
+ }) {
292
+ const t = i && typeof i == "object" ? i : e;
293
+ return {
294
+ startLon: P(t.startLon, e.startLon),
295
+ startLat: P(t.startLat, e.startLat),
296
+ endLon: P(t.endLon, e.endLon),
297
+ endLat: P(t.endLat, e.endLat)
298
+ };
299
+ }
300
+ function oe(i) {
301
+ return !!(i && typeof i.getEngineType == "function" && typeof i.getMapInstance == "function" && typeof i.upsertGridLayer == "function" && typeof i.showGridLayer == "function" && typeof i.hideGridLayer == "function" && typeof i.removeGridLayer == "function");
302
+ }
303
+ function ae(i = {}) {
304
+ return !!(i.tifUrl || i.imageUrl || i.grayImageUrl || i.imageGridData);
305
+ }
306
+ class De {
307
+ constructor(e = {}) {
308
+ this.options = {
309
+ visible: e.visible ?? !0,
310
+ layerId: e.layerId || "grid-layer-default",
311
+ defaultArea: k(e.defaultArea),
312
+ gridTotal: P(e.gridTotal, 4),
313
+ tileSize: P(e.tileSize, 512),
314
+ decimalPlaces: P(e.decimalPlaces, 2),
315
+ showLabel: !!e.showLabel,
316
+ showProbe: !!e.showProbe,
317
+ colorize: e.colorize || null
318
+ }, this.baseGIS = null, this.visible = this.options.visible, this.layerType = "unknown", this.currentPayload = null, (e.mapCore || e.baseGIS) && this.mount(e.mapCore || e.baseGIS);
319
+ }
320
+ mount(e) {
321
+ var t, s;
322
+ return oe(e) ? (this.baseGIS = e, f(
323
+ { engineType: ((s = (t = this.baseGIS).getEngineType) == null ? void 0 : s.call(t)) || "unknown" },
324
+ "GridLayerController mounted with BaseGIS."
325
+ )) : c(
326
+ "GridLayerController mount requires BaseGIS instance.",
327
+ "INVALID_MOUNT_TARGET"
328
+ );
329
+ }
330
+ resolveBaseGIS() {
331
+ var e, t;
332
+ return this.baseGIS ? (t = (e = this.baseGIS).getMapInstance) != null && t.call(e) ? f(null, "BaseGIS is ready.") : c(
333
+ "Map instance is not ready. Please call mapCore.init() first.",
334
+ "NOT_INITIALIZED"
335
+ ) : c("GridLayerController has not been mounted.", "NOT_MOUNTED");
336
+ }
337
+ getLayerId(e = {}) {
338
+ var t;
339
+ return typeof e == "string" && e ? e : (e == null ? void 0 : e.layerId) || (e == null ? void 0 : e.gridLayerId) || ((t = this.currentPayload) == null ? void 0 : t.layerId) || this.options.layerId;
340
+ }
341
+ buildPayload(e = {}) {
342
+ const t = e.imageUrl || e.grayImageUrl || e.imageGridData, s = e.area ? k(e.area, this.options.defaultArea) : t ? this.options.defaultArea : void 0;
343
+ return {
344
+ ...e,
345
+ layerId: this.getLayerId(e),
346
+ area: s,
347
+ gridTotal: P(e.gridTotal, this.options.gridTotal),
348
+ tileSize: P(e.tileSize, this.options.tileSize),
349
+ decimalPlaces: P(e.decimalPlaces, this.options.decimalPlaces),
350
+ showLabel: typeof e.showLabel == "boolean" ? e.showLabel : this.options.showLabel,
351
+ showProbe: typeof e.showProbe == "boolean" ? e.showProbe : this.options.showProbe,
352
+ colorize: e.colorize || this.options.colorize,
353
+ visible: typeof e.visible == "boolean" ? e.visible : this.visible
354
+ };
355
+ }
356
+ async load(e = {}) {
357
+ var r;
358
+ const t = this.resolveBaseGIS();
359
+ if (!t.success)
360
+ return t;
361
+ if (!ae(e))
362
+ return c(
363
+ "Grid layer requires tifUrl, imageUrl, grayImageUrl or imageGridData.",
364
+ "INVALID_GRID_SOURCE"
365
+ );
366
+ const s = this.buildPayload(e), n = await this.baseGIS.upsertGridLayer(s);
367
+ return n.success && (this.currentPayload = s, this.visible = s.visible !== !1, this.layerType = ((r = n == null ? void 0 : n.data) == null ? void 0 : r.layerType) || this.layerType), n;
368
+ }
369
+ loadTif(e = {}) {
370
+ return this.load({
371
+ ...e,
372
+ tifUrl: e.tifUrl
373
+ });
374
+ }
375
+ loadGrayImage(e = {}) {
376
+ return this.load({
377
+ ...e,
378
+ imageUrl: e.imageUrl || e.grayImageUrl,
379
+ imageSourceType: e.imageSourceType || "grayscale"
380
+ });
381
+ }
382
+ loadData(e = {}) {
383
+ return this.load({
384
+ ...e,
385
+ imageGridData: e.imageGridData || e.data
386
+ });
387
+ }
388
+ async update(e = {}) {
389
+ return this.currentPayload ? this.load({
390
+ ...this.currentPayload,
391
+ ...e,
392
+ layerId: e.layerId || e.gridLayerId || this.currentPayload.layerId
393
+ }) : c("Grid layer has not been loaded.", "NOT_LOADED");
394
+ }
395
+ show(e = {}) {
396
+ const t = this.resolveBaseGIS();
397
+ if (!t.success)
398
+ return t;
399
+ const s = this.baseGIS.showGridLayer({
400
+ layerId: this.getLayerId(e)
401
+ });
402
+ return s.success && (this.visible = !0), s;
403
+ }
404
+ hide(e = {}) {
405
+ const t = this.resolveBaseGIS();
406
+ if (!t.success)
407
+ return t;
408
+ const s = this.baseGIS.hideGridLayer({
409
+ layerId: this.getLayerId(e)
410
+ });
411
+ return s.success && (this.visible = !1), s;
412
+ }
413
+ destroy(e = {}) {
414
+ if (!this.resolveBaseGIS().success)
415
+ return this.currentPayload = null, this.layerType = "unknown", f(null, "Grid layer controller destroyed (local state only).");
416
+ const s = this.baseGIS.removeGridLayer({
417
+ layerId: this.getLayerId(e)
418
+ });
419
+ return this.currentPayload = null, this.layerType = "unknown", s.success ? f(null, "Grid layer controller destroyed.") : s;
420
+ }
421
+ getState() {
422
+ var e, t, s;
423
+ return {
424
+ mounted: !!this.baseGIS,
425
+ engineType: ((t = (e = this.baseGIS) == null ? void 0 : e.getEngineType) == null ? void 0 : t.call(e)) || "unknown",
426
+ layerType: this.layerType,
427
+ visible: this.visible,
428
+ layerId: ((s = this.currentPayload) == null ? void 0 : s.layerId) || this.options.layerId,
429
+ payload: this.currentPayload
430
+ };
431
+ }
432
+ }
433
+ function S(i, e = 0) {
434
+ const t = Number(i);
435
+ return Number.isFinite(t) ? t : e;
436
+ }
437
+ function V(i, e = {
438
+ startLon: 73,
439
+ startLat: 18,
440
+ endLon: 135,
441
+ endLat: 54
442
+ }) {
443
+ const t = i && typeof i == "object" ? i : e;
444
+ return {
445
+ startLon: S(t.startLon, e.startLon),
446
+ startLat: S(t.startLat, e.startLat),
447
+ endLon: S(t.endLon, e.endLon),
448
+ endLat: S(t.endLat, e.endLat)
449
+ };
450
+ }
451
+ function le(i) {
452
+ return !!(i && typeof i.getEngineType == "function" && typeof i.getMapInstance == "function" && typeof i.upsertImageLayer == "function" && typeof i.showImageLayer == "function" && typeof i.hideImageLayer == "function" && typeof i.removeImageLayer == "function");
453
+ }
454
+ class Re {
455
+ constructor(e = {}) {
456
+ this.options = {
457
+ visible: e.visible ?? !0,
458
+ opacity: S(e.opacity, 0.85),
459
+ defaultArea: V(e.defaultArea),
460
+ gridTotal: S(e.gridTotal, 4),
461
+ tileSize: S(e.tileSize, 512),
462
+ decimalPlaces: S(e.decimalPlaces, 2),
463
+ imageSourceType: e.imageSourceType || "color",
464
+ colorize: e.colorize || null,
465
+ layerId: e.layerId || "image-layer-default"
466
+ }, this.baseGIS = null, this.items = [], this.activeIndex = -1, this.visible = this.options.visible, this.layerType = "unknown", (e.mapCore || e.baseGIS) && this.mount(e.mapCore || e.baseGIS);
467
+ }
468
+ /**
469
+ * 绑定 BaseGIS 实例。
470
+ * 这里不关心具体引擎类型,只要求传入的是 BaseGIS 主类实例。
471
+ */
472
+ mount(e) {
473
+ var t, s;
474
+ return le(e) ? (this.baseGIS = e, f(
475
+ { engineType: ((s = (t = this.baseGIS).getEngineType) == null ? void 0 : s.call(t)) || "unknown" },
476
+ "ImageLayerController mounted with BaseGIS."
477
+ )) : c(
478
+ "ImageLayerController mount requires BaseGIS instance.",
479
+ "INVALID_MOUNT_TARGET"
480
+ );
481
+ }
482
+ resolveBaseGIS() {
483
+ var e, t;
484
+ return this.baseGIS ? (t = (e = this.baseGIS).getMapInstance) != null && t.call(e) ? f(null, "BaseGIS is ready.") : c(
485
+ "Map instance is not ready. Please call mapCore.init() first.",
486
+ "NOT_INITIALIZED"
487
+ ) : c("ImageLayerController has not been mounted.", "NOT_MOUNTED");
488
+ }
489
+ getLayerId(e = {}) {
490
+ return typeof e == "string" && e ? e : (e == null ? void 0 : e.layerId) || this.options.layerId;
491
+ }
492
+ buildLayerPayload(e, t = {}) {
493
+ return {
494
+ layerId: this.getLayerId(t),
495
+ imageUrl: e.imageUrl,
496
+ tifUrl: e.tifUrl,
497
+ area: V(e.area, this.options.defaultArea),
498
+ isSplit: !!e.isSplit,
499
+ imageSourceType: e.imageSourceType || this.options.imageSourceType,
500
+ isGrayImage: e.isGrayImage,
501
+ colorize: e.colorize || this.options.colorize,
502
+ minValue: e.minValue,
503
+ maxValue: e.maxValue,
504
+ grayMinValue: e.grayMinValue,
505
+ grayMaxValue: e.grayMaxValue,
506
+ noDataValue: e.noDataValue,
507
+ colorMapType: e.colorMapType,
508
+ type: e.type,
509
+ colorStops: e.colorStops,
510
+ colors: e.colors,
511
+ showProbe: e.showProbe,
512
+ enableProbe: e.enableProbe,
513
+ showMouseProbe: e.showMouseProbe,
514
+ showLabel: !!e.showLabel,
515
+ gridTotal: S(e.gridTotal, this.options.gridTotal),
516
+ tileSize: S(e.tileSize, this.options.tileSize),
517
+ decimalPlaces: S(e.decimalPlaces, this.options.decimalPlaces),
518
+ opacity: S(e.opacity, this.options.opacity),
519
+ visible: typeof t.visible == "boolean" ? t.visible : this.visible
520
+ };
521
+ }
522
+ /**
523
+ * 加载图片集合,并切换到默认索引。
524
+ * 每项字段示例:id / name / imageUrl / tifUrl / area / opacity / isSplit / imageSourceType / colorize / showLabel
525
+ */
526
+ async load(e = [], t = {}) {
527
+ if (!Array.isArray(e) || e.length === 0)
528
+ return c("Image list is empty.", "INVALID_ITEMS");
529
+ const s = e.map((r, o) => ({
530
+ id: (r == null ? void 0 : r.id) || `image-${o}`,
531
+ name: (r == null ? void 0 : r.name) || `Image ${o + 1}`,
532
+ imageUrl: (r == null ? void 0 : r.imageUrl) || "",
533
+ tifUrl: (r == null ? void 0 : r.tifUrl) || "",
534
+ description: (r == null ? void 0 : r.description) || "",
535
+ area: V(r == null ? void 0 : r.area, this.options.defaultArea),
536
+ opacity: r == null ? void 0 : r.opacity,
537
+ isSplit: r == null ? void 0 : r.isSplit,
538
+ imageSourceType: r == null ? void 0 : r.imageSourceType,
539
+ isGrayImage: r == null ? void 0 : r.isGrayImage,
540
+ colorize: r == null ? void 0 : r.colorize,
541
+ minValue: r == null ? void 0 : r.minValue,
542
+ maxValue: r == null ? void 0 : r.maxValue,
543
+ grayMinValue: r == null ? void 0 : r.grayMinValue,
544
+ grayMaxValue: r == null ? void 0 : r.grayMaxValue,
545
+ noDataValue: r == null ? void 0 : r.noDataValue,
546
+ colorMapType: r == null ? void 0 : r.colorMapType,
547
+ type: r == null ? void 0 : r.type,
548
+ colorStops: r == null ? void 0 : r.colorStops,
549
+ colors: r == null ? void 0 : r.colors,
550
+ showProbe: r == null ? void 0 : r.showProbe,
551
+ enableProbe: r == null ? void 0 : r.enableProbe,
552
+ showMouseProbe: r == null ? void 0 : r.showMouseProbe,
553
+ showLabel: r == null ? void 0 : r.showLabel,
554
+ gridTotal: r == null ? void 0 : r.gridTotal,
555
+ tileSize: r == null ? void 0 : r.tileSize,
556
+ decimalPlaces: r == null ? void 0 : r.decimalPlaces
557
+ })).filter((r) => r.imageUrl || r.tifUrl);
558
+ if (s.length === 0)
559
+ return c("No valid imageUrl or tifUrl found in items.", "INVALID_ITEMS");
560
+ this.items = s, typeof t.visible == "boolean" && (this.visible = t.visible);
561
+ const n = Number.isInteger(t.index) ? t.index : 0;
562
+ return this.switchTo(n);
563
+ }
564
+ /**
565
+ * 切换图片。
566
+ * target 可传索引数字,也可传图片 id。
567
+ */
568
+ async switchTo(e) {
569
+ var a;
570
+ const t = this.resolveBaseGIS();
571
+ if (!t.success)
572
+ return t;
573
+ if (!Array.isArray(this.items) || this.items.length === 0)
574
+ return c("Image list has not been loaded.", "NOT_LOADED");
575
+ let s = -1;
576
+ if (typeof e == "number" ? s = e : typeof e == "string" && (s = this.items.findIndex((l) => l.id === e)), s < 0 || s >= this.items.length)
577
+ return c(`Invalid image target "${e}".`, "INVALID_TARGET");
578
+ const n = this.items[s], r = this.buildLayerPayload(n), o = await this.baseGIS.upsertImageLayer(r);
579
+ return o.success ? (this.activeIndex = s, this.layerType = ((a = o == null ? void 0 : o.data) == null ? void 0 : a.layerType) || this.layerType, f(
580
+ { activeIndex: s, activeItem: n },
581
+ `Image switched to "${n.name}".`
582
+ )) : o;
583
+ }
584
+ async next() {
585
+ if (!this.items.length)
586
+ return c("Image list has not been loaded.", "NOT_LOADED");
587
+ const e = this.activeIndex < 0 ? 0 : (this.activeIndex + 1) % this.items.length;
588
+ return this.switchTo(e);
589
+ }
590
+ async prev() {
591
+ if (!this.items.length)
592
+ return c("Image list has not been loaded.", "NOT_LOADED");
593
+ const e = this.activeIndex < 0 ? this.items.length - 1 : (this.activeIndex - 1 + this.items.length) % this.items.length;
594
+ return this.switchTo(e);
595
+ }
596
+ show(e = {}) {
597
+ const t = this.resolveBaseGIS();
598
+ if (!t.success)
599
+ return t;
600
+ const s = this.baseGIS.showImageLayer({
601
+ layerId: this.getLayerId(e)
602
+ });
603
+ return s.success && (this.visible = !0), s;
604
+ }
605
+ hide(e = {}) {
606
+ const t = this.resolveBaseGIS();
607
+ if (!t.success)
608
+ return t;
609
+ const s = this.baseGIS.hideImageLayer({
610
+ layerId: this.getLayerId(e)
611
+ });
612
+ return s.success && (this.visible = !1), s;
613
+ }
614
+ /**
615
+ * 销毁控制器。
616
+ * 如果地图已经先销毁,则只清理控制器本地状态。
617
+ */
618
+ destroy(e = {}) {
619
+ if (!this.resolveBaseGIS().success)
620
+ return this.items = [], this.activeIndex = -1, this.layerType = "unknown", f(null, "Image layer controller destroyed (local state only).");
621
+ const s = this.baseGIS.removeImageLayer({
622
+ layerId: this.getLayerId(e)
623
+ });
624
+ return this.items = [], this.activeIndex = -1, this.layerType = "unknown", s.success ? f(null, "Image layer controller destroyed.") : s;
625
+ }
626
+ getState() {
627
+ var e, t;
628
+ return {
629
+ mounted: !!this.baseGIS,
630
+ engineType: ((t = (e = this.baseGIS) == null ? void 0 : e.getEngineType) == null ? void 0 : t.call(e)) || "unknown",
631
+ layerType: this.layerType,
632
+ visible: this.visible,
633
+ total: this.items.length,
634
+ activeIndex: this.activeIndex,
635
+ activeItem: this.items[this.activeIndex] || null
636
+ };
637
+ }
638
+ }
639
+ function B(i = {}) {
640
+ return Array.isArray(i) || Array.isArray(i == null ? void 0 : i.features) ? { points: i } : i || {};
641
+ }
642
+ function q(i = {}) {
643
+ const e = B(i);
644
+ return ["points", "data", "items"].some(
645
+ (t) => Object.prototype.hasOwnProperty.call(e, t)
646
+ );
647
+ }
648
+ function ce(i) {
649
+ return !!(i && typeof i.getEngineType == "function" && typeof i.getMapInstance == "function" && typeof i.upsertPointDensityLayer == "function" && typeof i.showPointDensityLayer == "function" && typeof i.hidePointDensityLayer == "function" && typeof i.removePointDensityLayer == "function" && typeof i.clearPointDensityLayer == "function" && typeof i.getPointDensityLayerState == "function");
650
+ }
651
+ function ue(i = {}) {
652
+ const { mapCore: e, baseGIS: t, ...s } = i;
653
+ return s;
654
+ }
655
+ class Fe {
656
+ constructor(e = {}) {
657
+ const t = ue(e), s = t.pointDensityLayerId || t.densityLayerId || t.layerId || t.id || "point-density-default";
658
+ this.options = {
659
+ layerId: s,
660
+ visible: t.visible ?? !0,
661
+ idKey: t.idKey || "id"
662
+ }, this.defaultPayload = {
663
+ ...t,
664
+ layerId: s,
665
+ visible: this.options.visible
666
+ }, this.baseGIS = null, this.currentPayload = null, this.layerType = "unknown", this.visible = this.options.visible, this.currentState = {
667
+ layerId: s,
668
+ sourceCount: 0,
669
+ visibleCount: 0,
670
+ hiddenCount: 0,
671
+ gridCount: 0,
672
+ gridSize: t.gridSize ?? t.pixelRange ?? 150,
673
+ visible: this.visible,
674
+ destroyed: !0
675
+ }, (e.mapCore || e.baseGIS) && this.mount(e.mapCore || e.baseGIS);
676
+ }
677
+ mount(e) {
678
+ var t, s;
679
+ return ce(e) ? (this.baseGIS = e, f(
680
+ { engineType: ((s = (t = this.baseGIS).getEngineType) == null ? void 0 : s.call(t)) || "unknown" },
681
+ "PointDensityController mounted with BaseGIS."
682
+ )) : c(
683
+ "PointDensityController mount requires BaseGIS instance.",
684
+ "INVALID_MOUNT_TARGET"
685
+ );
686
+ }
687
+ resolveBaseGIS() {
688
+ var e, t;
689
+ return this.baseGIS ? (t = (e = this.baseGIS).getMapInstance) != null && t.call(e) ? f(null, "BaseGIS is ready.") : c(
690
+ "Map instance is not ready. Please call mapCore.init() first.",
691
+ "NOT_INITIALIZED"
692
+ ) : c("PointDensityController has not been mounted.", "NOT_MOUNTED");
693
+ }
694
+ getLayerId(e = {}) {
695
+ var t;
696
+ return typeof e == "string" && e ? e : (e == null ? void 0 : e.pointDensityLayerId) || (e == null ? void 0 : e.densityLayerId) || (e == null ? void 0 : e.layerId) || (e == null ? void 0 : e.id) || ((t = this.currentPayload) == null ? void 0 : t.layerId) || this.options.layerId;
697
+ }
698
+ buildPayload(e = {}) {
699
+ const t = B(e), s = this.getLayerId(t);
700
+ return {
701
+ ...this.defaultPayload,
702
+ ...t,
703
+ layerId: s,
704
+ visible: typeof t.visible == "boolean" ? t.visible : this.visible
705
+ };
706
+ }
707
+ syncStateFromResult(e) {
708
+ var s;
709
+ const t = ((s = e == null ? void 0 : e.data) == null ? void 0 : s.state) || (e == null ? void 0 : e.data) || null;
710
+ !t || typeof t != "object" || (this.currentState = {
711
+ ...this.currentState,
712
+ ...t
713
+ }, typeof t.visible == "boolean" && (this.visible = t.visible));
714
+ }
715
+ async load(e = {}, t = {}) {
716
+ var l;
717
+ const s = this.resolveBaseGIS();
718
+ if (!s.success)
719
+ return s;
720
+ const n = B(e), r = B(t), o = this.buildPayload({
721
+ ...n,
722
+ ...r
723
+ });
724
+ if (!q(o))
725
+ return c(
726
+ "Point density layer requires points, data or items.",
727
+ "INVALID_POINT_SOURCE"
728
+ );
729
+ const a = await this.baseGIS.upsertPointDensityLayer(o);
730
+ return a.success && (this.currentPayload = o, this.visible = o.visible !== !1, this.layerType = ((l = a == null ? void 0 : a.data) == null ? void 0 : l.layerType) || this.layerType, this.syncStateFromResult(a)), a;
731
+ }
732
+ upsert(e = {}, t = {}) {
733
+ return this.load(e, t);
734
+ }
735
+ async update(e = {}) {
736
+ const t = {
737
+ ...this.currentPayload || this.defaultPayload,
738
+ ...B(e)
739
+ };
740
+ return !this.currentPayload && !q(t) ? c("Point density layer has not been loaded.", "NOT_LOADED") : this.load(t);
741
+ }
742
+ setConfig(e = {}) {
743
+ return this.update(e);
744
+ }
745
+ show(e = {}) {
746
+ const t = this.resolveBaseGIS();
747
+ if (!t.success)
748
+ return t;
749
+ const s = this.baseGIS.showPointDensityLayer({
750
+ ...e,
751
+ layerId: this.getLayerId(e)
752
+ });
753
+ return s.success && (this.visible = !0, this.syncStateFromResult(s)), s;
754
+ }
755
+ hide(e = {}) {
756
+ const t = this.resolveBaseGIS();
757
+ if (!t.success)
758
+ return t;
759
+ const s = this.baseGIS.hidePointDensityLayer({
760
+ ...e,
761
+ layerId: this.getLayerId(e)
762
+ });
763
+ return s.success && (this.visible = !1, this.syncStateFromResult(s)), s;
764
+ }
765
+ toggle(e) {
766
+ return typeof e == "boolean" ? e ? this.show() : this.hide() : this.visible ? this.hide() : this.show();
767
+ }
768
+ clear(e = {}) {
769
+ const t = this.resolveBaseGIS();
770
+ if (!t.success)
771
+ return t;
772
+ const s = this.baseGIS.clearPointDensityLayer({
773
+ ...e,
774
+ layerId: this.getLayerId(e)
775
+ });
776
+ return s.success && (this.currentPayload = this.currentPayload ? {
777
+ ...this.currentPayload,
778
+ points: [],
779
+ data: [],
780
+ items: []
781
+ } : null, this.syncStateFromResult(s)), s;
782
+ }
783
+ refreshState(e = {}) {
784
+ const t = this.resolveBaseGIS();
785
+ if (!t.success)
786
+ return t;
787
+ const s = this.baseGIS.getPointDensityLayerState({
788
+ ...e,
789
+ layerId: this.getLayerId(e)
790
+ });
791
+ return s.success && this.syncStateFromResult(s), s;
792
+ }
793
+ destroy(e = {}) {
794
+ if (!this.resolveBaseGIS().success)
795
+ return this.currentPayload = null, this.layerType = "unknown", this.currentState = {
796
+ ...this.currentState,
797
+ sourceCount: 0,
798
+ visibleCount: 0,
799
+ hiddenCount: 0,
800
+ gridCount: 0,
801
+ destroyed: !0
802
+ }, f(null, "Point density layer controller destroyed (local state only).");
803
+ const s = this.baseGIS.removePointDensityLayer({
804
+ ...e,
805
+ layerId: this.getLayerId(e)
806
+ });
807
+ return this.currentPayload = null, this.layerType = "unknown", this.currentState = {
808
+ ...this.currentState,
809
+ sourceCount: 0,
810
+ visibleCount: 0,
811
+ hiddenCount: 0,
812
+ gridCount: 0,
813
+ destroyed: !0
814
+ }, s.success ? f(null, "Point density layer controller destroyed.") : s;
815
+ }
816
+ removeLayer(e = {}) {
817
+ return this.destroy(e);
818
+ }
819
+ getState() {
820
+ var e, t, s, n, r, o, a;
821
+ if ((t = (e = this.baseGIS) == null ? void 0 : e.getMapInstance) != null && t.call(e) && this.currentPayload) {
822
+ const l = (n = (s = this.baseGIS).getPointDensityLayerState) == null ? void 0 : n.call(s, {
823
+ layerId: this.currentPayload.layerId || this.options.layerId
824
+ });
825
+ l != null && l.success && this.syncStateFromResult(l);
826
+ }
827
+ return {
828
+ mounted: !!this.baseGIS,
829
+ engineType: ((o = (r = this.baseGIS) == null ? void 0 : r.getEngineType) == null ? void 0 : o.call(r)) || "unknown",
830
+ layerType: this.layerType,
831
+ visible: this.visible,
832
+ layerId: ((a = this.currentPayload) == null ? void 0 : a.layerId) || this.options.layerId,
833
+ payload: this.currentPayload,
834
+ ...this.currentState
835
+ };
836
+ }
837
+ }
838
+ function D(i = {}) {
839
+ return Array.isArray(i) || Array.isArray(i == null ? void 0 : i.features) ? { points: i } : i || {};
840
+ }
841
+ function H(i = {}) {
842
+ const e = D(i);
843
+ return ["points", "data", "items"].some(
844
+ (t) => Object.prototype.hasOwnProperty.call(e, t)
845
+ );
846
+ }
847
+ function he(i) {
848
+ return !!(i && typeof i.getEngineType == "function" && typeof i.getMapInstance == "function" && typeof i.upsertPointLargeLayer == "function" && typeof i.showPointLargeLayer == "function" && typeof i.hidePointLargeLayer == "function" && typeof i.removePointLargeLayer == "function" && typeof i.setPointLargeHighlight == "function" && typeof i.clearPointLargeHighlight == "function" && typeof i.removePointLargePoint == "function" && typeof i.clearPointLargeLayer == "function");
849
+ }
850
+ function Y(i, e = {}) {
851
+ return i && typeof i == "object" && !Array.isArray(i) ? i.pointId ?? i.highlightId ?? i.key ?? i.id : i ?? e.pointId ?? e.highlightId ?? e.key ?? e.id;
852
+ }
853
+ function de(i, e = "id", t = "") {
854
+ var s, n;
855
+ return !i || typeof i != "object" || Array.isArray(i) ? t : i[e] ?? ((s = i.properties) == null ? void 0 : s[e]) ?? i.id ?? ((n = i.properties) == null ? void 0 : n.id) ?? t;
856
+ }
857
+ function ye(i = {}) {
858
+ const { mapCore: e, baseGIS: t, ...s } = i;
859
+ return s;
860
+ }
861
+ class Ee {
862
+ constructor(e = {}) {
863
+ const t = ye(e), s = t.pointLargeLayerId || t.largeLayerId || t.layerId || t.id || "point-large-default";
864
+ this.options = {
865
+ layerId: s,
866
+ visible: t.visible ?? !0,
867
+ idKey: t.idKey || "id"
868
+ }, this.defaultPayload = {
869
+ ...t,
870
+ layerId: s,
871
+ visible: this.options.visible
872
+ }, this.baseGIS = null, this.currentPayload = null, this.layerType = "unknown", this.visible = this.options.visible, this.currentState = {
873
+ layerId: s,
874
+ visible: this.visible,
875
+ total: 0,
876
+ renderedCount: 0,
877
+ highlightedId: null,
878
+ building: !1,
879
+ destroyed: !0
880
+ }, (e.mapCore || e.baseGIS) && this.mount(e.mapCore || e.baseGIS);
881
+ }
882
+ mount(e) {
883
+ var t, s;
884
+ return he(e) ? (this.baseGIS = e, f(
885
+ { engineType: ((s = (t = this.baseGIS).getEngineType) == null ? void 0 : s.call(t)) || "unknown" },
886
+ "PointLargeLayerController mounted with BaseGIS."
887
+ )) : c(
888
+ "PointLargeLayerController mount requires BaseGIS instance.",
889
+ "INVALID_MOUNT_TARGET"
890
+ );
891
+ }
892
+ resolveBaseGIS() {
893
+ var e, t;
894
+ return this.baseGIS ? (t = (e = this.baseGIS).getMapInstance) != null && t.call(e) ? f(null, "BaseGIS is ready.") : c(
895
+ "Map instance is not ready. Please call mapCore.init() first.",
896
+ "NOT_INITIALIZED"
897
+ ) : c("PointLargeLayerController has not been mounted.", "NOT_MOUNTED");
898
+ }
899
+ getLayerId(e = {}, t = {}) {
900
+ var n;
901
+ const { allowId: s = !0 } = t;
902
+ return typeof e == "string" && e ? e : (e == null ? void 0 : e.pointLargeLayerId) || (e == null ? void 0 : e.largeLayerId) || (e == null ? void 0 : e.layerId) || (s ? e == null ? void 0 : e.id : "") || ((n = this.currentPayload) == null ? void 0 : n.layerId) || this.options.layerId;
903
+ }
904
+ buildPayload(e = {}) {
905
+ const t = D(e), s = this.getLayerId(t);
906
+ return {
907
+ ...this.defaultPayload,
908
+ ...t,
909
+ layerId: s,
910
+ visible: typeof t.visible == "boolean" ? t.visible : this.visible
911
+ };
912
+ }
913
+ syncStateFromResult(e) {
914
+ var s;
915
+ const t = ((s = e == null ? void 0 : e.data) == null ? void 0 : s.state) || (e == null ? void 0 : e.data) || null;
916
+ !t || typeof t != "object" || (this.currentState = {
917
+ ...this.currentState,
918
+ ...t
919
+ }, typeof t.visible == "boolean" && (this.visible = t.visible));
920
+ }
921
+ /**
922
+ * 加载或重建海量点位。
923
+ * 支持 load(points, options) 或 load({ points, ...options }) 两种调用方式。
924
+ */
925
+ async load(e = {}, t = {}) {
926
+ var l;
927
+ const s = this.resolveBaseGIS();
928
+ if (!s.success)
929
+ return s;
930
+ const n = D(e), r = D(t), o = this.buildPayload({
931
+ ...n,
932
+ ...r
933
+ });
934
+ if (!H(o))
935
+ return c(
936
+ "Point large layer requires points, data or items.",
937
+ "INVALID_POINT_SOURCE"
938
+ );
939
+ const a = await this.baseGIS.upsertPointLargeLayer(o);
940
+ return a.success && (this.currentPayload = o, this.visible = o.visible !== !1, this.layerType = ((l = a == null ? void 0 : a.data) == null ? void 0 : l.layerType) || this.layerType, this.syncStateFromResult(a)), a;
941
+ }
942
+ upsert(e = {}, t = {}) {
943
+ return this.load(e, t);
944
+ }
945
+ async update(e = {}) {
946
+ const t = {
947
+ ...this.currentPayload || this.defaultPayload,
948
+ ...D(e)
949
+ };
950
+ return !this.currentPayload && !H(t) ? c("Point large layer has not been loaded.", "NOT_LOADED") : this.load(t);
951
+ }
952
+ show(e = {}) {
953
+ const t = this.resolveBaseGIS();
954
+ if (!t.success)
955
+ return t;
956
+ const s = this.baseGIS.showPointLargeLayer({
957
+ ...e,
958
+ layerId: this.getLayerId(e)
959
+ });
960
+ return s.success && (this.visible = !0, this.syncStateFromResult(s)), s;
961
+ }
962
+ hide(e = {}) {
963
+ const t = this.resolveBaseGIS();
964
+ if (!t.success)
965
+ return t;
966
+ const s = this.baseGIS.hidePointLargeLayer({
967
+ ...e,
968
+ layerId: this.getLayerId(e)
969
+ });
970
+ return s.success && (this.visible = !1, this.syncStateFromResult(s)), s;
971
+ }
972
+ toggle(e) {
973
+ return typeof e == "boolean" ? e ? this.show() : this.hide() : this.visible ? this.hide() : this.show();
974
+ }
975
+ setHighlight(e, t = {}) {
976
+ const s = this.resolveBaseGIS();
977
+ if (!s.success)
978
+ return s;
979
+ const n = e && typeof e == "object" && !Array.isArray(e) ? e : t, r = Y(e, n);
980
+ if (r == null || r === "")
981
+ return c("Point id is required when setting highlight.", "INVALID_POINT_ID");
982
+ const o = this.baseGIS.setPointLargeHighlight({
983
+ ...n,
984
+ layerId: this.getLayerId(n, { allowId: !1 }),
985
+ pointId: r
986
+ });
987
+ return o.success && this.syncStateFromResult(o), o;
988
+ }
989
+ highlight(e, t = {}) {
990
+ return this.setHighlight(e, t);
991
+ }
992
+ setHighlighted(e, t = {}) {
993
+ return this.setHighlight(e, t);
994
+ }
995
+ clearHighlight(e = {}) {
996
+ const t = this.resolveBaseGIS();
997
+ if (!t.success)
998
+ return t;
999
+ const s = this.baseGIS.clearPointLargeHighlight({
1000
+ ...e,
1001
+ layerId: this.getLayerId(e)
1002
+ });
1003
+ return s.success && this.syncStateFromResult(s), s;
1004
+ }
1005
+ clearHighlighted(e = {}) {
1006
+ return this.clearHighlight(e);
1007
+ }
1008
+ removeCachedPoints(e = []) {
1009
+ if (!this.currentPayload || !Array.isArray(this.currentPayload.points))
1010
+ return;
1011
+ const t = this.currentPayload.idKey || this.options.idKey, s = new Set(e.map((n) => String(n)));
1012
+ this.currentPayload = {
1013
+ ...this.currentPayload,
1014
+ points: this.currentPayload.points.filter((n, r) => {
1015
+ const o = de(n, t, r);
1016
+ return !s.has(String(o));
1017
+ })
1018
+ };
1019
+ }
1020
+ removePoint(e, t = {}) {
1021
+ const s = this.resolveBaseGIS();
1022
+ if (!s.success)
1023
+ return s;
1024
+ const n = e && typeof e == "object" && !Array.isArray(e) ? e : t, r = Y(e, n);
1025
+ if (r == null || r === "")
1026
+ return c("Point id is required when removing point.", "INVALID_POINT_ID");
1027
+ const o = this.baseGIS.removePointLargePoint({
1028
+ ...n,
1029
+ layerId: this.getLayerId(n, { allowId: !1 }),
1030
+ pointId: r
1031
+ });
1032
+ return o.success && (this.removeCachedPoints([r]), this.syncStateFromResult(o)), o;
1033
+ }
1034
+ deletePoint(e, t = {}) {
1035
+ return this.removePoint(e, t);
1036
+ }
1037
+ removeById(e, t = {}) {
1038
+ return this.removePoint(e, t);
1039
+ }
1040
+ async removePoints(e = [], t = {}) {
1041
+ const s = this.resolveBaseGIS();
1042
+ if (!s.success)
1043
+ return s;
1044
+ const n = Array.isArray(e) ? e : [e];
1045
+ if (n.length === 0)
1046
+ return c("Point id list is required when removing points.", "INVALID_POINT_ID");
1047
+ const r = this.baseGIS.removePointLargePoints({
1048
+ ...t,
1049
+ layerId: this.getLayerId(t, { allowId: !1 }),
1050
+ pointIds: n
1051
+ });
1052
+ return r.success && (this.removeCachedPoints(n), this.syncStateFromResult(r)), r;
1053
+ }
1054
+ deletePoints(e = [], t = {}) {
1055
+ return this.removePoints(e, t);
1056
+ }
1057
+ removeByIds(e = [], t = {}) {
1058
+ return this.removePoints(e, t);
1059
+ }
1060
+ clear(e = {}) {
1061
+ const t = this.resolveBaseGIS();
1062
+ if (!t.success)
1063
+ return t;
1064
+ const s = this.baseGIS.clearPointLargeLayer({
1065
+ ...e,
1066
+ layerId: this.getLayerId(e)
1067
+ });
1068
+ return s.success && (this.currentPayload = this.currentPayload ? {
1069
+ ...this.currentPayload,
1070
+ points: [],
1071
+ data: [],
1072
+ items: []
1073
+ } : null, this.syncStateFromResult(s)), s;
1074
+ }
1075
+ refreshState(e = {}) {
1076
+ const t = this.resolveBaseGIS();
1077
+ if (!t.success)
1078
+ return t;
1079
+ const s = this.baseGIS.getPointLargeLayerState({
1080
+ ...e,
1081
+ layerId: this.getLayerId(e)
1082
+ });
1083
+ return s.success && this.syncStateFromResult(s), s;
1084
+ }
1085
+ /**
1086
+ * 销毁图层。
1087
+ * 如果地图已经先销毁,则只清理控制器本地状态,避免页面卸载时报错。
1088
+ */
1089
+ destroy(e = {}) {
1090
+ if (!this.resolveBaseGIS().success)
1091
+ return this.currentPayload = null, this.layerType = "unknown", this.currentState = {
1092
+ ...this.currentState,
1093
+ total: 0,
1094
+ renderedCount: 0,
1095
+ building: !1,
1096
+ destroyed: !0
1097
+ }, f(null, "Point large layer controller destroyed (local state only).");
1098
+ const s = this.baseGIS.removePointLargeLayer({
1099
+ ...e,
1100
+ layerId: this.getLayerId(e)
1101
+ });
1102
+ return this.currentPayload = null, this.layerType = "unknown", this.currentState = {
1103
+ ...this.currentState,
1104
+ total: 0,
1105
+ renderedCount: 0,
1106
+ building: !1,
1107
+ destroyed: !0
1108
+ }, s.success ? f(null, "Point large layer controller destroyed.") : s;
1109
+ }
1110
+ removeLayer(e = {}) {
1111
+ return this.destroy(e);
1112
+ }
1113
+ getState() {
1114
+ var e, t, s, n, r, o, a;
1115
+ if ((t = (e = this.baseGIS) == null ? void 0 : e.getMapInstance) != null && t.call(e) && this.currentPayload) {
1116
+ const l = (n = (s = this.baseGIS).getPointLargeLayerState) == null ? void 0 : n.call(s, {
1117
+ layerId: this.currentPayload.layerId || this.options.layerId
1118
+ });
1119
+ l != null && l.success && this.syncStateFromResult(l);
1120
+ }
1121
+ return {
1122
+ mounted: !!this.baseGIS,
1123
+ engineType: ((o = (r = this.baseGIS) == null ? void 0 : r.getEngineType) == null ? void 0 : o.call(r)) || "unknown",
1124
+ layerType: this.layerType,
1125
+ visible: this.visible,
1126
+ layerId: ((a = this.currentPayload) == null ? void 0 : a.layerId) || this.options.layerId,
1127
+ payload: this.currentPayload,
1128
+ ...this.currentState
1129
+ };
1130
+ }
1131
+ }
1132
+ function A() {
1133
+ return typeof window < "u" ? window.Cesium : null;
1134
+ }
1135
+ function fe(i) {
1136
+ let e = i;
1137
+ return e > 90 && (e -= 180), e < -90 && (e += 180), e;
1138
+ }
1139
+ function ge(i, e = 0) {
1140
+ return G.divIcon({
1141
+ className: "pressure-label-icon",
1142
+ html: `<span style="transform: translate(-50%, -50%) rotate(${fe(e)}deg)">${i}</span>`,
1143
+ iconSize: [0, 0],
1144
+ iconAnchor: [0, 0]
1145
+ });
1146
+ }
1147
+ function Ie(i) {
1148
+ return G.divIcon({
1149
+ className: `pressure-center-icon pressure-center-icon--${i.type.toLowerCase()}`,
1150
+ html: `<span class="pressure-center-icon__type">${i.type}</span><span class="pressure-center-icon__value">${i.value}</span>`,
1151
+ iconSize: [0, 0],
1152
+ iconAnchor: [0, 0]
1153
+ });
1154
+ }
1155
+ function U(i, e) {
1156
+ return i.some(
1157
+ (t) => !(e.right < t.left || e.left > t.right || e.bottom < t.top || e.top > t.bottom)
1158
+ );
1159
+ }
1160
+ function W(i, e, t) {
1161
+ return {
1162
+ left: i.x - e,
1163
+ right: i.x + e,
1164
+ top: i.y - t,
1165
+ bottom: i.y + t
1166
+ };
1167
+ }
1168
+ function Z(i, e, t = 18, s = 10) {
1169
+ i.sort((n, r) => n.score - r.score);
1170
+ for (let n = 0; n < i.length; n += 1) {
1171
+ const r = i[n], o = W(r.point, t, s);
1172
+ if (!U(e, o))
1173
+ return e.push(o), r;
1174
+ }
1175
+ return null;
1176
+ }
1177
+ function K(i = [], e = 0) {
1178
+ return e ? i.map((t) => [t[0], t[1] + e]) : i;
1179
+ }
1180
+ function me(i = [], e = 2) {
1181
+ if (i.length <= 2 || e <= 1)
1182
+ return i;
1183
+ const t = [];
1184
+ for (let n = 0; n < i.length; n += e)
1185
+ t.push(i[n]);
1186
+ const s = i[i.length - 1];
1187
+ return t[t.length - 1] !== s && t.push(s), t;
1188
+ }
1189
+ function be(i) {
1190
+ let e = Number(i);
1191
+ for (; e > 180; )
1192
+ e -= 360;
1193
+ for (; e < -180; )
1194
+ e += 360;
1195
+ return e;
1196
+ }
1197
+ function X(i) {
1198
+ return Math.round(Number(i) / 100);
1199
+ }
1200
+ function pe(i = [], e = 0) {
1201
+ const t = [];
1202
+ for (let s = 0; s < i.length - 1; s += 2) {
1203
+ const n = Number(i[s]), r = Number(i[s + 1]) + e;
1204
+ Number.isFinite(n) && Number.isFinite(r) && t.push([n, r]);
1205
+ }
1206
+ return t;
1207
+ }
1208
+ function Se(i, e, t, s, n) {
1209
+ const r = n * n, o = r * n;
1210
+ return [
1211
+ 0.5 * (2 * e[0] + (-i[0] + t[0]) * n + (2 * i[0] - 5 * e[0] + 4 * t[0] - s[0]) * r + (-i[0] + 3 * e[0] - 3 * t[0] + s[0]) * o),
1212
+ 0.5 * (2 * e[1] + (-i[1] + t[1]) * n + (2 * i[1] - 5 * e[1] + 4 * t[1] - s[1]) * r + (-i[1] + 3 * e[1] - 3 * t[1] + s[1]) * o)
1213
+ ];
1214
+ }
1215
+ function ve(i = [], e = 5) {
1216
+ if (i.length < 3)
1217
+ return i;
1218
+ const t = [i[0]];
1219
+ for (let s = 0; s < i.length - 1; s += 1) {
1220
+ const n = i[s - 1] || i[s], r = i[s], o = i[s + 1], a = i[s + 2] || o;
1221
+ for (let l = 1; l <= e; l += 1)
1222
+ t.push(Se(n, r, o, a, l / e));
1223
+ }
1224
+ return t;
1225
+ }
1226
+ function Ce(i = {}) {
1227
+ const e = (i.isoline || []).map((s) => {
1228
+ const n = Number(s.value);
1229
+ return {
1230
+ value: n,
1231
+ hpa: X(n),
1232
+ major: n % 800 === 0,
1233
+ lines: [ve(pe(s.points))].filter((r) => r.length > 1)
1234
+ };
1235
+ }), t = ["high", "low"].flatMap((s) => {
1236
+ const n = i[s] || {}, r = Array.isArray(n.value) ? n.value : [], o = Array.isArray(n.points) ? n.points : [], a = [];
1237
+ for (let l = 0; l < o.length - 1; l += 2)
1238
+ a.push({
1239
+ type: s === "high" ? "H" : "L",
1240
+ value: X(r[l / 2]),
1241
+ lat: Number(o[l]),
1242
+ lon: be(o[l + 1])
1243
+ });
1244
+ return a;
1245
+ });
1246
+ return {
1247
+ isolines: e,
1248
+ centers: t
1249
+ };
1250
+ }
1251
+ function Ve(i = {}) {
1252
+ const e = /* @__PURE__ */ new Map();
1253
+ return (t = "default") => {
1254
+ const s = t || "default";
1255
+ return e.has(s) || e.set(s, Ce(i[s] || i.default || {})), e.get(s);
1256
+ };
1257
+ }
1258
+ class Le {
1259
+ constructor(e = {}) {
1260
+ this.mapCore = e.mapCore, this.mapContainerId = e.mapContainerId, this.getData = e.getData, this.isVisible = e.isVisible, this.onStateChange = e.onStateChange, this.worldCopyOffsets = e.worldCopyOffsets || [-360, 0, 360], this.cesiumWorldCopyOffsets = e.cesiumWorldCopyOffsets || [0], this.cesiumLineThinStep = e.cesiumLineThinStep || 2, this.labelLayerGroup = null, this.cesiumLabelCollection = null, this.labelUpdateTimer = null, this.removeViewChangeListener = null;
1261
+ }
1262
+ // 当前引擎类型由 BaseGIS 决定,标注层只负责适配具体绘制方式。
1263
+ isCesiumEngine() {
1264
+ var e, t;
1265
+ return ((t = (e = this.mapCore) == null ? void 0 : e.getEngineType) == null ? void 0 : t.call(e)) === "cesium";
1266
+ }
1267
+ // Cesium 3D 模式需要判断地球背面遮挡,2D/哥伦布视图不做额外遮挡过滤。
1268
+ getCesiumSceneMode() {
1269
+ var t, s, n;
1270
+ const e = (s = (t = this.mapCore) == null ? void 0 : t.getMapInstance) == null ? void 0 : s.call(t);
1271
+ return (n = e == null ? void 0 : e.scene) == null ? void 0 : n.mode;
1272
+ }
1273
+ // 挂载标注层事件:Leaflet 监听地图事件,Cesium 走 BaseGIS 的视图变化回调。
1274
+ mount() {
1275
+ var t, s, n, r, o, a;
1276
+ if (this.isCesiumEngine()) {
1277
+ this.removeViewChangeListener = ((r = (n = (s = (t = this.mapCore) == null ? void 0 : t.onViewChange) == null ? void 0 : s.call(t, {
1278
+ onEnd: () => this.scheduleUpdate(),
1279
+ endDelay: 180
1280
+ })) == null ? void 0 : n.data) == null ? void 0 : r.off) || null;
1281
+ return;
1282
+ }
1283
+ const e = (a = (o = this.mapCore) == null ? void 0 : o.getMapInstance) == null ? void 0 : a.call(o);
1284
+ e && (this.labelLayerGroup = G.layerGroup().addTo(e), e.on("moveend zoomend resize", this.scheduleUpdate, this));
1285
+ }
1286
+ // 地图连续移动时只在下一帧刷新一次标签,减少重复碰撞计算。
1287
+ scheduleUpdate() {
1288
+ this.labelUpdateTimer && window.cancelAnimationFrame(this.labelUpdateTimer), this.labelUpdateTimer = window.requestAnimationFrame(() => {
1289
+ this.labelUpdateTimer = null, this.update();
1290
+ });
1291
+ }
1292
+ // 根据当前显隐状态和引擎类型刷新标注。
1293
+ update() {
1294
+ var e;
1295
+ return (e = this.isVisible) != null && e.call(this) ? this.isCesiumEngine() ? this.updateCesiumLabels() : this.updateLeafletLabels() : (this.clear(), 0);
1296
+ }
1297
+ // 清空当前标注,并同步标签数量为 0。
1298
+ clear() {
1299
+ var e;
1300
+ this.isCesiumEngine() ? this.clearCesiumLabelCollection() : (e = this.labelLayerGroup) == null || e.clearLayers(), this.emitStateChange(0);
1301
+ }
1302
+ // 销毁时移除地图事件、Cesium LabelCollection 和 Leaflet 图层组。
1303
+ destroy() {
1304
+ var t, s, n, r, o;
1305
+ this.labelUpdateTimer && (window.cancelAnimationFrame(this.labelUpdateTimer), this.labelUpdateTimer = null);
1306
+ const e = (s = (t = this.mapCore) == null ? void 0 : t.getMapInstance) == null ? void 0 : s.call(t);
1307
+ (n = e == null ? void 0 : e.off) == null || n.call(e, "moveend zoomend resize", this.scheduleUpdate, this), (r = this.removeViewChangeListener) == null || r.call(this), this.removeViewChangeListener = null, this.clearCesiumLabelCollection(!0), (o = this.labelLayerGroup) == null || o.remove(), this.labelLayerGroup = null;
1308
+ }
1309
+ // 把标签数量回传给页面状态面板。
1310
+ emitStateChange(e) {
1311
+ var t;
1312
+ (t = this.onStateChange) == null || t.call(this, {
1313
+ labelCount: e
1314
+ });
1315
+ }
1316
+ // Cesium 3D 球面下,屏幕外或地球背面的点不参与标签候选。
1317
+ isCesiumPointVisible(e) {
1318
+ var u, h, g, d, y, I;
1319
+ const t = (h = (u = this.mapCore) == null ? void 0 : u.getMapInstance) == null ? void 0 : h.call(u), s = A(), n = t == null ? void 0 : t.scene;
1320
+ if (!t || !s || !n)
1321
+ return !1;
1322
+ if (this.getCesiumSceneMode() !== s.SceneMode.SCENE3D)
1323
+ return !0;
1324
+ const r = ((g = n.globe) == null ? void 0 : g.ellipsoid) || ((d = n.mapProjection) == null ? void 0 : d.ellipsoid), o = ((y = n.camera) == null ? void 0 : y.positionWC) || ((I = n.camera) == null ? void 0 : I.position);
1325
+ if (!r || !o)
1326
+ return !0;
1327
+ const a = s.Cartesian3.fromDegrees(e[1], e[0], 0);
1328
+ return new s.EllipsoidalOccluder(r, o).isPointVisible(a);
1329
+ }
1330
+ // 标签候选点只在地图容器附近参与碰撞,防止屏幕外点影响布局。
1331
+ isCesiumScreenPointInViewport(e, t = 80) {
1332
+ const s = document.getElementById(this.mapContainerId), n = (s == null ? void 0 : s.clientWidth) || 0, r = (s == null ? void 0 : s.clientHeight) || 0;
1333
+ return !n || !r ? !0 : !(e.x < -t || e.y < -t || e.x > n + t || e.y > r + t);
1334
+ }
1335
+ // LabelCollection 比为每个标签创建 Entity 更轻量,适合动态重建。
1336
+ ensureCesiumLabelCollection() {
1337
+ var s, n, r;
1338
+ const e = (n = (s = this.mapCore) == null ? void 0 : s.getMapInstance) == null ? void 0 : n.call(s), t = A();
1339
+ return !((r = e == null ? void 0 : e.scene) != null && r.primitives) || !t ? null : (this.cesiumLabelCollection || (this.cesiumLabelCollection = e.scene.primitives.add(new t.LabelCollection())), this.cesiumLabelCollection);
1340
+ }
1341
+ // 数据更新和图层隐藏时清空标签;页面卸载时才销毁集合。
1342
+ clearCesiumLabelCollection(e = !1) {
1343
+ var s, n, r;
1344
+ const t = (n = (s = this.mapCore) == null ? void 0 : s.getMapInstance) == null ? void 0 : n.call(s);
1345
+ if (this.cesiumLabelCollection) {
1346
+ if (e && ((r = t == null ? void 0 : t.scene) != null && r.primitives)) {
1347
+ t.scene.primitives.remove(this.cesiumLabelCollection), this.cesiumLabelCollection = null;
1348
+ return;
1349
+ }
1350
+ this.cesiumLabelCollection.removeAll();
1351
+ }
1352
+ }
1353
+ // 页面数据统一是 [lat, lon],Cesium 创建坐标时需要 [lon, lat]。
1354
+ createCesiumPosition(e) {
1355
+ return A().Cartesian3.fromDegrees(e[1], e[0], 0);
1356
+ }
1357
+ // 将地理点投影到容器像素坐标,供标签碰撞避让使用。
1358
+ projectCesiumPoint(e) {
1359
+ var n, r;
1360
+ if (!this.isCesiumPointVisible(e))
1361
+ return null;
1362
+ const t = (r = (n = this.mapCore) == null ? void 0 : n.projectToContainerPoint) == null ? void 0 : r.call(n, {
1363
+ latitude: e[0],
1364
+ longitude: e[1]
1365
+ });
1366
+ if (!(t != null && t.success))
1367
+ return null;
1368
+ const s = G.point(t.data.x, t.data.y);
1369
+ return this.isCesiumScreenPointInViewport(s) ? s : null;
1370
+ }
1371
+ // Cesium 添加单个标签,中心点标签和线值标签共用该方法。
1372
+ addCesiumLabel(e, t, s = {}) {
1373
+ const n = A(), r = this.ensureCesiumLabelCollection();
1374
+ return !r || !n || !this.isCesiumPointVisible(e) ? null : r.add({
1375
+ position: this.createCesiumPosition(e),
1376
+ text: t,
1377
+ font: s.font || "12px Arial",
1378
+ fillColor: s.fillColor || n.Color.fromCssColorString("#244349"),
1379
+ outlineColor: n.Color.fromCssColorString("rgba(255,255,255,0.72)"),
1380
+ outlineWidth: s.outlineWidth ?? 2,
1381
+ style: n.LabelStyle.FILL_AND_OUTLINE,
1382
+ showBackground: s.showBackground !== !1,
1383
+ backgroundColor: s.backgroundColor || n.Color.fromCssColorString("rgba(246,251,231,0.92)"),
1384
+ backgroundPadding: s.backgroundPadding || new n.Cartesian2(7, 4),
1385
+ horizontalOrigin: n.HorizontalOrigin.CENTER,
1386
+ verticalOrigin: n.VerticalOrigin.CENTER,
1387
+ disableDepthTestDistance: s.disableDepthTestDistance ?? 0,
1388
+ scale: s.scale || 1
1389
+ });
1390
+ }
1391
+ // Cesium H/L 中心点标注,先做屏幕碰撞检测再绘制。
1392
+ addCesiumCenters(e, t) {
1393
+ const s = A();
1394
+ if (!s)
1395
+ return 0;
1396
+ let n = 0;
1397
+ return e.centers.forEach((r) => {
1398
+ this.cesiumWorldCopyOffsets.forEach((o) => {
1399
+ const a = [r.lat, r.lon + o], l = this.projectCesiumPoint(a);
1400
+ if (!l)
1401
+ return;
1402
+ const u = W(l, 18, 20);
1403
+ U(t, u) || (t.push(u), this.addCesiumLabel(a, `${r.type}
1404
+ ${r.value}`, {
1405
+ font: "700 18px Arial",
1406
+ fillColor: s.Color.fromCssColorString(r.type === "H" ? "#efb7ff" : "#e3f8ff"),
1407
+ backgroundColor: s.Color.TRANSPARENT,
1408
+ showBackground: !1,
1409
+ outlineWidth: 3
1410
+ }), n += 1);
1411
+ });
1412
+ }), n;
1413
+ }
1414
+ // Leaflet H/L 中心点标注,按当前视野过滤后再做碰撞检测。
1415
+ addLeafletCenters(e, t) {
1416
+ var o, a, l, u;
1417
+ const s = (a = (o = this.mapCore) == null ? void 0 : o.getMapInstance) == null ? void 0 : a.call(o), n = (u = (l = s == null ? void 0 : s.getBounds) == null ? void 0 : l.call(s)) == null ? void 0 : u.pad(0.2);
1418
+ if (!s || !n || !this.labelLayerGroup)
1419
+ return 0;
1420
+ let r = 0;
1421
+ return e.centers.forEach((h) => {
1422
+ this.worldCopyOffsets.forEach((g) => {
1423
+ const d = [h.lat, h.lon + g];
1424
+ if (!n.contains(d))
1425
+ return;
1426
+ const y = s.latLngToContainerPoint(d), I = W(y, 16, 18);
1427
+ U(t, I) || (t.push(I), G.marker(d, {
1428
+ interactive: !1,
1429
+ keyboard: !1,
1430
+ icon: Ie(h),
1431
+ zIndexOffset: 140
1432
+ }).addTo(this.labelLayerGroup), r += 1);
1433
+ });
1434
+ }), r;
1435
+ }
1436
+ // 线值标签统一从折线中采样候选点,再按离视野中心的距离排序。
1437
+ getLineLabelCandidates(e, t = {}) {
1438
+ const { bounds: s, useSegmentMidpoint: n = !1, viewCenter: r, projectPoint: o } = t, a = [], l = Math.max(Math.floor(e.length / 40), 1);
1439
+ for (let u = 0; u < e.length - 1; u += l) {
1440
+ const h = e[u], g = e[Math.min(u + l, e.length - 1)], d = [
1441
+ (h[0] + g[0]) / 2,
1442
+ (h[1] + g[1]) / 2
1443
+ ];
1444
+ if (s && !s.contains(d))
1445
+ continue;
1446
+ const y = o(h), I = o(g), m = o(d);
1447
+ if (!y || !I || !m)
1448
+ continue;
1449
+ const p = n ? G.point((y.x + I.x) / 2, (y.y + I.y) / 2) : m;
1450
+ a.push({
1451
+ position: d,
1452
+ point: p,
1453
+ angle: Math.atan2(I.y - y.y, I.x - y.x) * 180 / Math.PI,
1454
+ score: p.distanceTo(r)
1455
+ });
1456
+ }
1457
+ return a;
1458
+ }
1459
+ // Leaflet 线值标签:每条线选择靠近视野中心且不碰撞的位置。
1460
+ addLeafletLineLabels(e, t) {
1461
+ var a, l, u, h;
1462
+ const s = (l = (a = this.mapCore) == null ? void 0 : a.getMapInstance) == null ? void 0 : l.call(a), n = (h = (u = s == null ? void 0 : s.getBounds) == null ? void 0 : u.call(s)) == null ? void 0 : h.pad(0.15);
1463
+ if (!s || !n || !this.labelLayerGroup)
1464
+ return 0;
1465
+ const r = s.getSize().divideBy(2);
1466
+ let o = 0;
1467
+ return e.isolines.forEach((g) => {
1468
+ this.worldCopyOffsets.forEach((d) => {
1469
+ g.lines.forEach((y) => {
1470
+ const I = K(y, d), m = Z(this.getLineLabelCandidates(I, {
1471
+ bounds: n,
1472
+ useSegmentMidpoint: !0,
1473
+ viewCenter: r,
1474
+ projectPoint: (p) => s.latLngToContainerPoint(p)
1475
+ }), t);
1476
+ m && (G.marker(m.position, {
1477
+ interactive: !1,
1478
+ keyboard: !1,
1479
+ icon: ge(g.hpa, m.angle),
1480
+ zIndexOffset: 120
1481
+ }).addTo(this.labelLayerGroup), o += 1);
1482
+ });
1483
+ });
1484
+ }), o;
1485
+ }
1486
+ // Cesium 线值标签:先将候选点投影到屏幕,再按距离和碰撞筛选。
1487
+ addCesiumLineLabels(e, t) {
1488
+ let s = 0;
1489
+ const n = document.getElementById(this.mapContainerId), r = G.point(((n == null ? void 0 : n.clientWidth) || 0) / 2, ((n == null ? void 0 : n.clientHeight) || 0) / 2);
1490
+ return e.isolines.forEach((o) => {
1491
+ this.cesiumWorldCopyOffsets.forEach((a) => {
1492
+ o.lines.forEach((l) => {
1493
+ const u = me(K(l, a), this.cesiumLineThinStep), h = Z(this.getLineLabelCandidates(u, {
1494
+ viewCenter: r,
1495
+ projectPoint: (g) => this.projectCesiumPoint(g)
1496
+ }), t);
1497
+ h && (this.addCesiumLabel(h.position, String(o.hpa), {
1498
+ font: "12px Arial"
1499
+ }), s += 1);
1500
+ });
1501
+ });
1502
+ }), s;
1503
+ }
1504
+ // 重建 Cesium 全部标签,并请求场景刷新。
1505
+ updateCesiumLabels() {
1506
+ var a, l, u, h, g, d, y, I, m;
1507
+ const e = (l = (a = this.mapCore) == null ? void 0 : a.getMapInstance) == null ? void 0 : l.call(a), t = (u = this.getData) == null ? void 0 : u.call(this);
1508
+ if (!t)
1509
+ return this.clear(), 0;
1510
+ const s = this.cesiumLabelCollection;
1511
+ this.cesiumLabelCollection = null;
1512
+ const n = this.ensureCesiumLabelCollection();
1513
+ if (!n)
1514
+ return this.cesiumLabelCollection = s, 0;
1515
+ const r = [];
1516
+ let o = 0;
1517
+ try {
1518
+ o = this.addCesiumCenters(t, r) + this.addCesiumLineLabels(t, r), s && s !== n && ((h = e == null ? void 0 : e.scene) != null && h.primitives) && e.scene.primitives.remove(s);
1519
+ } catch (p) {
1520
+ throw (y = (d = (g = e == null ? void 0 : e.scene) == null ? void 0 : g.primitives) == null ? void 0 : d.remove) == null || y.call(d, n), this.cesiumLabelCollection = s, p;
1521
+ }
1522
+ return this.emitStateChange(o), (m = (I = e == null ? void 0 : e.scene) == null ? void 0 : I.requestRender) == null || m.call(I), o;
1523
+ }
1524
+ // 重建 Leaflet 全部标签和 marker。
1525
+ updateLeafletLabels() {
1526
+ var a, l, u;
1527
+ const e = (a = this.getData) == null ? void 0 : a.call(this), t = (u = (l = this.mapCore) == null ? void 0 : l.getMapInstance) == null ? void 0 : u.call(l);
1528
+ if (!e || !t || !this.labelLayerGroup)
1529
+ return this.clear(), 0;
1530
+ const s = this.labelLayerGroup, n = G.layerGroup();
1531
+ this.labelLayerGroup = n;
1532
+ const r = [];
1533
+ let o = 0;
1534
+ try {
1535
+ o = this.addLeafletCenters(e, r) + this.addLeafletLineLabels(e, r), n.addTo(t), s == null || s.remove();
1536
+ } catch (h) {
1537
+ throw n.remove(), this.labelLayerGroup = s, h;
1538
+ }
1539
+ return this.emitStateChange(o), o;
1540
+ }
1541
+ }
1542
+ class ze {
1543
+ constructor(e = {}) {
1544
+ this.mapCore = e.mapCore, this.contourController = new ne({
1545
+ mapCore: e.mapCore,
1546
+ layerId: e.layerId || "pressure-contour",
1547
+ color: e.color || "rgba(255,255,255,0.82)",
1548
+ weight: e.weight ?? 1.15,
1549
+ width: e.width ?? 1.15,
1550
+ opacity: e.opacity ?? 1,
1551
+ smoothFactor: e.smoothFactor ?? 0.2,
1552
+ lineJoin: e.lineJoin || "round",
1553
+ lineCap: e.lineCap || "round",
1554
+ worldCopyOffsets: e.worldCopyOffsets || [-360, 0, 360],
1555
+ lineThinStep: e.lineThinStep || 1,
1556
+ onStateChange: e.onContourStateChange
1557
+ }), this.annotationLayer = new Le({
1558
+ mapCore: e.mapCore,
1559
+ mapContainerId: e.mapContainerId,
1560
+ getData: e.getData,
1561
+ isVisible: e.isAnnotationVisible,
1562
+ worldCopyOffsets: e.worldCopyOffsets || [-360, 0, 360],
1563
+ cesiumWorldCopyOffsets: e.cesiumWorldCopyOffsets || [0],
1564
+ cesiumLineThinStep: e.cesiumLineThinStep || 2,
1565
+ onStateChange: e.onAnnotationStateChange
1566
+ });
1567
+ }
1568
+ mount() {
1569
+ this.annotationLayer.mount();
1570
+ }
1571
+ buildPayload(e, t = {}) {
1572
+ return {
1573
+ isolines: (e == null ? void 0 : e.isolines) || [],
1574
+ visible: t.visible !== !1,
1575
+ ...t
1576
+ };
1577
+ }
1578
+ async load(e, t = {}) {
1579
+ this.annotationLayer.clear();
1580
+ const s = await this.contourController.load(this.buildPayload(e, t));
1581
+ return s != null && s.success && this.annotationLayer.update(), s;
1582
+ }
1583
+ async update(e, t = {}) {
1584
+ const s = this.buildPayload(e, t), r = !!this.contourController.getState().payload ? await this.contourController.update(s) : await this.contourController.load(s);
1585
+ return r != null && r.success && this.annotationLayer.update(), r;
1586
+ }
1587
+ hide() {
1588
+ const e = this.contourController.hide();
1589
+ return this.annotationLayer.clear(), e;
1590
+ }
1591
+ updateAnnotations() {
1592
+ return this.annotationLayer.update();
1593
+ }
1594
+ scheduleAnnotationUpdate() {
1595
+ this.annotationLayer.scheduleUpdate();
1596
+ }
1597
+ clearAnnotations() {
1598
+ this.annotationLayer.clear();
1599
+ }
1600
+ getState() {
1601
+ return this.contourController.getState();
1602
+ }
1603
+ destroy() {
1604
+ this.annotationLayer.destroy(), this.contourController.destroy();
1605
+ }
1606
+ }
1607
+ class z {
1608
+ constructor(e = {}) {
1609
+ this.rawData = e, this.bound = Array.isArray(e.Bound) ? e.Bound : [], this.data = Array.isArray(e.DataAry) ? e.DataAry : [], this.valid = !1, this.errorMessage = "", this.lonMin = 0, this.latMin = 0, this.lonMax = 0, this.latMax = 0, this.lonCount = 0, this.latCount = 0, this.lonSpan = 0, this.latSpan = 0, this.lonStep = 0, this.latStep = 0, this.valueScale = 1, this.parse();
1610
+ }
1611
+ parse() {
1612
+ if (this.bound.length < 6) {
1613
+ this.errorMessage = "Wind field Bound must contain at least 6 values.";
1614
+ return;
1615
+ }
1616
+ const [e, t, s, n, r, o, a = 1] = this.bound, l = Number(s) * Number(n) * 2;
1617
+ if (!Number.isFinite(Number(e)) || !Number.isFinite(Number(t)) || Number(s) < 2 || Number(n) < 2 || Number(r) <= 0 || Number(o) <= 0 || this.data.length !== l) {
1618
+ this.errorMessage = `Invalid wind field data. Expected DataAry length ${l}, got ${this.data.length}.`;
1619
+ return;
1620
+ }
1621
+ this.lonMin = Number(e), this.latMin = Number(t), this.lonCount = Number(s), this.latCount = Number(n), this.lonSpan = Number(r), this.latSpan = Number(o), this.valueScale = Number(a) || 1, this.lonMax = this.lonMin + this.lonSpan, this.latMax = this.latMin + this.latSpan, this.lonStep = this.lonSpan / (this.lonCount - 1), this.latStep = this.latSpan / (this.latCount - 1), this.valid = !0;
1622
+ }
1623
+ contains(e, t) {
1624
+ return Number.isFinite(e) && Number.isFinite(t) && e >= this.lonMin && e <= this.lonMax && t >= this.latMin && t <= this.latMax;
1625
+ }
1626
+ getBounds() {
1627
+ return {
1628
+ west: this.lonMin,
1629
+ south: this.latMin,
1630
+ east: this.lonMax,
1631
+ north: this.latMax
1632
+ };
1633
+ }
1634
+ getCenter() {
1635
+ return {
1636
+ lon: this.lonMin + this.lonSpan / 2,
1637
+ lat: this.latMin + this.latSpan / 2
1638
+ };
1639
+ }
1640
+ getVector(e, t) {
1641
+ const s = (e * this.lonCount + t) * 2;
1642
+ return {
1643
+ u: Number(this.data[s]) / this.valueScale,
1644
+ v: Number(this.data[s + 1]) / this.valueScale
1645
+ };
1646
+ }
1647
+ /**
1648
+ * 双线性插值。
1649
+ *
1650
+ * 数据约定为从左下角开始平铺,因此 row 直接对应从南到北的纬度索引。
1651
+ */
1652
+ sample(e, t) {
1653
+ if (!this.valid || !this.contains(e, t))
1654
+ return null;
1655
+ const s = (e - this.lonMin) / this.lonStep, n = (t - this.latMin) / this.latStep, r = Math.max(0, Math.min(Math.floor(s), this.lonCount - 2)), o = Math.max(0, Math.min(Math.floor(n), this.latCount - 2)), a = r + 1, l = o + 1, u = Math.max(0, Math.min(s - r, 1)), h = Math.max(0, Math.min(n - o, 1)), g = this.getVector(o, r), d = this.getVector(o, a), y = this.getVector(l, r), I = this.getVector(l, a), m = 1 - u, p = 1 - h, v = m * p, C = u * p, L = m * h, N = u * h, T = g.u * v + d.u * C + y.u * L + I.u * N, M = g.v * v + d.v * C + y.v * L + I.v * N;
1656
+ return !Number.isFinite(T) || !Number.isFinite(M) ? null : {
1657
+ u: T,
1658
+ v: M,
1659
+ speed: Math.hypot(T, M)
1660
+ };
1661
+ }
1662
+ }
1663
+ const J = [
1664
+ { value: 0, color: [36, 88, 190] },
1665
+ { value: 2, color: [36, 145, 184] },
1666
+ { value: 5, color: [54, 177, 111] },
1667
+ { value: 8, color: [158, 198, 72] },
1668
+ { value: 11, color: [229, 178, 78] },
1669
+ { value: 14, color: [224, 103, 117] },
1670
+ { value: 18, color: [162, 82, 202] }
1671
+ ], Q = [
1672
+ { value: 0, color: [178, 223, 255] },
1673
+ { value: 3, color: [190, 248, 222] },
1674
+ { value: 6, color: [235, 252, 174] },
1675
+ { value: 10, color: [255, 222, 150] },
1676
+ { value: 14, color: [255, 166, 156] },
1677
+ { value: 18, color: [232, 153, 255] }
1678
+ ];
1679
+ function b(i, e, t) {
1680
+ return Math.min(Math.max(i, e), t);
1681
+ }
1682
+ function Pe(i) {
1683
+ if (Array.isArray(i) && i.length >= 3)
1684
+ return [Number(i[0]) || 0, Number(i[1]) || 0, Number(i[2]) || 0];
1685
+ if (typeof i != "string")
1686
+ return null;
1687
+ const e = i.trim().replace("#", "");
1688
+ if (/^[0-9a-f]{6}$/i.test(e))
1689
+ return [
1690
+ parseInt(e.slice(0, 2), 16),
1691
+ parseInt(e.slice(2, 4), 16),
1692
+ parseInt(e.slice(4, 6), 16)
1693
+ ];
1694
+ const t = i.match(/rgba?\(([^)]+)\)/i);
1695
+ if (!t)
1696
+ return null;
1697
+ const s = t[1].split(",").map((n) => Number(n.trim()));
1698
+ return s.length < 3 || s.slice(0, 3).some((n) => !Number.isFinite(n)) ? null : s.slice(0, 3);
1699
+ }
1700
+ function E(i, e) {
1701
+ const s = (Array.isArray(i) && i.length > 0 ? i : e).map((n, r) => {
1702
+ const o = Number((n == null ? void 0 : n.value) ?? (n == null ? void 0 : n.speed) ?? (n == null ? void 0 : n[0]) ?? r), a = Pe((n == null ? void 0 : n.color) ?? (n == null ? void 0 : n[1]) ?? n);
1703
+ return !Number.isFinite(o) || !a ? null : { value: o, color: a };
1704
+ }).filter(Boolean).sort((n, r) => n.value - r.value);
1705
+ return s.length > 0 ? s : e;
1706
+ }
1707
+ function we(i, e) {
1708
+ if (!Array.isArray(i) || i.length === 0)
1709
+ return [255, 255, 255];
1710
+ if (e <= i[0].value)
1711
+ return i[0].color;
1712
+ for (let t = 1; t < i.length; t += 1) {
1713
+ const s = i[t], n = i[t - 1];
1714
+ if (e <= s.value) {
1715
+ const r = Math.max(s.value - n.value, 1e-4), o = b((e - n.value) / r, 0, 1);
1716
+ return n.color.map(
1717
+ (a, l) => Math.round(a + (s.color[l] - a) * o)
1718
+ );
1719
+ }
1720
+ }
1721
+ return i[i.length - 1].color;
1722
+ }
1723
+ function _(i, e) {
1724
+ const [t, s, n] = i;
1725
+ return `rgba(${t}, ${s}, ${n}, ${b(e, 0, 1)})`;
1726
+ }
1727
+ function Ge(i, e) {
1728
+ if (!i || typeof i != "object")
1729
+ return e;
1730
+ const t = Number(i.west), s = Number(i.south), n = Number(i.east), r = Number(i.north);
1731
+ return [t, s, n, r].every(Number.isFinite) ? {
1732
+ west: Math.min(t, n),
1733
+ south: Math.min(s, r),
1734
+ east: Math.max(t, n),
1735
+ north: Math.max(s, r)
1736
+ } : e;
1737
+ }
1738
+ function Te(i, e) {
1739
+ const t = {
1740
+ west: Math.max(i.west, e.west),
1741
+ south: Math.max(i.south, e.south),
1742
+ east: Math.min(i.east, e.east),
1743
+ north: Math.min(i.north, e.north)
1744
+ };
1745
+ return t.west >= t.east || t.south >= t.north ? null : t;
1746
+ }
1747
+ function j(i, e, t) {
1748
+ return i && Number.isFinite(i.x) && Number.isFinite(i.y) && i.x >= -64 && i.x <= e + 64 && i.y >= -64 && i.y <= t + 64;
1749
+ }
1750
+ function Me(i) {
1751
+ return i && Number.isFinite(i.x) && Number.isFinite(i.y);
1752
+ }
1753
+ function xe(i) {
1754
+ return String(i || "").toLowerCase();
1755
+ }
1756
+ class Ne {
1757
+ constructor(e = {}) {
1758
+ this.id = e.id || "wind-field-default", this.container = e.container || null, this.project = typeof e.project == "function" ? e.project : null, this.getViewBounds = typeof e.getViewBounds == "function" ? e.getViewBounds : null, this.getSceneMode = typeof e.getSceneMode == "function" ? e.getSceneMode : null, this.grid = e.grid instanceof z ? e.grid : new z(e.data), this.options = {
1759
+ zIndex: Number(e.zIndex ?? 30),
1760
+ visible: e.visible !== !1,
1761
+ running: e.running !== !1,
1762
+ particleCount: Number(e.particleCount ?? 1400),
1763
+ maxFrameParticles: Number(e.maxFrameParticles ?? e.frameParticleLimit ?? 1200),
1764
+ sceneModeMaxFrameParticles: Number(e.sceneModeMaxFrameParticles ?? 0),
1765
+ maxAge: Number(e.maxAge ?? 58),
1766
+ frameRate: Number(e.frameRate ?? 30),
1767
+ velocityScale: Number(e.velocityScale ?? 900),
1768
+ lineWidth: Number(e.lineWidth ?? 0.85),
1769
+ color: e.color || "rgba(230, 248, 255, 0.52)",
1770
+ fadeOpacity: Number(e.fadeOpacity ?? 0.86),
1771
+ blendMode: e.blendMode || "lighter",
1772
+ particleOpacity: Number(e.particleOpacity ?? 0.58),
1773
+ velocityOverlay: e.velocityOverlay !== !1,
1774
+ velocityOverlayOpacity: Number(e.velocityOverlayOpacity ?? 0.22),
1775
+ velocityOverlayCellSize: Number(e.velocityOverlayCellSize ?? 54),
1776
+ velocityOverlayEdgeFade: Number(e.velocityOverlayEdgeFade ?? 0.12),
1777
+ height: Number(e.height ?? 0),
1778
+ devicePixelRatio: Number(e.devicePixelRatio ?? window.devicePixelRatio ?? 1),
1779
+ interactionResumeDelay: Number(e.interactionResumeDelay ?? 80),
1780
+ projectionGrid: e.projectionGrid !== !1,
1781
+ projectionGridCols: Number(e.projectionGridCols ?? 32),
1782
+ projectionGridRows: Number(e.projectionGridRows ?? 20)
1783
+ }, this.colorScale = E(e.colorScale, J), this.particleColorScale = E(
1784
+ e.particleColorScale,
1785
+ Q
1786
+ ), this.canvas = null, this.ctx = null, this.overlayCanvas = null, this.overlayCtx = null, this.particles = [], this.animationFrame = null, this.lastFrameTime = 0, this.destroyed = !1, this.width = 0, this.height = 0, this.resizeObserver = null, this.interactionSuspended = !1, this.runningBeforeInteraction = !1, this.overlayDirty = !0, this.spawnBoundsCache = null, this.resumeTimer = null, this.particleCursor = 0, this.projectionGrid = null, this.mount();
1787
+ }
1788
+ isReady() {
1789
+ return !!(this.container && this.project && this.grid.valid);
1790
+ }
1791
+ createCanvas(e, t) {
1792
+ const s = document.createElement("canvas");
1793
+ return s.className = e, s.style.position = "absolute", s.style.inset = "0", s.style.width = "100%", s.style.height = "100%", s.style.pointerEvents = "none", s.style.zIndex = String(t), s.style.display = this.options.visible ? "block" : "none", this.container.appendChild(s), s;
1794
+ }
1795
+ mount() {
1796
+ if (!this.container || this.canvas)
1797
+ return;
1798
+ window.getComputedStyle(this.container).position === "static" && (this.container.style.position = "relative"), this.overlayCanvas = this.createCanvas(
1799
+ "dt-gis-wind-field-canvas dt-gis-wind-field-canvas--overlay",
1800
+ this.options.zIndex
1801
+ ), this.overlayCtx = this.overlayCanvas.getContext("2d"), this.canvas = this.createCanvas(
1802
+ "dt-gis-wind-field-canvas dt-gis-wind-field-canvas--particle",
1803
+ this.options.zIndex + 1
1804
+ ), this.ctx = this.canvas.getContext("2d"), this.resizeObserver = new ResizeObserver(() => {
1805
+ this.resize(), this.reset();
1806
+ }), this.resizeObserver.observe(this.container), this.resize(), this.reset(), this.drawVelocityOverlay(), this.options.running && this.start();
1807
+ }
1808
+ resize() {
1809
+ if (!this.canvas || !this.overlayCanvas || !this.container)
1810
+ return;
1811
+ const e = this.container.getBoundingClientRect(), t = b(this.options.devicePixelRatio || 1, 1, 2), s = Math.max(1, Math.floor(e.width)), n = Math.max(1, Math.floor(e.height));
1812
+ s === this.width && n === this.height || (this.width = s, this.height = n, [
1813
+ [this.canvas, this.ctx],
1814
+ [this.overlayCanvas, this.overlayCtx]
1815
+ ].forEach(([r, o]) => {
1816
+ r.width = Math.floor(s * t), r.height = Math.floor(n * t), o == null || o.setTransform(t, 0, 0, t, 0, 0);
1817
+ }), this.overlayDirty = !0, this.invalidateProjectionGrid(), this.clear());
1818
+ }
1819
+ clear() {
1820
+ this.clearOverlay(), this.clearParticles();
1821
+ }
1822
+ clearOverlay() {
1823
+ this.overlayCtx && this.overlayCtx.clearRect(0, 0, this.width, this.height);
1824
+ }
1825
+ clearParticles() {
1826
+ this.ctx && this.ctx.clearRect(0, 0, this.width, this.height);
1827
+ }
1828
+ updateOptions(e = {}) {
1829
+ this.options = {
1830
+ ...this.options,
1831
+ ...e
1832
+ }, e.colorScale !== void 0 && (this.colorScale = E(e.colorScale, J), this.overlayDirty = !0), e.particleColorScale !== void 0 && (this.particleColorScale = E(
1833
+ e.particleColorScale,
1834
+ Q
1835
+ )), this.canvas && (this.canvas.style.zIndex = String(this.options.zIndex + 1), this.canvas.style.display = this.options.visible ? "block" : "none"), this.overlayCanvas && (this.overlayCanvas.style.zIndex = String(this.options.zIndex), this.overlayCanvas.style.display = this.options.visible ? "block" : "none"), e.data && (this.grid = new z(e.data), this.overlayDirty = !0, this.reset()), (e.particleCount !== void 0 || e.maxAge !== void 0 || e.velocityOverlay !== void 0 || e.velocityOverlayOpacity !== void 0 || e.velocityOverlayCellSize !== void 0 || e.velocityOverlayEdgeFade !== void 0 || e.projectionGrid !== void 0 || e.projectionGridCols !== void 0 || e.projectionGridRows !== void 0 || e.reset === !0) && (this.overlayDirty = !0, this.reset()), this.drawVelocityOverlay();
1836
+ }
1837
+ refreshSpawnBounds() {
1838
+ return this.spawnBoundsCache = this.getSpawnBounds(), this.invalidateProjectionGrid(), this.spawnBoundsCache;
1839
+ }
1840
+ shouldUseProjectionGrid() {
1841
+ var t;
1842
+ if (!this.options.projectionGrid)
1843
+ return !1;
1844
+ const e = xe((t = this.getSceneMode) == null ? void 0 : t.call(this));
1845
+ return e === "2d" || e === "2.5d";
1846
+ }
1847
+ invalidateProjectionGrid() {
1848
+ this.projectionGrid = null;
1849
+ }
1850
+ buildProjectionGrid(e = this.spawnBoundsCache) {
1851
+ if (!this.shouldUseProjectionGrid() || !e)
1852
+ return this.projectionGrid = null, null;
1853
+ const t = b(Math.floor(this.options.projectionGridCols) || 32, 8, 96), s = b(Math.floor(this.options.projectionGridRows) || 20, 6, 64), n = [];
1854
+ for (let r = 0; r <= s; r += 1)
1855
+ for (let o = 0; o <= t; o += 1) {
1856
+ const a = e.west + (e.east - e.west) * (o / t), l = e.south + (e.north - e.south) * (r / s);
1857
+ n.push(this.project(a, l, this.options.height));
1858
+ }
1859
+ return this.projectionGrid = {
1860
+ bounds: e,
1861
+ cols: t,
1862
+ rows: s,
1863
+ nodes: n
1864
+ }, this.projectionGrid;
1865
+ }
1866
+ projectPoint(e, t) {
1867
+ const s = this.projectionGrid || this.buildProjectionGrid(this.spawnBoundsCache);
1868
+ if (!s || !s.bounds)
1869
+ return this.project(e, t, this.options.height);
1870
+ const { bounds: n, cols: r, rows: o, nodes: a } = s, l = Math.max(n.east - n.west, 1e-4), u = Math.max(n.north - n.south, 1e-4), h = (e - n.west) / l * r, g = (t - n.south) / u * o, d = b(Math.floor(h), 0, r - 1), y = b(Math.floor(g), 0, o - 1), I = d + 1, m = y + 1, p = b(h - d, 0, 1), v = b(g - y, 0, 1), C = r + 1, L = a[y * C + d], N = a[y * C + I], T = a[m * C + d], M = a[m * C + I];
1871
+ if (![L, N, T, M].every(Me))
1872
+ return this.project(e, t, this.options.height);
1873
+ const R = 1 - p, F = 1 - v;
1874
+ return {
1875
+ x: L.x * R * F + N.x * p * F + T.x * R * v + M.x * p * v,
1876
+ y: L.y * R * F + N.y * p * F + T.y * R * v + M.y * p * v
1877
+ };
1878
+ }
1879
+ getSpawnBounds() {
1880
+ var s;
1881
+ const e = this.grid.getBounds(), t = Ge((s = this.getViewBounds) == null ? void 0 : s.call(this), e);
1882
+ return Te(e, t) || e;
1883
+ }
1884
+ createParticle(e = this.spawnBoundsCache || this.refreshSpawnBounds()) {
1885
+ if (!e)
1886
+ return {
1887
+ lon: 0,
1888
+ lat: 0,
1889
+ age: this.options.maxAge,
1890
+ maxAge: this.options.maxAge
1891
+ };
1892
+ for (let t = 0; t < 8; t += 1) {
1893
+ const s = e.west + Math.random() * (e.east - e.west), n = e.south + Math.random() * (e.north - e.south), r = this.grid.sample(s, n);
1894
+ if (r && r.speed > 0)
1895
+ return {
1896
+ lon: s,
1897
+ lat: n,
1898
+ screenX: null,
1899
+ screenY: null,
1900
+ age: Math.floor(Math.random() * this.options.maxAge),
1901
+ maxAge: this.options.maxAge + Math.floor(Math.random() * this.options.maxAge * 0.45)
1902
+ };
1903
+ }
1904
+ return {
1905
+ lon: e.west + Math.random() * (e.east - e.west),
1906
+ lat: e.south + Math.random() * (e.north - e.south),
1907
+ screenX: null,
1908
+ screenY: null,
1909
+ age: this.options.maxAge,
1910
+ maxAge: this.options.maxAge
1911
+ };
1912
+ }
1913
+ clearParticleScreenCache() {
1914
+ this.particles.forEach((e) => {
1915
+ e.screenX = null, e.screenY = null;
1916
+ });
1917
+ }
1918
+ reset() {
1919
+ if (!this.isReady())
1920
+ return;
1921
+ this.clear();
1922
+ const e = b(Math.floor(this.options.particleCount), 1, 8e3), t = this.refreshSpawnBounds();
1923
+ this.particles = Array.from({ length: e }, () => this.createParticle(t)), this.particleCursor = 0, this.overlayDirty = !0, this.drawVelocityOverlay();
1924
+ }
1925
+ getParticleColorIndex(e) {
1926
+ if (!Array.isArray(this.particleColorScale) || this.particleColorScale.length <= 1)
1927
+ return 0;
1928
+ for (let t = 1; t < this.particleColorScale.length; t += 1) {
1929
+ const s = this.particleColorScale[t - 1], n = this.particleColorScale[t], r = s.value + (n.value - s.value) / 2;
1930
+ if (e <= r)
1931
+ return t - 1;
1932
+ }
1933
+ return this.particleColorScale.length - 1;
1934
+ }
1935
+ drawVelocityOverlay() {
1936
+ if (!this.overlayDirty || !this.overlayCtx || !this.isReady() || (this.clearOverlay(), this.overlayDirty = !1, !this.options.velocityOverlay))
1937
+ return;
1938
+ const e = this.spawnBoundsCache || this.refreshSpawnBounds();
1939
+ if (!e)
1940
+ return;
1941
+ const t = this.overlayCtx, s = b(Number(this.options.velocityOverlayCellSize) || 54, 28, 96), n = b(Math.ceil(this.width / s), 10, 64), r = b(Math.ceil(this.height / s), 8, 48), o = (e.east - e.west) / n, a = (e.north - e.south) / r, l = s * 1.25, u = this.grid.getBounds();
1942
+ t.save(), t.globalCompositeOperation = "source-over";
1943
+ for (let h = 0; h < r; h += 1) {
1944
+ const g = e.south + (h + 0.5) * a;
1945
+ for (let d = 0; d < n; d += 1) {
1946
+ const y = e.west + (d + 0.5) * o, I = this.grid.sample(y, g);
1947
+ if (!I || I.speed <= 0)
1948
+ continue;
1949
+ const m = this.projectPoint(y, g);
1950
+ if (!j(m, this.width, this.height))
1951
+ continue;
1952
+ const p = we(this.colorScale, I.speed), v = this.getDataEdgeOpacity(y, g, u), C = this.options.velocityOverlayOpacity * v;
1953
+ if (C <= 0.01)
1954
+ continue;
1955
+ const L = t.createRadialGradient(m.x, m.y, 0, m.x, m.y, l);
1956
+ L.addColorStop(0, _(p, C)), L.addColorStop(1, _(p, 0)), t.fillStyle = L, t.fillRect(m.x - l, m.y - l, l * 2, l * 2);
1957
+ }
1958
+ }
1959
+ t.restore();
1960
+ }
1961
+ getDataEdgeOpacity(e, t, s) {
1962
+ const n = b(this.options.velocityOverlayEdgeFade, 0, 0.35);
1963
+ if (n <= 0 || !s)
1964
+ return 1;
1965
+ const r = (e - s.west) / Math.max(s.east - s.west, 1e-4), o = (t - s.south) / Math.max(s.north - s.south, 1e-4), a = Math.min(r, 1 - r, o, 1 - o);
1966
+ return b(a / n, 0, 1);
1967
+ }
1968
+ start() {
1969
+ this.destroyed || (this.options.running = !0, this.interactionSuspended = !1, this.animationFrame || (this.lastFrameTime = performance.now(), this.animationFrame = requestAnimationFrame((e) => this.animate(e))));
1970
+ }
1971
+ cancelAnimationFrameOnly() {
1972
+ this.animationFrame && (cancelAnimationFrame(this.animationFrame), this.animationFrame = null);
1973
+ }
1974
+ stop() {
1975
+ this.options.running = !1, this.cancelAnimationFrameOnly();
1976
+ }
1977
+ clearResumeTimer() {
1978
+ this.resumeTimer && (window.clearTimeout(this.resumeTimer), this.resumeTimer = null);
1979
+ }
1980
+ suspendForInteraction() {
1981
+ this.interactionSuspended || this.destroyed || (this.clearResumeTimer(), this.runningBeforeInteraction = this.options.running, this.interactionSuspended = !0, this.cancelAnimationFrameOnly(), this.clear());
1982
+ }
1983
+ resumeAfterInteraction() {
1984
+ this.destroyed || (this.resize(), this.clearParticles(), this.refreshSpawnBounds(), this.clearParticleScreenCache(), this.overlayDirty = !0, this.interactionSuspended = !1, this.clearResumeTimer(), this.resumeTimer = window.setTimeout(() => {
1985
+ this.resumeTimer = null, !(this.destroyed || this.interactionSuspended) && this.drawVelocityOverlay();
1986
+ }, Math.max(this.options.interactionResumeDelay, 0)), this.runningBeforeInteraction && this.start());
1987
+ }
1988
+ show() {
1989
+ this.options.visible = !0, this.canvas && (this.canvas.style.display = "block"), this.overlayCanvas && (this.overlayCanvas.style.display = "block"), this.drawVelocityOverlay(), this.options.running && this.start();
1990
+ }
1991
+ hide() {
1992
+ this.options.visible = !1, this.canvas && (this.canvas.style.display = "none"), this.overlayCanvas && (this.overlayCanvas.style.display = "none");
1993
+ }
1994
+ stepParticle(e, t) {
1995
+ const s = this.grid.sample(e.lon, e.lat), n = Number.isFinite(e.screenX) && Number.isFinite(e.screenY) ? { x: e.screenX, y: e.screenY } : this.projectPoint(e.lon, e.lat);
1996
+ if (!s || s.speed <= 0 || !j(n, this.width, this.height))
1997
+ return Object.assign(e, this.createParticle()), null;
1998
+ const r = e.lat * Math.PI / 180, o = Math.max(Math.cos(r) * 111320, 1e3), a = 111320, l = this.options.velocityScale * t, u = e.lon + s.u * l / o, h = e.lat + s.v * l / a, g = this.grid.sample(u, h), d = this.projectPoint(u, h);
1999
+ return !g || !j(d, this.width, this.height) ? (Object.assign(e, this.createParticle()), null) : (e.lon = u, e.lat = h, e.screenX = d.x, e.screenY = d.y, e.age += 1, e.age > e.maxAge && Object.assign(e, this.createParticle()), { from: n, to: d, speed: g.speed });
2000
+ }
2001
+ getFrameParticleCount(e) {
2002
+ var r;
2003
+ const t = b(
2004
+ Math.floor(this.options.maxFrameParticles || e),
2005
+ 1,
2006
+ e
2007
+ ), s = Math.floor(this.options.sceneModeMaxFrameParticles || 0), n = String(((r = this.getSceneMode) == null ? void 0 : r.call(this)) || "").toLowerCase();
2008
+ return (n === "2d" || n === "2.5d") && s > 0 ? b(s, 1, t) : t;
2009
+ }
2010
+ drawFrame(e) {
2011
+ if (!this.ctx || this.width <= 0 || this.height <= 0)
2012
+ return;
2013
+ const t = this.ctx;
2014
+ t.globalCompositeOperation = "destination-in", t.fillStyle = `rgba(0, 0, 0, ${b(this.options.fadeOpacity, 0.75, 0.98)})`, t.fillRect(0, 0, this.width, this.height), t.globalCompositeOperation = this.options.blendMode, t.lineCap = "round", t.lineJoin = "round";
2015
+ const s = this.particleColorScale.map(() => []), n = this.particles.length, r = this.getFrameParticleCount(n);
2016
+ for (let o = 0; o < r; o += 1) {
2017
+ const a = (this.particleCursor + o) % n, l = this.stepParticle(this.particles[a], e);
2018
+ l && s[this.getParticleColorIndex(l.speed)].push(l);
2019
+ }
2020
+ this.particleCursor = (this.particleCursor + r) % n, s.forEach((o, a) => {
2021
+ if (o.length === 0)
2022
+ return;
2023
+ const l = this.particleColorScale.length <= 1 ? 0 : a / (this.particleColorScale.length - 1);
2024
+ t.lineWidth = this.options.lineWidth * (0.72 + l * 0.56), t.strokeStyle = this.particleColorScale[a] ? _(this.particleColorScale[a].color, this.options.particleOpacity) : this.options.color, t.beginPath(), o.forEach((u) => {
2025
+ t.moveTo(u.from.x, u.from.y), t.lineTo(u.to.x, u.to.y);
2026
+ }), t.stroke();
2027
+ });
2028
+ }
2029
+ animate(e) {
2030
+ if (this.animationFrame = null, !(this.destroyed || !this.options.running || this.interactionSuspended)) {
2031
+ if (this.options.visible && this.isReady()) {
2032
+ const t = 1e3 / b(this.options.frameRate, 1, 60), s = e - this.lastFrameTime;
2033
+ if (s >= t) {
2034
+ const n = b(s / 16.67, 0.5, 2.5);
2035
+ this.lastFrameTime = e, this.drawFrame(n);
2036
+ }
2037
+ }
2038
+ this.animationFrame = requestAnimationFrame((t) => this.animate(t));
2039
+ }
2040
+ }
2041
+ getState() {
2042
+ return {
2043
+ id: this.id,
2044
+ valid: this.grid.valid,
2045
+ visible: this.options.visible,
2046
+ running: this.options.running,
2047
+ particleCount: this.particles.length,
2048
+ bounds: this.grid.getBounds(),
2049
+ center: this.grid.getCenter()
2050
+ };
2051
+ }
2052
+ destroy() {
2053
+ var e, t;
2054
+ this.stop(), this.destroyed = !0, this.clearResumeTimer(), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), (e = this.canvas) != null && e.parentNode && this.canvas.parentNode.removeChild(this.canvas), (t = this.overlayCanvas) != null && t.parentNode && this.overlayCanvas.parentNode.removeChild(this.overlayCanvas), this.clear(), this.canvas = null, this.ctx = null, this.overlayCanvas = null, this.overlayCtx = null, this.particles = [];
2055
+ }
2056
+ }
2057
+ function x(i = {}) {
2058
+ return typeof i == "string" ? i || "wind-field-default" : (i == null ? void 0 : i.id) || (i == null ? void 0 : i.layerId) || "wind-field-default";
2059
+ }
2060
+ function ee(i = {}) {
2061
+ const {
2062
+ id: e,
2063
+ layerId: t,
2064
+ data: s,
2065
+ windData: n,
2066
+ options: r,
2067
+ container: o,
2068
+ project: a,
2069
+ getViewBounds: l,
2070
+ ...u
2071
+ } = i || {};
2072
+ return {
2073
+ ...u,
2074
+ ...r || {}
2075
+ };
2076
+ }
2077
+ function te(i) {
2078
+ return !!(i && typeof i.getMapInstance == "function" && typeof i.getMapContainer == "function" && typeof i.projectToContainerPoint == "function" && typeof i.getViewBounds == "function" && typeof i.onViewChange == "function");
2079
+ }
2080
+ class _e {
2081
+ constructor(e = {}) {
2082
+ this.baseGIS = null, this.layers = /* @__PURE__ */ new Map();
2083
+ const t = (e == null ? void 0 : e.mapCore) || (e == null ? void 0 : e.baseGIS) || (te(e) ? e : null);
2084
+ t && this.mount(t);
2085
+ }
2086
+ mount(e) {
2087
+ var t, s;
2088
+ return te(e) ? (this.baseGIS = e, f(
2089
+ { engineType: ((s = (t = this.baseGIS).getEngineType) == null ? void 0 : s.call(t)) || "unknown" },
2090
+ "WindFieldMethods mounted with BaseGIS."
2091
+ )) : c("WindFieldMethods mount requires BaseGIS instance.", "INVALID_MOUNT_TARGET");
2092
+ }
2093
+ resolveBaseGIS() {
2094
+ var e, t;
2095
+ return this.baseGIS ? (t = (e = this.baseGIS).getMapInstance) != null && t.call(e) ? f(null, "BaseGIS is ready.") : c(
2096
+ "Map instance is not ready. Please call mapCore.init() first.",
2097
+ w.NOT_INITIALIZED
2098
+ ) : c("WindFieldMethods has not been mounted.", "NOT_MOUNTED");
2099
+ }
2100
+ addWindField(e = {}) {
2101
+ var l, u;
2102
+ const t = this.resolveBaseGIS();
2103
+ if (!t.success)
2104
+ return t;
2105
+ const s = (e == null ? void 0 : e.data) || (e == null ? void 0 : e.windData);
2106
+ if (!s)
2107
+ return c("Wind field data is required.", w.FAILED);
2108
+ const n = this.baseGIS.getMapContainer();
2109
+ if (!(n != null && n.success) || !((l = n.data) != null && l.container))
2110
+ return (n == null ? void 0 : n.success) === !1 ? n : c("Map container is not available.", w.NOT_INITIALIZED);
2111
+ const r = x(e);
2112
+ this.removeWindField(r);
2113
+ const o = new Ne({
2114
+ id: r,
2115
+ data: s,
2116
+ container: n.data.container,
2117
+ ...ee(e),
2118
+ project: (h, g, d = 0) => {
2119
+ const y = this.baseGIS.projectToContainerPoint({
2120
+ longitude: h,
2121
+ latitude: g,
2122
+ height: d
2123
+ });
2124
+ return y != null && y.success ? y.data : null;
2125
+ },
2126
+ getViewBounds: () => {
2127
+ const h = this.baseGIS.getViewBounds();
2128
+ return h != null && h.success ? h.data : null;
2129
+ },
2130
+ getSceneMode: () => {
2131
+ var g, d, y;
2132
+ const h = (d = (g = this.baseGIS).getSceneMode) == null ? void 0 : d.call(g);
2133
+ return h != null && h.success ? (y = h.data) == null ? void 0 : y.mode : "";
2134
+ }
2135
+ });
2136
+ if (!o.grid.valid)
2137
+ return o.destroy(), c(o.grid.errorMessage || "Invalid wind field data.", w.FAILED);
2138
+ const a = this.baseGIS.onViewChange({
2139
+ onStart: () => o.suspendForInteraction(),
2140
+ onEnd: () => o.resumeAfterInteraction()
2141
+ });
2142
+ return a != null && a.success ? (this.layers.set(r, {
2143
+ layer: o,
2144
+ offViewChange: (u = a.data) == null ? void 0 : u.off
2145
+ }), f(o.getState(), `Wind field "${r}" added.`)) : (o.destroy(), a || c("View change listener is not available."));
2146
+ }
2147
+ updateWindField(e = {}) {
2148
+ const t = this.resolveBaseGIS();
2149
+ if (!t.success)
2150
+ return t;
2151
+ const s = x(e), n = this.layers.get(s);
2152
+ if (!n)
2153
+ return c(`Wind field "${s}" not found.`, w.FAILED);
2154
+ const r = ee(e), o = (e == null ? void 0 : e.data) || (e == null ? void 0 : e.windData);
2155
+ return o && (r.data = o), n.layer.updateOptions(r), f(n.layer.getState(), `Wind field "${s}" updated.`);
2156
+ }
2157
+ startWindField(e = {}) {
2158
+ const t = x(e), s = this.layers.get(t);
2159
+ return s ? (s.layer.start(), f(s.layer.getState(), `Wind field "${t}" started.`)) : c(`Wind field "${t}" not found.`, w.FAILED);
2160
+ }
2161
+ stopWindField(e = {}) {
2162
+ const t = x(e), s = this.layers.get(t);
2163
+ return s ? (s.layer.stop(), f(s.layer.getState(), `Wind field "${t}" stopped.`)) : c(`Wind field "${t}" not found.`, w.FAILED);
2164
+ }
2165
+ showWindField(e = {}) {
2166
+ const t = x(e), s = this.layers.get(t);
2167
+ return s ? (s.layer.show(), f(s.layer.getState(), `Wind field "${t}" shown.`)) : c(`Wind field "${t}" not found.`, w.FAILED);
2168
+ }
2169
+ hideWindField(e = {}) {
2170
+ const t = x(e), s = this.layers.get(t);
2171
+ return s ? (s.layer.hide(), f(s.layer.getState(), `Wind field "${t}" hidden.`)) : c(`Wind field "${t}" not found.`, w.FAILED);
2172
+ }
2173
+ removeWindField(e = {}) {
2174
+ var n;
2175
+ const t = x(e), s = this.layers.get(t);
2176
+ return s ? ((n = s.offViewChange) == null || n.call(s), s.layer.destroy(), this.layers.delete(t), f({ layerId: t, removed: !0 }, `Wind field "${t}" removed.`)) : f({ layerId: t, removed: !1 }, `Wind field "${t}" not found.`);
2177
+ }
2178
+ clearWindFields() {
2179
+ const e = this.layers.size;
2180
+ return this.layers.forEach((t) => {
2181
+ var s;
2182
+ (s = t.offViewChange) == null || s.call(t), t.layer.destroy();
2183
+ }), this.layers.clear(), f({ count: e }, `Wind fields cleared: ${e}.`);
2184
+ }
2185
+ getState() {
2186
+ return {
2187
+ mounted: !!this.baseGIS,
2188
+ count: this.layers.size,
2189
+ layers: Array.from(this.layers.values()).map((e) => e.layer.getState())
2190
+ };
2191
+ }
2192
+ }
2193
+ export {
2194
+ ne as ContourLayerController,
2195
+ Be as GraphicGroupController,
2196
+ De as GridLayerController,
2197
+ Re as ImageLayerController,
2198
+ Fe as PointDensityController,
2199
+ Ee as PointLargeLayerController,
2200
+ ze as PressureContourLayer,
2201
+ _e as WindFieldMethods,
2202
+ Ce as buildPressureRenderData,
2203
+ Ve as createPressureDataResolver
2204
+ };