grid-webgl-openlayers 1.0.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,1208 @@
1
+ var at = Object.defineProperty;
2
+ var rt = (i, t, e) => t in i ? at(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
3
+ var l = (i, t, e) => rt(i, typeof t != "symbol" ? t + "" : t, e);
4
+ import Z from "ol/layer/Image";
5
+ import q from "ol/source/ImageCanvas";
6
+ import { transformExtent as Y, fromLonLat as st, toLonLat as ot } from "ol/proj";
7
+ const D = -9999;
8
+ function G(i) {
9
+ return 2 ** Math.max(0, Math.min(3, Math.floor((11 - i) / 2)));
10
+ }
11
+ function lt(i, t, e, n) {
12
+ const a = (i.startLat + i.endLat) * 0.5, r = i.lonStep * t;
13
+ if (n === "EPSG:3857") {
14
+ const s = 111320 * Math.cos(a * Math.PI / 180);
15
+ return r * s / Math.max(e, 1e-12);
16
+ }
17
+ return r / Math.max(e, 1e-12);
18
+ }
19
+ function K(i, t, e, n, a = "EPSG:4326") {
20
+ const r = G(t), s = lt(i, r, e, a), o = Math.max(1, Math.round(n / Math.max(s, 1)));
21
+ return r * o;
22
+ }
23
+ function Q(i, t, e, n, a) {
24
+ let r = 0, s = 0;
25
+ const { latCount: o, lonCount: d } = t;
26
+ for (let h = 0; h < a; h++)
27
+ for (let c = 0; c < a; c++) {
28
+ const g = e + h, u = n + c;
29
+ if (g >= o || u >= d) continue;
30
+ const p = i[g * d + u];
31
+ p == null || Number.isNaN(p) || (r += p, s++);
32
+ }
33
+ return s > 0 ? r / s : D;
34
+ }
35
+ function dt(i, t, e, n) {
36
+ const a = [
37
+ t.startLon,
38
+ t.startLat,
39
+ t.endLon,
40
+ t.endLat
41
+ ], [r, s, o, d] = e, [h, c, g, u] = a, p = Math.max(r, h), m = Math.max(s, c), x = Math.min(o, g), L = Math.min(d, u);
42
+ if (p >= x || m >= L) return null;
43
+ const { startLon: _, startLat: b, lonStep: M, latStep: y, lonCount: C, latCount: R } = t, f = G(n), E = Math.max(0, Math.floor((p - _) / M / f) * f), w = Math.min(C, Math.ceil((x - _) / M)), T = Math.max(0, Math.floor((m - b) / y / f) * f), v = Math.min(R, Math.ceil((L - b) / y));
44
+ if (E >= w || T >= v) return null;
45
+ const S = Math.ceil((w - E) / f), P = Math.ceil((v - T) / f), X = new Float32Array(S * P);
46
+ let it = 0;
47
+ for (let z = v - f; z >= T; z -= f)
48
+ for (let I = E; I < w; I += f)
49
+ X[it++] = Q(i, t, z, I, f);
50
+ return {
51
+ data: X,
52
+ width: S,
53
+ height: P,
54
+ bbox: [_ + E * M, b + T * y, _ + w * M, b + v * y],
55
+ resolution: [M * f, y * f],
56
+ lodLevel: Math.log2(f),
57
+ lodStep: f
58
+ };
59
+ }
60
+ function B(i, t, e, n, a, r, s, o = "EPSG:4326") {
61
+ const { startLon: d, startLat: h, lonStep: c, latStep: g, lonCount: u, latCount: p } = t, m = G(n), x = K(t, n, a, r, o), [L, _, b, M] = e, y = Math.max(0, Math.floor((L - d) / c / x) * x), C = Math.min(u, Math.ceil((b - d) / c)), R = Math.max(0, Math.floor((_ - h) / g / x) * x), f = Math.min(p, Math.ceil((M - h) / g));
62
+ if (y >= C || R >= f) return [];
63
+ const E = [];
64
+ for (let w = R; w < f; w += x)
65
+ for (let T = y; T < C; T += x) {
66
+ const v = Q(i, t, w, T, m);
67
+ if (v === D || Number.isNaN(v)) continue;
68
+ const S = d + (T + m * 0.5) * c, P = h + (w + m * 0.5) * g;
69
+ S < d || S >= t.endLon || P < h || P >= t.endLat || E.push({ lon: S, lat: P, text: v.toFixed(s) });
70
+ }
71
+ return E;
72
+ }
73
+ function ht(i, t, e) {
74
+ const n = new Float32Array(t * e);
75
+ for (let a = 0; a < t; a++)
76
+ for (let r = 0; r < e; r++)
77
+ n[a * e + r] = i[a][r];
78
+ return n;
79
+ }
80
+ function ct(i) {
81
+ let t = 1 / 0, e = -1 / 0;
82
+ for (const n of i)
83
+ n == null || Number.isNaN(n) || (n < t && (t = n), n > e && (e = n));
84
+ return { min: t, max: e };
85
+ }
86
+ function ut(i, t, e, n) {
87
+ const { startLon: a, startLat: r, lonStep: s, latStep: o, lonCount: d, latCount: h } = t, c = Math.floor((e - a) / s), g = Math.floor((n - r) / o);
88
+ if (c < 0 || g < 0 || c >= d || g >= h) return null;
89
+ const u = i[g * d + c];
90
+ return u == null || Number.isNaN(u) ? null : u;
91
+ }
92
+ class gt {
93
+ constructor() {
94
+ l(this, "worker");
95
+ l(this, "seq", 0);
96
+ l(this, "pending", /* @__PURE__ */ new Map());
97
+ this.worker = new Worker(new URL(
98
+ /* @vite-ignore */
99
+ "/assets/gridData.worker-z5TRvtQ2.js",
100
+ import.meta.url
101
+ ), { type: "module" }), this.worker.onmessage = (t) => {
102
+ const e = t.data, n = this.pending.get(e.id);
103
+ if (n) {
104
+ if (this.pending.delete(e.id), !e.ok) {
105
+ n.reject(new Error(e.error));
106
+ return;
107
+ }
108
+ n.resolve(e);
109
+ }
110
+ }, this.worker.onerror = () => {
111
+ this.pending.forEach(({ reject: t }) => t(new Error("worker error"))), this.pending.clear();
112
+ };
113
+ }
114
+ init(t, e) {
115
+ const n = ++this.seq;
116
+ return new Promise((a, r) => {
117
+ this.pending.set(n, { resolve: a, reject: r }), this.worker.postMessage({ type: "init", meta: t, flat: e, id: n }, [e.buffer]);
118
+ }).then(() => {
119
+ });
120
+ }
121
+ call(t) {
122
+ const e = ++this.seq;
123
+ return new Promise((n, a) => {
124
+ this.pending.set(e, { resolve: n, reject: a }), this.worker.postMessage({ ...t, id: e });
125
+ });
126
+ }
127
+ readWindow(t, e) {
128
+ return this.call({
129
+ type: "readWindow",
130
+ extent4326: t,
131
+ zoom: e
132
+ }).then((n) => n.tile).catch(() => null);
133
+ }
134
+ computeLabels(t, e, n, a, r, s = "EPSG:4326") {
135
+ return this.call({
136
+ type: "computeLabels",
137
+ extent4326: t,
138
+ zoom: e,
139
+ resolution: n,
140
+ distancePx: a,
141
+ precision: r,
142
+ projCode: s
143
+ }).then((o) => o.labels).catch(() => []);
144
+ }
145
+ terminate() {
146
+ this.worker.terminate();
147
+ }
148
+ }
149
+ class pt {
150
+ constructor() {
151
+ l(this, "meta");
152
+ l(this, "flat");
153
+ l(this, "loaded", !1);
154
+ l(this, "worker", new gt());
155
+ l(this, "lastExtent", null);
156
+ l(this, "lastZoom", -1);
157
+ l(this, "cachedTile", null);
158
+ l(this, "tileRequestId", 0);
159
+ }
160
+ get bbox() {
161
+ return [this.meta.startLon, this.meta.startLat, this.meta.endLon, this.meta.endLat];
162
+ }
163
+ get metadata() {
164
+ return { ...this.meta, nodata: D, bbox: this.bbox };
165
+ }
166
+ get isLoaded() {
167
+ return this.loaded;
168
+ }
169
+ async load(t) {
170
+ const e = await fetch(t).then((n) => n.json());
171
+ await this.loadData(e);
172
+ }
173
+ /** 直接加载 JSON 对象(Vue / Node 传入内存数据时使用) */
174
+ async loadData(t) {
175
+ this.meta = {
176
+ startLat: t.startLat,
177
+ endLat: t.endLat,
178
+ startLon: t.startLon,
179
+ endLon: t.endLon,
180
+ latStep: t.latStep,
181
+ lonStep: t.lonStep,
182
+ latCount: t.latCount,
183
+ lonCount: t.lonCount
184
+ }, this.flat = ht(t.ds, this.meta.latCount, this.meta.lonCount), await this.worker.init(this.meta, this.flat.slice()), this.loaded = !0;
185
+ }
186
+ getLodStep(t) {
187
+ return G(t);
188
+ }
189
+ getLabelStep(t, e, n, a = "EPSG:4326") {
190
+ return K(this.meta, t, e, n, a);
191
+ }
192
+ /** 异步 readWindow(Worker) */
193
+ async readWindowAsync(t, e) {
194
+ if (!this.loaded) return null;
195
+ if (this.cachedTile && this.lastZoom === e && this.lastExtent && O(this.lastExtent, t))
196
+ return this.cachedTile;
197
+ const n = ++this.tileRequestId, a = await this.worker.readWindow(t, e);
198
+ return n !== this.tileRequestId ? this.cachedTile : (a && (this.lastExtent = [...t], this.lastZoom = e, this.cachedTile = a), a);
199
+ }
200
+ /** 同步 readWindow(Worker 未就绪时 fallback) */
201
+ readWindow(t, e) {
202
+ if (!this.loaded) return null;
203
+ if (this.cachedTile && this.lastZoom === e && this.lastExtent && O(this.lastExtent, t))
204
+ return this.cachedTile;
205
+ const n = dt(this.flat, this.meta, t, e);
206
+ return n && (this.lastExtent = [...t], this.lastZoom = e, this.cachedTile = n), n;
207
+ }
208
+ async computeLabelsAsync(t, e, n, a, r, s = "EPSG:4326") {
209
+ if (!this.loaded) return [];
210
+ try {
211
+ const o = await this.worker.computeLabels(
212
+ t,
213
+ e,
214
+ n,
215
+ a,
216
+ r,
217
+ s
218
+ );
219
+ if (o.length > 0) return o;
220
+ } catch {
221
+ }
222
+ return B(this.flat, this.meta, t, e, n, a, r, s);
223
+ }
224
+ computeLabelsSync(t, e, n, a, r, s = "EPSG:4326") {
225
+ return this.loaded ? B(this.flat, this.meta, t, e, n, a, r, s) : [];
226
+ }
227
+ getValueAt(t, e, n) {
228
+ const a = n ?? this.cachedTile;
229
+ if (!a) return null;
230
+ const [r, s, o, d] = a.bbox;
231
+ if (t < r || t > o || e < s || e > d) return null;
232
+ const [h, c] = a.resolution, g = Math.floor((t - r) / h), u = Math.floor((d - e) / c);
233
+ if (g < 0 || u < 0 || g >= a.width || u >= a.height) return null;
234
+ const p = a.data[u * a.width + g];
235
+ return p === D || Number.isNaN(p) ? null : p;
236
+ }
237
+ getNativeValueAt(t, e) {
238
+ return ut(this.flat, this.meta, t, e);
239
+ }
240
+ computeStats() {
241
+ return ct(this.flat);
242
+ }
243
+ get nativeResolution() {
244
+ return [this.meta.lonStep, this.meta.latStep];
245
+ }
246
+ get gridOrigin() {
247
+ return [this.meta.startLon, this.meta.startLat];
248
+ }
249
+ invalidateCache() {
250
+ this.cachedTile = null, this.lastExtent = null, this.tileRequestId++;
251
+ }
252
+ dispose() {
253
+ this.worker.terminate();
254
+ }
255
+ }
256
+ function O(i, t, e = 1e-6) {
257
+ return i.length === t.length && i.every((n, a) => Math.abs(n - t[a]) < e);
258
+ }
259
+ const mt = `#version 300 es
260
+ in vec2 a_position;
261
+ out vec2 v_uv;
262
+ void main() {
263
+ v_uv = a_position * 0.5 + 0.5;
264
+ gl_Position = vec4(a_position, 0.0, 1.0);
265
+ }
266
+ `, ft = `#version 300 es
267
+ precision highp float;
268
+
269
+ in vec2 v_uv;
270
+ out vec4 fragColor;
271
+
272
+ uniform sampler2D u_data;
273
+ uniform sampler2D u_legend;
274
+ uniform mat3 u_transform;
275
+ uniform vec2 u_size;
276
+ uniform vec2 u_delta;
277
+ uniform float u_pixel_ratio;
278
+ uniform vec4 u_data_bbox; // minLon, minLat, maxLon, maxLat
279
+ uniform vec2 u_cell_size; // LOD lonStep, latStep(数据采样)
280
+ uniform vec2 u_native_cell_size; // 原始格距
281
+ uniform vec2 u_grid_origin; // startLon, startLat
282
+ uniform vec2 u_data_size; // cols, rows
283
+ uniform vec2 u_legend_meta; // min, max
284
+ uniform vec2 u_display_range; // 显示区间 [min, max],区间外格点隐藏
285
+ uniform float u_nodata;
286
+ uniform float u_opacity;
287
+ uniform float u_show_grid;
288
+ uniform float u_grid_lod;
289
+ uniform float u_proj_mercator; // 1 = EPSG:3857
290
+
291
+ vec2 mapCoordToLonLat(vec2 mapCoord) {
292
+ if (u_proj_mercator < 0.5) return mapCoord;
293
+ const float MAX_EXT = 20037508.342789244;
294
+ float lon = mapCoord.x / MAX_EXT * 180.0;
295
+ float lat = atan(exp(mapCoord.y / MAX_EXT * 3.141592653589793)) * 360.0 / 3.141592653589793 - 90.0;
296
+ return vec2(lon, lat);
297
+ }
298
+
299
+ vec2 getLonLat(vec2 uv) {
300
+ vec2 xy = (vec2(uv.x, 1.0 - uv.y) * u_size) / u_pixel_ratio - u_delta;
301
+ float projX = u_transform[0][0] * xy.x + u_transform[1][0] * xy.y + u_transform[2][0];
302
+ float projY = u_transform[0][1] * xy.x + u_transform[1][1] * xy.y + u_transform[2][1];
303
+ return mapCoordToLonLat(vec2(projX, projY));
304
+ }
305
+
306
+ vec4 lookupLegend(float value) {
307
+ float t = clamp((value - u_legend_meta.x) / (u_legend_meta.y - u_legend_meta.x), 0.0, 1.0);
308
+ return texture(u_legend, vec2(t, 0.5));
309
+ }
310
+
311
+ float gridLineFactor(vec2 lonlat, vec2 cellSize, vec4 dataBbox) {
312
+ if (u_show_grid < 0.5) return 0.0;
313
+ float fx = fract((lonlat.x - dataBbox.x) / cellSize.x);
314
+ float fy = fract((lonlat.y - dataBbox.y) / cellSize.y);
315
+ float edge = min(min(fx, 1.0 - fx), min(fy, 1.0 - fy));
316
+ float pxLon = cellSize.x / (u_data_bbox.z - u_data_bbox.x) * u_size.x / u_pixel_ratio;
317
+ float pxLat = cellSize.y / (u_data_bbox.w - u_data_bbox.y) * u_size.y / u_pixel_ratio;
318
+ float threshold = 1.0 / min(pxLon, pxLat);
319
+ return 1.0 - smoothstep(0.0, threshold, edge);
320
+ }
321
+
322
+ void main() {
323
+ vec2 lonlat = getLonLat(v_uv);
324
+
325
+ if (lonlat.x < u_data_bbox.x || lonlat.x > u_data_bbox.z ||
326
+ lonlat.y < u_data_bbox.y || lonlat.y > u_data_bbox.w) {
327
+ discard;
328
+ }
329
+
330
+ float col = floor((lonlat.x - u_data_bbox.x) / u_cell_size.x);
331
+ float row = floor((u_data_bbox.w - lonlat.y) / u_cell_size.y);
332
+ col = clamp(col, 0.0, u_data_size.x - 1.0);
333
+ row = clamp(row, 0.0, u_data_size.y - 1.0);
334
+
335
+ vec2 texCoord = (vec2(col + 0.5, row + 0.5)) / u_data_size;
336
+ float v = texture(u_data, texCoord).r;
337
+
338
+ if (isnan(v) || abs(v - u_nodata) < 0.001) {
339
+ discard;
340
+ }
341
+
342
+ if (v < u_display_range.x || v > u_display_range.y) {
343
+ discard;
344
+ }
345
+
346
+ vec4 color = lookupLegend(v);
347
+ if (color.a < 0.02) {
348
+ discard;
349
+ }
350
+
351
+ float grid = gridLineFactor(lonlat, u_cell_size, u_data_bbox);
352
+ vec3 rgb = mix(color.rgb, vec3(0.15, 0.15, 0.15), grid * 0.55);
353
+ fragColor = vec4(rgb, color.a * u_opacity);
354
+ }
355
+ `;
356
+ function $(i, t, e) {
357
+ const n = i.createShader(t);
358
+ if (i.shaderSource(n, e), i.compileShader(n), !i.getShaderParameter(n, i.COMPILE_STATUS))
359
+ throw new Error(i.getShaderInfoLog(n) ?? "shader compile error");
360
+ return n;
361
+ }
362
+ function xt(i, t, e) {
363
+ const n = i.createProgram();
364
+ if (i.attachShader(n, $(i, i.VERTEX_SHADER, t)), i.attachShader(n, $(i, i.FRAGMENT_SHADER, e)), i.linkProgram(n), !i.getProgramParameter(n, i.LINK_STATUS))
365
+ throw new Error(i.getProgramInfoLog(n) ?? "program link error");
366
+ return n;
367
+ }
368
+ class _t {
369
+ constructor(t) {
370
+ l(this, "gl");
371
+ l(this, "program");
372
+ l(this, "vao");
373
+ l(this, "dataTexture", null);
374
+ l(this, "legend", null);
375
+ l(this, "lastTileKey", "");
376
+ l(this, "loc", {});
377
+ const e = t.getContext("webgl2", {
378
+ alpha: !0,
379
+ antialias: !1,
380
+ preserveDrawingBuffer: !1
381
+ });
382
+ if (!e) throw new Error("WebGL2 not supported");
383
+ this.gl = e, this.program = xt(e, mt, ft), this.vao = this.initQuad();
384
+ for (const n of [
385
+ "u_data",
386
+ "u_legend",
387
+ "u_transform",
388
+ "u_size",
389
+ "u_delta",
390
+ "u_pixel_ratio",
391
+ "u_data_bbox",
392
+ "u_cell_size",
393
+ "u_native_cell_size",
394
+ "u_grid_origin",
395
+ "u_data_size",
396
+ "u_legend_meta",
397
+ "u_display_range",
398
+ "u_nodata",
399
+ "u_opacity",
400
+ "u_show_grid",
401
+ "u_grid_lod",
402
+ "u_proj_mercator"
403
+ ])
404
+ this.loc[n] = e.getUniformLocation(this.program, n);
405
+ }
406
+ initQuad() {
407
+ const t = this.gl, e = t.createVertexArray();
408
+ t.bindVertexArray(e);
409
+ const n = t.createBuffer();
410
+ t.bindBuffer(t.ARRAY_BUFFER, n), t.bufferData(t.ARRAY_BUFFER, new Float32Array([-1, 1, -1, -1, 1, 1, 1, -1]), t.STATIC_DRAW);
411
+ const a = t.getAttribLocation(this.program, "a_position");
412
+ return t.enableVertexAttribArray(a), t.vertexAttribPointer(a, 2, t.FLOAT, !1, 0, 0), t.bindVertexArray(null), e;
413
+ }
414
+ resize(t, e) {
415
+ const n = this.gl;
416
+ n.canvas.width = Math.max(1, Math.floor(t)), n.canvas.height = Math.max(1, Math.floor(e)), n.viewport(0, 0, n.canvas.width, n.canvas.height);
417
+ }
418
+ setLegend(t) {
419
+ this.legend = t;
420
+ }
421
+ uploadTile(t) {
422
+ const e = `${t.width}x${t.height}-${t.lodStep}-${t.bbox.join(",")}`;
423
+ if (e === this.lastTileKey && this.dataTexture) return;
424
+ const n = this.gl;
425
+ this.dataTexture || (this.dataTexture = n.createTexture()), n.bindTexture(n.TEXTURE_2D, this.dataTexture), n.texImage2D(n.TEXTURE_2D, 0, n.R32F, t.width, t.height, 0, n.RED, n.FLOAT, t.data), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, n.NEAREST), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, n.NEAREST), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, n.CLAMP_TO_EDGE), this.lastTileKey = e;
426
+ }
427
+ render(t, e) {
428
+ if (!this.dataTexture || !this.legend) return;
429
+ const n = this.gl;
430
+ n.clearColor(0, 0, 0, 0), n.clear(n.COLOR_BUFFER_BIT), n.enable(n.BLEND), n.blendFunc(n.SRC_ALPHA, n.ONE_MINUS_SRC_ALPHA), n.useProgram(this.program), n.bindVertexArray(this.vao), n.activeTexture(n.TEXTURE0), n.bindTexture(n.TEXTURE_2D, this.dataTexture), n.uniform1i(this.loc.u_data, 0), n.activeTexture(n.TEXTURE1), n.bindTexture(n.TEXTURE_2D, this.legend.texture), n.uniform1i(this.loc.u_legend, 1);
431
+ const [a, r, s, o] = t.bbox, [d, h] = t.resolution;
432
+ n.uniformMatrix3fv(this.loc.u_transform, !1, e.transform), n.uniform2f(this.loc.u_size, e.size[0], e.size[1]), n.uniform2f(this.loc.u_delta, e.delta[0], e.delta[1]), n.uniform1f(this.loc.u_pixel_ratio, e.pixelRatio), n.uniform4f(this.loc.u_data_bbox, a, r, s, o), n.uniform2f(this.loc.u_cell_size, d, h), n.uniform2f(this.loc.u_native_cell_size, e.nativeCellSize[0], e.nativeCellSize[1]), n.uniform2f(this.loc.u_grid_origin, e.gridOrigin[0], e.gridOrigin[1]), n.uniform2f(this.loc.u_data_size, t.width, t.height), n.uniform2f(this.loc.u_legend_meta, this.legend.min, this.legend.max), n.uniform2f(this.loc.u_display_range, e.displayRange[0], e.displayRange[1]), n.uniform1f(this.loc.u_nodata, -9999), n.uniform1f(this.loc.u_opacity, e.opacity), n.uniform1f(this.loc.u_show_grid, e.showGrid ? 1 : 0), n.uniform1f(this.loc.u_grid_lod, e.gridLod), n.uniform1f(this.loc.u_proj_mercator, e.projMercator ? 1 : 0), n.drawArrays(n.TRIANGLE_STRIP, 0, 4), n.bindVertexArray(null);
433
+ }
434
+ dispose() {
435
+ const t = this.gl;
436
+ this.dataTexture && t.deleteTexture(this.dataTexture), this.legend && t.deleteTexture(this.legend.texture), t.deleteProgram(this.program), t.deleteVertexArray(this.vao);
437
+ }
438
+ }
439
+ function bt(i) {
440
+ return new Float32Array([i[0], i[1], 0, i[2], i[3], 0, i[4], i[5], 1]);
441
+ }
442
+ function Lt(i, t, e) {
443
+ return [
444
+ (i[0] - t[0]) / e,
445
+ (t[3] - i[3]) / e
446
+ ];
447
+ }
448
+ const k = 256;
449
+ function J(i) {
450
+ if (i.length === 9) {
451
+ const e = parseInt(i.slice(1, 7), 16), n = parseInt(i.slice(7, 9), 16);
452
+ return [e >> 16 & 255, e >> 8 & 255, e & 255, n];
453
+ }
454
+ const t = parseInt(i.slice(1), 16);
455
+ return [t >> 16 & 255, t >> 8 & 255, t & 255, 255];
456
+ }
457
+ function yt(i, t, e) {
458
+ return [
459
+ Math.round(i[0] + (t[0] - i[0]) * e),
460
+ Math.round(i[1] + (t[1] - i[1]) * e),
461
+ Math.round(i[2] + (t[2] - i[2]) * e),
462
+ Math.round(i[3] + (t[3] - i[3]) * e)
463
+ ];
464
+ }
465
+ function Mt(i, t) {
466
+ if (t <= i[0][0]) return i[0][1];
467
+ if (t >= i[i.length - 1][0]) return i[i.length - 1][1];
468
+ for (let e = 0; e < i.length - 1; e++) {
469
+ const [n, a] = i[e], [r, s] = i[e + 1];
470
+ if (t >= n && t <= r) {
471
+ const o = r === n ? 0 : (t - n) / (r - n);
472
+ return yt(a, s, o);
473
+ }
474
+ }
475
+ return i[i.length - 1][1];
476
+ }
477
+ function j(i, t) {
478
+ const e = t.filter(([d]) => d > -9e3 && d < 9e3), n = e[0][0], a = e[e.length - 1][0], r = Math.max(a - n, 0.01), s = new Uint8Array(k * 4);
479
+ for (let d = 0; d < k; d++) {
480
+ const h = n + r * d / (k - 1);
481
+ s.set(Mt(e, h), d * 4);
482
+ }
483
+ const o = i.createTexture();
484
+ return i.bindTexture(i.TEXTURE_2D, o), i.texImage2D(i.TEXTURE_2D, 0, i.RGBA, k, 1, 0, i.RGBA, i.UNSIGNED_BYTE, s), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), { texture: o, min: n, max: a, width: k };
485
+ }
486
+ function A(i, t) {
487
+ const e = Math.max(t - i, 0.01), n = (r) => i + e * r, a = [
488
+ [i, "#e8f5e9"],
489
+ [n(0.08), "#c8e6c9"],
490
+ [n(0.2), "#a5d6a7"],
491
+ [n(0.35), "#66bb6a"],
492
+ [n(0.55), "#43a047"],
493
+ [n(0.75), "#2e7d32"],
494
+ [t, "#1b5e20"]
495
+ ];
496
+ return [
497
+ [-9999, [0, 0, 0, 0]],
498
+ ...a.map(([r, s]) => [r, J(s)]),
499
+ [9999, [0, 0, 0, 0]]
500
+ ];
501
+ }
502
+ function $t(i, t) {
503
+ const e = [
504
+ [i, "#313695"],
505
+ [i + (t - i) * 0.15, "#4575b4"],
506
+ [i + (t - i) * 0.3, "#74add1"],
507
+ [i + (t - i) * 0.45, "#abd9e9"],
508
+ [i + (t - i) * 0.55, "#fee090"],
509
+ [i + (t - i) * 0.7, "#fdae61"],
510
+ [i + (t - i) * 0.85, "#f46d43"],
511
+ [t, "#a50026"]
512
+ ];
513
+ return [
514
+ [-9999, [0, 0, 0, 0]],
515
+ ...e.map(([n, a]) => [n, J(a)]),
516
+ [9999, [0, 0, 0, 0]]
517
+ ];
518
+ }
519
+ function tt(i, t, e) {
520
+ const a = (e ?? A(i, t)).filter(([c]) => c > -9e3 && c < 9e3);
521
+ if (a.length < 2) return A(i, t);
522
+ const r = a[0][0], s = a[a.length - 1][0], o = Math.max(s - r, 0.01), d = Math.max(t - i, 0.01), h = a.map(([c, g]) => {
523
+ const u = (c - r) / o;
524
+ return [i + u * d, g];
525
+ });
526
+ return [
527
+ [-9999, [0, 0, 0, 0]],
528
+ ...h,
529
+ [9999, [0, 0, 0, 0]]
530
+ ];
531
+ }
532
+ function V(i) {
533
+ const t = i.filter(([e]) => e > -9e3 && e < 9e3);
534
+ return { min: t[0][0], max: t[t.length - 1][0] };
535
+ }
536
+ function W(i) {
537
+ return i.filter(([t]) => t > -9e3 && t < 9e3).map(([t]) => t);
538
+ }
539
+ function jt(i, t) {
540
+ const { min: e, max: n } = V(t), a = Math.max(n - e, 0.01);
541
+ return Math.max(0, Math.min(1, (i - e) / a));
542
+ }
543
+ function U(i, t) {
544
+ return t <= 1 ? 0 : i / (t - 1);
545
+ }
546
+ function wt(i, t) {
547
+ if (t.length <= 1 || i <= t[0]) return 0;
548
+ if (i >= t[t.length - 1]) return 1;
549
+ for (let e = 0; e < t.length - 1; e++) {
550
+ const n = t[e], a = t[e + 1];
551
+ if (i >= n && i <= a) {
552
+ const r = a === n ? 0 : (i - n) / (a - n), s = U(e, t.length), o = U(e + 1, t.length);
553
+ return s + r * (o - s);
554
+ }
555
+ }
556
+ return 1;
557
+ }
558
+ function Tt(i, t) {
559
+ if (t.length <= 1) return t[0] ?? 0;
560
+ const e = Math.max(0, Math.min(1, i)), n = t.length - 1, a = Math.min(n - 1, Math.floor(e * n)), r = e * n - a, s = t[a], o = t[a + 1];
561
+ return s + r * (o - s);
562
+ }
563
+ function vt(i) {
564
+ const t = et(i), e = t.length;
565
+ return `linear-gradient(to right, ${t.map(([a, r], s) => {
566
+ const o = e <= 1 ? 0 : s / (e - 1) * 100;
567
+ return `${nt(r)} ${o}%`;
568
+ }).join(", ")})`;
569
+ }
570
+ function et(i) {
571
+ return i.filter(([t]) => t > -9e3 && t < 9e3);
572
+ }
573
+ function nt(i) {
574
+ return `rgba(${i[0]},${i[1]},${i[2]},${i[3] / 255})`;
575
+ }
576
+ function Wt(i) {
577
+ const t = i.filter(([r]) => r > -9e3 && r < 9e3), e = t[0][0], n = t[t.length - 1][0];
578
+ return `linear-gradient(to right, ${t.map(([r, s]) => {
579
+ const o = (r - e) / (n - e) * 100;
580
+ return `rgba(${s[0]},${s[1]},${s[2]},${s[3] / 255}) ${o}%`;
581
+ }).join(", ")})`;
582
+ }
583
+ function Rt(i) {
584
+ return i === "EPSG:3857";
585
+ }
586
+ function Et(i, t, e) {
587
+ return e === "EPSG:4326" ? [i, t] : st([i, t]);
588
+ }
589
+ function Ct(i, t, e) {
590
+ return e === "EPSG:4326" ? [i, t] : ot([i, t]);
591
+ }
592
+ function St(i, t) {
593
+ return t === "EPSG:4326" ? i : Y(i, "EPSG:4326", t);
594
+ }
595
+ function N(i, t) {
596
+ return t === "EPSG:4326" ? i : Y(i, t, "EPSG:4326");
597
+ }
598
+ class Pt extends Z {
599
+ constructor(e) {
600
+ const n = document.createElement("canvas"), a = document.createElement("canvas"), r = new _t(n), s = {};
601
+ super({
602
+ opacity: e.opacity ?? 0.85,
603
+ zIndex: e.zIndex ?? 2,
604
+ source: new q({
605
+ canvasFunction: (g, u, p, m, x) => s.fn(g, u, p, m, x),
606
+ ratio: 1
607
+ })
608
+ });
609
+ l(this, "loader");
610
+ l(this, "glCanvas");
611
+ l(this, "displayCanvas");
612
+ l(this, "renderer");
613
+ l(this, "legend", null);
614
+ l(this, "currentTile", null);
615
+ l(this, "showGridLines");
616
+ l(this, "colorRamp");
617
+ l(this, "displayMin");
618
+ l(this, "displayMax");
619
+ l(this, "mapRef", null);
620
+ l(this, "fetchVersion", 0);
621
+ l(this, "viewUnbind", null);
622
+ l(this, "onMapChange", () => this.scheduleFetch());
623
+ this.loader = e.loader, this.glCanvas = n, this.displayCanvas = a, this.renderer = r, this.showGridLines = e.showGrid ?? !1;
624
+ const o = this.loader.computeStats(), d = e.colorRamp ?? A(o.min, o.max);
625
+ this.colorRamp = d;
626
+ const { min: h, max: c } = V(d);
627
+ this.displayMin = h, this.displayMax = c, this.legend = j(r.gl, d), r.setLegend(this.legend), s.fn = this.renderFrame.bind(this);
628
+ }
629
+ /** 当前图例数值范围 */
630
+ getLegendRange() {
631
+ return V(this.colorRamp);
632
+ }
633
+ getColorRamp() {
634
+ return this.colorRamp;
635
+ }
636
+ /** 设置完整色带并刷新渲染 */
637
+ setColorRamp(e) {
638
+ this.colorRamp = e, this.rebuildLegend();
639
+ }
640
+ /** 仅调整图例 min/max(保留当前色带样式) */
641
+ setLegendRange(e, n) {
642
+ this.setColorRamp(tt(e, n, this.colorRamp));
643
+ }
644
+ /** 色斑图实际显示的数值区间(滑块控制) */
645
+ getDisplayRange() {
646
+ return { min: this.displayMin, max: this.displayMax };
647
+ }
648
+ setDisplayRange(e, n) {
649
+ const { min: a, max: r } = this.getLegendRange(), o = Math.max(r - a, 0.01) * 1e-3;
650
+ let d = Math.max(a, Math.min(e, r)), h = Math.min(r, Math.max(n, a));
651
+ h - d < o && (h = Math.min(r, d + o)), this.displayMin = d, this.displayMax = h, this.refreshRender();
652
+ }
653
+ clampDisplayRange() {
654
+ const { min: e, max: n } = this.getLegendRange();
655
+ this.setDisplayRange(
656
+ Math.max(e, Math.min(this.displayMin, n)),
657
+ Math.min(n, Math.max(this.displayMax, e))
658
+ );
659
+ }
660
+ refreshRender() {
661
+ var e;
662
+ (e = this.getSource()) == null || e.changed(), this.changed();
663
+ }
664
+ getShowGrid() {
665
+ return this.showGridLines;
666
+ }
667
+ rebuildLegend() {
668
+ this.legend && this.renderer.gl.deleteTexture(this.legend.texture), this.legend = j(this.renderer.gl, this.colorRamp), this.renderer.setLegend(this.legend), this.clampDisplayRange();
669
+ }
670
+ setShowGrid(e) {
671
+ this.showGridLines = e, this.refreshRender();
672
+ }
673
+ refreshData() {
674
+ this.loader.invalidateCache(), this.scheduleFetch();
675
+ }
676
+ scheduleFetch() {
677
+ const e = this.mapRef;
678
+ if (!e || !this.loader.isLoaded) return;
679
+ const n = e.getView(), a = n.getProjection().getCode(), r = e.getSize();
680
+ if (!r) return;
681
+ const s = N(n.calculateExtent(r), a), o = n.getZoom() ?? 6, d = ++this.fetchVersion;
682
+ this.loader.readWindowAsync(s, o).then((h) => {
683
+ var c;
684
+ d === this.fetchVersion && (h && (this.currentTile = h), (c = this.getSource()) == null || c.changed());
685
+ });
686
+ }
687
+ renderFrame(e, n, a, r) {
688
+ const [s, o] = r, d = Math.floor(s * a), h = Math.floor(o * a);
689
+ this.displayCanvas.width = d, this.displayCanvas.height = h, this.renderer.resize(d, h);
690
+ const c = this.mapRef;
691
+ if (!c || !this.loader.isLoaded)
692
+ return this.displayCanvas;
693
+ const g = c.getView(), u = g.getProjection().getCode(), p = g.getZoom() ?? 6, m = c.getSize(), x = m ? N(g.calculateExtent(m), u) : e, L = this.currentTile ?? this.loader.readWindow(x, p);
694
+ if (!L)
695
+ return this.displayCanvas.getContext("2d").clearRect(0, 0, d, h), this.displayCanvas;
696
+ this.currentTile = L, this.renderer.uploadTile(L);
697
+ const _ = c.frameState_, b = _ == null ? void 0 : _.pixelToCoordinateTransform, M = b ? bt(b) : new Float32Array([1, 0, 0, 0, -1, 0, 0, 0, 1]), y = g.calculateExtent(m ?? r), C = Lt(y, e, n);
698
+ this.renderer.render(L, {
699
+ transform: Array.from(M),
700
+ size: [d, h],
701
+ delta: C,
702
+ pixelRatio: a,
703
+ dataBbox: L.bbox,
704
+ nativeCellSize: this.loader.nativeResolution,
705
+ gridOrigin: this.loader.gridOrigin,
706
+ gridLod: this.loader.getLodStep(p),
707
+ opacity: this.getOpacity(),
708
+ showGrid: this.showGridLines,
709
+ projMercator: Rt(u),
710
+ displayRange: [this.displayMin, this.displayMax]
711
+ });
712
+ const R = this.displayCanvas.getContext("2d");
713
+ return R.clearRect(0, 0, d, h), R.drawImage(this.glCanvas, 0, 0), this.displayCanvas;
714
+ }
715
+ attachMap(e) {
716
+ this.mapRef = e, e.on("moveend", this.onMapChange), this.bindView(e.getView()), this.scheduleFetch();
717
+ }
718
+ reattachView(e) {
719
+ this.mapRef = e, this.bindView(e.getView()), this.scheduleFetch();
720
+ }
721
+ bindView(e) {
722
+ var n;
723
+ (n = this.viewUnbind) == null || n.call(this), e.on("change:resolution", this.onMapChange), this.viewUnbind = () => e.un("change:resolution", this.onMapChange);
724
+ }
725
+ getDataValue(e, n) {
726
+ return this.loader.getValueAt(e, n, this.currentTile);
727
+ }
728
+ dispose() {
729
+ this.renderer.dispose();
730
+ }
731
+ }
732
+ function kt(i, t, e) {
733
+ const n = i.getPixelFromCoordinate(t);
734
+ return n ? [n[0] * e, n[1] * e] : null;
735
+ }
736
+ class Vt extends Z {
737
+ constructor(e) {
738
+ const n = document.createElement("canvas"), a = {};
739
+ super({
740
+ zIndex: e.zIndex ?? 3,
741
+ source: new q({
742
+ canvasFunction: (r, s, o, d, h) => a.fn(r, s, o, d, h),
743
+ ratio: 1
744
+ })
745
+ });
746
+ l(this, "loader");
747
+ l(this, "mapRef", null);
748
+ l(this, "canvas");
749
+ l(this, "labels", []);
750
+ l(this, "fetchVersion", 0);
751
+ l(this, "viewUnbind", null);
752
+ l(this, "onMapChange", () => this.scheduleFetch());
753
+ l(this, "opts");
754
+ this.loader = e.loader, this.canvas = n, this.opts = {
755
+ distance: e.distance ?? 80,
756
+ precision: e.precision ?? 1,
757
+ fontSize: e.fontSize ?? 11,
758
+ color: e.color ?? "rgba(20, 20, 20, 0.92)"
759
+ }, a.fn = this.renderFrame.bind(this);
760
+ }
761
+ attachMap(e) {
762
+ this.mapRef = e, e.on("moveend", this.onMapChange), this.bindView(e.getView()), this.scheduleFetch();
763
+ }
764
+ /** 切换投影后重新绑定 View 监听 */
765
+ reattachView(e) {
766
+ this.mapRef = e, this.bindView(e.getView()), this.scheduleFetch();
767
+ }
768
+ bindView(e) {
769
+ var n;
770
+ (n = this.viewUnbind) == null || n.call(this), e.on("change:resolution", this.onMapChange), this.viewUnbind = () => e.un("change:resolution", this.onMapChange);
771
+ }
772
+ refreshData() {
773
+ this.labels = [], this.scheduleFetch();
774
+ }
775
+ scheduleFetch() {
776
+ var g;
777
+ const e = this.mapRef;
778
+ if (!e || !this.loader.isLoaded) return;
779
+ const n = e.getView(), a = n.getProjection().getCode(), r = e.getSize(), s = n.getCenter();
780
+ if (!r || !s) return;
781
+ const o = N(n.calculateExtent(r), a), d = n.getZoom() ?? 6, h = n.getResolution() ?? 1, c = ++this.fetchVersion;
782
+ this.labels = this.loader.computeLabelsSync(
783
+ o,
784
+ d,
785
+ h,
786
+ this.opts.distance,
787
+ this.opts.precision,
788
+ a
789
+ ), (g = this.getSource()) == null || g.changed(), this.loader.computeLabelsAsync(
790
+ o,
791
+ d,
792
+ h,
793
+ this.opts.distance,
794
+ this.opts.precision,
795
+ a
796
+ ).then((u) => {
797
+ var p;
798
+ c === this.fetchVersion && (this.labels = u, (p = this.getSource()) == null || p.changed());
799
+ });
800
+ }
801
+ renderFrame(e, n, a, r) {
802
+ const [s, o] = r, d = Math.max(1, Math.floor(s * a)), h = Math.max(1, Math.floor(o * a));
803
+ this.canvas.width = d, this.canvas.height = h;
804
+ const c = this.canvas.getContext("2d");
805
+ c.clearRect(0, 0, d, h);
806
+ const g = this.mapRef;
807
+ if (!g || this.labels.length === 0)
808
+ return this.canvas;
809
+ const u = this.opts.fontSize * a;
810
+ c.font = `${u}px system-ui, -apple-system, sans-serif`, c.textAlign = "center", c.textBaseline = "middle", c.lineWidth = Math.max(2, 2 * a), c.lineJoin = "round", c.strokeStyle = "rgba(255, 255, 255, 0.9)", c.fillStyle = this.opts.color;
811
+ const p = g.getView().getProjection().getCode();
812
+ for (const m of this.labels) {
813
+ const x = Et(m.lon, m.lat, p), L = kt(g, x, a);
814
+ if (!L) continue;
815
+ const [_, b] = L;
816
+ _ < -u || _ > d + u || b < -u || b > h + u || (c.strokeText(m.text, _, b), c.fillText(m.text, _, b));
817
+ }
818
+ return this.canvas;
819
+ }
820
+ }
821
+ function Dt(i) {
822
+ return typeof i == "number" ? [i, i, i, i] : i;
823
+ }
824
+ class F {
825
+ constructor(t, e, n, a, r, s) {
826
+ l(this, "map");
827
+ l(this, "loader");
828
+ l(this, "choroplethLayer");
829
+ l(this, "gridValueLayer");
830
+ l(this, "stats");
831
+ l(this, "pointerHandler", null);
832
+ l(this, "pointerUnbind", null);
833
+ l(this, "destroyed", !1);
834
+ this.fitOpts = s, this.map = t, this.loader = e, this.choroplethLayer = n, this.gridValueLayer = a, this.stats = r;
835
+ }
836
+ get projection() {
837
+ return this.map.getView().getProjection().getCode();
838
+ }
839
+ static async create(t) {
840
+ if (!t.map)
841
+ throw new Error("GridMapView: map is required");
842
+ if (!t.dataUrl && !t.data)
843
+ throw new Error("GridMapView: dataUrl or data is required");
844
+ const e = new pt();
845
+ t.data ? await e.loadData(t.data) : await e.load(t.dataUrl);
846
+ const n = e.computeStats(), a = t.legendMin ?? n.min, r = t.legendMax ?? n.max, s = t.colorRamp ? t.colorRamp : tt(a, r, A(a, r)), o = new Pt({
847
+ loader: e,
848
+ colorRamp: s,
849
+ opacity: t.choroplethOpacity ?? 0.75,
850
+ showGrid: t.showGrid ?? !1,
851
+ zIndex: t.choroplethZIndex ?? 2
852
+ });
853
+ o.setVisible(t.showChoropleth ?? !0);
854
+ const d = new Vt({
855
+ loader: e,
856
+ distance: t.labelDistance ?? 80,
857
+ precision: t.labelPrecision ?? 1,
858
+ fontSize: t.labelFontSize ?? 11,
859
+ zIndex: t.labelsZIndex ?? 3
860
+ });
861
+ d.setVisible(t.showLabels ?? !0);
862
+ const h = t.map;
863
+ o.attachMap(h), d.attachMap(h), h.addLayer(o), h.addLayer(d);
864
+ const c = Dt(t.fitPadding ?? 40), g = t.fitMaxZoom ?? 10, u = new F(h, e, o, d, n, {
865
+ padding: c,
866
+ maxZoom: g
867
+ });
868
+ if (t.autoFit !== !1 && u.fitToData(), t.displayMin != null || t.displayMax != null) {
869
+ const { min: p, max: m } = u.getLegendRange();
870
+ u.setDisplayRange(t.displayMin ?? p, t.displayMax ?? m);
871
+ }
872
+ return t.onPointerMove && u.onPointerMove(t.onPointerMove), u;
873
+ }
874
+ /** 拾取 lon/lat 处格点值;超出数据范围或 displayRange 时返回 null */
875
+ getValueAt(t, e) {
876
+ return this.pickValue(t, e);
877
+ }
878
+ pickValue(t, e) {
879
+ const [n, a, r, s] = this.loader.bbox;
880
+ if (t < n || t > r || e < a || e > s) return null;
881
+ const o = this.choroplethLayer.getDataValue(t, e) ?? this.loader.getNativeValueAt(t, e);
882
+ if (o == null) return null;
883
+ if (this.choroplethLayer.getVisible()) {
884
+ const { min: d, max: h } = this.getDisplayRange();
885
+ if (o < d || o > h) return null;
886
+ }
887
+ return o;
888
+ }
889
+ onPointerMove(t) {
890
+ var n;
891
+ (n = this.pointerUnbind) == null || n.call(this), this.pointerHandler = t;
892
+ const e = (a) => {
893
+ if (a.dragging) return;
894
+ const r = this.projection, [s, o] = Ct(a.coordinate[0], a.coordinate[1], r), d = this.map.getView().getZoom() ?? 6, h = this.pickValue(s, o);
895
+ t({
896
+ lon: s,
897
+ lat: o,
898
+ value: h,
899
+ zoom: d,
900
+ lod: this.loader.getLodStep(d)
901
+ });
902
+ };
903
+ return this.map.on("pointermove", e), this.pointerUnbind = () => {
904
+ this.map.un("pointermove", e), this.pointerHandler === t && (this.pointerHandler = null);
905
+ }, this.pointerUnbind;
906
+ }
907
+ refreshView() {
908
+ this.destroyed || (this.loader.invalidateCache(), this.choroplethLayer.reattachView(this.map), this.gridValueLayer.reattachView(this.map));
909
+ }
910
+ getLayerVisibility() {
911
+ return {
912
+ choropleth: this.choroplethLayer.getVisible(),
913
+ grid: this.choroplethLayer.getShowGrid(),
914
+ labels: this.gridValueLayer.getVisible()
915
+ };
916
+ }
917
+ setLayerVisibility(t) {
918
+ t.choropleth !== void 0 && this.setShowChoropleth(t.choropleth), t.grid !== void 0 && this.setShowGrid(t.grid), t.labels !== void 0 && this.setShowLabels(t.labels);
919
+ }
920
+ setShowChoropleth(t) {
921
+ this.choroplethLayer.setVisible(t);
922
+ }
923
+ setShowGrid(t) {
924
+ this.choroplethLayer.setShowGrid(t);
925
+ }
926
+ setShowLabels(t) {
927
+ this.gridValueLayer.setVisible(t);
928
+ }
929
+ getLegendRange() {
930
+ return this.choroplethLayer.getLegendRange();
931
+ }
932
+ setLegendRange(t, e) {
933
+ this.choroplethLayer.setLegendRange(t, e);
934
+ }
935
+ setColorRamp(t) {
936
+ this.choroplethLayer.setColorRamp(t);
937
+ }
938
+ getColorRamp() {
939
+ return this.choroplethLayer.getColorRamp();
940
+ }
941
+ getDisplayRange() {
942
+ return this.choroplethLayer.getDisplayRange();
943
+ }
944
+ setDisplayRange(t, e) {
945
+ this.choroplethLayer.setDisplayRange(t, e);
946
+ }
947
+ fitToData() {
948
+ const t = St(this.loader.bbox, this.projection);
949
+ this.map.getView().fit(t, { padding: this.fitOpts.padding, maxZoom: this.fitOpts.maxZoom });
950
+ }
951
+ getLodStep() {
952
+ return this.loader.getLodStep(this.map.getView().getZoom() ?? 6);
953
+ }
954
+ destroy() {
955
+ var t;
956
+ this.destroyed || (this.destroyed = !0, (t = this.pointerUnbind) == null || t.call(this), this.pointerUnbind = null, this.map.removeLayer(this.choroplethLayer), this.map.removeLayer(this.gridValueLayer), this.choroplethLayer.dispose(), this.loader.dispose());
957
+ }
958
+ }
959
+ async function At(i) {
960
+ return F.create(i);
961
+ }
962
+ const Ht = At, Gt = `
963
+ .gred-legend-slider { user-select: none; font: 11px/1.4 system-ui, sans-serif; }
964
+ .gred-legend-slider__title { margin-bottom: 6px; color: #333; }
965
+ .gred-legend-slider__body { overflow: visible; }
966
+ .gred-legend-slider__track {
967
+ position: relative; height: 18px; border: 1px solid #ccc; border-radius: 4px; cursor: pointer;
968
+ }
969
+ .gred-legend-slider__bar {
970
+ position: absolute; inset: 0; border-radius: 3px;
971
+ }
972
+ .gred-legend-slider__blocks {
973
+ position: absolute; inset: 0; border-radius: 3px; overflow: hidden;
974
+ }
975
+ .gred-legend-slider__block {
976
+ position: absolute; top: 0; bottom: 0;
977
+ }
978
+ .gred-legend-slider__mask {
979
+ position: absolute; top: 0; bottom: 0; background: rgba(255,255,255,0.72); pointer-events: none;
980
+ }
981
+ .gred-legend-slider__mask--left { left: 0; }
982
+ .gred-legend-slider__mask--right { right: 0; }
983
+ .gred-legend-slider__thumb {
984
+ position: absolute; top: 50%; width: 12px; height: 22px; margin-left: -6px;
985
+ transform: translateY(-50%); background: #fff; border: 2px solid #333; border-radius: 3px;
986
+ box-shadow: 0 1px 4px rgba(0,0,0,0.25); cursor: grab; z-index: 2;
987
+ }
988
+ .gred-legend-slider__thumb:active { cursor: grabbing; }
989
+ .gred-legend-slider__labels {
990
+ position: relative; height: 18px; margin: 3px 0 0; padding: 0;
991
+ }
992
+ .gred-legend-slider__label {
993
+ position: absolute; top: 0; transform: translateX(-50%);
994
+ color: #333; font-size: 10px; white-space: nowrap; line-height: 1.2;
995
+ }
996
+ .gred-legend-slider__label--edge-left { transform: translateX(0); }
997
+ .gred-legend-slider__label--edge-right { transform: translateX(-100%); }
998
+ `;
999
+ let H = !1;
1000
+ function zt() {
1001
+ if (H) return;
1002
+ H = !0;
1003
+ const i = document.createElement("style");
1004
+ i.textContent = Gt, document.head.appendChild(i);
1005
+ }
1006
+ class It {
1007
+ constructor(t) {
1008
+ l(this, "root");
1009
+ l(this, "body");
1010
+ l(this, "track");
1011
+ l(this, "bar");
1012
+ l(this, "blocks");
1013
+ l(this, "labelsRow");
1014
+ l(this, "maskLeft");
1015
+ l(this, "maskRight");
1016
+ l(this, "thumbMin");
1017
+ l(this, "thumbMax");
1018
+ l(this, "legendMin");
1019
+ l(this, "legendMax");
1020
+ l(this, "displayMin");
1021
+ l(this, "displayMax");
1022
+ l(this, "colorRamp");
1023
+ l(this, "legendTicks");
1024
+ l(this, "legendMode");
1025
+ l(this, "precision");
1026
+ l(this, "showTitle");
1027
+ l(this, "onChange");
1028
+ l(this, "dragging", null);
1029
+ l(this, "onPointerMove", (t) => {
1030
+ if (!this.dragging) return;
1031
+ const e = this.track.getBoundingClientRect(), n = Math.max(0, Math.min(1, (t.clientX - e.left) / e.width)), a = Tt(n, this.legendTicks);
1032
+ this.dragging === "min" ? this.displayMin = Math.min(a, this.displayMax) : this.displayMax = Math.max(a, this.displayMin), this.applyDisplayRange(this.displayMin, this.displayMax, !1);
1033
+ });
1034
+ l(this, "onPointerUp", () => {
1035
+ this.dragging = null;
1036
+ });
1037
+ zt(), this.colorRamp = t.colorRamp, this.legendTicks = t.legendTicks ?? W(t.colorRamp), this.legendMode = t.legendMode ?? "blocks";
1038
+ const { min: e, max: n } = V(this.colorRamp);
1039
+ if (this.legendMin = e, this.legendMax = n, this.displayMin = t.displayMin ?? e, this.displayMax = t.displayMax ?? n, this.precision = t.precision ?? 1, this.showTitle = t.showTitle !== !1, this.onChange = t.onChange, this.root = document.createElement("div"), this.root.className = "gred-legend-slider", this.showTitle) {
1040
+ const a = document.createElement("div");
1041
+ a.className = "gred-legend-slider__title", a.textContent = "格点值", this.root.appendChild(a);
1042
+ }
1043
+ this.body = document.createElement("div"), this.body.className = "gred-legend-slider__body", this.track = document.createElement("div"), this.track.className = "gred-legend-slider__track", this.bar = document.createElement("div"), this.bar.className = "gred-legend-slider__bar", this.blocks = document.createElement("div"), this.blocks.className = "gred-legend-slider__blocks", this.track.appendChild(this.bar), this.track.appendChild(this.blocks), this.maskLeft = document.createElement("div"), this.maskLeft.className = "gred-legend-slider__mask gred-legend-slider__mask--left", this.maskRight = document.createElement("div"), this.maskRight.className = "gred-legend-slider__mask gred-legend-slider__mask--right", this.track.appendChild(this.maskLeft), this.track.appendChild(this.maskRight), this.thumbMin = this.createThumb("min"), this.thumbMax = this.createThumb("max"), this.track.appendChild(this.thumbMin), this.track.appendChild(this.thumbMax), this.labelsRow = document.createElement("div"), this.labelsRow.className = "gred-legend-slider__labels", this.body.appendChild(this.track), this.body.appendChild(this.labelsRow), this.root.appendChild(this.body), t.container.appendChild(this.root), document.addEventListener("pointermove", this.onPointerMove), document.addEventListener("pointerup", this.onPointerUp), this.updateBar(), this.rebuildLabels(), this.applyDisplayRange(this.displayMin, this.displayMax, !0);
1044
+ }
1045
+ createThumb(t) {
1046
+ const e = document.createElement("div");
1047
+ return e.className = "gred-legend-slider__thumb", e.addEventListener("pointerdown", (n) => {
1048
+ n.preventDefault(), this.dragging = t, e.setPointerCapture(n.pointerId);
1049
+ }), e;
1050
+ }
1051
+ /** 均匀布局位置 */
1052
+ evenPct(t) {
1053
+ return wt(t, this.legendTicks);
1054
+ }
1055
+ evenPctByIndex(t) {
1056
+ return U(t, this.legendTicks.length);
1057
+ }
1058
+ fmt(t) {
1059
+ return t.toFixed(this.precision);
1060
+ }
1061
+ updateBar() {
1062
+ const { min: t, max: e } = V(this.colorRamp);
1063
+ if (this.legendMin = t, this.legendMax = e, this.legendMode === "gradient")
1064
+ this.bar.style.display = "block", this.blocks.style.display = "none", this.bar.style.background = vt(this.colorRamp);
1065
+ else {
1066
+ this.bar.style.display = "none", this.blocks.style.display = "block", this.blocks.replaceChildren();
1067
+ const n = et(this.colorRamp), a = n.length - 1;
1068
+ for (let r = 0; r < a; r++) {
1069
+ const [, s] = n[r], o = this.evenPctByIndex(r) * 100, d = (this.evenPctByIndex(r + 1) - this.evenPctByIndex(r)) * 100, h = document.createElement("div");
1070
+ h.className = "gred-legend-slider__block", h.style.left = `${o}%`, h.style.width = `${d}%`, h.style.background = nt(s), this.blocks.appendChild(h);
1071
+ }
1072
+ }
1073
+ }
1074
+ rebuildLabels() {
1075
+ this.labelsRow.replaceChildren();
1076
+ const t = this.legendTicks.length;
1077
+ this.legendTicks.forEach((e, n) => {
1078
+ const a = document.createElement("span");
1079
+ a.className = "gred-legend-slider__label", n === 0 && a.classList.add("gred-legend-slider__label--edge-left"), n === t - 1 && a.classList.add("gred-legend-slider__label--edge-right"), a.textContent = this.fmt(e), a.style.left = `${this.evenPctByIndex(n) * 100}%`, this.labelsRow.appendChild(a);
1080
+ });
1081
+ }
1082
+ applyDisplayRange(t, e, n) {
1083
+ var c;
1084
+ const r = Math.max(this.legendMax - this.legendMin, 0.01) * 1e-3;
1085
+ let s = Math.max(this.legendMin, Math.min(t, this.legendMax)), o = Math.min(this.legendMax, Math.max(e, this.legendMin));
1086
+ o - s < r && (o = Math.min(this.legendMax, s + r)), this.displayMin = s, this.displayMax = o;
1087
+ const d = this.evenPct(s), h = this.evenPct(o);
1088
+ this.thumbMin.style.left = `${d * 100}%`, this.thumbMax.style.left = `${h * 100}%`, this.maskLeft.style.width = `${d * 100}%`, this.maskRight.style.width = `${(1 - h) * 100}%`, n || (c = this.onChange) == null || c.call(this, { displayMin: s, displayMax: o });
1089
+ }
1090
+ setLegendMode(t) {
1091
+ this.legendMode !== t && (this.legendMode = t, this.updateBar());
1092
+ }
1093
+ getLegendMode() {
1094
+ return this.legendMode;
1095
+ }
1096
+ setColorRamp(t, e) {
1097
+ this.colorRamp = t, this.legendTicks = e ?? W(t), this.updateBar(), this.rebuildLabels(), this.applyDisplayRange(this.displayMin, this.displayMax, !0);
1098
+ }
1099
+ setLegendTicks(t) {
1100
+ this.legendTicks = t, this.rebuildLabels(), this.updateBar(), this.applyDisplayRange(this.displayMin, this.displayMax, !0);
1101
+ }
1102
+ getLegendTicks() {
1103
+ return [...this.legendTicks];
1104
+ }
1105
+ setDisplayRange(t, e, n = !1) {
1106
+ this.applyDisplayRange(t, e, n);
1107
+ }
1108
+ getDisplayRange() {
1109
+ return { displayMin: this.displayMin, displayMax: this.displayMax };
1110
+ }
1111
+ getLegendRange() {
1112
+ return { min: this.legendMin, max: this.legendMax };
1113
+ }
1114
+ destroy() {
1115
+ document.removeEventListener("pointermove", this.onPointerMove), document.removeEventListener("pointerup", this.onPointerUp), this.root.remove();
1116
+ }
1117
+ }
1118
+ function Zt(i) {
1119
+ return new It(i);
1120
+ }
1121
+ const Ut = {
1122
+ background: "rgba(255, 255, 255, 0.92)",
1123
+ width: "280px",
1124
+ padding: "10px 14px 12px",
1125
+ borderRadius: "8px",
1126
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
1127
+ zIndex: 10
1128
+ }, Nt = {
1129
+ "bottom-right": { bottom: 24, right: 12 },
1130
+ "bottom-left": { bottom: 24, left: 12 },
1131
+ "top-right": { top: 12, right: 12 },
1132
+ "top-left": { top: 12, left: 12 }
1133
+ };
1134
+ function qt(i = "bottom-right", t = {}) {
1135
+ const e = { ...Ut, ...t }, n = i === "custom" ? {} : Nt[i], a = {
1136
+ position: "absolute",
1137
+ background: e.background,
1138
+ width: typeof e.width == "number" ? `${e.width}px` : e.width,
1139
+ padding: e.padding,
1140
+ borderRadius: e.borderRadius,
1141
+ boxShadow: e.boxShadow,
1142
+ zIndex: t.zIndex ?? e.zIndex,
1143
+ font: t.font ?? "11px system-ui, sans-serif",
1144
+ boxSizing: "border-box"
1145
+ }, r = { ...n, ...t };
1146
+ for (const s of ["bottom", "right", "left", "top"]) {
1147
+ const o = r[s];
1148
+ o != null && (a[s] = typeof o == "number" ? `${o}px` : o);
1149
+ }
1150
+ return a;
1151
+ }
1152
+ function Yt(i) {
1153
+ return {
1154
+ getVisibility: () => (i == null ? void 0 : i.getLayerVisibility()) ?? null,
1155
+ setLayerVisibility: (t) => i == null ? void 0 : i.setLayerVisibility(t),
1156
+ setShowChoropleth: (t) => i == null ? void 0 : i.setShowChoropleth(t),
1157
+ setShowGrid: (t) => i == null ? void 0 : i.setShowGrid(t),
1158
+ setShowLabels: (t) => i == null ? void 0 : i.setShowLabels(t),
1159
+ toggleChoropleth: () => {
1160
+ if (!i) return;
1161
+ const t = i.getLayerVisibility();
1162
+ i.setShowChoropleth(!t.choropleth);
1163
+ },
1164
+ toggleGrid: () => {
1165
+ if (!i) return;
1166
+ const t = i.getLayerVisibility();
1167
+ i.setShowGrid(!t.grid);
1168
+ },
1169
+ toggleLabels: () => {
1170
+ if (!i) return;
1171
+ const t = i.getLayerVisibility();
1172
+ i.setShowLabels(!t.labels);
1173
+ }
1174
+ };
1175
+ }
1176
+ export {
1177
+ pt as A,
1178
+ Pt as C,
1179
+ Ut as D,
1180
+ F as G,
1181
+ It as L,
1182
+ Vt as a,
1183
+ Nt as b,
1184
+ j as c,
1185
+ tt as d,
1186
+ At as e,
1187
+ Ht as f,
1188
+ Yt as g,
1189
+ Zt as h,
1190
+ St as i,
1191
+ A as j,
1192
+ $t as k,
1193
+ Tt as l,
1194
+ W as m,
1195
+ et as n,
1196
+ V as o,
1197
+ Et as p,
1198
+ Ct as q,
1199
+ qt as r,
1200
+ Wt as s,
1201
+ vt as t,
1202
+ nt as u,
1203
+ U as v,
1204
+ wt as w,
1205
+ jt as x,
1206
+ N as y
1207
+ };
1208
+ //# sourceMappingURL=layerControlHelpers-BSZqa4fP.js.map