給大家分享一個我最近利用業(yè)余時間做的DEMO,純屬好玩。。哈哈哈

屏幕截圖...

extrude_terrain.gif
實際上就是基于mapbox extrude layer 的應(yīng)用,創(chuàng)建mapbox extrude layer 的代碼如下:
function addTerrainLayer() {
map.addSource('voxelSource', {
'type': 'geojson',
'data': voxelGjson, // 關(guān)鍵就是數(shù)據(jù)源得包含一個標(biāo)識高度的字段,一般是polygon類型的數(shù)據(jù)
});
map.addLayer({
'id': 'terrain-extrusion',
'type': 'fill-extrusion', // 選擇 layer 的type 為fill-extrusion
'source': 'voxelSource',
'paint': {
// See the Mapbox Style Specification for details on data expressions.
// https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions
// Get the fill-extrusion-color from the source 'color' property.
'fill-extrusion-color': ['get', 'color'],
// Get fill-extrusion-height from the source 'height' property.
'fill-extrusion-height': ['get', 'height'],
// // Get fill-extrusion-base from the source 'base_height' property.
'fill-extrusion-base': ['get', 'base_height'],
// Make extrusions slightly opaque for see through indoor walls.
'fill-extrusion-opacity': 1
}
});
}
高程數(shù)據(jù)來源
關(guān)鍵的地方就是配置 layer type 為 fill-extrusion,并且source 的data 中包含一個字段去標(biāo)識高度/高程。
高程數(shù)據(jù)的來源就是左邊這張普通的高程圖片,右邊是對應(yīng)的真彩色圖像

image.png
RGB 波段中 R 波段的亮度標(biāo)識高度值,所以其他倆字段都是0,alpha 是255。地形色彩由上圖的RGB 決定,這兩幅圖的像素寬高是一致的,所以真彩色和高程幾乎是一一對應(yīng)的。實際上可以把色彩信息和高程合并在一張 png 中。
讀取高程構(gòu)建 layer source
- 如何把高程圖中的高度讀取出來: 先繪制到 canvas 中,再利用 ctx.getImageData 把所有像素的波段值讀取成 ImageData 類型的對象
- ImageData.data: Uint8ClampedArray 這個字段中包含的Uint8Array 長度是 圖像 width * height * 波段數(shù)量 4 . 例如 [1, 0, 0, 255, 200, 0, 0, 255, ...] 表示第一個像素的 R波段是1,第二個像素紅波段值是200.
- 構(gòu)建用于拉伸的多邊形要素,正方形或者六邊形都是不錯的選擇。正方形更有一種我的世界的感覺。。哈哈哈
voxel 顏色也是同樣方式,通過getImageData 取自 真彩色圖像的RGB 三個波段。 所以本文最關(guān)鍵的部分應(yīng)該就是 getImageData 這個函數(shù)了,以及后續(xù)對 Uint8Array 的取值操作。
實際上就是構(gòu)建帶高度屬性的geojson polygon
return {"type": "Feature",
"properties": {
"level": 1,
"name": "voxel",
"height": height*10,
"base_height": 0,
color: voxelColor
},
"geometry": {
"coordinates": [
[
[
centerX-voxelWidth,
centerY+voxelWidth
],
// ... 其他點(diǎn)坐標(biāo)不去展示了。。
]
],
"type": "Polygon"
},
id: `${centerX}${centerY}${height}`
};
在線DEMO 地址
后面準(zhǔn)備有空再研究下mapbox custom layer,據(jù)說可以接管地圖 webgl 的部分,應(yīng)該挺有意思的。
歡迎去 github 項目把玩各種 mapbox demo 和小插件,插件庫 Gzip 后僅需18Kb !!!