GEE学习3-ImageCollection的可视化3-高级功能
三、高级功能
最后这一部分将讲一下如何通过裁剪、透明度和图层合成等方法,实现添加多边形边界、强调感兴趣区和比较集合中的影像等增加可视化效果的效果。
下面的内容均使用非洲冬季的温度变化作为例子,详细的信息可查阅前两节内容。(官方使用温度作为例子真是太切题了)
首先导入影像
var tempCol = ee.ImageCollection('NOAA/GFS0P25')
.filterDate('2018-12-22', '2018-12-23')
.limit(24)
.select('temperature_2m_above_ground');
//定义可视化参数
var visArgs = {
min: -40.0,
max: 35.0,
palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red']
};
//将图像转换为RGB可视化图像并复制的函数
//从原始图像到RGB图像。
var tempColVis= tempCol.map(function(img) {
return img.visualize(visArgs);
});
//以非洲作为研究区域
var AfricaCol=ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017')
.filterMetadata('wld_rgn','equals','Africa');
//确定制作的动画的区域
var Africaroi=ee.Geometry.Rectangle({ coords: [-27.3, -39.3, 56.7, 43.1], geodesic: false});
(1)叠加(Overlay)
叠加分为矢量的叠加和栅格的叠加。
叠加矢量数据(要素)一般使用的是paint方法。尽管这些要素可以直接绘制在现有图像上,但是官方建议的更好的方法是将矢量要素绘制在空白图像上,对其进行样式设置,然后将结果与其他样式化的图像叠加。
// 定义一个空图像以绘制特征
var empty = ee.Image().byte();
// 将边界绘制到空图像上
var AfricaOutline = empty
.paint({featureCollection: AfricaCol, color: 1, width: 1})
//将图像转为RGB格式,并将线的颜色设置为黑
.visualize({palette: '000000'});
//使用混合(blend)操作将边界线图像覆盖至整个温度影像集上
var tempColOutline = tempColVis.map(function(img) {
return img.blend(AfricaOutline);
});
// 设置动画参数
var videoArgs = {
dimensions: 768,
region: Africaroi,
framesPerSecond: 7,
crs: 'EPSG:3857'
};
print(ui.Thumbnail(tempColOutline, videoArgs));
还有一种是图像的叠加
// 定义一个空图像以绘制特征
var empty = ee.Image().byte();
// 将边界绘制到空图像上
var AfricaOutline = empty
.paint({featureCollection: AfricaCol, color: 1, width: 1})
//将图像转为RGB格式,并将线的颜色设置为黑
.visualize({palette: '000000'});
//使用混合(blend)操作将边界线图像覆盖至整个温度影像集上
var tempColOutline = tempColVis.map(function(img) {
return img.blend(AfricaOutline);
});
///////////////////前面的步骤与vector叠加相同///////////
//定义一个半透明的灰色RGB图像,以使基础图像变暗
var dullLayer = ee.Image.constant(175).visualize({
opacity: 0.6, min: 0, max: 255, forceRgbOutput: true});
//将上述图像映射到温度图像集上
var finalVisCol = tempColOutline.map(function(img) {
return img
// 叠加灰度图
.blend(dullLayer)
// 再叠加一层清晰的非洲地区温度图像
//clipToCollection:将温度影像按照非洲的边界进行裁剪
.blend(img.clipToCollection(AfricaCol));
});
///////////////////后面的步骤也与vector叠加相同///////////
// 设置动画参数
var videoArgs = {
dimensions: 768,
region: Africaroi,
framesPerSecond: 7,
crs: 'EPSG:3857'
};
print(ui.Thumbnail(finalVisCol, videoArgs));
当然也可以叠加地形层
var hillshade = ee.Terrain.hillshade(ee.Image('USGS/SRTMGL1_003')
//放大高程以增加山体阴影的对比度
.multiply(100))
//裁剪DEM
.clipToCollection(AfricaCol);
var finalVisCol = tempColVis.map(function(img) {
return hillshade
.blend(img.clipToCollection(AfricaCol).visualize({opacity: 0.6}));
});
// 设置动画属性
var videoArgs = {
dimensions: 768,
region: Africaroi,
framesPerSecond: 7,
crs: 'EPSG:3857'
};
print(ui.Thumbnail(finalVisCol, videoArgs));
(2)转场
在GEE中,官方给出转场的效果有闪烁(flicker)、淡入(Fade)、划入(Slider)。事实上,官方并没有给出封装好的直接实现这些转场的方法,需要自己想办法去实现。。。所以理论上所有的转场效果应该都能实现233
闪烁(flicker)转场的设置比较简单,如果只有两个图像默认使用flicker转场效果,只需要设定动画的参数即可,使用framesPerSecond可以调整转场的速度快慢
//准备数据
var aoi = ee.Geometry.Polygon(
[[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null, false);
var temp = ee.ImageCollection('NOAA/GFS0P25')
var summerSolTemp = temp
.filterDate('2018-06-21', '2018-06-22')
.filterMetadata('forecast_hours', 'equals', 12)
.first()
.select('temperature_2m_above_ground');
var winterSolTemp = temp
.filterDate('2018-12-22', '2018-12-23')
.filterMetadata('forecast_hours', 'equals', 12)
.first()
.select('temperature_2m_above_ground');
var tempCol = ee.ImageCollection([
summerSolTemp.set('season', 'summer'),
winterSolTemp.set('season', 'winter')
]);
var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');
var visArgs = {
min: -40.0,
max: 35.0,
palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red']
};
var tempColVis = tempCol.map(function(img) {
return img .visualize(visArgs)
.clipToCollection(countries)
.unmask(0)
.copyProperties(img, img.propertyNames());
});
//调整动画参数
var videoArgs = {
dimensions: 768,
region: aoi,
framesPerSecond: 2,
crs: 'EPSG:3857'
};
print(ui.Thumbnail(tempColVis, videoArgs));
淡入(Fade)转场则需要构建一个从0到1的不透明度增量序列,通过降低一层的不透明度同时增加另一层的不透明度的方式,实现两层之间的淡入淡出的效果。
//这里需注意不透明度不能直接设置为0和1
var opacityList = ee.List.sequence({start: 0.99999, end: 0.00001, count: 20});
var summerImg = tempColVis.filter(ee.Filter.eq('season', 'summer')).first();
var winterImg = tempColVis.filter(ee.Filter.eq('season', 'winter')).first();
//以迭代方式调整的不透明度
var imgList = opacityList.map(function(opacity) {
var opacityCompliment = ee.Number(1).subtract(ee.Number(opacity));
var winterImgFade = winterImg.visualize({opacity: opacity});
var summerImgFade = summerImg.visualize({opacity: opacityCompliment});
return summerImgFade.blend(winterImgFade).set('opacity', opacity); });
var fadeForward = ee.ImageCollection.fromImages(imgList);
//生成另一个集合,该集合按不透明度递增的顺序排序,代表反向
var fadeBackward = fadeForward.sort({property: 'opacity'});
var fadeCol = fadeForward.merge(fadeBackward);
var videoArgs = {
dimensions: 768,
region: aoi,
framesPerSecond: 25,
crs: 'EPSG:3857'
};
print(ui.Thumbnail(fadeCol, videoArgs));
划入(Slider)转场是通过在一定的经度范围内迭代调整覆盖图像的不透明度来实现的,整体思路与淡入转场类似。下面的例子给出了左右划入的转场效果,如果想实现上下划入的效果只要把经度改成纬度即可:
var lonSeq = ee.List.sequence({start: -179, end: 179, count: 20});
var longitude = ee.Image.pixelLonLat().select('longitude');
var summerImg = tempColVis.filter(ee.Filter.eq('season', 'summer')).first();
var winterImg = tempColVis.filter(ee.Filter.eq('season', 'winter')).first();
var imgList = lonSeq.map(function(lon) {
lon = ee.Number(lon);
var mask = longitude.gt(lon);
return summerImg.blend(winterImg.updateMask(mask)).set('lon', lon);
});
var sliderColForward = ee.ImageCollection.fromImages(imgList);
var sliderColbackward = sliderColForward .sort({property: 'lon', ascending: false});
var sliderCol = sliderColForward.merge(sliderColbackward);
var videoArgs = {
dimensions: 768,
region: aoi,
framesPerSecond: 25,
crs: 'EPSG:3857'
};
print(ui.Thumbnail(sliderCol, videoArgs));
四、学以致用
前面的内容基本上涵盖了图像可视化的方方面面,其中很多官方给出的小细节都是值得学习的,剩下创新的部分就要靠大家的想象力和实际的需求啦~
给大家分享我做的一个可视化效果图~
浙公网安备 33010602011771号