使用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
问题原因
- 格式不匹配:VRT是GDAL的栅格虚拟格式,不能存储矢量数据。你用GeoPandas的
to_file把矢量数据写入.vrt后缀的vsimem路径,导致生成的内容不是GDAL能识别的矢量数据源。 - 库支持限制: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
相关产品推荐
相关产品推荐

