cog-tiler-wasm 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/cog-tiler.js +46 -11
- package/cog_tiler_wasm_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -210,10 +210,12 @@ fully transparent.
|
|
|
210
210
|
colormaps (see [above](#titiler-style-cog-api)). Next: band-math
|
|
211
211
|
**`expression`** and `color_formula`.
|
|
212
212
|
- **Warping** of projected/4326 sources and **paletted/categorical** rendering
|
|
213
|
-
are done in [`cog-tiler.js`](cog-tiler.js) (proj4js + geotiff.js).
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
213
|
+
are done in [`cog-tiler.js`](cog-tiler.js) (proj4js + geotiff.js). **Planar**
|
|
214
|
+
(`INTERLEAVE=BAND`) multi-band COGs are read per-band via geotiff.js too, since
|
|
215
|
+
whitebox-wasm's streaming decoder is chunky-only. Next: planar support
|
|
216
|
+
**upstream in `whitebox-wasm`** (and exposing its proj string + color table) to
|
|
217
|
+
drop the geotiff.js dependency, then move the warp into the Rust crate
|
|
218
|
+
(`proj4rs`).
|
|
217
219
|
- **Edge / WASI serving** - run the same module as a serverless XYZ endpoint
|
|
218
220
|
near the data, not only in the browser.
|
|
219
221
|
- **STAC / mosaics** - multi-asset orchestration.
|
package/cog-tiler.js
CHANGED
|
@@ -239,7 +239,18 @@ export async function openCog(source) {
|
|
|
239
239
|
if (!Array.isArray(levels) || levels.length === 0) {
|
|
240
240
|
throw new Error("levels_json() returned no levels");
|
|
241
241
|
}
|
|
242
|
-
|
|
242
|
+
// Open the GeoTIFF with geotiff.js when we need the CRS (non-3857) or to check
|
|
243
|
+
// the planar config (multi-band). whitebox-wasm's streaming decoder is
|
|
244
|
+
// chunky-only, so planar (INTERLEAVE=BAND) multi-band COGs are read per-band
|
|
245
|
+
// through geotiff.js instead (see _assembleWindow / point).
|
|
246
|
+
const multiBand = levels[0].bands > 1;
|
|
247
|
+
let tiff = null, img = null, planar = false;
|
|
248
|
+
if (stream.epsg !== 3857 || multiBand) {
|
|
249
|
+
tiff = await openTiff();
|
|
250
|
+
img = await tiff.getImage();
|
|
251
|
+
planar = multiBand && img.fileDirectory.PlanarConfiguration === 2;
|
|
252
|
+
}
|
|
253
|
+
const base = { url: label, range, stream, levels, gt, nodata: stream.nodata, tiff, planar };
|
|
243
254
|
|
|
244
255
|
if (stream.epsg === 3857) {
|
|
245
256
|
return new CogSource({
|
|
@@ -253,8 +264,6 @@ export async function openCog(source) {
|
|
|
253
264
|
}
|
|
254
265
|
|
|
255
266
|
// Warp path: read the real source CRS + optional palette from the header.
|
|
256
|
-
const tiff = await openTiff();
|
|
257
|
-
const img = await tiff.getImage();
|
|
258
267
|
const srcDef = geokeysToProj4.toProj4(img.getGeoKeys()).proj4;
|
|
259
268
|
if (!srcDef) throw new Error("could not derive source CRS from GeoTIFF geokeys");
|
|
260
269
|
const toSource = proj4("EPSG:3857", srcDef); // forward: mercator -> source
|
|
@@ -326,10 +335,27 @@ export class CogSource {
|
|
|
326
335
|
return p;
|
|
327
336
|
}
|
|
328
337
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
338
|
+
/** geotiff.js image for an overview level (cached). Used for planar reads. */
|
|
339
|
+
_tiffImage(level) {
|
|
340
|
+
if (!this._imgs) this._imgs = new Map();
|
|
341
|
+
let p = this._imgs.get(level);
|
|
342
|
+
if (!p) {
|
|
343
|
+
p = this.tiff.getImage(level);
|
|
344
|
+
this._imgs.set(level, p);
|
|
345
|
+
}
|
|
346
|
+
return p;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Fetch + decode band `band` (0-based) over a level pixel window into a
|
|
350
|
+
// row-major buffer. Chunky COGs go through whitebox (cached, NaN for gaps);
|
|
351
|
+
// planar (INTERLEAVE=BAND) COGs are read per-band via geotiff.js, which
|
|
352
|
+
// whitebox's chunky-only streaming decoder can't address.
|
|
332
353
|
async _assembleWindow(level, x, y, w, h, band = 0) {
|
|
354
|
+
if (this.planar) {
|
|
355
|
+
const img = await this._tiffImage(level);
|
|
356
|
+
const rasters = await img.readRasters({ window: [x, y, x + w, y + h], samples: [band] });
|
|
357
|
+
return rasters[0]; // typed array, length w*h, row-major
|
|
358
|
+
}
|
|
333
359
|
const lv = this.levels[level];
|
|
334
360
|
const tiles = JSON.parse(this.stream.tiles_for_window(level, x, y, w, h));
|
|
335
361
|
const decoded = await Promise.all(tiles.map((t) => this._getTile(level, t)));
|
|
@@ -570,14 +596,23 @@ export class CogSource {
|
|
|
570
596
|
if (col < 0 || col >= l0.width || row < 0 || row >= l0.height) {
|
|
571
597
|
return { coordinates: [lon, lat], values: [], band_names: [], outside: true };
|
|
572
598
|
}
|
|
573
|
-
const tcol = Math.floor(col / l0.tile_width), trow = Math.floor(row / l0.tile_height);
|
|
574
|
-
const [off, len] = Array.from(this.stream.tile_range(0, tcol, trow));
|
|
575
|
-
const px = await this._getTile(0, { col: tcol, row: trow, offset: off, length: len });
|
|
576
|
-
const base = ((row % l0.tile_height) * l0.tile_width + (col % l0.tile_width)) * l0.bands;
|
|
577
599
|
const bands = bidx ? bidx.map((b) => b - 1) : Array.from({ length: l0.bands }, (_, i) => i);
|
|
600
|
+
let values;
|
|
601
|
+
if (this.planar) {
|
|
602
|
+
// Planar: whitebox can't address bands 1..n; read the pixel via geotiff.js.
|
|
603
|
+
const img = await this._tiffImage(0);
|
|
604
|
+
const r = await img.readRasters({ window: [col, row, col + 1, row + 1], samples: bands });
|
|
605
|
+
values = r.map((b) => b[0]);
|
|
606
|
+
} else {
|
|
607
|
+
const tcol = Math.floor(col / l0.tile_width), trow = Math.floor(row / l0.tile_height);
|
|
608
|
+
const [off, len] = Array.from(this.stream.tile_range(0, tcol, trow));
|
|
609
|
+
const px = await this._getTile(0, { col: tcol, row: trow, offset: off, length: len });
|
|
610
|
+
const base = ((row % l0.tile_height) * l0.tile_width + (col % l0.tile_width)) * l0.bands;
|
|
611
|
+
values = bands.map((b) => px[base + b]);
|
|
612
|
+
}
|
|
578
613
|
return {
|
|
579
614
|
coordinates: [lon, lat],
|
|
580
|
-
values
|
|
615
|
+
values,
|
|
581
616
|
band_names: bands.map((b) => `b${b + 1}`),
|
|
582
617
|
};
|
|
583
618
|
}
|
package/cog_tiler_wasm_bg.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"Qiusheng Wu <giswqs@gmail.com>"
|
|
6
6
|
],
|
|
7
7
|
"description": "Serverless Cloud Optimized GeoTIFF (COG) dynamic tiling in WebAssembly. TiTiler-style XYZ tiles, no backend.",
|
|
8
|
-
"version": "0.2.
|
|
8
|
+
"version": "0.2.1",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|