Reputation:
I am trying to return a binary array of floating points. I get a Float32Array from a geotiff library, however the http can only return a string or buffer so I have to 'convert' it to a buffer.
const tiff = await geotiff.fromUrl(ahnUrl);
const image = await tiff.getImage();
const data = await image.readRasters(); <-- Is Float32Array
res.writeHead(200, {'Content-Type': 'application/octet-stream'});
var buf = Buffer.allocUnsafe( data.width * data.height );
for ( var y = 0; y < data.height; y++ )
{
for ( var x = 0; x < data.width; x++ )
{
buf.writeFloatLE(data[y*data.width+x]);
}
}
// buf = Buffer.from(data); <-- does not work
// buf = Buffer.from(data.buffer); neither
res.end(buf);
The problem is the double for loop, I do not want this. Ideally, there is no additional data copy and definitely not this very slow double for loop. Speed is pretty critical.
I am new to javascript/nodejs, but it appears that the Float32Array is multidimensional as its length returns 1, but its width and height are 1024x1024 (as expected).
The result of 'const buf = Buffer.from(data)' is a buffer with a single byte length.
Upvotes: 1
Views: 2259
Reputation: 11
A thanks, this does help. However, doing Buffer.from( Float32Array ) results in a 1byte per float buffer plus it copies the data. To get it working you also have to use this package:
let toBuffer = require("typedarray-to-buffer")
function()
{
const data = await image.readRasters({interleave:true});
const buf = toBuffer(data); <-- Now if contains 1 float, this is 4 bytes long.
}
Upvotes: 1
Reputation: 2439
I think you've misunderstood the return type of readRasters
. As far as I can tell from the docs, it's not by default a Float32Array
, but an array of arrays (one for each channel, e.g. R, G, and B).
By default, the raster is split to a separate array for each component. For an RGB image for example, we'd get three arrays, one for red, green and blue.
Try passing {interleave: true}
to readRasters
.
If we want instead all the bands interleaved in one big array, we have to pass the interleave: true option:
After that Buffer.from
aught to do the trick.
Upvotes: 0