@nika-js/onlymap 0.5.9 → 0.5.11

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,1585 @@
1
+ import { w as ae } from "./mgrs-BY9bIvp4.js";
2
+ import { am as ce, an as le, ao as ee, ap as te, aq as ue, b as he, ar as de, l as Z, as as fe, d as pe, at as me, au as ge, av as ve, aw as ne } from "./index-DTRXxe7D.js";
3
+ function Pe(o, e, t) {
4
+ const { projectedCorners: n } = e, { topLeft: s, topRight: r, bottomRight: a, bottomLeft: i } = n, c = t(s[0], s[1]), u = t(r[0], r[1]), l = t(a[0], a[1]), d = t(i[0], i[1]), f = [
5
+ c,
6
+ u,
7
+ l,
8
+ d,
9
+ c
10
+ ], h = [
11
+ (c[0] + l[0]) / 2,
12
+ (c[1] + l[1]) / 2
13
+ ], p = new ce({
14
+ id: `${o}-label`,
15
+ data: [
16
+ {
17
+ position: h,
18
+ text: `x=${e.index.x} y=${e.index.y} z=${e.index.z}`
19
+ }
20
+ ],
21
+ getColor: [255, 255, 255, 255],
22
+ getSize: 24,
23
+ sizeUnits: "pixels",
24
+ outlineWidth: 3,
25
+ outlineColor: [0, 0, 0, 255],
26
+ fontSettings: { sdf: !0 }
27
+ });
28
+ return [new le({
29
+ id: o,
30
+ data: [f],
31
+ getPath: (g) => g,
32
+ getColor: [255, 0, 0, 255],
33
+ // Red
34
+ getWidth: 2,
35
+ widthUnits: "pixels",
36
+ pickable: !1
37
+ }), p];
38
+ }
39
+ const xe = [
40
+ [1 / 3, 1 / 3, 1 / 3],
41
+ // centroid
42
+ [0.5, 0.5, 0],
43
+ // edge 0–1
44
+ [0.5, 0, 0.5],
45
+ // edge 0–2
46
+ [0, 0.5, 0.5]
47
+ // edge 1–2
48
+ ], be = 0.125;
49
+ class Te {
50
+ reprojectors;
51
+ /** Width of the image in pixels */
52
+ width;
53
+ /** Height of the image in pixels */
54
+ height;
55
+ /**
56
+ * UV vertex coordinates (x, y), i.e.
57
+ * [x0, y0, x1, y1, ...]
58
+ *
59
+ * These coordinates are floats that range from [0, 1] in both X and Y.
60
+ */
61
+ uvs;
62
+ /**
63
+ * XY Positions in output CRS, computed via exact forward reprojection.
64
+ */
65
+ exactOutputPositions;
66
+ /**
67
+ * triangle vertex indices
68
+ */
69
+ triangles;
70
+ _halfedges;
71
+ /**
72
+ * The UV texture coordinates of candidates found from
73
+ * `findReprojectionCandidate`.
74
+ *
75
+ * Maybe in the future we'll want to store the barycentric coordinates instead
76
+ * of just the uv coordinates?
77
+ */
78
+ _candidatesUV;
79
+ _queueIndices;
80
+ _queue;
81
+ _errors;
82
+ _pending;
83
+ _pendingLen;
84
+ constructor(e, t, n = t) {
85
+ this.reprojectors = e, this.width = t, this.height = n, this.uvs = [], this.exactOutputPositions = [], this.triangles = [], this._halfedges = [], this._candidatesUV = [], this._queueIndices = [], this._queue = [], this._errors = [], this._pending = [], this._pendingLen = 0;
86
+ const s = 1, r = 1, a = this._addPoint(0, 0), i = this._addPoint(s, 0), c = this._addPoint(0, r), u = this._addPoint(s, r), l = this._addTriangle(u, a, c, -1, -1, -1);
87
+ this._addTriangle(a, u, i, l, -1, -1), this._flush();
88
+ }
89
+ /**
90
+ * Refine the mesh until its maximum error gets below the given one
91
+ *
92
+ * @param maxError The maximum reprojection error in input pixels that the mesh should achieve.
93
+ * @param maxIterations Optional safeguard to prevent infinite loops in case of non-convergence. If the mesh fails to converge within this number of iterations, a warning will be logged and the function will return early.
94
+ *
95
+ * @return {[type]} [return description]
96
+ */
97
+ run(e = be, { maxIterations: t = 1e4 } = {}) {
98
+ if (e <= 0)
99
+ throw new Error("maxError must be positive");
100
+ let n = 0;
101
+ for (; this.getMaxError() > e; )
102
+ if (this.refine(), ++n > t) {
103
+ console.warn(`RasterReprojector: mesh refinement did not converge after ${n} iterations (maxError=${e}, currentError=${this.getMaxError()})`);
104
+ break;
105
+ }
106
+ }
107
+ // refine the mesh with a single point
108
+ refine() {
109
+ this._step(), this._flush();
110
+ }
111
+ // max error of the current mesh
112
+ getMaxError() {
113
+ return this._errors[0];
114
+ }
115
+ // rasterize and queue all triangles that got added or updated in _step
116
+ _flush() {
117
+ for (let e = 0; e < this._pendingLen; e++) {
118
+ const t = this._pending[e];
119
+ this._findReprojectionCandidate(t);
120
+ }
121
+ this._pendingLen = 0;
122
+ }
123
+ /**
124
+ * Conversion of upstream's `_findCandidate` for reprojection error handling.
125
+ *
126
+ * @param t The index (into `this.triangles`) of the pending triangle to process.
127
+ *
128
+ * @return Doesn't return; instead modifies internal state.
129
+ */
130
+ _findReprojectionCandidate(e) {
131
+ const t = 2 * this.triangles[e * 3 + 0], n = 2 * this.triangles[e * 3 + 1], s = 2 * this.triangles[e * 3 + 2], r = this.uvs[t], a = this.uvs[t + 1], i = this.uvs[n], c = this.uvs[n + 1], u = this.uvs[s], l = this.uvs[s + 1], d = this.exactOutputPositions[t], f = this.exactOutputPositions[t + 1], h = this.exactOutputPositions[n], p = this.exactOutputPositions[n + 1], m = this.exactOutputPositions[s], g = this.exactOutputPositions[s + 1];
132
+ let b = 0, P = 0, x = 0;
133
+ for (const v of xe) {
134
+ const T = A(r, i, u, v[0], v[1], v[2]), L = A(a, c, l, v[0], v[1], v[2]), j = A(d, h, m, v[0], v[1], v[2]), w = A(f, p, g, v[0], v[1], v[2]), O = T * (this.width - 1), z = L * (this.height - 1), H = this.reprojectors.inverseReproject(j, w), F = this.reprojectors.inverseTransform(H[0], H[1]), oe = O - F[0], ie = z - F[1], W = Math.hypot(oe, ie);
135
+ W > b && (b = W, P = T, x = L);
136
+ }
137
+ (P === r && x === a || P === i && x === c || P === u && x === l) && (b = 0), this._candidatesUV[2 * e] = P, this._candidatesUV[2 * e + 1] = x, this._queuePush(e, b);
138
+ }
139
+ // process the next triangle in the queue, splitting it with a new point
140
+ _step() {
141
+ const e = this._queuePop(), t = e * 3 + 0, n = e * 3 + 1, s = e * 3 + 2, r = this.triangles[t], a = this.triangles[n], i = this.triangles[s], c = this.uvs[2 * r], u = this.uvs[2 * r + 1], l = this.uvs[2 * a], d = this.uvs[2 * a + 1], f = this.uvs[2 * i], h = this.uvs[2 * i + 1], p = this._candidatesUV[2 * e], m = this._candidatesUV[2 * e + 1], g = this._addPoint(p, m);
142
+ if (D(c, u, l, d, p, m) === 0)
143
+ this._handleCollinear(g, t);
144
+ else if (D(l, d, f, h, p, m) === 0)
145
+ this._handleCollinear(g, n);
146
+ else if (D(f, h, c, u, p, m) === 0)
147
+ this._handleCollinear(g, s);
148
+ else {
149
+ const b = this._halfedges[t], P = this._halfedges[n], x = this._halfedges[s], v = this._addTriangle(r, a, g, b, -1, -1, t), T = this._addTriangle(a, i, g, P, -1, v + 1), L = this._addTriangle(i, r, g, x, v + 2, T + 1);
150
+ this._legalize(v), this._legalize(T), this._legalize(L);
151
+ }
152
+ }
153
+ // add coordinates for a new vertex
154
+ _addPoint(e, t) {
155
+ const n = this.uvs.length >> 1;
156
+ this.uvs.push(e, t);
157
+ const s = e * (this.width - 1), r = t * (this.height - 1), a = this.reprojectors.forwardTransform(s, r), i = this.reprojectors.forwardReproject(a[0], a[1]);
158
+ return this.exactOutputPositions.push(i[0], i[1]), n;
159
+ }
160
+ // add or update a triangle in the mesh
161
+ _addTriangle(e, t, n, s, r, a, i = this.triangles.length) {
162
+ const c = i / 3;
163
+ return this.triangles[i + 0] = e, this.triangles[i + 1] = t, this.triangles[i + 2] = n, this._halfedges[i + 0] = s, this._halfedges[i + 1] = r, this._halfedges[i + 2] = a, s >= 0 && (this._halfedges[s] = i + 0), r >= 0 && (this._halfedges[r] = i + 1), a >= 0 && (this._halfedges[a] = i + 2), this._candidatesUV[2 * c + 0] = 0, this._candidatesUV[2 * c + 1] = 0, this._queueIndices[c] = -1, this._pending[this._pendingLen++] = c, i;
164
+ }
165
+ _legalize(e) {
166
+ const t = this._halfedges[e];
167
+ if (t < 0)
168
+ return;
169
+ const n = e - e % 3, s = t - t % 3, r = n + (e + 1) % 3, a = n + (e + 2) % 3, i = s + (t + 2) % 3, c = s + (t + 1) % 3, u = this.triangles[a], l = this.triangles[e], d = this.triangles[r], f = this.triangles[i], h = this.uvs;
170
+ if (!ye(h[2 * u], h[2 * u + 1], h[2 * l], h[2 * l + 1], h[2 * d], h[2 * d + 1], h[2 * f], h[2 * f + 1]))
171
+ return;
172
+ const p = this._halfedges[r], m = this._halfedges[a], g = this._halfedges[i], b = this._halfedges[c];
173
+ this._queueRemove(n / 3), this._queueRemove(s / 3);
174
+ const P = this._addTriangle(u, f, d, -1, g, p, n), x = this._addTriangle(f, u, l, P, m, b, s);
175
+ this._legalize(P + 1), this._legalize(x + 2);
176
+ }
177
+ // handle a case where new vertex is on the edge of a triangle
178
+ _handleCollinear(e, t) {
179
+ const n = t - t % 3, s = n + (t + 1) % 3, r = n + (t + 2) % 3, a = this.triangles[r], i = this.triangles[t], c = this.triangles[s], u = this._halfedges[s], l = this._halfedges[r], d = this._halfedges[t];
180
+ if (d < 0) {
181
+ const L = this._addTriangle(e, a, i, -1, l, -1, n), j = this._addTriangle(a, e, c, L, -1, u);
182
+ this._legalize(L + 1), this._legalize(j + 2);
183
+ return;
184
+ }
185
+ const f = d - d % 3, h = f + (d + 2) % 3, p = f + (d + 1) % 3, m = this.triangles[h], g = this._halfedges[h], b = this._halfedges[p];
186
+ this._queueRemove(f / 3);
187
+ const P = this._addTriangle(a, i, e, l, -1, -1, n), x = this._addTriangle(i, m, e, b, -1, P + 1, f), v = this._addTriangle(m, c, e, g, -1, x + 1), T = this._addTriangle(c, a, e, u, P + 2, v + 1);
188
+ this._legalize(P), this._legalize(x), this._legalize(v), this._legalize(T);
189
+ }
190
+ // priority queue methods
191
+ _queuePush(e, t) {
192
+ const n = this._queue.length;
193
+ this._queueIndices[e] = n, this._queue.push(e), this._errors.push(t), this._queueUp(n);
194
+ }
195
+ _queuePop() {
196
+ const e = this._queue.length - 1;
197
+ return this._queueSwap(0, e), this._queueDown(0, e), this._queuePopBack();
198
+ }
199
+ _queuePopBack() {
200
+ const e = this._queue.pop();
201
+ return this._errors.pop(), this._queueIndices[e] = -1, e;
202
+ }
203
+ _queueRemove(e) {
204
+ const t = this._queueIndices[e];
205
+ if (t < 0) {
206
+ const s = this._pending.indexOf(e);
207
+ if (s !== -1)
208
+ this._pending[s] = this._pending[--this._pendingLen];
209
+ else
210
+ throw new Error("Broken triangulation (something went wrong).");
211
+ return;
212
+ }
213
+ const n = this._queue.length - 1;
214
+ n !== t && (this._queueSwap(t, n), this._queueDown(t, n) || this._queueUp(t)), this._queuePopBack();
215
+ }
216
+ _queueLess(e, t) {
217
+ return this._errors[e] > this._errors[t];
218
+ }
219
+ _queueSwap(e, t) {
220
+ const n = this._queue[e], s = this._queue[t];
221
+ this._queue[e] = s, this._queue[t] = n, this._queueIndices[n] = t, this._queueIndices[s] = e;
222
+ const r = this._errors[e];
223
+ this._errors[e] = this._errors[t], this._errors[t] = r;
224
+ }
225
+ _queueUp(e) {
226
+ let t = e;
227
+ for (; ; ) {
228
+ const n = t - 1 >> 1;
229
+ if (n === t || !this._queueLess(t, n))
230
+ break;
231
+ this._queueSwap(n, t), t = n;
232
+ }
233
+ }
234
+ _queueDown(e, t) {
235
+ let n = e;
236
+ for (; ; ) {
237
+ const s = 2 * n + 1;
238
+ if (s >= t || s < 0)
239
+ break;
240
+ const r = s + 1;
241
+ let a = s;
242
+ if (r < t && this._queueLess(r, s) && (a = r), !this._queueLess(a, n))
243
+ break;
244
+ this._queueSwap(n, a), n = a;
245
+ }
246
+ return n > e;
247
+ }
248
+ }
249
+ function D(o, e, t, n, s, r) {
250
+ return (t - s) * (e - r) - (n - r) * (o - s);
251
+ }
252
+ function ye(o, e, t, n, s, r, a, i) {
253
+ const c = o - a, u = e - i, l = t - a, d = n - i, f = s - a, h = r - i, p = c * c + u * u, m = l * l + d * d, g = f * f + h * h;
254
+ return c * (d * g - m * h) - u * (l * g - m * f) + p * (l * h - d * f) < 0;
255
+ }
256
+ function A(o, e, t, n, s, r) {
257
+ return n * o + s * e + r * t;
258
+ }
259
+ const se = {
260
+ name: "create-texture-unorm",
261
+ inject: {
262
+ "fs:#decl": "uniform sampler2D textureName;",
263
+ "fs:DECKGL_FILTER_COLOR": (
264
+ /* glsl */
265
+ `
266
+ color = texture(textureName, geometry.uv);
267
+ `
268
+ )
269
+ },
270
+ getUniforms: (o) => ({
271
+ textureName: o.textureName
272
+ })
273
+ }, Le = (
274
+ /* glsl */
275
+ `#version 300 es
276
+ #define SHADER_NAME simple-mesh-layer-fs
277
+
278
+ precision highp float;
279
+
280
+ in vec2 vTexCoord;
281
+ in vec3 cameraPosition;
282
+ in vec3 normals_commonspace;
283
+ in vec4 position_commonspace;
284
+ in vec4 vColor;
285
+
286
+ out vec4 fragColor;
287
+
288
+ void main(void) {
289
+ geometry.uv = vTexCoord;
290
+
291
+ vec3 normal;
292
+ if (simpleMesh.flatShading) {
293
+
294
+ normal = normalize(cross(dFdx(position_commonspace.xyz), dFdy(position_commonspace.xyz)));
295
+ } else {
296
+ normal = normals_commonspace;
297
+ }
298
+
299
+ // We initialize color here before passing into DECKGL_FILTER_COLOR
300
+ vec4 color;
301
+ DECKGL_FILTER_COLOR(color, geometry);
302
+
303
+ vec3 lightColor = lighting_getLightColor(color.rgb, cameraPosition, position_commonspace.xyz, normal);
304
+ fragColor = vec4(lightColor, color.a * layer.opacity);
305
+ }
306
+ `
307
+ ), Oe = {
308
+ ...ee.defaultProps,
309
+ // Note: putting `image` in defaultProps causes Maplibre to fail to render
310
+ // labels in interleaved mode 🤷‍♂️
311
+ // image: { type: "image", value: null, async: true },
312
+ renderPipeline: { type: "array", value: [], compare: !0 },
313
+ // Disable lighting by default (avoids darkening raster)
314
+ material: {
315
+ ambient: 1,
316
+ diffuse: 0,
317
+ shininess: 0,
318
+ specularColor: [0, 0, 0]
319
+ }
320
+ };
321
+ class je extends ee {
322
+ static layerName = "mesh-texture-layer";
323
+ static defaultProps = Oe;
324
+ _resolveRenderPipeline() {
325
+ const { image: e, renderPipeline: t } = this.props;
326
+ return [...e ? [{ module: se, props: { textureName: e } }] : [], ...t ?? []];
327
+ }
328
+ updateState(e) {
329
+ this.hasRenderPipelineChanged(e) && (e.changeFlags.extensionsChanged = !0), super.updateState(e);
330
+ }
331
+ /** Returns true if the render pipeline has changed between the old and new props. */
332
+ hasRenderPipelineChanged(e) {
333
+ const { oldProps: t, props: n } = e;
334
+ if (!!t.image != !!n.image)
335
+ return !0;
336
+ const s = t.renderPipeline ?? [], r = n.renderPipeline ?? [];
337
+ if (s.length !== r.length)
338
+ return !0;
339
+ for (let a = 0; a < s.length; a++)
340
+ if (s[a]?.module.name !== r[a]?.module.name)
341
+ return !0;
342
+ return !1;
343
+ }
344
+ getShaders() {
345
+ const e = super.getShaders(), t = e.modules;
346
+ for (const n of this._resolveRenderPipeline())
347
+ t.push(n.module);
348
+ return {
349
+ ...e,
350
+ // Override upstream's fragment shader with our copy with modified
351
+ // injection points
352
+ fs: Le,
353
+ modules: t
354
+ };
355
+ }
356
+ draw(e) {
357
+ const t = {};
358
+ for (const n of this._resolveRenderPipeline())
359
+ t[n.module.name] = n.props || {};
360
+ for (const n of super.getModels())
361
+ n.shaderInputs.setProps(t);
362
+ super.draw(e);
363
+ }
364
+ }
365
+ const we = 0.125, U = [
366
+ [252, 73, 163],
367
+ // pink
368
+ [255, 51, 204],
369
+ // magenta-pink
370
+ [204, 102, 255],
371
+ // purple-ish
372
+ [153, 51, 255],
373
+ // deep purple
374
+ [102, 204, 255],
375
+ // sky blue
376
+ [51, 153, 255],
377
+ // clear blue
378
+ [102, 255, 204],
379
+ // teal
380
+ [51, 255, 170],
381
+ // aqua-teal
382
+ [0, 255, 0],
383
+ // lime green
384
+ [51, 204, 51],
385
+ // stronger green
386
+ [255, 204, 102],
387
+ // light orange
388
+ [255, 179, 71],
389
+ // golden-orange
390
+ [255, 102, 102],
391
+ // salmon
392
+ [255, 80, 80],
393
+ // red-salmon
394
+ [255, 0, 0],
395
+ // red
396
+ [204, 0, 0],
397
+ // crimson
398
+ [255, 128, 0],
399
+ // orange
400
+ [255, 153, 51],
401
+ // bright orange
402
+ [255, 255, 102],
403
+ // yellow
404
+ [255, 255, 51],
405
+ // lemon
406
+ [0, 255, 255],
407
+ // turquoise
408
+ [0, 204, 255]
409
+ // cyan
410
+ ], Me = {
411
+ // A prop with `type: "image"` gets converted to a texture automatically by
412
+ // deck.gl (as long as async: true)
413
+ image: { type: "image", value: null, async: !0 },
414
+ renderPipeline: { type: "array", value: [], compare: !0 },
415
+ debug: !1,
416
+ debugOpacity: 0.5
417
+ };
418
+ class Ce extends te {
419
+ static layerName = "RasterLayer";
420
+ static defaultProps = Me;
421
+ initializeState() {
422
+ this.setState({});
423
+ }
424
+ updateState(e) {
425
+ super.updateState(e);
426
+ const { props: t, oldProps: n, changeFlags: s } = e, r = t.reprojectionFns.forwardTransform !== n.reprojectionFns?.forwardTransform || t.reprojectionFns.inverseTransform !== n.reprojectionFns?.inverseTransform || t.reprojectionFns.forwardReproject !== n.reprojectionFns?.forwardReproject || t.reprojectionFns.inverseReproject !== n.reprojectionFns?.inverseReproject;
427
+ (!!s.dataChanged || t.width !== n.width || t.height !== n.height || r || t.maxError !== n.maxError) && this._generateMesh();
428
+ }
429
+ _generateMesh() {
430
+ const { width: e, height: t, reprojectionFns: n, maxError: s = we } = this.props, r = new Te(n, e + 1, t + 1);
431
+ r.run(s);
432
+ const { indices: a, positions: i, texCoords: c } = Ae(r);
433
+ this.setState({
434
+ reprojector: r,
435
+ mesh: {
436
+ indices: { value: a, size: 1 },
437
+ attributes: {
438
+ POSITION: { value: i, size: 3 },
439
+ TEXCOORD_0: { value: c, size: 2 }
440
+ }
441
+ }
442
+ });
443
+ }
444
+ renderDebugLayer() {
445
+ const { reprojector: e } = this.state, { debugOpacity: t } = this.props;
446
+ return e ? new ue(this.getSubLayerProps({
447
+ id: "polygon",
448
+ // https://deck.gl/docs/developer-guide/performance#supply-binary-blobs-to-the-data-prop
449
+ // This `data` gets passed into `getPolygon` with the row index.
450
+ data: { reprojector: e, length: e.triangles.length / 3 },
451
+ getPolygon: (n, { index: s, data: r }) => {
452
+ const a = r.reprojector.triangles, i = e.exactOutputPositions, c = a[s * 3], u = a[s * 3 + 1], l = a[s * 3 + 2];
453
+ return [
454
+ [i[c * 2], i[c * 2 + 1]],
455
+ [i[u * 2], i[u * 2 + 1]],
456
+ [i[l * 2], i[l * 2 + 1]],
457
+ [i[c * 2], i[c * 2 + 1]]
458
+ ];
459
+ },
460
+ getFillColor: (n, { index: s, target: r }) => {
461
+ const a = U[s % U.length];
462
+ return r[0] = a[0], r[1] = a[1], r[2] = a[2], r[3] = 255, r;
463
+ },
464
+ getLineColor: [0, 0, 0],
465
+ getLineWidth: 1,
466
+ lineWidthUnits: "pixels",
467
+ opacity: t !== void 0 && Number.isFinite(t) ? Math.max(0, Math.min(1, t)) : 1,
468
+ pickable: !1
469
+ })) : null;
470
+ }
471
+ renderLayers() {
472
+ const { mesh: e } = this.state, { debug: t, image: n, renderPipeline: s } = this.props;
473
+ if (!e || !n && (s?.length ?? 0) === 0)
474
+ return null;
475
+ const a = [new je(this.getSubLayerProps({
476
+ id: "raster",
477
+ image: n,
478
+ renderPipeline: s,
479
+ // Dummy data because we're only rendering _one_ instance of this mesh
480
+ // https://github.com/visgl/deck.gl/blob/93111b667b919148da06ff1918410cf66381904f/modules/geo-layers/src/terrain-layer/terrain-layer.ts#L241
481
+ data: [1],
482
+ mesh: e,
483
+ // We're only rendering a single mesh, without instancing
484
+ // https://github.com/visgl/deck.gl/blob/93111b667b919148da06ff1918410cf66381904f/modules/geo-layers/src/terrain-layer/terrain-layer.ts#L244
485
+ _instanced: !1,
486
+ // Dummy accessors for the dummy data
487
+ // We place our mesh at the coordinate origin
488
+ getPosition: [0, 0, 0],
489
+ // We give a white color to turn off color mixing with the texture
490
+ getColor: [255, 255, 255]
491
+ }))];
492
+ if (t) {
493
+ const i = this.renderDebugLayer();
494
+ i && a.push(i);
495
+ }
496
+ return a;
497
+ }
498
+ }
499
+ function Ae(o) {
500
+ const e = o.uvs.length / 2, t = new Float32Array(e * 3), n = new Float32Array(o.uvs);
501
+ for (let r = 0; r < e; r++)
502
+ t[r * 3] = o.exactOutputPositions[r * 2], t[r * 3 + 1] = o.exactOutputPositions[r * 2 + 1], t[r * 3 + 2] = 0;
503
+ return {
504
+ indices: new Uint32Array(o.triangles),
505
+ positions: t,
506
+ texCoords: n
507
+ };
508
+ }
509
+ class ft {
510
+ levels;
511
+ projectTo3857;
512
+ projectFrom3857;
513
+ projectTo4326;
514
+ projectFrom4326;
515
+ projectedBounds;
516
+ constructor(e) {
517
+ if (e.levels.length === 0)
518
+ throw new Error("AffineTileset requires at least one level");
519
+ this.levels = e.levels, this.projectTo3857 = e.projectTo3857, this.projectFrom3857 = e.projectFrom3857, this.projectTo4326 = e.projectTo4326, this.projectFrom4326 = e.projectFrom4326, this.projectedBounds = e.levels[0].projectedBounds;
520
+ }
521
+ }
522
+ function Re(o, e) {
523
+ return [1, 0, o, 0, 1, e];
524
+ }
525
+ function pt(o, e = o) {
526
+ return [o, 0, 0, 0, e, 0];
527
+ }
528
+ function y([o, e, t, n, s, r], a, i) {
529
+ return [
530
+ o * a + e * i + t,
531
+ n * a + s * i + r
532
+ ];
533
+ }
534
+ function ze([o, e, t, n, s, r], [a, i, c, u, l, d]) {
535
+ return [
536
+ o * a + e * u,
537
+ o * i + e * l,
538
+ o * c + e * d + t,
539
+ n * a + s * u,
540
+ n * i + s * l,
541
+ n * c + s * d + r
542
+ ];
543
+ }
544
+ function q([o, e, t, n, s, r]) {
545
+ const a = o * s - e * n;
546
+ if (a === 0)
547
+ throw new Error("Cannot invert degenerate transform");
548
+ const i = 1 / a, c = s * i, u = -e * i, l = -n * i, d = o * i;
549
+ return [
550
+ c,
551
+ u,
552
+ -t * c - r * u,
553
+ l,
554
+ d,
555
+ -t * l - r * d
556
+ ];
557
+ }
558
+ function De(o) {
559
+ return o[0];
560
+ }
561
+ function Xe(o) {
562
+ return o[4];
563
+ }
564
+ class mt {
565
+ tileWidth;
566
+ tileHeight;
567
+ matrixWidth;
568
+ matrixHeight;
569
+ metersPerPixel;
570
+ /**
571
+ * Source-CRS bounding box of the level's array `[minX, minY, maxX, maxY]`.
572
+ * Computed from the affine applied to the four array corners.
573
+ */
574
+ projectedBounds;
575
+ _affine;
576
+ _invAffine;
577
+ constructor(e) {
578
+ this._affine = e.affine, this._invAffine = q(e.affine), this.tileWidth = e.tileWidth, this.tileHeight = e.tileHeight, this.matrixWidth = Math.ceil(e.arrayWidth / e.tileWidth), this.matrixHeight = Math.ceil(e.arrayHeight / e.tileHeight);
579
+ const t = De(e.affine), n = Xe(e.affine);
580
+ this.metersPerPixel = Math.sqrt(Math.abs(t * n)) * e.mpu;
581
+ const s = [
582
+ y(e.affine, 0, 0),
583
+ y(e.affine, e.arrayWidth, 0),
584
+ y(e.affine, 0, e.arrayHeight),
585
+ y(e.affine, e.arrayWidth, e.arrayHeight)
586
+ ], r = s.map(([i]) => i), a = s.map(([, i]) => i);
587
+ this.projectedBounds = [
588
+ Math.min(...r),
589
+ Math.min(...a),
590
+ Math.max(...r),
591
+ Math.max(...a)
592
+ ];
593
+ }
594
+ projectedTileCorners(e, t) {
595
+ const n = this.tileWidth, s = this.tileHeight, r = this._affine;
596
+ return {
597
+ topLeft: y(r, e * n, t * s),
598
+ topRight: y(r, (e + 1) * n, t * s),
599
+ bottomLeft: y(r, e * n, (t + 1) * s),
600
+ bottomRight: y(r, (e + 1) * n, (t + 1) * s)
601
+ };
602
+ }
603
+ tileTransform(e, t) {
604
+ const n = Re(e * this.tileWidth, t * this.tileHeight), s = ze(this._affine, n), r = q(s);
605
+ return {
606
+ forwardTransform: (a, i) => y(s, a, i),
607
+ inverseTransform: (a, i) => y(r, a, i)
608
+ };
609
+ }
610
+ crsBoundsToTileRange(e, t, n, s) {
611
+ const r = this._invAffine, a = [
612
+ y(r, e, t),
613
+ y(r, n, t),
614
+ y(r, e, s),
615
+ y(r, n, s)
616
+ ], i = a.map(([T]) => T), c = a.map(([, T]) => T), u = Math.min(...i), l = Math.max(...i), d = Math.min(...c), f = Math.max(...c), h = this.tileWidth, p = this.tileHeight, m = this.matrixWidth - 1, g = this.matrixHeight - 1, b = Math.max(0, Math.floor(u / h)), P = Math.min(m, Math.floor(l / h)), x = Math.max(0, Math.floor(d / p)), v = Math.min(g, Math.floor(f / p));
617
+ return { minCol: b, maxCol: P, minRow: x, maxRow: v };
618
+ }
619
+ }
620
+ function gt(o, { semiMajorAxis: e } = {}) {
621
+ switch (o = o.toLowerCase(), o) {
622
+ case "m":
623
+ case "metre":
624
+ case "meter":
625
+ case "meters":
626
+ return 1;
627
+ case "foot":
628
+ return 0.3048;
629
+ case "us survey foot":
630
+ return 1200 / 3937;
631
+ }
632
+ if (o === "degree") {
633
+ if (e === void 0)
634
+ throw new Error("CRS with degrees unit requires ellipsoid semi-major-axis");
635
+ return 2 * Math.PI * e / 360;
636
+ }
637
+ throw new Error(`Unsupported CRS units: ${o} when computing metersPerUnit.`);
638
+ }
639
+ function Ie(o) {
640
+ const e = ae(o);
641
+ return e.projName === "longlat" && (!e.units || e.units === "unknown") && (e.units = "degree", e.to_meter = void 0), e;
642
+ }
643
+ const k = /* @__PURE__ */ new Map();
644
+ async function vt(o) {
645
+ const e = `EPSG:${o}`, t = k.get(e);
646
+ if (t !== void 0)
647
+ return t;
648
+ const n = await Be(o), s = Ie(n);
649
+ return k.set(e, s), s;
650
+ }
651
+ async function Be(o) {
652
+ const e = `https://epsg.io/${o}.json`, t = await fetch(e);
653
+ if (!t.ok)
654
+ throw new Error(`Failed to fetch PROJJSON from ${e}`);
655
+ return await t.json();
656
+ }
657
+ function I(o, e, t, n, s, r = {}) {
658
+ const { densifyPts: a = 21 } = r, i = [e, n, n, e], c = [t, t, s, s];
659
+ let u = 1 / 0, l = 1 / 0, d = -1 / 0, f = -1 / 0;
660
+ for (let h = 0; h < 4; h++) {
661
+ const p = i[h], m = c[h], g = i[(h + 1) % 4], b = c[(h + 1) % 4];
662
+ for (let P = 0; P <= a; P++) {
663
+ const x = P / (a + 1), [v, T] = o(p + (g - p) * x, m + (b - m) * x);
664
+ v < u && (u = v), T < l && (l = T), v > d && (d = v), T > f && (f = T);
665
+ }
666
+ }
667
+ return [u, l, d, f];
668
+ }
669
+ const V = 6378137, Y = 85.05112877980659;
670
+ function Ee(o, e) {
671
+ const t = o * Math.PI * V / 180, n = e * Math.PI / 180, s = Math.log(Math.tan(Math.PI / 4 + n / 2)) * V;
672
+ return [t, s];
673
+ }
674
+ function Pt(o, e) {
675
+ return (t, n) => {
676
+ const [s, r] = o(t, n);
677
+ if (Number.isFinite(s) && Number.isFinite(r))
678
+ return [s, r];
679
+ const [a, i] = e(t, n), c = Math.max(-Y, Math.min(Y, i));
680
+ return Ee(a, c);
681
+ };
682
+ }
683
+ const Se = 65536;
684
+ class re {
685
+ entries = /* @__PURE__ */ new Map();
686
+ maxEntries;
687
+ constructor({ maxEntries: e = Se } = {}) {
688
+ this.maxEntries = Math.max(0, e);
689
+ }
690
+ /** Number of cached entries. */
691
+ get size() {
692
+ return this.entries.size;
693
+ }
694
+ /**
695
+ * Look up the cached bounding volume for tile `(z, x, y)`. On a hit the entry
696
+ * is marked most-recently-used. Returns `undefined` on a miss.
697
+ */
698
+ get(e, t, n) {
699
+ const s = `${e}/${t}/${n}`, r = this.entries.get(s);
700
+ if (r !== void 0)
701
+ return this.entries.delete(s), this.entries.set(s, r), r;
702
+ }
703
+ /** Store the bounding volume for tile `(z, x, y)` as most-recently-used. */
704
+ set(e, t, n, s) {
705
+ const r = `${e}/${t}/${n}`;
706
+ this.entries.delete(r), this.entries.set(r, s);
707
+ }
708
+ /**
709
+ * If the cache is over its soft cap, drop least-recently-used entries down to
710
+ * roughly half of `maxEntries`. No-op when at or under the cap. Call once at
711
+ * the start of a traversal, never mid-traversal.
712
+ */
713
+ sweep() {
714
+ if (this.entries.size <= this.maxEntries)
715
+ return;
716
+ const e = Math.floor(this.maxEntries / 2), t = this.entries.size - e, n = [];
717
+ for (const s of this.entries.keys())
718
+ if (n.push(s), n.length >= t)
719
+ break;
720
+ for (const s of n)
721
+ this.entries.delete(s);
722
+ }
723
+ }
724
+ const G = 512, Ne = [
725
+ [0.5, 0.5],
726
+ // center
727
+ [0, 0],
728
+ // top-left
729
+ [0, 1],
730
+ // bottom-left
731
+ [1, 0],
732
+ // top-right
733
+ [1, 1]
734
+ // bottom-right
735
+ ], He = Ne.concat([
736
+ [0, 0.5],
737
+ // left edge
738
+ [0.5, 0],
739
+ // top edge
740
+ [1, 0.5],
741
+ // right edge
742
+ [0.5, 1]
743
+ // bottom edge
744
+ ]), B = 6378137, E = 2 * Math.PI * B, J = E / 2, K = 85.05112877980659;
745
+ class R {
746
+ /** Index across a row */
747
+ x;
748
+ /** Index down a column */
749
+ y;
750
+ /** Zoom index assumed to be (higher = finer detail) */
751
+ z;
752
+ descriptor;
753
+ /**
754
+ * Flag indicating whether any descendant of this tile is visible.
755
+ *
756
+ * Used to prevent loading parent tiles when children are visible (avoids
757
+ * overdraw).
758
+ */
759
+ childVisible;
760
+ /**
761
+ * Flag indicating this tile should be rendered
762
+ *
763
+ * Set to `true` when this is the appropriate LOD for its distance from camera.
764
+ */
765
+ selected;
766
+ /** A cache of the children of this node. */
767
+ _children;
768
+ constructor(e, t, n, { descriptor: s }) {
769
+ this.x = e, this.y = t, this.z = n, this.descriptor = s;
770
+ }
771
+ /** Get the level info for this tile's z index. */
772
+ get level() {
773
+ return this.descriptor.levels[this.z];
774
+ }
775
+ /** Get the children of this node.
776
+ *
777
+ * Find all tiles at level this.z + 1 whose spatial extent overlaps this tile.
778
+ *
779
+ * A tileset pyramid is not guaranteed to be a quadtree — it is a stack of
780
+ * independent grids. We find children by mapping the parent tile's CRS bounds
781
+ * into the child grid using {@link RasterTilesetLevel.crsBoundsToTileRange}.
782
+ */
783
+ get children() {
784
+ if (!this._children) {
785
+ const e = this.descriptor.levels.length - 1;
786
+ if (this.z >= e)
787
+ return this._children = null, null;
788
+ const t = this.z + 1, n = this.descriptor.levels[t], s = this.level.projectedTileCorners(this.x, this.y), r = Ge(s), { minCol: a, maxCol: i, minRow: c, maxRow: u } = n.crsBoundsToTileRange(...r), l = [], { descriptor: d } = this;
789
+ for (let f = c; f <= u; f++)
790
+ for (let h = a; h <= i; h++)
791
+ l.push(new R(h, f, t, { descriptor: d }));
792
+ this._children = l.length > 0 ? l : null;
793
+ }
794
+ return this._children;
795
+ }
796
+ /**
797
+ * Recursively traverse the tile pyramid to determine if this tile (or its
798
+ * descendants) should be rendered.
799
+ *
800
+ * I.e. "Given this tile node, should I render this tile, or should I recurse
801
+ * into its children?"
802
+ *
803
+ * The algorithm performs:
804
+ * 1. Visibility culling - reject tiles outside the view frustum
805
+ * 2. Bounds checking - reject tiles outside the specified geographic bounds
806
+ * 3. LOD selection - choose appropriate zoom level based on distance from camera
807
+ * 4. Recursive subdivision - if LOD is insufficient, test child tiles
808
+ *
809
+ * Additionally, there should never be overdraw, i.e. a tile should never be
810
+ * rendered if any of its descendants are rendered.
811
+ *
812
+ * @returns true if this tile or any descendant is visible, false otherwise
813
+ */
814
+ update(e) {
815
+ this.childVisible = !1, this.selected = !1;
816
+ const { viewport: t, cullingVolume: n, elevationBounds: s, minZ: r, maxZ: a = this.descriptor.levels.length - 1, project: i, bounds: c, pixelRatio: u, boundingVolumeCache: l } = e, { boundingVolume: d, commonSpaceBounds: f } = this.getBoundingVolume(s, i, l);
817
+ if (c && !this.insideBounds(c, f) || n.computeVisibility(d) < 0)
818
+ return !1;
819
+ const p = this.children;
820
+ if (!this.childVisible && this.z >= r) {
821
+ const m = Ye(d, t.zoom);
822
+ if (this.level.metersPerPixel * u / m <= 1 || this.z >= a || p === null && this.z >= r)
823
+ return this.selected = !0, !0;
824
+ }
825
+ if (p && p.length > 0) {
826
+ this.selected = !1;
827
+ let m = !1;
828
+ for (const g of p)
829
+ g.update(e) && (m = !0);
830
+ return this.childVisible = m, m;
831
+ }
832
+ return !0;
833
+ }
834
+ /**
835
+ * Collect all tiles marked as selected in the tree.
836
+ * Recursively traverses the entire tree and gathers tiles where selected=true.
837
+ *
838
+ * @param result - Accumulator array for selected tiles
839
+ * @returns Array of selected RasterTileNode tiles
840
+ */
841
+ getSelected(e = []) {
842
+ if (this.selected && e.push(this), this._children)
843
+ for (const t of this._children)
844
+ t.getSelected(e);
845
+ return e;
846
+ }
847
+ /**
848
+ * Test if this tile intersects the specified bounds in Web Mercator space.
849
+ * Used to filter tiles when only a specific geographic region is needed.
850
+ *
851
+ * @param bounds - [minX, minY, maxX, maxY] in Web Mercator units (0-512)
852
+ * @returns true if tile overlaps the bounds
853
+ */
854
+ insideBounds(e, t) {
855
+ const [n, s, r, a] = e, [i, c, u, l] = t;
856
+ return i < r && u > n && c < a && l > s;
857
+ }
858
+ /**
859
+ * The 3D bounding volume for this tile in deck.gl's common coordinate space,
860
+ * used for frustum culling.
861
+ *
862
+ * Memoized in `boundingVolumeCache` (keyed by `z/x/y`): a tile's bounding
863
+ * volume depends only on `(z, x, y, zRange)` for a given descriptor, so on a
864
+ * cache hit it is returned without rerunning {@link computeBoundingVolume}'s
865
+ * proj4 reprojections + oriented-bounding-box fit.
866
+ */
867
+ getBoundingVolume(e, t, n) {
868
+ const s = n.get(this.z, this.x, this.y);
869
+ if (s && s.zRange[0] === e[0] && s.zRange[1] === e[1])
870
+ return s;
871
+ const r = this.computeBoundingVolume(e, t);
872
+ return n.set(this.z, this.x, this.y, { zRange: e, ...r }), r;
873
+ }
874
+ /**
875
+ * Compute (without caching) the 3D bounding volume for this tile in deck.gl's
876
+ * common coordinate space.
877
+ *
878
+ * TODO: In the future, we can add a fast path in the case that the source
879
+ * tiling is already in EPSG:3857.
880
+ */
881
+ computeBoundingVolume(e, t) {
882
+ return t && pe(!1, "TODO: implement getBoundingVolume in Globe view"), this._getGenericBoundingVolume(e);
883
+ }
884
+ /**
885
+ * Generic case - sample reference points and reproject to Web Mercator, then
886
+ * convert to deck.gl common space
887
+ *
888
+ */
889
+ _getGenericBoundingVolume(e) {
890
+ const [t, n] = e, s = this.level.projectedTileCorners(this.x, this.y), a = We(He, s, this.descriptor.projectTo3857, this.descriptor.projectTo4326).map((h) => Ze(h)), i = [];
891
+ for (const h of a)
892
+ i.push([h[0], h[1], t]), t !== n && i.push([h[0], h[1], n]);
893
+ let c = Number.POSITIVE_INFINITY, u = Number.POSITIVE_INFINITY, l = Number.NEGATIVE_INFINITY, d = Number.NEGATIVE_INFINITY;
894
+ for (const [h, p] of a)
895
+ h < c && (c = h), p < u && (u = p), h > l && (l = h), p > d && (d = p);
896
+ const f = [c, u, l, d];
897
+ return {
898
+ boundingVolume: me(i),
899
+ commonSpaceBounds: f
900
+ };
901
+ }
902
+ }
903
+ function Fe(o, e) {
904
+ return (t, n) => {
905
+ const [s, r] = o(t, n);
906
+ if (Number.isFinite(s) && Number.isFinite(r))
907
+ return [s, r];
908
+ const [a, i] = e(t, n), u = Math.max(-K, Math.min(K, i)) * Math.PI / 180, l = a * Math.PI * B / 180, d = Math.log(Math.tan(Math.PI / 4 + u / 2)) * B;
909
+ return [l, d];
910
+ };
911
+ }
912
+ function We(o, e, t, n) {
913
+ const { topLeft: s, topRight: r, bottomLeft: a, bottomRight: i } = e, c = Fe(t, n), u = [];
914
+ for (const [l, d] of o) {
915
+ const [f, h] = Je(s, r, a, i, l, d);
916
+ u.push(c(f, h));
917
+ }
918
+ return u;
919
+ }
920
+ function Ze([o, e]) {
921
+ const t = Math.max(-J, Math.min(J, e));
922
+ return [
923
+ (o / E + 0.5) * G,
924
+ (t / E + 0.5) * G
925
+ ];
926
+ }
927
+ const Ue = 100;
928
+ function qe(o) {
929
+ const { descriptor: e, viewport: t, datasetWgs84Bounds: n } = o, s = e.levels[0], r = [];
930
+ if (s.matrixWidth * s.matrixHeight <= Ue) {
931
+ for (let p = 0; p < s.matrixHeight; p++)
932
+ for (let m = 0; m < s.matrixWidth; m++)
933
+ r.push(new R(m, p, 0, { descriptor: e }));
934
+ return r;
935
+ }
936
+ const i = t.getBounds(), c = [
937
+ Math.max(n[0], i[0]),
938
+ Math.max(n[1], i[1]),
939
+ Math.min(n[2], i[2]),
940
+ Math.min(n[3], i[3])
941
+ ];
942
+ if (c[0] > c[2] || c[1] > c[3])
943
+ return r;
944
+ const [u, l, d, f] = I(e.projectFrom4326, c[0], c[1], c[2], c[3]), h = s.crsBoundsToTileRange(u, l, d, f);
945
+ for (let p = h.minRow; p <= h.maxRow; p++)
946
+ for (let m = h.minCol; m <= h.maxCol; m++)
947
+ r.push(new R(m, p, 0, { descriptor: e }));
948
+ return r;
949
+ }
950
+ function ke(o, e) {
951
+ const { viewport: t, maxZ: n, zRange: s, wgs84Bounds: r, pixelRatio: a = 1 } = e, i = e.boundingVolumeCache ?? new re();
952
+ i.sweep();
953
+ const c = t instanceof he && t.resolution ? t.projectPosition : null, u = Object.values(t.getFrustumPlanes()).map(({ normal: O, distance: z }) => new de(O.clone().negate(), z)), l = new fe(u), d = t.distanceScales.unitsPerMeter[2], f = s && s[0] * d || 0, h = s && s[1] * d || 0, p = 0, [m, g, b, P] = r, x = Z([m, g]), v = Z([b, P]), T = [
954
+ x[0],
955
+ x[1],
956
+ v[0],
957
+ v[1]
958
+ ], L = qe({
959
+ descriptor: o,
960
+ viewport: t,
961
+ datasetWgs84Bounds: r
962
+ }), j = {
963
+ viewport: t,
964
+ project: c,
965
+ cullingVolume: l,
966
+ elevationBounds: [f, h],
967
+ minZ: p,
968
+ maxZ: n,
969
+ bounds: T,
970
+ pixelRatio: a,
971
+ boundingVolumeCache: i
972
+ };
973
+ for (const O of L)
974
+ O.update(j);
975
+ const w = [];
976
+ for (const O of L)
977
+ O.getSelected(w);
978
+ return w;
979
+ }
980
+ function Ve(o, e) {
981
+ return 40075016686e-3 * Math.cos(o * Math.PI / 180) / 2 ** (e + 8);
982
+ }
983
+ function Ye(o, e) {
984
+ const [t, n] = ge(o.center);
985
+ return Ve(n, e);
986
+ }
987
+ function Ge({ topLeft: o, topRight: e, bottomLeft: t, bottomRight: n }) {
988
+ const s = [o[0], e[0], t[0], n[0]], r = [o[1], e[1], t[1], n[1]];
989
+ return [Math.min(...s), Math.min(...r), Math.max(...s), Math.max(...r)];
990
+ }
991
+ function Je(o, e, t, n, s, r) {
992
+ const a = (1 - s) * (1 - r), i = s * (1 - r), c = (1 - s) * r, u = s * r;
993
+ return [
994
+ o[0] * a + e[0] * i + t[0] * c + n[0] * u,
995
+ o[1] * a + e[1] * i + t[1] * c + n[1] * u
996
+ ];
997
+ }
998
+ function Ke(o, e) {
999
+ const t = o.length;
1000
+ if (t < 2)
1001
+ return o;
1002
+ const { getCenter: n, reference: s } = e, r = s[0], a = s[1], i = new Float64Array(t);
1003
+ for (let l = 0; l < t; l++) {
1004
+ const d = n(o[l]), f = d[0] - r, h = d[1] - a;
1005
+ i[l] = f * f + h * h;
1006
+ }
1007
+ const c = new Uint32Array(t);
1008
+ for (let l = 0; l < t; l++)
1009
+ c[l] = l;
1010
+ c.sort((l, d) => i[l] - i[d]);
1011
+ const u = o.slice();
1012
+ for (let l = 0; l < t; l++)
1013
+ o[l] = u[c[l]];
1014
+ return o;
1015
+ }
1016
+ function Qe(o, e, t) {
1017
+ const [n, s, r, a] = e.getBounds(), i = [
1018
+ (n + r) / 2,
1019
+ (s + a) / 2
1020
+ ];
1021
+ return Ke(o, {
1022
+ reference: i,
1023
+ getCenter: t
1024
+ });
1025
+ }
1026
+ class _e extends ve {
1027
+ descriptor;
1028
+ wgs84Bounds;
1029
+ getPixelRatio;
1030
+ boundingVolumeCache;
1031
+ constructor(e, t, { getPixelRatio: n, maxBoundingVolumeCacheSize: s } = {}) {
1032
+ super(e), this.descriptor = t, this.getPixelRatio = n ?? (() => 1), this.boundingVolumeCache = new re({
1033
+ maxEntries: s
1034
+ });
1035
+ const r = I(this.descriptor.projectTo4326, ...this.descriptor.projectedBounds), a = 85.0511287798066;
1036
+ this.wgs84Bounds = [
1037
+ r[0],
1038
+ Math.max(r[1], -a),
1039
+ r[2],
1040
+ Math.min(r[3], a)
1041
+ ];
1042
+ }
1043
+ /**
1044
+ * Get tile indices visible in viewport
1045
+ * Uses frustum culling similar to OSM implementation
1046
+ *
1047
+ * Overviews follow TileMatrixSet ordering: index 0 = coarsest, higher = finer
1048
+ *
1049
+ * `minZoom` and `maxZoom` gate against `viewport.zoom` (not the tileset
1050
+ * z-index, which is an overview level in our descriptor). When the
1051
+ * viewport zoom is outside these bounds this method returns an empty
1052
+ * list — no new tile fetches, and because deck.gl's `updateTileStates`
1053
+ * marks unselected cached tiles invisible, no rendering either.
1054
+ * `visibleMinZoom` / `visibleMaxZoom` (deck.gl 9.3+) are deliberately
1055
+ * not honored: their documented "fetch but don't render" semantic
1056
+ * requires a notion of clamping to a coarser z, which doesn't
1057
+ * generalize to descriptors with sparse or single overviews. See
1058
+ * `dev-docs/zoom-terminology.md` for the rationale.
1059
+ */
1060
+ getTileIndices(e) {
1061
+ const { viewport: t, minZoom: n } = e;
1062
+ if (typeof n == "number" && t.zoom < n)
1063
+ return [];
1064
+ const s = this.descriptor.levels.length - 1, r = typeof e.maxZoom == "number" ? Math.min(e.maxZoom, s) : s, a = ke(this.descriptor, {
1065
+ viewport: t,
1066
+ maxZ: r,
1067
+ zRange: e.zRange ?? null,
1068
+ wgs84Bounds: this.wgs84Bounds,
1069
+ pixelRatio: this.getPixelRatio(),
1070
+ boundingVolumeCache: this.boundingVolumeCache
1071
+ });
1072
+ return this.sortTileIndicesByDistance(a, t);
1073
+ }
1074
+ /**
1075
+ * Sort tile indices by ascending distance from the viewport center in
1076
+ * projected (common/world) space so loads initiate center-out.
1077
+ *
1078
+ * Short-circuits when `tileIndices.length <= maxRequests` — all fetches
1079
+ * would start concurrently regardless of order in that case. Mutates and
1080
+ * returns `tileIndices`.
1081
+ */
1082
+ sortTileIndicesByDistance(e, t) {
1083
+ const { maxRequests: n } = this.opts;
1084
+ if (e.length <= n)
1085
+ return e;
1086
+ const s = this.descriptor;
1087
+ return Qe(e, t, (r) => {
1088
+ const { x: a, y: i, z: c } = r, { topLeft: u, bottomRight: l } = s.levels[c].projectedTileCorners(a, i), d = [
1089
+ (u[0] + l[0]) / 2,
1090
+ (u[1] + l[1]) / 2
1091
+ ];
1092
+ return s.projectTo4326(d[0], d[1]);
1093
+ });
1094
+ }
1095
+ getTileId(e) {
1096
+ return `${e.x}-${e.y}-${e.z}`;
1097
+ }
1098
+ getParentIndex(e) {
1099
+ if (e.z === 0)
1100
+ return e;
1101
+ const t = this.descriptor.levels[e.z], n = this.descriptor.levels[e.z - 1], s = n.metersPerPixel * n.tileWidth, r = n.metersPerPixel * n.tileHeight, a = t.metersPerPixel * t.tileWidth, i = t.metersPerPixel * t.tileHeight, c = s / a, u = r / i;
1102
+ return {
1103
+ x: Math.floor(e.x / c),
1104
+ y: Math.floor(e.y / u),
1105
+ z: e.z - 1
1106
+ };
1107
+ }
1108
+ getTileZoom(e) {
1109
+ return e.z;
1110
+ }
1111
+ getTileMetadata(e) {
1112
+ const { x: t, y: n, z: s } = e, r = this.descriptor.levels[s], { tileHeight: a, tileWidth: i } = r, { topLeft: c, topRight: u, bottomLeft: l, bottomRight: d } = r.projectedTileCorners(t, n), f = {
1113
+ topLeft: c,
1114
+ topRight: u,
1115
+ bottomLeft: l,
1116
+ bottomRight: d
1117
+ }, h = [
1118
+ Math.min(c[0], u[0], l[0], d[0]),
1119
+ Math.min(c[1], u[1], l[1], d[1]),
1120
+ Math.max(c[0], u[0], l[0], d[0]),
1121
+ Math.max(c[1], u[1], l[1], d[1])
1122
+ ], [p, m, g, b] = I(this.descriptor.projectTo4326, ...h), { forwardTransform: P, inverseTransform: x } = r.tileTransform(t, n);
1123
+ return {
1124
+ bbox: {
1125
+ west: p,
1126
+ south: m,
1127
+ east: g,
1128
+ north: b
1129
+ },
1130
+ projectedBbox: {
1131
+ left: h[0],
1132
+ bottom: h[1],
1133
+ right: h[2],
1134
+ top: h[3]
1135
+ },
1136
+ projectedCorners: f,
1137
+ tileWidth: i,
1138
+ tileHeight: a,
1139
+ forwardTransform: P,
1140
+ inverseTransform: x
1141
+ };
1142
+ }
1143
+ }
1144
+ const S = 512, $e = 40075016686e-3, Q = S / $e, et = {
1145
+ ...ne.defaultProps,
1146
+ maxError: 0.125,
1147
+ debug: !1,
1148
+ debugOpacity: 0.5
1149
+ };
1150
+ class xt extends te {
1151
+ static layerName = "RasterTileLayer";
1152
+ static defaultProps = et;
1153
+ /**
1154
+ * The currently effective {@link RasterTilesetDescriptor}.
1155
+ *
1156
+ * Subclasses override this to return a descriptor built from their own
1157
+ * async-parsed state. Returns `undefined` while the source is still
1158
+ * loading; `renderLayers()` returns `null` in that case.
1159
+ *
1160
+ * The inline cast to `RasterTileLayerProps<DataT>` is required because
1161
+ * `tilesetDescriptor` is declared on `ExtraProps`, not on the base's
1162
+ * `RasterTileLayerBaseProps`. For direct use the default `ExtraProps`
1163
+ * brings it in; for subclass use this method is overridden and the cast
1164
+ * is never reached.
1165
+ */
1166
+ _tilesetDescriptor() {
1167
+ return this.props.tilesetDescriptor;
1168
+ }
1169
+ /**
1170
+ * The currently effective tile-fetch callback.
1171
+ *
1172
+ * Subclasses override this to adapt their user-facing `getTileData`
1173
+ * signature into the base's `(tile, options) => Promise<DataT>` shape.
1174
+ * Returns `undefined` when the callback is not yet available.
1175
+ */
1176
+ _getTileDataCallback() {
1177
+ return this.props.getTileData;
1178
+ }
1179
+ /**
1180
+ * The currently effective per-tile render callback.
1181
+ *
1182
+ * Subclasses override this to thread their user-facing `renderTile` and
1183
+ * any inferred default. Returns `undefined` when no callback is available.
1184
+ */
1185
+ _renderTileCallback() {
1186
+ return this.props.renderTile;
1187
+ }
1188
+ /**
1189
+ * Hook for rendering per-tile debug overlay sub-layers.
1190
+ *
1191
+ * Called once per tile from `_renderSubLayers` only when `props.debug` is
1192
+ * `true`. The hook fires both before data has arrived (`data` is `null`) and
1193
+ * after (`data` is the fetched `DataT`), so the default outline can render
1194
+ * during loading.
1195
+ *
1196
+ * Default behavior renders the primary tile boundary via
1197
+ * {@link renderDebugTileOutline} using the active descriptor. Subclasses can
1198
+ * override to replace, extend (via `super._renderDebug(...)`), or suppress
1199
+ * the default — for example, a multi-source layer can replace the default
1200
+ * with per-band tile outlines and tiered metadata labels once `data` is
1201
+ * available.
1202
+ */
1203
+ _renderDebug(e, t) {
1204
+ const n = this._tilesetDescriptor();
1205
+ return n ? Pe(`${this.id}-${e.id}-bounds`, e, n.projectTo4326) : [];
1206
+ }
1207
+ renderLayers() {
1208
+ const e = this._tilesetDescriptor(), t = this._getTileDataCallback(), n = this._renderTileCallback();
1209
+ return !e || !t || !n ? null : this._renderTileLayer(e, t, n);
1210
+ }
1211
+ _renderTileLayer(e, t, n) {
1212
+ const s = this.context.device;
1213
+ class r extends _e {
1214
+ constructor(L) {
1215
+ super(L, e, {
1216
+ getPixelRatio: () => {
1217
+ const j = s.getDefaultCanvasContext(), [w] = j.getDrawingBufferSize(), [O] = j.getCSSSize();
1218
+ return O ? w / O : 1;
1219
+ }
1220
+ });
1221
+ }
1222
+ }
1223
+ const { tileSize: a, zoomOffset: i, maxZoom: c, minZoom: u, extent: l, debounceTime: d, maxCacheSize: f, maxCacheByteSize: h, maxRequests: p, refinementStrategy: m, updateTriggers: g, onTileError: b, onTileLoad: P, onTileUnload: x, onViewportLoad: v } = this.props;
1224
+ return new ne({
1225
+ id: `raster-tile-layer-${this.id}`,
1226
+ TilesetClass: r,
1227
+ getTileData: (T) => this._wrapGetTileData(T, t),
1228
+ renderSubLayers: (T) => this._renderSubLayers(T, e, n),
1229
+ updateTriggers: {
1230
+ renderSubLayers: g?.renderTile
1231
+ },
1232
+ tileSize: a,
1233
+ zoomOffset: i,
1234
+ maxZoom: c,
1235
+ minZoom: u,
1236
+ extent: l,
1237
+ debounceTime: d,
1238
+ maxCacheSize: f,
1239
+ maxCacheByteSize: h,
1240
+ maxRequests: p,
1241
+ refinementStrategy: m,
1242
+ onTileError: b,
1243
+ onTileLoad: P,
1244
+ onTileUnload: x,
1245
+ onViewportLoad: v
1246
+ });
1247
+ }
1248
+ async _wrapGetTileData(e, t) {
1249
+ const { signal: n } = e, s = this.props.signal, r = s && n ? AbortSignal.any([s, n]) : s ?? n, a = {
1250
+ device: this.context.device,
1251
+ signal: r
1252
+ };
1253
+ return t(e, a);
1254
+ }
1255
+ _renderSubLayers(e, t, n) {
1256
+ const { maxError: s, debug: r, debugOpacity: a } = this.props, i = e.tile, c = r ? this._renderDebug(i, e.data ?? null) : [];
1257
+ if (!e.data)
1258
+ return c;
1259
+ const { forwardTransform: u, inverseTransform: l } = i, d = n(e.data);
1260
+ if (!d)
1261
+ return c;
1262
+ const { image: f, renderPipeline: h } = d, { width: p, height: m } = e.data, g = this.context.viewport.resolution !== void 0, b = g ? {
1263
+ forwardTransform: u,
1264
+ inverseTransform: l,
1265
+ forwardReproject: t.projectTo4326,
1266
+ inverseReproject: t.projectFrom4326
1267
+ } : {
1268
+ forwardTransform: u,
1269
+ inverseTransform: l,
1270
+ forwardReproject: t.projectTo3857,
1271
+ inverseReproject: t.projectFrom3857
1272
+ }, P = g ? {} : {
1273
+ coordinateSystem: "cartesian",
1274
+ coordinateOrigin: [S / 2, S / 2, 0],
1275
+ // biome-ignore format: array
1276
+ modelMatrix: [
1277
+ Q,
1278
+ 0,
1279
+ 0,
1280
+ 0,
1281
+ 0,
1282
+ Q,
1283
+ 0,
1284
+ 0,
1285
+ 0,
1286
+ 0,
1287
+ 1,
1288
+ 0,
1289
+ 0,
1290
+ 0,
1291
+ 0,
1292
+ 1
1293
+ ]
1294
+ };
1295
+ return [new Ce(this.getSubLayerProps({
1296
+ id: `${e.id}-raster`,
1297
+ width: p,
1298
+ height: m,
1299
+ // Passing `image: undefined` explicitly would trip isAsyncPropLoading
1300
+ // and cause a transient black flash (see issue #376).
1301
+ ...f !== void 0 && { image: f },
1302
+ renderPipeline: h,
1303
+ maxError: s,
1304
+ reprojectionFns: b,
1305
+ debug: r,
1306
+ debugOpacity: a,
1307
+ ...P
1308
+ })), ...c];
1309
+ }
1310
+ }
1311
+ const C = "colormap", tt = {
1312
+ name: C,
1313
+ fs: `uniform ${C}Uniforms {
1314
+ int colormapIndex;
1315
+ float reversed;
1316
+ } ${C};
1317
+ `,
1318
+ inject: {
1319
+ "fs:#decl": `precision highp sampler2DArray;
1320
+ uniform sampler2DArray colormapTexture;
1321
+ `,
1322
+ "fs:DECKGL_FILTER_COLOR": (
1323
+ /* glsl */
1324
+ `
1325
+ float idx = mix(color.r, 1.0 - color.r, ${C}.reversed);
1326
+ color = texture(
1327
+ colormapTexture,
1328
+ vec3(idx, 0.5, float(${C}.colormapIndex))
1329
+ );
1330
+ `
1331
+ )
1332
+ },
1333
+ uniformTypes: {
1334
+ colormapIndex: "i32",
1335
+ reversed: "f32"
1336
+ },
1337
+ getUniforms: (o) => ({
1338
+ colormapTexture: o.colormapTexture,
1339
+ colormapIndex: o.colormapIndex ?? 0,
1340
+ reversed: o.reversed ?? !1
1341
+ })
1342
+ }, X = {
1343
+ accent: 0,
1344
+ afmhot: 1,
1345
+ algae: 2,
1346
+ amp: 3,
1347
+ autumn: 4,
1348
+ balance: 5,
1349
+ binary: 6,
1350
+ blues: 7,
1351
+ bone: 8,
1352
+ brbg: 9,
1353
+ brg: 10,
1354
+ bugn: 11,
1355
+ bupu: 12,
1356
+ bwr: 13,
1357
+ cfastie: 14,
1358
+ cividis: 15,
1359
+ cmrmap: 16,
1360
+ cool: 17,
1361
+ coolwarm: 18,
1362
+ copper: 19,
1363
+ cubehelix: 20,
1364
+ curl: 21,
1365
+ dark2: 22,
1366
+ deep: 23,
1367
+ delta: 24,
1368
+ dense: 25,
1369
+ diff: 26,
1370
+ flag: 27,
1371
+ gist_earth: 28,
1372
+ gist_gray: 29,
1373
+ gist_heat: 30,
1374
+ gist_ncar: 31,
1375
+ gist_rainbow: 32,
1376
+ gist_stern: 33,
1377
+ gist_yarg: 34,
1378
+ gnbu: 35,
1379
+ gnuplot: 36,
1380
+ gnuplot2: 37,
1381
+ gray: 38,
1382
+ greens: 39,
1383
+ greys: 40,
1384
+ haline: 41,
1385
+ hot: 42,
1386
+ hsv: 43,
1387
+ ice: 44,
1388
+ inferno: 45,
1389
+ jet: 46,
1390
+ magma: 47,
1391
+ matter: 48,
1392
+ nipy_spectral: 49,
1393
+ ocean: 50,
1394
+ oranges: 51,
1395
+ orrd: 52,
1396
+ oxy: 53,
1397
+ paired: 54,
1398
+ pastel1: 55,
1399
+ pastel2: 56,
1400
+ phase: 57,
1401
+ pink: 58,
1402
+ piyg: 59,
1403
+ plasma: 60,
1404
+ prgn: 61,
1405
+ prism: 62,
1406
+ pubu: 63,
1407
+ pubugn: 64,
1408
+ puor: 65,
1409
+ purd: 66,
1410
+ purples: 67,
1411
+ rain: 68,
1412
+ rainbow: 69,
1413
+ rdbu: 70,
1414
+ rdgy: 71,
1415
+ rdpu: 72,
1416
+ rdylbu: 73,
1417
+ rdylgn: 74,
1418
+ reds: 75,
1419
+ rplumbo: 76,
1420
+ schwarzwald: 77,
1421
+ seismic: 78,
1422
+ set1: 79,
1423
+ set2: 80,
1424
+ set3: 81,
1425
+ solar: 82,
1426
+ spectral: 83,
1427
+ speed: 84,
1428
+ spring: 85,
1429
+ summer: 86,
1430
+ tab10: 87,
1431
+ tab20: 88,
1432
+ tab20b: 89,
1433
+ tab20c: 90,
1434
+ tarn: 91,
1435
+ tempo: 92,
1436
+ terrain: 93,
1437
+ thermal: 94,
1438
+ topo: 95,
1439
+ turbid: 96,
1440
+ turbo: 97,
1441
+ twilight: 98,
1442
+ twilight_shifted: 99,
1443
+ viridis: 100,
1444
+ winter: 101,
1445
+ wistia: 102,
1446
+ ylgn: 103,
1447
+ ylgnbu: 104,
1448
+ ylorbr: 105,
1449
+ ylorrd: 106
1450
+ };
1451
+ function nt(o, e) {
1452
+ if (e.width !== 256)
1453
+ throw new Error(`Expected a 256-pixel-wide colormap sprite, got width ${e.width}.`);
1454
+ const t = new Uint8Array(e.data.buffer, e.data.byteOffset, e.data.byteLength);
1455
+ return o.createTexture({
1456
+ dimension: "2d-array",
1457
+ format: "rgba8unorm",
1458
+ width: 256,
1459
+ height: 1,
1460
+ depth: e.height,
1461
+ data: t,
1462
+ mipLevels: 1,
1463
+ sampler: {
1464
+ minFilter: "linear",
1465
+ magFilter: "linear",
1466
+ // Clamp in every axis so an out-of-range colormapIndex yields an
1467
+ // edge color rather than wrapping to an unrelated colormap.
1468
+ addressModeU: "clamp-to-edge",
1469
+ addressModeV: "clamp-to-edge",
1470
+ addressModeW: "clamp-to-edge"
1471
+ }
1472
+ });
1473
+ }
1474
+ async function st(o) {
1475
+ const e = await rt(o);
1476
+ try {
1477
+ return ot(e);
1478
+ } finally {
1479
+ e.close();
1480
+ }
1481
+ }
1482
+ async function rt(o) {
1483
+ if (o instanceof ImageBitmap)
1484
+ return o;
1485
+ const e = new Blob([o]);
1486
+ return createImageBitmap(e);
1487
+ }
1488
+ function ot(o) {
1489
+ const t = new OffscreenCanvas(o.width, o.height).getContext("2d");
1490
+ if (!t)
1491
+ throw new Error("Failed to obtain 2D context for decoding the colormap sprite.");
1492
+ return t.drawImage(o, 0, 0), t.getImageData(0, 0, o.width, o.height);
1493
+ }
1494
+ const N = "nodata", it = `uniform ${N}Uniforms {
1495
+ float value;
1496
+ } ${N};
1497
+ `, at = {
1498
+ name: N,
1499
+ fs: it,
1500
+ inject: {
1501
+ "fs:DECKGL_FILTER_COLOR": (
1502
+ /* glsl */
1503
+ `
1504
+ if (color.r == nodata.value) {
1505
+ discard;
1506
+ }
1507
+ `
1508
+ )
1509
+ },
1510
+ uniformTypes: {
1511
+ value: "f32"
1512
+ },
1513
+ getUniforms: (o) => ({
1514
+ value: o.value
1515
+ })
1516
+ }, M = "linearRescale", ct = {
1517
+ name: M,
1518
+ fs: `uniform ${M}Uniforms {
1519
+ float rescaleMin;
1520
+ float rescaleMax;
1521
+ } ${M};
1522
+ `,
1523
+ inject: {
1524
+ "fs:DECKGL_FILTER_COLOR": (
1525
+ /* glsl */
1526
+ `
1527
+ color.rgb = clamp((color.rgb - ${M}.rescaleMin) / (${M}.rescaleMax - ${M}.rescaleMin), 0.0, 1.0);
1528
+ `
1529
+ )
1530
+ },
1531
+ uniformTypes: {
1532
+ rescaleMin: "f32",
1533
+ rescaleMax: "f32"
1534
+ },
1535
+ getUniforms: (o) => ({
1536
+ rescaleMin: o.rescaleMin ?? 0,
1537
+ rescaleMax: o.rescaleMax ?? 1
1538
+ })
1539
+ }, lt = "data:image/png;base64,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", _ = /* @__PURE__ */ new WeakMap();
1540
+ function bt(o) {
1541
+ const e = _.get(o);
1542
+ if (e) return e;
1543
+ const t = (async () => {
1544
+ const n = await (await fetch(lt)).arrayBuffer();
1545
+ return nt(o, await st(n));
1546
+ })();
1547
+ return _.set(o, t), t;
1548
+ }
1549
+ const $ = /* @__PURE__ */ new Set();
1550
+ function ut(o) {
1551
+ return o in X ? X[o] : ($.has(o) || ($.add(o), console.warn(`[onlymapjs] raster: unknown colormap "${o}" — falling back to gray.`)), X.gray);
1552
+ }
1553
+ function Tt(o, e) {
1554
+ const t = [
1555
+ // Per-tile textureName (not the layer-level `image:` shorthand — that
1556
+ // binds only the first tile's sampler in this setup).
1557
+ { module: se, props: { textureName: o.texture } }
1558
+ ], n = e.nodataOverride ?? o.nodata;
1559
+ return n != null && Number.isFinite(n) && t.push({ module: at, props: { value: n } }), t.push({
1560
+ module: ct,
1561
+ props: { rescaleMin: e.rescaleMin ?? 0, rescaleMax: e.rescaleMax ?? 255 }
1562
+ }), o.bandCount === 1 && t.push({
1563
+ module: tt,
1564
+ props: { colormapTexture: o.colormapTexture, colormapIndex: ut(e.colormap ?? "gray") }
1565
+ }), { renderPipeline: t };
1566
+ }
1567
+ export {
1568
+ mt as A,
1569
+ tt as C,
1570
+ at as F,
1571
+ xt as R,
1572
+ y as a,
1573
+ se as b,
1574
+ ze as c,
1575
+ ft as d,
1576
+ vt as e,
1577
+ Pt as f,
1578
+ Tt as g,
1579
+ bt as h,
1580
+ q as i,
1581
+ gt as m,
1582
+ Ie as p,
1583
+ pt as s,
1584
+ Re as t
1585
+ };