@developmentseed/raster-reproject 0.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,558 @@
1
+ /**
2
+ * Define [**uv coordinates**](https://en.wikipedia.org/wiki/UV_mapping) as a float-valued image-local coordinate space where the top left is `(0, 0)` and the bottom right is `(1, 1)`.
3
+ *
4
+ * Define [**Barycentric coordinates**](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) as float-valued triangle-local coordinates, represented as a 3-tuple of floats, where the tuple must add up to 1. The coordinate represents "how close to each vertex" a point in the interior of a triangle is. I.e. `(0, 0, 1)`, `(0, 1, 0)`, and `(1, 0, 0)` are all valid barycentric coordinates that define one of the three vertices. `(1/3, 1/3, 1/3)` represents the centroid of a triangle. `(1/2, 1/2, 0)` represents a point that is halfway between vertices `a` and `b` and has "none" of vertex `c`.
5
+ *
6
+ *
7
+ * ## Changes
8
+ *
9
+ * - Delatin coordinates are in terms of pixel space whereas here we use uv space.
10
+ *
11
+ * Originally copied from https://github.com/mapbox/delatin under the ISC
12
+ * license, then subject to further modifications.
13
+ */
14
+ /**
15
+ * Barycentric sample points in uv space for where to sample reprojection
16
+ * errors.
17
+ */
18
+ // TODO: Increase sampling density if uv area is large
19
+ // Note: these sample points should never be an existing vertex (that is, no
20
+ // vertex of a sample point should ever be `1`, such as `(0,0,1)`, because that
21
+ // would try to sample exactly at an existing triangle vertex).
22
+ const SAMPLE_POINTS = [
23
+ [1 / 3, 1 / 3, 1 / 3], // centroid
24
+ [0.5, 0.5, 0], // edge 0–1
25
+ [0.5, 0, 0.5], // edge 0–2
26
+ [0, 0.5, 0.5], // edge 1–2
27
+ ];
28
+ export class RasterReprojector {
29
+ reprojectors;
30
+ width;
31
+ height;
32
+ /**
33
+ * UV vertex coordinates (x, y), i.e.
34
+ * [x0, y0, x1, y1, ...]
35
+ *
36
+ * These coordinates are floats that range from [0, 1] in both X and Y.
37
+ */
38
+ uvs;
39
+ /**
40
+ * XY Positions in output CRS, computed via exact forward reprojection.
41
+ */
42
+ exactOutputPositions;
43
+ /**
44
+ * triangle vertex indices
45
+ */
46
+ triangles;
47
+ _halfedges;
48
+ /**
49
+ * The UV texture coordinates of candidates found from
50
+ * `findReprojectionCandidate`.
51
+ *
52
+ * Maybe in the future we'll want to store the barycentric coordinates instead
53
+ * of just the uv coordinates?
54
+ */
55
+ _candidatesUV;
56
+ _queueIndices;
57
+ _queue;
58
+ _errors;
59
+ _pending;
60
+ _pendingLen;
61
+ constructor(reprojectors, width, height = width) {
62
+ this.reprojectors = reprojectors;
63
+ this.width = width;
64
+ this.height = height;
65
+ this.uvs = []; // vertex coordinates (x, y)
66
+ this.exactOutputPositions = [];
67
+ this.triangles = []; // mesh triangle indices
68
+ // additional triangle data
69
+ this._halfedges = [];
70
+ this._candidatesUV = [];
71
+ this._queueIndices = [];
72
+ this._queue = []; // queue of added triangles
73
+ this._errors = [];
74
+ this._pending = []; // triangles pending addition to queue
75
+ this._pendingLen = 0;
76
+ // The two initial triangles cover the entire input texture in UV space, so
77
+ // they range from [0, 0] to [1, 1] in u and v.
78
+ const u1 = 1;
79
+ const v1 = 1;
80
+ const p0 = this._addPoint(0, 0);
81
+ const p1 = this._addPoint(u1, 0);
82
+ const p2 = this._addPoint(0, v1);
83
+ const p3 = this._addPoint(u1, v1);
84
+ // add initial two triangles
85
+ const t0 = this._addTriangle(p3, p0, p2, -1, -1, -1);
86
+ this._addTriangle(p0, p3, p1, t0, -1, -1);
87
+ this._flush();
88
+ }
89
+ // refine the mesh until its maximum error gets below the given one
90
+ run(maxError = 1) {
91
+ while (this.getMaxError() > maxError) {
92
+ this.refine();
93
+ }
94
+ }
95
+ // refine the mesh with a single point
96
+ refine() {
97
+ this._step();
98
+ this._flush();
99
+ }
100
+ // max error of the current mesh
101
+ getMaxError() {
102
+ return this._errors[0];
103
+ }
104
+ // rasterize and queue all triangles that got added or updated in _step
105
+ _flush() {
106
+ for (let i = 0; i < this._pendingLen; i++) {
107
+ const t = this._pending[i];
108
+ this._findReprojectionCandidate(t);
109
+ }
110
+ this._pendingLen = 0;
111
+ }
112
+ // Original, upstream implementation of FindCandidate:
113
+ // // rasterize a triangle, find its max error, and queue it for processing
114
+ // private _findCandidate(
115
+ // p0x: number,
116
+ // p0y: number,
117
+ // p1x: number,
118
+ // p1y: number,
119
+ // p2x: number,
120
+ // p2y: number,
121
+ // t: number,
122
+ // ) {
123
+ // // triangle bounding box
124
+ // const minX = Math.min(p0x, p1x, p2x);
125
+ // const minY = Math.min(p0y, p1y, p2y);
126
+ // const maxX = Math.max(p0x, p1x, p2x);
127
+ // const maxY = Math.max(p0y, p1y, p2y);
128
+ // // forward differencing variables
129
+ // let w00 = orient(p1x, p1y, p2x, p2y, minX, minY);
130
+ // let w01 = orient(p2x, p2y, p0x, p0y, minX, minY);
131
+ // let w02 = orient(p0x, p0y, p1x, p1y, minX, minY);
132
+ // const a01 = p1y - p0y;
133
+ // const b01 = p0x - p1x;
134
+ // const a12 = p2y - p1y;
135
+ // const b12 = p1x - p2x;
136
+ // const a20 = p0y - p2y;
137
+ // const b20 = p2x - p0x;
138
+ // // pre-multiplied z values at vertices
139
+ // const a = orient(p0x, p0y, p1x, p1y, p2x, p2y);
140
+ // const z0 = this.heightAt(p0x, p0y) / a;
141
+ // const z1 = this.heightAt(p1x, p1y) / a;
142
+ // const z2 = this.heightAt(p2x, p2y) / a;
143
+ // // iterate over pixels in bounding box
144
+ // let maxError = 0;
145
+ // let mx = 0;
146
+ // let my = 0;
147
+ // for (let y = minY; y <= maxY; y++) {
148
+ // // compute starting offset
149
+ // let dx = 0;
150
+ // if (w00 < 0 && a12 !== 0) {
151
+ // dx = Math.max(dx, Math.floor(-w00 / a12));
152
+ // }
153
+ // if (w01 < 0 && a20 !== 0) {
154
+ // dx = Math.max(dx, Math.floor(-w01 / a20));
155
+ // }
156
+ // if (w02 < 0 && a01 !== 0) {
157
+ // dx = Math.max(dx, Math.floor(-w02 / a01));
158
+ // }
159
+ // let w0 = w00 + a12 * dx;
160
+ // let w1 = w01 + a20 * dx;
161
+ // let w2 = w02 + a01 * dx;
162
+ // let wasInside = false;
163
+ // for (let x = minX + dx; x <= maxX; x++) {
164
+ // // check if inside triangle
165
+ // if (w0 >= 0 && w1 >= 0 && w2 >= 0) {
166
+ // wasInside = true;
167
+ // // compute z using barycentric coordinates
168
+ // const z = z0 * w0 + z1 * w1 + z2 * w2;
169
+ // const dz = Math.abs(z - this.heightAt(x, y));
170
+ // if (dz > maxError) {
171
+ // maxError = dz;
172
+ // mx = x;
173
+ // my = y;
174
+ // }
175
+ // } else if (wasInside) {
176
+ // break;
177
+ // }
178
+ // w0 += a12;
179
+ // w1 += a20;
180
+ // w2 += a01;
181
+ // }
182
+ // w00 += b12;
183
+ // w01 += b20;
184
+ // w02 += b01;
185
+ // }
186
+ // if (
187
+ // (mx === p0x && my === p0y) ||
188
+ // (mx === p1x && my === p1y) ||
189
+ // (mx === p2x && my === p2y)
190
+ // ) {
191
+ // maxError = 0;
192
+ // }
193
+ // // update triangle metadata
194
+ // this._candidatesUV[2 * t] = mx;
195
+ // this._candidatesUV[2 * t + 1] = my;
196
+ // // add triangle to priority queue
197
+ // this._queuePush(t, maxError);
198
+ // }
199
+ /**
200
+ * Conversion of upstream's `_findCandidate` for reprojection error handling.
201
+ *
202
+ * @param {number} t The index (into `this.triangles`) of the pending triangle to process.
203
+ *
204
+ * @return {void} Doesn't return; instead modifies internal state.
205
+ */
206
+ _findReprojectionCandidate(t) {
207
+ // Find the three vertices of this triangle
208
+ const a = 2 * this.triangles[t * 3 + 0];
209
+ const b = 2 * this.triangles[t * 3 + 1];
210
+ const c = 2 * this.triangles[t * 3 + 2];
211
+ // Get the UV coordinates of each vertex
212
+ const p0u = this.uvs[a];
213
+ const p0v = this.uvs[a + 1];
214
+ const p1u = this.uvs[b];
215
+ const p1v = this.uvs[b + 1];
216
+ const p2u = this.uvs[c];
217
+ const p2v = this.uvs[c + 1];
218
+ // Get the **known** output CRS positions of each vertex
219
+ const out0x = this.exactOutputPositions[a];
220
+ const out0y = this.exactOutputPositions[a + 1];
221
+ const out1x = this.exactOutputPositions[b];
222
+ const out1y = this.exactOutputPositions[b + 1];
223
+ const out2x = this.exactOutputPositions[c];
224
+ const out2y = this.exactOutputPositions[c + 1];
225
+ // A running tally of the maximum pixel error of each of our candidate
226
+ // points
227
+ let maxError = 0;
228
+ // The point in uv coordinates that produced the max error
229
+ // Note that upstream also initializes the point of max error to [0, 0]
230
+ let maxErrorU = 0;
231
+ let maxErrorV = 0;
232
+ // Recall that the sample point is in barycentric coordinates
233
+ for (const samplePoint of SAMPLE_POINTS) {
234
+ // Get the UV coordinates of the sample point
235
+ const uvSampleU = barycentricMix(p0u, p1u, p2u, samplePoint[0], samplePoint[1], samplePoint[2]);
236
+ const uvSampleV = barycentricMix(p0v, p1v, p2v, samplePoint[0], samplePoint[1], samplePoint[2]);
237
+ // Get the output CRS coordinates of the sample point by bilinear
238
+ // interpolation
239
+ const outSampleX = barycentricMix(out0x, out1x, out2x, samplePoint[0], samplePoint[1], samplePoint[2]);
240
+ const outSampleY = barycentricMix(out0y, out1y, out2y, samplePoint[0], samplePoint[1], samplePoint[2]);
241
+ // Convert uv to pixel space
242
+ const pixelExactX = uvSampleU * (this.width - 1);
243
+ const pixelExactY = uvSampleV * (this.height - 1);
244
+ // Reproject these linearly-interpolated coordinates **from target CRS
245
+ // to input CRS**. This gives us the **exact position in input space**
246
+ // of the linearly interpolated sample point in output space.
247
+ const inputCRSSampled = this.reprojectors.inverseReproject(outSampleX, outSampleY);
248
+ // Find the pixel coordinates of the sampled point by using the inverse
249
+ // geotransform.
250
+ const pixelSampled = this.reprojectors.inputCRSToPixel(inputCRSSampled[0], inputCRSSampled[1]);
251
+ // 4. error in pixel space
252
+ const dx = pixelExactX - pixelSampled[0];
253
+ const dy = pixelExactY - pixelSampled[1];
254
+ const err = Math.hypot(dx, dy);
255
+ if (err > maxError) {
256
+ maxError = err;
257
+ maxErrorU = uvSampleU;
258
+ maxErrorV = uvSampleV;
259
+ }
260
+ }
261
+ //////
262
+ // Now we can resume with code from upstream's `_findCandidate` that
263
+ // modifies the internal state of what triangles to subdivide.
264
+ // Check that the max error point is not one of the existing triangle
265
+ // vertices
266
+ // TODO: perhaps we should use float precision epsilon here?
267
+ if ((maxErrorU === p0u && maxErrorV === p0v) ||
268
+ (maxErrorU === p1u && maxErrorV === p1v) ||
269
+ (maxErrorU === p2u && maxErrorV === p2v)) {
270
+ maxError = 0;
271
+ }
272
+ // update triangle metadata
273
+ this._candidatesUV[2 * t] = maxErrorU;
274
+ this._candidatesUV[2 * t + 1] = maxErrorV;
275
+ // add triangle to priority queue
276
+ this._queuePush(t, maxError);
277
+ }
278
+ // process the next triangle in the queue, splitting it with a new point
279
+ _step() {
280
+ // pop triangle with highest error from priority queue
281
+ const t = this._queuePop();
282
+ const e0 = t * 3 + 0;
283
+ const e1 = t * 3 + 1;
284
+ const e2 = t * 3 + 2;
285
+ const p0 = this.triangles[e0];
286
+ const p1 = this.triangles[e1];
287
+ const p2 = this.triangles[e2];
288
+ const au = this.uvs[2 * p0];
289
+ const av = this.uvs[2 * p0 + 1];
290
+ const bu = this.uvs[2 * p1];
291
+ const bv = this.uvs[2 * p1 + 1];
292
+ const cu = this.uvs[2 * p2];
293
+ const cv = this.uvs[2 * p2 + 1];
294
+ const pu = this._candidatesUV[2 * t];
295
+ const pv = this._candidatesUV[2 * t + 1];
296
+ const pn = this._addPoint(pu, pv);
297
+ if (orient(au, av, bu, bv, pu, pv) === 0) {
298
+ this._handleCollinear(pn, e0);
299
+ }
300
+ else if (orient(bu, bv, cu, cv, pu, pv) === 0) {
301
+ this._handleCollinear(pn, e1);
302
+ }
303
+ else if (orient(cu, cv, au, av, pu, pv) === 0) {
304
+ this._handleCollinear(pn, e2);
305
+ }
306
+ else {
307
+ const h0 = this._halfedges[e0];
308
+ const h1 = this._halfedges[e1];
309
+ const h2 = this._halfedges[e2];
310
+ const t0 = this._addTriangle(p0, p1, pn, h0, -1, -1, e0);
311
+ const t1 = this._addTriangle(p1, p2, pn, h1, -1, t0 + 1);
312
+ const t2 = this._addTriangle(p2, p0, pn, h2, t0 + 2, t1 + 1);
313
+ this._legalize(t0);
314
+ this._legalize(t1);
315
+ this._legalize(t2);
316
+ }
317
+ }
318
+ // add coordinates for a new vertex
319
+ _addPoint(u, v) {
320
+ const i = this.uvs.length >> 1;
321
+ this.uvs.push(u, v);
322
+ // compute and store exact output position via reprojection
323
+ const pixelX = u * (this.width - 1);
324
+ const pixelY = v * (this.height - 1);
325
+ const inputPosition = this.reprojectors.pixelToInputCRS(pixelX, pixelY);
326
+ const exactOutputPosition = this.reprojectors.forwardReproject(inputPosition[0], inputPosition[1]);
327
+ this.exactOutputPositions.push(exactOutputPosition[0], exactOutputPosition[1]);
328
+ return i;
329
+ }
330
+ // add or update a triangle in the mesh
331
+ _addTriangle(a, b, c, ab, bc, ca, e = this.triangles.length) {
332
+ const t = e / 3; // new triangle index
333
+ // add triangle vertices
334
+ this.triangles[e + 0] = a;
335
+ this.triangles[e + 1] = b;
336
+ this.triangles[e + 2] = c;
337
+ // add triangle halfedges
338
+ this._halfedges[e + 0] = ab;
339
+ this._halfedges[e + 1] = bc;
340
+ this._halfedges[e + 2] = ca;
341
+ // link neighboring halfedges
342
+ if (ab >= 0) {
343
+ this._halfedges[ab] = e + 0;
344
+ }
345
+ if (bc >= 0) {
346
+ this._halfedges[bc] = e + 1;
347
+ }
348
+ if (ca >= 0) {
349
+ this._halfedges[ca] = e + 2;
350
+ }
351
+ // init triangle metadata
352
+ this._candidatesUV[2 * t + 0] = 0;
353
+ this._candidatesUV[2 * t + 1] = 0;
354
+ this._queueIndices[t] = -1;
355
+ // add triangle to pending queue for later rasterization
356
+ this._pending[this._pendingLen++] = t;
357
+ // return first halfedge index
358
+ return e;
359
+ }
360
+ _legalize(a) {
361
+ // if the pair of triangles doesn't satisfy the Delaunay condition
362
+ // (p1 is inside the circumcircle of [p0, pl, pr]), flip them,
363
+ // then do the same check/flip recursively for the new pair of triangles
364
+ //
365
+ // pl pl
366
+ // /||\ / \
367
+ // al/ || \bl al/ \a
368
+ // / || \ / \
369
+ // / a||b \ flip /___ar___\
370
+ // p0\ || /p1 => p0\---bl---/p1
371
+ // \ || / \ /
372
+ // ar\ || /br b\ /br
373
+ // \||/ \ /
374
+ // pr pr
375
+ const b = this._halfedges[a];
376
+ if (b < 0) {
377
+ return;
378
+ }
379
+ const a0 = a - (a % 3);
380
+ const b0 = b - (b % 3);
381
+ const al = a0 + ((a + 1) % 3);
382
+ const ar = a0 + ((a + 2) % 3);
383
+ const bl = b0 + ((b + 2) % 3);
384
+ const br = b0 + ((b + 1) % 3);
385
+ const p0 = this.triangles[ar];
386
+ const pr = this.triangles[a];
387
+ const pl = this.triangles[al];
388
+ const p1 = this.triangles[bl];
389
+ const uvs = this.uvs;
390
+ if (!inCircle(uvs[2 * p0], uvs[2 * p0 + 1], uvs[2 * pr], uvs[2 * pr + 1], uvs[2 * pl], uvs[2 * pl + 1], uvs[2 * p1], uvs[2 * p1 + 1])) {
391
+ return;
392
+ }
393
+ const hal = this._halfedges[al];
394
+ const har = this._halfedges[ar];
395
+ const hbl = this._halfedges[bl];
396
+ const hbr = this._halfedges[br];
397
+ this._queueRemove(a0 / 3);
398
+ this._queueRemove(b0 / 3);
399
+ const t0 = this._addTriangle(p0, p1, pl, -1, hbl, hal, a0);
400
+ const t1 = this._addTriangle(p1, p0, pr, t0, har, hbr, b0);
401
+ this._legalize(t0 + 1);
402
+ this._legalize(t1 + 2);
403
+ }
404
+ // handle a case where new vertex is on the edge of a triangle
405
+ _handleCollinear(pn, a) {
406
+ const a0 = a - (a % 3);
407
+ const al = a0 + ((a + 1) % 3);
408
+ const ar = a0 + ((a + 2) % 3);
409
+ const p0 = this.triangles[ar];
410
+ const pr = this.triangles[a];
411
+ const pl = this.triangles[al];
412
+ const hal = this._halfedges[al];
413
+ const har = this._halfedges[ar];
414
+ const b = this._halfedges[a];
415
+ if (b < 0) {
416
+ const t0 = this._addTriangle(pn, p0, pr, -1, har, -1, a0);
417
+ const t1 = this._addTriangle(p0, pn, pl, t0, -1, hal);
418
+ this._legalize(t0 + 1);
419
+ this._legalize(t1 + 2);
420
+ return;
421
+ }
422
+ const b0 = b - (b % 3);
423
+ const bl = b0 + ((b + 2) % 3);
424
+ const br = b0 + ((b + 1) % 3);
425
+ const p1 = this.triangles[bl];
426
+ const hbl = this._halfedges[bl];
427
+ const hbr = this._halfedges[br];
428
+ this._queueRemove(b0 / 3);
429
+ const t0 = this._addTriangle(p0, pr, pn, har, -1, -1, a0);
430
+ const t1 = this._addTriangle(pr, p1, pn, hbr, -1, t0 + 1, b0);
431
+ const t2 = this._addTriangle(p1, pl, pn, hbl, -1, t1 + 1);
432
+ const t3 = this._addTriangle(pl, p0, pn, hal, t0 + 2, t2 + 1);
433
+ this._legalize(t0);
434
+ this._legalize(t1);
435
+ this._legalize(t2);
436
+ this._legalize(t3);
437
+ }
438
+ // priority queue methods
439
+ _queuePush(t, error) {
440
+ const i = this._queue.length;
441
+ this._queueIndices[t] = i;
442
+ this._queue.push(t);
443
+ this._errors.push(error);
444
+ this._queueUp(i);
445
+ }
446
+ _queuePop() {
447
+ const n = this._queue.length - 1;
448
+ this._queueSwap(0, n);
449
+ this._queueDown(0, n);
450
+ return this._queuePopBack();
451
+ }
452
+ _queuePopBack() {
453
+ const t = this._queue.pop();
454
+ this._errors.pop();
455
+ this._queueIndices[t] = -1;
456
+ return t;
457
+ }
458
+ _queueRemove(t) {
459
+ const i = this._queueIndices[t];
460
+ if (i < 0) {
461
+ const it = this._pending.indexOf(t);
462
+ if (it !== -1) {
463
+ this._pending[it] = this._pending[--this._pendingLen];
464
+ }
465
+ else {
466
+ throw new Error("Broken triangulation (something went wrong).");
467
+ }
468
+ return;
469
+ }
470
+ const n = this._queue.length - 1;
471
+ if (n !== i) {
472
+ this._queueSwap(i, n);
473
+ if (!this._queueDown(i, n)) {
474
+ this._queueUp(i);
475
+ }
476
+ }
477
+ this._queuePopBack();
478
+ }
479
+ _queueLess(i, j) {
480
+ return this._errors[i] > this._errors[j];
481
+ }
482
+ _queueSwap(i, j) {
483
+ const pi = this._queue[i];
484
+ const pj = this._queue[j];
485
+ this._queue[i] = pj;
486
+ this._queue[j] = pi;
487
+ this._queueIndices[pi] = j;
488
+ this._queueIndices[pj] = i;
489
+ const e = this._errors[i];
490
+ this._errors[i] = this._errors[j];
491
+ this._errors[j] = e;
492
+ }
493
+ _queueUp(j0) {
494
+ let j = j0;
495
+ while (true) {
496
+ const i = (j - 1) >> 1;
497
+ if (i === j || !this._queueLess(j, i)) {
498
+ break;
499
+ }
500
+ this._queueSwap(i, j);
501
+ j = i;
502
+ }
503
+ }
504
+ _queueDown(i0, n) {
505
+ let i = i0;
506
+ while (true) {
507
+ const j1 = 2 * i + 1;
508
+ if (j1 >= n || j1 < 0) {
509
+ break;
510
+ }
511
+ const j2 = j1 + 1;
512
+ let j = j1;
513
+ if (j2 < n && this._queueLess(j2, j1)) {
514
+ j = j2;
515
+ }
516
+ if (!this._queueLess(j, i)) {
517
+ break;
518
+ }
519
+ this._queueSwap(i, j);
520
+ i = j;
521
+ }
522
+ return i > i0;
523
+ }
524
+ }
525
+ function orient(ax, ay, bx, by, cx, cy) {
526
+ return (bx - cx) * (ay - cy) - (by - cy) * (ax - cx);
527
+ }
528
+ function inCircle(ax, ay, bx, by, cx, cy, px, py) {
529
+ const dx = ax - px;
530
+ const dy = ay - py;
531
+ const ex = bx - px;
532
+ const ey = by - py;
533
+ const fx = cx - px;
534
+ const fy = cy - py;
535
+ const ap = dx * dx + dy * dy;
536
+ const bp = ex * ex + ey * ey;
537
+ const cp = fx * fx + fy * fy;
538
+ return (dx * (ey * cp - bp * fy) -
539
+ dy * (ex * cp - bp * fx) +
540
+ ap * (ex * fy - ey * fx) <
541
+ 0);
542
+ }
543
+ /**
544
+ * Interpolate the value at a given barycentric coordinate within a triangle.
545
+ *
546
+ * I've seen the name "mix" used before in graphics programming to refer to
547
+ * barycentric linear interpolation.
548
+ *
549
+ * Note: the caller must call this method twice: once for u and once again for
550
+ * v. We do this because we want to avoid allocating an array for the return
551
+ * value.
552
+ */
553
+ function barycentricMix(a, b, c,
554
+ // Barycentric coordinates
555
+ t0, t1, t2) {
556
+ return t0 * a + t1 * b + t2 * c;
557
+ }
558
+ //# sourceMappingURL=delatin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delatin.js","sourceRoot":"","sources":["../src/delatin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { applyAffine, invertGeoTransform } from "./affine.js";
2
+ export type { GeoTransform } from "./affine.js";
3
+ export { RasterReprojector } from "./delatin.js";
4
+ export type { ReprojectionFns } from "./delatin.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { applyAffine, invertGeoTransform } from "./affine.js";
2
+ export { RasterReprojector } from "./delatin.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,18 @@
1
+ export type GeoTransform = [number, number, number, number, number, number];
2
+ /**
3
+ * Find the inverse of this GeoTransform.
4
+ *
5
+ * Ported from rasterio/affine:
6
+ * https://github.com/rasterio/affine/blob/a7a916fc7012f8afeb6489246ada61a76ccb8bc7/src/affine.py#L671-L692
7
+ * under the BSD-3-Clause License.
8
+ *
9
+ * @param {GeoTransform} gt Geotransform.
10
+ *
11
+ * @return {GeoTransform} Inverse of the geotransform.
12
+ */
13
+ export declare function invertGeoTransform(gt: GeoTransform): GeoTransform;
14
+ /**
15
+ * Apply a GeoTransform to a coordinate.
16
+ */
17
+ export declare function applyAffine(x: number, y: number, gt: [number, number, number, number, number, number]): [number, number];
18
+ //# sourceMappingURL=affine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"affine.d.ts","sourceRoot":"","sources":["../../src/affine.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE5E;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,YAAY,CAgBjE;AAWD;;GAEG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GACnD,CAAC,MAAM,EAAE,MAAM,CAAC,CAGlB"}