• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Cesium结合GIS天地图 加载倾斜摄影3dtile + vue3

武飞扬头像
归宿乐瑶
帮助1

实现思路

  1. 将倾斜摄影OSGB数据转换为3dtile(转换方式很多,可以利用第三方工具cesiumlab)
  2. 利用Cesium加载GIS地图,我这里使用的是天地图,可以加载其他地图都行
  3. 加载3dtile数据到地图中展示

安装插件

npm install cesium

加载地图

以加载天地图为例,需要先到天地图官网去申请开发者,获取一个token,以下代码直接粘贴就行,注释中已说明

  1.  
    //初始化地图
  2.  
    let viewer;
  3.  
     
  4.  
    function initMap() {
  5.  
    const tianDiTuToken = '天地图token'
  6.  
    const mapOption = {
  7.  
    url: `http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=${tianDiTuToken}`,
  8.  
    layer: "tdtBasicLayer",
  9.  
    style: "default",
  10.  
    format: "image/jpeg",
  11.  
    tileMatrixSetID: "GoogleMapsCompatible",
  12.  
    maximumLevel: 18
  13.  
    };
  14.  
    const imgProvider = new WebMapTileServiceImageryProvider(mapOption);
  15.  
     
  16.  
    const viewerOption = {
  17.  
    animation: false,//是否创建动画小器件,左下角仪表
  18.  
    baseLayerPicker: false,//是否显示图层选择器
  19.  
    fullscreenButton: false,//是否显示全屏按钮
  20.  
    geocoder: false,//是否显示geocoder小器件,右上角查询按钮
  21.  
    homeButton: false,//是否显示Home按钮
  22.  
    infoBox: false,//是否显示信息框
  23.  
    sceneModePicker: false,//是否显示3D/2D选择器
  24.  
    scene3DOnly: false,//如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
  25.  
    selectionIndicator: false,//是否显示选取指示器组件
  26.  
    timeline: false,//是否显示时间轴
  27.  
    navigationHelpButton: false,//是否显示右上角的帮助按钮
  28.  
    baselLayerPicker: false,// 将图层选择的控件关掉,才能添加其他影像数据
  29.  
    shadows: true,//是否显示背影
  30.  
    shouldAnimate: true,
  31.  
    imageryProvider: imgProvider,
  32.  
    }
  33.  
     
  34.  
    viewer = new Viewer("map", viewerOption);
  35.  
    // 添加中文注记图层
  36.  
    viewer.imageryLayers.addImageryProvider(
  37.  
    new WebMapTileServiceImageryProvider({
  38.  
    url: `http://t0.tianditu.com/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default.jpg&tk=${tianDiTuToken}`,
  39.  
    layer: "tdtAnnoLayer",
  40.  
    style: "default",
  41.  
    format: "image/jpeg",
  42.  
    tileMatrixSetID: "GoogleMapsCompatible",
  43.  
    show: false,
  44.  
    }));
  45.  
    //优化项--关闭相关特效
  46.  
    viewer.scene.debugShowFramesPerSecond = true;//显示fps
  47.  
    viewer.scene.moon.show = false;//月亮
  48.  
    viewer.scene.fog.enabled = false;//雾
  49.  
    viewer.scene.sun.show = false;//太阳
  50.  
    viewer.scene.skyBox.show = false;//天空盒
  51.  
    viewer.resolutionScale = 1.0;//画面细度,默认值为1.0
  52.  
    //去除版权信息
  53.  
    viewer._cesiumWidget._creditContainer.style.display = "none";
  54.  
    }
学新通
学新通
初始化地图效果

加载倾斜摄影3dtitle

3Dtitle文件我这里是以nginx代理的方式访问的,也可以直接放到项目文件夹中引用

  1.  
    //加载倾斜摄影图像
  2.  
    function init3Dtiles() {
  3.  
    const tileSet = new Cesium3DTileset({
  4.  
    url: "http://127.0.0.1/data/tileset.json",
  5.  
    maximumMemoryUsage: 100,//不可设置太高,目标机子空闲内存值以内,防止浏览器过于卡
  6.  
    maximumScreenSpaceError: 32,//用于驱动细节细化级别的最大屏幕空间错误;较高的值可提供更好的性能,但视觉质量较低。
  7.  
    maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数
  8.  
    shadows: false,//是否显示阴影
  9.  
    skipLevelOfDetail: true,// 确定是否应在遍历期间应用详细级别跳过(默认false)
  10.  
    baseScreenSpaceError: 1024,//When skipLevelOfDetailis true,在跳过详细级别之前必须达到的屏幕空间错误(默认1024)
  11.  
    skipScreenSpaceErrorFactor: 16,// 定义要跳过的最小屏幕空间错误的乘数。与 一起使用skipLevels来确定要加载哪些图块(默认16)
  12.  
    skipLevels: 1,//skipLevelOfDetail是true 一个常量,定义了加载图块时要跳过的最小级别数。为 0 时,不跳过任何级别。与 一起使用skipScreenSpaceErrorFactor来确定要加载哪些图块。(默认1)
  13.  
    immediatelyLoadDesiredLevelOfDetail: false,//当skipLevelOfDetail是时true,只会下载满足最大屏幕空间错误的图块。忽略跳过因素,只加载所需的图块(默认false)
  14.  
    loadSiblings: false,// 如果为true则不会在已加载完概况房屋后,自动从中心开始超清化房屋 --- 何时确定在遍历期间skipLevelOfDetail是否true始终下载可见瓦片的兄弟姐妹(默认false)
  15.  
    cullWithChildrenBounds: true,//是否使用子边界体积的并集来剔除瓦片(默认true)
  16.  
    dynamicScreenSpaceError: true,//减少距离相机较远的图块的屏幕空间错误(默认false)
  17.  
    dynamicScreenSpaceErrorDensity: 0.00278,//数值加大,能让周边加载变快 --- 用于调整动态屏幕空间误差的密度,类似于雾密度(默认0.00278)
  18.  
    dynamicScreenSpaceErrorFactor: 4.0,// 用于增加计算的动态屏幕空间误差的因素(默认4.0)
  19.  
    dynamicScreenSpaceErrorHeightFalloff: 0.25//密度开始下降的瓦片集高度的比率(默认0.25)
  20.  
    });
  21.  
     
  22.  
    viewer.scene.primitives.add(tileSet);
  23.  
    viewer.zoomTo(tileSet);
  24.  
     
  25.  
    }
学新通
学新通
加载倾斜摄影图像效果

加载后发现倾斜图像与地图存在一定位置和高度的偏差,这里我们需要再调整一下图像的位置以及高度,调整代码如下

  1.  
    //更新倾斜摄影位置
  2.  
    function update3dtilesMaxtrix(tileSet) {
  3.  
    //调整参数
  4.  
    let params = {
  5.  
    tx: 113.06265738392063, //模型中心X轴坐标(经度,单位:十进制度)
  6.  
    ty: 22.646803971034342, //模型中心Y轴坐标(纬度,单位:十进制度)
  7.  
    tz: 40, //模型中心Z轴坐标(高程,单位:米)
  8.  
    rx: 0, //X轴(经度)方向旋转角度(单位:度)
  9.  
    ry: 0, //Y轴(纬度)方向旋转角度(单位:度)
  10.  
    rz: 2, //Z轴(高程)方向旋转角度(单位:度)
  11.  
    scale: 1.30//缩放比例
  12.  
    };
  13.  
    //旋转
  14.  
    const mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
  15.  
    const my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
  16.  
    const mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
  17.  
    const rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
  18.  
    const rotationY = Cesium.Matrix4.fromRotationTranslation(my);
  19.  
    const rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
  20.  
    //平移
  21.  
    const position = Cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz);
  22.  
    const m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
  23.  
    //旋转、平移矩阵相乘
  24.  
    Cesium.Matrix4.multiply(m, rotationX, m);
  25.  
    Cesium.Matrix4.multiply(m, rotationY, m);
  26.  
    Cesium.Matrix4.multiply(m, rotationZ, m);
  27.  
    //比例缩放
  28.  
    const scale = Cesium.Matrix4.fromUniformScale(params.scale)
  29.  
    Cesium.Matrix4.multiply(m, scale, m)
  30.  
    console.log("矩阵m:", m);
  31.  
    //赋值给tileset
  32.  
    tileSet._root.transform = m;
  33.  
    }
学新通

在加载倾斜摄影成功后调用以上方法:

  1.  
    //加载倾斜摄影图像
  2.  
    function init3Dtiles() {
  3.  
    const tileSet = new Cesium3DTileset({
  4.  
    url: "http://127.0.0.1/data/tileset.json"
  5.  
    //...代码省略,同上
  6.  
    });
  7.  
     
  8.  
    viewer.scene.primitives.add(tileSet);
  9.  
    viewer.zoomTo(tileSet);
  10.  
     
  11.  
    //调用方法
  12.  
    //加载后调整倾斜摄影的位置、角度等参数
  13.  
    tileSet.readyPromise.then((tileset) => {
  14.  
    update3dtilesMaxtrix(tileset);
  15.  
    });
  16.  
    }
学新通
学新通
调整后的展示效果

 完整代码如下:

  1.  
    <template>
  2.  
    <div id="map" style='z-index:100;position: absolute;top: 0; bottom: 0;right: 0;left: 0;'></div>
  3.  
    </template>
  4.  
     
  5.  
    <script>
  6.  
    import * as Cesium from "cesium";
  7.  
    import {Cesium3DTileset, Viewer, WebMapTileServiceImageryProvider} from "cesium";
  8.  
    import {onMounted} from 'vue'
  9.  
     
  10.  
    export default {
  11.  
    name: "MapComponent",
  12.  
    setup() {
  13.  
    //初始化地图
  14.  
    let viewer;
  15.  
     
  16.  
    function initMap() {
  17.  
    const tianDiTuToken = '天地图token'
  18.  
    const mapOption = {
  19.  
    url: `http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=${tianDiTuToken}`,
  20.  
    layer: "tdtBasicLayer",
  21.  
    style: "default",
  22.  
    format: "image/jpeg",
  23.  
    tileMatrixSetID: "GoogleMapsCompatible",
  24.  
    maximumLevel: 18
  25.  
    };
  26.  
    const imgProvider = new WebMapTileServiceImageryProvider(mapOption);
  27.  
     
  28.  
    const viewerOption = {
  29.  
    animation: false,//是否创建动画小器件,左下角仪表
  30.  
    baseLayerPicker: false,//是否显示图层选择器
  31.  
    fullscreenButton: false,//是否显示全屏按钮
  32.  
    geocoder: false,//是否显示geocoder小器件,右上角查询按钮
  33.  
    homeButton: false,//是否显示Home按钮
  34.  
    infoBox: false,//是否显示信息框
  35.  
    sceneModePicker: false,//是否显示3D/2D选择器
  36.  
    scene3DOnly: false,//如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
  37.  
    selectionIndicator: false,//是否显示选取指示器组件
  38.  
    timeline: false,//是否显示时间轴
  39.  
    navigationHelpButton: false,//是否显示右上角的帮助按钮
  40.  
    baselLayerPicker: false,// 将图层选择的控件关掉,才能添加其他影像数据
  41.  
    shadows: true,//是否显示背影
  42.  
    shouldAnimate: true,
  43.  
    imageryProvider: imgProvider,
  44.  
    }
  45.  
     
  46.  
    viewer = new Viewer("map", viewerOption);
  47.  
    // 添加中文注记图层
  48.  
    viewer.imageryLayers.addImageryProvider(
  49.  
    new WebMapTileServiceImageryProvider({
  50.  
    url: `http://t0.tianditu.com/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default.jpg&tk=${tianDiTuToken}`,
  51.  
    layer: "tdtAnnoLayer",
  52.  
    style: "default",
  53.  
    format: "image/jpeg",
  54.  
    tileMatrixSetID: "GoogleMapsCompatible",
  55.  
    show: false,
  56.  
    }));
  57.  
    //优化项--关闭相关特效
  58.  
    viewer.scene.debugShowFramesPerSecond = true;//显示fps
  59.  
    viewer.scene.moon.show = false;//月亮
  60.  
    viewer.scene.fog.enabled = false;//雾
  61.  
    viewer.scene.sun.show = false;//太阳
  62.  
    viewer.scene.skyBox.show = false;//天空盒
  63.  
    viewer.resolutionScale = 1.0;//画面细度,默认值为1.0
  64.  
    //去除版权信息
  65.  
    viewer._cesiumWidget._creditContainer.style.display = "none";
  66.  
    }
  67.  
     
  68.  
    //加载倾斜摄影图像
  69.  
    function init3Dtiles() {
  70.  
    const tileSet = new Cesium3DTileset({
  71.  
    url: "http://127.0.0.1/data/tileset.json",
  72.  
    maximumMemoryUsage: 100,//不可设置太高,目标机子空闲内存值以内,防止浏览器过于卡
  73.  
    maximumScreenSpaceError: 32,//用于驱动细节细化级别的最大屏幕空间错误;较高的值可提供更好的性能,但视觉质量较低。
  74.  
    maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数
  75.  
    shadows: false,//是否显示阴影
  76.  
    skipLevelOfDetail: true,// 确定是否应在遍历期间应用详细级别跳过(默认false)
  77.  
    baseScreenSpaceError: 1024,//When skipLevelOfDetailis true,在跳过详细级别之前必须达到的屏幕空间错误(默认1024)
  78.  
    skipScreenSpaceErrorFactor: 16,// 定义要跳过的最小屏幕空间错误的乘数。与 一起使用skipLevels来确定要加载哪些图块(默认16)
  79.  
    skipLevels: 1,//skipLevelOfDetail是true 一个常量,定义了加载图块时要跳过的最小级别数。为 0 时,不跳过任何级别。与 一起使用skipScreenSpaceErrorFactor来确定要加载哪些图块。(默认1)
  80.  
    immediatelyLoadDesiredLevelOfDetail: false,//当skipLevelOfDetail是时true,只会下载满足最大屏幕空间错误的图块。忽略跳过因素,只加载所需的图块(默认false)
  81.  
    loadSiblings: false,// 如果为true则不会在已加载完概况房屋后,自动从中心开始超清化房屋 --- 何时确定在遍历期间skipLevelOfDetail是否true始终下载可见瓦片的兄弟姐妹(默认false)
  82.  
    cullWithChildrenBounds: true,//是否使用子边界体积的并集来剔除瓦片(默认true)
  83.  
    dynamicScreenSpaceError: true,//减少距离相机较远的图块的屏幕空间错误(默认false)
  84.  
    dynamicScreenSpaceErrorDensity: 0.00278,//数值加大,能让周边加载变快 --- 用于调整动态屏幕空间误差的密度,类似于雾密度(默认0.00278)
  85.  
    dynamicScreenSpaceErrorFactor: 4.0,// 用于增加计算的动态屏幕空间误差的因素(默认4.0)
  86.  
    dynamicScreenSpaceErrorHeightFalloff: 0.25//密度开始下降的瓦片集高度的比率(默认0.25)
  87.  
    });
  88.  
     
  89.  
    viewer.scene.primitives.add(tileSet);
  90.  
    viewer.zoomTo(tileSet);
  91.  
     
  92.  
    //加载后调整倾斜摄影的位置、角度等参数
  93.  
    tileSet.readyPromise.then((tileset) => {
  94.  
    update3dtilesMaxtrix(tileset);
  95.  
    });
  96.  
    }
  97.  
     
  98.  
    //更新倾斜摄影位置
  99.  
    function update3dtilesMaxtrix(tileSet) {
  100.  
    //调整参数
  101.  
    let params = {
  102.  
    tx: 113.06265738392063, //模型中心X轴坐标(经度,单位:十进制度)
  103.  
    ty: 22.646803971034342, //模型中心Y轴坐标(纬度,单位:十进制度)
  104.  
    tz: 40, //模型中心Z轴坐标(高程,单位:米)
  105.  
    rx: 0, //X轴(经度)方向旋转角度(单位:度)
  106.  
    ry: 0, //Y轴(纬度)方向旋转角度(单位:度)
  107.  
    rz: 2, //Z轴(高程)方向旋转角度(单位:度)
  108.  
    scale: 1.30//缩放比例
  109.  
    };
  110.  
    //旋转
  111.  
    const mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
  112.  
    const my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
  113.  
    const mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
  114.  
    const rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
  115.  
    const rotationY = Cesium.Matrix4.fromRotationTranslation(my);
  116.  
    const rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
  117.  
    //平移
  118.  
    const position = Cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz);
  119.  
    const m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
  120.  
    //旋转、平移矩阵相乘
  121.  
    Cesium.Matrix4.multiply(m, rotationX, m);
  122.  
    Cesium.Matrix4.multiply(m, rotationY, m);
  123.  
    Cesium.Matrix4.multiply(m, rotationZ, m);
  124.  
    //比例缩放
  125.  
    const scale = Cesium.Matrix4.fromUniformScale(params.scale)
  126.  
    Cesium.Matrix4.multiply(m, scale, m)
  127.  
    console.log("矩阵m:", m);
  128.  
    //赋值给tileset
  129.  
    tileSet._root.transform = m;
  130.  
    }
  131.  
     
  132.  
    onMounted(() => {
  133.  
    initMap();
  134.  
    init3Dtiles()
  135.  
    })
  136.  
    }
  137.  
    }
  138.  
    </script>
  139.  
     
  140.  
    <style scoped>
  141.  
    @import url('../../node_modules/cesium/Source/Widgets/widgets.css');
  142.  
     
  143.  
    html,
  144.  
    body,
  145.  
    #map {
  146.  
    height: 100%;
  147.  
    width: 100%;
  148.  
    margin: 0;
  149.  
    padding: 0;
  150.  
    overflow: hidden;
  151.  
    }
  152.  
    </style>
学新通

以上是学习Cesium加载倾斜摄影的过程,中间踩过很多坑,下一篇将踩坑的过程记录下,希望对有遇到同样问题的小伙伴有所帮助

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgafjee
系列文章
更多 icon
同类精品
更多 icon
继续加载