昨天阅读了一篇质量很高的python绘制地形图博客。有感而发,我便想到了GEE数据源众多、计算速度快、计算算子多的特点,使用GEE应该不会逊色于python。
GEE的DEM数据众多,读者可以根据自己的需要选择合适的数据源。研究区范围大,可以选择分辨率较低的数据,如果研究区域较小,则尽量使用高分辨率DEM。
这里考虑到试验区是我老家四川省,这里使用覆盖全球的30m分辨率NASA DEM。
// 引入数据源 研究区选择我的老家四川省
var
dataset = ee.Image(
'NASA/NASADEM_HGT/001'
);
var
elevation = dataset.select(
'elevation'
).clip(ROI);
// 设置可视化参数
var
elevationVis = {
min
:
0
,
max
:
8000
,
//可视化
Map
.addLayer(elevation, elevationVis,
'Elevation'
);
Map
.centerObject(ROI,
7
);
2
颜色配色表
待数据加载完成之后,数据的颜色不好看,这个时候就需要
调色板
。有几种办法,一种是在GEE中手动调整DEM显示:
还有一个就是可以参考别人的已经设置好的调色板,直接调用,这里我推荐一个GitHub仓库
ee-palettes
(https://github.com/gee-community/ee-palettes):
该仓库汇集了近两百种配色方案,在GEE中直接调用即可:
调用这个仓库,只需要引入函数库,然后new一个调色板,并将该配色方案填入地图加载函数中,注意设置最大值与最小值。然后对照着颜色表逐个尝试,找到最适合自己的颜色方案。
//调用仓库已经配置好的调色板
var
palettes =
require
(
'users/gena/packages:palettes'
);
var
palette_bamako = palettes.crameri.bamako[
10
,
25
,
50
];
Map
.addLayer(elevation, {
min
:
0
,
max
:
8000
,
palette
: palette_bamako},
'crameri.bamako'
);
var
palette_rainbow = palettes.kovesi.rainbow_bgyr_35_85_c72[
7
];
Map
.addLayer(elevation, {
min
:
0
,
max
:
8000
,
palette
: palette_rainbow},
'palette_rainbow'
);
var
palette_misc = palettes.misc.jet[
7
];
Map
.addLayer(elevation, {
min
:
0
,
max
:
8000
,
palette
: palette_misc},
'palette_misc'
);
var
palette_diverging = palettes.kovesi.diverging_linear_bjy_30_90_c45[
7
];
Map
.addLayer(elevation, {
min
:
0
,
max
:
8000
,
palette
: palette_diverging},
'palette_diverging'
);
在配色过程中,也可以注意调色板的最大值与最小值对于DEM显示的影响。四川省的最高海拔为7556米,最低海拔为188米。但是这并不代表我们的配色值域应该遵从最大最小值,因为在配色中如果像素值大于max值,则颜色为最右端,值会自动调整的,如果我们能找到最佳的值域范围,则内部的像素点因为高度差异引起的
对比更明显
,换句话说,使用大部分值域范围的显示效果更佳。
根据四川省的DEM值分布直方图,我做了以下几个对比:
//值域范围对比
//0-8000m
var
palette_rainbow1 = palettes.kovesi.rainbow_bgyr_35_85_c72[
7
];
Map
.addLayer(elevation, {
min
:
0
,
max
:
8000
,
palette
: palette_rainbow1},
'palette_rainbow1'
);
//最大值与最小值
var
palette_rainbow2 = palettes.kovesi.rainbow_bgyr_35_85_c72[
7
];
Map
.addLayer(elevation, {
min
:
188
,
max
:
7556
,
palette
: palette_rainbow2},
'palette_rainbow2'
);
//直方图的横轴最大值与最小值
var
palette_rainbow3 = palettes.kovesi.rainbow_bgyr_35_85_c72[
7
];
Map
.addLayer(elevation, {
min
:
451
,
max
:
4525
,
palette
: palette_rainbow3},
'palette_rainbow3'
);
//直方图的横轴最小值与6000
var
palette_rainbow4 = palettes.kovesi.rainbow_bgyr_35_85_c72[
7
];
Map
.addLayer(elevation, {
min
:
451
,
max
:
6000
,
palette
: palette_rainbow4},
'palette_rainbow4'
);
如何选取合适
调色板的值域范围
,也是优雅绘制DEM的重要因素。
3
山体阴影;
选取了较好的DEM数据源、调色板、值域范围后,我们可以加入山体阴影来增强DEM的显示效果。函数 ee.Terrain.hillshade(input,azimuth, elevation)是生成山体阴影的算子,input为DEM,azimuth是方位角,elevation是高度角。
方向角指的是太阳的角度方向,是以北为基准方向在 0 到 360 度范围内按顺时针进行测量的,90º 的方位角为东。高度指的是照明源高出地平线的角度或坡度。高度的单位为度,范围为 0(位于地平线上)到 90(位于头上)之间。需要注意hillshade的值域为0-255.
//山体阴影
var
palette_hillshade = palettes.crameri.bamako[
10
,
25
,
50
];
var
exaggeration =
20
;
var
hillshade = ee.Terrain.hillshade(elevation.multiply(exaggeration),
270
,
45
);
Map
.addLayer(hillshade, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade'
);
影响山体阴影显示效果的有方位角:
//不同的方位角
var
palette_hillshade = palettes.crameri.bamako[
10
,
25
,
50
];
var
exaggeration =
20
;
var
hillshade_45 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
45
,
15
);
Map
.addLayer(hillshade_45, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_45'
);
var
hillshade_135 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
135
,
15
);
Map
.addLayer(hillshade_135, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_135'
);
var
hillshade_225 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
225
,
15
);
Map
.addLayer(hillshade_225, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_225'
);
var
hillshade_315 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
315
,
15
);
Map
.addLayer(hillshade_315, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_315'
);
GEE的默认方向角为270º ,作者可以根据自身需求选择合适的方位角。
不同的高度角也会影响山体阴影的显示效果:
//不同的高度角
var
palette_hillshade = palettes.crameri.bamako[
10
,
25
,
50
];
var
exaggeration =
20
;
var
hillshade_15 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
270
,
15
);
Map
.addLayer(hillshade_15, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_15'
);
var
hillshade_30 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
270
,
30
);
Map
.addLayer(hillshade_30, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_30'
);
var
hillshade_45 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
270
,
45
);
Map
.addLayer(hillshade_45, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_45'
);
var
hillshade_60 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
270
,
60
);
Map
.addLayer(hillshade_60, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_60'
);
var
hillshade_75 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
270
,
75
);
Map
.addLayer(hillshade_75, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_75'
);
var
hillshade_90 = ee.Terrain.hillshade(elevation.multiply(exaggeration),
270
,
90
);
Map
.addLayer(hillshade_90, {
min
:
0
,
max
:
255
,
palette
: palette_hillshade},
'palette_hillshade_90'
);
一般来说,高度角越小,山体阴影效果越强,高度角在gee中默认是45°。
Part3
代码链接
Part4
写在最后
总结以下,要优雅地使用GEE绘制DEM:
首先得
选好数据源
,小研究区选择分辨率高的DEM,大研究区可以选择低分辨率DEM;
其次是选好
调色板
,这里推荐使用第三方库ee-palettes,然后就是注意调色板的最值范围;
其次是制作
山体阴影
,注意选择合适的太阳高度角与方位角。
该文只是提供一个制作思路,由于作者的审美水平有限,读者不必完全按照我的配色方案来制作地形图,
怎么好看怎么来
。
Part5
参考
Clarmy吱声.如何用Python绘制炫酷的立体地形图
转载自:
锐多宝的地理空间
版权归原作者所有,如有侵权请告知删除
如果亲觉得我们的文章还不错的话,那就请分享转发一下吧!
bbs.3s001.com
微信ID:
bbs3s001
返回搜狐,查看更多