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

如何解决Streamlit中下载Google Earth Engine影像的报错问题

解决GEE影像通过Streamlit下载按钮导出GeoTIFF的报错问题

问题背景

尝试从Google Earth Engine下载GeoTiff格式的火灾数据,在实现Streamlit下载按钮时触发报错:

Invalid binary data format: <class ‘ee.image.Image’>

原始代码

import datetime
import ee
import streamlit as st
import geemap.foliumap as geemap
import os
import folium

Map = geemap.Map(locate_control=True)

col1, col2, col3, col4, col5= st.columns([1, 1, 1, 2, 2])
with col1:
    longitude = st.number_input("Longitude", 102, 110, 105)
with col2:
    latitude = st.number_input("Latitude", 10, 16, 12)
with col3:
    zoom = st.number_input("Zoom", 0, 20, 7)

Map.setCenter(longitude, latitude, zoom)

with col4:
    start = st.date_input("Start Date for Fire Forest: YYYY/MM/DD", datetime.date(2021, 1, 1))
with col5:
    end = st.date_input("End Date for Fire Forest: YYYY/MM/DD", datetime.date(2021, 1, 3))

start_date = start.strftime("%Y-%m-%d")
end_date = end.strftime("%Y-%m-%d")

countries=ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017")
country = countries.filter(ee.Filter.eq('country_na', 'Cambodia'));
esa = ee.ImageCollection("FIRMS").select('T21').filterBounds(country).filterDate(start_date,end_date).mosaic().clip(country)
esa_vis = {"min": 325,"max": 400,"palette": ['red', 'orange', 'yellow'],}
Map.addLayer(country,{}, name ="Cambodia Global Boundary")
Map.addLayer(esa, esa_vis, 'fire')

#To test export image
out_dir = os.path.join(os.path.expanduser('~'), 'Downloads')
filename = os.path.join(out_dir, 'fire.tiff')
# image = esa.clip(country).unmask()
date=(start_date,end_date)
geemap.ee_export_image(esa, filename=filename, scale=30, region=country, file_per_band=False)
st.download_button('Download fire Output (.tiff)',
                esa,
                file_name = "fire.tiff",
                mime= "image/GeoTIFF")

#Add legend
labels = ['Fire Detection']
colors = ['#FF0000']
Map.add_legend(
            title="Legend",
            labels=labels,
            colors=colors)

#Press on map and show lat and lng
Map.add_child(folium.LatLngPopup())

Map.to_streamlit(height=550)

报错原因

st.download_button的data参数要求传入本地二进制数据/字节流,但代码中直接传入了GEE云端的ee.Image对象(esa),这个对象只是云端影像的引用,并非可直接下载的本地数据,因此触发格式错误。

解决方案

先将GEE影像下载到本地临时文件,再读取文件的二进制内容传给下载按钮。修改后的完整代码如下:

修改后的完整代码

import datetime
import ee
import streamlit as st
import geemap.foliumap as geemap
import os
import folium

# 初始化GEE授权
ee.Initialize()

Map = geemap.Map(locate_control=True)

col1, col2, col3, col4, col5= st.columns([1, 1, 1, 2, 2])
with col1:
    longitude = st.number_input("Longitude", 102, 110, 105)
with col2:
    latitude = st.number_input("Latitude", 10, 16, 12)
with col3:
    zoom = st.number_input("Zoom", 0, 20, 7)

Map.setCenter(longitude, latitude, zoom)

with col4:
    start = st.date_input("Start Date for Fire Forest: YYYY/MM/DD", datetime.date(2021, 1, 1))
with col5:
    end = st.date_input("End Date for Fire Forest: YYYY/MM/DD", datetime.date(2021, 1, 3))

start_date = start.strftime("%Y-%m-%d")
end_date = end.strftime("%Y-%m-%d")

countries=ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017")
country = countries.filter(ee.Filter.eq('country_na', 'Cambodia'));
esa = ee.ImageCollection("FIRMS").select('T21').filterBounds(country).filterDate(start_date,end_date).mosaic().clip(country)
esa_vis = {"min": 325,"max": 400,"palette": ['red', 'orange', 'yellow'],}
Map.addLayer(country,{}, name ="Cambodia Global Boundary")
Map.addLayer(esa, esa_vis, 'fire')

# 将GEE影像下载到本地指定路径
out_dir = os.path.join(os.path.expanduser('~'), 'Downloads')
filename = os.path.join(out_dir, 'fire.tiff')
geemap.ee_export_image(esa, filename=filename, scale=30, region=country, file_per_band=False)

# 读取本地文件二进制数据,传给下载按钮
if os.path.exists(filename):
    with open(filename, "rb") as f:
        tiff_data = f.read()
    st.download_button(
        label='Download fire Output (.tiff)',
        data=tiff_data,
        file_name="fire.tiff",
        mime="image/GeoTIFF"
    )
else:
    st.error("影像下载失败,请检查GEE授权或网络连接")

# 添加图例
labels = ['Fire Detection']
colors = ['#FF0000']
Map.add_legend(
            title="Legend",
            labels=labels,
            colors=colors)

# 点击地图显示经纬度
Map.add_child(folium.LatLngPopup())

Map.to_streamlit(height=550)

关键修改点

  1. 新增ee.Initialize()确保GEE授权完成,避免下载失败
  2. 保留geemap.ee_export_image完成云端影像到本地的下载
  3. 通过open(filename, "rb")读取本地GeoTIFF的二进制数据
  4. 将二进制数据iff_data作为st.download_button的data参数传入

大文件替代方案

如果处理超大影像,推荐直接生成GEE官方下载链接,避免本地存储压力:

# 生成GEE原生下载链接
download_url = esa.getDownloadURL({
    'scale': 30,
    'region': country.geometry(),
    'filePerBand': False
})

# 在Streamlit中显示下载链接
st.markdown(f"[点击下载火灾数据]({download_url})", unsafe_allow_html=True)

内容的提问来源于stack exchange,提问作者Remote Sensing and Mapping

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:31:25