各位掘友,大家好,我是 安大桃子 。在当下数字化地图与地理信息蓬勃发展的浪潮里,WebGIS 技术成为关键力量。倾斜摄影模型作为一种能真实反映地物地貌的三维数据,在城市规划、虚拟现实、地理分析等领域广泛应用。本文将带你深入探索如何利用 Mapbox GL 和 Deck.gl 在 Web 应用中加载 3D Tileset 倾斜摄影模型,开启 WebGIS 开发 进阶之路。

一、技术栈简介
(一)Mapbox GL
Mapbox GL 是一个强大的 JavaScript 库,用于在 Web 浏览器中创建交互式地图。它提供了丰富的地图样式、交互功能,支持多种数据格式,开发者能轻松定制地图外观和行为,满足不同应用场景需求。
(二)Deck.gl
Deck.gl 是用于在地图和数据可视化场景中高效渲染大规模数据集的 JavaScript 框架。它基于 WebGL 技术,能处理复杂的地理空间数据,实现高性能的可视化效果。在加载 3D Tileset 倾斜摄影模型时,Deck.gl 的Tile3DLayer
图层发挥关键作用,让开发者便捷加载和展示 3D 瓦片数据。
二、准备工作
开发前,需引入相关库和依赖。在 Vue 项目中,通过
java
npm install mapbox-gl
npm install @deck.gl
npm install @loaders.gl/3d-tiles
安装所需库,同时引入 Mapbox GL 的 CSS 样式文件,为地图提供基本样式。
三、代码实现
(一)初始化 Mapbox 地图
在 Vue 组件的setup
函数中,利用onMounted
生命周期钩子初始化 Mapbox 地图。
typescript
import { onMounted, ref } from 'vue';
import mapboxgl from'mapbox-gl';
import'mapbox-gl/dist/mapbox-gl.css';
import { Map } from'mapbox-gl';
const mapContainer = ref();
const map = ref<Map>();
const accessToken = 'your token';
onMounted(() => {
mapboxgl.accessToken = accessToken;
map.value = new mapboxgl.Map({
container: mapContainer.value,
style:'mapbox://styles/mapbox/streets-v11',
center: [108.97230063743861, 34.23179735056136],
zoom: 14,
preserveDrawingBuffer: true
});
});
这段代码设置了地图容器、样式、初始中心坐标和缩放级别,并通过accessToken
授权访问 Mapbox 服务。
(二)加载 3D Tileset 倾斜摄影模型
定义load3DTiles
函数,借助 Deck.gl 的MapboxOverlay
和Tile3DLayer
加载 3D Tileset 数据。
typescript
import { MapboxOverlay } from "@deck.gl/mapbox";
import { Tile3DLayer } from "@deck.gl/geo-layers";
import { Tiles3DLoader } from '@loaders.gl/3d-tiles';
import { Matrix4 } from '@math.gl/core';
function load3DTiles(layerConfig: { id: any; url: any; }) {
const deckOverlay = new MapboxOverlay({
layers: [
new Tile3DLayer({
id: layerConfig.id,
loader: Tiles3DLoader,
data: layerConfig.url,
parameters: {
depthWriteEnabled: true,
depthTest: false
},
onTileError: (err) => {
console.log(err);
},
onTilesetLoad: (tileset) => {
tileset.setProps({ maximumScreenSpaceError: 1 });
const { cartographicCenter, zoom } = tileset;
console.log("cartographicCenter", cartographicCenter?.toString());
let boundingBox = tileset.root?.boundingBox;
if (cartographicCenter && map.value) {
map.value!.jumpTo({
center: [cartographicCenter[0], cartographicCenter[1]],
zoom: zoom
});
if (boundingBox) {
let mMtx = new Matrix4().makeTranslation(1, 1, -boundingBox[1][2]);
tileset.modelMatrix = mMtx;
console.log("tileset", tileset.modelMatrix);
}
}
}
})
]
});
return deckOverlay;
}
在load3DTiles
函数中:
- 创建
MapboxOverlay
实例,其中包含一个Tile3DLayer
图层。 Tile3DLayer
配置了loader
为Tiles3DLoader
,用于加载 3D 瓦片数据,data
属性指定数据 URL。- 设置
parameters
关闭深度写入和深度测试,适应地下模型显示。 onTileError
回调处理瓦片加载错误,onTilesetLoad
回调在数据集加载完成后,设置最大屏幕空间误差,调整地图视角到模型中心,并根据模型边界框调整模型位置。
(三)将模型添加到地图
在地图初始化完成后,调用load3DTiles
函数加载模型,并添加到地图。
typescript
onMounted(() => {
// 地图初始化代码...
let deckOverlay = load3DTiles({
id: "3dTiles",
url: 'https://zouyaoji.top/vue-cesium/SampleData/Cesium3DTiles/Tilesets/dayanta/tileset.json'
});
map.value.addControl(deckOverlay);
});

(四) 调整模型位置
这时候倾斜摄影就能加载出来了,但是模型悬浮在地图上方,高度有问题;不过不要着急,修改一下矩阵个就可以调整过来了。
typescript
onTilesetLoad: (tileset) => {
tileset.setProps({ maximumScreenSpaceError: 1 });
const { cartographicCenter, zoom } = tileset;
console.log("cartographicCenter", cartographicCenter?.toString());
let boundingBox = tileset.root?.boundingBox;
if (cartographicCenter && map.value) {
map.value!.jumpTo({
center: [cartographicCenter[0], cartographicCenter[1]],
zoom: zoom
});
if (boundingBox) {
let mMtx = new Matrix4().makeTranslation(1, 1, -boundingBox[1][2]);
tileset.modelMatrix = mMtx;
console.log("tileset", tileset.modelMatrix);
}
}
}
这样,3D Tileset 倾斜摄影模型就成功加载到 Mapbox 地图上。
四、总结与拓展
通过 Mapbox GL 和 Deck.gl 的结合,我们实现了在 Web 应用中加载 3D Tileset 倾斜摄影模型。这种技术组合为三维地理信息可视化提供了强大支持,开发者可在此基础上进一步拓展:
-
优化性能 :根据数据量和应用场景,调整
Tile3DLayer
参数,如viewport
、maxZoom
等,提升渲染性能。 -
添加交互功能:利用 Mapbox GL 和 Deck.gl 的交互 API,实现模型选择、缩放、旋转等交互操作,增强用户体验。
-
数据融合:结合其他地理数据,如矢量数据、栅格数据,丰富地图信息,满足更复杂的业务需求。
希望本文能帮助你掌握 Mapbox GL + Deck.gl 加载 3D Tileset 倾斜摄影模型的技术,在三维地图开发领域创造更多精彩应用。
![]() |
---|
我是 安大桃子,专注前端代码世界的'筑梦师'。这一趟前端开发的代码之旅暂时告一段落啦,希望文章中的代码思路和技巧能成为你构建前端项目的得力工具。前端技术日新月异,咱们一起在这充满挑战与机遇的领域持续探索,下次代码冒险,咱们不见不散! |