You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用folium.raster_layers.ImageOverlay()时地图图像不显示的问题

Folium叠加GeoTIFF仅显示边界框无图像的问题排查与解决

我尝试用folium将GeoTIFF叠加到底图上,代码如下:

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

但输出仅显示边界框细线,内部无图像。已尝试:

  • 改用PNG/JPG替代GeoTIFF,结果相同
  • 查看栅格值范围为0至311000
  • 确认CRS为EPSG:3875(注:实际Web Mercator标准代号为EPSG:3857,疑似笔误)

系统信息:Windows 10、folium v0.14.0、rasterio v1.2.10


问题根源

  1. folium.ImageOverlay不支持直接读取GeoTIFF路径:它仅接受图像格式数据(numpy数组、本地可访问的图像文件路径/URL),GeoTIFF是栅格数据格式,无法直接被识别为图像。
  2. 栅格值范围超出图像像素有效范围:你的栅格值是0-311000,而图像像素的有效显示范围是0-255,未做归一化处理会导致图像显示异常(全黑或无内容)。
  3. 手动设置的bounds与实际栅格范围不匹配:手动输入的边界框可能和GeoTIFF的真实范围存在偏差,导致图像无法正确映射到底图。

修复步骤与代码

核心处理逻辑

  1. 归一化栅格值到0-255的图像像素范围
  2. 从GeoTIFF读取数据并转换为folium可识别的numpy数组格式
  3. 自动获取栅格边界并转换为folium底图使用的WGS84(EPSG:4326)坐标系

修改后的代码:

import folium
import rasterio
import numpy as np
from rasterio.warp import transform_bounds

imgfile = r"path\to\geotiff"

# 读取并预处理栅格数据
with rasterio.open(imgfile) as dobj:
    # 确认坐标系为Web Mercator(EPSG:3857),若不是需先转换
    assert dobj.crs == "EPSG:3857", "GeoTIFF需为EPSG:3857坐标系"
    
    # 读取第一波段数据
    data = dobj.read(1)
    
    # 归一化栅格值到0-255范围
    data_min, data_max = np.min(data), np.max(data)
    normalized_data = ((data - data_min) / (data_max - data_min)) * 255
    normalized_data = normalized_data.astype(np.uint8)
    
    # 将栅格边界从EPSG:3857转换为EPSG:4326(folium使用的坐标系)
    bounds_4326 = transform_bounds(
        dobj.crs, "EPSG:4326",
        dobj.bounds.left, dobj.bounds.bottom,
        dobj.bounds.right, dobj.bounds.top
    )
    # 转换为folium要求的bounds格式:[[south, west], [north, east]]
    folium_bounds = [[bounds_4326[1], bounds_4326[0]], [bounds_4326[3], bounds_4326[2]]]

# 创建地图
m = folium.Map(location=[38.57456919518837, -121.48348853857401], zoom_start=9)

# 添加处理后的图像叠加层
img = folium.raster_layers.ImageOverlay(
    image=normalized_data,
    name="GeoTIFF Overlay",
    bounds=folium_bounds,
    opacity=0.7,  # 降低透明度方便查看底图
    interactive=True,
    zindex=1
)

folium.Popup("归一化后的栅格图像").add_to(img)
img.add_to(m)
folium.LayerControl().add_to(m)

m

额外说明

  • 若GeoTIFF是多波段(如RGB),需读取多个波段并组合成(height, width, 3)格式的numpy数组。
  • 若原始GeoTIFF坐标系不是EPSG:3857,需先用rasterio.warp.reproject将数据转换为Web Mercator坐标系后再处理。
  • 转换为PNG/JPG格式时,同样需要先归一化数值范围,否则图像会因超出像素范围而显示异常。

内容的提问来源于stack exchange,提问作者Darren C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:33:25