Showing geotiff raster data

Hi!

I’m quite new to Streamlit but this looks to be an amazing tool to use and quickly deploy some web apps. I’m trying to assess if this solves some of my current needs, and mostly about visualizing raster data. Think any GeoTiff file like a DEM, some satellite imagery or any similar kind of image that has geolocation & dedicated metadata.

I haven’t seen example of that being done anywhere, so I was wondering if this is something that was possible and if someone could point me in that direction if so?

I understand that pydeck is one option but I’m not familiar with it, going through their doc it seems like they always use PNG files, never really geospatial raster data.

This would be of great help to build some quite complete geospatial webapps!

Thanks! :slight_smile:

Hi @MaxLenormand, welcome to the Streamlit community!

Per this answer, GeoTIFF isn’t well supported in the browser, but later in the thread a possible work-around is provided using the Pillow library:

Best,
Randy

Hi Randy, thanks for taking the time to answer!

Yes GeoTiff might be a terrible idea for browser indeed.
I saw in that thread that COGs (Cloud Optimized Geotiffs) were a the way to go, now that I think about it I should have started with this in my question!

I’ll dig down this road, if you do have any tips on that I’d be more than happy to get some directions :slight_smile: I seem to understand markdown is the way to go?

EDIT: If I understand correctly, the work around right now seems to mostly be about converting a GeoTiff to something like a PNG or a COG to display it in a static way? I was wondering if there was a way to integrate said COG (as this seems to be the best format for georaster browser manipulation) into a static map like going through Leaflet, mapbox, Folium, etc.? All I have seen so far seems to be example using vector data (polygons, points, etc.)

Thanks!

After a bit of tinkering I got something working, sortof

It’s probably super inefficient but at least it works; based on your work @randyzwitch on streamlit-folium and rasterio:

import streamlit as st
from streamlit_folium import folium_static
import folium
import rasterio
import numpy as np

# A dummy Sentinel 2 COG I had laying around
tif = "streamlit_app/WGS84_S2_image.tif"
# This is probably hugely inefficient, but it works. Opens the COG as a numpy array
src = rasterio.open(tif)
array = src.read()
bounds = src.bounds

x1,y1,x2,y2 = src.bounds
bbox = [(bounds.bottom, bounds.left), (bounds.top, bounds.right)]


st.title("Plotting maps!")
# center on Liberty Bell
m = folium.Map(location=[14.59, 120.98], zoom_start=6)

# add marker for Liberty Bell
tooltip = "Manilla city"
folium.Marker(
    [14.599512, 120.984222], popup="This is it!", tooltip=tooltip
).add_to(m)

img = folium.raster_layers.ImageOverlay(
    name="Sentinel 2",
    image=np.moveaxis(array, 0, -1),
    bounds=bbox,
    opacity=0.9,
    interactive=True,
    cross_origin=False,
    zindex=1,
)

# folium.Popup("I am an image").add_to(img)
img.add_to(m)
folium.LayerControl().add_to(m)

# call to render Folium map in Streamlit
folium_static(m)

And voila!

Now this is far from perfect of course but I think it should do the tricky for some very basic visualization at least.
I’d love to hear more about how this could be improved :slight_smile:

I would imagine:

  • No need to save the raster as COG here, all that is need is 1. the array, 2. the bounding box. Those can be saved seperately, for something that gets open in Python a lot faster than using rasterio. Maybe a PNG is the way to go then?

if this isn’t clear yet I’m in the process of learning anything having to do with frontend and webapp :smile:

1 Like

Hi @MaxLenormand . You could also take a look at GeoViews https://geoviews.org/. I believe you can use it to visualise geotiff. And you can convert to matplotib or bokeh objects.

Hi Marc,

Thanks, I’ll give that a try! Though I wonder if this will work with Streamlit? I’ll have a look, thanks for the idea!