Skip to content

Commit cf8352f

Browse files
committed
auto-detect pixel depth of output
1 parent 4a3acff commit cf8352f

File tree

3 files changed

+84
-33
lines changed

3 files changed

+84
-33
lines changed

geowarp.js

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ const geowarp = function geowarp({
123123
out_array_types, // array of constructor names passed to internal call to xdim's prepareData function
124124
out_bands, // array of bands to keep and order, default is keeping all the bands in same order
125125
out_data, // single or multi-dimensional array that geowarp will fill in with the output
126-
out_pixel_depth, // number of output bands
126+
out_pixel_depth, // optional, number of output bands
127127
out_pixel_height, // optional, automatically calculated from out_bbox
128128
out_pixel_width, // optional, automatically calculated from out_bbox
129129
out_bbox = null,
@@ -271,9 +271,6 @@ const geowarp = function geowarp({
271271
}
272272

273273
if (debug_level >= 1) console.log("[geowarp] read_bands:", read_bands);
274-
275-
out_pixel_depth ??= out_bands?.length ?? read_bands?.length ?? in_pixel_depth;
276-
277274
if (debug_level >= 1) console.log("[geowarp] out_height:", out_height);
278275
if (debug_level >= 1) console.log("[geowarp] out_width:", out_width);
279276

@@ -423,24 +420,11 @@ const geowarp = function geowarp({
423420
cache_process = predicted_cache_hit_rate >= 0.85;
424421
}
425422

426-
// dimensions of the output
427-
const out_sizes = {
428-
band: out_pixel_depth,
429-
row: out_height,
430-
column: out_width
431-
};
432-
433-
out_data ??= xdim.prepareData({
434-
fill: out_no_data,
435-
layout: out_layout,
436-
sizes: out_sizes,
437-
arrayTypes: out_array_types
438-
}).data;
439-
440423
if (typeof insert_pixel !== "function") {
441-
const update = xdim.prepareUpdate({ data: out_data, layout: out_layout, sizes: out_sizes });
424+
let update;
442425

443-
const insert_pixel_sync = ({ row, column, pixel, raw }) => {
426+
// only works once update is defined later on
427+
const update_pixel = ({ row, column, pixel }) => {
444428
pixel.forEach((value, band) => {
445429
update({
446430
point: { band, row, column },
@@ -449,18 +433,44 @@ const geowarp = function geowarp({
449433
});
450434
};
451435

452-
const insert_pixel_async = ({ pixel: px, row, ...rest }) => {
453-
pending++;
454-
return px.then(pixel => {
455-
insert_pixel_sync({ pixel, row, ...rest });
456-
pending--;
457-
});
436+
let insert_pixel_sync = ({ pixel, ...rest }) => {
437+
try {
438+
out_pixel_depth ??= pixel.length;
439+
if (debug_level >= 1) console.log("[geowarp] out_pixel_depth:", out_pixel_depth);
440+
441+
const out_sizes = {
442+
band: out_pixel_depth,
443+
row: out_height,
444+
column: out_width
445+
};
446+
if (debug_level >= 1) console.log("[geowarp] out_sizes:", out_sizes);
447+
448+
out_data ??= xdim.prepareData({
449+
fill: out_no_data,
450+
layout: out_layout,
451+
sizes: out_sizes,
452+
arrayTypes: out_array_types
453+
}).data;
454+
if (debug_level >= 1) console.log("[geowarp] out_data:", typeof out_data);
455+
456+
update = xdim.prepareUpdate({ data: out_data, layout: out_layout, sizes: out_sizes });
457+
if (debug_level >= 1) console.log("[geowarp] prepared update function");
458+
459+
// replace self, so subsequent calls go directly to update_pixel
460+
insert_pixel_sync = update_pixel;
461+
462+
update_pixel({ pixel, ...rest });
463+
} catch (error) {
464+
console.error("first call to insert_pixel_sync failed:", error);
465+
}
458466
};
459467

460468
insert_pixel = ({ pixel, ...rest }) => {
461-
// hot swap insert_pixel based on whether the first call returns a promise or not
462-
insert_pixel = pixel.then ? insert_pixel_async : insert_pixel_sync;
463-
insert_pixel({ pixel, ...rest });
469+
pending++;
470+
quickResolve(pixel).then(px => {
471+
insert_pixel_sync({ pixel: px, ...rest });
472+
pending--;
473+
});
464474
};
465475
}
466476

@@ -896,7 +906,7 @@ const geowarp = function geowarp({
896906

897907
if (debug_level >= 1) console.log("[geowarp] took " + (performance.now() - start_time).toFixed(0) + "ms");
898908

899-
const result = {
909+
const generate_result = () => ({
900910
data: out_data,
901911
out_bands,
902912
out_layout,
@@ -905,7 +915,7 @@ const geowarp = function geowarp({
905915
out_sample_height,
906916
out_sample_width,
907917
read_bands
908-
};
918+
});
909919

910920
if (pending > 0) {
911921
// async return
@@ -914,13 +924,13 @@ const geowarp = function geowarp({
914924
const intervalId = setInterval(() => {
915925
if (pending === 0) {
916926
clearInterval(intervalId);
917-
resolve(result);
927+
resolve(generate_result());
918928
}
919929
}, ms);
920930
});
921931
} else {
922932
// sync return
923-
return result;
933+
return generate_result();
924934
}
925935
};
926936

test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,3 +643,43 @@ test("rescale", async ({ eq }) => {
643643
eq(data.length, 4); // check band count
644644
eq(data[0][0].constructor.name, "Array");
645645
});
646+
647+
test("auto-detect out_pixel_depth", async ({ eq }) => {
648+
const filename = "gadas.tif";
649+
const filepath = path.resolve(__dirname, "./test-data", filename);
650+
const geotiff = await GeoTIFF.fromFile(filepath);
651+
const image = await geotiff.getImage(0);
652+
const rasters = await image.readRasters();
653+
const in_bbox = image.getBoundingBox();
654+
const height = image.getHeight();
655+
const width = image.getWidth();
656+
// ProjectedCSTypeGeoKey says 32767, but PCSCitationGeoKey says ESRI PE String = 3857.esriwkt
657+
const in_srs = 3857;
658+
const out_srs = 3857;
659+
const out_height = Math.round(height / 10);
660+
const out_width = Math.round(width / 10);
661+
662+
const result = await geowarp({
663+
debug_level: 1,
664+
expr: async ({ pixel: [r, g, b, a] }) => (b > 150 ? [223, 255, 0] : [r, g, b]),
665+
in_bbox,
666+
in_data: rasters,
667+
in_layout: "[band][row,column]",
668+
in_srs,
669+
in_height: height,
670+
in_width: width,
671+
out_height,
672+
out_width,
673+
out_layout: "[band][row][column]",
674+
out_srs,
675+
method: "median"
676+
});
677+
678+
const { data } = result;
679+
680+
if (process.env.WRITE) {
681+
writePNGSync({ h: out_height, w: out_width, data, filepath: "./test-output/out-pixel-depth" });
682+
}
683+
eq(data.length, 3); // check band count
684+
eq(data[0][0].constructor.name, "Array");
685+
});

test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ const runTileTests = async ({
369369
"20,23,12",
370370
"22,30,17",
371371
"22,30,19",
372+
"36,46,45",
372373
"42,51,48"
373374
],
374375
turbos: [false, true],

0 commit comments

Comments
 (0)