vue+cusium实现单体化

代码页

<template> 
    <div>
    <div id="cesiumDemo"></div>
      <transition name="el-fade-in-linear">
        <div class="buildMessageBox messageBox" v-show="buildMessageBoxShow">
          <div class="topLine"></div>
          <div class="slantLine"></div>
          <div class="title">
            <span class="messageBoxTit">{
    
    {
    
    name}}</span>
          </div>
          <div class="contList">
            <span class="messageBoxTit">电耗:</span><span class="messageVal">25410kw-h</span>
          </div>
          <div class="contList">
            <span class="messageBoxTit">水耗:</span><span class="messageVal">1149</span>
          </div>
          <div class="contList">
            <span class="messageBoxTit">已入住人口:</span><span class="messageVal">56</span>
          </div>
        </div>
      </transition>
   </div>
</template>
<script>
  import {
    
    
    set3Dtitle2,
    lablelist,
    cylinderModel
  } from '../../assets/js/cusium.js'//公用部分封装代码
  let viewer
  let tilesFloodTest
  let options
  export default {
    
    
    data() {
    
    
      return {
    
    
        name: "",
        buildMessageBoxShow: false,
        mapMouseDown: false,
        // // 分层单体化反选数据
        layered: {
    
    
          first: {
    
    
            // -2793123.2216803157
            // y: 4684923.801403305
            // z: 3295058.384405283
            center: {
    
    
              x: "-2793123.2216803157",
              y: "4684923.801403305",
              z: "3295058.384405283"
            },
            priipt1: 0,
            priipt2: 0,
            priipt3: 0,
            priipt4: -12,
            priipt5: -20,
            priipt6: 0,
            priipt7: 70,
            priipt8: 52,
            priipt9: 65,
          },
          second: {
    
    
            // x: -2793214.4280046094
            // y: 4684885.426110703
            // z: 3295035.7843646174
            center: {
    
    
              x: '-2793214.4280046094',
              y: '4684885.426110703',
              z: '3295035.7843646174',
            },
            priipt1: 0,
            priipt2: 0,
            priipt3: 0,
            priipt4: -25,
            priipt5: -8,
            priipt6: 0,
            priipt7: 65,
            priipt8: 35,
            priipt9: 65,
          }
        },
        lablelists: [{
    
    
            x: "120.80302807741732",
            y: '31.30709242677048',
            z: 40,
            Text: '1'
          },
          {
    
    
            x: '120.80408198509431',
            y: '31.30709242677048',
            Text: '2',
            z: 40
          },
        ],
        building: {
    
    
          first: {
    
    
            cylinder1: 18.7,
            id: 'first',
            x: "120.80302807741732",
            y: '31.30709242677048'
          },
          second: {
    
    
            cylinder1: 23,
            id: 'second',
            x: '120.80408198509431',
            y: '31.30709242677048'
          },
        }
      }
    },
    mounted() {
    
    
        this.getCesiumDem()    
    },
    methods: {
    
    
      // 楼栋单体化
      layeredTilesModel(data) {
    
    
        let scene = viewer.scene
        if (tilesFloodTest) {
    
    
          tilesFloodTest.destroy()
        }
        var center = new Cesium.Cartesian3(
          this.layered[data].center.x, this.layered[data].center.y, this.layered[data].center.z,
        )
        var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center)
        var hprRotation = Cesium.Matrix3.fromHeadingPitchRoll(
          // 第一个参数是y轴偏移角度,第二个参数是x轴偏移角度,第三个参数是z轴偏移角度
          new Cesium.HeadingPitchRoll(Number(this.layered[data].priipt1), Number(this.layered[data].priipt2), Number(
            this.layered[data].priipt3))
        )
        var hpr = Cesium.Matrix4.fromRotationTranslation(
          hprRotation,
          // 第一个参数是遮罩整体的横向定位,第二个参数是竖向定位,第三个参数是高度定位
          new Cesium.Cartesian3(Number(this.layered[data].priipt4), Number(this.layered[data].priipt5), Number(this
            .layered[data].priipt6))
        )
        Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix)
        tilesFloodTest = scene.primitives.add(
          new Cesium.ClassificationPrimitive({
    
    
            geometryInstances: new Cesium.GeometryInstance({
    
    
              geometry: Cesium.BoxGeometry.fromDimensions({
    
    
                vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
                // 第一个参数是遮罩的整体横向长度,第二个参数是竖向长度,第三个参数是整体高度
                dimensions: new Cesium.Cartesian3(Number(this.layered[data].priipt7), Number(this.layered[
                  data].priipt8), Number(this.layered[data].priipt9))
              }),
              modelMatrix: modelMatrix,
              attributes: {
    
    
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                  Cesium.Color.fromCssColorString('#D22809').withAlpha(0.5)
                ),
                show: new Cesium.ShowGeometryInstanceAttribute(true)
              },
              // id: 'volume 1'
            }),
            classificationType: Cesium.ClassificationType.CESIUM_3D_TILE
          })
        )
      },
      // 实例cesium
      getCesiumDem() {
    
    
        let self = this
        Cesium.Ion.defaultAccessToken ='你的token'
        viewer = new Cesium.Viewer('cesiumDemo', {
    
    
          animation: false, // 是否显示动画控件
          baseLayerPicker: false, // 是否显示图层选择控件
          geocoder: false, // 是否显示地名查找控件
          timeline: false, // 是否显示时间线控件
          sceneModePicker: true, // 是否显示投影方式控件
          navigationHelpButton: false, // 是否显示帮助信息控件
          infoBox: true, // 是否显示点击要素之后显示的信息
          fullscreenButton: false, // 是否显示全屏按钮
          selectionIndicator: false, // 是否显示选中指示框
          scene3DOnly: true,
          homeButton: false,
          terrainProvider: new Cesium.EllipsoidTerrainProvider({
    
    }),
        })
        set3Dtitle2(viewer)//摄影模型

        for (var i = 0; i < self.lablelists.length; i++) {
    
    
          let a = i
          let data = self.lablelists
          lablelist(viewer, data, a)//文字内容
        }
        let building = self.building
        cylinderModel(viewer, building, 'first')//模型柱体
        cylinderModel(viewer, building, 'second')
        // 地图事件开始
        // 得到当前三维场景
        let scene = viewer.scene
        var terrainProvider = Cesium.createWorldTerrain({
    
    
          requestVertexNormals: true
        });
        viewer.terrainProvider = terrainProvider;
        viewer.scene.globe.enableLighting = true;
        // 得到当前三维场景的椭球体
        let ellipsoid = scene.globe.ellipsoid
        let entity = viewer.entities.add({
    
    
          label: {
    
    
            show: false
          }
        })
        let longitudeString = null
        let latitudeString = null
        let height = null
        // 定义当前场景的画布元素的事件处理
        let handler = new Cesium.ScreenSpaceEventHandler(scene.canvas)
        // 设置鼠标移动事件的处理函数,这里负责监听x,y坐标值变化
        handler.setInputAction(function(event) {
    
    
          if (self.mapMouseDown === true) {
    
    
            self.buildMessageBoxShow = false
            if (tilesFloodTest) {
    
    
              tilesFloodTest.destroy()
            }
          }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
        // 鼠标按下
        handler.setInputAction(function(movement) {
    
    
          self.mapMouseDown = true
        }, Cesium.ScreenSpaceEventType.LEFT_DOWN)
        // 鼠标弹起
        handler.setInputAction(function(movement) {
    
    
          self.mapMouseDown = false
        }, Cesium.ScreenSpaceEventType.LEFT_UP)
        //  设置鼠标点击事件
        handler.setInputAction(function(event) {
    
    
          let cartesian = viewer.camera.pickEllipsoid(event.position, ellipsoid)
          if (cartesian) {
    
    
            console.log(cartesian, 111)
            // 将笛卡尔坐标转换为地理坐标
            let cartographic = ellipsoid.cartesianToCartographic(cartesian)
            // 将弧度转为度的十进制度表示
            longitudeString = Cesium.Math.toDegrees(cartographic.longitude)
            latitudeString = Cesium.Math.toDegrees(cartographic.latitude)
            // 获取相机高度
            height = Math.ceil(viewer.camera.positionCartographic.height)
            entity.position = cartesian
            console.log(longitudeString)
            console.log(latitudeString)
            let pick = viewer.scene.pick(event.position)
            if (Cesium.defined(pick) && pick) {
    
    
              if (pick.id && pick.id.name) {
    
    
                let modelDataObj = JSON.parse(pick.id.name)
                // 检测点击楼栋实体
                if (modelDataObj.cesiumType === 'cylinderBuilding') {
    
    
                  self.buildMessageBoxShow = true
                  let winpos = viewer.scene.cartesianToCanvasCoordinates(
                    pick.id.position._value
                  )
                  let name = pick.id.id
                  self.name = name
                  // 计算弹框的位置
                  self.layeredTilesModel(pick.id.id)//单体化渲染
                  setTimeout(() => {
    
    
                    let mainMessageBoxDom = document.querySelector('.buildMessageBox')
                    let winposWihth = mainMessageBoxDom.offsetWidth
                    let winposHeight = mainMessageBoxDom.offsetHeight
                    mainMessageBoxDom.style.left = (Math.floor(winpos.x) - (winposWihth / 2) + 230) + 'px'
                    mainMessageBoxDom.style.top = (Math.floor(winpos.y) - winposHeight - 70) + 'px'

                  }, 10)
                  // 检测点击到分层实体
                }
              } else {
    
    
                self.buildMessageBoxShow = false
                if (tilesFloodTest) {
    
    
                  tilesFloodTest.destroy()
                }
              }
            } else {
    
    
              self.buildMessageBoxShow = false
              if (tilesFloodTest) {
    
    
                tilesFloodTest.destroy()
              }
            }
          } else {
    
    
            entity.label.show = false
          }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
        // 地图事件结束

      }
    }
  }
</script>

<style>
//效果自己设置
</style>

公用代码部分

// 保利倾斜摄影
export function set3Dtitle2(viewer) {
    
    
  let translation = Cesium.Cartesian3.fromArray([0, 0, -170])
  let m = Cesium.Matrix4.fromTranslation(translation)
  let palaceTileset = new Cesium.Cesium3DTileset({
    
    
    url: './static/demo/tileset.json',//模型位置
    modelMatrix: m,
    maximumScreenSpaceError: 64 // 默认16
  })
  //添加到场景
  viewer.scene.primitives.add(palaceTileset);
  //控制模型的位置
  palaceTileset.readyPromise.then(function(palaceTileset) {
    
    
    viewer.scene.primitives.add(palaceTileset);
    var heightOffset = 0; //可以改变3Dtiles的高度
    var boundingSphere = palaceTileset.boundingSphere;
    var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
    var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
    var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset);
    var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
    palaceTileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
    viewer.zoomTo(palaceTileset, new Cesium.HeadingPitchRange(0.5, -0.2, palaceTileset.boundingSphere.radius *
      1.0));
  });
  //定位到三维模型
  viewer.zoomTo(palaceTileset)
}
//单点值
export function lablelist(viewer, data, a) {
    
    
  //添加点位
  // fromDegrees(经度,纬度,高度,椭球,结果)从以度为单位的经度和纬度值返回Cartesian3位置
  viewer.entities.add({
    
    
    position: Cesium.Cartesian3.fromDegrees(data[a].x, data[a].y, data[
      a].z),
    // 文字
    label: {
    
    
      // 文本。支持显式换行符“ \ n”
      text: data[a].Text,
      // 字体样式,以CSS语法指定字体
      font: '14pt Source Han Sans CN',
      // 字体颜色
      fillColor: Cesium.Color.WHITE,
      // 背景颜色
      backgroundColor: Cesium.Color.BLUE,
      // 是否显示背景颜色
      showBackground: true,
      // 字体边框
      outline: true,
      // 字体边框颜色
      outlineColor: Cesium.Color.WHITE,
      // 字体边框尺寸
      outlineWidth: 2,
      // 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
      scale: 1.0,
      // 设置样式:FILL:填写标签的文本,但不要勾勒轮廓;OUTLINE:概述标签的文本,但不要填写;FILL_AND_OUTLINE:填写并概述标签文本。
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      // 相对于坐标的水平位置
      verticalOrigin: Cesium.VerticalOrigin.CENTER,
      // 相对于坐标的水平位置
      horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
      // 该属性指定标签在屏幕空间中距此标签原点的像素偏移量
      pixelOffset: new Cesium.Cartesian2(10, 0),
      // 显示在距相机的距离处的属性,多少区间内是可以显示的
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1000),
      // 是否显示
      show: true
    }
  });
}
// 楼栋柱体实体
export function cylinderModel(viewer, building, data) {
    
    
  viewer.entities.add({
    
    
    id: building[data].id,
    name: '{
    
    "cesiumType": "cylinderBuilding"}',
    position: Cesium.Cartesian3.fromDegrees(building[data].x, building[data].y, 10),
    orientation: Cesium.Transforms.headingPitchRollQuaternion(
      new Cesium.Cartesian3.fromDegrees(building[data].x, building[data].y, 10),
      new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(140), Cesium.Math.toRadians(0), Cesium.Math
        .toRadians(0))
    ),
    cylinder: {
    
    
      length: 50, // 圆柱体高度
      topRadius: 35, // 圆柱体顶部半径
      bottomRadius: 35, // 圆柱体底部半径
      material: Cesium.Color.fromCssColorString('rgba(255,255,255,0.01 )'), // 材质
      // material: Cesium.Color.fromCssColorString('rgba(255, 255, 255, 1)'), // 材质
      slices: 100, // 圆柱周围圆圈分段数
      numberOfVerticalLines: 100 // 圆柱垂直线分段数
    }
  }, )

}

效果展示

在这里插入图片描述

模型部分只用于学习,想要的同学们留言

猜你喜欢

转载自blog.csdn.net/m0_69327201/article/details/128959022