Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GeoTIFF loader #1280

Open
zakjan opened this issue Mar 18, 2021 · 9 comments
Open

GeoTIFF loader #1280

zakjan opened this issue Mar 18, 2021 · 9 comments

Comments

@zakjan
Copy link

zakjan commented Mar 18, 2021

Target Use case

Loading GeoTIFF raster data (including float bands) and rendering them with deck.gl-raster

Proposed feature

@loaders.gl/geotiff package using geotiff.js inside

@ibgreen
Copy link
Collaborator

ibgreen commented Mar 18, 2021

@zakjan this could be a nice addition. If you are interested in working on this happy to sync on the best approach.

@im28
Copy link

im28 commented Aug 25, 2022

This seems to be solved by #1469 & #1448
Unfortunately, there is no proper documentation on the website.

@giovannicimolin
Copy link
Collaborator

Hey folks,

I'm trying to display a GeoTIFF orthophoto on a deck.gl map but I don't have a good idea of where to start. There's not a lot of documentation on the geotiff module and I'm not familiar with how loaders fully work.

Is it currently possible to use the GeoTIFF module to load aerial images into a BitmapLayer?
If not, can you point me to some resources on things missing for this to happen? (I can try to hack together a loader for this).
If yes, can you give me a barebones example or simple explanation? (I can contribute documentation for it).

@ibgreen
Copy link
Collaborator

ibgreen commented Nov 29, 2023

The viv team (who do molecular biology visualizations using deck.gl, see the deck.gl showcases page) have used OME TIFF with deck.gl to great effect. They contributed their loader to loaders.gl but unfortunately there has not been sufficient time to get everything working with GeoTIFFs so it remains an undocumented module.

I saw a recent post from @kylebarron around the topic so maybe there is something in the works.

If you are serious about getting this working in a reusable way I can provide more support.

@kylebarron
Copy link
Collaborator

I don't have any plans myself to work on/improve a GeoTIFF loader in JS. You may want to read the documentation for the underlying geotiff.js as well

@ibgreen
Copy link
Collaborator

ibgreen commented Nov 29, 2023

The existing loaders.gl code is here: https://github.com/visgl/loaders.gl/tree/master/modules/geotiff

@giovannicimolin
Copy link
Collaborator

giovannicimolin commented Dec 11, 2023

@ibgreen @kylebarron After spending a few hours banging my head on the keyboard I've finally managed to display a simple GeoTIFF orthophoto as a Deck.GL layer using BitmapLayer.

Most of the time, it was a learning experience and I ended up trying many things until I found a solution that worked.
A few notes about it:

  • The geospatial information from the TIFF is not used since I already have that information coming my API. It can be retrieved from inside the loader after geotiff.js loads the file (example), but I don't know how to push that into the BitmapLayer from there.
  • Only retrieves the first image inside a TIFF.
  • Assumes the image is RGB and relies on geotiff.js mechanism to decode it properly.
  • imageData.data.set(new Uint8ClampedArray(rgbData as unknown as Uint8Array)); I don't like this but these were some acrobatics I had to do in order for things to work.

Here's how I did it:

import { fromArrayBuffer  } from "geotiff";

const loadGeoTiff = async (data: ArrayBuffer) => {
    // Load using Geotiff.js
    const tiff = await fromArrayBuffer(data);

    // Assumes we only have one image inside TIFF
    const image = await tiff.getImage();

    // Read image and size
    const rgbData = await image.readRGB({enableAlpha: true});
    const width = image.getWidth();
    const height = image.getHeight();

    // Create a new ImageData object
    const imageData = new ImageData(width, height);
    imageData.data.set(new Uint8ClampedArray(rgbData as unknown as Uint8Array));
    return imageData;
}


export const GeoTiffLoader = {
    id: "GeoTIFF",
    name: 'GeoTIFF',
    module: '',
    version: '1',
    options: {},
    mimeTypes: ["image/tiff", "image/geotiff"],
    extensions: ['geotiff', 'tiff'],
    parse: loadGeoTiff,
};

Let me know if this is a good (and acceptable) starting point for a contribution.
I'm happy to help in any way I can. 😁

@ibgreen
Copy link
Collaborator

ibgreen commented Dec 11, 2023

@giovannicimolin I think this would be a very nice contribution. For full control we need to build something like a GeoTIFFSource that lets the application load individual bands etc. But in parallel it is nice to offer an easy-to-use GeoTIFFLoader and the above looks like a great start.

We would need an (ideally small) geotiff sample file (either in the test/data directory or contributed to deck.gl-data repo) and a test case that loaded it successfully.

For longer term:

  • We do need to include the geospatial information, that is kind of the whole point. I would define a new return type:
type GeoReferencedImage  = {
  crs: ...,
  image: Image...;
};

- We would want to add an example to loaders.gl/examples that shows it working with deck.gl

@giovannicimolin
Copy link
Collaborator

@ibgreen Started a WIP PR here: #2839

I added a few TODO items and will work on making it more complete in the next few weeks.
Also, I don't know exactly how the split the code into the already existing folders, so comments are welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants