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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:34:54