目录
[四、NDVI 计算函数(calculateNDVI)](#四、NDVI 计算函数(calculateNDVI))
[六、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 日的日期对象,因processTimePeriod中filterDate为左闭右开,此处无需调整日期(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即可下载数据
若觉得代码对您的研究 / 项目有帮助,欢迎点击打赏支持!需要完整代码的朋友,打赏后可在后台私信(复制文章标题发给我),我会尽快发您完整可运行代码,感谢支持!