@nika-js/onlymap 0.4.6 → 0.5.1

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.
Files changed (34) hide show
  1. package/README.md +6 -4
  2. package/THIRD-PARTY-LICENSES.md +2 -2
  3. package/dist/{LercDecode.es-B49qauXg.js → LercDecode.es-BNF7PeWz.js} +1 -1
  4. package/dist/{basemap-nJ_ODY7r.js → basemap-7GQL0KSL.js} +1 -1
  5. package/dist/cityjson-urQeujQv.js +407 -0
  6. package/dist/cityjson.d.ts +138 -0
  7. package/dist/data-layer.d.ts +21 -0
  8. package/dist/elements/om-map.d.ts +30 -0
  9. package/dist/{index-uDJbHjA9.js → index-7PZgoR0X.js} +1 -1
  10. package/dist/{index-CeOjfL2p.js → index-9W_UXlPB.js} +2 -2
  11. package/dist/{index-DjlGZov2.js → index-BKiYWYJz.js} +1 -1
  12. package/dist/index-CW1n5LdO.js +4006 -0
  13. package/dist/{index-o_yRv2lD.js → index-ULFXRQAo.js} +1 -1
  14. package/dist/{index-DSkgI4Oc.js → index-ppCRU8Eb.js} +11369 -11186
  15. package/dist/ir-snapshot.d.ts +2 -0
  16. package/dist/ir.d.ts +7 -0
  17. package/dist/layer-registry.d.ts +14 -0
  18. package/dist/{lerc-CaQOmDCP.js → lerc-C-D0ZLmp.js} +2 -2
  19. package/dist/license.d.ts +34 -8
  20. package/dist/onlymap.standalone.js +22520 -21925
  21. package/dist/onlymapjs.js +19 -19
  22. package/dist/quota-notice.d.ts +43 -0
  23. package/dist/raster-D43jYSib.js +4842 -0
  24. package/dist/runtime-core.d.ts +1 -0
  25. package/dist/version.d.ts +1 -1
  26. package/docs/3d-assets.md +99 -1
  27. package/llms.txt +2 -2
  28. package/onlymapjs.html-data.json +12 -8
  29. package/package.json +2 -1
  30. package/skills/onlymapjs/SKILL.md +3 -1
  31. package/skills/onlymapjs/references/patterns.md +4 -0
  32. package/skills/onlymapjs/references/syntax.md +85 -16
  33. package/skills/onlymapjs/references/testing.md +1 -1
  34. package/dist/raster-DMq8FgiV.js +0 -8843
@@ -0,0 +1,4842 @@
1
+ import Ae from "./index-CW1n5LdO.js";
2
+ import { ak as Mt, al as Rt, am as tt, an as nt, ao as zt, b as Ft, ap as Dt, l as Ee, aq as Nt, d as Ut, ar as Bt, as as Gt, at as Kt, au as rt } from "./index-ppCRU8Eb.js";
3
+ import { w as _t } from "./mgrs-BY9bIvp4.js";
4
+ function Xt(e, t, n) {
5
+ const { projectedCorners: r } = t, { topLeft: o, topRight: i, bottomRight: s, bottomLeft: a } = r, l = n(o[0], o[1]), c = n(i[0], i[1]), u = n(s[0], s[1]), h = n(a[0], a[1]), p = [
6
+ l,
7
+ c,
8
+ u,
9
+ h,
10
+ l
11
+ ], d = [
12
+ (l[0] + u[0]) / 2,
13
+ (l[1] + u[1]) / 2
14
+ ], g = new Mt({
15
+ id: `${e}-label`,
16
+ data: [
17
+ {
18
+ position: d,
19
+ text: `x=${t.index.x} y=${t.index.y} z=${t.index.z}`
20
+ }
21
+ ],
22
+ getColor: [255, 255, 255, 255],
23
+ getSize: 24,
24
+ sizeUnits: "pixels",
25
+ outlineWidth: 3,
26
+ outlineColor: [0, 0, 0, 255],
27
+ fontSettings: { sdf: !0 }
28
+ });
29
+ return [new Rt({
30
+ id: e,
31
+ data: [p],
32
+ getPath: (y) => y,
33
+ getColor: [255, 0, 0, 255],
34
+ // Red
35
+ getWidth: 2,
36
+ widthUnits: "pixels",
37
+ pickable: !1
38
+ }), g];
39
+ }
40
+ const Wt = [
41
+ [1 / 3, 1 / 3, 1 / 3],
42
+ // centroid
43
+ [0.5, 0.5, 0],
44
+ // edge 0–1
45
+ [0.5, 0, 0.5],
46
+ // edge 0–2
47
+ [0, 0.5, 0.5]
48
+ // edge 1–2
49
+ ], Ht = 0.125;
50
+ class kt {
51
+ reprojectors;
52
+ /** Width of the image in pixels */
53
+ width;
54
+ /** Height of the image in pixels */
55
+ height;
56
+ /**
57
+ * UV vertex coordinates (x, y), i.e.
58
+ * [x0, y0, x1, y1, ...]
59
+ *
60
+ * These coordinates are floats that range from [0, 1] in both X and Y.
61
+ */
62
+ uvs;
63
+ /**
64
+ * XY Positions in output CRS, computed via exact forward reprojection.
65
+ */
66
+ exactOutputPositions;
67
+ /**
68
+ * triangle vertex indices
69
+ */
70
+ triangles;
71
+ _halfedges;
72
+ /**
73
+ * The UV texture coordinates of candidates found from
74
+ * `findReprojectionCandidate`.
75
+ *
76
+ * Maybe in the future we'll want to store the barycentric coordinates instead
77
+ * of just the uv coordinates?
78
+ */
79
+ _candidatesUV;
80
+ _queueIndices;
81
+ _queue;
82
+ _errors;
83
+ _pending;
84
+ _pendingLen;
85
+ constructor(t, n, r = n) {
86
+ this.reprojectors = t, this.width = n, this.height = r, this.uvs = [], this.exactOutputPositions = [], this.triangles = [], this._halfedges = [], this._candidatesUV = [], this._queueIndices = [], this._queue = [], this._errors = [], this._pending = [], this._pendingLen = 0;
87
+ const o = 1, i = 1, s = this._addPoint(0, 0), a = this._addPoint(o, 0), l = this._addPoint(0, i), c = this._addPoint(o, i), u = this._addTriangle(c, s, l, -1, -1, -1);
88
+ this._addTriangle(s, c, a, u, -1, -1), this._flush();
89
+ }
90
+ /**
91
+ * Refine the mesh until its maximum error gets below the given one
92
+ *
93
+ * @param maxError The maximum reprojection error in input pixels that the mesh should achieve.
94
+ * @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.
95
+ *
96
+ * @return {[type]} [return description]
97
+ */
98
+ run(t = Ht, { maxIterations: n = 1e4 } = {}) {
99
+ if (t <= 0)
100
+ throw new Error("maxError must be positive");
101
+ let r = 0;
102
+ for (; this.getMaxError() > t; )
103
+ if (this.refine(), ++r > n) {
104
+ console.warn(`RasterReprojector: mesh refinement did not converge after ${r} iterations (maxError=${t}, currentError=${this.getMaxError()})`);
105
+ break;
106
+ }
107
+ }
108
+ // refine the mesh with a single point
109
+ refine() {
110
+ this._step(), this._flush();
111
+ }
112
+ // max error of the current mesh
113
+ getMaxError() {
114
+ return this._errors[0];
115
+ }
116
+ // rasterize and queue all triangles that got added or updated in _step
117
+ _flush() {
118
+ for (let t = 0; t < this._pendingLen; t++) {
119
+ const n = this._pending[t];
120
+ this._findReprojectionCandidate(n);
121
+ }
122
+ this._pendingLen = 0;
123
+ }
124
+ /**
125
+ * Conversion of upstream's `_findCandidate` for reprojection error handling.
126
+ *
127
+ * @param t The index (into `this.triangles`) of the pending triangle to process.
128
+ *
129
+ * @return Doesn't return; instead modifies internal state.
130
+ */
131
+ _findReprojectionCandidate(t) {
132
+ const n = 2 * this.triangles[t * 3 + 0], r = 2 * this.triangles[t * 3 + 1], o = 2 * this.triangles[t * 3 + 2], i = this.uvs[n], s = this.uvs[n + 1], a = this.uvs[r], l = this.uvs[r + 1], c = this.uvs[o], u = this.uvs[o + 1], h = this.exactOutputPositions[n], p = this.exactOutputPositions[n + 1], d = this.exactOutputPositions[r], g = this.exactOutputPositions[r + 1], f = this.exactOutputPositions[o], y = this.exactOutputPositions[o + 1];
133
+ let j = 0, b = 0, S = 0;
134
+ for (const v of Wt) {
135
+ const L = re(i, a, c, v[0], v[1], v[2]), E = re(s, l, u, v[0], v[1], v[2]), M = re(h, d, f, v[0], v[1], v[2]), z = re(p, g, y, v[0], v[1], v[2]), I = L * (this.width - 1), J = E * (this.height - 1), q = this.reprojectors.inverseReproject(M, z), te = this.reprojectors.inverseTransform(q[0], q[1]), ne = I - te[0], It = J - te[1], Oe = Math.hypot(ne, It);
136
+ Oe > j && (j = Oe, b = L, S = E);
137
+ }
138
+ (b === i && S === s || b === a && S === l || b === c && S === u) && (j = 0), this._candidatesUV[2 * t] = b, this._candidatesUV[2 * t + 1] = S, this._queuePush(t, j);
139
+ }
140
+ // process the next triangle in the queue, splitting it with a new point
141
+ _step() {
142
+ const t = this._queuePop(), n = t * 3 + 0, r = t * 3 + 1, o = t * 3 + 2, i = this.triangles[n], s = this.triangles[r], a = this.triangles[o], l = this.uvs[2 * i], c = this.uvs[2 * i + 1], u = this.uvs[2 * s], h = this.uvs[2 * s + 1], p = this.uvs[2 * a], d = this.uvs[2 * a + 1], g = this._candidatesUV[2 * t], f = this._candidatesUV[2 * t + 1], y = this._addPoint(g, f);
143
+ if (ce(l, c, u, h, g, f) === 0)
144
+ this._handleCollinear(y, n);
145
+ else if (ce(u, h, p, d, g, f) === 0)
146
+ this._handleCollinear(y, r);
147
+ else if (ce(p, d, l, c, g, f) === 0)
148
+ this._handleCollinear(y, o);
149
+ else {
150
+ const j = this._halfedges[n], b = this._halfedges[r], S = this._halfedges[o], v = this._addTriangle(i, s, y, j, -1, -1, n), L = this._addTriangle(s, a, y, b, -1, v + 1), E = this._addTriangle(a, i, y, S, v + 2, L + 1);
151
+ this._legalize(v), this._legalize(L), this._legalize(E);
152
+ }
153
+ }
154
+ // add coordinates for a new vertex
155
+ _addPoint(t, n) {
156
+ const r = this.uvs.length >> 1;
157
+ this.uvs.push(t, n);
158
+ const o = t * (this.width - 1), i = n * (this.height - 1), s = this.reprojectors.forwardTransform(o, i), a = this.reprojectors.forwardReproject(s[0], s[1]);
159
+ return this.exactOutputPositions.push(a[0], a[1]), r;
160
+ }
161
+ // add or update a triangle in the mesh
162
+ _addTriangle(t, n, r, o, i, s, a = this.triangles.length) {
163
+ const l = a / 3;
164
+ return this.triangles[a + 0] = t, this.triangles[a + 1] = n, this.triangles[a + 2] = r, this._halfedges[a + 0] = o, this._halfedges[a + 1] = i, this._halfedges[a + 2] = s, o >= 0 && (this._halfedges[o] = a + 0), i >= 0 && (this._halfedges[i] = a + 1), s >= 0 && (this._halfedges[s] = a + 2), this._candidatesUV[2 * l + 0] = 0, this._candidatesUV[2 * l + 1] = 0, this._queueIndices[l] = -1, this._pending[this._pendingLen++] = l, a;
165
+ }
166
+ _legalize(t) {
167
+ const n = this._halfedges[t];
168
+ if (n < 0)
169
+ return;
170
+ const r = t - t % 3, o = n - n % 3, i = r + (t + 1) % 3, s = r + (t + 2) % 3, a = o + (n + 2) % 3, l = o + (n + 1) % 3, c = this.triangles[s], u = this.triangles[t], h = this.triangles[i], p = this.triangles[a], d = this.uvs;
171
+ if (!Zt(d[2 * c], d[2 * c + 1], d[2 * u], d[2 * u + 1], d[2 * h], d[2 * h + 1], d[2 * p], d[2 * p + 1]))
172
+ return;
173
+ const g = this._halfedges[i], f = this._halfedges[s], y = this._halfedges[a], j = this._halfedges[l];
174
+ this._queueRemove(r / 3), this._queueRemove(o / 3);
175
+ const b = this._addTriangle(c, p, h, -1, y, g, r), S = this._addTriangle(p, c, u, b, f, j, o);
176
+ this._legalize(b + 1), this._legalize(S + 2);
177
+ }
178
+ // handle a case where new vertex is on the edge of a triangle
179
+ _handleCollinear(t, n) {
180
+ const r = n - n % 3, o = r + (n + 1) % 3, i = r + (n + 2) % 3, s = this.triangles[i], a = this.triangles[n], l = this.triangles[o], c = this._halfedges[o], u = this._halfedges[i], h = this._halfedges[n];
181
+ if (h < 0) {
182
+ const E = this._addTriangle(t, s, a, -1, u, -1, r), M = this._addTriangle(s, t, l, E, -1, c);
183
+ this._legalize(E + 1), this._legalize(M + 2);
184
+ return;
185
+ }
186
+ const p = h - h % 3, d = p + (h + 2) % 3, g = p + (h + 1) % 3, f = this.triangles[d], y = this._halfedges[d], j = this._halfedges[g];
187
+ this._queueRemove(p / 3);
188
+ const b = this._addTriangle(s, a, t, u, -1, -1, r), S = this._addTriangle(a, f, t, j, -1, b + 1, p), v = this._addTriangle(f, l, t, y, -1, S + 1), L = this._addTriangle(l, s, t, c, b + 2, v + 1);
189
+ this._legalize(b), this._legalize(S), this._legalize(v), this._legalize(L);
190
+ }
191
+ // priority queue methods
192
+ _queuePush(t, n) {
193
+ const r = this._queue.length;
194
+ this._queueIndices[t] = r, this._queue.push(t), this._errors.push(n), this._queueUp(r);
195
+ }
196
+ _queuePop() {
197
+ const t = this._queue.length - 1;
198
+ return this._queueSwap(0, t), this._queueDown(0, t), this._queuePopBack();
199
+ }
200
+ _queuePopBack() {
201
+ const t = this._queue.pop();
202
+ return this._errors.pop(), this._queueIndices[t] = -1, t;
203
+ }
204
+ _queueRemove(t) {
205
+ const n = this._queueIndices[t];
206
+ if (n < 0) {
207
+ const o = this._pending.indexOf(t);
208
+ if (o !== -1)
209
+ this._pending[o] = this._pending[--this._pendingLen];
210
+ else
211
+ throw new Error("Broken triangulation (something went wrong).");
212
+ return;
213
+ }
214
+ const r = this._queue.length - 1;
215
+ r !== n && (this._queueSwap(n, r), this._queueDown(n, r) || this._queueUp(n)), this._queuePopBack();
216
+ }
217
+ _queueLess(t, n) {
218
+ return this._errors[t] > this._errors[n];
219
+ }
220
+ _queueSwap(t, n) {
221
+ const r = this._queue[t], o = this._queue[n];
222
+ this._queue[t] = o, this._queue[n] = r, this._queueIndices[r] = n, this._queueIndices[o] = t;
223
+ const i = this._errors[t];
224
+ this._errors[t] = this._errors[n], this._errors[n] = i;
225
+ }
226
+ _queueUp(t) {
227
+ let n = t;
228
+ for (; ; ) {
229
+ const r = n - 1 >> 1;
230
+ if (r === n || !this._queueLess(n, r))
231
+ break;
232
+ this._queueSwap(r, n), n = r;
233
+ }
234
+ }
235
+ _queueDown(t, n) {
236
+ let r = t;
237
+ for (; ; ) {
238
+ const o = 2 * r + 1;
239
+ if (o >= n || o < 0)
240
+ break;
241
+ const i = o + 1;
242
+ let s = o;
243
+ if (i < n && this._queueLess(i, o) && (s = i), !this._queueLess(s, r))
244
+ break;
245
+ this._queueSwap(r, s), r = s;
246
+ }
247
+ return r > t;
248
+ }
249
+ }
250
+ function ce(e, t, n, r, o, i) {
251
+ return (n - o) * (t - i) - (r - i) * (e - o);
252
+ }
253
+ function Zt(e, t, n, r, o, i, s, a) {
254
+ const l = e - s, c = t - a, u = n - s, h = r - a, p = o - s, d = i - a, g = l * l + c * c, f = u * u + h * h, y = p * p + d * d;
255
+ return l * (h * y - f * d) - c * (u * y - f * p) + g * (u * d - h * p) < 0;
256
+ }
257
+ function re(e, t, n, r, o, i) {
258
+ return r * e + o * t + i * n;
259
+ }
260
+ const Se = {
261
+ name: "create-texture-unorm",
262
+ inject: {
263
+ "fs:#decl": "uniform sampler2D textureName;",
264
+ "fs:DECKGL_FILTER_COLOR": (
265
+ /* glsl */
266
+ `
267
+ color = texture(textureName, geometry.uv);
268
+ `
269
+ )
270
+ },
271
+ getUniforms: (e) => ({
272
+ textureName: e.textureName
273
+ })
274
+ }, Vt = (
275
+ /* glsl */
276
+ `#version 300 es
277
+ #define SHADER_NAME simple-mesh-layer-fs
278
+
279
+ precision highp float;
280
+
281
+ in vec2 vTexCoord;
282
+ in vec3 cameraPosition;
283
+ in vec3 normals_commonspace;
284
+ in vec4 position_commonspace;
285
+ in vec4 vColor;
286
+
287
+ out vec4 fragColor;
288
+
289
+ void main(void) {
290
+ geometry.uv = vTexCoord;
291
+
292
+ vec3 normal;
293
+ if (simpleMesh.flatShading) {
294
+
295
+ normal = normalize(cross(dFdx(position_commonspace.xyz), dFdy(position_commonspace.xyz)));
296
+ } else {
297
+ normal = normals_commonspace;
298
+ }
299
+
300
+ // We initialize color here before passing into DECKGL_FILTER_COLOR
301
+ vec4 color;
302
+ DECKGL_FILTER_COLOR(color, geometry);
303
+
304
+ vec3 lightColor = lighting_getLightColor(color.rgb, cameraPosition, position_commonspace.xyz, normal);
305
+ fragColor = vec4(lightColor, color.a * layer.opacity);
306
+ }
307
+ `
308
+ ), Yt = {
309
+ ...tt.defaultProps,
310
+ // Note: putting `image` in defaultProps causes Maplibre to fail to render
311
+ // labels in interleaved mode 🤷‍♂️
312
+ // image: { type: "image", value: null, async: true },
313
+ renderPipeline: { type: "array", value: [], compare: !0 },
314
+ // Disable lighting by default (avoids darkening raster)
315
+ material: {
316
+ ambient: 1,
317
+ diffuse: 0,
318
+ shininess: 0,
319
+ specularColor: [0, 0, 0]
320
+ }
321
+ };
322
+ class Jt extends tt {
323
+ static layerName = "mesh-texture-layer";
324
+ static defaultProps = Yt;
325
+ _resolveRenderPipeline() {
326
+ const { image: t, renderPipeline: n } = this.props;
327
+ return [...t ? [{ module: Se, props: { textureName: t } }] : [], ...n ?? []];
328
+ }
329
+ updateState(t) {
330
+ this.hasRenderPipelineChanged(t) && (t.changeFlags.extensionsChanged = !0), super.updateState(t);
331
+ }
332
+ /** Returns true if the render pipeline has changed between the old and new props. */
333
+ hasRenderPipelineChanged(t) {
334
+ const { oldProps: n, props: r } = t;
335
+ if (!!n.image != !!r.image)
336
+ return !0;
337
+ const o = n.renderPipeline ?? [], i = r.renderPipeline ?? [];
338
+ if (o.length !== i.length)
339
+ return !0;
340
+ for (let s = 0; s < o.length; s++)
341
+ if (o[s]?.module.name !== i[s]?.module.name)
342
+ return !0;
343
+ return !1;
344
+ }
345
+ getShaders() {
346
+ const t = super.getShaders(), n = t.modules;
347
+ for (const r of this._resolveRenderPipeline())
348
+ n.push(r.module);
349
+ return {
350
+ ...t,
351
+ // Override upstream's fragment shader with our copy with modified
352
+ // injection points
353
+ fs: Vt,
354
+ modules: n
355
+ };
356
+ }
357
+ draw(t) {
358
+ const n = {};
359
+ for (const r of this._resolveRenderPipeline())
360
+ n[r.module.name] = r.props || {};
361
+ for (const r of super.getModels())
362
+ r.shaderInputs.setProps(n);
363
+ super.draw(t);
364
+ }
365
+ }
366
+ const qt = 0.125, Ie = [
367
+ [252, 73, 163],
368
+ // pink
369
+ [255, 51, 204],
370
+ // magenta-pink
371
+ [204, 102, 255],
372
+ // purple-ish
373
+ [153, 51, 255],
374
+ // deep purple
375
+ [102, 204, 255],
376
+ // sky blue
377
+ [51, 153, 255],
378
+ // clear blue
379
+ [102, 255, 204],
380
+ // teal
381
+ [51, 255, 170],
382
+ // aqua-teal
383
+ [0, 255, 0],
384
+ // lime green
385
+ [51, 204, 51],
386
+ // stronger green
387
+ [255, 204, 102],
388
+ // light orange
389
+ [255, 179, 71],
390
+ // golden-orange
391
+ [255, 102, 102],
392
+ // salmon
393
+ [255, 80, 80],
394
+ // red-salmon
395
+ [255, 0, 0],
396
+ // red
397
+ [204, 0, 0],
398
+ // crimson
399
+ [255, 128, 0],
400
+ // orange
401
+ [255, 153, 51],
402
+ // bright orange
403
+ [255, 255, 102],
404
+ // yellow
405
+ [255, 255, 51],
406
+ // lemon
407
+ [0, 255, 255],
408
+ // turquoise
409
+ [0, 204, 255]
410
+ // cyan
411
+ ], Qt = {
412
+ // A prop with `type: "image"` gets converted to a texture automatically by
413
+ // deck.gl (as long as async: true)
414
+ image: { type: "image", value: null, async: !0 },
415
+ renderPipeline: { type: "array", value: [], compare: !0 },
416
+ debug: !1,
417
+ debugOpacity: 0.5
418
+ };
419
+ class Tt extends nt {
420
+ static layerName = "RasterLayer";
421
+ static defaultProps = Qt;
422
+ initializeState() {
423
+ this.setState({});
424
+ }
425
+ updateState(t) {
426
+ super.updateState(t);
427
+ const { props: n, oldProps: r, changeFlags: o } = t, i = n.reprojectionFns.forwardTransform !== r.reprojectionFns?.forwardTransform || n.reprojectionFns.inverseTransform !== r.reprojectionFns?.inverseTransform || n.reprojectionFns.forwardReproject !== r.reprojectionFns?.forwardReproject || n.reprojectionFns.inverseReproject !== r.reprojectionFns?.inverseReproject;
428
+ (!!o.dataChanged || n.width !== r.width || n.height !== r.height || i || n.maxError !== r.maxError) && this._generateMesh();
429
+ }
430
+ _generateMesh() {
431
+ const { width: t, height: n, reprojectionFns: r, maxError: o = qt } = this.props, i = new kt(r, t + 1, n + 1);
432
+ i.run(o);
433
+ const { indices: s, positions: a, texCoords: l } = $t(i);
434
+ this.setState({
435
+ reprojector: i,
436
+ mesh: {
437
+ indices: { value: s, size: 1 },
438
+ attributes: {
439
+ POSITION: { value: a, size: 3 },
440
+ TEXCOORD_0: { value: l, size: 2 }
441
+ }
442
+ }
443
+ });
444
+ }
445
+ renderDebugLayer() {
446
+ const { reprojector: t } = this.state, { debugOpacity: n } = this.props;
447
+ return t ? new zt(this.getSubLayerProps({
448
+ id: "polygon",
449
+ // https://deck.gl/docs/developer-guide/performance#supply-binary-blobs-to-the-data-prop
450
+ // This `data` gets passed into `getPolygon` with the row index.
451
+ data: { reprojector: t, length: t.triangles.length / 3 },
452
+ getPolygon: (r, { index: o, data: i }) => {
453
+ const s = i.reprojector.triangles, a = t.exactOutputPositions, l = s[o * 3], c = s[o * 3 + 1], u = s[o * 3 + 2];
454
+ return [
455
+ [a[l * 2], a[l * 2 + 1]],
456
+ [a[c * 2], a[c * 2 + 1]],
457
+ [a[u * 2], a[u * 2 + 1]],
458
+ [a[l * 2], a[l * 2 + 1]]
459
+ ];
460
+ },
461
+ getFillColor: (r, { index: o, target: i }) => {
462
+ const s = Ie[o % Ie.length];
463
+ return i[0] = s[0], i[1] = s[1], i[2] = s[2], i[3] = 255, i;
464
+ },
465
+ getLineColor: [0, 0, 0],
466
+ getLineWidth: 1,
467
+ lineWidthUnits: "pixels",
468
+ opacity: n !== void 0 && Number.isFinite(n) ? Math.max(0, Math.min(1, n)) : 1,
469
+ pickable: !1
470
+ })) : null;
471
+ }
472
+ renderLayers() {
473
+ const { mesh: t } = this.state, { debug: n, image: r, renderPipeline: o } = this.props;
474
+ if (!t || !r && (o?.length ?? 0) === 0)
475
+ return null;
476
+ const s = [new Jt(this.getSubLayerProps({
477
+ id: "raster",
478
+ image: r,
479
+ renderPipeline: o,
480
+ // Dummy data because we're only rendering _one_ instance of this mesh
481
+ // https://github.com/visgl/deck.gl/blob/93111b667b919148da06ff1918410cf66381904f/modules/geo-layers/src/terrain-layer/terrain-layer.ts#L241
482
+ data: [1],
483
+ mesh: t,
484
+ // We're only rendering a single mesh, without instancing
485
+ // https://github.com/visgl/deck.gl/blob/93111b667b919148da06ff1918410cf66381904f/modules/geo-layers/src/terrain-layer/terrain-layer.ts#L244
486
+ _instanced: !1,
487
+ // Dummy accessors for the dummy data
488
+ // We place our mesh at the coordinate origin
489
+ getPosition: [0, 0, 0],
490
+ // We give a white color to turn off color mixing with the texture
491
+ getColor: [255, 255, 255]
492
+ }))];
493
+ if (n) {
494
+ const a = this.renderDebugLayer();
495
+ a && s.push(a);
496
+ }
497
+ return s;
498
+ }
499
+ }
500
+ function $t(e) {
501
+ const t = e.uvs.length / 2, n = new Float32Array(t * 3), r = new Float32Array(e.uvs);
502
+ for (let i = 0; i < t; i++)
503
+ n[i * 3] = e.exactOutputPositions[i * 2], n[i * 3 + 1] = e.exactOutputPositions[i * 2 + 1], n[i * 3 + 2] = 0;
504
+ return {
505
+ indices: new Uint32Array(e.triangles),
506
+ positions: n,
507
+ texCoords: r
508
+ };
509
+ }
510
+ class en {
511
+ levels;
512
+ projectTo3857;
513
+ projectFrom3857;
514
+ projectTo4326;
515
+ projectFrom4326;
516
+ projectedBounds;
517
+ constructor(t) {
518
+ if (t.levels.length === 0)
519
+ throw new Error("AffineTileset requires at least one level");
520
+ this.levels = t.levels, this.projectTo3857 = t.projectTo3857, this.projectFrom3857 = t.projectFrom3857, this.projectTo4326 = t.projectTo4326, this.projectFrom4326 = t.projectFrom4326, this.projectedBounds = t.levels[0].projectedBounds;
521
+ }
522
+ }
523
+ function Le(e, t) {
524
+ return [1, 0, e, 0, 1, t];
525
+ }
526
+ function tn(e, t = e) {
527
+ return [e, 0, 0, 0, t, 0];
528
+ }
529
+ function A([e, t, n, r, o, i], s, a) {
530
+ return [
531
+ e * s + t * a + n,
532
+ r * s + o * a + i
533
+ ];
534
+ }
535
+ function ae([e, t, n, r, o, i], [s, a, l, c, u, h]) {
536
+ return [
537
+ e * s + t * c,
538
+ e * a + t * u,
539
+ e * l + t * h + n,
540
+ r * s + o * c,
541
+ r * a + o * u,
542
+ r * l + o * h + i
543
+ ];
544
+ }
545
+ function de([e, t, n, r, o, i]) {
546
+ const s = e * o - t * r;
547
+ if (s === 0)
548
+ throw new Error("Cannot invert degenerate transform");
549
+ const a = 1 / s, l = o * a, c = -t * a, u = -r * a, h = e * a;
550
+ return [
551
+ l,
552
+ c,
553
+ -n * l - i * c,
554
+ u,
555
+ h,
556
+ -n * u - i * h
557
+ ];
558
+ }
559
+ function nn(e) {
560
+ return e[0];
561
+ }
562
+ function rn(e) {
563
+ return e[4];
564
+ }
565
+ class on {
566
+ tileWidth;
567
+ tileHeight;
568
+ matrixWidth;
569
+ matrixHeight;
570
+ metersPerPixel;
571
+ /**
572
+ * Source-CRS bounding box of the level's array `[minX, minY, maxX, maxY]`.
573
+ * Computed from the affine applied to the four array corners.
574
+ */
575
+ projectedBounds;
576
+ _affine;
577
+ _invAffine;
578
+ constructor(t) {
579
+ this._affine = t.affine, this._invAffine = de(t.affine), this.tileWidth = t.tileWidth, this.tileHeight = t.tileHeight, this.matrixWidth = Math.ceil(t.arrayWidth / t.tileWidth), this.matrixHeight = Math.ceil(t.arrayHeight / t.tileHeight);
580
+ const n = nn(t.affine), r = rn(t.affine);
581
+ this.metersPerPixel = Math.sqrt(Math.abs(n * r)) * t.mpu;
582
+ const o = [
583
+ A(t.affine, 0, 0),
584
+ A(t.affine, t.arrayWidth, 0),
585
+ A(t.affine, 0, t.arrayHeight),
586
+ A(t.affine, t.arrayWidth, t.arrayHeight)
587
+ ], i = o.map(([a]) => a), s = o.map(([, a]) => a);
588
+ this.projectedBounds = [
589
+ Math.min(...i),
590
+ Math.min(...s),
591
+ Math.max(...i),
592
+ Math.max(...s)
593
+ ];
594
+ }
595
+ projectedTileCorners(t, n) {
596
+ const r = this.tileWidth, o = this.tileHeight, i = this._affine;
597
+ return {
598
+ topLeft: A(i, t * r, n * o),
599
+ topRight: A(i, (t + 1) * r, n * o),
600
+ bottomLeft: A(i, t * r, (n + 1) * o),
601
+ bottomRight: A(i, (t + 1) * r, (n + 1) * o)
602
+ };
603
+ }
604
+ tileTransform(t, n) {
605
+ const r = Le(t * this.tileWidth, n * this.tileHeight), o = ae(this._affine, r), i = de(o);
606
+ return {
607
+ forwardTransform: (s, a) => A(o, s, a),
608
+ inverseTransform: (s, a) => A(i, s, a)
609
+ };
610
+ }
611
+ crsBoundsToTileRange(t, n, r, o) {
612
+ const i = this._invAffine, s = [
613
+ A(i, t, n),
614
+ A(i, r, n),
615
+ A(i, t, o),
616
+ A(i, r, o)
617
+ ], a = s.map(([L]) => L), l = s.map(([, L]) => L), c = Math.min(...a), u = Math.max(...a), h = Math.min(...l), p = Math.max(...l), d = this.tileWidth, g = this.tileHeight, f = this.matrixWidth - 1, y = this.matrixHeight - 1, j = Math.max(0, Math.floor(c / d)), b = Math.min(f, Math.floor(u / d)), S = Math.max(0, Math.floor(h / g)), v = Math.min(y, Math.floor(p / g));
618
+ return { minCol: j, maxCol: b, minRow: S, maxRow: v };
619
+ }
620
+ }
621
+ function sn(e, { semiMajorAxis: t } = {}) {
622
+ switch (e = e.toLowerCase(), e) {
623
+ case "m":
624
+ case "metre":
625
+ case "meter":
626
+ case "meters":
627
+ return 1;
628
+ case "foot":
629
+ return 0.3048;
630
+ case "us survey foot":
631
+ return 1200 / 3937;
632
+ }
633
+ if (e === "degree") {
634
+ if (t === void 0)
635
+ throw new Error("CRS with degrees unit requires ellipsoid semi-major-axis");
636
+ return 2 * Math.PI * t / 360;
637
+ }
638
+ throw new Error(`Unsupported CRS units: ${e} when computing metersPerUnit.`);
639
+ }
640
+ function ot(e) {
641
+ const t = _t(e);
642
+ return t.projName === "longlat" && (!t.units || t.units === "unknown") && (t.units = "degree", t.to_meter = void 0), t;
643
+ }
644
+ const Me = /* @__PURE__ */ new Map();
645
+ async function an(e) {
646
+ const t = `EPSG:${e}`, n = Me.get(t);
647
+ if (n !== void 0)
648
+ return n;
649
+ const r = await ln(e), o = ot(r);
650
+ return Me.set(t, o), o;
651
+ }
652
+ async function ln(e) {
653
+ const t = `https://epsg.io/${e}.json`, n = await fetch(t);
654
+ if (!n.ok)
655
+ throw new Error(`Failed to fetch PROJJSON from ${t}`);
656
+ return await n.json();
657
+ }
658
+ function pe(e, t, n, r, o, i = {}) {
659
+ const { densifyPts: s = 21 } = i, a = [t, r, r, t], l = [n, n, o, o];
660
+ let c = 1 / 0, u = 1 / 0, h = -1 / 0, p = -1 / 0;
661
+ for (let d = 0; d < 4; d++) {
662
+ const g = a[d], f = l[d], y = a[(d + 1) % 4], j = l[(d + 1) % 4];
663
+ for (let b = 0; b <= s; b++) {
664
+ const S = b / (s + 1), [v, L] = e(g + (y - g) * S, f + (j - f) * S);
665
+ v < c && (c = v), L < u && (u = L), v > h && (h = v), L > p && (p = L);
666
+ }
667
+ }
668
+ return [c, u, h, p];
669
+ }
670
+ const Re = 6378137, ze = 85.05112877980659;
671
+ function cn(e, t) {
672
+ const n = e * Math.PI * Re / 180, r = t * Math.PI / 180, o = Math.log(Math.tan(Math.PI / 4 + r / 2)) * Re;
673
+ return [n, o];
674
+ }
675
+ function un(e, t) {
676
+ return (n, r) => {
677
+ const [o, i] = e(n, r);
678
+ if (Number.isFinite(o) && Number.isFinite(i))
679
+ return [o, i];
680
+ const [s, a] = t(n, r), l = Math.max(-ze, Math.min(ze, a));
681
+ return cn(s, l);
682
+ };
683
+ }
684
+ const hn = 65536;
685
+ class it {
686
+ entries = /* @__PURE__ */ new Map();
687
+ maxEntries;
688
+ constructor({ maxEntries: t = hn } = {}) {
689
+ this.maxEntries = Math.max(0, t);
690
+ }
691
+ /** Number of cached entries. */
692
+ get size() {
693
+ return this.entries.size;
694
+ }
695
+ /**
696
+ * Look up the cached bounding volume for tile `(z, x, y)`. On a hit the entry
697
+ * is marked most-recently-used. Returns `undefined` on a miss.
698
+ */
699
+ get(t, n, r) {
700
+ const o = `${t}/${n}/${r}`, i = this.entries.get(o);
701
+ if (i !== void 0)
702
+ return this.entries.delete(o), this.entries.set(o, i), i;
703
+ }
704
+ /** Store the bounding volume for tile `(z, x, y)` as most-recently-used. */
705
+ set(t, n, r, o) {
706
+ const i = `${t}/${n}/${r}`;
707
+ this.entries.delete(i), this.entries.set(i, o);
708
+ }
709
+ /**
710
+ * If the cache is over its soft cap, drop least-recently-used entries down to
711
+ * roughly half of `maxEntries`. No-op when at or under the cap. Call once at
712
+ * the start of a traversal, never mid-traversal.
713
+ */
714
+ sweep() {
715
+ if (this.entries.size <= this.maxEntries)
716
+ return;
717
+ const t = Math.floor(this.maxEntries / 2), n = this.entries.size - t, r = [];
718
+ for (const o of this.entries.keys())
719
+ if (r.push(o), r.length >= n)
720
+ break;
721
+ for (const o of r)
722
+ this.entries.delete(o);
723
+ }
724
+ }
725
+ const Fe = 512, dn = [
726
+ [0.5, 0.5],
727
+ // center
728
+ [0, 0],
729
+ // top-left
730
+ [0, 1],
731
+ // bottom-left
732
+ [1, 0],
733
+ // top-right
734
+ [1, 1]
735
+ // bottom-right
736
+ ], pn = dn.concat([
737
+ [0, 0.5],
738
+ // left edge
739
+ [0.5, 0],
740
+ // top edge
741
+ [1, 0.5],
742
+ // right edge
743
+ [0.5, 1]
744
+ // bottom edge
745
+ ]), me = 6378137, ge = 2 * Math.PI * me, De = ge / 2, Ne = 85.05112877980659;
746
+ class ie {
747
+ /** Index across a row */
748
+ x;
749
+ /** Index down a column */
750
+ y;
751
+ /** Zoom index assumed to be (higher = finer detail) */
752
+ z;
753
+ descriptor;
754
+ /**
755
+ * Flag indicating whether any descendant of this tile is visible.
756
+ *
757
+ * Used to prevent loading parent tiles when children are visible (avoids
758
+ * overdraw).
759
+ */
760
+ childVisible;
761
+ /**
762
+ * Flag indicating this tile should be rendered
763
+ *
764
+ * Set to `true` when this is the appropriate LOD for its distance from camera.
765
+ */
766
+ selected;
767
+ /** A cache of the children of this node. */
768
+ _children;
769
+ constructor(t, n, r, { descriptor: o }) {
770
+ this.x = t, this.y = n, this.z = r, this.descriptor = o;
771
+ }
772
+ /** Get the level info for this tile's z index. */
773
+ get level() {
774
+ return this.descriptor.levels[this.z];
775
+ }
776
+ /** Get the children of this node.
777
+ *
778
+ * Find all tiles at level this.z + 1 whose spatial extent overlaps this tile.
779
+ *
780
+ * A tileset pyramid is not guaranteed to be a quadtree — it is a stack of
781
+ * independent grids. We find children by mapping the parent tile's CRS bounds
782
+ * into the child grid using {@link RasterTilesetLevel.crsBoundsToTileRange}.
783
+ */
784
+ get children() {
785
+ if (!this._children) {
786
+ const t = this.descriptor.levels.length - 1;
787
+ if (this.z >= t)
788
+ return this._children = null, null;
789
+ const n = this.z + 1, r = this.descriptor.levels[n], o = this.level.projectedTileCorners(this.x, this.y), i = Sn(o), { minCol: s, maxCol: a, minRow: l, maxRow: c } = r.crsBoundsToTileRange(...i), u = [], { descriptor: h } = this;
790
+ for (let p = l; p <= c; p++)
791
+ for (let d = s; d <= a; d++)
792
+ u.push(new ie(d, p, n, { descriptor: h }));
793
+ this._children = u.length > 0 ? u : null;
794
+ }
795
+ return this._children;
796
+ }
797
+ /**
798
+ * Recursively traverse the tile pyramid to determine if this tile (or its
799
+ * descendants) should be rendered.
800
+ *
801
+ * I.e. "Given this tile node, should I render this tile, or should I recurse
802
+ * into its children?"
803
+ *
804
+ * The algorithm performs:
805
+ * 1. Visibility culling - reject tiles outside the view frustum
806
+ * 2. Bounds checking - reject tiles outside the specified geographic bounds
807
+ * 3. LOD selection - choose appropriate zoom level based on distance from camera
808
+ * 4. Recursive subdivision - if LOD is insufficient, test child tiles
809
+ *
810
+ * Additionally, there should never be overdraw, i.e. a tile should never be
811
+ * rendered if any of its descendants are rendered.
812
+ *
813
+ * @returns true if this tile or any descendant is visible, false otherwise
814
+ */
815
+ update(t) {
816
+ this.childVisible = !1, this.selected = !1;
817
+ const { viewport: n, cullingVolume: r, elevationBounds: o, minZ: i, maxZ: s = this.descriptor.levels.length - 1, project: a, bounds: l, pixelRatio: c, boundingVolumeCache: u } = t, { boundingVolume: h, commonSpaceBounds: p } = this.getBoundingVolume(o, a, u);
818
+ if (l && !this.insideBounds(l, p) || r.computeVisibility(h) < 0)
819
+ return !1;
820
+ const g = this.children;
821
+ if (!this.childVisible && this.z >= i) {
822
+ const f = vn(h, n.zoom);
823
+ if (this.level.metersPerPixel * c / f <= 1 || this.z >= s || g === null && this.z >= i)
824
+ return this.selected = !0, !0;
825
+ }
826
+ if (g && g.length > 0) {
827
+ this.selected = !1;
828
+ let f = !1;
829
+ for (const y of g)
830
+ y.update(t) && (f = !0);
831
+ return this.childVisible = f, f;
832
+ }
833
+ return !0;
834
+ }
835
+ /**
836
+ * Collect all tiles marked as selected in the tree.
837
+ * Recursively traverses the entire tree and gathers tiles where selected=true.
838
+ *
839
+ * @param result - Accumulator array for selected tiles
840
+ * @returns Array of selected RasterTileNode tiles
841
+ */
842
+ getSelected(t = []) {
843
+ if (this.selected && t.push(this), this._children)
844
+ for (const n of this._children)
845
+ n.getSelected(t);
846
+ return t;
847
+ }
848
+ /**
849
+ * Test if this tile intersects the specified bounds in Web Mercator space.
850
+ * Used to filter tiles when only a specific geographic region is needed.
851
+ *
852
+ * @param bounds - [minX, minY, maxX, maxY] in Web Mercator units (0-512)
853
+ * @returns true if tile overlaps the bounds
854
+ */
855
+ insideBounds(t, n) {
856
+ const [r, o, i, s] = t, [a, l, c, u] = n;
857
+ return a < i && c > r && l < s && u > o;
858
+ }
859
+ /**
860
+ * The 3D bounding volume for this tile in deck.gl's common coordinate space,
861
+ * used for frustum culling.
862
+ *
863
+ * Memoized in `boundingVolumeCache` (keyed by `z/x/y`): a tile's bounding
864
+ * volume depends only on `(z, x, y, zRange)` for a given descriptor, so on a
865
+ * cache hit it is returned without rerunning {@link computeBoundingVolume}'s
866
+ * proj4 reprojections + oriented-bounding-box fit.
867
+ */
868
+ getBoundingVolume(t, n, r) {
869
+ const o = r.get(this.z, this.x, this.y);
870
+ if (o && o.zRange[0] === t[0] && o.zRange[1] === t[1])
871
+ return o;
872
+ const i = this.computeBoundingVolume(t, n);
873
+ return r.set(this.z, this.x, this.y, { zRange: t, ...i }), i;
874
+ }
875
+ /**
876
+ * Compute (without caching) the 3D bounding volume for this tile in deck.gl's
877
+ * common coordinate space.
878
+ *
879
+ * TODO: In the future, we can add a fast path in the case that the source
880
+ * tiling is already in EPSG:3857.
881
+ */
882
+ computeBoundingVolume(t, n) {
883
+ return n && Ut(!1, "TODO: implement getBoundingVolume in Globe view"), this._getGenericBoundingVolume(t);
884
+ }
885
+ /**
886
+ * Generic case - sample reference points and reproject to Web Mercator, then
887
+ * convert to deck.gl common space
888
+ *
889
+ */
890
+ _getGenericBoundingVolume(t) {
891
+ const [n, r] = t, o = this.level.projectedTileCorners(this.x, this.y), s = gn(pn, o, this.descriptor.projectTo3857, this.descriptor.projectTo4326).map((d) => fn(d)), a = [];
892
+ for (const d of s)
893
+ a.push([d[0], d[1], n]), n !== r && a.push([d[0], d[1], r]);
894
+ let l = Number.POSITIVE_INFINITY, c = Number.POSITIVE_INFINITY, u = Number.NEGATIVE_INFINITY, h = Number.NEGATIVE_INFINITY;
895
+ for (const [d, g] of s)
896
+ d < l && (l = d), g < c && (c = g), d > u && (u = d), g > h && (h = g);
897
+ const p = [l, c, u, h];
898
+ return {
899
+ boundingVolume: Bt(a),
900
+ commonSpaceBounds: p
901
+ };
902
+ }
903
+ }
904
+ function mn(e, t) {
905
+ return (n, r) => {
906
+ const [o, i] = e(n, r);
907
+ if (Number.isFinite(o) && Number.isFinite(i))
908
+ return [o, i];
909
+ const [s, a] = t(n, r), c = Math.max(-Ne, Math.min(Ne, a)) * Math.PI / 180, u = s * Math.PI * me / 180, h = Math.log(Math.tan(Math.PI / 4 + c / 2)) * me;
910
+ return [u, h];
911
+ };
912
+ }
913
+ function gn(e, t, n, r) {
914
+ const { topLeft: o, topRight: i, bottomLeft: s, bottomRight: a } = t, l = mn(n, r), c = [];
915
+ for (const [u, h] of e) {
916
+ const [p, d] = Ln(o, i, s, a, u, h);
917
+ c.push(l(p, d));
918
+ }
919
+ return c;
920
+ }
921
+ function fn([e, t]) {
922
+ const n = Math.max(-De, Math.min(De, t));
923
+ return [
924
+ (e / ge + 0.5) * Fe,
925
+ (n / ge + 0.5) * Fe
926
+ ];
927
+ }
928
+ const yn = 100;
929
+ function wn(e) {
930
+ const { descriptor: t, viewport: n, datasetWgs84Bounds: r } = e, o = t.levels[0], i = [];
931
+ if (o.matrixWidth * o.matrixHeight <= yn) {
932
+ for (let g = 0; g < o.matrixHeight; g++)
933
+ for (let f = 0; f < o.matrixWidth; f++)
934
+ i.push(new ie(f, g, 0, { descriptor: t }));
935
+ return i;
936
+ }
937
+ const a = n.getBounds(), l = [
938
+ Math.max(r[0], a[0]),
939
+ Math.max(r[1], a[1]),
940
+ Math.min(r[2], a[2]),
941
+ Math.min(r[3], a[3])
942
+ ];
943
+ if (l[0] > l[2] || l[1] > l[3])
944
+ return i;
945
+ const [c, u, h, p] = pe(t.projectFrom4326, l[0], l[1], l[2], l[3]), d = o.crsBoundsToTileRange(c, u, h, p);
946
+ for (let g = d.minRow; g <= d.maxRow; g++)
947
+ for (let f = d.minCol; f <= d.maxCol; f++)
948
+ i.push(new ie(f, g, 0, { descriptor: t }));
949
+ return i;
950
+ }
951
+ function Pn(e, t) {
952
+ const { viewport: n, maxZ: r, zRange: o, wgs84Bounds: i, pixelRatio: s = 1 } = t, a = t.boundingVolumeCache ?? new it();
953
+ a.sweep();
954
+ const l = n instanceof Ft && n.resolution ? n.projectPosition : null, c = Object.values(n.getFrustumPlanes()).map(({ normal: I, distance: J }) => new Dt(I.clone().negate(), J)), u = new Nt(c), h = n.distanceScales.unitsPerMeter[2], p = o && o[0] * h || 0, d = o && o[1] * h || 0, g = 0, [f, y, j, b] = i, S = Ee([f, y]), v = Ee([j, b]), L = [
955
+ S[0],
956
+ S[1],
957
+ v[0],
958
+ v[1]
959
+ ], E = wn({
960
+ descriptor: e,
961
+ viewport: n,
962
+ datasetWgs84Bounds: i
963
+ }), M = {
964
+ viewport: n,
965
+ project: l,
966
+ cullingVolume: u,
967
+ elevationBounds: [p, d],
968
+ minZ: g,
969
+ maxZ: r,
970
+ bounds: L,
971
+ pixelRatio: s,
972
+ boundingVolumeCache: a
973
+ };
974
+ for (const I of E)
975
+ I.update(M);
976
+ const z = [];
977
+ for (const I of E)
978
+ I.getSelected(z);
979
+ return z;
980
+ }
981
+ function bn(e, t) {
982
+ return 40075016686e-3 * Math.cos(e * Math.PI / 180) / 2 ** (t + 8);
983
+ }
984
+ function vn(e, t) {
985
+ const [n, r] = Gt(e.center);
986
+ return bn(r, t);
987
+ }
988
+ function Sn({ topLeft: e, topRight: t, bottomLeft: n, bottomRight: r }) {
989
+ const o = [e[0], t[0], n[0], r[0]], i = [e[1], t[1], n[1], r[1]];
990
+ return [Math.min(...o), Math.min(...i), Math.max(...o), Math.max(...i)];
991
+ }
992
+ function Ln(e, t, n, r, o, i) {
993
+ const s = (1 - o) * (1 - i), a = o * (1 - i), l = (1 - o) * i, c = o * i;
994
+ return [
995
+ e[0] * s + t[0] * a + n[0] * l + r[0] * c,
996
+ e[1] * s + t[1] * a + n[1] * l + r[1] * c
997
+ ];
998
+ }
999
+ function Cn(e, t) {
1000
+ const n = e.length;
1001
+ if (n < 2)
1002
+ return e;
1003
+ const { getCenter: r, reference: o } = t, i = o[0], s = o[1], a = new Float64Array(n);
1004
+ for (let u = 0; u < n; u++) {
1005
+ const h = r(e[u]), p = h[0] - i, d = h[1] - s;
1006
+ a[u] = p * p + d * d;
1007
+ }
1008
+ const l = new Uint32Array(n);
1009
+ for (let u = 0; u < n; u++)
1010
+ l[u] = u;
1011
+ l.sort((u, h) => a[u] - a[h]);
1012
+ const c = e.slice();
1013
+ for (let u = 0; u < n; u++)
1014
+ e[u] = c[l[u]];
1015
+ return e;
1016
+ }
1017
+ function jn(e, t, n) {
1018
+ const [r, o, i, s] = t.getBounds(), a = [
1019
+ (r + i) / 2,
1020
+ (o + s) / 2
1021
+ ];
1022
+ return Cn(e, {
1023
+ reference: a,
1024
+ getCenter: n
1025
+ });
1026
+ }
1027
+ class xn extends Kt {
1028
+ descriptor;
1029
+ wgs84Bounds;
1030
+ getPixelRatio;
1031
+ boundingVolumeCache;
1032
+ constructor(t, n, { getPixelRatio: r, maxBoundingVolumeCacheSize: o } = {}) {
1033
+ super(t), this.descriptor = n, this.getPixelRatio = r ?? (() => 1), this.boundingVolumeCache = new it({
1034
+ maxEntries: o
1035
+ });
1036
+ const i = pe(this.descriptor.projectTo4326, ...this.descriptor.projectedBounds), s = 85.0511287798066;
1037
+ this.wgs84Bounds = [
1038
+ i[0],
1039
+ Math.max(i[1], -s),
1040
+ i[2],
1041
+ Math.min(i[3], s)
1042
+ ];
1043
+ }
1044
+ /**
1045
+ * Get tile indices visible in viewport
1046
+ * Uses frustum culling similar to OSM implementation
1047
+ *
1048
+ * Overviews follow TileMatrixSet ordering: index 0 = coarsest, higher = finer
1049
+ *
1050
+ * `minZoom` and `maxZoom` gate against `viewport.zoom` (not the tileset
1051
+ * z-index, which is an overview level in our descriptor). When the
1052
+ * viewport zoom is outside these bounds this method returns an empty
1053
+ * list — no new tile fetches, and because deck.gl's `updateTileStates`
1054
+ * marks unselected cached tiles invisible, no rendering either.
1055
+ * `visibleMinZoom` / `visibleMaxZoom` (deck.gl 9.3+) are deliberately
1056
+ * not honored: their documented "fetch but don't render" semantic
1057
+ * requires a notion of clamping to a coarser z, which doesn't
1058
+ * generalize to descriptors with sparse or single overviews. See
1059
+ * `dev-docs/zoom-terminology.md` for the rationale.
1060
+ */
1061
+ getTileIndices(t) {
1062
+ const { viewport: n, minZoom: r } = t;
1063
+ if (typeof r == "number" && n.zoom < r)
1064
+ return [];
1065
+ const o = this.descriptor.levels.length - 1, i = typeof t.maxZoom == "number" ? Math.min(t.maxZoom, o) : o, s = Pn(this.descriptor, {
1066
+ viewport: n,
1067
+ maxZ: i,
1068
+ zRange: t.zRange ?? null,
1069
+ wgs84Bounds: this.wgs84Bounds,
1070
+ pixelRatio: this.getPixelRatio(),
1071
+ boundingVolumeCache: this.boundingVolumeCache
1072
+ });
1073
+ return this.sortTileIndicesByDistance(s, n);
1074
+ }
1075
+ /**
1076
+ * Sort tile indices by ascending distance from the viewport center in
1077
+ * projected (common/world) space so loads initiate center-out.
1078
+ *
1079
+ * Short-circuits when `tileIndices.length <= maxRequests` — all fetches
1080
+ * would start concurrently regardless of order in that case. Mutates and
1081
+ * returns `tileIndices`.
1082
+ */
1083
+ sortTileIndicesByDistance(t, n) {
1084
+ const { maxRequests: r } = this.opts;
1085
+ if (t.length <= r)
1086
+ return t;
1087
+ const o = this.descriptor;
1088
+ return jn(t, n, (i) => {
1089
+ const { x: s, y: a, z: l } = i, { topLeft: c, bottomRight: u } = o.levels[l].projectedTileCorners(s, a), h = [
1090
+ (c[0] + u[0]) / 2,
1091
+ (c[1] + u[1]) / 2
1092
+ ];
1093
+ return o.projectTo4326(h[0], h[1]);
1094
+ });
1095
+ }
1096
+ getTileId(t) {
1097
+ return `${t.x}-${t.y}-${t.z}`;
1098
+ }
1099
+ getParentIndex(t) {
1100
+ if (t.z === 0)
1101
+ return t;
1102
+ const n = this.descriptor.levels[t.z], r = this.descriptor.levels[t.z - 1], o = r.metersPerPixel * r.tileWidth, i = r.metersPerPixel * r.tileHeight, s = n.metersPerPixel * n.tileWidth, a = n.metersPerPixel * n.tileHeight, l = o / s, c = i / a;
1103
+ return {
1104
+ x: Math.floor(t.x / l),
1105
+ y: Math.floor(t.y / c),
1106
+ z: t.z - 1
1107
+ };
1108
+ }
1109
+ getTileZoom(t) {
1110
+ return t.z;
1111
+ }
1112
+ getTileMetadata(t) {
1113
+ const { x: n, y: r, z: o } = t, i = this.descriptor.levels[o], { tileHeight: s, tileWidth: a } = i, { topLeft: l, topRight: c, bottomLeft: u, bottomRight: h } = i.projectedTileCorners(n, r), p = {
1114
+ topLeft: l,
1115
+ topRight: c,
1116
+ bottomLeft: u,
1117
+ bottomRight: h
1118
+ }, d = [
1119
+ Math.min(l[0], c[0], u[0], h[0]),
1120
+ Math.min(l[1], c[1], u[1], h[1]),
1121
+ Math.max(l[0], c[0], u[0], h[0]),
1122
+ Math.max(l[1], c[1], u[1], h[1])
1123
+ ], [g, f, y, j] = pe(this.descriptor.projectTo4326, ...d), { forwardTransform: b, inverseTransform: S } = i.tileTransform(n, r);
1124
+ return {
1125
+ bbox: {
1126
+ west: g,
1127
+ south: f,
1128
+ east: y,
1129
+ north: j
1130
+ },
1131
+ projectedBbox: {
1132
+ left: d[0],
1133
+ bottom: d[1],
1134
+ right: d[2],
1135
+ top: d[3]
1136
+ },
1137
+ projectedCorners: p,
1138
+ tileWidth: a,
1139
+ tileHeight: s,
1140
+ forwardTransform: b,
1141
+ inverseTransform: S
1142
+ };
1143
+ }
1144
+ }
1145
+ const fe = 512, On = 40075016686e-3, Ue = fe / On, An = {
1146
+ ...rt.defaultProps,
1147
+ maxError: 0.125,
1148
+ debug: !1,
1149
+ debugOpacity: 0.5
1150
+ };
1151
+ class Be extends nt {
1152
+ static layerName = "RasterTileLayer";
1153
+ static defaultProps = An;
1154
+ /**
1155
+ * The currently effective {@link RasterTilesetDescriptor}.
1156
+ *
1157
+ * Subclasses override this to return a descriptor built from their own
1158
+ * async-parsed state. Returns `undefined` while the source is still
1159
+ * loading; `renderLayers()` returns `null` in that case.
1160
+ *
1161
+ * The inline cast to `RasterTileLayerProps<DataT>` is required because
1162
+ * `tilesetDescriptor` is declared on `ExtraProps`, not on the base's
1163
+ * `RasterTileLayerBaseProps`. For direct use the default `ExtraProps`
1164
+ * brings it in; for subclass use this method is overridden and the cast
1165
+ * is never reached.
1166
+ */
1167
+ _tilesetDescriptor() {
1168
+ return this.props.tilesetDescriptor;
1169
+ }
1170
+ /**
1171
+ * The currently effective tile-fetch callback.
1172
+ *
1173
+ * Subclasses override this to adapt their user-facing `getTileData`
1174
+ * signature into the base's `(tile, options) => Promise<DataT>` shape.
1175
+ * Returns `undefined` when the callback is not yet available.
1176
+ */
1177
+ _getTileDataCallback() {
1178
+ return this.props.getTileData;
1179
+ }
1180
+ /**
1181
+ * The currently effective per-tile render callback.
1182
+ *
1183
+ * Subclasses override this to thread their user-facing `renderTile` and
1184
+ * any inferred default. Returns `undefined` when no callback is available.
1185
+ */
1186
+ _renderTileCallback() {
1187
+ return this.props.renderTile;
1188
+ }
1189
+ /**
1190
+ * Hook for rendering per-tile debug overlay sub-layers.
1191
+ *
1192
+ * Called once per tile from `_renderSubLayers` only when `props.debug` is
1193
+ * `true`. The hook fires both before data has arrived (`data` is `null`) and
1194
+ * after (`data` is the fetched `DataT`), so the default outline can render
1195
+ * during loading.
1196
+ *
1197
+ * Default behavior renders the primary tile boundary via
1198
+ * {@link renderDebugTileOutline} using the active descriptor. Subclasses can
1199
+ * override to replace, extend (via `super._renderDebug(...)`), or suppress
1200
+ * the default — for example, a multi-source layer can replace the default
1201
+ * with per-band tile outlines and tiered metadata labels once `data` is
1202
+ * available.
1203
+ */
1204
+ _renderDebug(t, n) {
1205
+ const r = this._tilesetDescriptor();
1206
+ return r ? Xt(`${this.id}-${t.id}-bounds`, t, r.projectTo4326) : [];
1207
+ }
1208
+ renderLayers() {
1209
+ const t = this._tilesetDescriptor(), n = this._getTileDataCallback(), r = this._renderTileCallback();
1210
+ return !t || !n || !r ? null : this._renderTileLayer(t, n, r);
1211
+ }
1212
+ _renderTileLayer(t, n, r) {
1213
+ const o = this.context.device;
1214
+ class i extends xn {
1215
+ constructor(E) {
1216
+ super(E, t, {
1217
+ getPixelRatio: () => {
1218
+ const M = o.getDefaultCanvasContext(), [z] = M.getDrawingBufferSize(), [I] = M.getCSSSize();
1219
+ return I ? z / I : 1;
1220
+ }
1221
+ });
1222
+ }
1223
+ }
1224
+ const { tileSize: s, zoomOffset: a, maxZoom: l, minZoom: c, extent: u, debounceTime: h, maxCacheSize: p, maxCacheByteSize: d, maxRequests: g, refinementStrategy: f, updateTriggers: y, onTileError: j, onTileLoad: b, onTileUnload: S, onViewportLoad: v } = this.props;
1225
+ return new rt({
1226
+ id: `raster-tile-layer-${this.id}`,
1227
+ TilesetClass: i,
1228
+ getTileData: (L) => this._wrapGetTileData(L, n),
1229
+ renderSubLayers: (L) => this._renderSubLayers(L, t, r),
1230
+ updateTriggers: {
1231
+ renderSubLayers: y?.renderTile
1232
+ },
1233
+ tileSize: s,
1234
+ zoomOffset: a,
1235
+ maxZoom: l,
1236
+ minZoom: c,
1237
+ extent: u,
1238
+ debounceTime: h,
1239
+ maxCacheSize: p,
1240
+ maxCacheByteSize: d,
1241
+ maxRequests: g,
1242
+ refinementStrategy: f,
1243
+ onTileError: j,
1244
+ onTileLoad: b,
1245
+ onTileUnload: S,
1246
+ onViewportLoad: v
1247
+ });
1248
+ }
1249
+ async _wrapGetTileData(t, n) {
1250
+ const { signal: r } = t, o = this.props.signal, i = o && r ? AbortSignal.any([o, r]) : o ?? r, s = {
1251
+ device: this.context.device,
1252
+ signal: i
1253
+ };
1254
+ return n(t, s);
1255
+ }
1256
+ _renderSubLayers(t, n, r) {
1257
+ const { maxError: o, debug: i, debugOpacity: s } = this.props, a = t.tile, l = i ? this._renderDebug(a, t.data ?? null) : [];
1258
+ if (!t.data)
1259
+ return l;
1260
+ const { forwardTransform: c, inverseTransform: u } = a, h = r(t.data);
1261
+ if (!h)
1262
+ return l;
1263
+ const { image: p, renderPipeline: d } = h, { width: g, height: f } = t.data, y = this.context.viewport.resolution !== void 0, j = y ? {
1264
+ forwardTransform: c,
1265
+ inverseTransform: u,
1266
+ forwardReproject: n.projectTo4326,
1267
+ inverseReproject: n.projectFrom4326
1268
+ } : {
1269
+ forwardTransform: c,
1270
+ inverseTransform: u,
1271
+ forwardReproject: n.projectTo3857,
1272
+ inverseReproject: n.projectFrom3857
1273
+ }, b = y ? {} : {
1274
+ coordinateSystem: "cartesian",
1275
+ coordinateOrigin: [fe / 2, fe / 2, 0],
1276
+ // biome-ignore format: array
1277
+ modelMatrix: [
1278
+ Ue,
1279
+ 0,
1280
+ 0,
1281
+ 0,
1282
+ 0,
1283
+ Ue,
1284
+ 0,
1285
+ 0,
1286
+ 0,
1287
+ 0,
1288
+ 1,
1289
+ 0,
1290
+ 0,
1291
+ 0,
1292
+ 0,
1293
+ 1
1294
+ ]
1295
+ };
1296
+ return [new Tt(this.getSubLayerProps({
1297
+ id: `${t.id}-raster`,
1298
+ width: g,
1299
+ height: f,
1300
+ // Passing `image: undefined` explicitly would trip isAsyncPropLoading
1301
+ // and cause a transient black flash (see issue #376).
1302
+ ...p !== void 0 && { image: p },
1303
+ renderPipeline: d,
1304
+ maxError: o,
1305
+ reprojectionFns: j,
1306
+ debug: i,
1307
+ debugOpacity: s,
1308
+ ...b
1309
+ })), ...l];
1310
+ }
1311
+ }
1312
+ function En(e, t) {
1313
+ const n = e.length / 3, r = new Uint8ClampedArray(n * 4), o = 0, i = n, s = n * 2;
1314
+ for (let a = 0; a < n; a++)
1315
+ r[4 * a + 0] = e[o + a] >> 8, r[4 * a + 1] = e[i + a] >> 8, r[4 * a + 2] = e[s + a] >> 8, r[4 * a + 3] = 255;
1316
+ return new ImageData(r, n, 1);
1317
+ }
1318
+ var ye;
1319
+ (function(e) {
1320
+ e[e.Big = 19789] = "Big", e[e.Little = 18761] = "Little";
1321
+ })(ye || (ye = {}));
1322
+ var $;
1323
+ (function(e) {
1324
+ e[e.ReducedImage = 1] = "ReducedImage", e[e.Page = 2] = "Page", e[e.Mask = 4] = "Mask";
1325
+ })($ || ($ = {}));
1326
+ var Ge;
1327
+ (function(e) {
1328
+ e[e.TopLeft = 1] = "TopLeft", e[e.TopRight = 2] = "TopRight", e[e.BottomRight = 3] = "BottomRight", e[e.BottomLeft = 4] = "BottomLeft", e[e.LeftTop = 5] = "LeftTop", e[e.RightTOP = 6] = "RightTOP", e[e.RightBottom = 7] = "RightBottom", e[e.LeftBottom = 8] = "LeftBottom";
1329
+ })(Ge || (Ge = {}));
1330
+ var we;
1331
+ (function(e) {
1332
+ e[e.PixelIsArea = 1] = "PixelIsArea", e[e.PixelIsPoint = 2] = "PixelIsPoint";
1333
+ })(we || (we = {}));
1334
+ var G;
1335
+ (function(e) {
1336
+ e[e.Unknown = 0] = "Unknown", e[e.Projected = 1] = "Projected", e[e.Geographic = 2] = "Geographic", e[e.Geocentric = 3] = "Geocentric", e[e.UserDefined = 32767] = "UserDefined";
1337
+ })(G || (G = {}));
1338
+ var Ke;
1339
+ (function(e) {
1340
+ e[e.Image = 1] = "Image", e[e.ReducedImage = 2] = "ReducedImage", e[e.Page = 3] = "Page";
1341
+ })(Ke || (Ke = {}));
1342
+ var P;
1343
+ (function(e) {
1344
+ e[e.None = 1] = "None", e[e.Ccittrle = 2] = "Ccittrle", e[e.CcittT4 = 3] = "CcittT4", e[e.CcittT6 = 4] = "CcittT6", e[e.Lzw = 5] = "Lzw", e[e.Jpeg6 = 6] = "Jpeg6", e[e.Jpeg = 7] = "Jpeg", e[e.DeflateOther = 8] = "DeflateOther", e[e.T85 = 9] = "T85", e[e.T43 = 10] = "T43", e[e.Next = 32766] = "Next", e[e.Ccittrlew = 32771] = "Ccittrlew", e[e.PackBits = 32773] = "PackBits", e[e.ThunderScan = 32809] = "ThunderScan", e[e.It8ctpad = 32895] = "It8ctpad", e[e.It8lw = 32896] = "It8lw", e[e.It8mp = 32897] = "It8mp", e[e.It8bl = 32898] = "It8bl", e[e.PixarFilm = 32908] = "PixarFilm", e[e.PixarLog = 32909] = "PixarLog", e[e.Deflate = 32946] = "Deflate", e[e.Dcs = 32947] = "Dcs", e[e.Jbig = 34661] = "Jbig", e[e.SgiLog = 34676] = "SgiLog", e[e.SgiLog24 = 34677] = "SgiLog24", e[e.Jp2000 = 34712] = "Jp2000", e[e.Lerc = 34887] = "Lerc", e[e.Lzma = 34925] = "Lzma", e[e.Zstd = 5e4] = "Zstd", e[e.Webp = 50001] = "Webp", e[e.JpegXl = 50002] = "JpegXl", e[e.JpegXlDng17 = 52546] = "JpegXlDng17";
1345
+ })(P || (P = {}));
1346
+ var U;
1347
+ (function(e) {
1348
+ e[e.Contig = 1] = "Contig", e[e.Separate = 2] = "Separate";
1349
+ })(U || (U = {}));
1350
+ var V;
1351
+ (function(e) {
1352
+ e[e.None = 1] = "None", e[e.Horizontal = 2] = "Horizontal", e[e.FloatingPoint = 3] = "FloatingPoint";
1353
+ })(V || (V = {}));
1354
+ var F;
1355
+ (function(e) {
1356
+ e[e.Uint = 1] = "Uint", e[e.Int = 2] = "Int", e[e.Float = 3] = "Float", e[e.Void = 4] = "Void", e[e.ComplexInt = 5] = "ComplexInt", e[e.ComplexFloat = 6] = "ComplexFloat";
1357
+ })(F || (F = {}));
1358
+ var R;
1359
+ (function(e) {
1360
+ e[e.MinIsWhite = 0] = "MinIsWhite", e[e.MinIsBlack = 1] = "MinIsBlack", e[e.Rgb = 2] = "Rgb", e[e.Palette = 3] = "Palette", e[e.Mask = 4] = "Mask", e[e.Separated = 5] = "Separated", e[e.Ycbcr = 6] = "Ycbcr", e[e.Cielab = 8] = "Cielab", e[e.Icclab = 9] = "Icclab", e[e.Itulab = 10] = "Itulab", e[e.Cfa = 32803] = "Cfa", e[e.Logl = 32844] = "Logl", e[e.Logluv = 32845] = "Logluv";
1361
+ })(R || (R = {}));
1362
+ var m;
1363
+ (function(e) {
1364
+ e[e.SubFileType = 254] = "SubFileType", e[e.OldSubFileType = 255] = "OldSubFileType", e[e.ImageWidth = 256] = "ImageWidth", e[e.ImageHeight = 257] = "ImageHeight", e[e.BitsPerSample = 258] = "BitsPerSample", e[e.SampleFormat = 339] = "SampleFormat", e[e.Compression = 259] = "Compression", e[e.Photometric = 262] = "Photometric", e[e.TileWidth = 322] = "TileWidth", e[e.TileHeight = 323] = "TileHeight", e[e.TileOffsets = 324] = "TileOffsets", e[e.TileByteCounts = 325] = "TileByteCounts", e[e.JpegTables = 347] = "JpegTables", e[e.StripOffsets = 273] = "StripOffsets", e[e.StripByteCounts = 279] = "StripByteCounts", e[e.GdalMetadata = 42112] = "GdalMetadata", e[e.GdalNoData = 42113] = "GdalNoData", e[e.ModelPixelScale = 33550] = "ModelPixelScale", e[e.ModelTiePoint = 33922] = "ModelTiePoint", e[e.ModelTransformation = 34264] = "ModelTransformation", e[e.GeoKeyDirectory = 34735] = "GeoKeyDirectory", e[e.GeoDoubleParams = 34736] = "GeoDoubleParams", e[e.GeoAsciiParams = 34737] = "GeoAsciiParams", e[e.LercParameters = 50674] = "LercParameters", e[e.PlanarConfiguration = 284] = "PlanarConfiguration", e[e.CellLength = 265] = "CellLength", e[e.CellWidth = 264] = "CellWidth", e[e.ColorMap = 320] = "ColorMap", e[e.Copyright = 33432] = "Copyright", e[e.DateTime = 306] = "DateTime", e[e.ExtraSamples = 338] = "ExtraSamples", e[e.FillOrder = 266] = "FillOrder", e[e.FreeByteCounts = 289] = "FreeByteCounts", e[e.FreeOffsets = 288] = "FreeOffsets", e[e.GrayResponseCurve = 291] = "GrayResponseCurve", e[e.GrayResponseUnit = 290] = "GrayResponseUnit", e[e.HostComputer = 316] = "HostComputer", e[e.ImageDescription = 270] = "ImageDescription", e[e.Make = 271] = "Make", e[e.MaxSampleValue = 281] = "MaxSampleValue", e[e.MinSampleValue = 280] = "MinSampleValue", e[e.Model = 272] = "Model", e[e.Orientation = 274] = "Orientation", e[e.ResolutionUnit = 296] = "ResolutionUnit", e[e.RowsPerStrip = 278] = "RowsPerStrip", e[e.SamplesPerPixel = 277] = "SamplesPerPixel", e[e.Software = 305] = "Software", e[e.Threshholding = 263] = "Threshholding", e[e.XResolution = 282] = "XResolution", e[e.YResolution = 283] = "YResolution", e[e.BadFaxLines = 326] = "BadFaxLines", e[e.CleanFaxData = 327] = "CleanFaxData", e[e.ClipPath = 343] = "ClipPath", e[e.ConsecutiveBadFaxLines = 328] = "ConsecutiveBadFaxLines", e[e.Decode = 433] = "Decode", e[e.DefaultImageColor = 434] = "DefaultImageColor", e[e.DocumentName = 269] = "DocumentName", e[e.DotRange = 336] = "DotRange", e[e.HalftoneHints = 321] = "HalftoneHints", e[e.Indexed = 346] = "Indexed", e[e.PageName = 285] = "PageName", e[e.PageNumber = 297] = "PageNumber", e[e.Predictor = 317] = "Predictor", e[e.PrimaryChromaticities = 319] = "PrimaryChromaticities", e[e.ReferenceBlackWhite = 532] = "ReferenceBlackWhite", e[e.SMinSampleValue = 340] = "SMinSampleValue", e[e.SMaxSampleValue = 341] = "SMaxSampleValue", e[e.StripRowCounts = 559] = "StripRowCounts", e[e.SubIFDs = 330] = "SubIFDs", e[e.T4Options = 292] = "T4Options", e[e.T6Options = 293] = "T6Options", e[e.TransferFunction = 301] = "TransferFunction", e[e.WhitePoint = 318] = "WhitePoint", e[e.XClipPathUnits = 344] = "XClipPathUnits", e[e.XPosition = 286] = "XPosition", e[e.YCbCrCoefficients = 529] = "YCbCrCoefficients", e[e.YCbCrPositioning = 531] = "YCbCrPositioning", e[e.YCbCrSubSampling = 530] = "YCbCrSubSampling", e[e.YClipPathUnits = 345] = "YClipPathUnits", e[e.YPosition = 287] = "YPosition", e[e.ApertureValue = 37378] = "ApertureValue", e[e.ColorSpace = 40961] = "ColorSpace", e[e.DateTimeDigitized = 36868] = "DateTimeDigitized", e[e.DateTimeOriginal = 36867] = "DateTimeOriginal", e[e.ExifIFD = 34665] = "ExifIFD", e[e.ExifVersion = 36864] = "ExifVersion", e[e.ExposureTime = 33434] = "ExposureTime", e[e.FileSource = 41728] = "FileSource", e[e.Flash = 37385] = "Flash", e[e.FlashpixVersion = 40960] = "FlashpixVersion", e[e.FNumber = 33437] = "FNumber", e[e.ImageUniqueID = 42016] = "ImageUniqueID", e[e.LightSource = 37384] = "LightSource", e[e.MakerNote = 37500] = "MakerNote", e[e.ShutterSpeedValue = 37377] = "ShutterSpeedValue", e[e.UserComment = 37510] = "UserComment", e[e.IPTC = 33723] = "IPTC", e[e.ICCProfile = 34675] = "ICCProfile", e[e.XMP = 700] = "XMP";
1365
+ })(m || (m = {}));
1366
+ var w;
1367
+ (function(e) {
1368
+ e[e.GTModelTypeGeoKey = 1024] = "GTModelTypeGeoKey", e[e.GTRasterTypeGeoKey = 1025] = "GTRasterTypeGeoKey", e[e.GTCitationGeoKey = 1026] = "GTCitationGeoKey", e[e.GeodeticCRSGeoKey = 2048] = "GeodeticCRSGeoKey", e[e.GeodeticCitationGeoKey = 2049] = "GeodeticCitationGeoKey", e[e.GeodeticDatumGeoKey = 2050] = "GeodeticDatumGeoKey", e[e.PrimeMeridianGeoKey = 2051] = "PrimeMeridianGeoKey", e[e.GeogLinearUnitsGeoKey = 2052] = "GeogLinearUnitsGeoKey", e[e.GeogLinearUnitSizeGeoKey = 2053] = "GeogLinearUnitSizeGeoKey", e[e.GeogAngularUnitsGeoKey = 2054] = "GeogAngularUnitsGeoKey", e[e.GeogAngularUnitSizeGeoKey = 2055] = "GeogAngularUnitSizeGeoKey", e[e.EllipsoidGeoKey = 2056] = "EllipsoidGeoKey", e[e.EllipsoidSemiMajorAxisGeoKey = 2057] = "EllipsoidSemiMajorAxisGeoKey", e[e.EllipsoidSemiMinorAxisGeoKey = 2058] = "EllipsoidSemiMinorAxisGeoKey", e[e.EllipsoidInvFlatteningGeoKey = 2059] = "EllipsoidInvFlatteningGeoKey", e[e.PrimeMeridianLongitudeGeoKey = 2061] = "PrimeMeridianLongitudeGeoKey", e[e.GeogTOWGS84GeoKey = 2062] = "GeogTOWGS84GeoKey", e[e.GeogAzimuthUnitsGeoKey = 2060] = "GeogAzimuthUnitsGeoKey", e[e.ProjectedCRSGeoKey = 3072] = "ProjectedCRSGeoKey", e[e.ProjectedCitationGeoKey = 3073] = "ProjectedCitationGeoKey", e[e.ProjectionGeoKey = 3074] = "ProjectionGeoKey", e[e.ProjMethodGeoKey = 3075] = "ProjMethodGeoKey", e[e.ProjLinearUnitsGeoKey = 3076] = "ProjLinearUnitsGeoKey", e[e.ProjLinearUnitSizeGeoKey = 3077] = "ProjLinearUnitSizeGeoKey", e[e.ProjStdParallel1GeoKey = 3078] = "ProjStdParallel1GeoKey", e[e.ProjStdParallel2GeoKey = 3079] = "ProjStdParallel2GeoKey", e[e.ProjNatOriginLongGeoKey = 3080] = "ProjNatOriginLongGeoKey", e[e.ProjNatOriginLatGeoKey = 3081] = "ProjNatOriginLatGeoKey", e[e.ProjFalseEastingGeoKey = 3082] = "ProjFalseEastingGeoKey", e[e.ProjFalseNorthingGeoKey = 3083] = "ProjFalseNorthingGeoKey", e[e.ProjFalseOriginLongGeoKey = 3084] = "ProjFalseOriginLongGeoKey", e[e.ProjFalseOriginLatGeoKey = 3085] = "ProjFalseOriginLatGeoKey", e[e.ProjFalseOriginEastingGeoKey = 3086] = "ProjFalseOriginEastingGeoKey", e[e.ProjFalseOriginNorthingGeoKey = 3087] = "ProjFalseOriginNorthingGeoKey", e[e.ProjCenterLongGeoKey = 3088] = "ProjCenterLongGeoKey", e[e.ProjCenterLatGeoKey = 3089] = "ProjCenterLatGeoKey", e[e.ProjCenterEastingGeoKey = 3090] = "ProjCenterEastingGeoKey", e[e.ProjCenterNorthingGeoKey = 3091] = "ProjCenterNorthingGeoKey", e[e.ProjScaleAtNatOriginGeoKey = 3092] = "ProjScaleAtNatOriginGeoKey", e[e.ProjScaleAtCenterGeoKey = 3093] = "ProjScaleAtCenterGeoKey", e[e.ProjAzimuthAngleGeoKey = 3094] = "ProjAzimuthAngleGeoKey", e[e.ProjStraightVertPoleLongGeoKey = 3095] = "ProjStraightVertPoleLongGeoKey", e[e.ProjRectifiedGridAngleGeoKey = 3096] = "ProjRectifiedGridAngleGeoKey", e[e.VerticalGeoKey = 4096] = "VerticalGeoKey", e[e.VerticalCitationGeoKey = 4097] = "VerticalCitationGeoKey", e[e.VerticalDatumGeoKey = 4098] = "VerticalDatumGeoKey", e[e.VerticalUnitsGeoKey = 4099] = "VerticalUnitsGeoKey";
1369
+ })(w || (w = {}));
1370
+ var _e;
1371
+ (function(e) {
1372
+ e[e.Radian = 9101] = "Radian", e[e.Degree = 9102] = "Degree", e[e.ArcMinute = 9103] = "ArcMinute", e[e.ArcDegree = 9104] = "ArcDegree", e[e.Grad = 9105] = "Grad", e[e.Gon = 9106] = "Gon", e[e.Dms = 9107] = "Dms";
1373
+ })(_e || (_e = {}));
1374
+ var Xe;
1375
+ (function(e) {
1376
+ e[e.Metre = 9001] = "Metre", e[e.Foot = 9002] = "Foot", e[e.FootUsSurvey = 9003] = "FootUsSurvey", e[e.FootModifiedAmerican = 9004] = "FootModifiedAmerican", e[e.FootClarke = 9005] = "FootClarke", e[e.FootIndian = 9006] = "FootIndian", e[e.Link = 9007] = "Link", e[e.LinkBenoit = 9008] = "LinkBenoit", e[e.LinkSears = 9009] = "LinkSears", e[e.ChainBenoit = 9010] = "ChainBenoit", e[e.ChainSears = 9011] = "ChainSears", e[e.YardSears = 9012] = "YardSears", e[e.YardIndian = 9013] = "YardIndian", e[e.Fathom = 9014] = "Fathom", e[e.MileInternationalNautical = 9015] = "MileInternationalNautical";
1377
+ })(Xe || (Xe = {}));
1378
+ const In = {
1379
+ [m.TileByteCounts]: !0,
1380
+ [m.TileOffsets]: !0,
1381
+ [m.StripOffsets]: !0,
1382
+ [m.StripByteCounts]: !0,
1383
+ [m.BitsPerSample]: !0,
1384
+ [m.SampleFormat]: !0,
1385
+ [m.GeoKeyDirectory]: !0,
1386
+ [m.GeoDoubleParams]: !0
1387
+ };
1388
+ var x;
1389
+ (function(e) {
1390
+ e.None = "application/octet-stream", e.Jbig = "image/jbig", e.Dcs = "image/x-kodak-dcs", e.PackBits = "application/packbits", e.Jpeg = "image/jpeg", e.Jp2000 = "image/jp2", e.JpegXl = "image/jpegxl", e.Webp = "image/webp", e.Zstd = "application/zstd", e.Lzw = "application/lzw", e.Deflate = "application/deflate", e.Lerc = "application/lerc", e.Lzma = "application/x-lzma";
1391
+ })(x || (x = {}));
1392
+ const st = {
1393
+ [P.None]: x.None,
1394
+ [P.Lzw]: x.Lzw,
1395
+ [P.Jpeg6]: x.Jpeg,
1396
+ [P.Jpeg]: x.Jpeg,
1397
+ [P.DeflateOther]: x.Deflate,
1398
+ [P.Deflate]: x.Deflate,
1399
+ [P.Lerc]: x.Lerc,
1400
+ [P.Lzma]: x.Lzma,
1401
+ [P.Jp2000]: x.Jp2000,
1402
+ [P.Zstd]: x.Zstd,
1403
+ [P.Webp]: x.Webp,
1404
+ [P.JpegXl]: x.JpegXl,
1405
+ [P.Ccittrle]: x.None,
1406
+ [P.CcittT4]: x.None,
1407
+ [P.CcittT6]: x.None,
1408
+ [P.T85]: x.Jbig,
1409
+ [P.T43]: x.Jbig,
1410
+ [P.Next]: x.None,
1411
+ [P.Ccittrlew]: x.None,
1412
+ [P.PackBits]: x.PackBits,
1413
+ [P.ThunderScan]: x.None,
1414
+ [P.It8ctpad]: x.None,
1415
+ [P.It8lw]: x.None,
1416
+ [P.It8mp]: x.None,
1417
+ [P.It8bl]: x.None,
1418
+ [P.PixarFilm]: x.None,
1419
+ [P.PixarLog]: x.None,
1420
+ [P.Dcs]: x.Dcs,
1421
+ [P.Jbig]: x.Jbig,
1422
+ [P.SgiLog]: x.None,
1423
+ [P.SgiLog24]: x.None,
1424
+ [P.JpegXlDng17]: x.JpegXl
1425
+ };
1426
+ function Mn(e) {
1427
+ return e == null ? null : st[e];
1428
+ }
1429
+ var C;
1430
+ (function(e) {
1431
+ e[e.Uint8 = 1] = "Uint8", e[e.Ascii = 2] = "Ascii", e[e.Uint16 = 3] = "Uint16", e[e.Uint32 = 4] = "Uint32", e[e.Rational = 5] = "Rational", e[e.Int8 = 6] = "Int8", e[e.Undefined = 7] = "Undefined", e[e.Int16 = 8] = "Int16", e[e.Int32 = 9] = "Int32", e[e.SignedRational = 10] = "SignedRational", e[e.Float32 = 11] = "Float32", e[e.Float64 = 12] = "Float64", e[e.Ifd = 13] = "Ifd", e[e.Uint64 = 16] = "Uint64", e[e.Int64 = 17] = "Int64", e[e.Ifd8 = 18] = "Ifd8";
1432
+ })(C || (C = {}));
1433
+ var N;
1434
+ (function(e) {
1435
+ e[e.BigTiff = 43] = "BigTiff", e[e.Tiff = 42] = "Tiff";
1436
+ })(N || (N = {}));
1437
+ function W(e) {
1438
+ switch (e) {
1439
+ case C.Uint8:
1440
+ case C.Ascii:
1441
+ case C.Int8:
1442
+ case C.Undefined:
1443
+ return 1;
1444
+ case C.Uint16:
1445
+ case C.Int16:
1446
+ return 2;
1447
+ case C.Uint32:
1448
+ case C.Int32:
1449
+ case C.Float32:
1450
+ case C.Ifd:
1451
+ return 4;
1452
+ case C.Rational:
1453
+ case C.SignedRational:
1454
+ case C.Float64:
1455
+ case C.Uint64:
1456
+ case C.Int64:
1457
+ case C.Ifd8:
1458
+ return 8;
1459
+ default:
1460
+ throw new Error(`Invalid fieldType ${String(e)}`);
1461
+ }
1462
+ }
1463
+ var We;
1464
+ (function(e) {
1465
+ e[e.Double = 8] = "Double", e[e.Float32 = 4] = "Float32";
1466
+ })(We || (We = {}));
1467
+ var O;
1468
+ (function(e) {
1469
+ e[e.UInt64 = 8] = "UInt64", e[e.UInt32 = 4] = "UInt32", e[e.UInt16 = 2] = "UInt16", e[e.UInt8 = 1] = "UInt8";
1470
+ })(O || (O = {}));
1471
+ const He = 2 ** 32;
1472
+ function at(e, t, n) {
1473
+ const r = e.getUint32(t, n), o = e.getUint32(t + 4, n), i = n ? r + He * o : He * r + o;
1474
+ if (!Number.isSafeInteger(i))
1475
+ throw new Error(i + " exceeds MAX_SAFE_INTEGER. Precision may is lost");
1476
+ return i;
1477
+ }
1478
+ function K(e, t, n, r) {
1479
+ switch (n) {
1480
+ case O.UInt8:
1481
+ return e.getUint8(t);
1482
+ case O.UInt16:
1483
+ return e.getUint16(t, r);
1484
+ case O.UInt32:
1485
+ return e.getUint32(t, r);
1486
+ case O.UInt64:
1487
+ return at(e, t, r);
1488
+ }
1489
+ }
1490
+ function se(e, t, n) {
1491
+ return !(t < e.sourceOffset || e.sourceOffset + e.byteLength < t + n);
1492
+ }
1493
+ const lt = new ArrayBuffer(4), Rn = new Uint32Array(lt), zn = new Uint8Array(lt);
1494
+ Rn[0] = 1;
1495
+ const ke = zn[0] === 1;
1496
+ function Ze(e, t, n, r) {
1497
+ switch (e) {
1498
+ case C.Ascii:
1499
+ return String.fromCharCode(t.getUint8(n));
1500
+ case C.Undefined:
1501
+ case C.Uint8:
1502
+ return t.getUint8(n);
1503
+ case C.Int8:
1504
+ return t.getInt8(n);
1505
+ case C.Uint16:
1506
+ return t.getUint16(n, r);
1507
+ case C.Int16:
1508
+ return t.getInt16(n, r);
1509
+ case C.Uint32:
1510
+ case C.Ifd:
1511
+ return t.getUint32(n, r);
1512
+ case C.Int32:
1513
+ return t.getInt32(n, r);
1514
+ case C.Rational:
1515
+ return [t.getUint32(n, r), t.getUint32(n + 4, r)];
1516
+ case C.SignedRational:
1517
+ return [t.getInt32(n, r), t.getInt32(n + 4, r)];
1518
+ case C.Float64:
1519
+ return t.getFloat64(n, r);
1520
+ case C.Float32:
1521
+ return t.getFloat32(n, r);
1522
+ case C.Uint64:
1523
+ return at(t, n, r);
1524
+ default:
1525
+ throw new Error(`Unknown read type "${e}" "${C[e]}"`);
1526
+ }
1527
+ }
1528
+ function ct(e, t, n, r, o) {
1529
+ switch (o) {
1530
+ case C.Uint8:
1531
+ return new Uint8Array(t.buffer.slice(t.byteOffset + n, t.byteOffset + n + r));
1532
+ case C.Uint16:
1533
+ return e.isLittleEndian !== ke ? null : new Uint16Array(t.buffer.slice(t.byteOffset + n, t.byteOffset + n + r));
1534
+ case C.Uint32:
1535
+ return e.isLittleEndian !== ke ? null : new Uint32Array(t.buffer.slice(t.byteOffset + n, t.byteOffset + n + r));
1536
+ }
1537
+ return null;
1538
+ }
1539
+ function X(e, t, n, r, o, i) {
1540
+ const s = W(o), a = i * s;
1541
+ if (i === 1) {
1542
+ const c = Ze(o, n, r, e.isLittleEndian);
1543
+ return t && In[t] ? [c] : c;
1544
+ }
1545
+ switch (o) {
1546
+ case C.Ascii:
1547
+ return String.fromCharCode.apply(null, new Uint8Array(n.buffer, r, a - 1));
1548
+ }
1549
+ if (t === m.TileOffsets || t === m.TileByteCounts || t === m.StripOffsets || t === m.StripByteCounts) {
1550
+ const c = ct(e, n, r, a, o);
1551
+ if (c)
1552
+ return c;
1553
+ }
1554
+ const l = [];
1555
+ for (let c = 0; c < a; c += s)
1556
+ l.push(Ze(o, n, r + c, e.isLittleEndian));
1557
+ return l;
1558
+ }
1559
+ function Fn(e, t, n) {
1560
+ const r = t.getUint16(n + 0, e.isLittleEndian), o = t.getUint16(n + 2, e.isLittleEndian), i = K(t, n + 4, e.ifdConfig.pointer, e.isLittleEndian), a = W(o) * i;
1561
+ if (a <= e.ifdConfig.pointer) {
1562
+ const c = X(e, r, t, n + 4 + e.ifdConfig.pointer, o, i);
1563
+ return { type: "inline", id: r, name: m[r], count: i, value: c, dataType: o, tagOffset: n };
1564
+ }
1565
+ const l = K(t, n + 4 + e.ifdConfig.pointer, e.ifdConfig.pointer, e.isLittleEndian);
1566
+ switch (r) {
1567
+ case m.TileOffsets:
1568
+ case m.TileByteCounts:
1569
+ case m.StripByteCounts:
1570
+ case m.StripOffsets:
1571
+ const c = {
1572
+ type: "offset",
1573
+ id: r,
1574
+ name: m[r],
1575
+ count: i,
1576
+ dataType: o,
1577
+ dataOffset: l,
1578
+ isLoaded: !1,
1579
+ value: [],
1580
+ tagOffset: n
1581
+ };
1582
+ if (se(t, l, a)) {
1583
+ const u = ct(e, t, l - t.sourceOffset, a, o);
1584
+ u ? (c.value = u, c.isLoaded = !0) : Un(c, t);
1585
+ }
1586
+ return c;
1587
+ }
1588
+ if (se(t, l, a)) {
1589
+ const c = X(e, r, t, l - t.sourceOffset, o, i);
1590
+ return { type: "inline", id: r, name: m[r], count: i, value: c, dataType: o, tagOffset: n };
1591
+ }
1592
+ return { type: "lazy", id: r, name: m[r], count: i, dataOffset: l, dataType: o, tagOffset: n };
1593
+ }
1594
+ async function Dn(e, t, n) {
1595
+ if (e.value != null)
1596
+ return e.value;
1597
+ const o = W(e.dataType) * e.count, i = await t.source.fetch(e.dataOffset, o, n), s = new DataView(i);
1598
+ return e.value = X(t, e.id, s, 0, e.dataType, e.count), e.value;
1599
+ }
1600
+ async function Nn(e, t, n) {
1601
+ const r = W(t.dataType);
1602
+ if (t.view == null) {
1603
+ const o = await e.source.fetch(t.dataOffset, r * t.count, n);
1604
+ t.view = new DataView(o), t.view.sourceOffset = t.dataOffset;
1605
+ }
1606
+ return t.value = X(e, t.id, t.view, 0, t.dataType, t.count), t.view = void 0, t.isLoaded = !0, t.value;
1607
+ }
1608
+ function Un(e, t) {
1609
+ const n = W(e.dataType), r = t.byteOffset + e.dataOffset - t.sourceOffset;
1610
+ e.view = new DataView(t.buffer.slice(r, r + n * e.count)), e.view.sourceOffset = e.dataOffset;
1611
+ }
1612
+ async function Bn(e, t, n, r) {
1613
+ if (n > t.count || n < 0)
1614
+ throw new Error("TagOffset: out of bounds :" + n);
1615
+ if (t.value[n] != null)
1616
+ return t.value[n];
1617
+ const o = W(t.dataType);
1618
+ if (t.view == null) {
1619
+ const s = await e.source.fetch(t.dataOffset + n * o, o, r), a = new DataView(s), l = X(e, void 0, a, 0, t.dataType, 1);
1620
+ if (typeof l != "number")
1621
+ throw new Error("Value is not a number");
1622
+ return t.value[n] = l, l;
1623
+ }
1624
+ const i = X(e, void 0, t.view, n * o, t.dataType, 1);
1625
+ if (typeof i != "number")
1626
+ throw new Error("Value is not a number");
1627
+ return t.value[n] = i, i;
1628
+ }
1629
+ function Gn(e, t, n) {
1630
+ if (n > t.count || n < 0)
1631
+ throw new Error("TagOffset: out of bounds :" + n);
1632
+ if (t.value[n] != null)
1633
+ return t.value[n];
1634
+ if (t.view == null)
1635
+ return null;
1636
+ const r = W(t.dataType), o = X(e, void 0, t.view, n * r, t.dataType, 1);
1637
+ if (typeof o != "number")
1638
+ throw new Error("Value is not a number");
1639
+ return t.value[n] = o, o;
1640
+ }
1641
+ const Ve = 32767, Kn = /* @__PURE__ */ new Set([
1642
+ m.Compression,
1643
+ m.ImageHeight,
1644
+ m.ImageWidth,
1645
+ m.ModelPixelScale,
1646
+ m.ModelTiePoint,
1647
+ m.ModelTransformation,
1648
+ m.TileHeight,
1649
+ m.TileWidth
1650
+ ]), _n = /* @__PURE__ */ new Set([m.GeoKeyDirectory, m.GeoAsciiParams, m.GeoDoubleParams]);
1651
+ class Xn {
1652
+ /**
1653
+ * Id of the tif image, generally the image index inside the tif
1654
+ * where 0 is the root image, and every sub image is +1
1655
+ *
1656
+ * @example 0, 1, 2
1657
+ */
1658
+ id;
1659
+ /** Reference to the TIFF that owns this image */
1660
+ tiff;
1661
+ /** Has loadGeoTiffTags been called */
1662
+ isGeoTagsLoaded = !1;
1663
+ /** Sub tags stored in TiffTag.GeoKeyDirectory */
1664
+ tagsGeo = /* @__PURE__ */ new Map();
1665
+ /** All IFD tags that have been read for the image */
1666
+ tags;
1667
+ constructor(t, n, r) {
1668
+ this.tiff = t, this.id = n, this.tags = r;
1669
+ }
1670
+ /**
1671
+ * Force loading of important tags if they have not already been loaded
1672
+ *
1673
+ * @param loadGeoTags Whether to load the GeoKeyDirectory and unpack it
1674
+ */
1675
+ async init(t = !0, n) {
1676
+ const r = [];
1677
+ Kn.forEach((o) => {
1678
+ r.push(this.fetch(o, n));
1679
+ }), t && _n.forEach((o) => {
1680
+ r.push(this.fetch(o, n));
1681
+ }), await Promise.all(r), t && await this.loadGeoTiffTags();
1682
+ }
1683
+ /**
1684
+ * Get the value of a TiffTag if it has been loaded, null otherwise.
1685
+ *
1686
+ * If the value is not loaded use {@link TiffImage.fetch} to load the value
1687
+ * Or use {@link TiffImage.has} to check if the tag exists
1688
+ *
1689
+ *
1690
+ * @returns value if loaded, null otherwise
1691
+ */
1692
+ value(t) {
1693
+ const n = this.tags.get(t);
1694
+ return n == null || n.type === "offset" && n.isLoaded === !1 ? null : n.value;
1695
+ }
1696
+ /**
1697
+ * Does the tag exist
1698
+ *
1699
+ * @example
1700
+ * ```typescript
1701
+ * img.has(TiffTag.ImageWidth) // true
1702
+ * ```
1703
+ *
1704
+ * @param tag Tag to check
1705
+ * @returns true if the tag exists, false otherwise
1706
+ */
1707
+ has(t) {
1708
+ return this.tags.has(t);
1709
+ }
1710
+ /**
1711
+ * Load a tag.
1712
+ *
1713
+ * If it is not currently loaded, fetch the required data for the tag.
1714
+ *
1715
+ * @example
1716
+ * ```typescript
1717
+ * await img.fetch(TiffTag.ImageWidth) // 512 (px)
1718
+ * ```
1719
+ *
1720
+ * @param tag tag to fetch
1721
+ */
1722
+ async fetch(t, n) {
1723
+ const r = this.tags.get(t);
1724
+ if (r == null)
1725
+ return null;
1726
+ if (r.type === "inline")
1727
+ return r.value;
1728
+ if (r.type === "lazy")
1729
+ return Dn(r, this.tiff, n);
1730
+ if (r.isLoaded)
1731
+ return r.value;
1732
+ if (r.type === "offset")
1733
+ return Nn(this.tiff, r, n);
1734
+ throw new Error("Cannot fetch:" + t);
1735
+ }
1736
+ /**
1737
+ * Get the associated TiffTagGeo
1738
+ *
1739
+ * @example
1740
+ * ```typescript
1741
+ * image.valueGeo(TiffTagGeo.GTRasterTypeGeoKey)
1742
+ * ```
1743
+ * @throws if {@link loadGeoTiffTags} has not been called
1744
+ */
1745
+ valueGeo(t) {
1746
+ if (this.isGeoTagsLoaded === !1)
1747
+ throw new Error("loadGeoTiffTags() has not been called");
1748
+ return this.tagsGeo.get(t);
1749
+ }
1750
+ /**
1751
+ * Load and parse the GDAL_NODATA Tifftag
1752
+ *
1753
+ * @throws if the tag is not loaded
1754
+ * @returns null if the tag does not exist
1755
+ */
1756
+ get noData() {
1757
+ const t = this.tags.get(m.GdalNoData);
1758
+ if (t == null)
1759
+ return null;
1760
+ if (t.value != null)
1761
+ return Number(t.value);
1762
+ throw new Error("GdalNoData tag is not loaded");
1763
+ }
1764
+ /**
1765
+ * Load and unpack the GeoKeyDirectory
1766
+ *
1767
+ * @see {TiffTag.GeoKeyDirectory}
1768
+ */
1769
+ async loadGeoTiffTags() {
1770
+ if (this.isGeoTagsLoaded)
1771
+ return;
1772
+ const t = this.tags.get(m.GeoKeyDirectory);
1773
+ if (t == null) {
1774
+ this.isGeoTagsLoaded = !0;
1775
+ return;
1776
+ }
1777
+ if (t.type === "lazy" && t.value == null && await Promise.all([
1778
+ this.fetch(m.GeoKeyDirectory),
1779
+ this.fetch(m.GeoAsciiParams),
1780
+ this.fetch(m.GeoDoubleParams)
1781
+ ]), this.isGeoTagsLoaded = !0, t.value == null)
1782
+ return;
1783
+ const n = t.value;
1784
+ if (typeof n == "number")
1785
+ throw new Error("Invalid geo tags found");
1786
+ for (let r = 4; r <= n[3] * 4; r += 4) {
1787
+ const o = n[r], i = n[r + 1], s = n[r + 3];
1788
+ if (i === 0) {
1789
+ this.tagsGeo.set(o, s);
1790
+ continue;
1791
+ }
1792
+ const a = this.tags.get(i);
1793
+ if (a == null || a.value == null)
1794
+ continue;
1795
+ const l = n[r + 2];
1796
+ if (typeof a.value == "string")
1797
+ this.tagsGeo.set(o, a.value.slice(s, s + l - 1).trim());
1798
+ else if (Array.isArray(a.value))
1799
+ l === 1 ? this.tagsGeo.set(o, a.value[s]) : this.tagsGeo.set(o, a.value.slice(s, s + l));
1800
+ else
1801
+ throw new Error("Failed to extract GeoTiffTags");
1802
+ }
1803
+ }
1804
+ /**
1805
+ * Get the origin point for the image
1806
+ *
1807
+ * @returns origin point of the image
1808
+ */
1809
+ get origin() {
1810
+ const t = this.value(m.ModelTiePoint);
1811
+ if (t != null && t.length === 6)
1812
+ return [t[3], t[4], t[5]];
1813
+ const n = this.value(m.ModelTransformation);
1814
+ if (n != null)
1815
+ return [n[3], n[7], n[11]];
1816
+ if (this.value(m.SubFileType) === $.ReducedImage && this.id !== 0)
1817
+ return this.tiff.images[0].origin;
1818
+ throw new Error("Image does not have a geo transformation.");
1819
+ }
1820
+ /** Is there enough geo information on this image to figure out where its actually located */
1821
+ get isGeoLocated() {
1822
+ return this.value(m.ModelPixelScale) != null || this.value(m.ModelTransformation) != null ? !0 : this.isSubImage && this.id !== 0 ? this.tiff.images[0].isGeoLocated : !1;
1823
+ }
1824
+ /**
1825
+ * Get the resolution of the image
1826
+ *
1827
+ * @returns [x,y,z] pixel scale
1828
+ */
1829
+ get resolution() {
1830
+ const t = this.value(m.ModelPixelScale);
1831
+ if (t != null)
1832
+ return [t[0], -t[1], t[2]];
1833
+ const n = this.value(m.ModelTransformation);
1834
+ if (n != null)
1835
+ return [n[0], n[5], n[10]];
1836
+ if (this.isSubImage && this.id !== 0) {
1837
+ const r = this.tiff.images[0], [o, i, s] = r.resolution, a = r.size, l = this.size;
1838
+ return [o * a.width / l.width, i * a.height / l.height, s];
1839
+ }
1840
+ throw new Error("Image does not have a geo transformation.");
1841
+ }
1842
+ /**
1843
+ * Is this image a reduced size image
1844
+ * @see {@link TiffTag.SubFileType}
1845
+ * @returns true if SubFileType is Reduces image, false otherwise
1846
+ */
1847
+ get isSubImage() {
1848
+ return this.value(m.SubFileType) === $.ReducedImage;
1849
+ }
1850
+ /**
1851
+ * Bounding box of the image
1852
+ *
1853
+ * @returns [minX, minY, maxX, maxY] bounding box
1854
+ */
1855
+ get bbox() {
1856
+ const t = this.size, n = this.origin, r = this.resolution;
1857
+ if (n == null || t == null || r == null)
1858
+ throw new Error("Unable to calculate bounding box");
1859
+ const o = n[0], i = n[1], s = o + r[0] * t.width, a = i + r[1] * t.height;
1860
+ return [Math.min(o, s), Math.min(i, a), Math.max(o, s), Math.max(i, a)];
1861
+ }
1862
+ /**
1863
+ * Get the compression used by the tile
1864
+ *
1865
+ * @see {@link TiffCompressionMimeType}
1866
+ *
1867
+ * @returns Compression type eg webp
1868
+ */
1869
+ get compression() {
1870
+ const t = this.value(m.Compression);
1871
+ return t == null ? null : st[t];
1872
+ }
1873
+ /**
1874
+ * Attempt to read the EPSG Code from TiffGeoTags
1875
+ *
1876
+ * looks at TiffTagGeo.ProjectionGeoKey, TiffTagGeo.ProjectedCRSGeoKey and TiffTagGeo.GeodeticCRSGeoKey
1877
+ *
1878
+ * @returns EPSG Code if it exists and is not user defined.
1879
+ */
1880
+ get epsg() {
1881
+ const t = this.valueGeo(w.ProjectionGeoKey);
1882
+ if (t != null && t !== Ve)
1883
+ return t;
1884
+ let n = null;
1885
+ switch (this.valueGeo(w.GTModelTypeGeoKey)) {
1886
+ case G.Unknown:
1887
+ return null;
1888
+ case G.Projected:
1889
+ n = this.valueGeo(w.ProjectedCRSGeoKey);
1890
+ break;
1891
+ case G.Geographic:
1892
+ n = this.valueGeo(w.GeodeticCRSGeoKey);
1893
+ break;
1894
+ case G.Geocentric:
1895
+ n = this.valueGeo(w.GeodeticCRSGeoKey);
1896
+ break;
1897
+ case G.UserDefined:
1898
+ return null;
1899
+ }
1900
+ return n === Ve ? null : n;
1901
+ }
1902
+ /**
1903
+ * Get the size of the image
1904
+ *
1905
+ * @returns Size in pixels
1906
+ */
1907
+ get size() {
1908
+ const t = this.value(m.ImageWidth), n = this.value(m.ImageHeight);
1909
+ if (t == null || n == null)
1910
+ throw new Error("Tiff has no height or width");
1911
+ return { width: t, height: n };
1912
+ }
1913
+ /**
1914
+ * Determine if this image is tiled
1915
+ */
1916
+ isTiled() {
1917
+ return this.value(m.TileWidth) !== null;
1918
+ }
1919
+ /**
1920
+ * Get size of individual tiles
1921
+ */
1922
+ get tileSize() {
1923
+ const t = this.value(m.TileWidth), n = this.value(m.TileHeight);
1924
+ if (t == null || n == null)
1925
+ throw new Error("Tiff is not tiled");
1926
+ return { width: t, height: n };
1927
+ }
1928
+ /**
1929
+ * Number of tiles used to create this image
1930
+ */
1931
+ get tileCount() {
1932
+ const t = this.size, n = this.tileSize, r = Math.ceil(t.width / n.width), o = Math.ceil(t.height / n.height);
1933
+ return { x: r, y: o };
1934
+ }
1935
+ /**
1936
+ * Get the pointer to where the tiles start in the Tiff file
1937
+ *
1938
+ * @remarks Used to read tiled tiffs
1939
+ *
1940
+ * @returns file offset to where the tiffs are stored
1941
+ */
1942
+ get tileOffset() {
1943
+ const t = this.tags.get(m.TileOffsets);
1944
+ if (t == null)
1945
+ throw new Error("No tile offsets found");
1946
+ return t;
1947
+ }
1948
+ /**
1949
+ * Get the number of strip's inside this tiff
1950
+ *
1951
+ * @remarks Used to read striped tiffs
1952
+ *
1953
+ * @returns number of strips present
1954
+ */
1955
+ get stripCount() {
1956
+ return this.tags.get(m.StripByteCounts)?.count ?? 0;
1957
+ }
1958
+ // Clamp the bounds of the output image to the size of the image, as sometimes the edge tiles are not full tiles
1959
+ getTileBounds(t, n) {
1960
+ const { size: r, tileSize: o } = this, i = n * o.height, s = t * o.width, a = s + o.width >= r.width ? r.width - s : o.width, l = i + o.height >= r.height ? r.height - i : o.height;
1961
+ return { x: s, y: i, width: a, height: l };
1962
+ }
1963
+ /**
1964
+ * Read a strip into a ArrayBuffer
1965
+ *
1966
+ * Image has to be striped see {@link stripCount}
1967
+ *
1968
+ * @param index Strip index to read
1969
+ */
1970
+ async getStrip(t, n) {
1971
+ if (this.isTiled())
1972
+ throw new Error("Cannot read stripes, tiff is tiled: " + t);
1973
+ const r = this.tags.get(m.StripByteCounts), o = this.tags.get(m.StripOffsets);
1974
+ if (t >= r.count)
1975
+ throw new Error("Cannot read strip, index out of bounds");
1976
+ const [i, s] = await Promise.all([
1977
+ Q(this.tiff, o, t, n),
1978
+ Q(this.tiff, r, t, n)
1979
+ ]);
1980
+ return this.getBytes(i, s, n);
1981
+ }
1982
+ /** The jpeg header is stored in the IFD, read the JPEG header and adjust the byte array to include it */
1983
+ getJpegHeader(t) {
1984
+ const n = this.value(m.JpegTables);
1985
+ if (n == null)
1986
+ throw new Error("Unable to find Jpeg header");
1987
+ const r = n.slice(0, n.length - 2), o = new Uint8Array(t.byteLength + r.length - 2);
1988
+ return o.set(r, 0), o.set(new Uint8Array(t).slice(2), r.length), o.buffer.slice(o.byteOffset, o.byteOffset + o.byteLength);
1989
+ }
1990
+ /** Read image bytes at the given offset */
1991
+ async getBytes(t, n, r) {
1992
+ if (n === 0)
1993
+ return null;
1994
+ const o = await this.tiff.source.fetch(t, n, r);
1995
+ if (o.byteLength < n)
1996
+ throw new Error(`Failed to fetch bytes from offset:${t} wanted:${n} got:${o.byteLength}`);
1997
+ let i = this.value(m.Compression);
1998
+ i == null && (i = P.None);
1999
+ const s = Mn(i) ?? x.None;
2000
+ return i === P.Jpeg ? { mimeType: s, bytes: this.getJpegHeader(o), compression: i } : { mimeType: s, bytes: o, compression: i };
2001
+ }
2002
+ /**
2003
+ * Load a tile into a ArrayBuffer
2004
+ *
2005
+ * if the tile compression is JPEG, This will also apply the JPEG compression tables to the resulting ArrayBuffer see {@link getJpegHeader}
2006
+ *
2007
+ * @param x Tile x offset
2008
+ * @param y Tile y offset
2009
+ */
2010
+ async getTile(t, n, r) {
2011
+ const o = this.size, i = this.tileSize;
2012
+ if (i == null)
2013
+ throw new Error("Tiff is not tiled");
2014
+ const s = Math.ceil(o.height / i.height), a = Math.ceil(o.width / i.width);
2015
+ if (t >= a || n >= s)
2016
+ throw new Error(`Tile index is outside of range x:${t} >= ${a} or y:${n} >= ${s}`);
2017
+ const l = n * a + t, c = a * s;
2018
+ if (l >= c)
2019
+ throw new Error(`Tile index is outside of tile range: ${l} >= ${c}`);
2020
+ const { offset: u, imageSize: h } = await this.getTileSize(l, r);
2021
+ return this.getBytes(u, h, r);
2022
+ }
2023
+ /**
2024
+ * Does this tile exist in the tiff and does it actually have a value
2025
+ *
2026
+ * Sparse tiffs can have a lot of empty tiles, they set the tile size to `0 bytes` when the tile is empty
2027
+ * this checks the tile byte size to validate if it actually has any data.
2028
+ *
2029
+ * @param x Tile x offset
2030
+ * @param y Tile y offset
2031
+ *
2032
+ * @returns if the tile exists and has data
2033
+ */
2034
+ async hasTile(t, n, r) {
2035
+ const o = this.tileSize, i = this.size;
2036
+ if (o == null)
2037
+ throw new Error("Tiff is not tiled");
2038
+ const s = Math.ceil(i.height / o.height), a = Math.ceil(i.width / o.width);
2039
+ if (t >= a || n >= s)
2040
+ return !1;
2041
+ const l = n * a + t;
2042
+ return (await this.getTileSize(l, r)).offset > 0;
2043
+ }
2044
+ /**
2045
+ * Load the offset and byteCount of a tile
2046
+ *
2047
+ * if the tiff is sparse, offset and byteCount will be zero if the tile is empty
2048
+ *
2049
+ * @param index index in the tile array
2050
+ * @returns Offset and byteCount for the tile
2051
+ */
2052
+ async getTileSize(t, n) {
2053
+ const r = this.tags.get(m.TileByteCounts), o = Pe(this.tiff, this.tileOffset, t), i = Pe(this.tiff, r, t);
2054
+ if (o != null && i != null)
2055
+ return { offset: o, imageSize: i };
2056
+ const s = this.tiff.options?.tileLeaderByteSize;
2057
+ if (s) {
2058
+ const c = o ?? await Q(this.tiff, this.tileOffset, t, n);
2059
+ if (c === 0)
2060
+ return { offset: 0, imageSize: 0 };
2061
+ const u = await this.tiff.source.fetch(c - s, s, n);
2062
+ return { offset: c, imageSize: K(new DataView(u), 0, s, this.tiff.isLittleEndian) };
2063
+ }
2064
+ if (r == null)
2065
+ throw new Error("No tile byte counts found");
2066
+ const [a, l] = await Promise.all([
2067
+ o ?? Q(this.tiff, this.tileOffset, t, n),
2068
+ i ?? Q(this.tiff, r, t, n)
2069
+ ]);
2070
+ return { offset: a, imageSize: l };
2071
+ }
2072
+ }
2073
+ function Q(e, t, n, r) {
2074
+ const o = Pe(e, t, n);
2075
+ return o != null ? Promise.resolve(o) : Bn(e, t, n, r);
2076
+ }
2077
+ function Pe(e, t, n) {
2078
+ if (n < 0)
2079
+ throw new Error(`Tiff: ${e.source.url.href} out of bounds ${m[t.id]} index:${n} total:${t.count}`);
2080
+ return n >= t.count ? 0 : t.type === "inline" || t.isLoaded ? t.value[n] : Gn(e, t, n);
2081
+ }
2082
+ var k;
2083
+ (function(e) {
2084
+ e.GdalStructuralMetadataSize = "GDAL_STRUCTURAL_METADATA_SIZE", e.Layout = "LAYOUT", e.BlockOrder = "BLOCK_ORDER", e.BlockLeader = "BLOCK_LEADER", e.BlockTrailer = "BLOCK_TRAILER", e.KnownIncompatibleEdition = "KNOWN_INCOMPATIBLE_EDITION", e.MaskInterleavedWithImagery = "MASK_INTERLEAVED_WITH_IMAGERY";
2085
+ })(k || (k = {}));
2086
+ var Ye;
2087
+ (function(e) {
2088
+ e.RowMajor = "ROW_MAJOR";
2089
+ })(Ye || (Ye = {}));
2090
+ var be;
2091
+ (function(e) {
2092
+ e.uint32 = "SIZE_AS_UINT4";
2093
+ })(be || (be = {}));
2094
+ class Wn {
2095
+ options = /* @__PURE__ */ new Map();
2096
+ /**
2097
+ * Has GDAL optimized this tiff
2098
+ */
2099
+ get isCogOptimized() {
2100
+ return this.isBroken ? !1 : this.options.get(k.Layout) === "IFDS_BEFORE_DATA";
2101
+ }
2102
+ /**
2103
+ * Has GDAL determined this tiff is now broken
2104
+ */
2105
+ get isBroken() {
2106
+ return this.options.get(k.KnownIncompatibleEdition) === "YES";
2107
+ }
2108
+ /**
2109
+ * Load the ghost options from a source
2110
+ * @param bytes the ghost header bytes
2111
+ */
2112
+ process(t, n, r) {
2113
+ let o = "", i = "", s = !1;
2114
+ for (let a = 0; a < r; a++) {
2115
+ const l = t.getUint8(n + a);
2116
+ if (l === 0)
2117
+ break;
2118
+ const c = String.fromCharCode(l);
2119
+ c === `
2120
+ ` ? (this.options.set(o.trim(), i.trim()), o = "", i = "", s = !1) : c === "=" ? s = !0 : s ? i += c : o += c;
2121
+ }
2122
+ }
2123
+ /**
2124
+ * If the tile leader is set, how many bytes are allocated to the tile size
2125
+ */
2126
+ get tileLeaderByteSize() {
2127
+ switch (this.options.get(k.BlockLeader)) {
2128
+ case be.uint32:
2129
+ return O.UInt32;
2130
+ default:
2131
+ return null;
2132
+ }
2133
+ }
2134
+ get isMaskInterleaved() {
2135
+ return this.options.get(k.MaskInterleavedWithImagery) === "YES";
2136
+ }
2137
+ }
2138
+ const ut = {
2139
+ version: N.Tiff,
2140
+ pointer: O.UInt32,
2141
+ offset: O.UInt16,
2142
+ /**
2143
+ * Each tag entry is specified as
2144
+ * UInt16:TagCode
2145
+ * UInt16:TagType
2146
+ * UInt32:TagCount
2147
+ * UInt32:Pointer To Value or value
2148
+ */
2149
+ ifd: O.UInt16 + O.UInt16 + 2 * O.UInt32
2150
+ }, ht = {
2151
+ version: N.BigTiff,
2152
+ /** Size of most pointers */
2153
+ pointer: O.UInt64,
2154
+ /** Size of offsets */
2155
+ offset: O.UInt64,
2156
+ /**
2157
+ * Each tag entry is specified as
2158
+ * UInt16:TagCode
2159
+ * UInt16:TagType
2160
+ * UInt64:TagCount
2161
+ * UInt64:Pointer To Value or value
2162
+ */
2163
+ ifd: O.UInt16 + O.UInt16 + 2 * O.UInt64
2164
+ };
2165
+ N.BigTiff + "", N.Tiff + "";
2166
+ function Hn(e, t = 4, n = !0) {
2167
+ const r = e.toString(16).padStart(t, "0");
2168
+ return n ? "0x" + r : r;
2169
+ }
2170
+ class Z {
2171
+ /** Read 16KB blocks at a time */
2172
+ static DefaultReadSize = 16 * 1024;
2173
+ /** Read 16KB blocks at a time */
2174
+ defaultReadSize = Z.DefaultReadSize;
2175
+ /** Where this cog is fetching its data from */
2176
+ source;
2177
+ /** Big or small Tiff */
2178
+ version = N.Tiff;
2179
+ /** List of images, o is the base image */
2180
+ images = [];
2181
+ /** Ghost header options */
2182
+ options;
2183
+ /** Configuration for the size of the IFD */
2184
+ ifdConfig = ut;
2185
+ /** Is the tiff being read is little Endian */
2186
+ isLittleEndian = !1;
2187
+ /** Has init() been called */
2188
+ isInitialized = !1;
2189
+ _initPromise;
2190
+ /** A Tiff constructed from a source will not be pre-initialized with {@link init}. */
2191
+ constructor(t, n = { defaultReadSize: Z.DefaultReadSize }) {
2192
+ this.source = t, this.defaultReadSize = n.defaultReadSize;
2193
+ }
2194
+ /** Create a tiff and initialize it by reading the tiff headers */
2195
+ static create(t, n = { defaultReadSize: Z.DefaultReadSize }) {
2196
+ return new Z(t, n).init(n);
2197
+ }
2198
+ /**
2199
+ * Initialize the tiff loading in the header and all image headers.
2200
+ *
2201
+ * This is only required if the Tiff was created with the constructor, if you
2202
+ * used {@link create} this will have already been called.
2203
+ */
2204
+ init(t) {
2205
+ return this.isInitialized ? Promise.resolve(this) : this._initPromise ? this._initPromise : (this._initPromise = this.readHeader(t), this._initPromise);
2206
+ }
2207
+ /**
2208
+ * Find a image which has a resolution similar to the provided resolution
2209
+ *
2210
+ * @param resolution resolution to find
2211
+ */
2212
+ getImageByResolution(t) {
2213
+ const n = this.images[0], r = n.size, [o] = n.resolution, i = o * r.width;
2214
+ for (let s = this.images.length - 1; s > 0; s--) {
2215
+ const a = this.images[s], l = a.size;
2216
+ if (i / l.width - t <= 0.01)
2217
+ return a;
2218
+ }
2219
+ return n;
2220
+ }
2221
+ /** Read the Starting header and all Image headers from the source */
2222
+ async readHeader(t) {
2223
+ if (this.isInitialized)
2224
+ return this;
2225
+ const n = new DataView(await this.source.fetch(0, Je(this.source, 0, this.defaultReadSize), t));
2226
+ if (n.byteLength === 0)
2227
+ throw new Error("Unable to read empty tiff");
2228
+ n.sourceOffset = 0;
2229
+ let r = 0;
2230
+ const o = n.getUint16(r, this.isLittleEndian);
2231
+ r += 2, this.isLittleEndian = o === ye.Little, this.version = n.getUint16(r, this.isLittleEndian), r += 2;
2232
+ let i;
2233
+ if (this.version === N.BigTiff) {
2234
+ this.ifdConfig = ht;
2235
+ const a = n.getUint16(r, this.isLittleEndian);
2236
+ if (r += 2, a !== 8)
2237
+ throw new Error("Only 8byte pointers are supported");
2238
+ const l = n.getUint16(r, this.isLittleEndian);
2239
+ if (r += 2, l !== 0)
2240
+ throw new Error("Invalid big tiff header");
2241
+ i = K(n, r, this.ifdConfig.pointer, this.isLittleEndian), r += this.ifdConfig.pointer;
2242
+ } else if (this.version === N.Tiff)
2243
+ i = K(n, r, this.ifdConfig.pointer, this.isLittleEndian), r += this.ifdConfig.pointer;
2244
+ else
2245
+ throw new Error(`Only tiff supported version:${String(this.version)}`);
2246
+ const s = i - r;
2247
+ for (s > 0 && s < 16 * 1024 && (this.options = new Wn(), this.options.process(n, r, s)); i !== 0; ) {
2248
+ let a = n;
2249
+ if (!se(a, i, 1024)) {
2250
+ const l = await this.source.fetch(i, Je(this.source, i, this.defaultReadSize), t);
2251
+ a = new DataView(l), a.sourceOffset = i;
2252
+ }
2253
+ i = this.readIfd(i, a);
2254
+ }
2255
+ return await Promise.all(this.images.map((a) => a.init(!0, t))), this.isInitialized = !0, this;
2256
+ }
2257
+ /**
2258
+ * Read a IFD at a the provided offset
2259
+ *
2260
+ * @param offset file offset to read the header from
2261
+ * @param view offset that contains the bytes for the header
2262
+ */
2263
+ readIfd(t, n) {
2264
+ const r = t - n.sourceOffset, o = K(n, r, this.ifdConfig.offset, this.isLittleEndian), i = /* @__PURE__ */ new Map(), s = o * this.ifdConfig.ifd;
2265
+ if (!se(n, t, s))
2266
+ throw new Error("IFD out of range @ " + Hn(t) + " IFD" + this.images.length);
2267
+ const a = this.ifdConfig.ifd, l = r + this.ifdConfig.offset;
2268
+ for (let c = 0; c < o; c++) {
2269
+ const u = Fn(this, n, l + c * a);
2270
+ i.set(u.id, u);
2271
+ }
2272
+ return this.images.push(new Xn(this, this.images.length, i)), K(n, l + o * a, this.ifdConfig.pointer, this.isLittleEndian);
2273
+ }
2274
+ }
2275
+ function Je(e, t, n) {
2276
+ const r = e.metadata?.size;
2277
+ return r == null || r < 0 ? n : t + n > r ? r - t : n;
2278
+ }
2279
+ async function Ce(e, t) {
2280
+ const n = new Blob([e]), r = await createImageBitmap(n), o = new OffscreenCanvas(r.width, r.height), i = o.getContext("2d");
2281
+ i.drawImage(r, 0, 0), r.close();
2282
+ const { width: s, height: a } = o, c = i.getImageData(0, 0, s, a).data, u = t.samplesPerPixel;
2283
+ if (u === 4)
2284
+ return { layout: "pixel-interleaved", data: c };
2285
+ if (u === 3) {
2286
+ const h = s * a, p = new Uint8ClampedArray(h * 3);
2287
+ for (let d = 0, g = 0; d < p.length; d += 3, g += 4)
2288
+ p[d] = c[g], p[d + 1] = c[g + 1], p[d + 2] = c[g + 2];
2289
+ return { layout: "pixel-interleaved", data: p };
2290
+ }
2291
+ if (u === 1) {
2292
+ const h = s * a, p = new Uint8ClampedArray(h);
2293
+ for (let d = 0, g = 0; d < h; d++, g += 4)
2294
+ p[d] = c[g];
2295
+ return { layout: "pixel-interleaved", data: p };
2296
+ }
2297
+ throw new Error(`Unsupported SamplesPerPixel for JPEG: ${u}`);
2298
+ }
2299
+ function kn(e, t = "") {
2300
+ if (!e)
2301
+ throw new Error(t);
2302
+ }
2303
+ async function Zn(e, { format: t, signal: n }) {
2304
+ const r = e instanceof Response ? e : new Response(e);
2305
+ kn(r.body, "Response does not contain body.");
2306
+ try {
2307
+ return await new Response(r.body.pipeThrough(new DecompressionStream(t), { signal: n })).arrayBuffer();
2308
+ } catch {
2309
+ throw n?.throwIfAborted(), new Error(`Failed to decode ${t}`);
2310
+ }
2311
+ }
2312
+ async function dt(e) {
2313
+ return Zn(e, { format: "deflate" });
2314
+ }
2315
+ function Vn(e, t) {
2316
+ const n = e;
2317
+ let r = 0, o = e.length - t;
2318
+ do {
2319
+ for (let i = t; i > 0; i--)
2320
+ n[r + t] = (n[r + t] ?? 0) + (n[r] ?? 0), r++;
2321
+ o -= t;
2322
+ } while (o > 0);
2323
+ }
2324
+ function Yn(e, t, n) {
2325
+ let r = 0, o = e.length;
2326
+ const i = o / n;
2327
+ for (; o > t; ) {
2328
+ for (let a = t; a > 0; a--)
2329
+ e[r + t] += e[r], r++;
2330
+ o -= t;
2331
+ }
2332
+ const s = e.slice();
2333
+ for (let a = 0; a < i; a++)
2334
+ for (let l = 0; l < n; l++)
2335
+ e[n * a + l] = s[(n - l - 1) * i + a];
2336
+ }
2337
+ function Jn(e, t, n, r, o, i, s) {
2338
+ if (t === V.None)
2339
+ return e;
2340
+ const a = o / 8, l = s === U.Separate ? 1 : i;
2341
+ for (let c = 0; c < r; c++) {
2342
+ const u = c * l * n * a;
2343
+ if (u >= e.byteLength)
2344
+ break;
2345
+ if (t === V.Horizontal) {
2346
+ let h;
2347
+ const p = l * n;
2348
+ switch (o) {
2349
+ case 8:
2350
+ h = new Uint8Array(e, u, p);
2351
+ break;
2352
+ case 16:
2353
+ h = new Uint16Array(e, u, p);
2354
+ break;
2355
+ case 32:
2356
+ h = new Uint32Array(e, u, p);
2357
+ break;
2358
+ default:
2359
+ throw new Error(`Predictor 2 not supported for ${o} bits per sample.`);
2360
+ }
2361
+ Vn(h, l);
2362
+ } else if (t === V.FloatingPoint) {
2363
+ const h = new Uint8Array(e, u, l * n * a);
2364
+ Yn(h, l, a);
2365
+ }
2366
+ }
2367
+ return e;
2368
+ }
2369
+ async function qn(e) {
2370
+ return e;
2371
+ }
2372
+ const D = /* @__PURE__ */ new Map();
2373
+ D.set(P.None, () => Promise.resolve(qn));
2374
+ D.set(P.Deflate, () => Promise.resolve(dt));
2375
+ D.set(P.DeflateOther, () => Promise.resolve(dt));
2376
+ D.set(P.Lzw, () => import("./lzw-BY5a_5nb.js").then((e) => e.decode));
2377
+ D.set(P.Zstd, () => import("./zstd-jXobGRcq.js").then((e) => e.decode));
2378
+ D.set(P.Jpeg, () => Promise.resolve(Ce));
2379
+ D.set(P.Jpeg6, () => Promise.resolve(Ce));
2380
+ D.set(P.Webp, () => Promise.resolve(Ce));
2381
+ D.set(P.Lerc, () => import("./lerc-C-D0ZLmp.js").then((e) => e.l).then((e) => e.decode));
2382
+ async function je(e, t, n) {
2383
+ const r = D.get(t);
2384
+ if (!r)
2385
+ throw new Error(`Unsupported compression: ${t}`);
2386
+ const i = await (await r())(e, n);
2387
+ if (i instanceof ArrayBuffer) {
2388
+ const { predictor: s, width: a, height: l, bitsPerSample: c, samplesPerPixel: u, planarConfiguration: h } = n, p = Jn(i, s, a, l, c, u, h);
2389
+ return {
2390
+ layout: "pixel-interleaved",
2391
+ data: Tn(p, n)
2392
+ };
2393
+ }
2394
+ return i;
2395
+ }
2396
+ function Qn(e, t) {
2397
+ const n = new Uint8Array(e), r = new Uint8Array(t);
2398
+ for (let o = 0; o < t; o++)
2399
+ r[o] = n[o >> 3] >> 7 - (o & 7) & 1 ? 255 : 0;
2400
+ return r;
2401
+ }
2402
+ function Tn(e, t) {
2403
+ const { sampleFormat: n, bitsPerSample: r } = t;
2404
+ switch (n) {
2405
+ case F.Uint:
2406
+ switch (r) {
2407
+ case 1:
2408
+ return Qn(e, t.width * t.height * t.samplesPerPixel);
2409
+ case 8:
2410
+ return new Uint8Array(e);
2411
+ case 16:
2412
+ return new Uint16Array(e);
2413
+ case 32:
2414
+ return new Uint32Array(e);
2415
+ }
2416
+ break;
2417
+ case F.Int:
2418
+ switch (r) {
2419
+ case 8:
2420
+ return new Int8Array(e);
2421
+ case 16:
2422
+ return new Int16Array(e);
2423
+ case 32:
2424
+ return new Int32Array(e);
2425
+ }
2426
+ break;
2427
+ case F.Float:
2428
+ switch (r) {
2429
+ case 32:
2430
+ return new Float32Array(e);
2431
+ case 64:
2432
+ return new Float64Array(e);
2433
+ }
2434
+ break;
2435
+ }
2436
+ throw new Error(`Unsupported sample format/depth: SampleFormat=${n}, BitsPerSample=${r}`);
2437
+ }
2438
+ class $n {
2439
+ name = "source:cache";
2440
+ maxSize;
2441
+ /** Number of bytes cached in cacheA, when this overflows maxSize cacheA is moved to cacheB and cacheB is dropped */
2442
+ size = 0;
2443
+ /** Number of times `this.cacheB` has been cleared */
2444
+ resets = 0;
2445
+ /** Primary cache of objects */
2446
+ cacheA = /* @__PURE__ */ new Map();
2447
+ cacheB = /* @__PURE__ */ new Map();
2448
+ /** List of protocols to cache */
2449
+ protocols;
2450
+ constructor(t) {
2451
+ this.maxSize = t.size, this.protocols = new Set(t.protocols ?? []);
2452
+ }
2453
+ fetch(t, n) {
2454
+ if (this.protocols.size > 0 && !this.protocols.has(t.source.url.protocol) || t.length == null)
2455
+ return n(t);
2456
+ const r = `${t.source.url.toString()}@${t.offset}+${t.length}`;
2457
+ let o = this.cacheA.get(r);
2458
+ return o ? (o.hits++, o.promise) : (o = this.cacheB.get(r), o ? (o.hits++, o.saves++, this.size += o.size, this.cacheA.set(r, o), o.promise) : (o = { promise: n(t), hits: 0, saves: 0, size: t.length }, this.size += o.size, this.size > this.maxSize && (this.size = o.size, this.cacheB = this.cacheA, this.cacheA = /* @__PURE__ */ new Map(), this.resets++), this.cacheA.set(r, o), o.promise));
2459
+ }
2460
+ }
2461
+ class B extends Error {
2462
+ /** Status code for the error eg 403 - Forbidden vs 404 Not found */
2463
+ code;
2464
+ /** URL that the status code came from */
2465
+ url;
2466
+ /** File system that triggered the error */
2467
+ source;
2468
+ constructor(t, n, r, o) {
2469
+ super(t, { cause: o }), this.code = n, this.url = r.url, this.source = r, Object.defineProperty(this, "_sourceError", {
2470
+ enumerable: !1,
2471
+ // hide it from for..in
2472
+ value: "SourceError"
2473
+ });
2474
+ }
2475
+ /** Check that a unknown is a FsError */
2476
+ static is(t) {
2477
+ return t instanceof B ? !0 : typeof t != "object" || t == null ? !1 : "_sourceError" in t && t._sourceError === "SourceError";
2478
+ }
2479
+ }
2480
+ const le = {
2481
+ /** Convert a offset/length to a range request
2482
+ *
2483
+ * @example
2484
+ * ```typescript
2485
+ * ContentRange.toRange(10) // "bytes=10"
2486
+ * ContentRange.toRange(0, 1024) // "bytes=0-1023"
2487
+ * ```
2488
+ */
2489
+ toRange(e, t) {
2490
+ if (t == null)
2491
+ return `bytes=${e}`;
2492
+ if (e < 0)
2493
+ throw new Error("Cannot read from remote source with negative offset and length");
2494
+ return `bytes=${e}-${e + t - 1}`;
2495
+ },
2496
+ /**
2497
+ * Parse a Content-Range header to extract the size of the source
2498
+ *
2499
+ * @example
2500
+ * ```typescript
2501
+ * ContentRange.parseRange("bytes 200-1000/67589"); // 67589
2502
+ * ```
2503
+ * @throws if range is not a Content-Range with size
2504
+ */
2505
+ parseSize(e) {
2506
+ const [t, n] = e.split(" ");
2507
+ if (t !== "bytes")
2508
+ throw new Error("Failed to parse content-range: " + e);
2509
+ if (n == null)
2510
+ throw new Error("Failed to parse content-range: " + e);
2511
+ const [, r] = n.split("/"), o = Number(r);
2512
+ if (isNaN(o))
2513
+ throw new Error("Failed to parse content-range: " + e);
2514
+ return o;
2515
+ }
2516
+ };
2517
+ class er {
2518
+ source;
2519
+ middleware;
2520
+ static is(t) {
2521
+ return "middleware" in t;
2522
+ }
2523
+ constructor(t, n = []) {
2524
+ this.source = t, this.middleware = n;
2525
+ }
2526
+ get type() {
2527
+ return this.source.type;
2528
+ }
2529
+ get url() {
2530
+ return this.source.url;
2531
+ }
2532
+ get metadata() {
2533
+ return this.source.metadata;
2534
+ }
2535
+ head(t) {
2536
+ return this.source.head(t);
2537
+ }
2538
+ async fetch(t, n, r) {
2539
+ const o = this.middleware;
2540
+ if (o == null || o.length === 0)
2541
+ return this.source.fetch(t, n, r);
2542
+ const i = (s) => this.source.fetch(s.offset, s.length, r);
2543
+ return this.run(i, t, n, r);
2544
+ }
2545
+ /** Run a request using all the middleware */
2546
+ async run(t, n, r, o) {
2547
+ const i = this.middleware;
2548
+ if (i == null)
2549
+ return t({ source: this, offset: n, length: r, signal: o?.signal });
2550
+ function s(a, l) {
2551
+ return (c) => a.fetch(c, l);
2552
+ }
2553
+ for (let a = i.length - 1; a >= 0; a--)
2554
+ t = s(i[a], t);
2555
+ return t({ source: this, offset: n, length: r, signal: o?.signal });
2556
+ }
2557
+ }
2558
+ function tr(e) {
2559
+ try {
2560
+ return new URL(e);
2561
+ } catch {
2562
+ return null;
2563
+ }
2564
+ }
2565
+ class nr {
2566
+ name = "source:chunk";
2567
+ /** Number of bytes to chunk requests into */
2568
+ chunkSize;
2569
+ constructor(t) {
2570
+ this.chunkSize = t.size ?? 32 * 1024;
2571
+ }
2572
+ async fetch(t, n) {
2573
+ if (t.offset < 0 || t.length == null)
2574
+ return n(t);
2575
+ const r = Math.floor(t.offset / this.chunkSize), o = Math.ceil((t.offset + t.length) / this.chunkSize), i = t.source.metadata?.size;
2576
+ if (i != null && t.offset + t.length > i)
2577
+ throw new B(`Request outside of bounds ${le.toRange(t.offset, t.length)}`, 416, t.source);
2578
+ const s = r * this.chunkSize, l = (i != null ? Math.min(o * this.chunkSize, i) : o * this.chunkSize) - s, c = t.offset - s;
2579
+ return o - r > 1 ? (await this.fetchChunks(t, r, o)).slice(c, c + t.length) : t.offset === s && t.length === l ? n(t) : (await n({ ...t, offset: s, length: l })).slice(c, c + t.length);
2580
+ }
2581
+ async fetchChunks(t, n, r) {
2582
+ const o = [], i = t.source.metadata?.size ?? r * this.chunkSize;
2583
+ for (let l = n; l < r; l++) {
2584
+ const c = l * this.chunkSize, h = Math.min(c + this.chunkSize, i) - c;
2585
+ o.push(t.source.fetch(l * this.chunkSize, h, t.signal ? { signal: t.signal } : void 0));
2586
+ }
2587
+ const s = await Promise.all(o), a = new Uint8Array(o.length * this.chunkSize);
2588
+ for (let l = 0; l < s.length; l++)
2589
+ a.set(new Uint8Array(s[l]), l * this.chunkSize);
2590
+ return a.buffer;
2591
+ }
2592
+ }
2593
+ function qe(e) {
2594
+ const t = {}, n = e.headers.get("content-length");
2595
+ n && (t.size = parseInt(n));
2596
+ const r = e.headers.get("content-range");
2597
+ return r != null && (t.size = le.parseSize(r)), t.eTag = e.headers.get("etag") ?? void 0, t.contentType = e.headers.get("content-type") ?? void 0, t.contentDisposition = e.headers.get("content-disposition") ?? void 0, t.cacheControl = e.headers.get("cache-control") ?? void 0, t.contentEncoding = e.headers.get("content-encoding") ?? void 0, t;
2598
+ }
2599
+ class Y {
2600
+ constructor(t, n) {
2601
+ this.type = "http", this.url = typeof t == "string" ? Y.tryUrl(t) : t, this.headers = n;
2602
+ }
2603
+ /** Attempt to parse a relative string into a URL */
2604
+ static tryUrl(t) {
2605
+ try {
2606
+ return new URL(t);
2607
+ } catch {
2608
+ return typeof document < "u" ? new URL(t, document.baseURI) : new URL(t, import.meta.url);
2609
+ }
2610
+ }
2611
+ head() {
2612
+ return this._head ? this._head : (this._head = Y.fetch(this.url, { method: "HEAD", headers: this.headers }).then((t) => {
2613
+ if (!t.ok)
2614
+ throw delete this._head, new Error(`Failed to HEAD ${this.url.href}`, { cause: { statusCode: t.status, msg: t.statusText } });
2615
+ return this.metadata = qe(t), this.metadata;
2616
+ }), this._head);
2617
+ }
2618
+ async fetch(t, n, r) {
2619
+ try {
2620
+ const o = { range: le.toRange(t, n), ...this.headers }, i = await Y.fetch(this.url, { headers: o, signal: r?.signal });
2621
+ if (!i.ok)
2622
+ throw new B(`Failed to fetch ${this.url.href} ${o.range}`, i.status, this, new Error(i.statusText));
2623
+ const s = qe(i);
2624
+ if (this.metadata == null)
2625
+ this.metadata = s;
2626
+ else if (this.metadata.eTag && this.metadata.eTag !== s.eTag)
2627
+ throw new B(`ETag conflict ${this.url.href} ${o.range} expected: ${this.metadata.eTag} got: ${s.eTag}`, 409, this);
2628
+ return i.arrayBuffer();
2629
+ } catch (o) {
2630
+ throw B.is(o) && o.source === this ? o : new B(`Failed to fetch: ${this.url.href}`, 500, this, o);
2631
+ }
2632
+ }
2633
+ }
2634
+ Y.fetch = (e, t) => fetch(e, t);
2635
+ function rr(e) {
2636
+ if (typeof e != "string")
2637
+ return e;
2638
+ const t = tr(e);
2639
+ return t || new URL("memory://" + e);
2640
+ }
2641
+ class xe {
2642
+ url;
2643
+ type = "memory";
2644
+ data;
2645
+ metadata;
2646
+ static toArrayBuffer(t) {
2647
+ return t instanceof ArrayBuffer ? t : t.byteLength === t.buffer.byteLength ? t.buffer : t.buffer.slice(t.byteOffset, t.byteOffset + t.byteLength);
2648
+ }
2649
+ constructor(t, n) {
2650
+ const r = xe.toArrayBuffer(n ?? new Uint8Array());
2651
+ this.url = rr(t), this.data = r, this.metadata = { size: r.byteLength };
2652
+ }
2653
+ head() {
2654
+ return Promise.resolve({ size: this.data.byteLength });
2655
+ }
2656
+ fetch(t, n) {
2657
+ if (t < 0 && (t = this.data.byteLength + t), t > this.data.byteLength)
2658
+ throw new B(`Read offset outside of file bounds range:${le.toRange(t, n)} fileSize:${this.data.byteLength}`, 416, this);
2659
+ return Promise.resolve(this.data.slice(t, n == null ? void 0 : t + n));
2660
+ }
2661
+ }
2662
+ const pt = "https://proj.org/schemas/v0.7/projjson.schema.json", or = 1, ir = 2, ee = 32767, Qe = 1, sr = 2, ar = 3, lr = 4, cr = 5, ur = 6, hr = 7, dr = 8, pr = 9, mr = 10, gr = 11, fr = 12, yr = 14, wr = 15, Pr = 16, br = 17, vr = 18, Sr = 21, Lr = 22, Cr = 24, jr = 26, xr = 27, mt = 9102, Or = 9101, Ar = 9105, Er = {
2663
+ [mt]: "degree",
2664
+ [Or]: "radian",
2665
+ [Ar]: "grad"
2666
+ }, gt = 9001, Ir = 9002, Mr = 9003, Rr = {
2667
+ type: "LinearUnit",
2668
+ name: "US survey foot",
2669
+ conversion_factor: 0.30480060960121924
2670
+ }, zr = {
2671
+ [gt]: "metre",
2672
+ [Ir]: "foot",
2673
+ [Mr]: Rr
2674
+ };
2675
+ function Fr(e) {
2676
+ const t = e.modelType;
2677
+ if (t === or)
2678
+ return Nr(e);
2679
+ if (t === ir)
2680
+ return Dr(e);
2681
+ throw new Error(`Unsupported GeoTIFF model type: ${t}`);
2682
+ }
2683
+ function Dr(e) {
2684
+ const t = e.geodeticCRS;
2685
+ return t !== null && t !== ee ? t : ft(e, pt);
2686
+ }
2687
+ function Nr(e) {
2688
+ const t = e.projectedCRS;
2689
+ return t !== null && t !== ee ? t : Ur(e);
2690
+ }
2691
+ function ft(e, t) {
2692
+ const n = Br(e);
2693
+ let r = "Greenwich", o = 0;
2694
+ e.primeMeridian !== null && e.primeMeridian !== ee ? r = `EPSG:${e.primeMeridian}` : e.primeMeridianLongitude !== null && (o = e.primeMeridianLongitude, r = "User-defined");
2695
+ let i;
2696
+ e.geodeticDatum !== null && e.geodeticDatum !== ee ? i = {
2697
+ type: "GeodeticReferenceFrame",
2698
+ name: `Unknown datum based upon EPSG ${e.geodeticDatum} ellipsoid`
2699
+ } : i = {
2700
+ type: "GeodeticReferenceFrame",
2701
+ name: e.geodeticCitation ?? "User-defined",
2702
+ ellipsoid: n,
2703
+ prime_meridian: { name: r, longitude: o }
2704
+ };
2705
+ const s = {
2706
+ type: "GeographicCRS",
2707
+ name: e.geodeticCitation ?? "User-defined",
2708
+ datum: i,
2709
+ coordinate_system: Kr(e)
2710
+ };
2711
+ return t !== void 0 && (s.$schema = t), s;
2712
+ }
2713
+ function Ur(e) {
2714
+ const t = ft(e), n = Gr(e), r = _r(e);
2715
+ return {
2716
+ type: "ProjectedCRS",
2717
+ $schema: pt,
2718
+ name: e.projectedCitation ?? e.citation ?? "User-defined",
2719
+ base_crs: t,
2720
+ conversion: n,
2721
+ coordinate_system: r
2722
+ };
2723
+ }
2724
+ function Br(e) {
2725
+ if (e.ellipsoid !== null && e.ellipsoid !== ee) {
2726
+ const n = {
2727
+ name: `EPSG ellipsoid ${e.ellipsoid}`
2728
+ };
2729
+ return e.ellipsoidSemiMajorAxis !== null && (n.semi_major_axis = e.ellipsoidSemiMajorAxis), e.ellipsoidInvFlattening !== null ? n.inverse_flattening = e.ellipsoidInvFlattening : e.ellipsoidSemiMinorAxis !== null && (n.semi_minor_axis = e.ellipsoidSemiMinorAxis), n;
2730
+ }
2731
+ if (e.ellipsoidSemiMajorAxis === null)
2732
+ throw new Error("User-defined ellipsoid requires ellipsoidSemiMajorAxis");
2733
+ const t = {
2734
+ name: e.geodeticCitation ?? "User-defined",
2735
+ semi_major_axis: e.ellipsoidSemiMajorAxis
2736
+ };
2737
+ if (e.ellipsoidInvFlattening !== null)
2738
+ t.inverse_flattening = e.ellipsoidInvFlattening;
2739
+ else if (e.ellipsoidSemiMinorAxis !== null)
2740
+ t.semi_minor_axis = e.ellipsoidSemiMinorAxis;
2741
+ else
2742
+ throw new Error("User-defined ellipsoid requires ellipsoidInvFlattening or ellipsoidSemiMinorAxis");
2743
+ return t;
2744
+ }
2745
+ function Gr(e) {
2746
+ const t = e.projMethod;
2747
+ if (t === null)
2748
+ throw new Error("User-defined projected CRS requires projMethod");
2749
+ const n = (i, s, a = 0) => ({
2750
+ name: i,
2751
+ value: s ?? a,
2752
+ unit: "degree"
2753
+ }), r = (i, s, a = 0) => ({
2754
+ name: i,
2755
+ value: s ?? a,
2756
+ unit: "metre"
2757
+ }), o = (i, s, a = 1) => ({
2758
+ name: i,
2759
+ value: s ?? a,
2760
+ unit: "unity"
2761
+ });
2762
+ switch (t) {
2763
+ case Qe:
2764
+ case sr:
2765
+ case xr: {
2766
+ const i = t === Qe ? "Transverse Mercator" : "Transverse Mercator (South Orientated)";
2767
+ return {
2768
+ name: i,
2769
+ method: { name: i },
2770
+ parameters: [
2771
+ n("Latitude of natural origin", e.projNatOriginLat),
2772
+ n("Longitude of natural origin", e.projNatOriginLong),
2773
+ o("Scale factor at natural origin", e.projScaleAtNatOrigin),
2774
+ r("False easting", e.projFalseEasting),
2775
+ r("False northing", e.projFalseNorthing)
2776
+ ]
2777
+ };
2778
+ }
2779
+ case ar:
2780
+ case lr:
2781
+ case cr:
2782
+ case ur: {
2783
+ const i = "Hotine Oblique Mercator (variant B)";
2784
+ return {
2785
+ name: i,
2786
+ method: { name: i },
2787
+ parameters: [
2788
+ n("Latitude of projection centre", e.projCenterLat),
2789
+ n("Longitude of projection centre", e.projCenterLong),
2790
+ n("Azimuth of initial line", e.projAzimuthAngle),
2791
+ n("Angle from Rectified to Skew Grid", e.projAzimuthAngle),
2792
+ o("Scale factor on initial line", e.projScaleAtCenter),
2793
+ r("Easting at projection centre", e.projCenterEasting),
2794
+ r("Northing at projection centre", e.projCenterNorthing)
2795
+ ]
2796
+ };
2797
+ }
2798
+ case hr: {
2799
+ const i = "Mercator (variant A)";
2800
+ return {
2801
+ name: i,
2802
+ method: { name: i },
2803
+ parameters: [
2804
+ n("Latitude of natural origin", e.projNatOriginLat),
2805
+ n("Longitude of natural origin", e.projNatOriginLong),
2806
+ o("Scale factor at natural origin", e.projScaleAtNatOrigin),
2807
+ r("False easting", e.projFalseEasting),
2808
+ r("False northing", e.projFalseNorthing)
2809
+ ]
2810
+ };
2811
+ }
2812
+ case dr: {
2813
+ const i = "Lambert Conic Conformal (2SP)";
2814
+ return {
2815
+ name: i,
2816
+ method: { name: i },
2817
+ parameters: [
2818
+ n("Latitude of false origin", e.projFalseOriginLat ?? e.projNatOriginLat),
2819
+ n("Longitude of false origin", e.projFalseOriginLong ?? e.projNatOriginLong),
2820
+ n("Latitude of 1st standard parallel", e.projStdParallel1),
2821
+ n("Latitude of 2nd standard parallel", e.projStdParallel2),
2822
+ r("Easting at false origin", e.projFalseOriginEasting ?? e.projFalseEasting),
2823
+ r("Northing at false origin", e.projFalseOriginNorthing ?? e.projFalseNorthing)
2824
+ ]
2825
+ };
2826
+ }
2827
+ case pr: {
2828
+ const i = "Lambert Conic Conformal (1SP)";
2829
+ return {
2830
+ name: i,
2831
+ method: { name: i },
2832
+ parameters: [
2833
+ n("Latitude of natural origin", e.projNatOriginLat),
2834
+ n("Longitude of natural origin", e.projNatOriginLong),
2835
+ o("Scale factor at natural origin", e.projScaleAtNatOrigin),
2836
+ r("False easting", e.projFalseEasting),
2837
+ r("False northing", e.projFalseNorthing)
2838
+ ]
2839
+ };
2840
+ }
2841
+ case mr: {
2842
+ const i = "Lambert Azimuthal Equal Area";
2843
+ return {
2844
+ name: i,
2845
+ method: { name: i },
2846
+ parameters: [
2847
+ n("Latitude of natural origin", e.projCenterLat),
2848
+ n("Longitude of natural origin", e.projCenterLong),
2849
+ r("False easting", e.projFalseEasting),
2850
+ r("False northing", e.projFalseNorthing)
2851
+ ]
2852
+ };
2853
+ }
2854
+ case gr: {
2855
+ const i = "Albers Equal Area";
2856
+ return {
2857
+ name: i,
2858
+ method: { name: i },
2859
+ parameters: [
2860
+ n("Latitude of false origin", e.projFalseOriginLat ?? e.projNatOriginLat),
2861
+ n("Longitude of false origin", e.projFalseOriginLong ?? e.projNatOriginLong),
2862
+ n("Latitude of 1st standard parallel", e.projStdParallel1),
2863
+ n("Latitude of 2nd standard parallel", e.projStdParallel2),
2864
+ r("Easting at false origin", e.projFalseOriginEasting ?? e.projFalseEasting),
2865
+ r("Northing at false origin", e.projFalseOriginNorthing ?? e.projFalseNorthing)
2866
+ ]
2867
+ };
2868
+ }
2869
+ case fr: {
2870
+ const i = "Modified Azimuthal Equidistant";
2871
+ return {
2872
+ name: i,
2873
+ method: { name: i },
2874
+ parameters: [
2875
+ n("Latitude of natural origin", e.projCenterLat),
2876
+ n("Longitude of natural origin", e.projCenterLong),
2877
+ r("False easting", e.projFalseEasting),
2878
+ r("False northing", e.projFalseNorthing)
2879
+ ]
2880
+ };
2881
+ }
2882
+ case yr: {
2883
+ const i = "Stereographic";
2884
+ return {
2885
+ name: i,
2886
+ method: { name: i },
2887
+ parameters: [
2888
+ n("Latitude of natural origin", e.projCenterLat),
2889
+ n("Longitude of natural origin", e.projCenterLong),
2890
+ o("Scale factor at natural origin", e.projScaleAtCenter),
2891
+ r("False easting", e.projFalseEasting),
2892
+ r("False northing", e.projFalseNorthing)
2893
+ ]
2894
+ };
2895
+ }
2896
+ case wr: {
2897
+ const i = "Polar Stereographic (variant B)";
2898
+ return {
2899
+ name: i,
2900
+ method: { name: i },
2901
+ parameters: [
2902
+ n("Latitude of standard parallel", e.projNatOriginLat ?? e.projStdParallel1),
2903
+ n("Longitude of origin", e.projStraightVertPoleLong ?? e.projNatOriginLong),
2904
+ r("False easting", e.projFalseEasting),
2905
+ r("False northing", e.projFalseNorthing)
2906
+ ]
2907
+ };
2908
+ }
2909
+ case Pr: {
2910
+ const i = "Oblique Stereographic";
2911
+ return {
2912
+ name: i,
2913
+ method: { name: i },
2914
+ parameters: [
2915
+ n("Latitude of natural origin", e.projCenterLat),
2916
+ n("Longitude of natural origin", e.projCenterLong),
2917
+ o("Scale factor at natural origin", e.projScaleAtCenter),
2918
+ r("False easting", e.projFalseEasting),
2919
+ r("False northing", e.projFalseNorthing)
2920
+ ]
2921
+ };
2922
+ }
2923
+ case br: {
2924
+ const i = "Equidistant Cylindrical";
2925
+ return {
2926
+ name: i,
2927
+ method: { name: i },
2928
+ parameters: [
2929
+ n("Latitude of 1st standard parallel", e.projStdParallel1 ?? e.projCenterLat),
2930
+ n("Longitude of natural origin", e.projCenterLong),
2931
+ r("False easting", e.projFalseEasting),
2932
+ r("False northing", e.projFalseNorthing)
2933
+ ]
2934
+ };
2935
+ }
2936
+ case vr: {
2937
+ const i = "Cassini-Soldner";
2938
+ return {
2939
+ name: i,
2940
+ method: { name: i },
2941
+ parameters: [
2942
+ n("Latitude of natural origin", e.projNatOriginLat),
2943
+ n("Longitude of natural origin", e.projNatOriginLong),
2944
+ r("False easting", e.projFalseEasting),
2945
+ r("False northing", e.projFalseNorthing)
2946
+ ]
2947
+ };
2948
+ }
2949
+ case Lr: {
2950
+ const i = "American Polyconic";
2951
+ return {
2952
+ name: i,
2953
+ method: { name: i },
2954
+ parameters: [
2955
+ n("Latitude of natural origin", e.projNatOriginLat),
2956
+ n("Longitude of natural origin", e.projNatOriginLong),
2957
+ r("False easting", e.projFalseEasting),
2958
+ r("False northing", e.projFalseNorthing)
2959
+ ]
2960
+ };
2961
+ }
2962
+ case Cr: {
2963
+ const i = "Sinusoidal";
2964
+ return {
2965
+ name: i,
2966
+ method: { name: i },
2967
+ parameters: [
2968
+ n("Longitude of natural origin", e.projCenterLong),
2969
+ r("False easting", e.projFalseEasting),
2970
+ r("False northing", e.projFalseNorthing)
2971
+ ]
2972
+ };
2973
+ }
2974
+ case Sr: {
2975
+ const i = "Orthographic";
2976
+ return {
2977
+ name: i,
2978
+ method: { name: i },
2979
+ parameters: [
2980
+ n("Latitude of natural origin", e.projCenterLat),
2981
+ n("Longitude of natural origin", e.projCenterLong),
2982
+ r("False easting", e.projFalseEasting),
2983
+ r("False northing", e.projFalseNorthing)
2984
+ ]
2985
+ };
2986
+ }
2987
+ case jr: {
2988
+ const i = "New Zealand Map Grid";
2989
+ return {
2990
+ name: i,
2991
+ method: { name: i },
2992
+ parameters: [
2993
+ n("Latitude of natural origin", e.projNatOriginLat),
2994
+ n("Longitude of natural origin", e.projNatOriginLong),
2995
+ r("False easting", e.projFalseEasting),
2996
+ r("False northing", e.projFalseNorthing)
2997
+ ]
2998
+ };
2999
+ }
3000
+ default:
3001
+ throw new Error(`Unsupported coordinate transformation type: ${t}`);
3002
+ }
3003
+ }
3004
+ function Kr(e) {
3005
+ const t = Er[e.angularUnits ?? mt] ?? "degree";
3006
+ return {
3007
+ subtype: "ellipsoidal",
3008
+ axis: [
3009
+ {
3010
+ name: "Geodetic latitude",
3011
+ abbreviation: "Lat",
3012
+ direction: "north",
3013
+ unit: t
3014
+ },
3015
+ {
3016
+ name: "Geodetic longitude",
3017
+ abbreviation: "Lon",
3018
+ direction: "east",
3019
+ unit: t
3020
+ }
3021
+ ]
3022
+ };
3023
+ }
3024
+ function _r(e) {
3025
+ const t = zr[e.projLinearUnits ?? gt] ?? "metre";
3026
+ return {
3027
+ subtype: "Cartesian",
3028
+ axis: [
3029
+ { name: "Easting", abbreviation: "E", direction: "east", unit: t },
3030
+ { name: "Northing", abbreviation: "N", direction: "north", unit: t }
3031
+ ]
3032
+ };
3033
+ }
3034
+ const Xr = 1024 * 1024, Wr = 16 * 1024 * 1024, Te = 6;
3035
+ async function Hr(e, t, n) {
3036
+ if (t.length === 0)
3037
+ return [];
3038
+ const r = n?.coalesce ?? Xr, o = n?.maxRangeSize ?? Wr, i = n?.signal, s = kr(t, r, o), a = await Vr(e, s, i), l = new Array(t.length);
3039
+ for (let c = 0; c < t.length; c++) {
3040
+ const u = t[c], h = Zr(s, u.offset), p = s[h], d = a[h], g = u.offset - p.offset, f = g + u.length;
3041
+ if (f > d.byteLength)
3042
+ throw new Error(`Failed to fetch bytes from offset:${u.offset} wanted:${u.length} got:${d.byteLength - g}`);
3043
+ l[c] = d.slice(g, f);
3044
+ }
3045
+ return l;
3046
+ }
3047
+ function kr(e, t, n) {
3048
+ const r = [...e].sort((s, a) => s.offset - a.offset), o = [];
3049
+ let i = null;
3050
+ for (const s of r) {
3051
+ if (i == null) {
3052
+ i = { offset: s.offset, length: s.length };
3053
+ continue;
3054
+ }
3055
+ const a = i.offset + i.length, l = s.offset + s.length, c = s.offset - a, u = Math.max(a, l), h = u - i.offset;
3056
+ c <= t && h <= n ? i.length = u - i.offset : (o.push(i), i = { offset: s.offset, length: s.length });
3057
+ }
3058
+ return i != null && o.push(i), o;
3059
+ }
3060
+ function Zr(e, t) {
3061
+ let n = 0, r = e.length - 1;
3062
+ for (; n < r; ) {
3063
+ const o = n + r + 1 >>> 1;
3064
+ e[o].offset <= t ? n = o : r = o - 1;
3065
+ }
3066
+ return n;
3067
+ }
3068
+ async function Vr(e, t, n) {
3069
+ const r = new Array(t.length);
3070
+ for (let o = 0; o < t.length; o += Te) {
3071
+ const i = t.slice(o, o + Te), s = await Promise.all(i.map((a) => e.fetch(a.offset, a.length, { signal: n })));
3072
+ for (let a = 0; a < s.length; a++)
3073
+ r[o + a] = s[a];
3074
+ }
3075
+ return r;
3076
+ }
3077
+ async function yt(e, t, n, { boundless: r = !0, pool: o, signal: i } = {}) {
3078
+ const s = qr(e, t, n, { signal: i }), a = e.maskImage != null ? vt(e.maskImage, t, n, e.dataSource, {
3079
+ signal: i,
3080
+ debug: e._debug ? { label: "mask" } : void 0
3081
+ }) : Promise.resolve(null), [l, c] = await Promise.all([s, a]);
3082
+ return wt(e, t, n, l, c, { boundless: r, pool: o });
3083
+ }
3084
+ async function wt(e, t, n, r, o, { boundless: i, pool: s }) {
3085
+ const { bitsPerSample: a, predictor: l, planarConfiguration: c, sampleFormat: u, lercParameters: h } = e.cachedTags, { sampleFormat: p, bitsPerSample: d } = jt(u, a), g = ae(e.transform, Le(t * e.tileWidth, n * e.tileHeight)), f = e.image.value(m.SamplesPerPixel) ?? 1, y = {
3086
+ sampleFormat: p,
3087
+ bitsPerSample: d,
3088
+ samplesPerPixel: f,
3089
+ width: e.tileWidth,
3090
+ height: e.tileHeight,
3091
+ predictor: l,
3092
+ planarConfiguration: c,
3093
+ lercParameters: h
3094
+ }, [j, b] = await Promise.all([
3095
+ Jr(r, y, s),
3096
+ o != null && e.maskImage != null ? Yr(o, e.maskImage, s) : Promise.resolve(null)
3097
+ ]), S = {
3098
+ ...j,
3099
+ count: f,
3100
+ height: e.tileHeight,
3101
+ width: e.tileWidth,
3102
+ mask: b,
3103
+ transform: g,
3104
+ crs: e.crs,
3105
+ nodata: e.nodata
3106
+ };
3107
+ return {
3108
+ x: t,
3109
+ y: n,
3110
+ array: i === !0 ? S : eo(e, t, n, S)
3111
+ };
3112
+ }
3113
+ async function Pt(e, t, { boundless: n = !0, pool: r, signal: o } = {}) {
3114
+ if (t.length === 0)
3115
+ return [];
3116
+ const i = Tr(e, t, { signal: o }), s = e.maskImage != null ? Ct(e.maskImage, t, e.dataSource, {
3117
+ signal: o,
3118
+ debug: e._debug ? { label: "mask" } : void 0
3119
+ }) : Promise.resolve(t.map(() => null)), [a, l] = await Promise.all([
3120
+ i,
3121
+ s
3122
+ ]);
3123
+ return Promise.all(t.map(([c, u], h) => wt(e, c, u, a[h], l[h] ?? null, {
3124
+ boundless: n,
3125
+ pool: r
3126
+ })));
3127
+ }
3128
+ async function Yr(e, t, n) {
3129
+ const r = t.value(m.SampleFormat) ?? [1], o = t.value(m.BitsPerSample) ?? [8], { sampleFormat: i, bitsPerSample: s } = jt(r, new Uint16Array(o)), { width: a, height: l } = t.tileSize, c = {
3130
+ sampleFormat: i,
3131
+ bitsPerSample: s,
3132
+ samplesPerPixel: t.value(m.SamplesPerPixel) ?? 1,
3133
+ width: a,
3134
+ height: l,
3135
+ predictor: t.value(m.Predictor) ?? 1,
3136
+ planarConfiguration: t.value(m.PlanarConfiguration) ?? U.Contig
3137
+ }, u = (f, y, j) => n ? n.decode(f, y, j) : je(f, y, j), { bytes: h, compression: p } = e, d = await u(h, p, c), g = d.layout === "pixel-interleaved" ? d.data : d.bands[0];
3138
+ if (g instanceof Uint8Array)
3139
+ return g;
3140
+ throw new Error("Expected mask data to decode to Uint8Array");
3141
+ }
3142
+ async function Jr(e, t, n) {
3143
+ const r = (o, i, s) => n ? n.decode(o, i, s) : je(o, i, s);
3144
+ if (Array.isArray(e)) {
3145
+ const o = { ...t, samplesPerPixel: 1 };
3146
+ return { layout: "band-separate", bands: (await Promise.all(e.map(({ bytes: a, compression: l }) => r(a, l, o)))).map((a) => a.layout === "band-separate" ? a.bands[0] : a.data) };
3147
+ } else {
3148
+ const { bytes: o, compression: i } = e;
3149
+ return r(o, i, t);
3150
+ }
3151
+ }
3152
+ async function qr(e, t, n, { signal: r } = {}) {
3153
+ const o = e._debug ? { label: "data" } : void 0;
3154
+ switch (e.cachedTags.planarConfiguration) {
3155
+ case U.Contig: {
3156
+ const i = await vt(e.image, t, n, e.dataSource, {
3157
+ signal: r,
3158
+ debug: o
3159
+ });
3160
+ if (i === null)
3161
+ throw new Error(`Tile at (${t}, ${n}) not found`);
3162
+ return i;
3163
+ }
3164
+ case U.Separate:
3165
+ return await Qr(e, t, n, { signal: r });
3166
+ default:
3167
+ throw new Error(`Unsupported PlanarConfiguration: ${e.cachedTags.planarConfiguration}`);
3168
+ }
3169
+ }
3170
+ async function bt(e, t, n) {
3171
+ const { x: r, y: o } = e.image.tileCount, i = r * o, s = e.cachedTags.samplesPerPixel, a = [...Array(s).keys()].map((l) => {
3172
+ const c = l * i + n * r + t;
3173
+ return e.image.getTileSize(c);
3174
+ });
3175
+ return Promise.all(a);
3176
+ }
3177
+ async function Qr(e, t, n, { signal: r } = {}) {
3178
+ const o = e._debug ? { label: "data" } : void 0, s = (await bt(e, t, n)).map(async ({ offset: a, imageSize: l }) => {
3179
+ const c = await St(e.image, a, l, e.dataSource, { signal: r, debug: o });
3180
+ if (c === null)
3181
+ throw new Error(`Tile at (${t}, ${n}) not found`);
3182
+ return c;
3183
+ });
3184
+ return Promise.all(s);
3185
+ }
3186
+ async function Tr(e, t, { signal: n } = {}) {
3187
+ const r = e._debug ? { label: "data" } : void 0;
3188
+ switch (e.cachedTags.planarConfiguration) {
3189
+ case U.Contig:
3190
+ return (await Ct(e.image, t, e.dataSource, {
3191
+ signal: n,
3192
+ debug: r
3193
+ })).map((i, s) => {
3194
+ if (i === null) {
3195
+ const [a, l] = t[s];
3196
+ throw new Error(`Tile at (${a}, ${l}) not found`);
3197
+ }
3198
+ return i;
3199
+ });
3200
+ case U.Separate:
3201
+ return $r(e, t, { signal: n });
3202
+ default:
3203
+ throw new Error(`Unsupported PlanarConfiguration: ${e.cachedTags.planarConfiguration}`);
3204
+ }
3205
+ }
3206
+ async function $r(e, t, { signal: n } = {}) {
3207
+ const r = e._debug ? { label: "data" } : void 0, o = e.cachedTags.samplesPerPixel, s = (await Promise.all(t.map(([l, c]) => bt(e, l, c)))).flatMap((l) => l.map(({ offset: c, imageSize: u }) => ({
3208
+ offset: c,
3209
+ byteCount: u
3210
+ }))), a = await Lt(e.image, s, e.dataSource, { signal: n, debug: r });
3211
+ return t.map(([l, c], u) => a.slice(u * o, u * o + o).map((h) => {
3212
+ if (h === null)
3213
+ throw new Error(`Tile at (${l}, ${c}) not found`);
3214
+ return h;
3215
+ }));
3216
+ }
3217
+ async function vt(e, t, n, r, o) {
3218
+ const { size: i, tileSize: s } = e;
3219
+ if (s == null)
3220
+ throw new Error("Tiff is not tiled");
3221
+ const a = Math.ceil(i.height / s.height), l = Math.ceil(i.width / s.width);
3222
+ if (t >= l || n >= a)
3223
+ throw new Error(`Tile index is outside of range x:${t} >= ${l} or y:${n} >= ${a}`);
3224
+ const c = n * l + t, u = l * a;
3225
+ if (c >= u)
3226
+ throw new Error(`Tile index is outside of tile range: ${c} >= ${u}`);
3227
+ const { offset: h, imageSize: p } = await e.getTileSize(c);
3228
+ return St(e, h, p, r, o);
3229
+ }
3230
+ async function St(e, t, n, r, o) {
3231
+ if (n === 0)
3232
+ return null;
3233
+ o?.debug !== void 0 && console.log(`[geotiff dataSource] ${o.debug.label}: offset=${t} length=${n}`);
3234
+ const i = await r.fetch(t, n, o);
3235
+ if (i.byteLength < n)
3236
+ throw new Error(`Failed to fetch bytes from offset:${t} wanted:${n} got:${i.byteLength}`);
3237
+ const s = e.value(m.Compression) ?? P.None;
3238
+ return s === P.Jpeg ? {
3239
+ bytes: e.getJpegHeader(i),
3240
+ compression: s
3241
+ } : { bytes: i, compression: s };
3242
+ }
3243
+ async function Lt(e, t, n, r) {
3244
+ if (t.length === 0)
3245
+ return [];
3246
+ const o = new Array(t.length), i = [], s = [];
3247
+ for (let c = 0; c < t.length; c++) {
3248
+ const u = t[c];
3249
+ u.offset === 0 || u.byteCount === 0 ? o[c] = null : (s.push(c), i.push({ offset: u.offset, length: u.byteCount }));
3250
+ }
3251
+ if (i.length === 0)
3252
+ return o;
3253
+ if (r?.debug !== void 0)
3254
+ for (const c of i)
3255
+ console.log(`[geotiff dataSource] ${r.debug.label}: offset=${c.offset} length=${c.length}`);
3256
+ const a = await Hr(n, i, {
3257
+ coalesce: r?.coalesce,
3258
+ maxRangeSize: r?.maxRangeSize,
3259
+ signal: r?.signal
3260
+ }), l = e.value(m.Compression) ?? P.None;
3261
+ for (let c = 0; c < a.length; c++) {
3262
+ const u = s[c], h = a[c], p = l === P.Jpeg ? e.getJpegHeader(h) : h;
3263
+ o[u] = { bytes: p, compression: l };
3264
+ }
3265
+ return o;
3266
+ }
3267
+ async function Ct(e, t, n, r) {
3268
+ if (t.length === 0)
3269
+ return [];
3270
+ const { size: o, tileSize: i } = e;
3271
+ if (i == null)
3272
+ throw new Error("Tiff is not tiled");
3273
+ const s = Math.ceil(o.height / i.height), a = Math.ceil(o.width / i.width), l = a * s, c = t.map(([h, p]) => {
3274
+ if (h >= a || p >= s)
3275
+ throw new Error(`Tile index is outside of range x:${h} >= ${a} or y:${p} >= ${s}`);
3276
+ const d = p * a + h;
3277
+ if (d >= l)
3278
+ throw new Error(`Tile index is outside of tile range: ${d} >= ${l}`);
3279
+ return d;
3280
+ }), u = await Promise.all(c.map((h) => e.getTileSize(h)));
3281
+ return Lt(e, u.map((h) => ({ offset: h.offset, byteCount: h.imageSize })), n, r);
3282
+ }
3283
+ function eo(e, t, n, r) {
3284
+ const { width: o, height: i } = e.image.getTileBounds(t, n);
3285
+ if (o === e.tileWidth && i === e.tileHeight)
3286
+ return r;
3287
+ const s = r.mask ? ue(r.mask, e.tileWidth, o, i, 1) : r.mask;
3288
+ if (r.layout === "pixel-interleaved") {
3289
+ const { count: c, data: u } = r, h = ue(u, e.tileWidth, o, i, c);
3290
+ return {
3291
+ ...r,
3292
+ width: o,
3293
+ height: i,
3294
+ data: h,
3295
+ mask: s
3296
+ };
3297
+ }
3298
+ const { bands: a } = r, l = a.map((c) => ue(c, e.tileWidth, o, i, 1));
3299
+ return {
3300
+ ...r,
3301
+ width: o,
3302
+ height: i,
3303
+ bands: l,
3304
+ mask: s
3305
+ };
3306
+ }
3307
+ function ue(e, t, n, r, o) {
3308
+ const i = t * o, s = n * o, a = new e.constructor(s * r);
3309
+ for (let l = 0; l < r; l++)
3310
+ a.set(e.subarray(l * i, l * i + s), l * s);
3311
+ return a;
3312
+ }
3313
+ function jt(e, t) {
3314
+ const n = new Set(e), r = new Set(t);
3315
+ if (n.size > 1)
3316
+ throw new Error("Multiple sample formats are not supported.");
3317
+ if (r.size > 1)
3318
+ throw new Error("Multiple bits per sample values are not supported.");
3319
+ const o = e[0], i = t[0];
3320
+ if (o === void 0 || i === void 0)
3321
+ throw new Error("SampleFormat and BitsPerSample arrays cannot be empty.");
3322
+ return {
3323
+ sampleFormat: o,
3324
+ bitsPerSample: i
3325
+ };
3326
+ }
3327
+ function to(e, { count: t }) {
3328
+ if (e == null)
3329
+ return null;
3330
+ const o = new DOMParser().parseFromString(e, "text/xml").documentElement;
3331
+ if (o.tagName !== "GDALMetadata")
3332
+ throw new Error("Not a GDALMetadata XML block");
3333
+ const i = /* @__PURE__ */ new Map(), s = Array(t).fill(0), a = Array(t).fill(1), l = (c) => {
3334
+ const u = parseInt(c, 10) + 1;
3335
+ return i.has(u) || i.set(u, {
3336
+ max: null,
3337
+ min: null,
3338
+ mean: null,
3339
+ std: null,
3340
+ validPercent: null
3341
+ }), i.get(u);
3342
+ };
3343
+ for (const c of Array.from(o.querySelectorAll("Item"))) {
3344
+ const u = c.getAttribute("name"), h = c.getAttribute("sample"), p = c.textContent ?? "";
3345
+ if (h !== null)
3346
+ switch (u) {
3347
+ case "STATISTICS_MAXIMUM":
3348
+ l(h).max = parseFloat(p);
3349
+ break;
3350
+ case "STATISTICS_MEAN":
3351
+ l(h).mean = parseFloat(p);
3352
+ break;
3353
+ case "STATISTICS_MINIMUM":
3354
+ l(h).min = parseFloat(p);
3355
+ break;
3356
+ case "STATISTICS_STDDEV":
3357
+ l(h).std = parseFloat(p);
3358
+ break;
3359
+ case "STATISTICS_VALID_PERCENT":
3360
+ l(h).validPercent = parseFloat(p);
3361
+ break;
3362
+ case "OFFSET":
3363
+ s[parseInt(h, 10)] = parseFloat(p);
3364
+ break;
3365
+ case "SCALE":
3366
+ a[parseInt(h, 10)] = parseFloat(p);
3367
+ break;
3368
+ }
3369
+ }
3370
+ return { bandStatistics: i, offsets: s, scales: a };
3371
+ }
3372
+ async function no(e, t = {}) {
3373
+ const { signal: n } = t, r = e.value(m.Compression);
3374
+ if (r === null)
3375
+ throw new Error("Compression tag should always exist.");
3376
+ const [o, i, s, a, l, c, u, h, p, d, g, f, y] = await Promise.all([
3377
+ e.fetch(m.BitsPerSample, { signal: n }),
3378
+ e.fetch(m.ColorMap, { signal: n }),
3379
+ e.fetch(m.GdalNoData, { signal: n }),
3380
+ e.fetch(m.GdalMetadata, { signal: n }),
3381
+ e.fetch(m.LercParameters, { signal: n }),
3382
+ e.fetch(m.ModelPixelScale, { signal: n }),
3383
+ e.fetch(m.ModelTiePoint, { signal: n }),
3384
+ e.fetch(m.ModelTransformation, { signal: n }),
3385
+ e.fetch(m.Photometric, { signal: n }),
3386
+ e.fetch(m.PlanarConfiguration, { signal: n }),
3387
+ e.fetch(m.Predictor, { signal: n }),
3388
+ e.fetch(m.SampleFormat, { signal: n }),
3389
+ e.fetch(m.SamplesPerPixel, { signal: n })
3390
+ ]), j = (b) => {
3391
+ throw new Error(`${b} tag should always exist.`);
3392
+ };
3393
+ return o === null && j("BitsPerSample"), y === null && j("SamplesPerPixel"), p === null && j("Photometric"), {
3394
+ bitsPerSample: new Uint16Array(o),
3395
+ colorMap: i ? new Uint16Array(i) : void 0,
3396
+ compression: r,
3397
+ gdalMetadata: a,
3398
+ lercParameters: l,
3399
+ modelTiepoint: u,
3400
+ modelPixelScale: c,
3401
+ modelTransformation: h,
3402
+ nodata: s !== null ? Number(s) : null,
3403
+ photometric: p,
3404
+ // PlanarConfiguration defaults to interleaved/chunky/contig
3405
+ // https://web.archive.org/web/20240329145253/https://www.awaresystems.be/imaging/tiff/tifftags/planarconfiguration.html
3406
+ planarConfiguration: d ?? U.Contig,
3407
+ predictor: g ?? V.None,
3408
+ // Uint is the default sample format according to the spec
3409
+ // https://web.archive.org/web/20240329145340/https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html
3410
+ sampleFormat: f ?? [F.Uint],
3411
+ samplesPerPixel: y
3412
+ };
3413
+ }
3414
+ function ro(e) {
3415
+ const t = (n) => e.valueGeo(n) ?? null;
3416
+ return {
3417
+ // Configuration keys
3418
+ modelType: t(w.GTModelTypeGeoKey),
3419
+ rasterType: t(w.GTRasterTypeGeoKey),
3420
+ citation: t(w.GTCitationGeoKey),
3421
+ // Geographic CRS keys
3422
+ geodeticCRS: t(w.GeodeticCRSGeoKey),
3423
+ geodeticCitation: t(w.GeodeticCitationGeoKey),
3424
+ geodeticDatum: t(w.GeodeticDatumGeoKey),
3425
+ primeMeridian: t(w.PrimeMeridianGeoKey),
3426
+ linearUnits: t(w.GeogLinearUnitsGeoKey),
3427
+ linearUnitSize: t(w.GeogLinearUnitSizeGeoKey),
3428
+ angularUnits: t(w.GeogAngularUnitsGeoKey),
3429
+ angularUnitSize: t(w.GeogAngularUnitSizeGeoKey),
3430
+ ellipsoid: t(w.EllipsoidGeoKey),
3431
+ ellipsoidSemiMajorAxis: t(w.EllipsoidSemiMajorAxisGeoKey),
3432
+ ellipsoidSemiMinorAxis: t(w.EllipsoidSemiMinorAxisGeoKey),
3433
+ ellipsoidInvFlattening: t(w.EllipsoidInvFlatteningGeoKey),
3434
+ azimuthUnits: t(w.GeogAzimuthUnitsGeoKey),
3435
+ primeMeridianLongitude: t(w.PrimeMeridianLongitudeGeoKey),
3436
+ toWGS84: t(w.GeogTOWGS84GeoKey),
3437
+ // Projected CRS keys
3438
+ projectedCRS: t(w.ProjectedCRSGeoKey),
3439
+ projectedCitation: t(w.ProjectedCitationGeoKey),
3440
+ projection: t(w.ProjectionGeoKey),
3441
+ projMethod: t(w.ProjMethodGeoKey),
3442
+ projLinearUnits: t(w.ProjLinearUnitsGeoKey),
3443
+ projLinearUnitSize: t(w.ProjLinearUnitSizeGeoKey),
3444
+ projStdParallel1: t(w.ProjStdParallel1GeoKey),
3445
+ projStdParallel2: t(w.ProjStdParallel2GeoKey),
3446
+ projNatOriginLong: t(w.ProjNatOriginLongGeoKey),
3447
+ projNatOriginLat: t(w.ProjNatOriginLatGeoKey),
3448
+ projFalseEasting: t(w.ProjFalseEastingGeoKey),
3449
+ projFalseNorthing: t(w.ProjFalseNorthingGeoKey),
3450
+ projFalseOriginLong: t(w.ProjFalseOriginLongGeoKey),
3451
+ projFalseOriginLat: t(w.ProjFalseOriginLatGeoKey),
3452
+ projFalseOriginEasting: t(w.ProjFalseOriginEastingGeoKey),
3453
+ projFalseOriginNorthing: t(w.ProjFalseOriginNorthingGeoKey),
3454
+ projCenterLong: t(w.ProjCenterLongGeoKey),
3455
+ projCenterLat: t(w.ProjCenterLatGeoKey),
3456
+ projCenterEasting: t(w.ProjCenterEastingGeoKey),
3457
+ projCenterNorthing: t(w.ProjCenterNorthingGeoKey),
3458
+ projScaleAtNatOrigin: t(w.ProjScaleAtNatOriginGeoKey),
3459
+ projScaleAtCenter: t(w.ProjScaleAtCenterGeoKey),
3460
+ projAzimuthAngle: t(w.ProjAzimuthAngleGeoKey),
3461
+ projStraightVertPoleLong: t(w.ProjStraightVertPoleLongGeoKey),
3462
+ projRectifiedGridAngle: t(w.ProjRectifiedGridAngleGeoKey),
3463
+ // Vertical CRS keys
3464
+ verticalCRS: t(w.VerticalGeoKey),
3465
+ verticalCitation: t(w.VerticalCitationGeoKey),
3466
+ verticalDatum: t(w.VerticalDatumGeoKey),
3467
+ verticalUnits: t(w.VerticalUnitsGeoKey)
3468
+ };
3469
+ }
3470
+ function oo({ modelTiepoint: e, modelPixelScale: t, modelTransformation: n, rasterType: r }) {
3471
+ let o;
3472
+ if (e && t)
3473
+ o = io(e, t);
3474
+ else if (n)
3475
+ o = so(n);
3476
+ else
3477
+ throw new Error("The image does not have an affine transformation.");
3478
+ return r === we.PixelIsPoint && (o = ae(o, Le(-0.5, -0.5))), o;
3479
+ }
3480
+ function io(e, t) {
3481
+ const n = e[3], r = e[4], o = t[0], i = -t[1];
3482
+ return [o, 0, n, 0, i, r];
3483
+ }
3484
+ function so(e) {
3485
+ const t = e[3], n = e[7], r = e[1], o = e[4], i = e[0], s = e[5];
3486
+ return [i, r, t, o, s, n];
3487
+ }
3488
+ function xt(e, t, n, r = Math.floor) {
3489
+ const o = de(e.transform), [i, s] = A(o, t, n);
3490
+ return [r(s), r(i)];
3491
+ }
3492
+ function Ot(e, t, n, r = "center") {
3493
+ let o, i;
3494
+ switch (r) {
3495
+ case "center":
3496
+ o = n + 0.5, i = t + 0.5;
3497
+ break;
3498
+ case "ul":
3499
+ o = n, i = t;
3500
+ break;
3501
+ case "ur":
3502
+ o = n + 1, i = t;
3503
+ break;
3504
+ case "ll":
3505
+ o = n, i = t + 1;
3506
+ break;
3507
+ case "lr":
3508
+ o = n + 1, i = t + 1;
3509
+ break;
3510
+ }
3511
+ return A(e.transform, o, i);
3512
+ }
3513
+ class ao {
3514
+ cachedTags;
3515
+ /** The data source used for fetching tile data. */
3516
+ dataSource;
3517
+ /** A reference to the parent GeoTIFF object. */
3518
+ geotiff;
3519
+ /** The GeoKeyDirectory of the primary IFD. */
3520
+ gkd;
3521
+ /** The data IFD for this resolution level. */
3522
+ image;
3523
+ /** The IFD for the mask associated with this overview level, if any. */
3524
+ maskImage = null;
3525
+ constructor(t, n, r, o, i, s) {
3526
+ this.geotiff = t, this.gkd = n, this.image = r, this.maskImage = o, this.cachedTags = i, this.dataSource = s;
3527
+ }
3528
+ /**
3529
+ * The CRS parsed from the GeoKeyDirectory.
3530
+ *
3531
+ * Returns an EPSG code (number) for EPSG-coded CRSes, or a PROJJSON object
3532
+ * for user-defined CRSes. The result is cached after the first access.
3533
+ *
3534
+ * See also {@link GeoTIFF.epsg} for the EPSG code directly from the TIFF tags.
3535
+ */
3536
+ get crs() {
3537
+ return this.geotiff.crs;
3538
+ }
3539
+ /** Image height in pixels. */
3540
+ get height() {
3541
+ return this.image.size.height;
3542
+ }
3543
+ /** The no data value, or null if not set. */
3544
+ get nodata() {
3545
+ return this.geotiff.nodata;
3546
+ }
3547
+ /** Inherits the {@link GeoTIFF._debug} flag from the parent. */
3548
+ get _debug() {
3549
+ return this.geotiff._debug;
3550
+ }
3551
+ /** The number of tiles in the x and y directions */
3552
+ get tileCount() {
3553
+ return this.image.tileCount;
3554
+ }
3555
+ /** Tile height in pixels. */
3556
+ get tileHeight() {
3557
+ return this.image.tileSize.height;
3558
+ }
3559
+ /** Tile width in pixels. */
3560
+ get tileWidth() {
3561
+ return this.image.tileSize.width;
3562
+ }
3563
+ /**
3564
+ * Return the dataset's georeferencing transformation matrix.
3565
+ */
3566
+ get transform() {
3567
+ const t = this.geotiff.transform, n = this.geotiff.width / this.width, r = this.geotiff.height / this.height;
3568
+ return ae(t, tn(n, r));
3569
+ }
3570
+ /** Image width in pixels. */
3571
+ get width() {
3572
+ return this.image.size.width;
3573
+ }
3574
+ /** Fetch a single tile from the full-resolution image.
3575
+ *
3576
+ * @param x The tile column index (0-based).
3577
+ * @param y The tile row index (0-based).
3578
+ * @param options Optional parameters for fetching the tile.
3579
+ * @param options.boundless Whether to clip tiles that are partially outside the image bounds. When `true`, no clipping is applied and edge tiles are returned at the full nominal tile size. Defaults to `true`.
3580
+ * @param options.pool An optional {@link DecoderPool} for decoding the tile data. If not provided, a new decoder will be created for each tile.
3581
+ * @param options.signal An optional {@link AbortSignal} to cancel the fetch request.
3582
+ */
3583
+ async fetchTile(t, n, r = {}) {
3584
+ return await yt(this, t, n, r);
3585
+ }
3586
+ /**
3587
+ * Fetch multiple tiles in parallel.
3588
+ *
3589
+ * A future implementation may coalesce contiguous byte ranges to reduce
3590
+ * the number of HTTP requests.
3591
+ *
3592
+ * @param xy - Array of `[x, y]` tile coordinates.
3593
+ * @param options - Optional parameters (same as {@link fetchTile}).
3594
+ * @returns Array of {@link Tile} objects in the same order as `xy`.
3595
+ *
3596
+ * @see {@link fetchTile} for single-tile fetching.
3597
+ */
3598
+ async fetchTiles(t, n = {}) {
3599
+ return await Pt(this, t, n);
3600
+ }
3601
+ // TiledMixin
3602
+ // Transform mixin
3603
+ /**
3604
+ * Get the (row, col) pixel index containing the geographic coordinate (x, y).
3605
+ *
3606
+ * @param x x coordinate in the CRS.
3607
+ * @param y y coordinate in the CRS.
3608
+ * @param op Rounding function applied to fractional pixel indices.
3609
+ * Defaults to Math.floor.
3610
+ * @returns [row, col] pixel indices.
3611
+ */
3612
+ index(t, n, r = Math.floor) {
3613
+ return xt(this, t, n, r);
3614
+ }
3615
+ /**
3616
+ * Get the geographic (x, y) coordinate of the pixel at (row, col).
3617
+ *
3618
+ * @param row Pixel row.
3619
+ * @param col Pixel column.
3620
+ * @param offset Which part of the pixel to return. Defaults to "center".
3621
+ * @returns [x, y] in the CRS.
3622
+ */
3623
+ xy(t, n, r = "center") {
3624
+ return Ot(this, t, n, r);
3625
+ }
3626
+ }
3627
+ class _ {
3628
+ /**
3629
+ * Reduced-resolution overview levels, sorted finest-to-coarsest.
3630
+ *
3631
+ * Does not include the full-resolution image — use {@link fetchTile} on the
3632
+ * GeoTIFF instance itself for that.
3633
+ */
3634
+ overviews;
3635
+ /** A cached CRS value. */
3636
+ _crs;
3637
+ /** Cached TIFF tags that are pre-fetched when opening the GeoTIFF. */
3638
+ cachedTags;
3639
+ /** The data source used for fetching tile data.
3640
+ *
3641
+ * This is typically the raw source (e.g. HTTP or memory) rather than a
3642
+ * layered source with caching and chunking, to avoid unnecessary copying of
3643
+ * tile data through cache layers.
3644
+ */
3645
+ dataSource;
3646
+ /** The underlying Tiff instance. */
3647
+ tiff;
3648
+ /** The primary (full-resolution) TiffImage. */
3649
+ image;
3650
+ /** The mask IFD of the full-resolution GeoTIFF, if any. */
3651
+ maskImage;
3652
+ /** The GeoKeyDirectory of the primary IFD. */
3653
+ gkd;
3654
+ /** Parsed GDALMetadata tag, if present. */
3655
+ gdalMetadata;
3656
+ /**
3657
+ * Internal: when true, log each `dataSource` fetch (image tile data and
3658
+ * mask tile data) to the console with offset/length and a `data`/`mask`
3659
+ * label. Enable via the `debug` option on {@link GeoTIFF.open} or
3660
+ * {@link GeoTIFF.fromUrl}. Read by the tile-fetch path; not part of the
3661
+ * public API surface.
3662
+ *
3663
+ * @internal
3664
+ */
3665
+ _debug;
3666
+ constructor(t, n, r, o, i, s, a, l, c) {
3667
+ this.tiff = t, this.image = n, this.maskImage = r, this.gkd = o, this.overviews = i, this.cachedTags = s, this.dataSource = a, this.gdalMetadata = l, this._debug = c;
3668
+ }
3669
+ /**
3670
+ * Open a GeoTIFF from a @cogeotiff/core Source.
3671
+ *
3672
+ * This creates and initialises the underlying Tiff, then classifies IFDs.
3673
+ *
3674
+ * @param options.dataSource A source for fetching tile data. This is separate from the source used to construct the TIFF to allow for separate caching implementations.
3675
+ * @param options.headerSource The source used to construct the TIFF. This is typically a layered source with caching and chunking, to optimise access to TIFF tags and IFDs. Callers who want to control the initial read size should compose a `SourceChunk` of the desired block size; cogeotiff's default `defaultReadSize` (16 KiB) gets padded up by the chunking layer anyway.
3676
+ * @param options.signal An optional {@link AbortSignal} to cancel the header reads.
3677
+ * @param options.debug When true, the returned GeoTIFF logs each tile/mask data fetch to the console. Off by default.
3678
+ */
3679
+ static async open(t) {
3680
+ const { dataSource: n, headerSource: r, signal: o, debug: i } = t, s = await new Z(r).init({ signal: o });
3681
+ return s.options = void 0, _.fromTiff(s, n, { signal: o, debug: i });
3682
+ }
3683
+ /**
3684
+ * Create a GeoTIFF from an already-initialised Tiff instance.
3685
+ *
3686
+ * All IFDs are walked; mask IFDs are matched to data IFDs by matching
3687
+ * (width, height). Overviews are sorted from finest to coarsest resolution.
3688
+ *
3689
+ * @param dataSource A source for fetching tile data. This is separate from the source used to construct the TIFF to allow for separate caching implementations.
3690
+ * @param options.signal An optional {@link AbortSignal} to cancel header tag reads.
3691
+ * @param options.debug When true, the returned GeoTIFF logs each tile/mask data fetch to the console.
3692
+ */
3693
+ static async fromTiff(t, n, r = {}) {
3694
+ const { signal: o, debug: i = !1 } = r, s = t.images;
3695
+ if (s.length === 0)
3696
+ throw new Error("TIFF does not contain any IFDs");
3697
+ await Promise.all(s.map((b) => b.init(!0, { signal: o })));
3698
+ const a = s[0], l = ro(a), c = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
3699
+ for (let b = 1; b < s.length; b++) {
3700
+ const S = s[b], v = S.size, L = `${v.width},${v.height}`;
3701
+ lo(S) ? u.set(L, S) : c.set(L, S);
3702
+ }
3703
+ const h = `${a.size.width},${a.size.height}`, p = u.get(h) ?? null, d = Array.from(c.entries());
3704
+ d.sort((b, S) => {
3705
+ const v = b[1].size, L = S[1].size;
3706
+ return L.width * L.height - v.width * v.height;
3707
+ });
3708
+ const g = await no(a, { signal: o }), f = to(g.gdalMetadata, {
3709
+ count: g.samplesPerPixel
3710
+ }), y = new _(t, a, p, l, [], g, n, f, i), j = d.map(([b, S]) => {
3711
+ const v = u.get(b) ?? null;
3712
+ return new ao(y, l, S, v, g, n);
3713
+ });
3714
+ return y.overviews = j, y;
3715
+ }
3716
+ /**
3717
+ * Create a GeoTIFF from an ArrayBuffer containing the entire file.
3718
+ *
3719
+ * This is a convenience method that wraps the ArrayBuffer in a memory source
3720
+ * and calls {@link GeoTIFF.open}. For large files, consider using
3721
+ * {@link GeoTIFF.fromUrl} or {@link GeoTIFF.open} with a chunked HTTP source
3722
+ * to avoid loading the entire file into memory at once.
3723
+ *
3724
+ * @param input The ArrayBuffer containing the GeoTIFF file data.
3725
+ * @returns A Promise that resolves to a GeoTIFF instance.
3726
+ */
3727
+ static async fromArrayBuffer(t) {
3728
+ const n = new xe("memory://input.tif", t);
3729
+ return await _.open({
3730
+ dataSource: n,
3731
+ headerSource: n
3732
+ });
3733
+ }
3734
+ /**
3735
+ * Create a new GeoTIFF from a URL.
3736
+ *
3737
+ * Wraps the HTTP source with a fixed-size block-aligned LRU cache tuned for
3738
+ * TIFF metadata. cogeotiff's lazy per-entry reads (for tile offsets, byte
3739
+ * counts, and other tag values) are served by the block cache; adjacent
3740
+ * entries within a single block hit one underlying request. Tile data reads
3741
+ * bypass the cache and go straight to the raw HTTP source.
3742
+ *
3743
+ * @param url The URL of the GeoTIFF to open.
3744
+ * @param options Optional parameters.
3745
+ * @param options.chunkSize Bytes per chunk for the header cache. Defaults to 64 KiB (matches geotiff.js's BlockedSource).
3746
+ * @param options.cacheSize Total cache size in bytes. Defaults to 8 MiB (~128 blocks at the default chunk size).
3747
+ * @param options.signal An optional {@link AbortSignal} to cancel the header reads.
3748
+ * @param options.debug When true, the returned GeoTIFF logs each tile/mask data fetch to the console with offset/length and a `data`/`mask` label. Off by default.
3749
+ * @returns A Promise that resolves to a GeoTIFF instance.
3750
+ */
3751
+ static async fromUrl(t, { chunkSize: n = 64 * 1024, cacheSize: r = 8 * 1024 * 1024, signal: o, debug: i } = {}) {
3752
+ const s = new Y(t, {});
3753
+ s.metadata = { size: Number.POSITIVE_INFINITY };
3754
+ const a = new er(s, [
3755
+ new nr({ size: n }),
3756
+ new $n({ size: r })
3757
+ ]);
3758
+ return await _.open({
3759
+ // Tile data reads bypass the header cache (raw source).
3760
+ dataSource: s,
3761
+ headerSource: a,
3762
+ signal: o,
3763
+ debug: i
3764
+ });
3765
+ }
3766
+ // ── Properties from the primary image ─────────────────────────────────
3767
+ /**
3768
+ * The CRS parsed from the GeoKeyDirectory.
3769
+ *
3770
+ * Returns an EPSG code (number) for EPSG-coded CRSes, or a PROJJSON object
3771
+ * for user-defined CRSes. The result is cached after the first access.
3772
+ *
3773
+ * See also {@link GeoTIFF.epsg} for the EPSG code directly from the TIFF tags.
3774
+ */
3775
+ get crs() {
3776
+ return this._crs === void 0 && (this._crs = Fr(this.gkd)), this._crs;
3777
+ }
3778
+ /** Image width in pixels. */
3779
+ get width() {
3780
+ return this.image.size.width;
3781
+ }
3782
+ /** Image height in pixels. */
3783
+ get height() {
3784
+ return this.image.size.height;
3785
+ }
3786
+ /** The number of tiles in the x and y directions */
3787
+ get tileCount() {
3788
+ return this.image.tileCount;
3789
+ }
3790
+ /** Tile width in pixels. */
3791
+ get tileWidth() {
3792
+ return this.image.tileSize.width;
3793
+ }
3794
+ /** Tile height in pixels. */
3795
+ get tileHeight() {
3796
+ return this.image.tileSize.height;
3797
+ }
3798
+ /** The no data value, or null if not set. */
3799
+ get nodata() {
3800
+ return this.image.noData;
3801
+ }
3802
+ /** Whether the primary image is tiled. */
3803
+ get isTiled() {
3804
+ return this.image.isTiled();
3805
+ }
3806
+ /**
3807
+ * The pre-existing statistics for each band, if available.
3808
+ *
3809
+ * Extracted from the GDALMetadata TIFF tag; never computed on demand.
3810
+ * Keys are **1-based** band indices to match GDAL's convention.
3811
+ *
3812
+ * Returns `null` if no statistics are stored in the file.
3813
+ */
3814
+ get storedStats() {
3815
+ const t = this.gdalMetadata?.bandStatistics;
3816
+ return t && t.size > 0 ? t : null;
3817
+ }
3818
+ /**
3819
+ * The offset for each band (0-indexed), defaulting to 0.
3820
+ *
3821
+ * Extracted from the GDALMetadata TIFF tag.
3822
+ */
3823
+ get offsets() {
3824
+ return this.gdalMetadata?.offsets ?? Array(this.count).fill(0);
3825
+ }
3826
+ /**
3827
+ * The scale for each band (0-indexed), defaulting to 1.
3828
+ *
3829
+ * Extracted from the GDALMetadata TIFF tag.
3830
+ */
3831
+ get scales() {
3832
+ return this.gdalMetadata?.scales ?? Array(this.count).fill(1);
3833
+ }
3834
+ /** Number of bands (samples per pixel). */
3835
+ get count() {
3836
+ return this.image.value(m.SamplesPerPixel) ?? 1;
3837
+ }
3838
+ /** Bounding box [minX, minY, maxX, maxY] in the CRS. */
3839
+ get bbox() {
3840
+ return this.image.bbox;
3841
+ }
3842
+ /**
3843
+ * Return the dataset's georeferencing transformation matrix.
3844
+ */
3845
+ get transform() {
3846
+ const { modelPixelScale: t, modelTiepoint: n, modelTransformation: r } = this.cachedTags;
3847
+ return oo({
3848
+ modelTiepoint: n,
3849
+ modelPixelScale: t,
3850
+ modelTransformation: r,
3851
+ rasterType: this.gkd.rasterType
3852
+ });
3853
+ }
3854
+ // Mixins
3855
+ /** Fetch a single tile from the full-resolution image.
3856
+ *
3857
+ * @param x The tile column index (0-based).
3858
+ * @param y The tile row index (0-based).
3859
+ * @param options Optional parameters for fetching the tile.
3860
+ * @param options.boundless Whether to clip tiles that are partially outside the image bounds. When `true`, no clipping is applied and edge tiles are returned at the full nominal tile size. Defaults to `true`.
3861
+ * @param options.pool An optional {@link DecoderPool} for decoding the tile data. If not provided, a new decoder will be created for each tile.
3862
+ * @param options.signal An optional {@link AbortSignal} to cancel the fetch request.
3863
+ */
3864
+ async fetchTile(t, n, r = {}) {
3865
+ return await yt(this, t, n, r);
3866
+ }
3867
+ /**
3868
+ * Fetch multiple tiles in parallel.
3869
+ *
3870
+ * A future implementation may coalesce contiguous byte ranges to reduce
3871
+ * the number of HTTP requests.
3872
+ *
3873
+ * @param xy - Array of `[x, y]` tile coordinates.
3874
+ * @param options - Optional parameters (same as {@link fetchTile}).
3875
+ * @returns Array of {@link Tile} objects in the same order as `xy`.
3876
+ *
3877
+ * @see {@link fetchTile} for single-tile fetching.
3878
+ */
3879
+ async fetchTiles(t, n = {}) {
3880
+ return await Pt(this, t, n);
3881
+ }
3882
+ // Transform mixin
3883
+ /**
3884
+ * Get the (row, col) pixel index containing the geographic coordinate (x, y).
3885
+ *
3886
+ * @param x x coordinate in the CRS.
3887
+ * @param y y coordinate in the CRS.
3888
+ * @param op Rounding function applied to fractional pixel indices.
3889
+ * Defaults to Math.floor.
3890
+ * @returns [row, col] pixel indices.
3891
+ */
3892
+ index(t, n, r = Math.floor) {
3893
+ return xt(this, t, n, r);
3894
+ }
3895
+ /**
3896
+ * Get the geographic (x, y) coordinate of the pixel at (row, col).
3897
+ *
3898
+ * @param row Pixel row.
3899
+ * @param col Pixel column.
3900
+ * @param offset Which part of the pixel to return. Defaults to "center".
3901
+ * @returns [x, y] in the CRS.
3902
+ */
3903
+ xy(t, n, r = "center") {
3904
+ return Ot(this, t, n, r);
3905
+ }
3906
+ }
3907
+ function lo(e) {
3908
+ const t = e.value(m.SubFileType), n = e.value(m.Photometric);
3909
+ return t !== null && (t & $.Mask) !== 0 && n === R.Mask;
3910
+ }
3911
+ class co {
3912
+ worker;
3913
+ jobIdCounter = 0;
3914
+ jobs = /* @__PURE__ */ new Map();
3915
+ constructor(t) {
3916
+ this.worker = t, this.worker.addEventListener("message", (n) => this.onMessage(n));
3917
+ }
3918
+ get jobCount() {
3919
+ return this.jobs.size;
3920
+ }
3921
+ onMessage(t) {
3922
+ const { jobId: n, error: r, pixels: o } = t.data, i = this.jobs.get(n);
3923
+ this.jobs.delete(n), i && (r ? i.reject(new Error(r)) : i.resolve(o));
3924
+ }
3925
+ submitJob(t, n) {
3926
+ const r = this.jobIdCounter++;
3927
+ return new Promise((o, i) => {
3928
+ this.jobs.set(r, { resolve: o, reject: i }), this.worker.postMessage({ ...t, jobId: r }, { transfer: n });
3929
+ });
3930
+ }
3931
+ terminate() {
3932
+ this.worker.terminate();
3933
+ }
3934
+ }
3935
+ const uo = typeof navigator < "u" ? navigator.hardwareConcurrency ?? 2 : 2;
3936
+ class ho {
3937
+ workerWrappers;
3938
+ constructor(t = {}) {
3939
+ const { size: n = uo, createWorker: r } = t;
3940
+ if (this.workerWrappers = [], r && n > 0)
3941
+ for (let o = 0; o < n; o++)
3942
+ this.workerWrappers.push(new co(r()));
3943
+ }
3944
+ /** True when workers are available for off-main-thread decoding. */
3945
+ get hasWorkers() {
3946
+ return this.workerWrappers.length > 0;
3947
+ }
3948
+ /**
3949
+ * Decode a compressed tile buffer.
3950
+ *
3951
+ * When workers are available, the compressed `bytes` buffer is transferred
3952
+ * zero-copy to the least-loaded worker. The returned `DecodedPixels` typed
3953
+ * array buffers are transferred back to the main thread.
3954
+ *
3955
+ * When no workers are available, decoding runs on the main thread via the
3956
+ * normal `decode()` path.
3957
+ */
3958
+ async decode(t, n, r) {
3959
+ if (!this.hasWorkers)
3960
+ return je(t, n, r);
3961
+ const o = this.leastLoaded(), i = {
3962
+ compression: n,
3963
+ metadata: r,
3964
+ buffer: t
3965
+ };
3966
+ return await o.submitJob(i, [t]);
3967
+ }
3968
+ /** Terminate all workers and release resources. */
3969
+ destroy() {
3970
+ for (const t of this.workerWrappers)
3971
+ t.terminate();
3972
+ this.workerWrappers.length = 0;
3973
+ }
3974
+ leastLoaded() {
3975
+ let t = this.workerWrappers[0];
3976
+ for (let n = 1; n < this.workerWrappers.length; n++)
3977
+ this.workerWrappers[n].jobCount < t.jobCount && (t = this.workerWrappers[n]);
3978
+ return t;
3979
+ }
3980
+ }
3981
+ let oe = null;
3982
+ function po() {
3983
+ return oe !== null || (oe = new ho({
3984
+ createWorker: () => new Worker(new URL(
3985
+ /* @vite-ignore */
3986
+ "/assets/worker-DtIrTJB7.js",
3987
+ import.meta.url
3988
+ ), { type: "module" })
3989
+ })), oe;
3990
+ }
3991
+ function mo(e) {
3992
+ const { height: t, width: n } = e;
3993
+ if (e.layout === "band-separate")
3994
+ throw new Error("Band-separate images not yet implemented.");
3995
+ if (e.data.length === t * n * 4)
3996
+ return e;
3997
+ if (e.data.length === t * n * 3) {
3998
+ const r = e.data.length / 3 * 4, o = e.data instanceof Uint16Array, i = o ? new Uint16Array(r) : new Uint8ClampedArray(r), s = o ? 65535 : 255;
3999
+ for (let a = 0; a < e.data.length / 3; ++a)
4000
+ i[a * 4] = e.data[a * 3], i[a * 4 + 1] = e.data[a * 3 + 1], i[a * 4 + 2] = e.data[a * 3 + 2], i[a * 4 + 3] = s;
4001
+ return {
4002
+ ...e,
4003
+ count: 4,
4004
+ data: i
4005
+ };
4006
+ } else
4007
+ throw new Error(`Unexpected number of channels in raster data: ${e.data.length / (t * n)}`);
4008
+ }
4009
+ async function go(e) {
4010
+ return typeof e == "string" || e instanceof URL ? await _.fromUrl(e) : e instanceof ArrayBuffer ? await _.fromArrayBuffer(e) : e;
4011
+ }
4012
+ function fo(e, t) {
4013
+ const [n, r, o, i] = e.bbox, s = [
4014
+ t.forward([n, r]),
4015
+ // bottom-left
4016
+ t.forward([o, r]),
4017
+ // bottom-right
4018
+ t.forward([o, i]),
4019
+ // top-right
4020
+ t.forward([n, i])
4021
+ // top-left
4022
+ ], a = s.map((d) => d[0]), l = s.map((d) => d[1]), c = Math.min(...a), u = Math.min(...l), h = Math.max(...a), p = Math.max(...l);
4023
+ return { west: c, south: u, east: h, north: p };
4024
+ }
4025
+ const yo = (
4026
+ /* glsl */
4027
+ `
4028
+ vec3 black_zero_to_rgb(float value) {
4029
+ return vec3(value, value, value);
4030
+ }
4031
+ `
4032
+ ), wo = {
4033
+ name: "black-is-zero",
4034
+ inject: {
4035
+ "fs:#decl": yo,
4036
+ "fs:DECKGL_FILTER_COLOR": (
4037
+ /* glsl */
4038
+ `
4039
+ color.rgb = black_zero_to_rgb(color.r);
4040
+ `
4041
+ )
4042
+ }
4043
+ }, Po = (
4044
+ /* glsl */
4045
+ `
4046
+ const vec3 D65 = vec3(
4047
+ 0.95047, // Xn
4048
+ 1.00000, // Yn
4049
+ 1.08883 // Zn
4050
+ );
4051
+
4052
+ vec3 cielabToRgb(vec3 labTex) {
4053
+ // labTex in [0,1] from RGB8 texture
4054
+ float L = labTex.r * 255.0;
4055
+ float a = (labTex.g - 0.5) * 255.0;
4056
+ float b = (labTex.b - 0.5) * 255.0;
4057
+
4058
+ float y = (L + 16.0) / 116.0;
4059
+ float x = (a / 500.0) + y;
4060
+ float z = y - (b / 200.0);
4061
+
4062
+ vec3 xyz;
4063
+ vec3 v = vec3(x, y, z);
4064
+ vec3 v3 = v * v * v;
4065
+
4066
+ xyz = D65 * mix(
4067
+ (v - 16.0 / 116.0) / 7.787,
4068
+ v3,
4069
+ step(0.008856, v3)
4070
+ );
4071
+
4072
+ vec3 rgb = mat3(
4073
+ 3.2406, -1.5372, -0.4986,
4074
+ -0.9689, 1.8758, 0.0415,
4075
+ 0.0557, -0.2040, 1.0570
4076
+ ) * xyz;
4077
+
4078
+ // sRGB gamma
4079
+ rgb = mix(
4080
+ 12.92 * rgb,
4081
+ 1.055 * pow(rgb, vec3(1.0 / 2.4)) - 0.055,
4082
+ step(0.0031308, rgb)
4083
+ );
4084
+
4085
+ return clamp(rgb, 0.0, 1.0);
4086
+ }
4087
+ `
4088
+ ), bo = {
4089
+ name: "cielab-to-rgb",
4090
+ inject: {
4091
+ "fs:#decl": Po,
4092
+ "fs:DECKGL_FILTER_COLOR": (
4093
+ /* glsl */
4094
+ `
4095
+ color.rgb = cielabToRgb(color);
4096
+ `
4097
+ )
4098
+ }
4099
+ }, vo = (
4100
+ /* glsl */
4101
+ `
4102
+ vec3 cmykToRgb(vec4 cmyk) {
4103
+ // cmyk in [0.0, 1.0]
4104
+ float invK = 1.0 - cmyk.a;
4105
+
4106
+ return vec3(
4107
+ (1.0 - cmyk.r) * invK,
4108
+ (1.0 - cmyk.g) * invK,
4109
+ (1.0 - cmyk.b) * invK
4110
+ );
4111
+ }
4112
+ `
4113
+ ), So = {
4114
+ name: "cmyk-to-rgb",
4115
+ inject: {
4116
+ "fs:#decl": vo,
4117
+ "fs:DECKGL_FILTER_COLOR": (
4118
+ /* glsl */
4119
+ `
4120
+ color.rgb = cmykToRgb(color);
4121
+ `
4122
+ )
4123
+ }
4124
+ }, Lo = (
4125
+ /* glsl */
4126
+ `
4127
+ vec3 white_zero_to_rgb(float value) {
4128
+ return vec3(1.0 - value, 1.0 - value, 1.0 - value);
4129
+ }
4130
+ `
4131
+ ), Co = {
4132
+ name: "white-is-zero",
4133
+ inject: {
4134
+ "fs:#decl": Lo,
4135
+ "fs:DECKGL_FILTER_COLOR": (
4136
+ /* glsl */
4137
+ `
4138
+ color.rgb = white_zero_to_rgb(color.r);
4139
+ `
4140
+ )
4141
+ }
4142
+ }, T = "colormap", At = {
4143
+ name: T,
4144
+ fs: `uniform ${T}Uniforms {
4145
+ int colormapIndex;
4146
+ float reversed;
4147
+ } ${T};
4148
+ `,
4149
+ inject: {
4150
+ "fs:#decl": `precision highp sampler2DArray;
4151
+ uniform sampler2DArray colormapTexture;
4152
+ `,
4153
+ "fs:DECKGL_FILTER_COLOR": (
4154
+ /* glsl */
4155
+ `
4156
+ float idx = mix(color.r, 1.0 - color.r, ${T}.reversed);
4157
+ color = texture(
4158
+ colormapTexture,
4159
+ vec3(idx, 0.5, float(${T}.colormapIndex))
4160
+ );
4161
+ `
4162
+ )
4163
+ },
4164
+ uniformTypes: {
4165
+ colormapIndex: "i32",
4166
+ reversed: "f32"
4167
+ },
4168
+ getUniforms: (e) => ({
4169
+ colormapTexture: e.colormapTexture,
4170
+ colormapIndex: e.colormapIndex ?? 0,
4171
+ reversed: e.reversed ?? !1
4172
+ })
4173
+ }, he = {
4174
+ accent: 0,
4175
+ afmhot: 1,
4176
+ algae: 2,
4177
+ amp: 3,
4178
+ autumn: 4,
4179
+ balance: 5,
4180
+ binary: 6,
4181
+ blues: 7,
4182
+ bone: 8,
4183
+ brbg: 9,
4184
+ brg: 10,
4185
+ bugn: 11,
4186
+ bupu: 12,
4187
+ bwr: 13,
4188
+ cfastie: 14,
4189
+ cividis: 15,
4190
+ cmrmap: 16,
4191
+ cool: 17,
4192
+ coolwarm: 18,
4193
+ copper: 19,
4194
+ cubehelix: 20,
4195
+ curl: 21,
4196
+ dark2: 22,
4197
+ deep: 23,
4198
+ delta: 24,
4199
+ dense: 25,
4200
+ diff: 26,
4201
+ flag: 27,
4202
+ gist_earth: 28,
4203
+ gist_gray: 29,
4204
+ gist_heat: 30,
4205
+ gist_ncar: 31,
4206
+ gist_rainbow: 32,
4207
+ gist_stern: 33,
4208
+ gist_yarg: 34,
4209
+ gnbu: 35,
4210
+ gnuplot: 36,
4211
+ gnuplot2: 37,
4212
+ gray: 38,
4213
+ greens: 39,
4214
+ greys: 40,
4215
+ haline: 41,
4216
+ hot: 42,
4217
+ hsv: 43,
4218
+ ice: 44,
4219
+ inferno: 45,
4220
+ jet: 46,
4221
+ magma: 47,
4222
+ matter: 48,
4223
+ nipy_spectral: 49,
4224
+ ocean: 50,
4225
+ oranges: 51,
4226
+ orrd: 52,
4227
+ oxy: 53,
4228
+ paired: 54,
4229
+ pastel1: 55,
4230
+ pastel2: 56,
4231
+ phase: 57,
4232
+ pink: 58,
4233
+ piyg: 59,
4234
+ plasma: 60,
4235
+ prgn: 61,
4236
+ prism: 62,
4237
+ pubu: 63,
4238
+ pubugn: 64,
4239
+ puor: 65,
4240
+ purd: 66,
4241
+ purples: 67,
4242
+ rain: 68,
4243
+ rainbow: 69,
4244
+ rdbu: 70,
4245
+ rdgy: 71,
4246
+ rdpu: 72,
4247
+ rdylbu: 73,
4248
+ rdylgn: 74,
4249
+ reds: 75,
4250
+ rplumbo: 76,
4251
+ schwarzwald: 77,
4252
+ seismic: 78,
4253
+ set1: 79,
4254
+ set2: 80,
4255
+ set3: 81,
4256
+ solar: 82,
4257
+ spectral: 83,
4258
+ speed: 84,
4259
+ spring: 85,
4260
+ summer: 86,
4261
+ tab10: 87,
4262
+ tab20: 88,
4263
+ tab20b: 89,
4264
+ tab20c: 90,
4265
+ tarn: 91,
4266
+ tempo: 92,
4267
+ terrain: 93,
4268
+ thermal: 94,
4269
+ topo: 95,
4270
+ turbid: 96,
4271
+ turbo: 97,
4272
+ twilight: 98,
4273
+ twilight_shifted: 99,
4274
+ viridis: 100,
4275
+ winter: 101,
4276
+ wistia: 102,
4277
+ ylgn: 103,
4278
+ ylgnbu: 104,
4279
+ ylorbr: 105,
4280
+ ylorrd: 106
4281
+ };
4282
+ function jo(e, t) {
4283
+ if (t.width !== 256)
4284
+ throw new Error(`Expected a 256-pixel-wide colormap sprite, got width ${t.width}.`);
4285
+ const n = new Uint8Array(t.data.buffer, t.data.byteOffset, t.data.byteLength);
4286
+ return e.createTexture({
4287
+ dimension: "2d-array",
4288
+ format: "rgba8unorm",
4289
+ width: 256,
4290
+ height: 1,
4291
+ depth: t.height,
4292
+ data: n,
4293
+ mipLevels: 1,
4294
+ sampler: {
4295
+ minFilter: "linear",
4296
+ magFilter: "linear",
4297
+ // Clamp in every axis so an out-of-range colormapIndex yields an
4298
+ // edge color rather than wrapping to an unrelated colormap.
4299
+ addressModeU: "clamp-to-edge",
4300
+ addressModeV: "clamp-to-edge",
4301
+ addressModeW: "clamp-to-edge"
4302
+ }
4303
+ });
4304
+ }
4305
+ async function xo(e) {
4306
+ const t = await Oo(e);
4307
+ try {
4308
+ return Ao(t);
4309
+ } finally {
4310
+ t.close();
4311
+ }
4312
+ }
4313
+ async function Oo(e) {
4314
+ if (e instanceof ImageBitmap)
4315
+ return e;
4316
+ const t = new Blob([e]);
4317
+ return createImageBitmap(t);
4318
+ }
4319
+ function Ao(e) {
4320
+ const n = new OffscreenCanvas(e.width, e.height).getContext("2d");
4321
+ if (!n)
4322
+ throw new Error("Failed to obtain 2D context for decoding the colormap sprite.");
4323
+ return n.drawImage(e, 0, 0), n.getImageData(0, 0, e.width, e.height);
4324
+ }
4325
+ const ve = "nodata", Eo = `uniform ${ve}Uniforms {
4326
+ float value;
4327
+ } ${ve};
4328
+ `, Et = {
4329
+ name: ve,
4330
+ fs: Eo,
4331
+ inject: {
4332
+ "fs:DECKGL_FILTER_COLOR": (
4333
+ /* glsl */
4334
+ `
4335
+ if (color.r == nodata.value) {
4336
+ discard;
4337
+ }
4338
+ `
4339
+ )
4340
+ },
4341
+ uniformTypes: {
4342
+ value: "f32"
4343
+ },
4344
+ getUniforms: (e) => ({
4345
+ value: e.value
4346
+ })
4347
+ }, H = "linearRescale", Io = {
4348
+ name: H,
4349
+ fs: `uniform ${H}Uniforms {
4350
+ float rescaleMin;
4351
+ float rescaleMax;
4352
+ } ${H};
4353
+ `,
4354
+ inject: {
4355
+ "fs:DECKGL_FILTER_COLOR": (
4356
+ /* glsl */
4357
+ `
4358
+ color.rgb = clamp((color.rgb - ${H}.rescaleMin) / (${H}.rescaleMax - ${H}.rescaleMin), 0.0, 1.0);
4359
+ `
4360
+ )
4361
+ },
4362
+ uniformTypes: {
4363
+ rescaleMin: "f32",
4364
+ rescaleMax: "f32"
4365
+ },
4366
+ getUniforms: (e) => ({
4367
+ rescaleMin: e.rescaleMin ?? 0,
4368
+ rescaleMax: e.rescaleMax ?? 1
4369
+ })
4370
+ }, Mo = {
4371
+ name: "mask-texture",
4372
+ inject: {
4373
+ "fs:#decl": "uniform sampler2D maskTexture;",
4374
+ "fs:DECKGL_FILTER_COLOR": (
4375
+ /* glsl */
4376
+ `
4377
+ float maskValue = texture(maskTexture, geometry.uv).r;
4378
+ if (maskValue == 0.0) {
4379
+ discard;
4380
+ }
4381
+ `
4382
+ )
4383
+ },
4384
+ getUniforms: (e) => ({
4385
+ maskTexture: e.maskTexture
4386
+ })
4387
+ };
4388
+ function Ro(e, t, n) {
4389
+ const r = zo(e), o = Fo(t), i = Do(n), s = `${r}:${i}:${o}`, a = No[s];
4390
+ if (!a)
4391
+ throw new Error(`Unsupported texture format for SamplesPerPixel=${e}, BitsPerSample=${t}, SampleFormat=${n}`);
4392
+ return a;
4393
+ }
4394
+ function zo(e) {
4395
+ if (e === 1 || e === 2 || e === 3 || e === 4)
4396
+ return e;
4397
+ throw new Error(`Unsupported SamplesPerPixel ${e}. Only 1, 2, 3, or 4 are supported.`);
4398
+ }
4399
+ function Fo(e) {
4400
+ const t = e[0];
4401
+ for (let n = 1; n < e.length; n++)
4402
+ if (e[n] !== t)
4403
+ throw new Error(`Unsupported varying BitsPerSample ${e}. All samples must have the same bit width.`);
4404
+ if (t !== 8 && t !== 16 && t !== 32)
4405
+ throw new Error(`Unsupported BitsPerSample ${t}. Only 8, 16, or 32 are supported.`);
4406
+ return t;
4407
+ }
4408
+ function Do(e) {
4409
+ const t = e[0];
4410
+ for (let n = 1; n < e.length; n++)
4411
+ if (e[n] !== t)
4412
+ throw new Error(`Unsupported varying SampleFormat ${e}. All samples must have the same format.`);
4413
+ switch (t) {
4414
+ case F.Uint:
4415
+ return "unorm";
4416
+ case F.Int:
4417
+ return "sint";
4418
+ case F.Float:
4419
+ return "float";
4420
+ default:
4421
+ throw new Error(`Unsupported SampleFormat ${e}`);
4422
+ }
4423
+ }
4424
+ const No = {
4425
+ // 1 byte per pixel
4426
+ "1:sint:8": "r8sint",
4427
+ "1:uint:8": "r8uint",
4428
+ "1:unorm:8": "r8unorm",
4429
+ // 2 bytes per pixel (one channel)
4430
+ "1:float:16": "r16float",
4431
+ "1:sint:16": "r16sint",
4432
+ "1:uint:16": "r16uint",
4433
+ "1:unorm:16": "r16unorm",
4434
+ // 2 bytes per pixel (two channels)
4435
+ "2:sint:8": "rg8sint",
4436
+ "2:uint:8": "rg8uint",
4437
+ "2:unorm:8": "rg8unorm",
4438
+ // 4 bytes per pixel (one channel)
4439
+ "1:float:32": "r32float",
4440
+ "1:sint:32": "r32sint",
4441
+ "1:uint:32": "r32uint",
4442
+ // 4 bytes per pixel (two channels)
4443
+ "2:float:16": "rg16float",
4444
+ "2:sint:16": "rg16sint",
4445
+ "2:uint:16": "rg16uint",
4446
+ "2:unorm:16": "rg16unorm",
4447
+ // 4 bytes per pixel (four channels)
4448
+ "4:sint:8": "rgba8sint",
4449
+ "4:uint:8": "rgba8uint",
4450
+ "4:unorm:8": "rgba8unorm",
4451
+ // 6 bytes per pixel (three channels)
4452
+ // Note: this is supported on WebGL2 but not supported on WebGPU
4453
+ // I expect actual switch to WebGPU to be quite a ways off still
4454
+ "3:uint:16": "rgb16unorm-webgl",
4455
+ // 8 bytes per pixel (two channels)
4456
+ "2:float:32": "rg32float",
4457
+ "2:sint:32": "rg32sint",
4458
+ "2:uint:32": "rg32uint",
4459
+ // 8 bytes per pixel (four channels)
4460
+ "4:float:16": "rgba16float",
4461
+ "4:sint:16": "rgba16sint",
4462
+ "4:uint:16": "rgba16uint",
4463
+ "4:unorm:16": "rgba16unorm",
4464
+ // 12 bytes per pixel (three channels)
4465
+ "3:float:32": "rgb32float-webgl",
4466
+ // 16 bytes per pixel (four channels)
4467
+ "4:float:32": "rgba32float",
4468
+ "4:sint:32": "rgba32sint",
4469
+ "4:uint:32": "rgba32uint"
4470
+ };
4471
+ function Uo(e, t) {
4472
+ const { sampleFormat: n } = e.cachedTags;
4473
+ if (n === null)
4474
+ throw new Error("SampleFormat tag is required to infer render pipeline");
4475
+ switch (n[0]) {
4476
+ // Unsigned integers
4477
+ case F.Uint:
4478
+ return Bo(e, t);
4479
+ }
4480
+ throw new Error(`Inferring render pipeline for non-unsigned integers not yet supported. Found SampleFormat: ${n}`);
4481
+ }
4482
+ function Bo(e, t) {
4483
+ const { bitsPerSample: n, colorMap: r, photometric: o, sampleFormat: i, samplesPerPixel: s, nodata: a } = e.cachedTags, l = [
4484
+ {
4485
+ module: Se,
4486
+ props: {
4487
+ textureName: (d) => d.texture
4488
+ }
4489
+ }
4490
+ ];
4491
+ if (a !== null) {
4492
+ const d = 2 ** n[0] - 1, g = a / d;
4493
+ l.push({
4494
+ module: Et,
4495
+ props: { value: g }
4496
+ });
4497
+ }
4498
+ e.maskImage !== null && l.push({
4499
+ module: Mo,
4500
+ props: {
4501
+ // TODO: how to handle if mask failed to load and is undefined here
4502
+ maskTexture: (d) => d.mask
4503
+ }
4504
+ });
4505
+ const c = Go({
4506
+ count: s,
4507
+ photometric: o,
4508
+ device: t,
4509
+ colorMap: r
4510
+ });
4511
+ c && l.push(c);
4512
+ const u = o === R.Palette ? {
4513
+ magFilter: "nearest",
4514
+ minFilter: "nearest"
4515
+ } : {
4516
+ magFilter: "linear",
4517
+ minFilter: "linear"
4518
+ };
4519
+ return { getTileData: async (d, g) => {
4520
+ const { device: f, x: y, y: j, signal: b, pool: S } = g, v = await d.fetchTile(y, j, {
4521
+ boundless: !1,
4522
+ pool: S,
4523
+ signal: b
4524
+ });
4525
+ let { array: L } = v;
4526
+ const { width: E, height: M, mask: z } = L;
4527
+ let I = s;
4528
+ if (s === 3 && (L = mo(L), I = 4), L.layout === "band-separate")
4529
+ throw new Error("Band-separate images not yet implemented.");
4530
+ const J = Ro(
4531
+ // Add one sample for added alpha channel
4532
+ I,
4533
+ n,
4534
+ i
4535
+ );
4536
+ let q = L.data.byteLength;
4537
+ const te = f.createTexture({
4538
+ data: L.data,
4539
+ format: J,
4540
+ width: E,
4541
+ height: M,
4542
+ sampler: u
4543
+ });
4544
+ let ne;
4545
+ return z !== null && (ne = f.createTexture({
4546
+ data: z,
4547
+ // Single-channel 8-bit texture for the mask
4548
+ format: "r8unorm",
4549
+ width: E,
4550
+ height: M,
4551
+ // Use nearest filtering for the mask to avoid interpolated edges/halos
4552
+ sampler: {
4553
+ minFilter: "nearest",
4554
+ magFilter: "nearest"
4555
+ }
4556
+ }), q += z.byteLength), {
4557
+ texture: te,
4558
+ mask: ne,
4559
+ byteLength: q,
4560
+ height: L.height,
4561
+ width: L.width
4562
+ };
4563
+ }, renderTile: (d) => ({
4564
+ renderPipeline: l.map((g, f) => Ko(g, d))
4565
+ }) };
4566
+ }
4567
+ function Go({ count: e, colorMap: t, device: n, photometric: r }) {
4568
+ if (e === 3 || e === 4)
4569
+ return null;
4570
+ switch (r) {
4571
+ case R.MinIsWhite:
4572
+ return {
4573
+ module: Co
4574
+ };
4575
+ case R.MinIsBlack:
4576
+ return {
4577
+ module: wo
4578
+ };
4579
+ case R.Rgb:
4580
+ return null;
4581
+ case R.Palette: {
4582
+ if (!t)
4583
+ throw new Error("ColorMap is required for PhotometricInterpretation Palette");
4584
+ const { data: o, width: i, height: s } = En(t), a = n.createTexture({
4585
+ dimension: "2d-array",
4586
+ data: o,
4587
+ format: "rgba8unorm",
4588
+ width: i,
4589
+ height: s,
4590
+ depth: 1,
4591
+ mipLevels: 1,
4592
+ sampler: {
4593
+ minFilter: "nearest",
4594
+ magFilter: "nearest",
4595
+ addressModeU: "clamp-to-edge",
4596
+ addressModeV: "clamp-to-edge",
4597
+ addressModeW: "clamp-to-edge"
4598
+ }
4599
+ });
4600
+ return {
4601
+ module: At,
4602
+ props: {
4603
+ colormapTexture: a
4604
+ }
4605
+ };
4606
+ }
4607
+ // Not sure why cogeotiff calls this "Separated", but it means CMYK
4608
+ case R.Separated:
4609
+ return {
4610
+ module: So
4611
+ };
4612
+ case R.Ycbcr:
4613
+ return null;
4614
+ case R.Cielab:
4615
+ return {
4616
+ module: bo
4617
+ };
4618
+ default:
4619
+ throw new Error(`Unsupported PhotometricInterpretation ${r}`);
4620
+ }
4621
+ }
4622
+ function Ko(e, t) {
4623
+ const { module: n, props: r } = e;
4624
+ if (!r)
4625
+ return { module: n };
4626
+ const o = {};
4627
+ for (const [i, s] of Object.entries(r)) {
4628
+ const a = typeof s == "function" ? s(t) : s;
4629
+ a !== void 0 && (o[i] = a);
4630
+ }
4631
+ return { module: n, props: o };
4632
+ }
4633
+ function _o(e, t) {
4634
+ const r = [
4635
+ ...[...e.overviews].reverse(),
4636
+ e
4637
+ ].map((o) => new on({
4638
+ affine: o.transform,
4639
+ arrayWidth: o.width,
4640
+ arrayHeight: o.height,
4641
+ tileWidth: o.tileWidth,
4642
+ tileHeight: o.tileHeight,
4643
+ mpu: t.mpu
4644
+ }));
4645
+ return new en({
4646
+ levels: r,
4647
+ projectTo3857: t.projectTo3857,
4648
+ projectFrom3857: t.projectFrom3857,
4649
+ projectTo4326: t.projectTo4326,
4650
+ projectFrom4326: t.projectFrom4326
4651
+ });
4652
+ }
4653
+ class Xo extends Be {
4654
+ static layerName = "COGLayer";
4655
+ // COGLayer's getTileData signature differs from the base class's, so
4656
+ // `DefaultProps<COGLayerProps>` is not assignable to
4657
+ // `DefaultProps<RasterTileLayerProps>`. Cast to the base static-side type
4658
+ // to keep inheritance happy. The only COG-specific default is
4659
+ // `epsgResolver`; all behavior still flows from the base class.
4660
+ static defaultProps = {
4661
+ ...Be.defaultProps,
4662
+ epsgResolver: an
4663
+ };
4664
+ initializeState() {
4665
+ this.setState({});
4666
+ }
4667
+ updateState(t) {
4668
+ super.updateState(t);
4669
+ const { props: n, oldProps: r, changeFlags: o } = t;
4670
+ (!!o.dataChanged || n.geotiff !== r.geotiff) && (this.clearState(), this._parseGeoTIFF());
4671
+ }
4672
+ clearState() {
4673
+ this.setState({
4674
+ geotiff: void 0,
4675
+ tilesetDescriptor: void 0,
4676
+ defaultGetTileData: void 0,
4677
+ defaultRenderTile: void 0
4678
+ });
4679
+ }
4680
+ async _parseGeoTIFF() {
4681
+ const t = await go(this.props.geotiff), n = t.crs, r = typeof n == "number" ? await this.props.epsgResolver(n) : ot(n), o = Ae(r, "EPSG:4326"), i = (f, y) => o.forward([f, y], !1), s = (f, y) => o.inverse([f, y], !1), a = Ae(r, "EPSG:3857"), l = un((f, y) => a.forward([f, y], !1), i), c = (f, y) => a.inverse([f, y], !1), u = r.units;
4682
+ if (!u)
4683
+ throw new Error("Source projection is missing 'units' property, cannot compute meters per unit");
4684
+ const h = sn(u, {
4685
+ semiMajorAxis: r.datum?.a ?? r.a
4686
+ }), p = _o(t, {
4687
+ projectTo4326: i,
4688
+ projectFrom4326: s,
4689
+ projectTo3857: l,
4690
+ projectFrom3857: c,
4691
+ mpu: h
4692
+ });
4693
+ if (this.props.onGeoTIFFLoad) {
4694
+ const f = fo(t, o);
4695
+ this.props.onGeoTIFFLoad(t, {
4696
+ projection: r,
4697
+ geographicBounds: f
4698
+ });
4699
+ }
4700
+ let d, g;
4701
+ (!this.props.getTileData || !this.props.renderTile) && ({ getTileData: d, renderTile: g } = Uo(t, this.context.device)), this.setState({
4702
+ geotiff: t,
4703
+ tilesetDescriptor: p,
4704
+ defaultGetTileData: d,
4705
+ defaultRenderTile: g
4706
+ });
4707
+ }
4708
+ _tilesetDescriptor() {
4709
+ return this.state.tilesetDescriptor;
4710
+ }
4711
+ /**
4712
+ * Adapts the user-facing `(image, { x, y, ... }) => Promise<DataT>` signature
4713
+ * into RasterTileLayer's `(tile, { signal, device }) => Promise<DataT>`.
4714
+ */
4715
+ _getTileDataCallback() {
4716
+ const t = this.state.geotiff;
4717
+ if (!t)
4718
+ return;
4719
+ const n = this.props.getTileData ?? this.state.defaultGetTileData;
4720
+ return n ? async (o, i) => {
4721
+ const { x: s, y: a, z: l } = o.index, c = l === t.overviews.length ? t : t.overviews[t.overviews.length - 1 - l];
4722
+ return n(c, {
4723
+ device: i.device,
4724
+ x: s,
4725
+ y: a,
4726
+ signal: i.signal,
4727
+ pool: this.props.pool ?? po()
4728
+ });
4729
+ } : void 0;
4730
+ }
4731
+ _renderTileCallback() {
4732
+ const t = this.props.renderTile ?? this.state.defaultRenderTile;
4733
+ if (t)
4734
+ return t;
4735
+ }
4736
+ }
4737
+ const Wo = "data:image/png;base64,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", $e = /* @__PURE__ */ new WeakMap();
4738
+ function Ho(e) {
4739
+ const t = $e.get(e);
4740
+ if (t) return t;
4741
+ const n = (async () => {
4742
+ const r = await (await fetch(Wo)).arrayBuffer();
4743
+ return jo(e, await xo(r));
4744
+ })();
4745
+ return $e.set(e, n), n;
4746
+ }
4747
+ const et = /* @__PURE__ */ new Set();
4748
+ function ko(e) {
4749
+ return e in he ? he[e] : (et.has(e) || (et.add(e), console.warn(`[onlymapjs] COGLayer: unknown colormap "${e}" — falling back to gray.`)), he.gray);
4750
+ }
4751
+ function Zo(e) {
4752
+ const t = e.layout === "band-separate" ? e.bands[0] : e.data;
4753
+ return t instanceof Float32Array ? t : new Float32Array(t);
4754
+ }
4755
+ function Vo(e) {
4756
+ const t = e.width * e.height, n = new Float32Array(t * 4);
4757
+ if (e.layout === "band-separate") {
4758
+ const [r, o, i] = [e.bands[0], e.bands[1], e.bands[2]];
4759
+ for (let s = 0; s < t; s++)
4760
+ n[s * 4] = r[s], n[s * 4 + 1] = o[s], n[s * 4 + 2] = i[s], n[s * 4 + 3] = 1;
4761
+ } else {
4762
+ const { data: r, count: o } = e;
4763
+ for (let i = 0; i < t; i++)
4764
+ n[i * 4] = r[i * o], n[i * 4 + 1] = r[i * o + 1], n[i * 4 + 2] = r[i * o + 2], n[i * 4 + 3] = 1;
4765
+ }
4766
+ return n;
4767
+ }
4768
+ const Yo = async (e, { device: t, x: n, y: r, signal: o, pool: i }) => {
4769
+ const s = () => {
4770
+ throw o?.reason ?? new DOMException("aborted", "AbortError");
4771
+ };
4772
+ o?.aborted && s();
4773
+ const a = await e.fetchTile(n, r, { boundless: !1, pool: i, signal: o });
4774
+ o?.aborted && s();
4775
+ const l = a.array, c = e.cachedTags.samplesPerPixel, u = { minFilter: "nearest", magFilter: "nearest" }, h = c === 1, p = h ? Zo(l) : Vo(l), d = t.createTexture({
4776
+ data: p,
4777
+ format: h ? "r32float" : "rgba32float",
4778
+ width: l.width,
4779
+ height: l.height,
4780
+ sampler: u
4781
+ });
4782
+ return {
4783
+ width: l.width,
4784
+ height: l.height,
4785
+ byteLength: p.byteLength,
4786
+ texture: d,
4787
+ colormapTexture: await Ho(t),
4788
+ bandCount: c,
4789
+ nodata: l.nodata
4790
+ };
4791
+ };
4792
+ function Jo(e, t) {
4793
+ const n = [
4794
+ // Per-tile textureName (not the layer-level `image:` shorthand — that
4795
+ // binds only the first tile's sampler in this setup).
4796
+ { module: Se, props: { textureName: e.texture } }
4797
+ ], r = t.nodataOverride ?? e.nodata;
4798
+ return r != null && Number.isFinite(r) && n.push({ module: Et, props: { value: r } }), n.push({
4799
+ module: Io,
4800
+ props: { rescaleMin: t.rescaleMin ?? 0, rescaleMax: t.rescaleMax ?? 255 }
4801
+ }), e.bandCount === 1 && n.push({
4802
+ module: At,
4803
+ props: { colormapTexture: e.colormapTexture, colormapIndex: ko(t.colormap ?? "gray") }
4804
+ }), { renderPipeline: n };
4805
+ }
4806
+ class qo extends Xo {
4807
+ static layerName = "OmCOGLayer";
4808
+ // Plain nulls (not `{type:"number", value:null}` specs): deck's typed
4809
+ // number props reject null defaults with a console warning per instance.
4810
+ static defaultProps = {
4811
+ rescaleMin: null,
4812
+ rescaleMax: null,
4813
+ colormap: null,
4814
+ nodataOverride: null
4815
+ };
4816
+ constructor(t) {
4817
+ const n = t;
4818
+ if (!(n.rescaleMin != null || n.rescaleMax != null || n.colormap != null && n.colormap !== "" || n.nodataOverride != null)) {
4819
+ super(t);
4820
+ return;
4821
+ }
4822
+ super(t, {
4823
+ getTileData: Yo,
4824
+ renderTile: (o) => o ? Jo(o, n) : null,
4825
+ // Free the per-tile texture on cache eviction; the sprite texture is
4826
+ // device-scoped (WeakMap above) and must NOT be destroyed here.
4827
+ onTileUnload: (o) => {
4828
+ const i = o.data;
4829
+ i && typeof i == "object" && "texture" in i && i.texture.destroy();
4830
+ }
4831
+ });
4832
+ }
4833
+ }
4834
+ const ei = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4835
+ __proto__: null,
4836
+ OmCOGLayer: qo
4837
+ }, Symbol.toStringTag, { value: "Module" }));
4838
+ export {
4839
+ P as C,
4840
+ D,
4841
+ ei as r
4842
+ };