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

主要能力
- 多栅格/多波段参与同一表达式计算
- 支持单语句与多语句(代码块)两种模式
- 内置运算符与常用 NumPy 函数(算数/三角/逻辑/统计等)
- 自动对齐:当输入栅格空间参考或网格不一致时自动重采样并对齐
- NoData 与数值类型可控:默认输出为 双精度浮点小数,NoData 默认取当前类型可表示的最大值
使用方式
典型流程:
- 添加一个或多个输入栅格
- 在表达式区域输入“单语句”或“代码块”
- 设定输出栅格路径与通用输出参数(像素类型、NoData、压缩、坐标系等)
- 运行生成
栅格引用与波段引用
在栅格计算器中,表达式里的“变量”可以指向某个输入栅格或其指定波段。
- 引用范围
- 栅格引用仅在当前一次工具运行中有效
- 名称区分大小写
- 栅格引用(Raster Name)
- 直接使用输入列表中的“文件引用名称”(通常就是文件名)来引用栅格
示例(以文件名作为引用):
result = T50SKH_B02_100m.tif + T50SKH_B03_100m.tif
- 波段引用(RasterName.bandN)
- 多波段栅格可用
栅格名.bandN引用指定波段,N从 1 开始 - 单波段栅格中,
a与a.band1等价
示例:
nd = 空飞-多波段栅格-100m.tif.band4 - 空飞-多波段栅格-100m.tif.band2
非法示例:
c = a.band0
c = band1
语法规则
单语句模式
必须写成赋值形式:输出变量 = 表达式。
result = dem.tif * 0.001
由于界面中,默认会使用输出文件=,因此用户在输入框中直接输入表达式即可。

代码块(多语句)模式
- 允许定义临时变量和中间结果
- 至少有一句是赋值形式,否则无法输出
- 若存在多句赋值表达式,以最后一句赋值结果作为最终输出
- 变量命名,代码块中的变量必须是合法标识符(建议:小写字母 + 数字 + 下划线,且不以数字开头)
- 代码块中可以重复利用中间变量,让复杂逻辑更清晰。
# 定义掩膜
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 // B | GIS 中常用于分级 |
| % | 取模 | 余数 | 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/数学优先级。编写复杂条件时建议始终用括号明确意图:
()**- 一元
+x-x~x *///%+-- 位移
<<>> &^|- 比较
== != < <= > >= - 赋值
=
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 不是逐像元