使用Streamlit file_uploader读取.shp文件触发Fiona DriverError
解决Streamlit上传Shapefile并通过Geopandas读取的错误问题
问题分析
- 语法错误:代码中
df.append(gpd.read_file(d),encoding='utf-8')参数位置错误,encoding='utf-8'应作为gpd.read_file()的参数,而非append()的第二个参数。 - 核心格式问题:Shapefile是由
.shp、.shx、.dbf、.prj等多个关联文件组成的集合,单独上传.shp文件时,Geopandas依赖的Fiona库无法找到必要配套文件,导致识别失败;同时旧版本Geopandas(0.11.1)对直接读取Streamlit上传的BytesIO对象支持不佳。
解决方案
方案1:上传包含所有Shapefile文件的ZIP压缩包(推荐)
将所有Shapefile关联文件打包成ZIP,上传后读取压缩包内的内容:
import streamlit as st import geopandas as gpd import zipfile import io # 上传ZIP压缩包(需包含所有Shapefile关联文件) uploaded_zip = st.file_uploader("上传包含Shapefile的ZIP压缩包", type="zip") if uploaded_zip is not None: with zipfile.ZipFile(uploaded_zip, 'r') as zip_ref: # 定位压缩包中的.shp文件 shp_filename = next(f for f in zip_ref.namelist() if f.endswith('.shp')) # 读取Shapefile df = gpd.read_file(zip_ref.open(shp_filename), encoding='utf-8') # 展示数据 st.dataframe(df)
方案2:上传所有Shapefile关联文件并临时保存读取
如果需要单独上传所有关联文件,可通过临时目录保存后读取:
import streamlit as st import geopandas as gpd import os from tempfile import TemporaryDirectory # 允许上传多个文件,需包含所有Shapefile关联文件 uploaded_files = st.file_uploader("上传所有Shapefile相关文件(.shp/.shx/.dbf等)", accept_multiple_files=True) if uploaded_files: with TemporaryDirectory() as temp_dir: # 将上传的文件保存到临时目录 for file in uploaded_files: temp_file_path = os.path.join(temp_dir, file.name) with open(temp_file_path, 'wb') as f: f.write(file.getbuffer()) # 找到临时目录中的.shp文件 shp_file_path = next(os.path.join(temp_dir, f.name) for f in uploaded_files if f.name.endswith('.shp')) # 读取Shapefile df = gpd.read_file(shp_file_path, encoding='utf-8') # 展示数据 st.dataframe(df)
额外注意事项
- 确保上传的ZIP或文件集合中包含所有Shapefile必需的关联文件,缺失任何一个都会导致读取失败。
- 你的Geopandas版本(0.11.1)较旧,后续升级到0.12+版本后,对BytesIO对象的支持会有所改善,但Shapefile多文件依赖的问题依然存在。
内容的提问来源于stack exchange,提问作者JaeEun Yoo
相关产品推荐
相关产品推荐

