Cesium.js基础使用(vue)

如何通过Cesium创建一个地图:

1、npm安装(这里使用1.95.0版本)

npm i cesium@1.95.0 -s
或
yarn add cesium@1.95.0 -s

2、组件引入

import * as Cesium from "cesium/Cesium";

3、容器创建

<div id="cesiumContainer" />

4、核心类Viewer创建

在Cesium中Viewer是一切的开端,通过newCesium.Viewer(container, options)来创建一个Viewer对象,可以把该对象理解为三维虚拟地球,在Viewer对象上的所有操作,可以看作是对三维虚拟地球的操作。

const viewer = new Viewer("cesiumContainer", {
        infoBox: false,
        animation: false, // 是否显示动画控件
        homeButton: false, // 是否显示home键
        geocoder: false, // 是否显示地名查找控件
        baseLayerPicker: false, // 是否显示图层选择控件
        timeline: false, // 是否显示时间线控件
        fullscreenButton: false, // 是否全屏显示
        infoBox: false, // 是否显示点击要素之后显示的信息
        sceneModePicker: false, // 是否显示投影方式控件  三维/二维
        navigationInstructionsInitiallyVisible: false,
        navigationHelpButton: false, // 是否显示帮助信息控件
        orderIndependentTranslucency: false,
        shouldAnimate: true,
        scene3DOnly: false, // 每个几何实例将只能以3D渲染以节省GPU内存
        selectionIndicator: false, // 取消点击有绿框
        // imageryProvider: false, // 不提供地图
        baseLayerPicker: true, //是否显示图层选择控件
      });

5、 设置初始位置(经纬度、缩放比例)

    viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(
          113.764043,
          34.005325,
          8000000
        ),
      });

此时,一个地球就出现了!!!

cesium内置了一些图层供我们切换。

 还可以通过一些json数据给地图添加想要的区块图层

    //阿里云地理信息工具 数据获取
      viewer.dataSources.add(
        Cesium.GeoJsonDataSource.load(
          "https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json"
        )
      );
我们还可以通过cesium对一些建筑物进行观察

但需要申请Cesium的令牌(token)

如何申请?

通过以下官网地址申请

 Cesium ion

 使用:

 Cesium.Ion.defaultAccessToken =       "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNDVhMjQ0Yi05MDg4LTRlNDYtYTIxMi00YmI4ZWYxOWMyNTgiLCJpZCI6MTQ5MzYwLCJpYXQiOjE2ODc3ODQ0OTh9.KlhT_LCnsEtYyawpEmJ_wx44_qTUbgze-SxGMRavbAM";

之后就可以访问高清页面;

完整代码

<template>
  <div id="cesiumContainer" @dragover="allowDrop" @drop="drop">
    <nav>
      <button @click="draw('point')">点绘制</button>
      <button @click="draw('polyline')">线绘制</button>
      <button @click="draw('polygon')">圆绘制</button>
      <button @click="clearDrawEntities">清空</button>
    </nav>

    
  </div>
</template>

<script>
import * as Cesium from "cesium/Cesium";
import { Viewer } from "cesium/Cesium";

import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { transform, getTransform } from "ol/proj";
// import { selectNodesForSpecifiedRegion } from "../../utils/gis/commonMethods";
export default {
  name: "cesiumView",
  data() {
    return {
      // map: null,
      cesiumContainer: null,
      mapViewer: null,
      tempEntities: [],
      activeNames: [],
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    handleChange() {},

    //init
    initMap() {
      // 此应用程序正在使用 Cesium 的默认 ion 访问令牌,请在使用 Ceisum API 调用之前先注册一个你自己的 Cesium ion 访问令牌
      Cesium.Ion.defaultAccessToken =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNDVhMjQ0Yi05MDg4LTRlNDYtYTIxMi00YmI4ZWYxOWMyNTgiLCJpZCI6MTQ5MzYwLCJpYXQiOjE2ODc3ODQ0OTh9.KlhT_LCnsEtYyawpEmJ_wx44_qTUbgze-SxGMRavbAM";
      const viewer = new Viewer("cesiumContainer", {
        infoBox: false,
        animation: false, // 是否显示动画控件
        homeButton: false, // 是否显示home键
        geocoder: false, // 是否显示地名查找控件
        baseLayerPicker: false, // 是否显示图层选择控件
        timeline: false, // 是否显示时间线控件
        fullscreenButton: false, // 是否全屏显示
        infoBox: false, // 是否显示点击要素之后显示的信息
        sceneModePicker: false, // 是否显示投影方式控件  三维/二维
        navigationInstructionsInitiallyVisible: false,
        navigationHelpButton: false, // 是否显示帮助信息控件
        orderIndependentTranslucency: false,
        shouldAnimate: true,
        scene3DOnly: false, // 每个几何实例将只能以3D渲染以节省GPU内存
        selectionIndicator: false, // 取消点击有绿框
        // imageryProvider: false, // 不提供地图
        baseLayerPicker: true, //是否显示图层选择控件
      });
      //设置初始位置
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(
          113.764043,
          34.005325,
          3000
        ),
      });

      // entities 默认点位
      // const entity = viewer.entities.add({
      //   position: Cesium.Cartesian3.fromDegrees(116.39, 39.91, 400),
      //   point: {
      //     pixelSize: 50,
      //     color: new Cesium.Color(0, 1, 0, 1),
      //   },
      // });
      // //将摄像头设置到远点处
      // viewer.trackedEntity = entity;

      //阿里云地理信息工具 数据获取
      // viewer.dataSources.add(
      //   Cesium.GeoJsonDataSource.load(
      //     "https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json"
      //   )
      // );

      // Viewer.scene.globe.show = false;
      // logo去除
      viewer.cesiumWidget.creditContainer.style.display = "none";

      this.mapViewer = viewer;

      window.viewer = viewer;

      console.log(viewer, "viewer");
    },
    // deleteRectangle() {},

    //获取经纬度
    getPosition(viewer) {
      let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
      handler.setInputAction(function (event) {
        let cartesian = viewer.scene.pickPosition(event.position);
        let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
        let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
        let alt = cartographic.height; // 高度
        let coordinate = {
          longitude: Number(lng.toFixed(6)),
          latitude: Number(lat.toFixed(6)),
          altitude: Number(alt.toFixed(2)),
        };
        console.log(coordinate,'coordinate');
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },
    /**
     * Role map drop
     * Desc 元素拖入地图放置事件
     */
    drop(e) {
      e.preventDefault();

      this.getPosition(window.viewer);
      // console.log(e, "eeeeeeeeee");
      // const pos = transform(this.map.getEventCoordinate(e), "EPSG:3857", "EPSG:4326");
      // console.log(pos, "pos");

      // const pos = ol.proj.transform(pos, 'EPSG:3857', 'EPSG:4326');
      // const data = e.dataTransfer.getData("Text");
      // console.log(data,'data')
    },
    //图标拖动效果
    drag(event, item) {
      console.log(event, item, "---------------");
    },
    /**
     * Role dragover
     * Desc 在可拖动的元素或者被选择的文本被拖进一个有效的放置目标时(每几百毫秒)触发,
     *      允许元素拖入地图
     */
    allowDrop(e) {
      e.preventDefault();
      // event.preventDefault
    },
    draw(type) {
      //点绘制
      let _this = this;
      let viewer = this.mapViewer;
      let tempEntities = this.tempEntities;
      let position = [];
      let tempPoints = [];

      /**
       * Role  depthTestAgainstTerrain 开启地形深度检测
       * desc  开启地形检测后,会计算其他地理要素和地形之间的遮挡关系。未开启时,将会出现场景变化时,地物位置显示不正确。
       */
      viewer.scene.globe.depthTestAgainstTerrain = true;

      /**
       * Role ScreenSpaceEventHandler
       * type => canvas
       * default => Document
       * desc 处理用户输入事件。可以添加自定义功能以在以下位置执行当用户输入输入时。
       */
      let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

      switch (type) {
        case "point":
          //监听 鼠标左键
          handler.setInputAction(function (movement) {
            // 从相机位置通过windowPosition 世界坐标中的像素创建一条射线。返回Cartesian3射线的位置和方向。
            let ray = viewer.camera.getPickRay(movement.position);
            // 查找射线与渲染的地球表面之间的交点。射线必须以世界坐标给出。返回Cartesian3对象
            position = viewer.scene.globe.pick(ray, viewer.scene);
            let point = _this.drawPoint(position);
            tempEntities.push(point);

            /**
             * Role ScreenSpaceEventType
             * Desc 此枚举类型用于对鼠标事件进行分类:向下,向上,单击,双击,按住按钮时移动。
             */
          }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
          // 左键双击停止绘制
          handler.setInputAction(function () {
            handler.destroy(); //关闭事件句柄
            handler = null;
          }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
          // 右击单击停止绘制
          handler.setInputAction(function () {
            handler.destroy(); //关闭事件句柄
            handler = null;
          }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
          break;
        case "polyline":
          //鼠标移动事件
          handler.setInputAction(function (movement) {},
          Cesium.ScreenSpaceEventType.MIDDLE_CLICK);
          //左键点击操作
          handler.setInputAction(function (click) {
            //调用获取位置信息的接口
            let ray = viewer.camera.getPickRay(click.position);
            position = viewer.scene.globe.pick(ray, viewer.scene);
            tempPoints.push(position);
            let tempLength = tempPoints.length;
            //调用绘制点的接口
            let point = _this.drawPoint(tempPoints[tempPoints.length - 1]);
            tempEntities.push(point);
            if (tempLength > 1) {
              let pointline = _this.drawPolyline([
                tempPoints[tempPoints.length - 2],
                tempPoints[tempPoints.length - 1],
              ]);
              tempEntities.push(pointline);
            } else {
              // tooltip.innerHTML = "请绘制下一个点,右键结束";
            }
          }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
          //右键点击操作
          handler.setInputAction(function (click) {
            tempPoints = [];
            handler.destroy(); //关闭事件句柄
            handler = null;
          }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
          break;
        case "polygon":
          //鼠标移动事件
          handler.setInputAction(function (movement) {},
          Cesium.ScreenSpaceEventType.MOUSE_MOVE);
          //左键点击操作
          handler.setInputAction(function (click) {
            //调用获取位置信息的接口
            let ray = viewer.camera.getPickRay(click.position);
            position = viewer.scene.globe.pick(ray, viewer.scene);
            tempPoints.push(position);
            let tempLength = tempPoints.length;
            //调用绘制点的接口
            let point = _this.drawPoint(position);
            tempEntities.push(point);
            if (tempLength > 1) {
              let pointline = _this.drawPolyline([
                tempPoints[tempPoints.length - 2],
                tempPoints[tempPoints.length - 1],
              ]);
              tempEntities.push(pointline);
            } else {
              // tooltip.innerHTML = "请绘制下一个点,右键结束";
            }
          }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
          //右键点击操作
          handler.setInputAction(function (click) {
            let cartesian = viewer.camera.pickEllipsoid(
              click.position,
              viewer.scene.globe.ellipsoid
            );

            if (cartesian) {
              let tempLength = tempPoints.length;
              if (tempLength < 3) {
                alert("请选择3个以上的点再执行闭合操作命令");
              } else {
                //闭合最后一条线
                let pointline = _this.drawPolyline([
                  tempPoints[tempPoints.length - 1],
                  tempPoints[0],
                ]);
                tempEntities.push(pointline);
                _this.drawPolygon(tempPoints);
                tempEntities.push(tempPoints);
                handler.destroy(); //关闭事件句柄
                handler = null;
              }
            }
          }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
          break;
      }
    },
    drawPoint(position, config) {
      let viewer = this.mapViewer;
      let config_ = config ? config : {};
      return viewer.entities.add({
        name: "点几何对象",
        position: position,
        point: {
          color: Cesium.Color.SKYBLUE,
          pixelSize: 10,
          outlineColor: Cesium.Color.YELLOW,
          outlineWidth: 3,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        },
      });
    },
    drawPolyline(positions, config_) {
      let viewer = this.mapViewer;
      if (positions.length < 1) return;
      let config = config_ ? config_ : {};
      return viewer.entities.add({
        name: "线几何对象",
        polyline: {
          positions: positions,
          width: config.width ? config.width : 5.0,
          material: new Cesium.PolylineGlowMaterialProperty({
            color: config.color
              ? new Cesium.Color.fromCssColorString(config.color)
              : Cesium.Color.GOLD,
          }),
          depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
            color: config.color
              ? new Cesium.Color.fromCssColorString(config.color)
              : Cesium.Color.GOLD,
          }),
          clampToGround: true,
        },
      });
    },
    drawPolygon(positions, config_) {
      let viewer = this.mapViewer;
      if (positions.length < 2) return;
      let config = config_ ? config_ : {};
      return viewer.entities.add({
        name: "面几何对象",
        polygon: {
          hierarchy: positions,
          material: config.color
            ? new Cesium.Color.fromCssColorString(config.color).withAlpha(0.2)
            : new Cesium.Color.fromCssColorString("#FFD700").withAlpha(0.2),
        },
      });
    },
    //清除实体
    clearDrawEntities() {
      let viewer = this.mapViewer;
      this.tempEntities = [];
      // 清除之前的实体
      const entitys = viewer.entities._entities._array;
      let length = entitys.length;
      // 倒叙遍历防止实体减少之后entitys[f]不存在
      for (let f = length - 1; f >= 0; f--) {
        if (
          entitys[f]._name &&
          (entitys[f]._name === "点几何对象" ||
            entitys[f]._name === "线几何对象" ||
            entitys[f]._name === "面几何对象")
        ) {
          viewer.entities.remove(entitys[f]);
        }
      }
    },
  },
};
</script>

<style lang="less" scoped>
#cesiumContainer {
  width: 100vw;
  height: 100vh;
  position: relative;
  header {
    position: absolute;
    top: 0;
    width: 100%;
    height: 50px;
    background: rgba(0, 0, 0, 0.5);
  }
  .leftBar {
    width: 250px;
    height: 50%;
    position: absolute;
    top: 30%;
    z-index: 999;
    .el-collapse-item__content {
      display: flex;
      justify-content: space-between;
      // flex-wrap: wrap;
    }
    .collapseItems {
      // display: block;
      width: 100%;
      height: auto;
      .ivu-icon {
        display: block;
      }
      b {
        display: block;
        text-align: center;
      }
    }
  }
  nav {
    position: absolute;
    left: 20px;
    top: 20px;
    width: 150px;
    height: 180px;
    // background: rgba(0, 0, 0, 0.5);
    z-index: 999;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    button {
      width: 100%;
      height: 30px;
      cursor: pointer;
    }
  }
}
</style>

  • 11
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值