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 倾斜摄影模型的技术,在三维地图开发领域创造更多精彩应用。

我是 安大桃子,专注前端代码世界的'筑梦师'。这一趟前端开发的代码之旅暂时告一段落啦,希望文章中的代码思路和技巧能成为你构建前端项目的得力工具。前端技术日新月异,咱们一起在这充满挑战与机遇的领域持续探索,下次代码冒险,咱们不见不散!
相关推荐
一块小砖头儿15 分钟前
HTML向四周扩散背景
前端·javascript·html
杨超越luckly20 分钟前
HTML应用指南:利用POST请求获取全国申通快递服务网点位置信息
大数据·前端·信息可视化·数据分析·html
Allen Bright22 分钟前
【HTML-1】HTML骨架标签:构建网页的基础框架
前端·html
OneT1me42 分钟前
SN生成流水号并且打乱
java·linux·前端
眼镜chen44 分钟前
luckysheet的使用——17.将表格作为pdf下载到本地
前端·javascript·vue.js·chrome·pdf
_oP_i1 小时前
python实现pdf转图片(针对每一页)
前端·数据库·python
开开心心就好1 小时前
便捷的Office批量转PDF工具
前端·python·pdf·ocr·硬件架构·音视频·材料工程
通义灵码1 小时前
如何使用AI辅助开发CSS3 - 通义灵码功能全解析
前端·人工智能·阿里云·css3·通义灵码
_龙小鱼_1 小时前
Vue2到Vue3迁移问题解析
前端·javascript·vue.js
二川bro1 小时前
npm vs npx 终极指南:从原理到实战的深度对比 全面解析包管理器与包执行器的核心差异,助你精准选择工具
前端·arcgis·npm