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

如何通过VSIMEM实现FlatGeoBuf转GeoJSON(无磁盘写入)

FlatGeoBuf字节转GeoJSON(无磁盘写入)问题及解决

问题背景与初始尝试

我需要将从HTTP请求中读取的FlatGeoBuf字节数据转换为GeoJSON文件。已知可将.fgb文件存盘后用OGR打开,再通过已有函数导出GeoJSON,但希望完全避免磁盘写入。尝试使用GDAL的VSIMEM内存文件机制时遇到问题,初始代码如下:

def write_vsimem(mem_path: str, data: bytes) -> None:
    vsi_file = gdal.VSIFOpenL(mem_path, "w")
    size = len(data)
    try:
        gdal.VSIFWriteL(data, 1, size, vsi_file)
        if gdal.VSIFCloseL(vsi_file) != 0:
            raise RuntimeError(
                f"Failed to close VSIMEM file '{mem_path}': {gdal.GetLastErrorMsg()}"
            )
    except Exception as e:
        raise RuntimeError(f"Error writing to VSIMEM file '{mem_path}': {e}") from e

def convert_flatgeobuf_to_geojson(flatgeobuf_data: bytes, name: str) -> bytes:
    driver = ogr.GetDriverByName("FlatGeobuf")
    mem_path = f"/vsimem/{name}.fgb"
    fgb_data = driver.CreateDataSource(mem_path)
    if not fgb_data:
        raise RuntimeError(f"Failed to open FlatGeobuf file '{name}' with VSIMEM.")
    write_vsimem(mem_path, flatgeobuf_data)
    # Check if the layer exists
    if fgb_data.GetLayerCount() != 1:
        raise ValueError(
            f"Expected 1 layer in FlatGeobuf file '{name}', found {fgb_data.GetLayerCount()} layers."
        )
    # Get the layer and extract geojson
    layer = fgb_data.GetLayer(0)
    return layer_to_geojson(layer=layer)

运行时日志显示write_vsimem执行正常:

Converting FlatGeoBuf of size: 5570849
Write VSIMEM: 5570816

但随后报错OGR数据源为空:

Failed to hydrate data: Expected 1 layer in FlatGeobuf file 'my_layer', found 0 layers.

需要明确:

  • 无磁盘写入转换的目标是否可实现?
  • 初始代码的错误点在哪里?
  • 是否必须通过磁盘写入完成转换?

修正后的实现方案

根据提示,正确的实现方式是先将字节数据写入VSIMEM内存空间(无需调用CreateDataSource创建空数据源),再直接从内存路径打开数据源。修正后的代码如下:

def convert_flatgeobuf_to_geojson(flatgeobuf_data: bytes, name: str) -> bytes:
    mem_path = f"/vsimem/{name}.fgb"
    write_vsimem(mem_path, flatgeobuf_data)
    fgb_data = ogr.Open(mem_path)
    if not fgb_data:
        raise RuntimeError(f"Failed to open FlatGeobuf file '{name}' with VSIMEM.")
    # Check if the layer exists
    if fgb_data.GetLayerCount() != 1:
        raise ValueError(
            f"Expected 1 layer in FlatGeobuf file '{name}', found {fgb_data.GetLayerCount()} layers."
        )
    # Get the layer and extract geojson
    layer = fgb_data.GetLayer(0)
    return layer_to_geojson(layer=layer, layer_name=name)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 06:33:22