跳到主要内容

栅格计算器

栅格计算器用于对一个或多个栅格数据进行像元级(逐像元)计算。你可以用表达式对输入栅格的像元值执行数学、比较、逻辑、条件运算,生成新的栅格结果。计算基于 Python + NumPy 的数组运算模型,所有运算均按像元并行执行。

image-20260129154812751

主要能力

  • 多栅格/多波段参与同一表达式计算
  • 支持单语句与多语句(代码块)两种模式
  • 内置运算符与常用 NumPy 函数(算数/三角/逻辑/统计等)
  • 自动对齐:当输入栅格空间参考或网格不一致时自动重采样并对齐
  • NoData 与数值类型可控:默认输出为 双精度浮点小数,NoData 默认取当前类型可表示的最大值

使用方式

典型流程:

  1. 添加一个或多个输入栅格
  2. 在表达式区域输入“单语句”或“代码块”
  3. 设定输出栅格路径与通用输出参数(像素类型、NoData、压缩、坐标系等)
  4. 运行生成

栅格引用与波段引用

在栅格计算器中,表达式里的“变量”可以指向某个输入栅格或其指定波段。

  1. 引用范围
  • 栅格引用仅在当前一次工具运行中有效
  • 名称区分大小写
  1. 栅格引用(Raster Name)
  • 直接使用输入列表中的“文件引用名称”(通常就是文件名)来引用栅格

示例(以文件名作为引用):

result = T50SKH_B02_100m.tif + T50SKH_B03_100m.tif
  1. 波段引用(RasterName.bandN)
  • 多波段栅格可用 栅格名.bandN 引用指定波段,N 从 1 开始
  • 单波段栅格中,aa.band1 等价

示例:

nd = 空飞-多波段栅格-100m.tif.band4 - 空飞-多波段栅格-100m.tif.band2

非法示例:

c = a.band0
c = band1

语法规则

单语句模式

必须写成赋值形式:输出变量 = 表达式

result = dem.tif * 0.001

由于界面中,默认会使用输出文件=,因此用户在输入框中直接输入表达式即可。

image-20260129160557734

代码块(多语句)模式

  • 允许定义临时变量和中间结果
  • 至少有一句是赋值形式,否则无法输出
  • 若存在多句赋值表达式,以最后一句赋值结果作为最终输出
  • 变量命名,代码块中的变量必须是合法标识符(建议:小写字母 + 数字 + 下划线,且不以数字开头)
  • 代码块中可以重复利用中间变量,让复杂逻辑更清晰。
# 定义掩膜
m1 = (dem.tif >= 0) & (dem.tif <= 1610)
m2 = (dem.tif > 1610) & (dem.tif <= 2415)
m3 = (dem.tif > 2415) & (dem.tif <= 3468)
m4 = (dem.tif > 3468)

# 分类
result = (m1 * 1) + (m2 * 2) + (m3 * 3) + (m4 * 4)

支持的运算符

算术运算符

算术运算符名称含义示例说明
+加法相加A + B像元值相加
-减法相减A - B像元值相减
*乘法相乘A * B像元值相乘
/除法真除法A / B结果为浮点数
//整除向下取整除法A // BGIS 中常用于分级
%取模余数A % 5周期/分类编码
**幂运算A ** 2平方、指数模型

比较运算符

运算符名称含义示例GIS 含义
==等于是否相等A == B像元值是否相同
!=不等于是否不相等A != 0非 NoData
>大于是否大于A > 10阈值判断
<小于是否小于A < 0异常值判断
>=大于等于A >= 100下限约束
<=小于等于A <= 15上限约束

比较结果为逐像元布尔结果,可继续参与后续计算(布尔值在算术中会自动转为 0/1)。

# 布尔值参与算术:满足条件为 1,不满足为 0
result = (dem.tif > 1000) * 1

逻辑运算符(逐像元)

栅格计算器采用 Python + NumPy 语法模型。对于栅格数组的逻辑判断,不支持 Python 原生的 and / or / not 逻辑运算符, 请使用 NumPy 的逐像元逻辑运算方式:

  • 使用位运算符 &|~ 表示逻辑 AND / OR / NOT
  • 运算符作用于每一个像元(element-wise)
  • 条件表达式必须使用括号明确优先级

逻辑运算符用于组合多个条件:

运算符名称含义示例说明对应函数
&逻辑与同时为真(a > 0) & (a < 10)逐像元逻辑与logical_and(a, b)
|逻辑或任一为真(a > 0) | (a < 10)逐像元逻辑或logical_or(a, b)
~逻辑非取反~(a > 0)逐像元逻辑非logical_not(a)
逐元素异或逐元素异或logical_xor(a, b)

注意:组合条件时必须加括号。

risk = (slope.tif > 15) * 0.4 + (rain.tif > 100) * 0.6
mask = (a.tif > 0) & (a.tif < 10)

运算优先级(从高到低)

工具遵循常见的 Python/数学优先级。编写复杂条件时建议始终用括号明确意图:

  1. ()
  2. **
  3. 一元 +x -x ~x
  4. * / // %
  5. + -
  6. 位移 << >>
  7. & ^ |
  8. 比较 == != < <= > >=
  9. 赋值 =

NoData 与数值类型规则

  • 任何操作数中含有 NoData 时,结果为 NoData
  • 输出数值类型默认使用 double(Float64)以尽量避免精度损失
  • NoData 默认使用“当前输出类型可表示的最大值”

建议:

  • 参与运算的栅格若 NoData 口径不一致,先使用无效值相关工具统一 NoData,可减少意外传播
  • 如果希望“缺失当作 0”或“缺失当作常量”,需显式写出条件逻辑(通常用 where 实现)

空间一致性与自动重采样

多个栅格必须在空间上完全一致才能逐像元计算,包括:CRS、像元大小、网格对齐、范围(Extent)。

当输入栅格不一致时,工具会在计算前自动对齐,核心原则:

  • 以“输入列表中的第一个栅格”作为空间基准(不是表达式里出现的第一个)
  • 其它栅格会自动重投影/重采样到基准栅格网格
  • 内部重采样采用 GDAL 机制,默认使用最近邻

空间对齐的判断

栅格计算器(本工具)
└── 自动判断是否需要重采样
└── 调用 Raster.resample_gdal_by_raster()
└── GDAL Warp / Reproject / Resample
└── GDAL 内置插值算法(最近邻)

补充说明:

  • 对齐后的运算仅在基准栅格网格上进行;超出基准范围的区域将以 NoData 填充
  • 若输入栅格分辨率不同,会以基准栅格的像元大小为准

常见用例

NDVI(单波段)

ndvi = (T50SKH_B08_100m.tif - T50SKH_B04_100m.tif) / (T50SKH_B08_100m.tif + T50SKH_B04_100m.tif)

多波段加权

result = 空飞-多波段栅格-100m.tif.band1 * 0.5 + 空飞-多波段栅格-100m.tif.band2 * 0.5

多波段累加(Sigma)

result = Sigma([空飞-多波段栅格-100m.tif.band1, 空飞-多波段栅格-100m.tif.band2, 空飞-多波段栅格-100m.tif.band3])

三个栅格求最大值(嵌套 maximum)

使用累加函数Sigma 对多波段数据求和。

result = maximum(A.tif, maximum(B.tif, C.tif))

条件掩膜与提取

mask = (slope.tif > 15) & (rain.tif > 100)
result = where(mask, dem.tif, 0)

单位换算/线性缩放

# 例如:米 -> 千米
result = dem.tif / 1000.0

重分类 (where 函数)

重分类是将栅格像元的值根据特定的范围(Range)重新映射为新的分类值(Class Value)的过程。在 Python 栅格计算器中,由于标准的 if 语句无法直接处理数组(标量逻辑限制),必须使用 where 函数通过矩阵并行逻辑实现。

  • 语法:
    • 基础函数:where(条件, 满足条件的值, 不满足条件的值)),对于多级分类(如 4 类),需采用嵌套形式:where(条件1, 值1, where(条件2, 值2, 值3))
  • 输入文件
    • "T50SKH_B02_100m.tif": 单波段栅格数据
  • 计算公式 (expression):
    • where(T50SKH_B02_100m.tif <= 1610, 1, where(T50SKH_B02_100m.tif <= 2415, 2,where(T50SKH_B02_100m.tif <= 3468, 3, 4)))"
  • 可以使用多行语句,这样逻辑更清晰。
# 第一步:定义分类范围变量,提高可读性
class1 = T50SKH_B02_100m.tif <= 1610
class2 = T50SKH_B02_100m.tif <= 2415
class3 = T50SKH_B02_100m.tif <= 3468

# 第二步:通过嵌套 where 进行逐级分类赋值
# 逻辑:如果属于 class1 则给 1,否则继续判断是否属于 class2... 依此类推
result = where(class1, 1, where(class2, 2, where(class3, 3, 4)))

重分类 (逻辑、比较运算)

重分类是将栅格像元的值根据特定的范围(Range)重新映射为新的分类值(Class Value)的过程。在 Python 栅格计算器中,使用比较运算符(如 ><=)和逻辑运算符(如 logical_and)实现重分类。。

  • 语法:
    • 比较运算符greater_equal (>=), less_equal (<=), greater (>), less (<)。在表达式中可直接使用符号。
    • 逻辑运算符&|~ 表示逻辑logical_and (与), logical_or (或), logical_not (非)。用于组合多个区间条件。
  • 输入文件
    • "T50SKH_B02_100m.tif": 单波段栅格数据
  • 计算公式 (expression)1:
    • (T50SKH_B02_100m.tif <= 1610) * 1 + ((T50SKH_B02_100m.tif > 1610) & (T50SKH_B02_100m.tif <= 2415)) * 2 + ((T50SKH_B02_100m.tif > 2415) & (T50SKH_B02_100m.tif <= 3468)) * 3 + (T50SKH_B02_100m.tif > 3468) * 4”
  • 计算公式 (expression)2:
    • (T50SKH_B02_100m.tif <= 1610) * 1 + (T50SKH_B02_100m.tif > 1610) * (T50SKH_B02_100m.tif <= 2415) * 2 + (T50SKH_B02_100m.tif > 2415) * (T50SKH_B02_100m.tif <= 3468) * 3 + (T50SKH_B02_100m.tif > 3468) * 4
    • 说明:该表达式利用了布尔值参与算术运算时自动转为 0 或 1 的特性,通过乘法实现区间的逻辑“与”锁定,通过加法将互斥的分类结果进行叠加,从而在单行内完成所有重分类计算。比如当 T50SKH_B02_100m.tif <= 1610 时,表达式变为 1 * 1,结果为 1。当为 时,表达式变为 0 * 1,结果为 0
  • 可以使用多行语句,这样逻辑更清晰。
# 1. 使用比较运算符定义各个区间的布尔掩膜
# 范围 0 - 1610.47 -> 分类 1
m1 = (T50SKH_B02_100m.tif >= 0) & (T50SKH_B02_100m.tif <= 1610)

# 范围 1610.47 - 2415.71 -> 分类 2
# 使用 logical_and 函数或 & 符号
m2 = logical_and(T50SKH_B02_100m.tif > 1610, T50SKH_B02_100m.tif <= 2415)

# 范围 2415.71 - 3468.71 -> 分类 3
m3 = (T50SKH_B02_100m.tif > 2415) & (T50SKH_B02_100m.tif <= 3468)

# 范围 3468.71 - 15795 -> 分类 4
m4 = (T50SKH_B02_100m.tif > 3468)

# 2. 将布尔结果乘以分类值并累加得到最终结果
result = (m1 * 1) + (m2 * 2) + (m3 * 3) + (m4 * 4)

常见错误

c a + b          # 缺少等号
c = # 表达式缺失
c = a / 0 # 除零
mask = a > 0 and b > 0 # 错误:and/or/not 不是逐像元