0 结论
-
deck gl 是基于 WebGL 的数据可视化框架,可以集成在主流的地图框架(arcgis,google maps,mapbox )中使用, 也可以单独使用。
-
deck gl 通过layer进行数据可视化,支持多种展示效果,业内主要的使用场景基本是使用例如 Mapbox 作为 可视化层的背景,然后数据可视化的部分用deck实现
-
pbf类型的2d矢量数据,和xyz协议的底图数据,可以直接在deck gl里面使用。不过由于deck gl在加载一个图层layer的时候,对于鉴权token的传输无论是通过get参数还是header 都存在设置之后无法动态更新的问题,如果需要鉴权token动态更新,只能把这个layer删掉,重新创建,会存在token更新的时候feature消失再出现的问题
-
b3dm的3d tiles,可以通过deck gl的Tile3DLayer去渲染,也能展示出来,但是因为这个功能目前是deck gl的一个实验性质的功能,目前优化做的不好,实测了一下加载一个3d tiles,内存占了5个G ,特别卡,基本不可用
-
Quantized Mesh格式的地形只支持加载单个tile,不支持指定x,y,z 的方式去自动获取。所以也没法在deck中直接使用。deck gl 支持的地形是mapbox使用的 height map images协议的 地形数据
1 介绍
官网:https://deck.gl/
官方示例: https://deck.gl/examples/terrain-layer/
deck gl 是一个基于 WebGL 的数据可视化框架(渲染层),可以和一些主流的地图框架结合使用,几乎所有 Uber 的地理空间数据应用程序都使用 Mapbox 作为 http://deck.gl 可视化层的背景。主流可结合的底图组件包括:
-
arcgis
-
google maps
-
mapbox
示例:
在mapbox的底图上加载一个飞行航路图,数据来源是一个包含点类型的geojson, 通过deck gl在mapbox中添加了一个点类型的GeoJsonLayer,和一个指示从伦敦到每个点的ArcLayer
当然,deck gl也可以独立使用:
不依赖地图直接去展示数据,这里的所有数据都是geojson格式的:
2. 支持的layer
2.1 ArcLayer 弧形图
例如本文档的第一张图的效果
2.2 BitmapLayer 在指定区域内加载一张图
2.3 ColumnLayer
renders extruded cylinders (tessellated regular polygons) at given coordinates.
2.4 MVTLayer
2.4.1 在mapbox中加载:
示例代码:
const map = new mapboxgl.Map({
container: 'map',
style: '<https://basemaps.cartocdn.com/gl/positron-nolabels-gl-style/style.json',>
center: [-70.764436, 43.442947],
zoom: 16,
bearing: 0,
antialias: true,
pitch: 30
});
let token = 'eyJhbGciOiJIUzI1NiIsxNjYyNDQ3NTg5fQ.Ie_RnTBgOy8CwE34agUK-OZiYvIcYFOXZZniX6Ar2GA'
const deckOverlay = new DeckOverlay({
layers: [
new MVTLayer({
id: 'buildings',
data: `<https://xxxxxx/set-bi5reb2fe2Li9da9/1012091/{z}/{x}/{y}.pbf?auth_token=${token}`,>
minZoom: 0,
maxZoom: 23,
getLineColor: [192, 192, 192],
getFillColor: [140, 170, 180],
// getLineWidth: f => {
// switch (f.properties.class) {
// case 'street':
// return 6;
// case 'motorway':
// return 10;
// default:
// return 1;
// }
// },
lineWidthMinPixels: 1
})
]
});
map.addControl(deckOverlay);
map.addControl(new mapboxgl.NavigationControl());
展示效果
2.5 TileLayer
2.5.1 在mapbox中加载:
示例代码:
new TileLayer({
// <https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_servers>
data: `<https://xxxxxxx/imagery/asset/us-west-2/s/v1/data/tile/asset-huh4fi0wa4pyf3ke/51cfd1fa-b6b2-4001-9bc4-ced7a000da97/{z}/{x}/{y}.jpg?auth_token=${token}`,>
minZoom: 0,
maxZoom: 19,
tileSize: 256,
renderSubLayers: props => {
const {
bbox: {west, south, east, north}
} = props.tile;
return new BitmapLayer(props, {
data: null,
image: props.data,
bounds: [west, south, east, north]
});
}
}),
展示效果
2.6 Tile3DLayer(Experimental)
2.6.1 在mapbox中加载:
加载building数据:
示例代码:
import { MapboxLayer } from "@deck.gl/mapbox"
import { Tiles3DLoader } from '@loaders.gl/3d-tiles';
import {Tile3DLayer} from '@deck.gl/geo-layers';
const building_layer = new MapboxLayer({
id: 'buildings',
type: Tile3DLayer,
data: `<https://xxxxx/asset/d/v1/data/b3dm/asset-2b7923b72b4253f1/d3d-layer/tileset/454368_1660530444/tileset.json`,>
loader: Tiles3DLoader,
loadOptions: {
fetch: {
method: 'GET',
headers: {
'Authorization':`Bearer ${token_3d}`,
},
},
tileset: {
maximumMemoryUsage: 16,
viewDistanceScale: 5,
},
},
});
map.once('styledata', () => {
map.addLayer(building_layer);
map.setLayerZoomRange('buildings', 15, 22.1);
});
展示效果
加载一个3d tiles,内存占了5个G ,特别卡,基本不可用
卡顿原因分析:
deck-gl加载3d tiles 是用的 Loader.gl
Loader.gl 当前存在的坑:
-
不支持skipLevelOfDetail,这个参数在大数据情况下非常有用,可以大量减少不必要的请求
-
不支持剔除视锥之外的tile,就是如果你从一个点移动到另外一个点如果两点之间非常远,你会发现数据加载当前视窗范围的tile非常慢,慢如蜗牛,数据量超过十G,慢的让你怀疑人生,主要原因,是他们在请求的时候保留所有的tile,慢慢的找出需要加载的数据,关键最终他会把那些不在视锥的数据也加载,另方面也是主要通过Base traversal遍历,它必要保留下来。
-
父子切片的替换不支持默认replace,也就是如果转的数据refine默认都是replace情况下数据加载画面很混乱,切片不停的闪烁,体验感很差
-
不支持压缩纹理:比如经过crn或者ktx压缩之后loader.gl是无法解析的,如果你想扩展需要结合textures模块并且在这个类中
github上有其他人提的issue, 到现在看起来也还是open状态:
https://github.com/visgl/loaders.gl/issues/1565
2.7 TerrainLayer
The TerrainLayer reconstructs mesh surfaces from height map images, e.g. Mapzen Terrain Tiles, which encodes elevation into R,G,B values.
这个地形的协议是maobox使用的地形协议,我们目前生成的是ceisum的Quantized Mesh格式的地形,现在看文档deck gl 实现了QuantizedMeshLoader,但是这个目前看起来只支持单个terrain文件,不支持通过xyz去动态的获取数据,暂时也不可用.
QuantizedMeshLoader 相关链接:
https://loaders.gl/modules/terrain/docs/api-reference/quantized-mesh-loader