Mapbox GL + Deck.gl 三维实战:Mapbox 加载 Tileset3D 倾斜摄影模型

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

一、技术栈简介

(一)Mapbox GL

Mapbox GL 是一个强大的 JavaScript 库,用于在 Web 浏览器中创建交互式地图。它提供了丰富的地图样式、交互功能,支持多种数据格式,开发者能轻松定制地图外观和行为,满足不同应用场景需求。

(二)Deck.gl

Deck.gl 是用于在地图和数据可视化场景中高效渲染大规模数据集的 JavaScript 框架。它基于 WebGL 技术,能处理复杂的地理空间数据,实现高性能的可视化效果。在加载 3D Tileset 倾斜摄影模型时,Deck.glTile3DLayer图层发挥关键作用,让开发者便捷加载和展示 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.glMapboxOverlayTile3DLayer加载 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函数中:

  1. 创建MapboxOverlay实例,其中包含一个Tile3DLayer图层。
  2. Tile3DLayer配置了loaderTiles3DLoader,用于加载 3D 瓦片数据,data属性指定数据 URL。
  3. 设置parameters关闭深度写入和深度测试,适应地下模型显示。
  4. 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 倾斜摄影模型。这种技术组合为三维地理信息可视化提供了强大支持,开发者可在此基础上进一步拓展:

  1. 优化性能 :根据数据量和应用场景,调整Tile3DLayer参数,如viewportmaxZoom等,提升渲染性能。

  2. 添加交互功能:利用 Mapbox GL 和 Deck.gl 的交互 API,实现模型选择、缩放、旋转等交互操作,增强用户体验。

  3. 数据融合:结合其他地理数据,如矢量数据、栅格数据,丰富地图信息,满足更复杂的业务需求。

希望本文能帮助你掌握 Mapbox GL + Deck.gl 加载 3D Tileset 倾斜摄影模型的技术,在三维地图开发领域创造更多精彩应用。

我是 安大桃子,专注前端代码世界的'筑梦师'。这一趟前端开发的代码之旅暂时告一段落啦,希望文章中的代码思路和技巧能成为你构建前端项目的得力工具。前端技术日新月异,咱们一起在这充满挑战与机遇的领域持续探索,下次代码冒险,咱们不见不散!
相关推荐
涵信13 分钟前
第九节:性能优化高频题-首屏加载优化策略
前端·vue.js·性能优化
前端小巷子25 分钟前
CSS单位完全指南
前端·css
SunTecTec1 小时前
Flink Docker Application Mode 命令解析 - 修改命令以启用 Web UI
大数据·前端·docker·flink
拉不动的猪2 小时前
前端常见数组分析
前端·javascript·面试
小吕学编程2 小时前
ES练习册
java·前端·elasticsearch
Asthenia04123 小时前
Netty编解码器详解与实战
前端
袁煦丞3 小时前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛4 小时前
vue组件间通信
前端·javascript·vue.js
一笑code4 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员4 小时前
layui时间范围
前端·javascript·layui