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

使用array2raster遇AttributeError: NoneType错误的技术求助

问题:合并脚本后GDAL创建栅格返回NoneType导致AttributeError

我有两个脚本:一个用水文工具提取DEM汇水深度,输出汇水/非汇水的二进制数组;另一个做像素分组标记。之后调用array2raster函数将数组转成带空间属性的标签栅格,这个函数需要传入目标数组和带空间属性的栅格。

分开运行脚本时array2raster正常工作,但合并后调用出现错误:

AttributeError: 'NoneType' object has no attribute 'SetGeoTransform'

排查情况:

  • 合并和分开脚本里的dataset(gdal.Dataset类型)、array(numpy.array类型)输入完全一致,用的也是同一个输入栅格
  • driver.Create()生成的outRaster是NoneType,单独脚本里这个方法能正常运行

关键代码片段

第一部分脚本输出代码

sink_depth = wbt.depth_in_sink(
                        input_path,
                        output_path,
                        zero_background= True
)

读取输出的代码

spatial_image = gdal.Open(output_path)

数组转栅格核心函数及调用

def array2raster(newRasterfn, dataset, array, dtype):
    """
    从numpy.array保存GTiff文件
    输入:
        newRasterfn: 保存文件名
        dataset : 带空间信息的原始tif文件
        array : numpy.array 
        dtype: Byte 或 Float32
    """
    cols = array.shape[1]
    rows = array.shape[0]
    originX, pixelWidth, b, originY, d, pixelHeight = dataset.GetGeoTransform() 

    driver = gdal.GetDriverByName('GTiff')

    # 设置保存的数据类型
    GDT_dtype = gdal.GDT_Unknown
    if dtype == "Byte": 
        GDT_dtype = gdal.GDT_Byte
    elif dtype == "Float32":
        GDT_dtype = gdal.GDT_Float32
    else:
        print("不支持的数据类型。")

    # 设置波段数
    if array.ndim == 2:
        band_num = 1
    else:
        band_num = array.shape[2]

    outRaster = driver.Create(newRasterfn, cols, rows, band_num, GDT_dtype)
    outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))

    # 遍历所有波段
    for b in range(band_num):
        outband = outRaster.GetRasterBand(b + 1)
        # 将数组数据写入波段
        if band_num == 1:
            outband.WriteArray(array)
        else:
            outband.WriteArray(array[:,:,b])

    # 从输入tif设置投影信息
    prj=dataset.GetProjection()
    outRasterSRS = osr.SpatialReference(wkt=prj)
    outRaster.SetProjection(outRasterSRS.ExportToWkt())
    outband.FlushCache()
    print(prj)


array2raster("tif_folder/out_raster.tif", spatial_image, filtered_labels, "Byte")

解决建议

  • 检查输出路径的权限与合法性
    确认newRasterfn指定的目录(比如tif_folder)是否存在,GDAL不会自动创建目录;同时检查当前用户对目标路径是否有写入权限,避免写入受保护文件夹或无权限路径。

  • 验证GDAL驱动加载状态
    合并脚本后可能存在驱动加载异常,在调用Create()前添加验证:

    driver = gdal.GetDriverByName('GTiff')
    if not driver:
        raise RuntimeError("无法加载GTiff驱动")
    
  • 核对数组与输入栅格的尺寸匹配
    检查filtered_labels的行列数是否和spatial_image完全一致:对比array.shape[0]/array.shape[1]和dataset.RasterYSize/dataset.RasterXSize,尺寸不匹配会导致Create()失败。

  • 释放GDAL资源
    第一部分脚本生成的文件可能被wbt工具占用,导致后续操作异常。可以在gdal.Open()后确保wbt操作已完成,或显式关闭不再使用的数据集:

    spatial_image = gdal.Open(output_path)
    # 使用完成后关闭
    # spatial_image = None
    
  • 添加错误捕获
    在driver.Create()后立即检查返回值,输出详细错误信息定位问题:

    outRaster = driver.Create(newRasterfn, cols, rows, band_num, GDT_dtype)
    if not outRaster:
        print(f"创建栅格失败:路径{newRasterfn},尺寸{rows}x{cols},波段数{band_num},数据类型{GDT_dtype}")
        return
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:53:23