1、基于 GEE 的 NDVI 交互式时序可视化与趋势分析工具

1、基于 GEE 的 NDVI 交互式时序可视化与趋势分析工具

功能:

  1. 数据预处理:自动加载 Landsat 8 数据并进行去云处理。
  2. NDVI 计算:计算归一化植被指数。
  3. 趋势分析 (Trend Map):利用线性回归计算 NDVI 的变化斜率(Slope),并在地图上可视化(变绿还是变黄)。
  4. 交互式图表 (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: 这是右下角的侧边栏容器,用于展示图表而不是让图表遮挡地图。

如何使用

  1. 运行代码:点击编辑器上方的 "Run"。
  2. 观察地图
    • 地图上会加载两层数据。顶层是 "NDVI Trend Slope"(趋势斜率)。
    • 绿色区域:表示这几年植被在变好。
    • 红色/白色区域:表示植被在减少或无变化。
  3. 点击交互
    • 鼠标会变成"十字丝"形状。
    • 点击地图上感兴趣的区域(例如一片森林或城市边缘)。
    • 右下角的面板会生成一个时间序列图。
    • 绿线 是实际 NDVI 波动,红线是总体线性趋势。
相关推荐
```???2 小时前
666666999999
javascript·tcp/ip·node.js
我命由我123452 小时前
微信小程序 - 页面返回并传递数据(使用事件通道、操作页面栈)
开发语言·前端·javascript·微信小程序·小程序·前端框架·js
于谦2 小时前
git提交信息也能自动格式化了?committier快速体验
前端·javascript·代码规范
小高0072 小时前
React 避坑指南:彻底搞定不必要的重新渲染
前端·javascript·react.js
San30.2 小时前
从原型链到“圣杯模式”:JavaScript 继承方案的演进与终极解法
开发语言·javascript·原型模式
JS_GGbond2 小时前
浏览器三大核心API:LocalStorage、Fetch API、History API详解
前端·javascript
老前端的功夫2 小时前
首屏优化深度解析:从加载性能到用户体验的全面优化
前端·javascript·vue.js·架构·前端框架·ux
晴殇i3 小时前
性能飞跃!这几个现代浏览器API让页面加载速度提升至90+
前端·javascript·面试
Hilaku3 小时前
检测开发者工具是否打开?这几种方法让黑客无处遁形🤣
前端·javascript·前端框架