基于 Google Earth Engine 的 NDVI 交互式时序分析与可视化工具,支持长时间序列植被动态监测与空间趋势制图。
主要功能说明
- 数据预处理:自动获取 Landsat 8 表面反射率数据,并通过 QA 波段进行云和阴影像素的掩膜处理,提升数据质量。
- NDVI 计算:利用红光波段(SR_B4)与近红外波段(SR_B5)计算归一化植被指数。
- 趋势空间制图(Trend Map):采用线性回归模型拟合每个像元在时间序列上的 NDVI 变化斜率,生成区域尺度的趋势分布图,直观展示绿化或退化区域。
- 交互式时序图表(UI 面板):用户可在地图上任意点击选取位置,右侧界面将实时绘制该点的多年 NDVI 动态曲线,并叠加趋势拟合直线,便于局部精细化分析。
可通过界面右下角的控件对图像进行放大操作。该可视化结果适用于科研用途,且支持导出多种图像格式以满足不同需求。
多图层显示说明
系统默认加载以下多个图层,用户可自由切换查看:
- Selected Point:用于标识当前选中的地理位置,通常以红色标记呈现,方便定位分析点。
- NDVI Trend Slope:基于时间序列回归得出的每年 NDVI 变化速率图,反映植被长期变化趋势(单位:NDVI/年),常用线性回归或 Mann-Kendall 方法计算。
- NDVI Mean (Avg):多年平均 NDVI 分布图,体现研究区整体植被覆盖水平;图中彩色渲染部分即为此图层内容。
- Boundary Outline:导入的研究区域边界轮廓,一般由 Shapefile 或 FeatureCollection 构建而成,在地图中以白色或黑色边框形式显示。
GEE JavaScript 代码实现
请将以下脚本直接粘贴至 Google Earth Engine Code Editor 中运行执行。
注意:需修改如下行中的路径为你账户下实际存在的矢量资产路径:
var table = ee.FeatureCollection("projects/maxhecheng/assets/TPBoundary_HF");
/**
* 基于 GEE 的 NDVI 交互式时序可视化与趋势分析工具
* 修改版:使用自定义 Asset 边界
*/
// --- 1. 参数设置 ---
var startDate = '2015-01-01';
var endDate = '2023-12-31';
// 【修改点 1】加载你的自定义 Asset 边界
// 请确保该路径在你的 Assets 选项卡中真实存在且有读取权限
var table = ee.FeatureCollection("projects/maxhecheng/assets/TPBoundary_HF");
var aoi = table.geometry();
// 让地图中心自动定位到你的边界
Map.centerObject(aoi);
// --- 2. 核心函数 (保持不变) ---
// 2.1 Landsat 8 去云与缩放因子校正函数
function preprocessL8(image) {
var qa = image.select('QA_PIXEL');
var mask = qa.bitwiseAnd(1 << 3).eq(0)
.and(qa.bitwiseAnd(1 << 4).eq(0));
var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
return image.addBands(opticalBands, null, true).updateMask(mask);
}
// 2.2 计算 NDVI 函数
function addNDVI(image) {
var ndvi = image.normalizedDifference(['SR_B5', 'SR_B4']).rename('NDVI');
return image.addBands(ndvi).copyProperties(image, ['system:time_start']);
}
// --- 3. 数据加载与处理 ---
var l8Col = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
// 【修改点 2】这里不再使用 Map.getBounds(),而是直接过滤你的 aoi 范围
.filterBounds(aoi)
.filterDate(startDate, endDate)
.map(preprocessL8)
.map(addNDVI);
// --- 4. 空间趋势分析 (Linear Regression) ---
var collectionForTrend = l8Col.map(function(image) {
var date = image.date();
var years = date.difference(ee.Date('1970-01-01'), 'year');
返回图像并添加年份波段(重命名为 't' 并转换为浮点型):
return image.addBands(ee.Image(years).rename('t').float());
对时间序列集合进行趋势分析,选取 't' 和 'NDVI' 波段,使用线性拟合方法计算斜率:
var trend = collectionForTrend.select(['t', 'NDVI']).reduce(ee.Reducer.linearFit());
地图可视化设置
设定地图底图样式为混合模式(HYBRID),增强地形与影像的可读性。
Map.setOptions('HYBRID');
对 NDVI 均值结果进行区域裁剪,确保显示范围仅限于指定的研究区边界(aoi):
var ndviMean = l8Col.select('NDVI').mean().clip(aoI);
配置 NDVI 可视化参数,设定数值范围与颜色梯度方案:
var ndviVis = {min: 0, max: 0.8, palette: ['white', 'yellow', 'green', 'darkgreen']};
添加研究区域边界轮廓图层(红色空心线),便于识别分析范围:
Map.addLayer(ee.Image().paint(table, 0, 2), {palette: 'red'}, 'Boundary Outline');
将处理后的 NDVI 平均值图层加载至地图,图层默认不启用:
Map.addLayer(ndviMean, ndviVis, 'NDVI Mean (Avg)', false);
对趋势分析结果中的斜率部分进行可视化,并同样执行区域裁剪操作:
var slopeVis = {min: -0.05, max: 0.05, palette: ['red', 'white', 'green']};
Map.addLayer(trend.select('scale').clip(aoi), slopeVis, 'NDVI Trend Slope');
交互式用户界面构建
创建一个固定在地图右下角的面板,宽度设为 400px,用于展示分析结果和交互控件:
var panel = ui.Panel();
panel.style().set({width: '400px', position: 'bottom-right'});
Map.add(panel);
在面板中添加标题标签,设置字体大小与加粗样式:
var title = ui.Label({value: 'NDVI 时序分析工具', style: {fontSize: '20px', fontWeight: 'bold'}});
panel.add(title);
添加说明文字,提示用户可通过点击地图查看任意位置的 NDVI 变化情况:
panel.add(ui.Label('点击地图任意位置查看该点的 NDVI 变化趋势。'));
绑定地图点击事件,获取坐标点后动态生成时间序列图表:
Map.onClick(function(coords) {
var point = ee.Geometry.Point(coords.lon, coords.lat);
panel.widgets().set(2, ui.Label('正在计算图表...'));
var dot = ui.Map.Layer(point, {color: 'red'}, 'Selected Point');
Map.layers().set(3, dot);
var chart = ui.Chart.image.series({
imageCollection: l8Col.select('NDVI'),
region: point,
reducer: ee.Reducer.mean(),
scale: 30
}).setOptions({
title: 'NDVI 变化 (2015-2023)',
vAxis: {title: 'NDVI', viewWindow: {min: -0.2, max: 1}},
lineWidth: 1,
pointSize: 3,
trendlines: { 0: {type: 'linear', color: 'red', visibleInLegend: true} }
});
panel.widgets().set(2, chart);
});
设置鼠标指针样式为十字光标,提升空间选择的直观性:
Map.style().set('cursor', 'crosshair');
核心算法解析
1. NDVI 计算公式
采用标准归一化植被指数公式进行计算:
NDVI = (NIR - Red) / (NIR + Red)
在 Landsat 8 Collection 2 数据集中,近红外波段对应
SR_B5
,红光波段对应
SR_B4
。代码通过
normalizedDifference
函数完成波段运算。
2. 云掩膜处理(去云策略)
利用
QA_PIXEL
方法对影像进行质量控制,有效剔除受云层影响的像素,提升时间序列数据的可靠性。
3. 趋势分析 (Trend Analysis)
本研究采用了两种趋势分析方法,用于揭示植被变化的时空特征:
空间趋势(Spatial Map)
通过计算每个像元的线性趋势斜率,生成空间分布图。
ee.Reducer.linearFit()
在该图中,“Scale”(斜率)值以颜色表示:
- 正值(绿色区域):表明 NDVI 随时间上升,反映植被覆盖状况改善;
- 负值(红色区域):表示 NDVI 下降,意味着植被出现退化现象。
此图层默认加载于地图视图中,可直观识别区域内植被变好或变差的空间格局。
图表趋势(Chart Trendline)
该功能基于最小二乘法对时间序列点数据进行线性拟合,并展示 R 值(决定系数),用以评估趋势线的拟合程度。
ui.Chart
用户可通过以下方式触发图表生成:
.setOptions({trendlines: ...})
4. 交互逻辑(UI)
系统设计了动态交互机制,提升数据探索体验:
Map.onClick
这是一个事件监听模块。当用户在地图上点击时,系统会捕获所选位置的地理坐标,并据此创建一个采样点。
ee.Geometry.Point
随后,系统将利用该点位信息从影像集合(ImageCollection)中提取对应的 NDVI 时间序列数据,并绘制趋势图表。
ui.Panel
图表结果显示在界面右下角的侧边栏容器中,避免遮挡底图,确保地图与数据分析同步可视。
使用说明
运行代码
点击代码编辑器顶部的 “Run” 按钮执行脚本。
查看地图结果
执行后,地图将自动加载两个图层,其中顶层显示的是 “NDVI Trend Slope” 分布情况。
- 绿色区域:表示研究期间内植被状况持续向好;
- 红色或白色区域:指示植被减少或基本无显著变化。
进行交互操作
完成运行后,鼠标指针将变为“十字丝”样式,表示已进入交互模式。
- 在地图上选择任意感兴趣区域(如森林地带、城市边缘等)点击;
- 系统将在右下角面板中自动生成对应点位的 NDVI 时间序列图;
- 图中绿线代表实际观测到的 NDVI 波动情况;
- 红线则表示整体的线性变化趋势。