基于 GEE 的 MODIS 数据逐月植被覆盖度(FVC)计算与数据导出完整流程

目录

一、代码整体框架与依赖环境说明

二、可视化参数配置

三、研究区与地图定位

[四、NDVI 计算函数(calculateNDVI)](#四、NDVI 计算函数(calculateNDVI))

五、植被覆盖度(FVC)计算函数

[六、C 因子计算函数](#六、C 因子计算函数)

七、时间段数据处理函数

八、主函数与执行

九、运行结果


若觉得代码对您的研究 / 项目有帮助,欢迎点击打赏支持!需要完整代码的朋友,打赏后可在后台私信(复制文章标题发给我),我会尽快发您完整可运行代码,感谢支持!

本代码是基于 Google Earth Engine(GEE)平台,利用 MODIS NDVI 数据计算 2010 年逐月及年度植被覆盖度(FVC)、C 因子,并实现数据可视化与 Google Drive 导出的完整流程,核心逻辑为 "数据加载→预处理→FVC 计算→衍生指标计算→可视化与导出"

一、代码整体框架与依赖环境说明

运行环境基础:

该代码需在Google Earth Engine(GEE)代码编辑器中执行,依赖 GEE 平台的两大核心能力:

  • 云端遥感数据存储与调用(直接读取 MODIS 官方数据集,无需本地下载)
  • 分布式计算能力(处理大区域、长时间序列数据时,无需本地硬件支撑)
  • 前提条件:需提前在 GEE 中定义研究区矢量边界(变量名 roi),否则代码会因 "roi 未定义" 报错。

数据来源与特性:

核心数据源为MODIS/061/MOD13Q1,需明确其关键属性以理解代码设计逻辑:

数据属性 具体说明 对代码的影响
产品类型 NDVI(归一化植被指数)16 天合成产品 代码中 "时间段平均 NDVI" 实际是 16 天合成数据的进一步均值,需注意时间分辨率匹配
空间分辨率 250 米 代码中导出 FVC、计算分位数时均使用 250 米尺度,确保数据精度一致性
数值范围 原始值为 - 2000~10000 需通过multiply(0.0001)转换为 - 0.2~1.0 的实际 NDVI 值,否则计算结果会完全错误

二、可视化参数配置

javascript 复制代码
var visParams = {
  min: 0.0,
  max: 1.0,
  palette: [
    'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
    '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
    '012E01', '011D01', '011301'
  ]
};
  • 参数含义
    • min/max:定义 FVC 的显示范围,因 FVC 物理意义为 "植被覆盖比例",故限定 0(无植被)~1(全植被覆盖),若设为其他值会导致颜色映射失真(如将 0.5 显示为最大值,高覆盖区与中覆盖区颜色一致)。
    • palette:17 个十六进制颜色码,从白色(FFFFFF,FVC=0)到深绿色(011301,FVC=1),对应植被覆盖度从低到高的渐变,符合人眼对 "绿度代表植被" 的认知习惯。
  • 使用场景 :仅用于地图可视化(Map.addLayer),不影响 FVC 计算结果,可根据需求修改颜色(如将荒漠区颜色改为黄色,增强视觉区分度)。

三、研究区与地图定位

javascript 复制代码
Map.addLayer(roi, {color: "black"}, "ROI", false);
Map.centerObject(roi, 8);
  • Map.addLayer(roi, {color: "black"}, "ROI", false)
    • 第一个参数roi:待添加的研究区矢量数据(需提前导入 GEE,格式可为 Shapefile、KML 等)。
    • 第二个参数{color: "black"}:设置研究区边界线颜色为黑色,便于在地图上识别区域范围。
    • 第三个参数"ROI":图层名称,显示在 GEE 地图左侧 "图层" 面板中。
    • 第四个参数false:图层默认隐藏(true为默认显示),避免研究区边界遮挡 FVC 的颜色细节,需查看时手动勾选图层即可。
  • Map.centerObject(roi, 8)
    • 功能:将地图视图中心自动定位到研究区几何中心。
    • 第二个参数8:GEE 地图缩放级别(1~24,数字越大视角越近、分辨率越高),8 级对应约 10 公里尺度,可完整显示地级市 / 县级区域,若研究区为省级需改为 6~7 级,村级需改为 10~12 级。

四、NDVI 计算函数(calculateNDVI)

javascript 复制代码
function calculateNDVI(image) {
  return image.select('NDVI').multiply(0.0001).rename('NDVI');
}
  • 核心目的:解决 MODIS 原始数据 "数值存储与实际物理值不一致" 的问题。
  • 逐步解析
    • image.select('NDVI'):从输入的影像(image)中筛选出 "NDVI" 波段,因MOD13Q1数据包含 NDVI、EVI 等多个波段,需明确指定目标波段。
    • multiply(0.0001):执行缩放操作,将原始整数(如 "5000")转换为实际 NDVI 值(5000×0.0001=0.5),该系数来自 MODIS 官方数据文档(MOD13Q1的 Scale Factor 为 0.0001),不可随意修改(若改为 0.001 会导致 NDVI 值为 5.0,远超合理范围)。
    • rename('NDVI'):保持波段名称不变,避免后续函数因波段名错误无法调用(若改为 "ndvi",后续select('NDVI')会返回空值)。

五、植被覆盖度(FVC)计算函数

javascript 复制代码
function calculateFVC(NDVI, region, scale) {
  // 计算研究区NDVI的5%和95%分位数
  var percentile = NDVI.reduceRegion({
    reducer: ee.Reducer.percentile([5, 95]),
    geometry: region,
    scale: scale,
    maxPixels: 1e13
  });
  
  var NDVI_min = ee.Number(percentile.get('NDVI_p5'));
  var NDVI_max = ee.Number(percentile.get('NDVI_p95'));
  
  // FVC计算与范围限制
  var FVC = NDVI.subtract(NDVI_min)
                .divide(NDVI_max.subtract(NDVI_min))
                .clamp(0, 1)
                .rename('FVC');
  return FVC;
}
  • 函数参数说明

    • NDVI:输入的 NDVI 影像(需先经过calculateNDVI处理,确保为 - 0.2~1.0 的实际值)。
    • region:研究区矢量边界(通常为roi),用于计算分位数的空间范围。
    • scale:计算分位数时的空间尺度(单位:米),需与数据源分辨率一致(此处为 250 米),若设为 1000 米会导致分位数计算精度降低。
  • 分位数计算

    • ee.Reducer.percentile([5, 95]):GEE 内置的统计 Reducer,计算影像在指定区域内的 5% 和 95% 分位数,目的是排除极端值干扰(如研究区内的云、水体、裸岩等异常 NDVI 值,避免将其计入 "植被 / 非植被" 阈值)。
    • maxPixels: 1e13:设置最大处理像素数,因 GEE 默认限制单区域处理像素数(避免内存溢出),1e13 对应约 100 万平方公里(250 米分辨率下,1 像素 = 62500 平方米,1e13 像素 = 6.25e17 平方米 = 625 万平方公里),足够覆盖大部分区域。
    • percentile.get('NDVI_p5'):从分位数结果中提取 "NDVI 的 5% 分位数",GEE 会自动为结果命名为 "波段名_分位数"(如 NDVI 的 5% 分位数为 "NDVI_p5"),若波段名修改需同步调整此处命名。
  • FVC 计算逻辑(像元二分模型)

    • 公式原理:FVC = (NDVI - NDVI_min) / (NDVI_max - NDVI_min),假设研究区内仅 "纯植被"(NDVI=NDVI_max,FVC=1)和 "纯非植被"(NDVI=NDVI_min,FVC=0)两类像元,混合像元的 FVC 与 NDVI 呈线性关系。
    • clamp(0, 1):强制将计算结果限制在 0~1 范围内,因部分像元 NDVI 可能小于 NDVI_min(如水体,NDVI=-0.1)或大于 NDVI_max(如浓密森林,NDVI=0.95),若不限制会出现 FVC=-0.2 或 1.1 等无物理意义的值。

六、C 因子计算函数

javascript 复制代码
function calculateC(FVC) {
  return FVC.expression(
    "f == 0 ? 1 : (f > 78.3 ? 0 : 0.6508 - 0.3436 * log10(f))",
    {
      f: FVC.multiply(100)
    }
  ).rename('C');
}
  • C 因子含义:土壤侵蚀通用方程(USLE/RUSLE)中的 "植被覆盖与管理因子",取值范围 0~1,值越小表示植被对土壤侵蚀的抑制作用越强(C=0 时无侵蚀,C=1 时无植被保护)。
  • 详细解析
    • FVC.multiply(100):将 FVC 从 0~1 的小数转换为 0~100 的百分比(如 FVC=0.5→f=50),因经验公式的输入参数为百分比形式。

    • expression(...):GEE 中执行数学表达式的函数,支持条件判断(类似 JavaScript 的三元运算符),表达式逻辑如下:

      条件 C 因子值 物理意义
      f == 0(无植被) 1 无任何植被保护,土壤侵蚀最严重
      f > 78.3(高植被覆盖) 0 植被完全覆盖地表,无土壤侵蚀
      0 < f ≤ 78.3(中低植被覆盖) 0.6508 - 0.3436×log₁₀(f) 植被覆盖度越高,C 因子越小,侵蚀抑制作用越强
    • 注意:该公式为经验公式,适用于大部分区域,但针对特定生态系统(如荒漠草原、热带雨林)可能需要调整系数,需参考相关文献验证。

七、时间段数据处理函数

javascript 复制代码
function processTimePeriod(startDate, endDate, periodName) {
  // 加载MODIS NDVI数据
  var imageCol = ee.ImageCollection("MODIS/061/MOD13Q1")
                    .filterDate(startDate, endDate)
                    .filterBounds(roi)
                    .select(['NDVI']);
  
  // 计算平均NDVI并裁剪
  var NDVI = imageCol.mean().clip(roi);
  
  // 数据有效性检查
  if (NDVI.bandNames().size().getInfo() === 0) {
    print("无有效数据的时间段: " + periodName);
    return null;
  }
  
  // 计算NDVI、FVC
  NDVI = calculateNDVI(NDVI);
  var FVC = calculateFVC(NDVI, roi, 250);
  
  // 可视化与导出
  Map.addLayer(FVC, visParams, 'FVC_' + periodName);
  Export.image.toDrive({
    image: FVC,
    description: "FVC_" + periodName,
    scale: 250,
    region: roi,
    maxPixels: 1e13
  });
  
  return {period: periodName, fvc: FVC};
}
  • 函数参数

    • startDate/endDate:时间段的起止日期(需为ee.Date类型,如ee.Date.fromYMD(2010,1,1))。
    • periodName:时间段名称(如 "2010""2010_01"),用于图层命名和导出文件命名,便于区分不同时间段数据。
  • 数据加载与筛选

    • ee.ImageCollection("MODIS/061/MOD13Q1"):调用 GEE 中的MOD13Q1数据集(061 为版本号,代表 Collection 6.1,是当前常用版本)。
    • filterDate(startDate, endDate):按日期筛选数据,注意 GEE 中filterDate为 "左闭右开" 区间(如filterDate('2010-01-01','2010-02-01')实际包含 1 月 1 日~1 月 31 日数据),与代码中 "月度数据处理" 的逻辑匹配。
    • filterBounds(roi):按空间范围筛选,仅保留与研究区(roi)有交集的影像,减少无关数据计算量,提高效率。
    • select(['NDVI']):仅保留 NDVI 波段,排除 EVI、质量控制等无关波段,降低数据处理负荷。
  • 平均 NDVI 计算与裁剪

    • imageCol.mean():对筛选后的影像集合(imageCol)计算逐像元均值,将 16 天合成数据转换为 "时间段平均 NDVI"(如月度数据为该月内 2~3 期 16 天合成数据的均值),反映该时间段的植被平均状况。
    • clip(roi):将平均 NDVI 影像裁剪到研究区范围,避免导出数据包含研究区外的无效区域,减少文件大小。
  • 数据有效性检查

    • NDVI.bandNames().size().getInfo() === 0:检查裁剪后的 NDVI 影像是否包含有效波段(若imageCol无数据,mean()后会生成无波段的空影像)。
    • print(...):在 GEE 控制台打印无数据的时间段提示(如 "无有效数据的时间段: 2010_02"),便于排查问题(可能原因:研究区该时间段全为云覆盖、数据未收录等)。
    • return null:无有效数据时终止函数执行,避免后续计算报错。
  • 可视化与导出

    • Map.addLayer(FVC, visParams, 'FVC_' + periodName):将 FVC 影像添加到地图,图层名称为 "FVC_时间段"(如 "FVC_2010_01"),使用之前定义的visParams配色方案,便于直观对比不同时间段的植被覆盖差异。

    • Export.image.toDrive(...):将 FVC 影像导出到 Google Drive,关键参数说明:

      参数 含义 注意事项
      image: FVC 待导出的影像 若需同时导出 NDVI、C 因子,可改为image: ee.Image([NDVI, FVC, C])
      description 导出任务名称和文件前缀 需唯一,避免同名文件覆盖
      scale: 250 导出影像的空间分辨率 需与数据源分辨率一致(MOD13Q1为 250 米),设为更高分辨率(如 100 米)会导致数据重采样,无实际精度提升
      region: roi 导出的空间范围 需为ee.Geometry类型,若 roi 为矢量集合需转换为单一几何(如roi.geometry()
      maxPixels: 1e13 最大导出像素数 若研究区过大(如超过 100 万平方公里)需增大该值,否则会提示 "像素数超过限制"

八、主函数与执行

javascript 复制代码
function processData() {
  var results = []; 
  
  // 循环处理2010年
  for (var year = 2010; year <= 2010; year++) {
    // 处理年度数据
    var startYear = ee.Date.fromYMD(year, 1, 1);
    var endYear = ee.Date.fromYMD(year, 12, 31);
    var annualResult = processTimePeriod(startYear, endYear, year.toString());
    if (annualResult) results.push(annualResult);
    
    // 处理月度数据
    for (var month = 1; month <= 12; month++) {
      var startMonth = ee.Date.fromYMD(year, month, 1);
      var endMonth = startMonth.advance(1, 'month').advance(-1, 'day');
      var monthName = year + "_" + (month < 10 ? "0" + month : month);
      var monthlyResult = processTimePeriod(startMonth, endMonth, monthName);
      if (monthlyResult) results.push(monthlyResult);
    }
  }
  return results;
}

// 执行函数
var processingResults = processData();
  • 结果存储数组var results = []用于存储各时间段的处理结果(包含时间段名称period和 FVC 影像fvc),后续可通过该数组调用 FVC 影像(如计算年度 FVC 变化、提取月度均值等)。

  • 年度数据处理逻辑

    • ee.Date.fromYMD(year, 1, 1):生成该年 1 月 1 日的ee.Date对象(GEE 日期类型,不可直接用 JavaScript 的Date类型)。
    • endYear = ee.Date.fromYMD(year, 12, 31):生成该年 12 月 31 日的日期对象,因processTimePeriodfilterDate为左闭右开,此处无需调整日期(12 月 31 日为结束日期,会包含 12 月全月数据)。
    • year.toString():将年份(数字)转换为字符串,作为时间段名称(如 2010→"2010")。
    • if (annualResult) results.push(annualResult):仅当有有效数据时,才将结果加入results数组,避免存储空值。
  • 月度数据处理逻辑

    • startMonth = ee.Date.fromYMD(year, month, 1):生成该月 1 日的日期对象(如 2010 年 2 月→"2010-02-01")。
    • endMonth = startMonth.advance(1, 'month').advance(-1, 'day'):计算该月最后一天的日期,逻辑为 "当前月 1 日 + 1 个月 - 1 天"(如 2010 年 2 月 1 日 + 1 个月 = 3 月 1 日,再 - 1 天 = 2 月 28 日),避免手动判断月份天数(尤其解决 2 月、30 天 / 31 天月份的问题)。
    • month < 10 ? "0" + month : month:月份补零处理(如 1 月→"01",12 月→"12"),使月度名称格式统一(如 "2010_01" 而非 "2010_1"),便于后续文件排序和识别。
  • 函数执行var processingResults = processData()调用主函数,启动整个数据处理流程,执行后会在 GEE 控制台 "任务" 面板中生成 13 个导出任务(1 个年度 + 12 个月度),需手动点击 "运行" 并授权 Google Drive 访问,才能完成数据导出。

九、运行结果

运行结果的所有图层
研究区2010年植被覆盖度平均值计算结果可视化
研究区2010年01月植被覆盖度平均值计算结果可视化
研究区2010年04月植被覆盖度平均值计算结果可视化
研究区2010年07月植被覆盖度平均值计算结果可视化
研究区2010年10月植被覆盖度平均值计算结果可视化
点击RUN即可下载数据

若觉得代码对您的研究 / 项目有帮助,欢迎点击打赏支持!需要完整代码的朋友,打赏后可在后台私信(复制文章标题发给我),我会尽快发您完整可运行代码,感谢支持!

相关推荐
wanhengidc3 小时前
海外云手机是指什么
运维·服务器·游戏·智能手机·云计算
AWS官方合作商3 小时前
AWS Lambda的安全之道:S3静态加密与运行时完整性检查的双重保障
安全·云计算·aws
boonya16 小时前
ChatBox AI 中配置阿里云百炼模型实现聊天对话
人工智能·阿里云·云计算·chatboxai
AKAMAI16 小时前
AI 边缘计算:决胜未来
人工智能·云计算·边缘计算
阿里云云原生19 小时前
阿里云微服务引擎 MSE 及 API 网关 2025 年 10 月产品动态
阿里云·微服务·云原生·云计算
wanhengidc19 小时前
云手机能够流畅运行大型游戏吗
运维·服务器·游戏·智能手机·云计算
boonya1 天前
从阿里云大模型服务平台百炼看AI应用集成与实践
人工智能·阿里云·云计算
Akamai中国1 天前
AI 边缘计算:决胜未来
人工智能·云计算·边缘计算·云服务