/** * 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, }, }); }