mmomtchev / node-gdal-async

Node.js bindings for GDAL (Geospatial Data Abstraction Library) with full async support
https://mmomtchev.github.io/node-gdal-async/
Apache License 2.0
129 stars 26 forks source link

Error reading pixels from raster #76

Closed kochis closed 1 year ago

kochis commented 1 year ago

I'm getting the following error when trying to read pixels from a GeoTIFF file:

Error: Array length must be greater than or equal to 1296000000
    at node:internal/util:364:7
    at new Promise (<anonymous>)
    at RasterBandPixels.readAsync (node:internal/util:350:12)
    at RasterBandPixels.readAsync (/Users/_/Projects/gdal-test/node_modules/gdal-async/lib/gdal.js:938:28)
    at run (/Users/_/Projects/gdal-test/filter.js:20:44)

Uncertain either I'm doing something wrong in the code, or if the extension was not compiled correctly (though the other lines in the file are working, up til readAsync).

I'm using the following script:

const gdal = require('gdal-async');

const run = async () => {
  // open input
  const dataset = await gdal.openAsync('input.tif');
  const inputBand = await dataset.bands.getAsync(1);
  const [width, height] = [dataset.rasterSize.x, dataset.rasterSize.y];

  // create output
  const driver = gdal.drivers.get('GTiff');
  const outputDataset = await driver.createAsync('output.tif', width, height, 1, gdal.GDT_Byte);

  // copy projection info from source
  outputDataset.geoTransform = dataset.geoTransform;
  outputDataset.srs = dataset.srs;

  // process file
  const targetValue = 80;
  const inputData = await inputBand.pixels.readAsync(0, 0, width, height);
  const outputData = new Uint8Array(width * height);
  for (let i = 0; i < width * height; i++) {
    if (inputData[i] === targetValue) {
      outputData[i] = inputData[i];
    } else {
      outputData[i] = 0;
    }
  }

  // write output
  const outputBand = outputDataset.bands.get(1);
  await outputBand.pixels.writeAsync(0, 0, width, height, outputData);

  // close files
  dataset.close();
  outputDataset.close();
};

run()
  .then(() => console.log('Done.'))
  .catch(console.error);

Other info: node: 16.19.0 GDAL: 3.6.2 (via homebrew) OS: Mac OS 13.1, M1

Any help here would be greatly appreciated. Thanks!

kochis commented 1 year ago

Ah, looks like it's an array size issue. Was able to work around by processing in chunks.