基于Vue框架开发的页面加载三维维地图以及交互

一、在Vue项目中引入三维地图

1.安装对应的包

//安装mars3d主库
npm install mars3d --save   

//安装mars3d插件(按需安装)
npm install mars3d-space --save

2.为了方便使用,绑定到原型链,在其他vue文件,直接 this.mars3d 来使用

<template>
  <div :id='`tong3d-container${mapKey}`'
       :class="['tong3d-container', customClass, { 'tong3d-container-compare-rh' : compare }]"></div>
</template>

<script>
import Vue from 'vue'
import './lib/tong3d.css'
import './lib/tong3d'

// 为了方便使用,绑定到原型链,在其他vue文件,直接 this.mars3d 来使用
Vue.prototype.tong3d = tong3d
Vue.prototype.Cesium = tong3d.Cesium

export default {
  name: 'tong3dViewer',

  props: {
    // 初始化配置参数
    url: String,

    // 地图唯一性标识
    mapKey: {
      type: String,
      default: ''
    },

    // 自定义参数
    options: Object,

    // 是否分屏显示
    compare: {
      type: Boolean,
      default: false
    },

    // 是否插入到body元素上
    appendToBody: {
      type: Boolean,
      default: false
    },

    // 自定义css类名
    customClass: {
      type: String,
      default: ''
    }
  },

  mounted() {
    if (this.appendToBody) {
      document.body.appendChild(this.$el)
    }

    if (this.mapKey) {
      this.initTong3d(this.options)
    } else {
      tong3d.Resource.fetchJson({ url: this.url }).then((data) => {
        this.initTong3d(data.map3d)// 构建地图
      })
    }
  },

  beforeDestroy() {
    this[`map${this.mapKey}`].destroy()
    delete this[`map${this.mapKey}`]
  },

  methods: {
    initTong3d(options) {
      if (this[`map${this.mapKey}`]) {
        this[`map${this.mapKey}`].destroy()
      }

      const mapOptions = {
        ...options,
        ...this.options
      }

      // 创建三维地球场景
      var map = new tong3d.Map(`tong3d-container${this.mapKey}`, mapOptions)

      this[`map${this.mapKey}`] = map

      console.log('>>>>> 地图创建成功 >>>>', map)

      // 挂载到全局对象下,所有组件通过 this.map 访问
      // Vue.prototype[`map${this.mapKey}`] = map

      // 绑定对alert的处理,右键弹出信息更美观。
      // window.haoutil = window.haoutil || {}
      // window.haoutil.msg = (msg) => {
      //   this.$message.success(msg)
      // }
      // window.haoutil.alert = (msg) => {
      //   this.$message.success(msg)
      // }

      // 抛出事件
      this.$emit('onload', map)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.tong3d-container {
  height: 100%;
  overflow: hidden;
}

/* 重写Cesium的css */

/**cesium按钮背景色*/
.cesium-button {
  background-color: #3f4854;
  color: #e6e6e6;
  fill: #e6e6e6;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  line-height: 32px;
}

.cesium-viewer-geocoderContainer .cesium-geocoder-input {
  background-color: rgba(63, 72, 84, 0.7);
}

.cesium-viewer-geocoderContainer .cesium-geocoder-input:focus {
  background-color: rgba(63, 72, 84, 0.9);
}

.cesium-viewer-geocoderContainer .search-results {
  background-color: #3f4854;
}

.cesium-geocoder-searchButton {
  background-color: #3f4854;
}

.cesium-infoBox-title {
  background-color: #3f4854;
}

.cesium-infoBox {
  background: rgba(63, 72, 84, 0.9);
}

.cesium-toolbar-button img {
  height: 100%;
}

.cesium-performanceDisplay-defaultContainer {
  top: auto;
  bottom: 35px;
  right: 50px;
}

.cesium-performanceDisplay-ms,
.cesium-performanceDisplay-fps {
  color: #fff;
}

/**cesium工具栏位置*/
.cesium-viewer-toolbar {
  top: auto;
  left: auto;
  right: 12px;
  bottom: 35px;
}

.cesium-viewer-toolbar > .cesium-toolbar-button,
.cesium-navigationHelpButton-wrapper,
.cesium-viewer-geocoderContainer {
  margin-bottom: 5px;
  float: right;
  clear: both;
  text-align: center;
}

.cesium-baseLayerPicker-dropDown {
  bottom: 0;
  right: 40px;
  max-height: 700px;
  margin-bottom: 5px;
}

.cesium-navigation-help {
  top: auto;
  bottom: 0;
  right: 40px;
  transform-origin: right bottom;
}

.cesium-sceneModePicker-wrapper {
  width: auto;
}

.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-dropDown-icon {
  float: left;
  margin: 0 3px;
}

.cesium-viewer-geocoderContainer .search-results {
  left: 0;
  right: 40px;
  width: auto;
  z-index: 9999;
}

.cesium-infoBox-title {
  background-color: #3f4854;
}

.cesium-infoBox {
  top: 50px;
  background: rgba(63, 72, 84, 0.9);
}

/**左下工具栏菜单*/
.toolbar-dropdown-menu-div {
  background: rgba(43, 44, 47, 0.8);
  border: 1px solid #2b2c2f;
  z-index: 991;
  position: absolute;
  right: 60px;
  bottom: 40px;
  display: none;
}

.toolbar-dropdown-menu {
  min-width: 110px;
  padding: 0;
}

.toolbar-dropdown-menu > li {
  padding: 0 3px;
  margin: 2px 0;
}

.toolbar-dropdown-menu > li > a {
  color: #edffff;
  display: block;
  padding: 4px 10px;
  clear: both;
  font-weight: normal;
  line-height: 1.6;
  white-space: nowrap;
  text-decoration: none;
}

.toolbar-dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
  color: #fff;
  background-color: #444d59;
}

.toolbar-dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
  color: #fff;
  background-color: #444d59;
}

.toolbar-dropdown-menu i {
  padding-right: 5px;
}
</style>

3.加载三维地图

<!--
 * @Descripttion:
 * @version:
 * @Author: zhangfan
 * @email: 2207044692@qq.com
 * @Date: 2021-10-28 14:34:51
 * @LastEditors: zhangfan
 * @LastEditTime: 2022-03-18 14:13:25
-->
<template>
  <div id='centerDiv' class='mapcontainer'>
    <Map :url='configUrl' @onload='onMapload' />
  </div>
</template>

<script>
import Map from '../components/tong3d/Map.vue'
export default {
  name: 'Index',
  components: {
    Map
  },
  data() {
    return {
      configUrl:  {
          "map3d": {
            "scene": {
              "center": { "lat": 39.91737, "lng": 116.408293, "alt": 8000, "heading": 0, "pitch": -45 },
              "scene3DOnly": false,
              "shadows": false,
              "removeDblClick": true,
              "sceneMode": 3,
              "showSun": true,
              "showMoon": true,
              "showSkyBox": true,
              "showSkyAtmosphere": true,
              "fog": true,
              "fxaa": true,
              "globe": {
                "depthTestAgainstTerrain": true,
                "baseColor": "#546a53",
                "showGroundAtmosphere": true,
                "enableLighting": false
              },
              "cameraController": {
                "zoomFactor": 3.0,
                "minimumZoomDistance": 1,
                "maximumZoomDistance": 50000000,
                "enableRotate": true,
                "enableTranslate": true,
                "enableTilt": true,
                "enableZoom": true,
                "enableCollisionDetection": true,
                "minimumCollisionTerrainHeight": 15000
              }
            },
            "basemaps": [
              {
                "name": "地图",
                "icon": "img/12.png",
                "type": "xyz",
                "url": "http://xx.xx.xx.xx.xx/{z}/{x}/{y}.png",
                "subdomains": "abc",
                "show": true   
              }
            ]
          }
      },
    }
  },
  methods: {
    // 地图构造完成回调
    onMapload(map) {
      // 以下为演示代码
      // 创建entity图层
      this.graphicLayerData = new this.tong3d.layer.GraphicLayer()
      map.addLayer(this.graphicLayerData)
      this.mapBasice = map
    },
    // 画波纹
    addDemoGraphic1(graphicLayer,var2) {
        var graphic = new tong3d.graphic.CircleEntity({
          position: var2,
          style: {
            radius: 200,
            height: 0,
            material: tong3d.MaterialUtil.createMaterialProperty(tong3d.MaterialType.CircleWave, {
              color: "#ffff00",
              count: 2,
              speed: 5,
            }),
            clampToGround: true,
          },
        });
        graphicLayer.addGraphic(graphic);
      },
      //线条
    addDemoPolyline(graphicLayer,lineData) {
      let line =  new tong3d.graphic.PolylineEntity({
          positions:lineData,
          style:{
            width:3,
            material: mars3d.MaterialUtil.createMaterialProperty(
            //新建材质线
            mars3d.MaterialType.PolylineOutline, //线的材质
            {
              color: "#03F5FA",
              outlineWidth: 2, //线的轮廓宽度
              outlineColor: "#03F5FA", //线的轮廓颜色
            }
          ),
          }
      })
      graphicLayer.addGraphic(line)
    },
    // 使用图标点替换自定义
    addBillBort(graphicLayer,var1,var2,droneId){
      let graphic =new mars3d.graphic.BillboardEntity({
          position:var1,
          style:{
            image:"../../static/img/drone.png",
            droneId:droneId
          }
      })
      this.wrjGrapic.push(graphic)
      let tool = new mars3d.graphic.Tooltip({
          position:var1,
          style:{
            direction:'right',
            template:false,//不使用内置文档
            scaleByDistance:true,
            distanceDisplayCondition:true,
            offsetX:250,
            offsetY:155,
            html:this.toolText
          }
      })
      let line =  new tong3d.graphic.PolylineEntity({
          positions:[var2,var1],
          style:{
            width:5,
            material:  new Cesium.PolylineDashMaterialProperty({
              color: Cesium.Color.YELLOW,
              dashLength: 20 //短划线长度
            })
,
          }
      })
      //图标点鼠标移入时显示弹窗
      graphic.on(mars3d.EventType.mouseOver,()=>{graphicLayer.addGraphic(tool)})
      graphic.on(mars3d.EventType.mouseOut,()=>{graphicLayer.removeGraphic(tool)})

      // 左键显示历史数据,右键重置
      graphic.on(mars3d.EventType.click,this.showHisTrack)
      graphic.on(mars3d.EventType.rightClick,this.hiddHisTrack)
      graphicLayer.addGraphic(line)
      graphicLayer.addGraphic(graphic);
    },
    showHisTrack(e){
      // 获取参数
      console.log(e)
      if(!e.target){
        var ids = e.graphic.options.style.droneId//获取id
      }
      else{
        var ids = e.target.options.style.droneId//获取id
      }
      let ind = this.idList.indexOf(ids)
      console.log(ind)
      if(this.trackLayer[ind] == -1){
        this.trackLayer[ind] =  new this.tong3d.layer.GraphicLayer() 
        this.mapBasice.addLayer(this.trackLayer[ind])
      }
      else{
        this.trackLayer[ind].clear()
      }
    getHisTrack({
        droneld: ids,
      }).then(res => {
        let lineData = []
        res.data.forEach((item,index)=>{
          if(index < 15 ){
            if(this.curposition.indexOf(item.var2)==-1){
              this.addPoint(this.trackLayer[ind],JSON.parse(item.var2),JSON.parse(item.var1))
            }
            lineData.push(JSON.parse(item.var2))
          }
        })
        this.addDemoPolyline(this.trackLayer[ind],lineData)
      })
    },
    hiddHisTrack(e){
      // 获取参数
      console.log('hidde')
      console.log(e)
      let ids = e.graphic.options.style.droneId//获取id
      let ind = this.idList.indexOf(ids)
       if(this.trackLayer[ind] != -1){
        this.trackLayer[ind].clear()
        this.mapBasice.removeLayer(this.trackLayer[ind])
        this.trackLayer[ind] = -1
      }
    },
    addPoint(graphicLayer,point,point2){
      var graphic = new tong3d.graphic.PointEntity({
          position: point,
          style: {
           pixelSize:15,
           color:"#03F5FA"
          },
        });
        var graphicTwo = new tong3d.graphic.CircleEntity({
          position: point,
          style: {
            radius: 10,
            height: 0,
            material: tong3d.MaterialUtil.createMaterialProperty(tong3d.MaterialType.CircleWave, {
              color: "#00ffff",
              count: 2,
              speed: 5,
            }),
            clampToGround: true,
          },
        });
        let line =  new tong3d.graphic.PolylineEntity({
          positions:[point,point2],
          style:{
            width:5,
            material:  new Cesium.PolylineDashMaterialProperty({
              color: Cesium.Color.YELLOW,
              dashLength: 20 //短划线长度
            })
,
          }
      }) 
      let tool = new mars3d.graphic.Tooltip({
          position:point,
          style:{
            direction:'right',
            template:false,//不使用内置文档
            scaleByDistance:true,
            distanceDisplayCondition:true,
            offsetX:250,
            offsetY:155,
            html:this.toolText
          }
      })
        graphic.on(mars3d.EventType.mouseOver,()=>{graphicLayer.addGraphic(tool);})
        graphic.on(mars3d.EventType.mouseOut,()=>{graphicLayer.removeGraphic(tool)})
        graphicLayer.addGraphic(line)
        graphicLayer.addGraphic(graphicTwo);
        graphicLayer.addGraphic(graphic);
    }
  },
}
</script>


3.对应的开发文档和教程

在这里插入图片描述
对应的开发教程

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
基于Vue2的Cesium三维地图框架是一种使用Vue2框架和Cesium开源库进行地图可视化的解决方案。Cesium是一个强大的JavaScript库,支持三维地理信息展示,并提供了丰富的地理空间数据可视化功能。Vue2是一种流行的前端开发框架,它提供了组件化开发数据驱动的思想。 借助Vue2的特性,我们可以将Cesium的功能封装成Vue组件,并通过数据绑定、事件监听等方式与其他组件进行交互。这样,我们可以在Vue的生态系统中更加灵活地使用Cesium的功能。例如,我们可以基于Vue2和Cesium实现地图的双向绑定,使得地图的显示和交互可以与其他组件的数据状态关联起来。 基于Vue2的Cesium三维地图框架可以满足各种场景下的地理信息可视化需求。我们可以加载不同的地图图层,包括卫星影像、矢量地图等。同时,我们也可以添加各种地理要素,如点、线、面等,以展示各种地理数据。通过Cesium的丰富功能,我们可以实现地图的缩放、平移、旋转等操作,以及与地图上的要素进行交互。 使用基于Vue2的Cesium三维地图框架可以方便地构建交互式的地理信息系统。我们可以通过监听地图的各种事件,如点击、拖拽等,来实现与地图上要素的交互。同时,基于Vue2的Cesium三维地图框架还可以与其他Vue组件库结合,如Element UI、vuetify等,以实现更加美观和易用的用户界面。 总之,基于Vue2的Cesium三维地图框架能够结合Vue2和Cesium的优势,提供灵活、高效、丰富的地图可视化能力,使得开发者可以方便地构建各种场景下的三维地图应用。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值