Image not appearing over map when using folium.raster_layers.ImageOverlay()

90 Views Asked by At

I'm trying to overlay a .geotiff file on a basemap using folium. Here is my code:

import folium
import rasterio

imgfile = r"path\to\geotiff"
with rasterio.open(imgfile) as dobj:
    print(dobj.crs)

m = folium.Map(location=[38.57456919518837, -121.48348853857401],
               zoom_start = 9)

img = folium.raster_layers.ImageOverlay(
    image=imgfile,
    name="I am a jpeg",
    bounds=[[38.2, -122.3], [39.35, -120]],
    opacity=1,
    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)

m

However, this is what the output looks like: You see the thin line representing the bounding box, but nothing inside: enter image description here

Here's what I've explored:

  • Tried loading as PNG and JPG instead of GEOTIFF. Same result.
  • Used dataset.read() to get a sense of what the raster values are. They range from 0 up to 311,000
  • Confirmed that the CRS is 3875 (web mercator)

Any idea what's going on?

Software/system info:

  • Windows 10 OS
  • folium v0.14.0
  • rasterio v1.2.10
1

There are 1 best solutions below

0
Darren C. On

Solved!

It turns out that I need to read the tiff into a numpy array format using the .read() method. Here's the full answer:

import folium
import rasterio
from rasterio import warp
import numpy as np
from matplotlib import cm

# normalize to 0-100 scale for color ramp purposes
raster_in = r'/path/to/example.geotiff'

dataset= rasterio.open(raster_in, 'r') # open raster file

rasdata = dataset.read()[0] # read raster vals into numpy array

rasdata_normed = rasdata/rasdata.max() * 10 # normalization to help with color gradient

# set bounds using wgs84 projection (geotiff is in web mercator)
dest_crs = 'EPSG:4326'
left, bottom, right, top = [i for i in dataset.bounds]
bounds_4326 = warp.transform_bounds(src_crs=dataset.crs, dst_crs=dest_crs, left=left, 
                               bottom=bottom, right=right, top=top)

# map it out!
m = folium.Map([38, -122], zoom_start=8)
folium.raster_layers.ImageOverlay(
    image=rasdata_normed,
    name='sample map',
    opacity=0.5,
    bounds=[[bounds_4326[1], bounds_4326[0]], [bounds_4326[3], bounds_4326[2]]],
    interactive=False,
    cross_origin=False,
    zindex=1,
    colormap=cm.get_cmap('Blues', 10)
).add_to(m)
folium.LayerControl().add_to(m)

m