在vue上使用cesium开发三维地图的详细过程

 更新时间:2023年12月08日 08:52:04   作者:wy-naruto  
这篇文章主要给大家介绍了关于在vue上使用cesium开发三维地图的详细过程,Cesium是一个强大的JavaScript库,支持三维地理信息展示,并提供了丰富的地理空间数据可视化功能,需要的朋友可以参考下

需要注意的是,Cesium 使用 WebGL 技术,所以您需要确保浏览器支持 WebGL。

一:安装Cesium

可以通过 NPM 安装 Cesium。打开命令行界面,输入以下命令:

npm install cesium

安装完成后,您可以在 node_modules/cesium 目录下找到 Cesium 的 JavaScript 文件和相关文件。

二:在 Vue 项目中使用 Cesium

接下来,在 Vue 项目中引入 Cesium,可以使用以下几种方式。

方式一:在 index.html 文件中引入 Cesium

在您的 index.html 文件中添加以下代码:

<script src="./node_modules/cesium/Build/Cesium/Cesium.js"></script>
<link rel="stylesheet" href="./node_modules/cesium/Build/Cesium/Widgets/widgets.css" rel="external nofollow"  />

这将在整个 Vue 应用程序中加载 Cesium。

方式二:使用模块设置

在 main.js 文件中添加以下代码:

import Cesium from 'cesium/Cesium'
import 'cesium/Build/Cesium/Widgets/widgets.css'
Vue.prototype.Cesium = Cesium  // 将 Cesium 注册为 Vue 实例的属性

这样,您就可以在整个 Vue 应用程序中通过 this.Cesium 访问 Cesium 相关的类和方法。

三:创建一个 Cesium 场景

使用 Cesium 创建一个场景需要一个 HTML 元素来展示它。可以在 Vue 中使用 mounted() 钩子函数将 Cesium 场景添加到您的 Vue 组件中。

<template>
  <div id="cesiumContainer"></div>
</template>

<script>
  export default {
    mounted() {
      Cesium.Ion.defaultAccessToken =你的token
      this.viewer = new this.Cesium.Viewer('cesiumContainer'); // 创建 Cesium 场景
    }
  }
</script>

<style>
  #cesiumContainer {
    height: 100%;
    width: 100%;
  }
</style>

这只是一个简单的示例,您可以通过查看 Cesium 的文档和示例来学习如何使用更高级的功能。

注意:Cesium报错VM2395:1 Blocked script execution in 'about:blank' because the document's frame is sandboxed and the 'allow-scripts' permission is not set.

这个错误信息通常出现在脚本尝试在沙盒框架中运行,但是'allow-scripts'权限没有被设置。

沙盒是一种安全特性,将潜在风险的代码(例如第三方脚本)与系统的其余部分隔离开来,防止脚本对浏览器的恶意操作。'allow-scripts'是一个权限选项,允许在沙箱环境中运行脚本。如果未设置此权限,浏览器将阻止脚本在沙箱中运行并显示此错误消息。

可能是因为infoBox中使用复杂的HTML标记和JavaScript脚本

禁用infobox就可以解决

const viewer = new Viewer('cesiumContainer', {
  infoBox: false, // If set to false, the InfoBox widget will not be created.
});

中文API文档:http://cesium.xin/cesium/cn/Documentation1.72/index.html 

官方API文档:https://cesium.com/learn/cesiumjs/ref-doc/

this.viewer = new Cesium.Viewer(dom, {
      baseLayerPicker: true, // 如果设置为false,将不会创建右上角图层按钮。
      geocoder: true, // 如果设置为false,将不会创建右上角查询(放大镜)按钮。
      navigationHelpButton: true, // 如果设置为false,则不会创建右上角帮助(问号)按钮。
      homeButton: true, // 如果设置为false,将不会创建右上角主页(房子)按钮。
      sceneModePicker: true, // 如果设置为false,将不会创建右上角投影方式控件(显示二三维切换按钮)。
      animation: true, // 如果设置为false,将不会创建左下角动画小部件。
      timeline: true, // 如果设置为false,则不会创建正下方时间轴小部件。
      fullscreenButton: true, // 如果设置为false,将不会创建右下角全屏按钮。
      scene3DOnly: true, // 为 true 时,每个几何实例将仅以3D渲染以节省GPU内存。
      shouldAnimate: true, // 默认true ,否则为 false 。此选项优先于设置 Viewer#clockViewModel 。
      // ps. Viewer#clockViewModel 是用于控制当前时间的时钟视图模型。我们这里用不到时钟,就把shouldAnimate设为false
      infoBox: false, // 是否显示点击要素之后显示的信息,原生自带右上角弹窗
      sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
      requestRenderMode: false, // 启用请求渲染模式,不需要渲染,节约资源吧
      selectionIndicator: false, // Cesium 关闭点击绿色框
      // fullscreenElement: document.body, // 全屏时渲染的HTML元素 暂时没发现用处,虽然我关闭了全屏按钮,但是键盘按F11 浏览器也还是会进入全屏
      imageryProvider: layer0, //影像地图修改
      // imageryProviderViewModels: [img_tdt_yx, img_tdt_dx, img_tdt_sl], //可供BaseLayerPicker选择的图像图层ProviderViewModel数组
      terrainProvider: Cesium.createWorldTerrain(), //提供地形
    });
    //通过指定的url模板请求图块提供图像
    var layer0 = new Cesium.UrlTemplateImageryProvider({
      tileWidth: 256, //默认贴图宽度
      tileHeight: 256,
      url: "http://t{R}.tianditu.gov.cn/DataServer?T=img_w&amp;x={x}&amp;y={y}&amp;l={z}&amp;tk=7254799da9b1f3d1f335f09497cd8848",
      maximumLevel: 18,
      customTags: {
        R: function (imageryProvider, x, y, level) {
          return Math.floor(Math.random() * 6);
        },
      },
    });

四:三维球定位到中国 

flyto:将相机从当前位置移动到新位置。会有一个飞行动画 ; setview设置相机的位置,方向和变换。直接定位

// 三维球定位到中国
viewer.camera.flyTo({
  destination: Cesium.Cartesian3.fromDegrees(121.871337890625,30.893386706430803,178500),//定位的位置
  orientation: {
    heading :  Cesium.Math.toRadians(0),// 水平偏角,默认正北 0
    pitch : Cesium.Math.toRadians(-90),// 俯视角,-90,垂直向下
    roll : Cesium.Math.toRadians(0)
  },
  complete:function callback() {
    // 定位完成之后的回调函数
    setTimeout(()=>{
      getview()
    },2000) 
  }
});
var position = Cesium.Cartesian3.fromDegrees(86.889, 27.991, 84000);
//相机定位到珠穆朗玛峰
viewer.camera.setView({
    destination: position,
    orientation:{
        heading:Cesium.Math.toRadians(0.0), //正北
        pitch:Cesium.Math.toDegrees(-10), //平视
        roll: 0.0
    }
});

五:添加entities实体

const boundingSphere = new Cesium.BoundingSphere(
   Cesium.Cartesian3.fromDegrees(120.55538, 31.87532, 100),
   15000
);
// 定位到初始位置 将相机移到当前视图包含所提供的包围球的位置
this.viewer.camera.flyToBoundingSphere(boundingSphere, {
// 动画,定位到初始位置的过渡时间,设置成0,就没有动画
   duration: 0,
});
//初始点位数据
    loadPoints() {
      // 用模拟数据测试
      this.pointInfo = [
        {
          id: "392f7fbb-ae25-4eef-ac43-58fd91148d1f",
          latitude: "31.87532",
          longitude: "120.55538",
          psName: "点位1",
        },
        {
          id: "0278a88c-b4f4-4d64-9ccb-65831b3fb19d",
          latitude: "31.991057",
          longitude: "120.700713",
          psName: "点位2",
        },
        {
          id: "248f6853-2ced-4aa6-b679-ea6422a5f3ac",
          latitude: "31.94181",
          longitude: "120.51517",
          psName: "点位3",
        },
        {
          id: "F8DADA95-A438-49E1-B263-63AE3BD7DAC4",
          latitude: "31.97416",
          longitude: "120.56132",
          psName: "点位4",
        },
        {
          id: "9402a911-78c5-466a-9162-d5b04d0e48f0",
          latitude: "31.91604",
          longitude: "120.57771",
          psName: "点位5",
        },
        {
          id: "EB392DD3-6998-437F-8DCB-F805AD4DB340",
          latitude: "31.88727",
          longitude: "120.48887",
          psName: "点位6",
        },
      ];
      this.addMarker();
    },
    //初始化加载点位
    addMarker() {
      // 自定义label颜色
      const _textColor = "rgb(11, 255, 244)";
      // 清除上一次加载的点位
      this.clearMarker();
      // foreach循环加载点位
      this.pointInfo.forEach((pointObj) => {
        this.viewer.entities.add({
          name: pointObj.psName,
          code: pointObj.id,
          id: pointObj.id,
          position: Cesium.Cartesian3.fromDegrees(
            pointObj.longitude * 1,
            pointObj.latitude * 1
          ),

          点
          point: {
            pixelSize: 5,
            color: Cesium.Color.RED,
            outlineColor: Cesium.Color.WHITE,
            outlineWidth: 5,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //设置HeightReference高度参考类型为CLAMP_TO_GROUND贴地类型
          },
          // 文字标签
          label: {
            // show: false,
            text: pointObj.psName,
            font: "12px monospace",
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            // fillColor: Cesium.Color.LIME,
            fillColor: Cesium.Color.fromCssColorString(_textColor),
            outlineWidth: 4,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直方向以底部来计算标签的位置
            pixelOffset: new Cesium.Cartesian2(0, -20), // 偏移量
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //设置HeightReference高度参考类型为CLAMP_TO_GROUND贴地类型
          },
          // 图标
          billboard: {
            image: require("../../assets/images/profile.jpg"),
            width: 18,
            height: 24,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //设置HeightReference高度参考类型为CLAMP_TO_GROUND贴地类型
          },
        });
      });
    },

六:添加点击事件

http://cesium.xin/cesium/cn/Documentation1.72/global.html?classFilter=ScreenSpaceEventType#ScreenSpaceEventType

// 监听地图点击事件
      const handler = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );
      handler.setInputAction((e) => {
        console.log("鼠标点击事件", e.position.x * 1, e.position.y * 1);
        //清除之前的点位
        this.clearMarker();

        // 屏幕坐标转世界坐标——关键点
        const cartesian = this.viewer.camera.pickEllipsoid(
          e.position,
          this.viewer.scene.globe.ellipsoid
        );
        // 将笛卡尔坐标转换为地理坐标
        const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        // 将弧度转为度的十进制度表示,保留5位小数
        const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5);
        const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5);
        console.log(lon, lat);
        //新增点位
        this.viewer.entities.add({
          name: "1",
          id: "1",
          position: Cesium.Cartesian3.fromDegrees(lon, lat),
          // 点
          point: {
            pixelSize: 5,
            color: Cesium.Color.RED,
            outlineColor: Cesium.Color.WHITE,
            outlineWidth: 5,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //设置HeightReference高度参考类型为CLAMP_TO_GROUND贴地类型
          },
          label: {
            // show: false,
            text: "新增点位",
            font: "12px monospace",
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            // fillColor: Cesium.Color.LIME,
            fillColor: Cesium.Color.fromCssColorString("rgb(11, 255, 244)"),
            outlineWidth: 4,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直方向以底部来计算标签的位置
            pixelOffset: new Cesium.Cartesian2(0, -20), // 偏移量
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //设置HeightReference高度参考类型为CLAMP_TO_GROUND贴地类型
          },
          billboard: {
            image: require("../../assets/images/profile.jpg"),
            width: 18,
            height: 24,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //设置HeightReference高度参考类型为CLAMP_TO_GROUND贴地类型
          },
        });

        this.viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(lon, lat, 15000),
        });

        // 获取地图上的点位实体(entity)坐标
        const pick = this.viewer.scene.pick(e.position);
      }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

七:通过JSON加载范围线 

let res = Cesium.GeoJsonDataSource.load(jsonUrl, {
  stroke: {red: 1, green: 1, blue: 1, alpha: 0.4},
  fill: Cesium.Color.BLUE.withAlpha(0.4), //注意:颜色必须大写,即不能为blue
  strokeWidth: 3,
  clampToGround: true
});
  res.then(buffersource => {
  viewer.dataSources.add(buffersource);
  buffersource.name = "XXX";
})

总结 

到此这篇关于在vue上使用cesium开发三维地图的文章就介绍到这了,更多相关vue cesium开发三维地图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue循环el-button实现点击哪个按钮,那个按钮就变色

    vue循环el-button实现点击哪个按钮,那个按钮就变色

    这篇文章主要介绍了vue循环el-button实现点击哪个按钮,那个按钮就变色问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • VSCode写vue项目一键生成.vue模版,修改定义其他模板的方法

    VSCode写vue项目一键生成.vue模版,修改定义其他模板的方法

    这篇文章主要介绍了VSCode写vue项目一键生成.vue模版,修改定义其他模板的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • Vue的props配置项详解

    Vue的props配置项详解

    这篇文章主要为大家详细介绍了Vue的props配置项,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • vue3渲染函数(h函数)的变更剖析

    vue3渲染函数(h函数)的变更剖析

    这篇文章主要介绍了vue3渲染函数(h函数)的变化,文中给大家介绍了h函数的三个参数详细说明及vue3 h函数-绑定事件,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • vue element-plus中el-input修改边框border的方法

    vue element-plus中el-input修改边框border的方法

    element样式还是蛮好的,只是有时候我们需要做一些调整,比如el-input的边框,下面这篇文章主要给大家介绍了关于vue element-plus中el-input修改边框border的相关资料,需要的朋友可以参考下
    2022-09-09
  • 使用Vue+MySQL实现登录注册的实战案例

    使用Vue+MySQL实现登录注册的实战案例

    第一次用Vue+MySQL实现注册登录功能,就已经踩了很多坑,下面这篇文章主要给大家介绍了关于使用Vue+MySQL实现登录注册案例的相关资料,需要的朋友可以参考下
    2022-05-05
  • vue vue-esign签字板的demo

    vue vue-esign签字板的demo

    这篇文章主要介绍了vue vue-esign签字板的实例讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Vue中避免滥用this去读取data中数据

    Vue中避免滥用this去读取data中数据

    这篇文章主要介绍了Vue中避免滥用this去读取data中数据的的相关资料,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下
    2021-03-03
  • vue原理Compile之optimize标记静态节点源码示例

    vue原理Compile之optimize标记静态节点源码示例

    这篇文章主要为大家介绍了vue原理Compile之optimize标记静态节点源码示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 基于vue中css预加载使用sass的配置方式详解

    基于vue中css预加载使用sass的配置方式详解

    下面小编就为大家分享一篇基于vue中css预加载使用sass的配置方式详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03

最新评论