Vue结合mars3d基于天地图加载3dtiles模型(三维模型)

官网:http://mars3d.cn/doc
官方提供vue项目示例:https://github.com/marsgis/mars3d-vue-template

1.引入必要插件:
通过npm安装mars3d主库: npm install mars3d
2.在main.js中导入依赖
在这里插入图片描述
3.vue.config.js(或Webpack)配置

const webpack = require('webpack')
const path = require('path')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const cesiumSource = 'node_modules/mars3d-cesium/Build/Cesium/'

module.exports = {
  publicPath: './', // 打包后的位置
  outputDir: 'dist',//打包后的目录名称
  assetsDir: './static', // 静态资源目录名称
  productionSourceMap:false,  //去掉打包的时候生成的map文件
  lintOnSave: false, // 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
  configureWebpack: {
    plugins: [
      new webpack.DefinePlugin({
        CESIUM_BASE_URL: JSON.stringify('static')
      }),
      new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Workers'), to: 'static/Workers' }]),
      new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Assets'), to: 'static/Assets' }]),
      new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'ThirdParty'), to: 'static/ThirdParty' }]),
      new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Widgets'), to: 'static/Widgets' }])
    ],
    // pluginOptions: {
    //   'style-resources-loader': {
    //     preProcessor: 'sass',
    //     patterns: [
    //       path.resolve(__dirname, '@/assets/styles/*.scss')      //你的.scss文件所在目录
    //     ]
    //   }
    // },
    module: {
      unknownContextCritical: false,
      unknownContextRegExp: /\/cesium\/cesium\/Source\/Core\/buildModuleUrl\.js/
    }
  },
}

4.主要代码:

<template>
  <div class="mapcontainer">
    <Map :url="configUrl" @onload="onMapload" />
    <div class="bottomLayer" v-show="showLayerMan">
      <el-button v-for="item in layersList" :key="item.id" type="primary" round :class="[item.options.icon, {activeBtn: item.show}]" @click="updateLayerShow(item)">
        <div style="font-size: 16px;">{{item.name}}</div>
      </el-button>
    </div>
    <el-dialog
            title="3D库室"
            :visible.sync="DialogVisible3D"
            width="1300px"
            :before-close="DialogVisible3DClose">
      <iframe
              style="border:none"
              :src="room3DUrl"
              :width="1200"
              :height="600"
      ></iframe>
    </el-dialog>
  </div>
</template>

<script>
import Map from '@/components/mars3d/Map.vue'  // 此处用的map在官网模板代码里有

export default {
  components: {
    Map
  },
  data () {
    return {
      configUrl: 'config/config.json', // mars3D配置文件
      tilesetUrl: window.Tileset, // 获取三维模型地址
      layersList: [],
      showLayerMan: true,
      DialogVisible3D: false,
      room3DUrl: 'http://.....'  // 显示3d库室地址
    }
  },
  mounted () {
  },
  methods: {
    // 地图构造完成回调
    onMapload(map) {
      this.map = map
      this.removeLayer()
      // 3dTiles格式

      const tileLayer = new this.mars3d.layer.TilesetLayer({
        id: '202158',
        name: '模型',
        url: this.tilesetUrl,
        maximumScreenSpaceError: 16,
        maximumMemoryUsage: 1024,
        dynamicScreenSpaceError: true,
        cullWithChildrenBounds: false,
        skipLevelOfDetail: true,
        preferLeaves: true,
        position: { alt: -50 }, // 城市
        // rotation: { x: 240, y: 0, z: 0 },
        // center: {"lat":34.843297,"lng":114.79871,"alt":430,"heading":30,"pitch":-35},
        // flyTo: true
        icon: 'el-icon-s-home'
      })
      this.layer = tileLayer

      this.map.addLayer(this.layer)
      // 创建摄像头图层
      this.graphicLayerCamera = new this.mars3d.layer.GraphicLayer({id: '20210512',name: '摄像头', icon: 'el-icon-video-camera-solid'})
      this.map.addLayer(this.graphicLayerCamera)
      // 创建3d库室图层
      this.graphicLayer3D = new this.mars3d.layer.GraphicLayer({id: '20210525',name: '3d库室', icon: 'el-icon-receiving'})
      this.map.addLayer(this.graphicLayer3D)

      // 创建弹窗图层
      this.graphicLayerPopup = new this.mars3d.layer.GraphicLayer({id: '20210513',name: '弹窗', icon: 'el-icon-s-comment'})
      this.map.addLayer(this.graphicLayerPopup)

      // 加 摄像头
      this.addGraphicCamera()
      // 加 3d库室
      this.addGraphic3DRoom()

      this.addBtn()
      this.showModel()
    },
    removeLayer() {
      if (this.layer) {
        this.map.removeLayer(this.layer, true)
        this.layer = null
      }
    },
    // 添加自定义按钮
    addBtn () {
      let toolButton = new this.mars3d.control.ToolButton({
        title: '图层管理',
        icon: 'el-icon-coin',
        insertIndex: 3, //插入的位置顺序, 1是home按钮后面
        click: (event) => {
          this.showLayerMan = !this.showLayerMan
        },
      })
      this.map.addControl(toolButton)
       let popupButton = new this.mars3d.control.ToolButton({
         title: '弹窗事件',
         icon: 'el-icon-s-comment',
         insertIndex: 3, //插入的位置顺序, 1是home按钮后面
         click: () => {
           this.addDiv()
         },
       })
      this.map.addControl(popupButton)
    },
    //当前页面业务相关
    showModel() {
      this.layer.on(this.mars3d.EventType.load, () => {
        // 获取图层
        this.layersList = this.map.getLayers().filter((layer) => {return layer.name !== '模型'})
      })
      this.layer.on(this.mars3d.EventType.click, (event) => {
        console.log('单击了图层', event)
      })
      // 在layer上绑定监听事件
      this.graphicLayer3D.on(this.mars3d.EventType.click, (event) => {
        console.log('graphicLayer3D', event.graphic.id)
        this.DialogVisible3D = true
      })
      // 在layer上绑定监听事件
      this.graphicLayerCamera.on(this.mars3d.EventType.click, (event) => {
        console.log('监听layer,单击了矢量对象', event)
      })
      // 可在图层绑定右键菜单,对所有加到这个图层的矢量数据都生效
      this.graphicLayerCamera.bindContextMenu([
        {
          text: '删除对象',
          iconCls: 'fa fa-trash-o',
          callback: (e) => {
            const graphic = e.graphic
            if (graphic) {
              this.graphicLayerCamera.removeGraphic(graphic)
            }
          }
        }
      ])
    },
    //更新图层:显示隐藏状态
    updateLayerShow(layer) {
      layer.show = !layer.show
    },
    // 点击图标添加标签
    addDiv () {
      this.graphicLayerPopup.startDraw({
        type: 'divBillboard',
        style: {
          html: `<div style="background-color:red; width: 100px; height: 100px">
                        <div class="title">测试DIV点</div>
                        <div class="content">此处可以绑定任意Html代码和css效果</div>
                    </div >`,
          horizontalOrigin: this.Cesium.HorizontalOrigin.LEFT,
          verticalOrigin: this.Cesium.VerticalOrigin.BOTTOM,
        },
      })
    },
    // 添加图标
    addGraphicCamera() {
      let positions = [{name: '摄像头1', position: [114.803043, 34.846551, 30]},
        {name: '摄像头2', position: [114.803282, 34.846208, 30]},
        {name: '摄像头3', position: [114.802505, 34.846165, 30]}]
      positions.forEach((position) => {
        let graphic = new this.mars3d.graphic.BillboardEntity({
          name: position.name,
          position: position.position,
          style: {
            image: 'img/marker/camera.png',
            scale: 1,
          },
          popup: '<video autoplay controlspreload="none" controls width="440" height="320" src="mp4/11.mp4"></video>'
        })
        this.graphicLayerCamera.addGraphic(graphic)
      })
      this.graphicLayerCamera.show = false
    },
    addGraphic3DRoom() {
      let positions = [{id: 1, name: '库室1', position: [114.803443, 34.846651, 30]},
        {id: 2, name: '库室2', position: [114.803282, 34.846308, 30]},
        {id: 3, name: '库室3', position: [114.802805, 34.846665, 30]}]
      positions.forEach((position) => {
        let graphic = new this.mars3d.graphic.BillboardEntity({
          id: position.id,
          name: position.name,
          position: position.position,
          style: {
            image: 'img/marker/moxing.png',
            scale: 1,
            width: 50,
            height: 50,
          }
        })
        this.graphicLayer3D.addGraphic(graphic)
      })
      this.graphicLayer3D.show = false
    },
    DialogVisible3DClose() {
      this.DialogVisible3D = false
    }
  }
}
</script>

<style lang="scss" scoped>
  .mapcontainer {
    overflow: hidden;
    height: 100vh;
    .bottomLayer {
      position: relative;
      bottom: 150px;
      text-align: center;
      button {
        font-size: 24px;
        width: 90px;
        background: rgba(63, 72, 84, 0.88);
        /*border-color: #00ffff;*/
        border: 0;
      }
      .activeBtn {
        color: #00ffff;
      }
    }
    /deep/.el-dialog__wrapper {
      .el-dialog {
        background: rgba(36, 45, 52, 0.9);
        border: 1px solid #66b1ff;
        .el-dialog__title {
          color: #eee;
        }
        .el-dialog__body {
          text-align: center;
        }
      }
    }
  }
</style>

4.config.js文件
在这里插入图片描述

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值