JRC全球地表水数据集(Global Surface Water Explorer)是欧盟联合研究中心(Joint Research Centre)基于Landsat系列卫星影像开发的权威水体监测产品。这个数据集最吸引我的地方在于它整合了跨越37年(1984-2021)的471万+卫星影像,通过专家系统对每个30m×30m的像元进行水/非水分类,形成了时空连续的水体变化记录。
重要提示:最新版本GSW1.4包含5个子数据集(Monthly/Yearly/Change/Transition/MaxExtent),其中YearlyHistory最适合做年际变化分析,这也是本文重点使用的数据集。
我在实际项目中发现,这套数据有三个独特价值:
在Google Earth Engine(GEE)中处理地理数据时,研究区边界是首要条件。我推荐两种获取方式:
javascript复制// 方式1:直接绘制多边形
var geometry = ee.Geometry.Polygon(
[[[经度1,纬度1], [经度2,纬度2], ...]],
null, false
);
// 方式2:导入已有矢量文件(如广东省边界)
var geometry = ee.FeatureCollection('users/你的用户名/guangdongsheng')
避坑指南:务必检查geometry的坐标参考系(CRS),WGS84(EPSG:4326)是最通用的选择。我曾遇到因CRS不匹配导致裁剪错位的问题,后来养成了用
geometry.projection().getInfo()验证的习惯。
通过以下代码可获取1984-2021年的年度水体数据:
javascript复制var dataset = ee.ImageCollection('JRC/GSW1_4/YearlyHistory')
.filterBounds(geometry) // 空间过滤
.filterDate('1990-01-01','2021-12-31') // 时间过滤
.map(function(image){
return image.clip(geometry) // 裁剪研究区
.set('year', image.date().get('year')); // 添加年份属性
});
关键技巧:
print(dataset)查看影像数量及属性,避免空集合image.date().get('year')添加年份属性,方便后续按时间筛选在导出数据前,务必进行可视化验证:
javascript复制var visParams = {
bands: ['waterClass'],
min: 0,
max: 3,
palette: ['cccccc', 'ffffff', '99d9ea', '0000ff'] // 灰/白/浅蓝/深蓝
};
Map.addLayer(dataset.first(), visParams, '1990年水体');
Map.addLayer(dataset.filter(ee.Filter.eq('year',2020)).first(), visParams, '2020年水体');
颜色对照表:
传统单张导出方式效率低下,推荐安装geetools扩展库:
javascript复制var batch = require('users/fitoprincipe/geetools:batch');
batch.Download.ImageCollection.toDrive(dataset, "JRC_Export", {
name: 'JRC_{system:index}_{year}', // 使用影像ID+年份命名
region: geometry,
scale: 30,
crs: "EPSG:4326",
maxPixels: 1e13
});
参数详解:
name:支持变量替换,{system:index}是影像唯一ID,{year}是我们添加的属性scale:必须设为30m以保持原始分辨率maxPixels:增大该值可避免大区域导出失败当需要导出多年数据时,手动点击每个任务极其耗时。通过浏览器控制台运行以下脚本可自动提交所有任务:
javascript复制function autoRunTasks() {
// 获取所有运行按钮
var runButtons = document.querySelector('#task-pane')
.shadowRoot.querySelectorAll(".run-button");
// 依次点击运行
runButtons.forEach(function(btn) {
btn.click();
// 自动确认弹窗(5秒间隔)
setTimeout(function(){
var dialogs = document.querySelectorAll("ee-image-config-dialog");
dialogs.forEach(function(dialog){
dialog.shadowRoot.querySelector("ee-dialog")
.shadowRoot.querySelector("paper-dialog")
.querySelector(".ok-button").click();
});
}, 5000);
});
}
autoRunTasks();
实测经验:建议每次批量提交不超过10个任务,避免GEE服务器限制。我曾因一次性提交30+任务导致部分任务失败。
| 错误类型 | 可能原因 | 解决方案 |
|---|---|---|
Error: Export too large |
研究区过大/分辨率过高 | 减小区域或降低scale值 |
Invalid CRS |
坐标系统不匹配 | 明确指定crs: "EPSG:4326" |
Task timed out |
服务器繁忙 | 分时段重试或减小数据量 |
当发现某些年份数据缺失时:
print(dataset.aggregate_array('year')).filterDate('1989-12-01','1990-02-28')如果水体分类明显错误:
通过比较不同时期的水体面积,可计算变化率:
javascript复制var water1990 = dataset.filter(ee.Filter.eq('year',1990))
.mosaic()
.eq(3); // 永久水体
var water2020 = dataset.filter(ee.Filter.eq('year',2020))
.mosaic()
.eq(3);
var loss = water1990.and(water2020.not()); // 消失的水体
var gain = water1990.not().and(water2020); // 新增的水体
Map.addLayer(loss, {palette: 'red'}, '水体消失区域');
Map.addLayer(gain, {palette: 'green'}, '水体新增区域');
将JRC数据与其他数据集叠加分析:
javascript复制var dem = ee.Image('USGS/SRTMGL1_003').clip(geometry);
var slope = ee.Terrain.slope(dem);
// 分析水体分布与坡度的关系
var water = dataset.filter(ee.Filter.eq('year',2020)).mosaic().eq(3);
var stats = water.addBands(slope).reduceRegion({
reducer: ee.Reducer.mean().combine({
reducer2: ee.Reducer.histogram(),
sharedInputs: true
}),
geometry: geometry,
scale: 30,
maxPixels: 1e9
});
在完成多个项目后,我总结了三点核心经验:1)始终进行可视化验证;2)合理设置导出参数避免失败;3)善用属性系统管理时间序列数据。这套方法同样适用于其他遥感数据集的处理。