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

使用GDAL vsimem功能时遭遇文件不存在错误的技术问询

GDAL vsimem写入后无法读取的问题解决

问题代码

calculate_boundary_weights(polys_in_area, scale=config.boundary_scale).to_file("/vsimem/weights.vrt")
gdal.Rasterize(mem_ds, "/vsimem/weights.vrt", bands=[n_bands+2], burnValues=[1], allTouched=True)

错误信息

Traceback (most recent call last):
  File "/home/songzirui/桌面/planetunet-nonorm/main.py", line 17, in <module>
    preprocessing.preprocess_all(config)
  File "/home/songzirui/桌面/planetunet-nonorm/preprocessing.py", line 233, in preprocess_all
    gdal.Rasterize(mem_ds, "/vsimem/weights.vrt", bands=[n_bands+2], burnValues=[1], allTouched=True)
  File "/home/songzirui/anaconda3/envs/tfgdal/lib/python3.8/site-packages/osgeo/gdal.py", line 1526, in Rasterize
    srcDS = OpenEx(srcDS, gdalconst.OF_VECTOR)
  File "/home/songzirui/anaconda3/envs/tfgdal/lib/python3.8/site-packages/osgeo/gdal.py", line 4720, in OpenEx
    return _gdal.OpenEx(*args, **kwargs)
RuntimeError: No such file or directory

问题原因

  1. 格式不匹配:VRT是GDAL的栅格虚拟格式,不能存储矢量数据。你用GeoPandas的to_file把矢量数据写入.vrt后缀的vsimem路径,导致生成的内容不是GDAL能识别的矢量数据源。
  2. 库支持限制:GeoPandas底层依赖Fiona,默认情况下Fiona对GDAL虚拟文件系统(vsimem)的支持需要明确指定兼容的矢量格式,直接写.vrt会导致写入失败。

解决方法

方案1:直接传递内存矢量数据集(推荐)

跳过vsimem写入,把GeoDataFrame转成GDAL内存矢量数据集,直接用于栅格化:

import geopandas as gpd
from osgeo import gdal, ogr

# 获取GeoDataFrame
gdf = calculate_boundary_weights(polys_in_area, scale=config.boundary_scale)

# 创建OGR内存数据源
driver = ogr.GetDriverByName('Memory')
mem_vec_ds = driver.CreateDataSource('temp')
# 创建图层并设置坐标系
layer = mem_vec_ds.CreateLayer('weights', srs=gdf.crs.to_wkt())

# 添加属性字段
for col in gdf.columns:
    if col != 'geometry':
        # 根据数据类型匹配OGR字段类型
        field_type = ogr.OFTString if gdf[col].dtype == object else ogr.OFTReal
        field_def = ogr.FieldDefn(col, field_type)
        layer.CreateField(field_def)

# 写入矢量要素
for _, row in gdf.iterrows():
    feature = ogr.Feature(layer.GetLayerDefn())
    # 设置属性值
    for col in gdf.columns:
        if col != 'geometry':
            feature.SetField(col, row[col])
    # 设置几何对象
    geom = ogr.CreateGeometryFromWkb(row['geometry'].wkb)
    feature.SetGeometry(geom)
    layer.CreateFeature(feature)
    feature = None  # 释放资源

# 直接用内存数据集执行栅格化
gdal.Rasterize(mem_ds, mem_vec_ds, bands=[n_bands+2], burnValues=[1], allTouched=True)

方案2:用兼容格式写入vsimem

如果一定要用vsimem,指定GeoJSON这类GDAL支持的矢量格式写入:

gdf = calculate_boundary_weights(polys_in_area, scale=config.boundary_scale)
# 写入vsimem为GeoJSON格式
gdf.to_file("/vsimem/weights.geojson", driver='GeoJSON')

# 读取vsimem中的GeoJSON执行栅格化
gdal.Rasterize(mem_ds, "/vsimem/weights.geojson", bands=[n_bands+2], burnValues=[1], allTouched=True)

关键提示

  • vsimem是GDAL专属的内存文件系统,只有GDAL生态工具能直接识别,其他库需要明确支持GDAL虚拟路径。
  • 优先使用内存数据集直接传递,避免不必要的IO操作,效率更高。

内容的提问来源于stack exchange,提问作者HEXtoBIN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:49:56