jihongshun
2 天以前 cee560775962d3141360e5297126abbcca8e58fb
src/utils/components/init-map.vue
@@ -8,11 +8,63 @@
    <div class="cesiumBotton">
      <div class="cesiumButtonGroup">
        <el-button id="groundPoi" @click="addGroundPoi()" type="primary">地面点</el-button>
        <el-button id="groundPoi" @click="addGroundPoi()" type="primary">空中点</el-button>
        <el-button id="groundPoi" @click="addGroundPoi()" type="primary">停留时间</el-button>
        <!-- <el-button id="groundPoi" @click="addGroundPoi()" type="primary">停留时间</el-button> -->
        <el-input v-model="mergeNumber" placeholder="请输入合并范围" type="number" style="width: 150px;"></el-input>
        <el-button  @click="mergePoint()" type="success">合并</el-button>
        <el-button  @click="renderData()" type="success">数据渲染</el-button>
        <!-- <el-button  @click="VisualCone()" type="success">生成视锥体</el-button> -->
      </div>
      <div class="key-container">
        <div class="arrow-row">
          <div
              class="arrow"
              :class="{ active: activeKey === 'w' }"
            >W</div>
          </div>
          <div class="key-row">
            <div
              class="key"
              :class="{ active: activeKey === 'a' }"
              @mousedown="handleClick('a')"
            >A</div>
            <div
              class="key"
              :class="{ active: activeKey === 's' }"
              @mousedown="handleClick('s')"
            >S</div>
            <div
              class="key"
              :class="{ active: activeKey === 'd' }"
              @mousedown="handleClick('d')"
            >D</div>
          </div>
      </div>
      <div class="key-container">
        <div class="arrow-row">
          <div
              class="arrow"
              :class="{ active: activeKey === 'ArrowUp' }"
              @mousedown="handleClick('ArrowUp')"
            >↑</div>
          </div>
          <div class="key-row">
            <div
              class="key"
              :class="{ active: activeKey === 'ArrowLeft' }"
              @mousedown="handleClick('ArrowLeft')"
            >←</div>
            <div
              class="key"
              :class="{ active: activeKey === 'ArrowDown' }"
              @mousedown="handleClick('ArrowDown')"
            >↓</div>
            <div
              class="key"
              :class="{ active: activeKey === 'ArrowRight' }"
              @mousedown="handleClick('ArrowRight')"
            >→</div>
          </div>
      </div>
    </div>
@@ -36,12 +88,23 @@
let  viewerM;
let  viewerC;
let  counter = 0;
let  pois = [125.1541, 46.5542,0]
let  globalon  = 0
let  globalat = 0
let  pois = [globalon, globalat,0]
// let  pois = [0, 0,0]
let holdingPosition;
let rightKeyMove = false
// let  pois = [125.1541, 46.5542,0]
let  distance = 100; 
export default {
  props: {
    towerUrl: {
      type: String,
      default() {
        return ''
      }
    },
  },
  data(){
    return{
        moveSpeed: 1,
@@ -63,22 +126,30 @@
          space: false,
        },
        animationFrameId: null,
        mergeNumber:null
        mergeNumber:null,
        activeKey: null,
        timer: null,
        handler: null,
      frustumPrimitive: null,
      selected: false,
    }
  },
  mounted(){
    console.log('111111111111111111')
     this.initCesium();
  },
  beforeDestroy() {
    counter = 0
    this.removeKeyboardEvents();
    if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId);
    window.removeEventListener("keydown", this.handleKeydown);
    if (viewerC) viewerC.destroy();
  },
  methods:{
    initCesium() {
      viewerM = this.initViewer(this.$refs.cesiumContainer.id);
      viewerC = this.initViewer(this.$refs.cesiumCamera.id);
      window.viewerM = viewerM;
      window.viewerC = viewerC;
      // 💡 在这里继续调用 measure.js / camera.js / botton.js 等逻辑
      // 例如:window.registerMeasureTools(viewerM)
      setTimeout(()=>{
@@ -108,8 +179,6 @@
    initViewer(cesiumId){
      //cesium全球30米分辨率地形资源token
      let imageryProvider1 = new Cesium.TileMapServiceImageryProvider({
        // url: process.env.VUE_APP_BASE_GIS + "/daqing/dom-sea",
        // url: process.env.VUE_APP_BASE_GIS + "/daqing/dom-sea",
        url: `https://192.168.1.2:9999/daqing/dom-sea/`,
      });
      let viewer = new Cesium.Viewer(cesiumId, {
@@ -124,6 +193,7 @@
          navigationHelpButton: false,
          navigationInstructionsInitiallyVisible: false,
          imageryProvider: imageryProvider1,
          // imageryProvider: false,
          shadows: false,
          animation: false,
          infoBox: false,
@@ -132,14 +202,19 @@
          fullscreenButton: false,
          vrButton: false,
      });
      window.viewer = viewer;
       // 关闭天空盒效果
      // viewer.scene.skyAtmosphere = undefined; // 或者设置为 null
      // // 关闭光照效果
      // viewer.scene.globe.enableLighting = false; // 关闭光照效果
    //    viewer.imageryLayers.add(bdtvectoranoimagery);
      viewer._cesiumWidget._creditContainer.style.display="none";  
      return viewer;
      
    },
    loadModel(){
      const modelUrl = 'http://192.168.1.2:9001/model/tower.glb';  // GLB模型路径
      const modelUrl = this.towerUrl;  // GLB模型路径
       // 沿原点坐标和地面点坐标方向上选取空中点的距离
      //初始化相机窗口视角参数
      cameraPostion = viewerM.camera.position
@@ -149,17 +224,18 @@
      // 设置视角,使其默认查看某个地理位置
      viewerM.scene.camera.setView({
          destination: Cesium.Cartesian3.fromDegrees(125.1511, 46.5542, 349.0), // 以经纬度设置位置(例如:大庆龙兴路)
          destination: Cesium.Cartesian3.fromDegrees(globalon, globalat, 349.0), // 以经纬度设置位置(例如:大庆龙兴路)
          // destination: Cesium.Cartesian3.fromDegrees(0.0005, 0.0017, 207.8), // 以经纬度设置位置(例如:大庆龙兴路)
          orientation: {
              heading: Cesium.Math.toRadians(86.94),  // 方向
              pitch: Cesium.Math.toRadians(-30.22), // 俯角
              heading: Cesium.Math.toRadians(194.65),  // 方向
              pitch: Cesium.Math.toRadians(-31.43), // 俯角
              roll: 0
          }
      });
      //创建模型
      const glbModelPoi = Cesium.Cartesian3.fromDegrees(pois[0], pois[1],pois[2]);
      const heading = Cesium.Math.toRadians(10);
      const heading = Cesium.Math.toRadians(0);
      const pitch = Cesium.Math.toRadians(0);
      const roll = Cesium.Math.toRadians(0);
      const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
@@ -174,7 +250,6 @@
            orientation: orientations,
            model: {
                uri: url,
                scale: 20,
                shadows: Cesium.ShadowMode.DISABLED,
                imageBasedLightingFactor: new Cesium.Cartesian2(1, 0.5)
            }
@@ -184,6 +259,7 @@
      // 存下回调以便销毁
      // this._preRenderCallback = () => this.syncViewer();
      viewerM.scene.preRender.addEventListener( this.syncViewer());
      window.addEventListener("keydown", this.handleKeydown);
    },
    syncViewer(){
      console.log(viewerM.camera)
@@ -214,9 +290,6 @@
      }
    },
    addGroundPoi() {
      console.log('1111111111111111')
      console.log(new Cesium.ScreenSpaceEventHandler(viewerM.canvas))
      console.log(this)
        let createPinHandler = new Cesium.ScreenSpaceEventHandler(viewerM.canvas);
        let _this = this
        createPinHandler.setInputAction(function (click) {
@@ -232,7 +305,6 @@
                let lng = Cesium.Math.toDegrees(cartographic.longitude);
                let lat = Cesium.Math.toDegrees(cartographic.latitude);
                height = cartographic.height;
                // camPosition = lng+','+lat+','+height;
                console.log(lng+','+lat+','+height)
            }
@@ -263,45 +335,12 @@
                const scalerNormalize = Cesium.Cartesian3.multiplyByScalar(normalize,distance,new Cesium.Cartesian3());
                const tagert = Cesium.Cartesian3.add(holdingPosition,scalerNormalize,new Cesium.Cartesian3());
                console.log(Cesium.Cartographic.fromCartesian(tagert))
                var airCartographic= Cesium.Cartographic.fromCartesian(tagert)
                var airPointLongitude= Cesium.Math.toDegrees(airCartographic.longitude);
                var airPointLatitude = Cesium.Math.toDegrees(airCartographic.latitude);
                var airPointHeight = airCartographic.height;
                _this.creatPin("aerialPoiId"+counter,tagert,`空${counter}`,Cesium.Color.RED,viewerM);
                _this.updateCameraMovement();
                // console.log(direction)
                // console.log(normalize )
                // console.log(longitude)
                // console.log(latitude)
                // console.log(pois)
                // console.log(azimuthtwopoi(longitude,latitude,pois[0],pois[1]))
                // let data = {
                //   id:(Date.now().toString(16) + Math.random().toString(16).slice(2, 10)).slice(0, 16),
                //   label:`地面点${counter}`,
                //   longitude:longitude,
                //   latitude:latitude,
                //   height:height,
                //   children:[
                //     {
                //       id:(Date.now().toString(16) + Math.random().toString(16).slice(2, 10)).slice(0, 16),
                //       label:`空中点${counter}`,
                //       longitude:airPointLongitude,
                //       latitude:airPointLatitude,
                //       height:airPointHeight,
                //     }
                //   ]
                // }
                // _this.$emit('rightClickEnd',data)
                //结束右键监听
                createPinHandler.destroy();
                //结束主图联动鹰眼监听
                viewerM.scene.preRender.removeEventListener(_this.syncViewer());
                // viewerM.scene.preRender.removeEventListener(this._preRenderCallback);
                // if (this._preRenderCallback) {
                //   this.viewerM.scene.preRender.removeEventListener(this._preRenderCallback);
                //   this._preRenderCallback = null;
                // }
                //更新相机视角为空中点
                _this.changeCamera(tagert,_this.azimuthtwopoi(longitude,latitude,pois[0],pois[1]));
                rightKeyMove = true
                counter += 1;
@@ -341,7 +380,6 @@
        });
    },
    registerKeyboardEvents() {
      console.log('11111111111111111111111')
      window.addEventListener("keydown", this.onKeyDown);
      window.addEventListener("keyup", this.onKeyUp);
    },
@@ -401,9 +439,6 @@
        case "1":
          viewerC.scene.mode = Cesium.SceneMode.SCENE3D;
          break;
        // case "2":
        //   viewerC.scene.mode = Cesium.SceneMode.SCENE2D;
        //   break;
        case "3":
          viewerC.scene.mode = Cesium.SceneMode.COLUMBUS_VIEW;
          break;
@@ -411,22 +446,16 @@
    },
    onKeyUp(event) {
      //键盘抬起进行更新左侧空中点pin
      console.log(viewerM)
      console.log(counter)
      //获取右侧相机
      if(rightKeyMove){
        const camera = viewerC.camera;
        console.log(camera)
        const carto = Cesium.Cartographic.fromCartesian(camera.position);
        console.log(carto)
        //右侧相机视角转化为经纬度
        const lon = Cesium.Math.toDegrees(carto.longitude);
        const lat = Cesium.Math.toDegrees(carto.latitude);
        const height = carto.height;
        const position = Cesium.Cartesian3.fromDegrees(lon, lat, height)
        console.log(position)
        let pinBuilder = new Cesium.PinBuilder();
        // const dest = this.calculateDestinationPoint(lon, lat, camera.heading, speed);
        const groupEntity = viewerM.entities.getById("aerialPoiId"+(counter-1));
        //左侧地图同步更新pin空中点位置
        if (groupEntity == undefined) {
@@ -501,6 +530,7 @@
      }
    },
    updateCameraMovement() {
      console.log('111111111111111111111111111111111111111111')
      const camera = viewerC.camera;
      // Adjust speed by modifiers
      let currentSpeed = this.moveSpeed;
@@ -521,17 +551,8 @@
      let rotSpeed = 1;
      if (this.keyState.shift) rotSpeed *= this.speedMultiplier;
      if (this.keyState.ctrl) rotSpeed *= this.slowMultiplier;
      const multiplyByScalarrotateAmount = Cesium.Math.toRadians(0.5 * rotSpeed);
      // if (this.keyState.up) camera.lookUp(rotateAmount);
      // if (this.keyState.down) camera.lookDown(rotateAmount);
      // if (this.keyState.left) camera.lookLeft(rotateAmount);
      // if (this.keyState.right) camera.lookRight(rotateAmount);
      if (holdingPosition) {
          // const groupPosition  = groupEntity.position.getValue(Cesium.JulianDate.now());
          // console.log(groupPosition)
          const distance = Cesium.Cartesian3.distance(holdingPosition, camera.position);
          const surroundSpeed = 0.005; //环绕速度,角度
          let cameraHeading = camera.heading;
          let cameraPitch = camera.pitch;
@@ -548,9 +569,8 @@
          if (this.keyState.right) camera.lookRight(rotateAmount);
      }
      this.resetRoll();
      // Schedule next frame
      this.animationFrameId = requestAnimationFrame(this.updateCameraMovement);
      // this.animationFrameId = requestAnimationFrame(this.updateCameraMovement);
    }, 
    calculateDestinationPoint(lon1, lat1, bearing, distance, radius = 6371000) {
      const toRad = (d) => d * Math.PI / 180;
@@ -573,9 +593,7 @@
      return { lon: toDeg(lon2Norm), lat: toDeg(lat2Rad) };
    },
    uavMoveForward(speed) {
      console.log('11111' +speed)
      const camera = viewerC.camera;
      const carto = Cesium.Cartographic.fromCartesian(camera.position);
      const lon = Cesium.Math.toDegrees(carto.longitude);
@@ -626,15 +644,11 @@
    cammove_measure_point(){
      CesiumSurvey.cammeasureMovePoint(viewerM,'cammoveResultCon');
    },
    renderData(){
        this.$emit('renderData',viewerM)
    },
    mergePoint(){
      let allEntities = viewerM.entities.values; // 所有实体对象组成的数组
      console.log(allEntities)
      allEntities.forEach(entity => {
        console.log('ID:', entity.id);
        console.log('Position:', entity.position ? entity.position.getValue(Cesium.JulianDate.now()) : null);
        console.log('Name:', entity.name);
        console.log('Properties:', entity.properties); // 自定义属性
      });
      const grouped = {};
      //所有实体对象组成的数组转换成左侧树需要的格式
      allEntities.forEach(item => {
@@ -669,7 +683,6 @@
          ]
        };
      });
      console.log(result)
      this.$emit('mergePoint',result,this.mergeNumber,viewerM)
    },
    genId() {
@@ -683,7 +696,114 @@
        latitude: Cesium.Math.toDegrees(cartographic.latitude),
        height: cartographic.height
      };
    }
    },
    handleClick(key) {
      this.triggerKey(key);
    },
    triggerKey(key) {
      this.activeKey = key;
      clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        this.activeKey = null;
      }, 200);
      // 自定义动作触发
      console.log("Key triggered:", key);
      // 这里可以发出事件或调用其它方法
    },
    handleKeydown(e) {
      const key = e.key;
      console.log(key)
      const validKeys = ["a", "s", "d", "w",'q','e','ArrowUp','ArrowDown','ArrowLeft','ArrowRight','q','e'];
      if (validKeys.includes(key)) {
        this.triggerKey(key);
      }
      this.updateCameraMovement()
    },
    VisualCone(){
      this.addFrustum();
      this.initDragHandler();
    },
    addFrustum() {
      // 创建一个 PerspectiveFrustum
      const frustum = new Cesium.PerspectiveFrustum({
        fov: Cesium.Math.PI_OVER_THREE,
        aspectRatio: 1.0,
        near: 1.0,
        far: 500.0,
      });
      // 设置矩阵位置
      const position = Cesium.Cartesian3.fromDegrees(110.0, 30.0, 100.0);
      const direction = Cesium.Cartesian3.normalize(
        new Cesium.Cartesian3(1.0, 0.0, -1.0),
        new Cesium.Cartesian3()
      );
      const up = Cesium.Cartesian3.UNIT_Z;
      const right = Cesium.Cartesian3.cross(direction, up, new Cesium.Cartesian3());
      const rotation = Cesium.Matrix3.setColumns(
        new Cesium.Matrix3(),
        right,
        up,
        Cesium.Cartesian3.negate(direction, new Cesium.Cartesian3())
      );
      const modelMatrix = Cesium.Matrix4.fromRotationTranslation(rotation, position);
      this.frustumPrimitive = this.viewer.scene.primitives.add(
        new Cesium.DebugCameraPrimitive({
          frustum,
          modelMatrix,
          color: Cesium.Color.LIME.withAlpha(0.5),
        })
      );
    },
    initDragHandler() {
      const scene = viewerM.scene;
      const canvas = scene.canvas;
      this.handler = new Cesium.ScreenSpaceEventHandler(canvas);
      let isDragging = false;
      let lastPosition = null;
      this.handler.setInputAction((movement) => {
        const pickedObject = scene.pick(movement.position);
        if (pickedObject && pickedObject.primitive === this.frustumPrimitive) {
          this.selected = true;
          isDragging = true;
          lastPosition = movement.position;
        } else {
          this.selected = false;
        }
      }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
      this.handler.setInputAction((movement) => {
        if (isDragging && this.selected) {
          const start = scene.pickPosition(lastPosition);
          const end = scene.pickPosition(movement.endPosition);
          if (start && end) {
            const delta = Cesium.Cartesian3.subtract(
              end,
              start,
              new Cesium.Cartesian3()
            );
            const newMatrix = Cesium.Matrix4.multiplyByTranslation(
              this.frustumPrimitive.modelMatrix,
              delta,
              new Cesium.Matrix4()
            );
            this.frustumPrimitive.modelMatrix = newMatrix;
            lastPosition = movement.endPosition;
          }
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
      this.handler.setInputAction(() => {
        isDragging = false;
        lastPosition = null;
      }, Cesium.ScreenSpaceEventType.LEFT_UP);
    },
  }
}
</script>
@@ -738,3 +858,46 @@
.box_rb{width:10px;height:10px;position:absolute;border-bottom:2px solid #00d3e7;border-right:2px solid #00d3e7;right:0px;bottom:0px;}
.box_lb{width:10px;height:10px;position:absolute;border-bottom:2px solid #00d3e7;border-left:2px solid #00d3e7;left:0px;bottom:0px;}
</style>
<style scoped>
.key-container {
  display: inline-block;
  background-color: rgba(0, 0, 0, 0.7);
  padding: 8px 10px;
  border-radius: 10px;
  color: white;
  font-family: sans-serif;
  margin-top: 55px;
}
.arrow-row{
  display: flex;
  justify-content: center;
  margin-bottom: 4px;
}
.key-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
}
.arrow,
.key {
  width: 30px;
  height: 30px;
  margin: 0 2px;
  background-color: #333;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: bold;
  transition: background-color 0.2s;
  cursor: pointer;
}
.arrow.active,
.key.active {
  background-color: #00aaff;
}
</style>