From 566a75f6fc92a62a8218e019db46c63a9478cbbb Mon Sep 17 00:00:00 2001 From: gis-xh Date: Fri, 16 Jan 2026 15:27:17 +0800 Subject: [PATCH] =?UTF-8?q?refactor(LST=5Fdownload):=20=E4=BC=98=E5=8C=96L?= =?UTF-8?q?ST=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86=E6=B5=81=E7=A8=8B,=20?= =?UTF-8?q?=E5=B0=81=E8=A3=85=E5=A4=8D=E7=94=A8=E5=87=BD=E6=95=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GEE_Scripts/LST_download.js | 197 +++++++++++++++++++----------------- 1 file changed, 106 insertions(+), 91 deletions(-) diff --git a/GEE_Scripts/LST_download.js b/GEE_Scripts/LST_download.js index 74df598..4fa51e8 100644 --- a/GEE_Scripts/LST_download.js +++ b/GEE_Scripts/LST_download.js @@ -2,7 +2,7 @@ * 地表温度 (LST) 数据下载 —— 以年平均温度处理下载为例 * * @author CVEO Team - * @date 2026-01-15 + * @date 2026-01-16 * * 1. 加载并合并 Landsat-8, 9 30m LST 数据 * 2. 加载 MODIS MOD11A2 1km LST 数据 @@ -11,14 +11,16 @@ */ // 加载研究区域和影像 -var region_name = "应城市"; -var region_name_en = "Yingcheng"; -var region = Yingcheng; -var crs = "EPSG:4526"; -// var region_name = "保康县"; -// var region_name_en = "Baokang"; -// var region = Baokang; -// var crs = "EPSG:4525"; +// var region_name = "应城市"; +// var region_name_en = "Yingcheng"; +// var region = Yingcheng; +// var crs = "EPSG:4526"; +var region_name = "保康县"; +var region_name_en = "Baokang"; +var region = Baokang; +var crs = "EPSG:4525"; +var target_res = 30; +var orign_res = 1000; var start_year = 2021; var end_year = 2025; var start_date = start_year + "-01-01"; @@ -27,9 +29,9 @@ var cloud_threshold = 90; // 最大云量阈值 var LansatBands = ["ST_B10"]; var MODISBands = ["LST_Day_1km"]; var commonBands = ["LST"]; - +// 设置研究区域的缓冲区, 确保粗分辨率数据能够完整覆盖研究区域 var region_geo = region.geometry(); -var bounds = region_geo.bounds(); +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) @@ -81,9 +83,11 @@ function maskLandsatclouds(image) { // Bits 3 and 4 are cloud and cloud shadow, respectively. var cloudBitMask = 1 << 3; var shadowBitMask = 1 << 4; + var snowBitMask = 1 << 5; // Both flags should be set to zero, indicating clear conditions. var mask = qa.bitwiseAnd(cloudBitMask).eq(0) .and(qa.bitwiseAnd(shadowBitMask).eq(0)) + .and(qa.bitwiseAnd(snowBitMask).eq(0)) .and(qa_radsat.eq(0)); image = image.updateMask(mask); return image @@ -91,6 +95,34 @@ function maskLandsatclouds(image) { .copyProperties(image, ["system:time_start", "system:index", "system:id"]); } +/** + * 合成年度平均数据 + * @param {ee.ImageCollection} imageCollection 数据集合 + * @param {number} start_year 开始年份 + * @param {number} end_year 结束年份 + * @returns {ee.ImageCollection} 合成年度平均数据集合 + */ +function compositeYearly(imageCollection, start_year, end_year) { + var years = ee.List.sequence(start_year, end_year); + var months = ee.List.sequence(1, 12); + var yearlyImgCol = ee.ImageCollection.fromImages( + years.map(function (y) { + return ee.ImageCollection.fromImages( + months.map(function (m) { + return imageCollection + .filter(ee.Filter.calendarRange(y, y, "year")) + .filter(ee.Filter.calendarRange(m, m, "month")) + .mean() + .clip(bounds) + .set("month", m) + .set("year", y); + }) + ).mean().set("year", y); + }) + ); + return yearlyImgCol; +} + // 加载 Landsat-8, Landsat-9 SR 数据 var L8dataset = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2") .filter(common_filter) @@ -101,6 +133,27 @@ var L9dataset = ee.ImageCollection("LANDSAT/LC09/C02/T1_L2") .filter(ee.Filter.lt("CLOUD_COVER", cloud_threshold)); print(start_date + " - " + end_date + " Landsat-9 SR dataset", L9dataset); +// 加载 Landsat-8, Landsat-9 T2_L2 数据 (Tier 2) +var L8T2dataset = ee.ImageCollection("LANDSAT/LC08/C02/T2_L2") + .filter(common_filter) + .filter(ee.Filter.lt("CLOUD_COVER", cloud_threshold)); +print(start_date + " - " + end_date + " Landsat-8 T2_L2 SR dataset", L8T2dataset); +var L9T2dataset = ee.ImageCollection("LANDSAT/LC09/C02/T2_L2") + .filter(common_filter) + .filter(ee.Filter.lt("CLOUD_COVER", cloud_threshold)); +print(start_date + " - " + end_date + " Landsat-9 T2_L2 SR dataset", L9T2dataset); + +// 合并 Landsat-8, Landsat-9 LST 数据 (包括 T1_L2 和 T2_L2) +var LSTdataset = L8dataset.merge(L9dataset) + .merge(L8T2dataset) + .merge(L9T2dataset) + .filter(ee.Filter.eq("PROCESSING_LEVEL", "L2SP")) + .map(applyScaleFactors) + .map(maskLandsatclouds) + .select(LansatBands, commonBands) + .map(kelvinToCelsius); +print(start_date + " - " + end_date + " Landsat-8,9 T1_L2 & T2_L2 LST dataset", LSTdataset); + // 加载 MODIS LST 数据 var MODISLSTdataset = ee.ImageCollection('MODIS/061/MOD11A2') .filter(common_filter) @@ -109,32 +162,8 @@ var MODISLSTdataset = ee.ImageCollection('MODIS/061/MOD11A2') .map(kelvinToCelsius); print(start_date + " - " + end_date + " MODIS LST dataset", MODISLSTdataset); -// 合并 Landsat-8, Landsat-9 LST 数据 -var LSTdataset = L8dataset.merge(L9dataset) - .map(applyScaleFactors) - .map(maskLandsatclouds) - .select(LansatBands, commonBands) - .map(kelvinToCelsius); -print(start_date + " - " + end_date + " Landsat-8,9 LST dataset", LSTdataset); - // 合成年度平均 Landsat LST 数据 -var years = ee.List.sequence(start_year, end_year); -var months = ee.List.sequence(1, 12); -var yearlyLST = ee.ImageCollection.fromImages( - years.map(function (y) { - return ee.ImageCollection.fromImages( - months.map(function (m) { - return LSTdataset - .filter(ee.Filter.calendarRange(y, y, "year")) - .filter(ee.Filter.calendarRange(m, m, "month")) - .mean() - .clip(bounds) - .set("month", m) - .set("year", y); - }) - ).mean().set("year", y); - }) -); +var yearlyLST = compositeYearly(LSTdataset, start_year, end_year); if (start_year == end_year) { var year_str = start_year; } else { @@ -143,35 +172,29 @@ if (start_year == end_year) { print(year_str + " Annual Mean Landsat LST dataset", yearlyLST); // 合成年度平均 MODIS LST 数据 -var yearlyMODISLST = ee.ImageCollection.fromImages( - years.map(function (y) { - return ee.ImageCollection.fromImages( - months.map(function (m) { - return MODISLSTdataset - .filter(ee.Filter.calendarRange(y, y, "year")) - .filter(ee.Filter.calendarRange(m, m, "month")) - .mean() - .clip(bounds) - .set("month", m) - .set("year", y); - }) - ).mean().set("year", y); - }) -); +var yearlyMODISLST = compositeYearly(MODISLSTdataset, start_year, end_year); print(year_str + " Annual Mean MODIS LST dataset", yearlyMODISLST); -var total_mean_LST = LSTdataset.select("LST").mean(); +// 合成处理后会丢失投影信息, 需要重新设置投影 +var lst_proj = LSTdataset.first().select(0).projection(); +var modis_proj = MODISLSTdataset.first().select(0).projection(); +var total_mean_LST = LSTdataset.select("LST").mean().setDefaultProjection(lst_proj); print(year_str + " Total Year Mean Landsat LST Histogram", ui.Chart.image.histogram(total_mean_LST, region, 100, 258)); -var annual_mean_LST = yearlyLST.select("LST").mean(); +var annual_mean_LST = yearlyLST.select("LST").mean().setDefaultProjection(lst_proj); print(year_str + " Annual Mean Landsat LST Histogram", ui.Chart.image.histogram(annual_mean_LST, region, 100, 258)); -var total_mean_MODIS_LST = MODISLSTdataset.select("LST").mean(); +var total_mean_MODIS_LST = MODISLSTdataset.select("LST").mean().setDefaultProjection(modis_proj); print(year_str + " Total Year Mean MODIS LST Histogram", ui.Chart.image.histogram(total_mean_MODIS_LST, region, 1000, 258)); -var annual_mean_MODIS_LST = yearlyMODISLST.select("LST").mean(); +var annual_mean_MODIS_LST = yearlyMODISLST.select("LST").mean().setDefaultProjection(modis_proj); print(year_str + " Annual Mean MODIS LST Histogram", ui.Chart.image.histogram(annual_mean_MODIS_LST, region, 1000, 258)); +var annual_mean_MODIS_LST_30m = annual_mean_MODIS_LST.resample("bicubic").reproject({ + crs: "EPSG:4326", + scale: target_res, +}); + var lst_vis = { min: 5, max: 35, @@ -190,47 +213,39 @@ var styling = { }; Map.centerObject(region, 10); -Map.addLayer(total_mean_LST, lst_vis, year_str + " Landsat Total Year Mean LST"); -Map.addLayer(annual_mean_LST, lst_vis, year_str + " Landsat Annual Mean LST"); Map.addLayer(total_mean_MODIS_LST, lst_vis, year_str + " MODIS Total Year Mean LST"); Map.addLayer(annual_mean_MODIS_LST, lst_vis, year_str + " MODIS Annual Mean LST"); +Map.addLayer(annual_mean_MODIS_LST_30m, lst_vis, year_str + " MODIS Annual Mean LST 30m"); +Map.addLayer(total_mean_LST, lst_vis, year_str + " Landsat Total Year Mean LST"); +Map.addLayer(annual_mean_LST, lst_vis, year_str + " Landsat Annual Mean LST"); Map.addLayer(region.style(styling), {}, region_name); // 导出合并后的影像 // 明确设置数据类型为Float32, 否则默认类型为Float64, 会占用更多内存 // 并对缺失值进行填充, 否则默认为nan不便于后续本地处理 -var processed_img = annual_mean_LST.toFloat().unmask(-9999.0); -print("Start exporting " + year_str + "Yearly Mean LST image (" + crs + ")", processed_img); -Export.image.toDrive({ - image: processed_img, - description: region_name_en + "_Landsat_LST_" + year_str + "_30m", - folder: "LST", - region: region, // 添加后会自动裁剪 - scale: 30, - crs: crs, - maxPixels: 1e13, // GEE 最多支持 1e8 像素, 当超过时会自动分块 - fileFormat: "GeoTIFF", - // 导出COG云优化的GeoTIFF影像, 并明确设置缺失值为-9999.0 - formatOptions: { - cloudOptimized: true, - noData: -9999.0, - }, -}); +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, + }, + }); +} -// 导出 MODIS 合并后的影像 -var processed_modis_img = annual_mean_MODIS_LST.toFloat().unmask(-9999.0); -print("Start exporting " + year_str + " MODIS Yearly Mean LST image (" + crs + ")", processed_modis_img); -Export.image.toDrive({ - image: processed_modis_img, - description: region_name_en + "_MODIS_LST_" + year_str + "_1km", - folder: "LST", - region: region, - scale: 1000, - crs: crs, - maxPixels: 1e13, - fileFormat: "GeoTIFF", - formatOptions: { - cloudOptimized: true, - noData: -9999.0, - }, -}); +print("Start exporting " + year_str + "Yearly Mean LST image (" + crs + ")", annual_mean_LST); +exportCOG(annual_mean_LST, region_name_en + "_Landsat_LST_" + year_str + "_30m", "LST", region, 30, crs); + +print("Start exporting " + year_str + " MODIS Yearly Mean LST image (" + crs + ")", annual_mean_MODIS_LST); +exportCOG(annual_mean_MODIS_LST, region_name_en + "_MODIS_LST_" + year_str + "_1km", "LST", region, 1000, crs); \ No newline at end of file