vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue cesium开发三维地图

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

作者: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开发三维地图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文