172 lines
6.0 KiB
JavaScript
172 lines
6.0 KiB
JavaScript
/**
|
|
* 气象数据下载 —— 以年平均气温与年总降雨量处理下载为例
|
|
*
|
|
* @author CVEO Team
|
|
* @date 2026-01-16
|
|
*
|
|
* 1. 加载 ERA5-Land 数据
|
|
* 2. 合成年度平均气温数据, 年度总降雨量数据
|
|
* 3. 导出 COG 云优化并填补缺失值的 GeoTIFF 影像 (大区域 GEE 自动分块下载)
|
|
*/
|
|
|
|
// 加载研究区域和影像
|
|
// var region_name = "应城市";
|
|
// var region_name_en = "Yingcheng";
|
|
// var region = Yingcheng;
|
|
// var target_crs = "EPSG:4526";
|
|
var region_name = "保康县";
|
|
var region_name_en = "Baokang";
|
|
var region = Baokang;
|
|
var target_crs = "EPSG:4525";
|
|
var target_res = 30;
|
|
var orign_res = 10000;
|
|
var start_year = 2021;
|
|
var end_year = 2025;
|
|
var start_date = start_year + "-01-01";
|
|
var end_date = end_year + "-12-31";
|
|
var ERA5Bands = ["temperature_2m", "total_precipitation_sum"];
|
|
var commonBands = ["temperature", "total_precipitation_sum"];
|
|
// 设置研究区域的缓冲区, 确保粗分辨率数据能够完整覆盖研究区域
|
|
var region_geo = region.geometry();
|
|
var bounds = ee.Feature(region_geo.bounds()).buffer(orign_res * 3).geometry();
|
|
var common_filter = ee.Filter.and(
|
|
ee.Filter.bounds(bounds),
|
|
ee.Filter.date(start_date, end_date)
|
|
);
|
|
|
|
/**
|
|
* 开尔文转摄氏度
|
|
* @param {ee.Image} image Landsat LST image
|
|
* @returns {ee.Image} Landsat LST image in Celsius
|
|
*/
|
|
function kelvinToCelsius(image) {
|
|
return ee.Image(image.expression("B1 - 273.15", { B1: image.select("temperature") }))
|
|
.copyProperties(image)
|
|
.copyProperties(image, ["system:time_start", "system:index", "system:id"]);
|
|
}
|
|
|
|
// 加载 ERA5-Land 数据
|
|
var ERA5dataset = ee.ImageCollection("ECMWF/ERA5_LAND/MONTHLY_AGGR")
|
|
.filter(common_filter)
|
|
.select(ERA5Bands, commonBands);
|
|
print(start_date + " - " + end_date + " ERA5-Land dataset", ERA5dataset);
|
|
var ERA5Tempdataset = ERA5dataset.select("temperature").map(kelvinToCelsius);
|
|
var ERA5Raindataset = ERA5dataset.select("total_precipitation_sum");
|
|
|
|
// 合成年度平均 ERA5-Land 气温数据
|
|
var years = ee.List.sequence(start_year, end_year);
|
|
var yearlyTemp = ee.ImageCollection.fromImages(
|
|
years.map(function (y) {
|
|
return ERA5Tempdataset.filter(ee.Filter.calendarRange(y, y, "year"))
|
|
.mean()
|
|
.set("year", y);
|
|
})
|
|
);
|
|
var yearlyRain = ee.ImageCollection.fromImages(
|
|
years.map(function (y) {
|
|
return ERA5Raindataset.filter(ee.Filter.calendarRange(y, y, "year"))
|
|
.sum()
|
|
.set("year", y);
|
|
})
|
|
);
|
|
if (start_year == end_year) {
|
|
var year_str = start_year;
|
|
} else {
|
|
var year_str = start_year + "-" + end_year;
|
|
}
|
|
print(year_str + " Annual Mean ERA5-Land Temperature dataset", yearlyTemp);
|
|
print(year_str + " Annual Mean ERA5-Land Precipitation dataset", yearlyRain);
|
|
|
|
// 合成处理后会丢失投影信息, 需要重新设置投影
|
|
var proj = ERA5dataset.first().select(1).projection();
|
|
var annual_mean_temperature = ee.Image(yearlyTemp.mean()).setDefaultProjection(proj);
|
|
print(year_str + " Annual Mean ERA5-Land Temperature Histogram", ui.Chart.image.histogram(annual_mean_temperature, region, 10000, 258));
|
|
|
|
var annual_mean_precipitation = ee.Image(yearlyRain.mean()).setDefaultProjection(proj);
|
|
print(year_str + " Annual Mean ERA5-Land Precipitation Histogram", ui.Chart.image.histogram(annual_mean_precipitation, region, 10000, 258));
|
|
|
|
var annual_mean_temp_30m = annual_mean_temperature.clip(bounds).resample("bicubic").reproject({
|
|
crs: "EPSG:4326",
|
|
scale: target_res,
|
|
});
|
|
var annual_mean_precip_30m = annual_mean_precipitation.clip(bounds).resample("bicubic").reproject({
|
|
crs: "EPSG:4326",
|
|
scale: target_res,
|
|
});
|
|
|
|
var temperature_vis = {
|
|
min: -20,
|
|
max: 30,
|
|
palette: [
|
|
'040274', '040281', '0502a3', '0502b8', '0502ce', '0502e6',
|
|
'0602ff', '235cb1', '307ef3', '269db1', '30c8e2', '32d3ef',
|
|
'3be285', '3ff38f', '86e26f', '3ae237', 'b5e22e', 'd6e21f',
|
|
'fff705', 'ffd611', 'ffb613', 'ff8b13', 'ff6e08', 'ff500d',
|
|
'ff0000', 'de0101', 'c21301', 'a71001', '911003'
|
|
],
|
|
};
|
|
|
|
var precipitation_vis = {
|
|
min: 0,
|
|
max: 2,
|
|
palette: [
|
|
'000096', '0064ff', '00b4ff', '33db80', '9beb4a',
|
|
'ffeb00', 'ffb300', 'ff6400', 'eb1e00', 'af0000'
|
|
],
|
|
};
|
|
|
|
var styling = {
|
|
color: "blue",
|
|
fillColor: "00000000",
|
|
};
|
|
|
|
Map.centerObject(region, 9);
|
|
Map.addLayer(annual_mean_temperature, temperature_vis, year_str + " Annual Mean Temperature 0.1°");
|
|
Map.addLayer(annual_mean_precipitation, precipitation_vis, year_str + " Annual Mean Precipitation 0.1°");
|
|
Map.addLayer(annual_mean_temp_30m, temperature_vis, year_str + " Annual Mean Temperature " + target_res + "m");
|
|
Map.addLayer(annual_mean_precip_30m, precipitation_vis, year_str + " Annual Mean Precipitation " + target_res + "m");
|
|
Map.addLayer(region.style(styling), {}, region_name);
|
|
|
|
// 导出合并后的影像
|
|
// 明确设置数据类型为Float32, 否则默认类型为Float64, 会占用更多内存
|
|
// 并对缺失值进行填充, 否则默认为nan不便于后续本地处理
|
|
function exportCOG(image, description, folder, region, scale, crs) {
|
|
image = image.toFloat().unmask(-9999.0);
|
|
// 默认为 EPSG:4326 投影
|
|
crs = crs || "EPSG:4326";
|
|
Export.image.toDrive({
|
|
image: image,
|
|
description: description,
|
|
folder: folder,
|
|
region: region, // 添加后会自动裁剪
|
|
scale: scale,
|
|
crs: crs,
|
|
maxPixels: 1e13, // GEE 最多支持 1e8 像素, 当超过时会自动分块
|
|
fileFormat: "GeoTIFF",
|
|
// 导出COG云优化的GeoTIFF影像, 并明确设置缺失值为-9999.0
|
|
formatOptions: {
|
|
cloudOptimized: true,
|
|
noData: -9999.0,
|
|
},
|
|
});
|
|
}
|
|
|
|
print("Start exporting " + year_str + " Yearly Mean ERA5-Land Temperature (" + target_crs + " " + target_res + "m)", annual_mean_temp_30m);
|
|
exportCOG(
|
|
annual_mean_temp_30m,
|
|
region_name_en + "_ERA5_Temperature_" + year_str + "_" + target_res + "m",
|
|
"Temperature",
|
|
region,
|
|
target_res,
|
|
target_crs
|
|
);
|
|
print("Start exporting " + year_str + " Yearly Mean ERA5-Land Precipitation (" + target_crs + " " + target_res + "m)", annual_mean_precip_30m);
|
|
exportCOG(
|
|
annual_mean_precip_30m,
|
|
region_name_en + "_ERA5_Precipitation_" + year_str + "_" + target_res + "m",
|
|
"Precipitation",
|
|
region,
|
|
target_res,
|
|
target_crs
|
|
);
|