jihongshun
2025-08-13 2d829de89f7e4f8d55dd5784bf9dbd91a70751ef
点击树飞到不同的视角
已修改2个文件
190 ■■■■ 文件已修改
src/utils/components/init-map.vue 113 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/shootPoint/components/shootPointDialog.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/components/init-map.vue
@@ -30,8 +30,9 @@
      
    </div>
    <div class="zoom-info">
      <el-tag type="success">倍率: {{ zoomRatio.toFixed(1) }}X</el-tag>
      <el-tag type="success">距离: {{ betweenDistance.toFixed(1) }}米</el-tag>
        <el-tag type="success">倍率: {{ zoomRatio.toFixed(1) }}X</el-tag><br>
        <el-tag type="success">距离: {{ betweenDistance.toFixed(1) }}米</el-tag><br>
        <el-tag type="success">P: {{ cameraP.toFixed(1) }}&nbsp;&nbsp;T: {{ cameraT.toFixed(1) }} </el-tag>
    </div>
    
    
@@ -174,7 +175,9 @@
          28: '28X',
          56: '56X'
        },
        betweenDistance:0
        betweenDistance:0,
        cameraP:0.0,
        cameraT:0.0
    }
  },
  mounted(){
@@ -410,8 +413,8 @@
                setTimeout(() => {
                  viewerC.camera.changed.addEventListener(_this.onCameraChange)
                }, 100);
                //左侧树结构联动
                _this.dealTree()
                //结束右键监听
                createPinHandler.destroy();
                //结束主图联动鹰眼监听
@@ -518,6 +521,7 @@
      }
    },
    onKeyUp(event) {
      console.log()
      //键盘抬起进行更新左侧空中点pin
      //获取右侧相机
      if(rightKeyMove){
@@ -545,17 +549,19 @@
        }
        //计算两个点距离
        console.log(viewerM.entities)
           const groupEntityGround = viewerM.entities.getById("groundPoiId"+(counter-1));
           const groupPosition  = groupEntityGround.position.getValue(Cesium.JulianDate.now());
           if (groupPosition) {
              const cartographic = Cesium.Cartographic.fromCartesian(groupPosition);
              const longitude = Cesium.Math.toDegrees(cartographic.longitude);
              const latitude = Cesium.Math.toDegrees(cartographic.latitude);
              const point1 = Cesium.Cartesian3.fromDegrees(lon, lat);
              const point2 = Cesium.Cartesian3.fromDegrees(longitude, latitude);
              const gure = Cesium.Cartesian3.distance(point1, point2)
              this.betweenDistance  = gure
          }
        const groupEntityGround = viewerM.entities.getById("groundPoiId"+(counter-1));
        const groupPosition  = groupEntityGround.position.getValue(Cesium.JulianDate.now());
        if (groupPosition) {
            const cartographic = Cesium.Cartographic.fromCartesian(groupPosition);
            const longitude = Cesium.Math.toDegrees(cartographic.longitude);
            const latitude = Cesium.Math.toDegrees(cartographic.latitude);
            const point1 = Cesium.Cartesian3.fromDegrees(lon, lat);
            const point2 = Cesium.Cartesian3.fromDegrees(longitude, latitude);
            const gure = Cesium.Cartesian3.distance(point1, point2)
            this.betweenDistance  = gure
        }
        this.dealTree()
      }
      const key = event.key;
      const lower = key.toLowerCase();
@@ -721,6 +727,44 @@
    resetView() {
      // Fly back to the initial view (home) in 1 second
      viewerC.camera.flyHome(1.0);
    },
    dealTree(){
      let allEntities = viewerM.entities.values; // 所有实体对象组成的数组
      const grouped = {};
      //所有实体对象组成的数组转换成左侧树需要的格式
      allEntities.forEach(item => {
        const match = item.id.match(/(groundPoiId|aerialPoiId)(\d+)/);
        if (match) {
          const type = match[1]; // groundPoiId or aerialPoiId
          const index = match[2];
          if (!grouped[index]) grouped[index] = {};
          grouped[index][type] = item.position;
        }
      })
      const result = Object.keys(grouped).map((key, idx) => {
        const group = grouped[key];
        const positionGround = group.groundPoiId.getValue(Cesium.JulianDate.now())
        const positionAerialPo = group.aerialPoiId.getValue(Cesium.JulianDate.now())
        const groundPos = Cesium.Cartographic.fromCartesian(positionGround);
        const aerialPos = Cesium.Cartographic.fromCartesian(positionAerialPo);
        return {
          id: this.genId(),
          label: `地面点${idx}`,
          longitude: Cesium.Math.toDegrees(groundPos.longitude),
          latitude: Cesium.Math.toDegrees(groundPos.latitude),
          height: groundPos.height,
          children: [
            {
              id: this.genId(),
              label: `空中点${idx}`,
              longitude: Cesium.Math.toDegrees(aerialPos.longitude),
              latitude: Cesium.Math.toDegrees(aerialPos.latitude),
              height: aerialPos.height
            }
          ]
        };
      });
      this.$emit('dealTreeData',result)
    },
    mergePoint(){
      let allEntities = viewerM.entities.values; // 所有实体对象组成的数组
@@ -996,7 +1040,40 @@
    },
    onSliderInput(val) {
      this.zoomRatio = val;
    }
    },
    // 计算 heading(偏航角)
    computeHeading(fromCartesian, toCartesian) {
      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
      const direction = Cesium.Cartesian3.subtract(
        toCartesian,
        fromCartesian,
        new Cesium.Cartesian3()
      );
      const directionLocal = Cesium.Matrix4.multiplyByPointAsVector(
        Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()),
        direction,
        new Cesium.Cartesian3()
      );
      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
      return Math.atan2(directionLocal.x, directionLocal.y);
    },
    // 计算 pitch(俯仰角)
    computePitch(fromCartesian, toCartesian) {
      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
      const direction = Cesium.Cartesian3.subtract(
        toCartesian,
        fromCartesian,
        new Cesium.Cartesian3()
      );
      const directionLocal = Cesium.Matrix4.multiplyByPointAsVector(
        Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()),
        direction,
        new Cesium.Cartesian3()
      );
      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
      return Math.asin(directionLocal.z); // z轴向上
    },
  }
}
</script>
@@ -1047,7 +1124,7 @@
}
.moveResult{position:absolute;z-index:2;background-color:rgba(47,53,60,1);padding:0 5px;right:50%;bottom:30px;
    border:1px solid rgba(255,255,255,.1);box-sizing:content-box;width:220px;height:30px;font-size:14px;text-align:center}
.cammoveResult{position:absolute;z-index:2;background-color:rgba(47,53,60,1);padding:0 5px;right:calc(50% - 40px);bottom:30px;
.cammoveResult{position:absolute;z-index:2;background-color:rgba(47,53,60,1);padding:0 5px;right:calc(50% - 140px);bottom:35px;
    border:1px solid rgba(255,255,255,.1);box-sizing:content-box;width:400px;height:30px;font-size:14px;text-align:center}
.moveResultCon{margin-top:4px}
.cammoveResultCon{margin-top:4px;color: white;}
src/views/system/shootPoint/components/shootPointDialog.vue
@@ -33,13 +33,14 @@
                    :allow-drop="allowDrop"
                    @node-drop="handleDrop"
                    default-expand-all
                    @node-click="handleNodeClick"
                    ref="tree">
                  </el-tree>
                </div>
              </el-card>
          </el-col>
          <el-col :span="20">
              <InitMap v-if="showMap" @mergePoint="mergePoint" :towerUrl="towerUrl"  :deviceData="deviceData"></InitMap>
              <InitMap v-if="showMap" @mergePoint="mergePoint" :towerUrl="towerUrl"  :deviceData="deviceData"  @dealTreeData="dealTreeData"></InitMap>
          </el-col>
      </el-row>
      <span slot="footer" class="dialog-footer">
@@ -113,6 +114,78 @@
    }
  },  
  methods:{
   // 计算 heading(偏航角)
    computeHeading(fromCartesian, toCartesian) {
      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
      const direction = Cesium.Cartesian3.subtract(
        toCartesian,
        fromCartesian,
        new Cesium.Cartesian3()
      );
      const directionLocal = Cesium.Matrix4.multiplyByPointAsVector(
        Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()),
        direction,
        new Cesium.Cartesian3()
      );
      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
      return Math.atan2(directionLocal.x, directionLocal.y);
    },
    // 计算 pitch(俯仰角)
    computePitch(fromCartesian, toCartesian) {
      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
      const direction = Cesium.Cartesian3.subtract(
        toCartesian,
        fromCartesian,
        new Cesium.Cartesian3()
      );
      const directionLocal = Cesium.Matrix4.multiplyByPointAsVector(
        Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()),
        direction,
        new Cesium.Cartesian3()
      );
      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
      return Math.asin(directionLocal.z); // z轴向上
    },
    // 飞到 from 看向 to
    flyToAndLookAt(from, to) {
      const fromCartesian = Cesium.Cartesian3.fromDegrees(from[0], from[1], from[2]);
      const toCartesian = Cesium.Cartesian3.fromDegrees(to[0], to[1], to[2]);
      const heading = this.computeHeading(fromCartesian, toCartesian);
      const pitch = this.computePitch(fromCartesian, toCartesian);
      let viewer = window.viewerM
      viewer.camera.flyTo({
        destination: fromCartesian,
        orientation: {
          heading: heading,
          pitch: pitch,
          roll: 0.0
        },
        duration: 3
      });
    },
    handleNodeClick(data,node) {
      console.log(data);
      console.log(node)
      if(data.children && data.children.length >0) {
        //点击父级
        const from = [data.children[0].longitude,data.children[0].latitude, data.children[0].height];
        const to = [data.longitude,data.latitude, data.height];
        this.flyToAndLookAt(from, to);
      } else  {
        //点击子级
        const from = [data.longitude,data.latitude, data.height];
        const to = [node.parent?.data?.longitude,node.parent?.data?.latitude, node.parent?.data?.height];
        this.flyToAndLookAt(from, to);
      }
    },
    dealTreeData(arrList){
      this.treeData = arrList
      console.log(arrList)
    },
    convertToTree(data) {
      return data.map((item, index) => {
        const parentId = 'air_' + index;
@@ -266,7 +339,7 @@
        const ground = item
        const air = item.children[0]
        // 地面点到空中点 — 白色虚线
        // 地面点到7空中点 — 白色虚线
        viewer.entities.add({
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([