1、基于 GEE 的 NDVI 交互式时序可视化与趋势分析工具
功能:
- 数据预处理:自动加载 Landsat 8 数据并进行去云处理。
- NDVI 计算:计算归一化植被指数。
- 趋势分析 (Trend Map):利用线性回归计算 NDVI 的变化斜率(Slope),并在地图上可视化(变绿还是变黄)。
- 交互式图表 (UI):点击地图任意位置,右侧面板会自动生成该点的 NDVI 长时序变化曲线,并叠加线性趋势线。
GEE生成青藏高原的NDVI影像,在图中任意位置点击会放回此地区的NDVI时序分析库

点击上图右下角可以放大图像(用于科研再合适不过了,注意此图可下载多种图片格式)

本代码有多图层

● Selected Point:选中点的可视化(通常是红点或标记,用来显示你点击的位置)
● NDVI Trend Slope:NDVI长期趋势斜率(一般通过Mann-Kendall或线性回归计算得到的每个像元NDVI时间序列的变化速率,单位通常是NDVI/年)
● NDVI Mean (Avg):多年平均NDVI(多时相NDVI的均值图,反映研究区总体植被覆盖水平,上有颜色的图就是为此图层)
● Boundary Outline:研究区/感兴趣区域的边界轮廓(通常是shapefile或FeatureCollection导入后显示的白色或黑色边框)
GEE 代码 (JavaScript)
请将以下代码直接复制到 Google Earth Engine Code Editor 中运行。
注意var table = ee.FeatureCollection("projects/maxhecheng/assets/TPBoundary_HF");
以上一行代码请修改成你感兴趣的矢量区域
javascript
/**
* 基于 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');
return image.addBands(ee.Image(years).rename('t').float());
});
var trend = collectionForTrend.select(['t', 'NDVI'])
.reduce(ee.Reducer.linearFit());
// --- 5. 地图可视化 ---
Map.setOptions('HYBRID');
// 【修改点 3】裁剪结果,让图层只显示在你的边界形状内,而不是矩形
var ndviMean = l8Col.select('NDVI').mean().clip(aoi);
var ndviVis = {min: 0, max: 0.8, palette: ['white', 'yellow', 'green', 'darkgreen']};
// 添加边界轮廓 (空心),方便查看范围
Map.addLayer(ee.Image().paint(table, 0, 2), {palette: 'red'}, 'Boundary Outline');
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');
// --- 6. 构建交互式 UI 面板 (保持不变) ---
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);
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); // 注意这里变成了set(3),因为我们在前面加了一个边界图层
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');
其他GEE代码
其他GEE将同步到一下github仓库
我的GEE所以代码将会同步在github的同一个仓库里,欢迎大家使用和交流
GitHub仓库主页:https://github.com/mojoin/GEE-
详细介绍
代码核心逻辑解析
1. NDVI 公式与计算
代码使用了标准的 NDVI 公式:
N D V I = N I R − R e d N I R + R e d NDVI = \frac{NIR - Red}{NIR + Red} NDVI=NIR+RedNIR−Red
在 Landsat 8 Collection 2 数据中,对应的是 SR_B5 (近红外) 和 SR_B4 (红光)。代码中通过 normalizedDifference 函数高效完成。
2. 去云处理 (Cloud Masking)
使用了 QA_PIXEL 波段。这对于时序分析至关重要。如果包含云像素,NDVI 会急剧下降,导致生成的趋势线(Trendline)出现严重偏差(伪退化)。
3. 趋势分析 (Trend Analysis)
这里应用了两种趋势分析方法:
- 空间趋势 (Spatial Map) : 使用
ee.Reducer.linearFit()。- Scale (斜率): 正值(绿色)表示 NDVI 随时间增加(植被改善),负值(红色)表示减少(植被退化)。
- 这个图层默认加载在地图上,你可以一眼看出整个区域哪里在变好,哪里在变坏。
- 图表趋势 (Chart Trendline) : 在
ui.Chart中直接通过.setOptions({trendlines: ...})添加。这使用了最小二乘法来拟合点状图,并显示 R² (拟合优度)。
4. 交互逻辑 (UI)
Map.onClick: 这是一个事件监听器。当你在地图上点击时,它捕获坐标,生成一个ee.Geometry.Point,然后针对这个点过滤 ImageCollection 并生成图表。ui.Panel: 这是右下角的侧边栏容器,用于展示图表而不是让图表遮挡地图。
如何使用
- 运行代码:点击编辑器上方的 "Run"。
- 观察地图 :
- 地图上会加载两层数据。顶层是 "NDVI Trend Slope"(趋势斜率)。
- 绿色区域:表示这几年植被在变好。
- 红色/白色区域:表示植被在减少或无变化。
- 点击交互 :
- 鼠标会变成"十字丝"形状。
- 点击地图上感兴趣的区域(例如一片森林或城市边缘)。
- 右下角的面板会生成一个时间序列图。
- 绿线 是实际 NDVI 波动,红线是总体线性趋势。