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