feat(GEE_Scripts): 添加Sentinel-2影像下载脚本.

This commit is contained in:
谢泓 2025-12-09 12:44:26 +08:00
parent ff1dea2324
commit 11118915b3

View File

@ -0,0 +1,129 @@
/**
* Sentinel-2 哨兵二号数据下载 以下载 2025 年湖北省无云RGB三波段影像为例
*
* GEE 最新代码: https://code.earthengine.google.com/15b61c853c281deb3ef8fc416224c405
*
* @author CVEO Team
* @date 2025-12-08
*
* 1. 加载 Sentinel-2 数据与 Cloud Score+ 云掩膜
* 2. 合成年度无云影像
* 3. 导出COG云优化并填补缺失值的GeoTIFF影像分块
*/
// 加载研究区域和影像
var region_name = "湖北省";
var region_name_en = "Hubei";
var region = allCites.filter(ee.Filter.eq("省", region_name));
var year = 2025;
var start_date = year + "-01-01";
var end_date = year + "-12-31";
var cloud_threshold = 5; // 5% 云量
// Use 'cs' or 'cs_cdf', depending on your use case; see docs for guidance.
var QA_BAND = "cs_cdf";
// The threshold for masking; values between 0.50 and 0.65 generally work well.
// Higher values will remove thin clouds, haze & cirrus shadows.
var CLEAR_THRESHOLD = 0.8;
// Sentinel-2的B8A波段(20m)可能更适合代表近红外波段
// var s2Bands = ["B2", "B3", "B4", "B8", "B11", "B12"];
var s2Bands = ["B2", "B3", "B4", "B8A", "B11", "B12"];
var commonBands = ["Blue", "Green", "Red", "NIR", "SWIR1", "SWIR2"];
var region_geo = region.geometry();
var bounds = region_geo.bounds();
var common_filter = ee.Filter.and(
ee.Filter.bounds(bounds),
ee.Filter.date(start_date, end_date)
);
/**
* 基于 Cloud Score+ 云掩膜
* @param {ee.Image} image Sentinel-2 image
* @return {ee.Image} cloud masked Sentinel-2 image
*/
function maskS2cloudsByCS(image) {
var cloudMask = image.select(QA_BAND).gte(CLEAR_THRESHOLD);
image = image.updateMask(cloudMask);
return image
.copyProperties(image)
.copyProperties(image, ["system:time_start", "system:index", "system:id"]);
}
// 加载Sentinel-2 L2A数据与Cloud Score+云掩膜
// Cloud Score+ image collection.
// Note Cloud Score+ is produced from Sentinel-2 level 1C data and can be applied to either L1C or L2A collections.
var S2csPlus = ee.ImageCollection("GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED");
var S2dataset = ee
.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
.filter(common_filter)
.filter(ee.Filter.lt("CLOUDY_PIXEL_PERCENTAGE", cloud_threshold))
.select(s2Bands, commonBands)
.linkCollection(S2csPlus, [QA_BAND])
.map(maskS2cloudsByCS);
var s2_img = ee.Image(S2dataset.median());
var s2_img_rgb = s2_img.select(["Red", "Green", "Blue"]);
var s2_img_frgb = s2_img.select(["NIR", "Red", "Green"]);
var true_rgb_vis = {
bands: ["Red", "Green", "Blue"],
min: 0.0,
max: 3000,
};
var false_rgb_vis = {
min: 0.0,
max: 4000,
gamma: 1.4,
bands: ["NIR", "Red", "Green"],
};
var styling = {
color: "red",
fillColor: "00000000",
};
Map.centerObject(region, 7);
Map.addLayer(s2_img_frgb, false_rgb_vis, year + " Sentinel-2 False RGB", false);
Map.addLayer(s2_img_rgb, true_rgb_vis, year + " Sentinel-2 True RGB");
Map.addLayer(region.style(styling), {}, region_name);
// 导出裁剪处理后的Sentinel-2 RGB影像
var fileName = region_name_en + "_Sentinel-2_" + year;
// 区域过大, 需要先将 s2_img 划分为四块网格分开下载
var coords = ee.List(bounds.coordinates().get(0));
var minX = ee.Number(ee.List(coords.get(0)).get(0));
var minY = ee.Number(ee.List(coords.get(0)).get(1));
var maxX = ee.Number(ee.List(coords.get(2)).get(0));
var maxY = ee.Number(ee.List(coords.get(2)).get(1));
var midX = minX.add(maxX).divide(2);
var midY = minY.add(maxY).divide(2);
var grid1 = ee.Geometry.Rectangle([minX, minY, midX, midY]);
var grid2 = ee.Geometry.Rectangle([midX, minY, maxX, midY]);
var grid3 = ee.Geometry.Rectangle([minX, midY, midX, maxY]);
var grid4 = ee.Geometry.Rectangle([midX, midY, maxX, maxY]);
var grids = [grid1, grid2, grid3, grid4];
for (var i = 0; i < grids.length; i++) {
var grid_region = grids[i];
// 明确设置数据类型为Float32, 否则默认类型为Float64, 会占用更多内存
// 并对缺失值进行填充, 否则默认为nan不便于后续本地处理
var clipped_img = s2_img_rgb.clip(grid_region).toFloat().unmask(-9999.0);
var grid_fileName = fileName + "_grid_" + (i + 1);
Export.image.toDrive({
image: clipped_img,
description: grid_fileName,
folder: "Sentinel-2",
region: grid_region,
scale: 10,
maxPixels: 1e13, // GEE 最多支持 1e8 像素, 当超过时会自动分块
fileFormat: "GeoTIFF",
// 导出COG云优化的GeoTIFF影像, 并明确设置缺失值为-9999.0
formatOptions: {
cloudOptimized: true,
noData: -9999.0,
},
});
}