Sentinel-2是欧洲空间局(ESA)的一项地球观测任务,它提供了高分辨率的多光谱影像,覆盖了陆地、沿海和内陆水域。Sentinel-2数据可以用于多种应用,如土地覆盖变化、植被监测、农业管理、城市规划等。
本文使用Google Earth Engine(GEE)平台上的Sentinel-2数据和JavaScript语言。通过定义几何区域、年份、波段列表、开始日期和结束日期等参数,对影像集合进行了筛选和裁剪,然后使用自定义的函数对每个月的影像进行了平均合成
代码解析
首先定义一个矩形的几何区域(geometry),将对这个区域内的影像进行处理。可以在GEE平台上绘制几何区域,并导出其坐标值。
var geometry =
/* color: #00ffff */
/* shown: false */
/* displayProperties: [
{
"type": "rectangle"
}
] */
ee.Geometry.Polygon(
[[[119.31520539560792, 36.553716961237065],
[119.31520539560792, 36.27632745810304],
[119.60222321787354, 36.27632745810304],
[119.60222321787354, 36.553716961237065]]], null, false);
接下来,定义一个年份(year),这是要筛选的影像的年份。还定义一个波段列表(bandlist),这是要选择的影像的波段。Sentinel-2数据有13个波段,分别为B1-B12和B8A,其中B1-B4和B8A是10米分辨率,B5-B7和B8-B12是20米分辨率,B1是60米分辨率。在本文中,我们只选择了B2-B4三个波段,分别对应于蓝色、绿色和红色。
var year = 2020
var bandlist = ['B2','B3', 'B4'] //, 'B3', 'B4','B5','B6','B7','B8','B8A','B11','B12'
然后,定义一个开始日期(start)和一个结束日期(finish),这是要筛选的影像的时间范围。本文选择了2020年4月1日到2020年12月1日之间的影像。
var start = ee.Date(year + '-4-01');
var finish = ee.Date(year + '-12-1');
接着,我们使用ee.ImageCollection函数引用了哨兵2影像集合(dataset),并使用filterDate函数、filterBounds函数和filter函数对其进行了筛选。保留了开始日期和结束日期之间、几何区域内、云量小于20%的影像。还使用map函数对每个影像应用了一个maskS2函数,该函数用于裁剪影像到几何区域内。
var dataset = ee.ImageCollection('COPERNICUS/S2_SR')
.filterDate(start, finish)
.filterBounds(geometry)
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
.map(maskS2)
function maskS2(image) {
return image.clip(geometry);
}
使用select函数从影像集合中选择需要的波段,并创建了一个新的影像集合(dataset10)。本文只选择了B2-B4三个波段。
var dataset10 = dataset.select(bandlist);
然后使用difference函数计算了开始日期和结束日期之间的月份差(diff),并使用sequence函数和map函数创建了一个日期列表(range),该列表包含了开始日期到结束日期之间的每个月的第一天。例如,如果开始日期是2020年4月1日,结束日期是2020年12月1日,那么日期列表就是[2020-04-01, 2020-05-01, 2020-06-01, …, 2020-11-01]。
var diff = finish.difference(start, 'month')
var range = ee.List.sequence(0, diff.subtract(1)).map(function (month) { return start.advance(month, 'month') })
print("range", range)
接下来使用iterate函数对日期列表进行迭代,对每个月的影像进行合成,并创建了一个新的影像集合(newcol10)。使用自定义函数day_mosaics10接受一个日期和一个列表作为参数,返回一个更新的列表。该函数的逻辑如下:
- 将日期转换为ee.Date类型
- 将列表转换为ee.List类型
- 使用filterDate函数从影像集合中筛选出该日期到下个月第一天之间的影像
- 使用mean函数对筛选出的影像进行平均,得到一个单个的影像,并设置其日期属性为该日期的格式化字符串
- 使用toUint16函数将影像转换为无符号16位整数类型
- 使用If函数判断筛选出的影像是否为空,如果不为空,则将影像添加到列表中,如果为空,则返回原来的列表
//main data
var newcol10 = ee.ImageCollection(ee.List(range.iterate(day_mosaics10, ee.List([]))))
print("newcoln10", newcol10)
function day_mosaics10(date, newlist) {
// Cast
date = ee.Date(date)
newlist = ee.List(newlist)
// Filter collection between date and the next day
var filtered = dataset10.filterDate(date, date.advance(1, 'month'))
var image = ee.Image(filtered.mean()).set({ "date": date.format("YYYY-MM-dd") }).toUint16()
// Add the mosaic to a list only if the collection has images
return ee.List(ee.Algorithms.If(filtered.size(), newlist.add(image), newlist))
}
最后使用centerObject函数将地图视图中心设置为几何区域,并使用addLayer函数将新的影像集合中的第一个影像添加到地图上。定义了一个可视化参数(rgbVis),用于指定最小值、最大值和波段。还打印了影像集合中第一个影像的投影信息和分辨率。
Map.centerObject(geometry)
// Map.addLayer(dataset10.first(), {}, 'test');
var scaledataset10 = dataset10.first().projection().nominalScale();
print("scale", scaledataset10)
var rgbVis = {
min: 0.0,
max: 3000,
bands: ['B4', 'B3', 'B2'],
};
var image = newcol10.first()
// print("影像",bandsimage)
Map.addLayer(image, rgbVis, 'bandsimage');
结果展示
运行上述代码后,我们可以在GEE平台上看到如下结果:
这是2020年4月份的影像合成结果,我们可以看到几何区域内的土地覆盖情况。我们还可以在控制台中看到新的影像集合(newcol10)的信息,它包含了8个影像,分别对应于2020年4月到11月的每个月份。我们可以点击每个影像查看其属性和波段信息,也可以在地图上切换不同月份的影像查看其变化。
代码附录
var year = 2020
var bandlist = ['B2','B3', 'B4'] //, 'B3', 'B4','B5','B6','B7','B8','B8A','B11','B12'
// var bandlist='B2'
var start = ee.Date(year + '-4-01');
var finish = ee.Date(year + '-12-1');
var dataset = ee.ImageCollection('COPERNICUS/S2_SR')
.filterDate(start, finish)
.filterBounds(geometry)
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
.map(maskS2)
var dataset10 = dataset.select(bandlist);
var diff = finish.difference(start, 'month')
var range = ee.List.sequence(0, diff.subtract(1)).map(function (month) { return start.advance(month, 'month') })
print("range", range)
//main data
var newcol10 = ee.ImageCollection(ee.List(range.iterate(day_mosaics10, ee.List([]))))
print("newcoln10", newcol10)
Map.centerObject(geometry)
// Map.addLayer(dataset10.first(), {}, 'test');
var scaledataset10 = dataset10.first().projection().nominalScale();
print("scale", scaledataset10)
var rgbVis = {
min: 0.0,
max: 3000,
bands: ['B4', 'B3', 'B2'],
};
var image = newcol10.first()
// print("影像",bandsimage)
Map.addLayer(image, rgbVis, 'bandsimage');
function day_mosaics10(date, newlist) {
// Cast
date = ee.Date(date)
newlist = ee.List(newlist)
// Filter collection between date and the next day
var filtered = dataset10.filterDate(date, date.advance(1, 'month'))
var image = ee.Image(filtered.mean()).set({ "date": date.format("YYYY-MM-dd") }).toUint16()
// Add the mosaic to a list only if the collection has images
return ee.List(ee.Algorithms.If(filtered.size(), newlist.add(image), newlist))
}
function maskS2(image) {
return image.clip(geometry);
}