@developmentseed/deck.gl-raster 0.1.0-beta.2 → 0.1.0-beta.4

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 (42) hide show
  1. package/dist/index.cjs +0 -725
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +1 -141
  4. package/dist/index.d.ts +5 -142
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +2 -722
  7. package/dist/index.js.map +1 -1
  8. package/dist/layer.d.ts +72 -0
  9. package/dist/layer.d.ts.map +1 -0
  10. package/dist/layer.js +88 -0
  11. package/dist/layer.js.map +1 -0
  12. package/dist/mesh.d.ts +1 -0
  13. package/dist/mesh.d.ts.map +1 -0
  14. package/dist/mesh.js +2 -0
  15. package/dist/mesh.js.map +1 -0
  16. package/dist/raster-debug-layer.d.ts +51 -0
  17. package/dist/raster-debug-layer.d.ts.map +1 -0
  18. package/dist/raster-debug-layer.js +102 -0
  19. package/dist/raster-debug-layer.js.map +1 -0
  20. package/dist/raster-layer.d.ts +63 -0
  21. package/dist/raster-layer.d.ts.map +1 -0
  22. package/dist/raster-layer.js +102 -0
  23. package/dist/raster-layer.js.map +1 -0
  24. package/dist/src/index.d.ts +1 -0
  25. package/dist/src/index.d.ts.map +1 -0
  26. package/dist/src/index.js +2 -0
  27. package/dist/src/index.js.map +1 -0
  28. package/dist/src/layer.d.ts +1 -0
  29. package/dist/src/layer.d.ts.map +1 -0
  30. package/dist/src/layer.js +3 -0
  31. package/dist/src/layer.js.map +1 -0
  32. package/dist/src/mesh.d.ts +1 -0
  33. package/dist/src/mesh.d.ts.map +1 -0
  34. package/dist/src/mesh.js +2 -0
  35. package/dist/src/mesh.js.map +1 -0
  36. package/dist/tests/placeholder.test.d.ts +2 -0
  37. package/dist/tests/placeholder.test.d.ts.map +1 -0
  38. package/dist/tests/placeholder.test.js +7 -0
  39. package/dist/tests/placeholder.test.js.map +1 -0
  40. package/dist/tsconfig.tsbuildinfo +1 -0
  41. package/package.json +24 -26
  42. package/README.md +0 -80
package/dist/index.cjs CHANGED
@@ -1,729 +1,4 @@
1
1
  'use strict';
2
2
 
3
- var proj4 = require('proj4');
4
-
5
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
-
7
- var proj4__default = /*#__PURE__*/_interopDefault(proj4);
8
-
9
- var __defProp = Object.defineProperty;
10
- var __export = (target, all) => {
11
- for (var name in all)
12
- __defProp(target, name, { get: all[name], enumerable: true });
13
- };
14
-
15
- // src/reprojection/index.ts
16
- var reprojection_exports = {};
17
- __export(reprojection_exports, {
18
- RasterReprojector: () => RasterReprojector,
19
- affine: () => affine_exports,
20
- extractGeotiffReprojectors: () => extractGeotiffReprojectors,
21
- fromGeoTransform: () => fromGeoTransform
22
- });
23
-
24
- // src/reprojection/delatin.ts
25
- var SAMPLE_POINTS = [
26
- [1 / 3, 1 / 3, 1 / 3],
27
- // centroid
28
- [0.5, 0.5, 0],
29
- // edge 0–1
30
- [0.5, 0, 0.5],
31
- // edge 0–2
32
- [0, 0.5, 0.5]
33
- // edge 1–2
34
- ];
35
- var RasterReprojector = class {
36
- reprojectors;
37
- width;
38
- height;
39
- /**
40
- * UV vertex coordinates (x, y), i.e.
41
- * [x0, y0, x1, y1, ...]
42
- *
43
- * These coordinates are floats that range from [0, 1] in both X and Y.
44
- */
45
- uvs;
46
- /**
47
- * XY Positions in output CRS, computed via exact forward reprojection.
48
- */
49
- exactOutputPositions;
50
- /**
51
- * triangle vertex indices
52
- */
53
- triangles;
54
- _halfedges;
55
- /**
56
- * The UV texture coordinates of candidates found from
57
- * `findReprojectionCandidate`.
58
- *
59
- * Maybe in the future we'll want to store the barycentric coordinates instead
60
- * of just the uv coordinates?
61
- */
62
- _candidatesUV;
63
- _queueIndices;
64
- _queue;
65
- _errors;
66
- _pending;
67
- _pendingLen;
68
- constructor(reprojectors, width, height = width) {
69
- this.reprojectors = reprojectors;
70
- this.width = width;
71
- this.height = height;
72
- this.uvs = [];
73
- this.exactOutputPositions = [];
74
- this.triangles = [];
75
- this._halfedges = [];
76
- this._candidatesUV = [];
77
- this._queueIndices = [];
78
- this._queue = [];
79
- this._errors = [];
80
- this._pending = [];
81
- this._pendingLen = 0;
82
- const u1 = 1;
83
- const v1 = 1;
84
- const p0 = this._addPoint(0, 0);
85
- const p1 = this._addPoint(u1, 0);
86
- const p2 = this._addPoint(0, v1);
87
- const p3 = this._addPoint(u1, v1);
88
- const t0 = this._addTriangle(p3, p0, p2, -1, -1, -1);
89
- this._addTriangle(p0, p3, p1, t0, -1, -1);
90
- this._flush();
91
- }
92
- // refine the mesh until its maximum error gets below the given one
93
- run(maxError = 1) {
94
- while (this.getMaxError() > maxError) {
95
- this.refine();
96
- }
97
- }
98
- // refine the mesh with a single point
99
- refine() {
100
- this._step();
101
- this._flush();
102
- }
103
- // max error of the current mesh
104
- getMaxError() {
105
- return this._errors[0];
106
- }
107
- // rasterize and queue all triangles that got added or updated in _step
108
- _flush() {
109
- for (let i = 0; i < this._pendingLen; i++) {
110
- const t = this._pending[i];
111
- this._findReprojectionCandidate(t);
112
- }
113
- this._pendingLen = 0;
114
- }
115
- // Original, upstream implementation of FindCandidate:
116
- // // rasterize a triangle, find its max error, and queue it for processing
117
- // private _findCandidate(
118
- // p0x: number,
119
- // p0y: number,
120
- // p1x: number,
121
- // p1y: number,
122
- // p2x: number,
123
- // p2y: number,
124
- // t: number,
125
- // ) {
126
- // // triangle bounding box
127
- // const minX = Math.min(p0x, p1x, p2x);
128
- // const minY = Math.min(p0y, p1y, p2y);
129
- // const maxX = Math.max(p0x, p1x, p2x);
130
- // const maxY = Math.max(p0y, p1y, p2y);
131
- // // forward differencing variables
132
- // let w00 = orient(p1x, p1y, p2x, p2y, minX, minY);
133
- // let w01 = orient(p2x, p2y, p0x, p0y, minX, minY);
134
- // let w02 = orient(p0x, p0y, p1x, p1y, minX, minY);
135
- // const a01 = p1y - p0y;
136
- // const b01 = p0x - p1x;
137
- // const a12 = p2y - p1y;
138
- // const b12 = p1x - p2x;
139
- // const a20 = p0y - p2y;
140
- // const b20 = p2x - p0x;
141
- // // pre-multiplied z values at vertices
142
- // const a = orient(p0x, p0y, p1x, p1y, p2x, p2y);
143
- // const z0 = this.heightAt(p0x, p0y) / a;
144
- // const z1 = this.heightAt(p1x, p1y) / a;
145
- // const z2 = this.heightAt(p2x, p2y) / a;
146
- // // iterate over pixels in bounding box
147
- // let maxError = 0;
148
- // let mx = 0;
149
- // let my = 0;
150
- // for (let y = minY; y <= maxY; y++) {
151
- // // compute starting offset
152
- // let dx = 0;
153
- // if (w00 < 0 && a12 !== 0) {
154
- // dx = Math.max(dx, Math.floor(-w00 / a12));
155
- // }
156
- // if (w01 < 0 && a20 !== 0) {
157
- // dx = Math.max(dx, Math.floor(-w01 / a20));
158
- // }
159
- // if (w02 < 0 && a01 !== 0) {
160
- // dx = Math.max(dx, Math.floor(-w02 / a01));
161
- // }
162
- // let w0 = w00 + a12 * dx;
163
- // let w1 = w01 + a20 * dx;
164
- // let w2 = w02 + a01 * dx;
165
- // let wasInside = false;
166
- // for (let x = minX + dx; x <= maxX; x++) {
167
- // // check if inside triangle
168
- // if (w0 >= 0 && w1 >= 0 && w2 >= 0) {
169
- // wasInside = true;
170
- // // compute z using barycentric coordinates
171
- // const z = z0 * w0 + z1 * w1 + z2 * w2;
172
- // const dz = Math.abs(z - this.heightAt(x, y));
173
- // if (dz > maxError) {
174
- // maxError = dz;
175
- // mx = x;
176
- // my = y;
177
- // }
178
- // } else if (wasInside) {
179
- // break;
180
- // }
181
- // w0 += a12;
182
- // w1 += a20;
183
- // w2 += a01;
184
- // }
185
- // w00 += b12;
186
- // w01 += b20;
187
- // w02 += b01;
188
- // }
189
- // if (
190
- // (mx === p0x && my === p0y) ||
191
- // (mx === p1x && my === p1y) ||
192
- // (mx === p2x && my === p2y)
193
- // ) {
194
- // maxError = 0;
195
- // }
196
- // // update triangle metadata
197
- // this._candidatesUV[2 * t] = mx;
198
- // this._candidatesUV[2 * t + 1] = my;
199
- // // add triangle to priority queue
200
- // this._queuePush(t, maxError);
201
- // }
202
- /**
203
- * Conversion of upstream's `_findCandidate` for reprojection error handling.
204
- *
205
- * @param {number} t The index (into `this.triangles`) of the pending triangle to process.
206
- *
207
- * @return {void} Doesn't return; instead modifies internal state.
208
- */
209
- _findReprojectionCandidate(t) {
210
- const a2 = 2 * this.triangles[t * 3 + 0];
211
- const b2 = 2 * this.triangles[t * 3 + 1];
212
- const c = 2 * this.triangles[t * 3 + 2];
213
- const p0u = this.uvs[a2];
214
- const p0v = this.uvs[a2 + 1];
215
- const p1u = this.uvs[b2];
216
- const p1v = this.uvs[b2 + 1];
217
- const p2u = this.uvs[c];
218
- const p2v = this.uvs[c + 1];
219
- const out0x = this.exactOutputPositions[a2];
220
- const out0y = this.exactOutputPositions[a2 + 1];
221
- const out1x = this.exactOutputPositions[b2];
222
- const out1y = this.exactOutputPositions[b2 + 1];
223
- const out2x = this.exactOutputPositions[c];
224
- const out2y = this.exactOutputPositions[c + 1];
225
- let maxError = 0;
226
- let maxErrorU = 0;
227
- let maxErrorV = 0;
228
- for (const samplePoint of SAMPLE_POINTS) {
229
- const uvSampleU = barycentricMix(
230
- p0u,
231
- p1u,
232
- p2u,
233
- samplePoint[0],
234
- samplePoint[1],
235
- samplePoint[2]
236
- );
237
- const uvSampleV = barycentricMix(
238
- p0v,
239
- p1v,
240
- p2v,
241
- samplePoint[0],
242
- samplePoint[1],
243
- samplePoint[2]
244
- );
245
- const outSampleX = barycentricMix(
246
- out0x,
247
- out1x,
248
- out2x,
249
- samplePoint[0],
250
- samplePoint[1],
251
- samplePoint[2]
252
- );
253
- const outSampleY = barycentricMix(
254
- out0y,
255
- out1y,
256
- out2y,
257
- samplePoint[0],
258
- samplePoint[1],
259
- samplePoint[2]
260
- );
261
- const pixelExactX = uvSampleU * (this.width - 1);
262
- const pixelExactY = uvSampleV * (this.height - 1);
263
- const inputCRSSampled = this.reprojectors.inverseReproject(
264
- outSampleX,
265
- outSampleY
266
- );
267
- const pixelSampled = this.reprojectors.inputCRSToPixel(
268
- inputCRSSampled[0],
269
- inputCRSSampled[1]
270
- );
271
- const dx = pixelExactX - pixelSampled[0];
272
- const dy = pixelExactY - pixelSampled[1];
273
- const err = Math.hypot(dx, dy);
274
- if (err > maxError) {
275
- maxError = err;
276
- maxErrorU = uvSampleU;
277
- maxErrorV = uvSampleV;
278
- }
279
- }
280
- if (maxErrorU === p0u && maxErrorV === p0v || maxErrorU === p1u && maxErrorV === p1v || maxErrorU === p2u && maxErrorV === p2v) {
281
- maxError = 0;
282
- }
283
- this._candidatesUV[2 * t] = maxErrorU;
284
- this._candidatesUV[2 * t + 1] = maxErrorV;
285
- this._queuePush(t, maxError);
286
- }
287
- // process the next triangle in the queue, splitting it with a new point
288
- _step() {
289
- const t = this._queuePop();
290
- const e0 = t * 3 + 0;
291
- const e1 = t * 3 + 1;
292
- const e2 = t * 3 + 2;
293
- const p0 = this.triangles[e0];
294
- const p1 = this.triangles[e1];
295
- const p2 = this.triangles[e2];
296
- const au = this.uvs[2 * p0];
297
- const av = this.uvs[2 * p0 + 1];
298
- const bu = this.uvs[2 * p1];
299
- const bv = this.uvs[2 * p1 + 1];
300
- const cu = this.uvs[2 * p2];
301
- const cv = this.uvs[2 * p2 + 1];
302
- const pu = this._candidatesUV[2 * t];
303
- const pv = this._candidatesUV[2 * t + 1];
304
- const pn = this._addPoint(pu, pv);
305
- if (orient(au, av, bu, bv, pu, pv) === 0) {
306
- this._handleCollinear(pn, e0);
307
- } else if (orient(bu, bv, cu, cv, pu, pv) === 0) {
308
- this._handleCollinear(pn, e1);
309
- } else if (orient(cu, cv, au, av, pu, pv) === 0) {
310
- this._handleCollinear(pn, e2);
311
- } else {
312
- const h0 = this._halfedges[e0];
313
- const h1 = this._halfedges[e1];
314
- const h2 = this._halfedges[e2];
315
- const t0 = this._addTriangle(p0, p1, pn, h0, -1, -1, e0);
316
- const t1 = this._addTriangle(p1, p2, pn, h1, -1, t0 + 1);
317
- const t2 = this._addTriangle(p2, p0, pn, h2, t0 + 2, t1 + 1);
318
- this._legalize(t0);
319
- this._legalize(t1);
320
- this._legalize(t2);
321
- }
322
- }
323
- // add coordinates for a new vertex
324
- _addPoint(u, v) {
325
- const i = this.uvs.length >> 1;
326
- this.uvs.push(u, v);
327
- const pixelX = u * (this.width - 1);
328
- const pixelY = v * (this.height - 1);
329
- const inputPosition = this.reprojectors.pixelToInputCRS(pixelX, pixelY);
330
- const exactOutputPosition = this.reprojectors.forwardReproject(
331
- inputPosition[0],
332
- inputPosition[1]
333
- );
334
- this.exactOutputPositions.push(
335
- exactOutputPosition[0],
336
- exactOutputPosition[1]
337
- );
338
- return i;
339
- }
340
- // add or update a triangle in the mesh
341
- _addTriangle(a2, b2, c, ab, bc, ca, e2 = this.triangles.length) {
342
- const t = e2 / 3;
343
- this.triangles[e2 + 0] = a2;
344
- this.triangles[e2 + 1] = b2;
345
- this.triangles[e2 + 2] = c;
346
- this._halfedges[e2 + 0] = ab;
347
- this._halfedges[e2 + 1] = bc;
348
- this._halfedges[e2 + 2] = ca;
349
- if (ab >= 0) {
350
- this._halfedges[ab] = e2 + 0;
351
- }
352
- if (bc >= 0) {
353
- this._halfedges[bc] = e2 + 1;
354
- }
355
- if (ca >= 0) {
356
- this._halfedges[ca] = e2 + 2;
357
- }
358
- this._candidatesUV[2 * t + 0] = 0;
359
- this._candidatesUV[2 * t + 1] = 0;
360
- this._queueIndices[t] = -1;
361
- this._pending[this._pendingLen++] = t;
362
- return e2;
363
- }
364
- _legalize(a2) {
365
- const b2 = this._halfedges[a2];
366
- if (b2 < 0) {
367
- return;
368
- }
369
- const a0 = a2 - a2 % 3;
370
- const b0 = b2 - b2 % 3;
371
- const al = a0 + (a2 + 1) % 3;
372
- const ar = a0 + (a2 + 2) % 3;
373
- const bl = b0 + (b2 + 2) % 3;
374
- const br = b0 + (b2 + 1) % 3;
375
- const p0 = this.triangles[ar];
376
- const pr = this.triangles[a2];
377
- const pl = this.triangles[al];
378
- const p1 = this.triangles[bl];
379
- const uvs = this.uvs;
380
- if (!inCircle(
381
- uvs[2 * p0],
382
- uvs[2 * p0 + 1],
383
- uvs[2 * pr],
384
- uvs[2 * pr + 1],
385
- uvs[2 * pl],
386
- uvs[2 * pl + 1],
387
- uvs[2 * p1],
388
- uvs[2 * p1 + 1]
389
- )) {
390
- return;
391
- }
392
- const hal = this._halfedges[al];
393
- const har = this._halfedges[ar];
394
- const hbl = this._halfedges[bl];
395
- const hbr = this._halfedges[br];
396
- this._queueRemove(a0 / 3);
397
- this._queueRemove(b0 / 3);
398
- const t0 = this._addTriangle(p0, p1, pl, -1, hbl, hal, a0);
399
- const t1 = this._addTriangle(p1, p0, pr, t0, har, hbr, b0);
400
- this._legalize(t0 + 1);
401
- this._legalize(t1 + 2);
402
- }
403
- // handle a case where new vertex is on the edge of a triangle
404
- _handleCollinear(pn, a2) {
405
- const a0 = a2 - a2 % 3;
406
- const al = a0 + (a2 + 1) % 3;
407
- const ar = a0 + (a2 + 2) % 3;
408
- const p0 = this.triangles[ar];
409
- const pr = this.triangles[a2];
410
- const pl = this.triangles[al];
411
- const hal = this._halfedges[al];
412
- const har = this._halfedges[ar];
413
- const b2 = this._halfedges[a2];
414
- if (b2 < 0) {
415
- const t02 = this._addTriangle(pn, p0, pr, -1, har, -1, a0);
416
- const t12 = this._addTriangle(p0, pn, pl, t02, -1, hal);
417
- this._legalize(t02 + 1);
418
- this._legalize(t12 + 2);
419
- return;
420
- }
421
- const b0 = b2 - b2 % 3;
422
- const bl = b0 + (b2 + 2) % 3;
423
- const br = b0 + (b2 + 1) % 3;
424
- const p1 = this.triangles[bl];
425
- const hbl = this._halfedges[bl];
426
- const hbr = this._halfedges[br];
427
- this._queueRemove(b0 / 3);
428
- const t0 = this._addTriangle(p0, pr, pn, har, -1, -1, a0);
429
- const t1 = this._addTriangle(pr, p1, pn, hbr, -1, t0 + 1, b0);
430
- const t2 = this._addTriangle(p1, pl, pn, hbl, -1, t1 + 1);
431
- const t3 = this._addTriangle(pl, p0, pn, hal, t0 + 2, t2 + 1);
432
- this._legalize(t0);
433
- this._legalize(t1);
434
- this._legalize(t2);
435
- this._legalize(t3);
436
- }
437
- // priority queue methods
438
- _queuePush(t, error) {
439
- const i = this._queue.length;
440
- this._queueIndices[t] = i;
441
- this._queue.push(t);
442
- this._errors.push(error);
443
- this._queueUp(i);
444
- }
445
- _queuePop() {
446
- const n = this._queue.length - 1;
447
- this._queueSwap(0, n);
448
- this._queueDown(0, n);
449
- return this._queuePopBack();
450
- }
451
- _queuePopBack() {
452
- const t = this._queue.pop();
453
- this._errors.pop();
454
- this._queueIndices[t] = -1;
455
- return t;
456
- }
457
- _queueRemove(t) {
458
- const i = this._queueIndices[t];
459
- if (i < 0) {
460
- const it = this._pending.indexOf(t);
461
- if (it !== -1) {
462
- this._pending[it] = this._pending[--this._pendingLen];
463
- } else {
464
- throw new Error("Broken triangulation (something went wrong).");
465
- }
466
- return;
467
- }
468
- const n = this._queue.length - 1;
469
- if (n !== i) {
470
- this._queueSwap(i, n);
471
- if (!this._queueDown(i, n)) {
472
- this._queueUp(i);
473
- }
474
- }
475
- this._queuePopBack();
476
- }
477
- _queueLess(i, j) {
478
- return this._errors[i] > this._errors[j];
479
- }
480
- _queueSwap(i, j) {
481
- const pi = this._queue[i];
482
- const pj = this._queue[j];
483
- this._queue[i] = pj;
484
- this._queue[j] = pi;
485
- this._queueIndices[pi] = j;
486
- this._queueIndices[pj] = i;
487
- const e2 = this._errors[i];
488
- this._errors[i] = this._errors[j];
489
- this._errors[j] = e2;
490
- }
491
- _queueUp(j0) {
492
- let j = j0;
493
- while (true) {
494
- const i = j - 1 >> 1;
495
- if (i === j || !this._queueLess(j, i)) {
496
- break;
497
- }
498
- this._queueSwap(i, j);
499
- j = i;
500
- }
501
- }
502
- _queueDown(i0, n) {
503
- let i = i0;
504
- while (true) {
505
- const j1 = 2 * i + 1;
506
- if (j1 >= n || j1 < 0) {
507
- break;
508
- }
509
- const j2 = j1 + 1;
510
- let j = j1;
511
- if (j2 < n && this._queueLess(j2, j1)) {
512
- j = j2;
513
- }
514
- if (!this._queueLess(j, i)) {
515
- break;
516
- }
517
- this._queueSwap(i, j);
518
- i = j;
519
- }
520
- return i > i0;
521
- }
522
- };
523
- function orient(ax, ay, bx, by, cx, cy) {
524
- return (bx - cx) * (ay - cy) - (by - cy) * (ax - cx);
525
- }
526
- function inCircle(ax, ay, bx, by, cx, cy, px, py) {
527
- const dx = ax - px;
528
- const dy = ay - py;
529
- const ex = bx - px;
530
- const ey = by - py;
531
- const fx = cx - px;
532
- const fy = cy - py;
533
- const ap = dx * dx + dy * dy;
534
- const bp = ex * ex + ey * ey;
535
- const cp = fx * fx + fy * fy;
536
- return dx * (ey * cp - bp * fy) - dy * (ex * cp - bp * fx) + ap * (ex * fy - ey * fx) < 0;
537
- }
538
- function barycentricMix(a2, b2, c, t0, t1, t2) {
539
- return t0 * a2 + t1 * b2 + t2 * c;
540
- }
541
-
542
- // src/reprojection/affine.ts
543
- var affine_exports = {};
544
- __export(affine_exports, {
545
- applyAffine: () => applyAffine,
546
- invertGeoTransform: () => invertGeoTransform
547
- });
548
- function invertGeoTransform(gt) {
549
- if (isDegenerate(gt)) {
550
- throw new Error("Cannot invert degenerate transform");
551
- }
552
- const idet = 1 / determinant(gt);
553
- const [sa, sb, sc, sd, se, sf] = gt;
554
- const ra = se * idet;
555
- const rb = -sb * idet;
556
- const rd = -sd * idet;
557
- const re = sa * idet;
558
- return [
559
- ra,
560
- rb,
561
- -sc * ra - sf * rb,
562
- rd,
563
- re,
564
- -sc * rd - sf * re
565
- ];
566
- }
567
- function isDegenerate(gt) {
568
- return determinant(gt) === 0;
569
- }
570
- function determinant(gt) {
571
- return a(gt) * e(gt) - b(gt) * d(gt);
572
- }
573
- function a(gt) {
574
- return gt[0];
575
- }
576
- function b(gt) {
577
- return gt[1];
578
- }
579
- function d(gt) {
580
- return gt[3];
581
- }
582
- function e(gt) {
583
- return gt[4];
584
- }
585
- function applyAffine(x, y, gt) {
586
- const [a2, b2, c, d2, e2, f] = gt;
587
- return [a2 * x + b2 * y + c, d2 * x + e2 * y + f];
588
- }
589
- var OGC_84 = {
590
- $schema: "https://proj.org/schemas/v0.7/projjson.schema.json",
591
- type: "GeographicCRS",
592
- name: "WGS 84 (CRS84)",
593
- datum_ensemble: {
594
- name: "World Geodetic System 1984 ensemble",
595
- members: [
596
- {
597
- name: "World Geodetic System 1984 (Transit)",
598
- id: { authority: "EPSG", code: 1166 }
599
- },
600
- {
601
- name: "World Geodetic System 1984 (G730)",
602
- id: { authority: "EPSG", code: 1152 }
603
- },
604
- {
605
- name: "World Geodetic System 1984 (G873)",
606
- id: { authority: "EPSG", code: 1153 }
607
- },
608
- {
609
- name: "World Geodetic System 1984 (G1150)",
610
- id: { authority: "EPSG", code: 1154 }
611
- },
612
- {
613
- name: "World Geodetic System 1984 (G1674)",
614
- id: { authority: "EPSG", code: 1155 }
615
- },
616
- {
617
- name: "World Geodetic System 1984 (G1762)",
618
- id: { authority: "EPSG", code: 1156 }
619
- },
620
- {
621
- name: "World Geodetic System 1984 (G2139)",
622
- id: { authority: "EPSG", code: 1309 }
623
- }
624
- ],
625
- ellipsoid: {
626
- name: "WGS 84",
627
- semi_major_axis: 6378137,
628
- inverse_flattening: 298.257223563
629
- },
630
- accuracy: "2.0",
631
- id: { authority: "EPSG", code: 6326 }
632
- },
633
- coordinate_system: {
634
- subtype: "ellipsoidal",
635
- axis: [
636
- {
637
- name: "Geodetic longitude",
638
- abbreviation: "Lon",
639
- direction: "east",
640
- unit: "degree"
641
- },
642
- {
643
- name: "Geodetic latitude",
644
- abbreviation: "Lat",
645
- direction: "north",
646
- unit: "degree"
647
- }
648
- ]
649
- },
650
- scope: "Not known.",
651
- area: "World.",
652
- bbox: {
653
- south_latitude: -90,
654
- west_longitude: -180,
655
- north_latitude: 90,
656
- east_longitude: 180
657
- },
658
- // @ts-expect-error - proj4 types are incomplete
659
- id: { authority: "OGC", code: "CRS84" }
660
- };
661
- async function extractGeotiffReprojectors(tiff, outputCrs = OGC_84) {
662
- const image = await tiff.getImage();
663
- const geoKeys = image.getGeoKeys();
664
- const projectionCode = geoKeys.ProjectedCSTypeGeoKey || geoKeys.GeographicTypeGeoKey || null;
665
- const baseGeotransform = extractGeotransform(image);
666
- const sourceProjection = await getProjjson(projectionCode);
667
- if (sourceProjection === null) {
668
- throw new Error(
669
- "Could not determine source projection from GeoTIFF geo keys"
670
- );
671
- }
672
- const converter = proj4__default.default(sourceProjection, outputCrs);
673
- const { pixelToInputCRS, inputCRSToPixel } = fromGeoTransform(baseGeotransform);
674
- return {
675
- pixelToInputCRS,
676
- inputCRSToPixel,
677
- forwardReproject: (x, y) => converter.forward([x, y], false),
678
- inverseReproject: (x, y) => converter.inverse([x, y], false)
679
- };
680
- }
681
- function fromGeoTransform(geotransform) {
682
- const inverseGeotransform = invertGeoTransform(geotransform);
683
- return {
684
- pixelToInputCRS: (x, y) => applyAffine(x, y, geotransform),
685
- inputCRSToPixel: (x, y) => applyAffine(x, y, inverseGeotransform)
686
- };
687
- }
688
- async function getProjjson(projectionCode) {
689
- if (projectionCode === null) {
690
- return null;
691
- }
692
- const url = `https://epsg.io/${projectionCode}.json`;
693
- const response = await fetch(url);
694
- if (!response.ok) {
695
- throw new Error(`Failed to fetch projection data from ${url}`);
696
- }
697
- const data = await response.json();
698
- return data;
699
- }
700
- function extractGeotransform(image) {
701
- const origin = image.getOrigin();
702
- const resolution = image.getResolution();
703
- const fileDirectory = image.getFileDirectory();
704
- const modelTransformation = fileDirectory.ModelTransformation;
705
- let b2 = 0;
706
- let d2 = 0;
707
- if (modelTransformation && modelTransformation.length >= 16) {
708
- b2 = modelTransformation[1];
709
- d2 = modelTransformation[4];
710
- }
711
- return [
712
- resolution[0],
713
- // a: pixel width
714
- b2,
715
- // b: row rotation
716
- origin[0],
717
- // c: x origin
718
- d2,
719
- // d: column rotation
720
- resolution[1],
721
- // e: pixel height (often negative)
722
- origin[1]
723
- // f: y origin
724
- ];
725
- }
726
-
727
- exports.reprojection = reprojection_exports;
728
3
  //# sourceMappingURL=index.cjs.map
729
4
  //# sourceMappingURL=index.cjs.map