geotiffjs / geotiff.js

geotiff.js is a small library to parse TIFF files for visualization or analysis. It is written in pure JavaScript, and is usable in both the browser and node.js applications.
https://geotiffjs.github.io/
MIT License
845 stars 175 forks source link

using geotiff.js with react-native #411

Open gabebautista11 opened 8 months ago

gabebautista11 commented 8 months ago

Im getting the error:

The package at "node_modules/geotiff/dist-node/source/client/http.js" attempted to import the Node standard library module "http". It failed because the native React runtime does not include the Node standard library.

because rn does not have node is there a way to exclude the imports that need node like fs / http without breaking the code? I plan on just using read the fromArrayBuffer and read the data from a Buffer instead of a file or external source. Is there a way to do this with little code change or anyone know of a tiff parsing rn library I can use? I really do not want to write my own tiff parser and spend a lot of time when geotiff.js does everything I need to do.

constantinius commented 8 months ago

Hey @gabebautista11

geotiff.js allows to use any kind of source, and there are alternatives for nodes http API, like fetch or XMLHttpRequest. Additional ones can be added. So you don't have to use fromArrayBuffer, if you are opening large datasets.

So does you error happen at build time? Then you would likely need to adjust your build settings, so that the import of the not supported module does not break it.

By default, the fetch based source will be tried first, which seems to be supported by React Native, so you should be good to go.

Let me know if that helped.

gabebautista11 commented 8 months ago

It's a runtime / buildtime issue (I think it builds everything but when it attempts to load the view it errors). Im trying to read from a ArrayBuffer because I use axios to get a tiff file from my backend and I download it as an ArrayBuffer.

The error Im getting is at run time.

I think what you are saying for a build setting to ignore a failed import will work since I dont use http, fs, or the other things react-native does not support. Im just trying to figure out how to do that.

Screenshot 2023-11-21 at 9 52 36 AM
gabebautista11 commented 8 months ago

Im also looking into the geotiff npm package and see theire is a dist-modules. Can I somehow use this instead. The default import of import {fromArrayBuffer} from "geotiff" uses the dist-node code

gabebautista11 commented 8 months ago

@constantinius I just did a node test

async function geoTiffTest() { let path = "UAC/salt-lake"; let fileName = salt-lake_elevation_aspect_slope.tif; let req = await axios.get(https:/storage/${path}/${fileName}, { headers: { AccessKey: "key" }, responseType: "arraybuffer", // Use "arraybuffer" instead of "image/tiff" }); let buffer = req.data;

let tiff = await fromArrayBuffer(buffer.buffer); let img = await tiff.getImage(); const data = await img.readRasters(); console.log(data[0]); }

So my approach on react native is using the correct code its just the node thing.

gabebautista11 commented 8 months ago

when running this code Im getting the error

geoTiffTest();

async function geoTiffTest() {
  let path = "UAC/salt-lake";
  let fileName = `salt-lake_elevation_aspect_slope.tif`;
  let req = await axios.get(`https://path/${path}/${fileName}`, {
    headers: { AccessKey: "key" },
    responseType: "arraybuffer", // Use "arraybuffer" instead of "image/tiff"
  });
  let buffer = req.data;
  console.log("got buffer");
  let tiff = new geotiff(buffer.buffer);
  //let tiff = await fromArrayBuffer(buffer.buffer);
  console.log(tiff);
  //let img = await tiff.getImage();
  let data = await tiff.readRasters();
  //const data = await img.readRasters();
  console.log(data[0]);
}

file:///Users/gabebautista/Documents/School/Capstone/Test_Folder/node_modules/geotiff/dist-module/geotiff.js:340 (await this.source.fetch([{ ^

TypeError: this.source.fetch is not a function

gabebautista11 commented 8 months ago

ok @constantinius So I implemented some of geotiff into my react Native app and am now getting this error

 LOG  {"bigTiff": false, "cache": false, "firstIFDOffset": 0, "ghostValues": null, "ifdRequests": [], "littleEndian": true, "source": []}
 WARN  Possible Unhandled Promise Rejection (id: 2):
TypeError: this.source.fetch is not a function (it is undefined)
TypeError: this.source.fetch is not a function (it is undefined)

The code that goes with this is, I read a string from the local file system that Is encoded in UTF-8. This error happens on the const image = await tiff.getImage()

async function quickTest(regionName: string) {
  let fileData = await readFromFileSystem(filePaths.Overlays, `${regionName}.tiff`, EncodingType.UTF8);
  let buf = Buffer.from(fileData, "utf-8");

  const tiff = new GEOTIFF(buf.buffer, true, false, 0);
  console.log(tiff);

  const image = await tiff.getImage();
  const raster = await image.readRasters();
  console.log(raster[0]);
}
Screenshot 2023-11-22 at 9 59 58 AM

This is the code that is throwing the error, I think