如何用GeoPandas从内存中的Zip文件读取多个Shapefile
问题原因
Shapefile是由.shp、.shx、.dbf等多个配套文件组成的集合,仅读取单个.shp文件流无法让GeoPandas完成解析——它需要访问同组的所有辅助文件。原代码只打开了.shp文件,缺少关联的必要文件,导致格式识别失败。
解决方案
以下两种方案均无需本地下载Zip文件,直接在内存中完整读取Zip内的Shapefile:
方案一:利用GDAL虚拟文件系统直接读取远程Zip
GDAL支持通过/vsizip/路径直接识别Zip归档,结合远程URL可让GeoPandas直接读取目标Shapefile:
import json import geopandas as gpd import azure.functions as func def main(req: func.HttpRequest) -> func.HttpResponse: try: zipfile_url = "https://github.com/delatitude/spatialtestdata/raw/8c4dea03f4e325aefa523854d44a7084b6316f6e/Data.zip" # 构造GDAL可识别的虚拟Zip路径 vsizip_path = f"/vsizip/{zipfile_url}" gdfs = [] # 读取Zip内的两个Shapefile for shp_name in ["DAMSELFISH_distributions.shp", "DAMSELFISH_distributions2.shp"]: full_path = f"{vsizip_path}/{shp_name}" gdf = gpd.read_file(full_path) gdfs.append(gdf) rows, cols = gdf.shape print(f'GeoDataFrame: {rows} rows, {cols} columns\n') return func.HttpResponse(json.dumps({"Status": "success"}), status_code=200, mimetype="application/json") except Exception as e: return func.HttpResponse(f"Error: {str(e)}", status_code=500)
方案二:通过Fiona处理内存中的Zip归档
如果需要自动识别Zip内所有Shapefile(无需提前知道文件名),可使用Fiona的ZipMemoryFile加载内存中的Zip内容:
import io import json import geopandas as gpd import azure.functions as func import requests from fiona.io import ZipMemoryFile def main(req: func.HttpRequest) -> func.HttpResponse: try: zipfile_url = "https://github.com/delatitude/spatialtestdata/raw/8c4dea03f4e325aefa523854d44a7084b6316f6e/Data.zip" zip_response = requests.get(zipfile_url) zip_content = io.BytesIO(zip_response.content) gdfs = [] with ZipMemoryFile(zip_content) as zipf: # 遍历Zip内所有Shapefile图层 for layer in zipf.listlayers(): with zipf.open(layer) as collection: gdf = gpd.GeoDataFrame.from_features(collection, crs=collection.crs) gdfs.append(gdf) rows, cols = gdf.shape print(f'GeoDataFrame: {rows} rows, {cols} columns\n') return func.HttpResponse(json.dumps({"Status": "success"}), status_code=200, mimetype="application/json") except Exception as e: return func.HttpResponse(f"Error: {str(e)}", status_code=500)
关键说明
- 方案一代码简洁,依赖GDAL虚拟文件系统支持,适合已知Shapefile文件名的场景;
- 方案二可自动识别Zip内所有Shapefile图层,灵活性更高;
- 两种方案均完全在内存中处理,无需本地存储文件。
内容的提问来源于stack exchange,提问作者bytecode
相关产品推荐
相关产品推荐

