四、波段数学计算(计算NDVI)
我们已经看到了如何使用 ol/source/GeoTIFF
源代码来渲染真彩色和假彩色合成。我们通过将缩放的反射率值直接渲染到红色、绿色或蓝色显示通道中的一个来实现这一点。还可以对来自GeoTIFF(或其他数据瓦片源)的反射率值运行计算,并将输出值映射到RGBA颜色值。
ol/layer/WebGLTile
层接受可用于控制源样式渲染的 style
属性。在此示例中,我们将使用数学表达式从前面示例中使用的相同 Sentinel-2 源计算归一化植被指数 (NDVI)。
NDVI 是近红外 (NIR) 和红色之间的差异与近红外和红色反射率值之和的比率。
NDVI = (NIR - RED) / (NIR + RED)
这种归一化差异提供了绿色植被密度或健康状况的指数。通过将近红外和红色反射之间的差异除以它们的和,指数被规范化以抵消亮度或照明的变化。这个想法是,有植被的阳光坡和有植被的阴凉坡应该具有类似的指数。
要渲染 NDVI 值,我们需要将源配置为使用近红外 (B08) 和红色 (B04) 波段。更新您的 main.js
脚本,使源代码如下所示:
const source = new GeoTIFF({
sources: [
{
// red reflectance
url: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/21/H/UB/2021/9/S2B_21HUB_20210915_0_L2A/B04.tif',
max: 10000,
},
{
// near-infrared reflectance
url: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/21/H/UB/2021/9/S2B_21HUB_20210915_0_L2A/B08.tif',
max: 10000,
},
],
});
接下来,我们将创建用于根据源的输入波段计算 NDVI 的表达式。将以下变量添加到您的 main.js
中:
// near-infrared is the second band from above
const nir = ['band', 2];
// near-infrared is the first band from above
const red = ['band', 1];
const difference = ['-', nir, red];
const sum = ['+', nir, red];
const ndvi = ['/', difference, sum];
上面的表达式使用以下形式的基于数组的语法: [operator, ...arguments]
。 band
运算符从 sources
列表中访问 ol/source/GeoTIFF
的频段 – 其中第一个配置的频段为 1,第二个为 2,依此类推。 -
、 +
和 /
运算符计算其输入参数的差值、总和和比率。 ndvi
表达式将产生 -1(不太植被)和 1(非常植被)之间的值。下一步是将这些值映射到颜色。这种基于数组的语法在某些情况下可以简化代码逻辑,使操作符和参数的组合更加灵活和易于处理。
ol/layer/WebGLTile
图层的 style
采用 color
属性来确定每个像素的最终输出颜色。我们想要在无植被(棕色)和植被(绿色)NDVI 值之间插入颜色。为此,我们使用 interpolate
运算符,在多个停止值之间应用 linear
插值。
编辑 main.js
使图层定义如下所示:
const layer = new TileLayer({
source: source,
style: {
color: [
'interpolate',
['linear'],
ndvi,
-0.2, // ndvi values <= -0.2 will get the color below
[191, 191, 191],
0, // ndvi values between -0.2 and 0 will get an interpolated color between the one above and the one below
[255, 255, 224],
0.2,
[145, 191, 82],
0.4,
[79, 138, 46],
0.6,
[15, 84, 10],
],
},
});
color的表达式详见:https://openlayers.org/en/latest/apidoc/module-ol_expr_expression.html#~ExpressionValue
这里使用的表达式是:
['interpolate', interpolation, input, stop1, output1, ...stopN, outputN]
通过在成对的输入和输出之间进行插值来返回值:
interpolation
可以是['linear']
或['exponential', base]
,其中base
是从停止A到停止B的增加速率(即插值比被提高到的幂),值为1等效于['linear']
。input
和stopX
值必须都是number
类型。outputX
值可以是number
或color
值。注:
input
将被箝位在stop1
和stopN
之间,这意味着所有输出值将被包括在output1
和outputN
之间。
如果一切顺利,您应该可以在 http://localhost:5173/ 上看到 NDVI 的图像。
从 Sentinel-2 GeoTIFF 生成的 NDVI
选择这些阈值和颜色是一项困难的工作。接下来,我们将引入一个辅助库(colormap)来为我们完成此操作。