jihongshun
2025-07-03 307db148645230afc780a3d5d16ffb97aa32c189
src/views/system/shootPoint/components/shootPointDialog.vue
@@ -34,60 +34,12 @@
              </el-card>
          </el-col>
          <el-col :span="20">
              <!-- <el-card class="noScroll"> -->
                  <InitMap v-if="showMap" @mergePoint="mergePoint"></InitMap>
              <!-- </el-card> -->
              <InitMap v-if="showMap" @mergePoint="mergePoint" @renderData="renderData" :towerUrl="towerUrl"></InitMap>
          </el-col>
          <!-- <el-col :span="8">
                <div>
                  <div class="cameraView">
                    <a>相机视角</a>
                  </div>
                  <div class="uavView">
                    <a>无人机视角</a>
                  </div>
                  <div class="operationControl">
                    <a>操控相关(使用以下键控制相机视角)</a>
                    <div>
                      <el-button type="primary">地面点</el-button>
                      <el-button type="primary">空中点</el-button>
                      <el-button type="primary">悬停时间</el-button>
                    </div>
                    <div>
                       <div  class="container">
                          <div class="keypad">
                            <div class="row">
                              <div class="key">Q-上升</div>
                              <div class="key">W-向前</div>
                              <div class="key">E-下降</div>
                            </div>
                            <div class="row">
                              <div class="key">A- 向左</div>
                              <div class="key">S- 向后</div>
                              <div class="key">D- 向右</div>
                            </div>
                          </div>
                          <div class="arrow-pad">
                            <div class="arrow-row">
                              <div class="arrow empty"></div>
                              <div class="arrow">↑ - 向上看</div>
                              <div class="arrow empty"></div>
                            </div>
                            <div class="arrow-row">
                              <div class="arrow">← - 向左转</div>
                              <div class="arrow">↓ - 向下看</div>
                              <div class="arrow">→ - 向右转</div>
                            </div>
                          </div>
                        </div>
                    </div>
                  </div>
                </div>
          </el-col> -->
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeModal">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
        <el-button type="primary" @click="submit()" >确 定</el-button>
      </span>
    </el-dialog>
    <ChooseModelDialog v-if="showModel" @cancel ='cancel' @getRowData="getRowData" ></ChooseModelDialog>
@@ -97,7 +49,13 @@
import CesiumMap from "../../../../utils/components/cesium-map.vue";
import InitMap from "../../../../utils/components/init-map.vue";
import ChooseModelDialog from './chooseModelDialog.vue';
// const centerCartesian = Cesium.Cartesian3.fromDegrees(0,0, 236)
// const centerCartesian = Cesium.Cartesian3.fromDegrees(125.1949, 46.5143, 0)
 let globalon  = 125.1949
let globalat = 46.5143
const centerCartesian = Cesium.Cartesian3.fromDegrees(globalon,globalat , 236)
let relativeData
export default{
  name:'shootPointDialog',
   components: {
@@ -109,28 +67,6 @@
    return{
      dialogVisible :true,
      showModel:false,
      //  treeData: [{
      //     id: 1,
      //     label: '一级 1',
      //     children: [{
      //       id: 4,
      //       label: '二级 1-1',
      //     }]
      //   }, {
      //     id: 2,
      //     label: '一级 2',
      //     children: [{
      //       id: 5,
      //       label: '二级 2-1'
      //     }]
      //   }, {
      //     id: 3,
      //     label: '一级 3',
      //     children: [{
      //       id: 7,
      //       label: '二级 3-1'
      //     }]
      //   }],
        treeData:[],
        defaultProps: {
          children: 'children',
@@ -140,10 +76,294 @@
        initialCameraPosition: null,
        initialCameraOrientation: null,
        animationFrameId: null,
        showMap:false
        showMap:false,
        towerUrl:null,
        chooseModelId:null
    }
  },
  mounted(){
  },
  methods:{
    renderRelativePoints(viewer, data) {
      const airPoints = [];
      data.forEach(item => {
        const groundRel = item.relativePosition;
        const groundPos = Cesium.Cartesian3.add(
          centerCartesian,
          new Cesium.Cartesian3(groundRel.x, groundRel.y, groundRel.z),
          new Cesium.Cartesian3()
        );
        this.addPoint(viewer, groundPos, Cesium.Color.BLUE, item.label);
        item.children?.forEach(child => {
          const airRel = child.relativePosition;
          const airPos = Cesium.Cartesian3.add(
            centerCartesian,
            new Cesium.Cartesian3(airRel.x, airRel.y, airRel.z),
            new Cesium.Cartesian3()
          );
          this.addPoint(viewer, airPos, Cesium.Color.YELLOW, child.label);
          // 地面点到空中点用虚线
          this.drawLine(viewer, [groundPos, airPos], Cesium.Color.GRAY, true);
          airPoints.push(airPos);
        });
      });
      // 空中点之间连黄线
      if (airPoints.length > 1) {
        this.drawLine(viewer, airPoints, Cesium.Color.YELLOW);
      }
    },
    addPoint(viewer, position, color, label) {
      viewer.entities.add({
        name: label,
        position,
        point: {
          pixelSize: 10,
          color: color,
          heightReference: Cesium.HeightReference.NONE
        },
        label: {
          text: label,
          font: '12px sans-serif',
          pixelOffset: new Cesium.Cartesian2(10, -10),
          style: Cesium.LabelStyle.FILL,
          fillColor: color,
          showBackground: true,
        }
      });
    },
    drawLine(viewer, positions, color, dashed = false) {
      viewer.entities.add({
        polyline: {
          positions,
          width: 2,
          material: dashed
            ? new Cesium.PolylineDashMaterialProperty({
                color: color,
                dashLength: 8,
              })
            : color,
        }
      });
    },
    //空间坐标反渲染
    renderData(viewerM){
      let data = [
    {
        "id": "197ced8ed37d58af",
        "label": "地面点0",
        "longitude": 125.15396706149502,
        "latitude": 46.5542193007498,
        "height": 110.34582699579633,
        "children": [
            {
                "id": "197ced8ed37d12bf",
                "label": "空中点0",
                "longitude": 125.15269101779384,
                "latitude": 46.554404555297005,
                "height": 110.34669117272557,
                "relativePosition": {
                    "x": 147.6013223491609,
                    "y": -21.93333655036986,
                    "z": -75.59047747310251
                }
            }
        ],
        "relativePosition": {
            "x": 58.98418062273413,
            "y": -66.05175063293427,
            "z": -89.7526711942628
        }
    },
    {
        "id": "197ced8ed372ae58",
        "label": "地面点1",
        "longitude": 125.15396775899208,
        "latitude": 46.55421205599431,
        "height": 129.0598176992881,
        "children": [
            {
                "id": "197ced8ed3796b97",
                "label": "空中点1",
                "longitude": 125.15267500755259,
                "latitude": 46.55432990371885,
                "height": 129.06068032390132,
                "relativePosition": {
                    "x": 137.72684245044366,
                    "y": -5.778328162617981,
                    "z": -67.71026689186692
                }
            }
        ],
        "relativePosition": {
            "x": 51.19412293517962,
            "y": -55.08268230734393,
            "z": -76.7196572907269
        }
    },
    {
        "id": "197ced8ed373aacd",
        "label": "地面点2",
        "longitude": 125.15398622045456,
        "latitude": 46.55420774953827,
        "height": 147.7039314240401,
        "children": [
            {
                "id": "197ced8ed3744bed",
                "label": "空中点2",
                "longitude": 125.15268854335208,
                "latitude": 46.5542961263164,
                "height": 147.70478259476405,
                "relativePosition": {
                    "x": 127.92680113529786,
                    "y": 6.335606334730983,
                    "z": -56.756238551810384
                }
            }
        ],
        "relativePosition": {
            "x": 42.45445924857631,
            "y": -45.13116115285084,
            "z": -63.51276256516576
        }
    },
    {
        "id": "id_v5g7eyc8",
        "label": "地面点2-加高",
        "longitude": 125.15398622045456,
        "latitude": 46.55420774953827,
        "height": 147.7039314240401,
        "children": [
            {
                "id": "id_6w8bt6y5",
                "label": "空中点2-加高",
                "longitude": 125.15268854335208,
                "latitude": 46.5542961263164,
                "height": 197.70478259476405,
                "relativePosition": {
                    "x": 108.13033775659278,
                    "y": 34.448136328253895,
                    "z": -20.454920462332666
                }
            }
        ],
        "relativePosition": {
            "x": 42.45445924857631,
            "y": -45.13116115285084,
            "z": -63.51276256516576
        }
    },
    {
        "id": "id_wztyoy7w",
        "label": "地面点3",
        "longitude": 125.15421307297069,
        "latitude": 46.55421685854876,
        "height": 148.48833812454288,
        "children": [
            {
                "id": "id_cu78b9f1",
                "label": "空中点3-加高",
                "longitude": 125.15548763490776,
                "latitude": 46.55440688016316,
                "height": 198.48919020619783,
                "relativePosition": {
                    "x": -62.53922047605738,
                    "y": -96.01450884295627,
                    "z": -11.418861056677997
                }
            }
        ],
        "relativePosition": {
            "x": 28.343377863056958,
            "y": -55.307947248686105,
            "z": -62.246930407360196
        }
    },
    {
        "id": "197ced8ed37d0c3c",
        "label": "地面点3",
        "longitude": 125.15421307297069,
        "latitude": 46.55421685854876,
        "height": 148.48833812454288,
        "children": [
            {
                "id": "197ced8ed376225d",
                "label": "空中点3",
                "longitude": 125.15548763490776,
                "latitude": 46.55440688016316,
                "height": 148.48919020619783,
                "relativePosition": {
                    "x": -42.741424133535475,
                    "y": -124.12601430807263,
                    "z": -47.72024560905993
                }
            }
        ],
        "relativePosition": {
            "x": 28.343377863056958,
            "y": -55.307947248686105,
            "z": -62.246930407360196
        }
    },
    {
        "id": "197ced8ed378f22b",
        "label": "地面点4",
        "longitude": 125.15423241198647,
        "latitude": 46.55421195661101,
        "height": 129.07723014528972,
        "children": [
            {
                "id": "197ced8ed37bbaff",
                "label": "空中点4",
                "longitude": 125.1555253737729,
                "latitude": 46.55432870085922,
                "height": 129.07809286219634,
                "relativePosition": {
                    "x": -41.05480555212125,
                    "y": -131.5471526850015,
                    "z": -67.78957635723054
                }
            }
        ],
        "relativePosition": {
            "x": 34.58874865854159,
            "y": -66.75211867084727,
            "z": -76.71461268886924
        }
    },
    {
        "id": "197ced8ed372f8ad",
        "label": "地面点5",
        "longitude": 125.15423571155253,
        "latitude": 46.55422768619577,
        "height": 111.12748104722147,
        "children": [
            {
                "id": "197ced8ed373e993",
                "label": "空中点5",
                "longitude": 125.15551594222936,
                "latitude": 46.554398406019274,
                "height": 112.12216624922397,
                "relativePosition": {
                    "x": -30.5103326481767,
                    "y": -145.26342066843063,
                    "z": -74.77150713000447
                }
            }
        ],
        "relativePosition": {
            "x": 42.219932773150504,
            "y": -78.02784454869106,
            "z": -88.54415378533304
        }
    }
]
      this.renderRelativePoints(viewerM,data)
    },
    handleClose(){
      this.dialogVisible = false
    },
@@ -158,15 +378,10 @@
    },
    mergePoint(arr,mergeNumber,viewer){
      this.treeData = arr
      console.log(mergeNumber)
      const result = this.replaceCloseChildrenWithHighestPoint(this.treeData,mergeNumber);
      console.log(result)
      console.log(viewer)
      console.log(window.viewer)
      const updated = this.insertRaisedPoints(result, 125.1541, 46.5542, 236, 130);
      // const updated = this.insertRaisedPoints(result, 0,0, 236, 130);
      const updated = this.insertRaisedPoints(result, globalon, globalat, 236, 130);
      this.treeData = updated
      console.log(updated)
      const airPoints = []
      this.treeData.forEach(item => {
        const ground = item
@@ -179,9 +394,9 @@
              ground.longitude, ground.latitude, ground.height,
              air.longitude, air.latitude, air.height
            ]),
            width: 2,
            width: 5,
            material: new Cesium.PolylineDashMaterialProperty({
              color: Cesium.Color.WHITE,
              color: Cesium.Color.RED,
              dashLength: 16.0
            })
          }
@@ -194,11 +409,14 @@
        viewer.entities.add({
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights(positions),
            width: 2,
            material: Cesium.Color.YELLOW
            width: 5,
            material: Cesium.Color.RED
          }
        })
      }
      console.log(this.treeData)
      // this.conversionPosition()
      this.dealData()
    },
    insertRaisedPoints(data, centerLon, centerLat, centerHeight, radius = 130) {
      const center = Cesium.Cartesian3.fromDegrees(centerLon, centerLat, centerHeight);
@@ -346,35 +564,12 @@
    },
    getRowData(row){
      console.log(row)
      // //选择好模型 并且自动飞到模型位置
      // const position = Cesium.Cartesian3.fromDegrees(0, 0, 0);
      // // 设置模型方向(可选)
      // // const heading = Cesium.Math.toRadians(135); // 朝东南方向
      // let model = viewer.entities.getById("modelList");
      // const heading = Cesium.Math.toRadians(120); // 朝东南方向
      // const pitch = 0;
      // const roll = 0;
      // const orientation = Cesium.Transforms.headingPitchRollQuaternion(
      //   position,
      //   new Cesium.HeadingPitchRoll(heading, pitch, roll)
      // );
      // if(!model) {
      //   // 加载 glTF 模型
      //   const entity = viewer.entities.add({
      //     id: "modelList",
      //     name: "modelList",
      //     position: position,
      //     orientation: orientation,
      //     model: {
      //       uri: "/Model/tower.glb", // 替换成你的模型路径
      //       scale: 1000,
      //     },
      //   });
      //   viewer.flyTo(entity)
      // }else {
      //   model.orientation = orientation
      // }
      this.chooseModelId = row.id
      this.showMap =false
      this.$nextTick(()=>{
        this.towerUrl = row.modelRoute
      this.showMap = true
      })
    },
    beforeDestroy() {
      // 清理 RAF 和事件
@@ -407,8 +602,89 @@
    },
    handleDrop (draggingNode, dropNode, dropType, ev) {
      console.log('拖拽完成', { draggingNode, dropNode, dropType })
      // Element-UI 已经帮你把 treeData 的顺序调好了,
      // 如果要保存顺序到后端,遍历 treeData 发请求即可
    },
    toRelativePosition(lon, lat, height, centerCartesian) {
      const worldPos = Cesium.Cartesian3.fromDegrees(lon, lat, height);
      const relative = new Cesium.Cartesian3();
      Cesium.Cartesian3.subtract(worldPos, centerCartesian, relative);
      return relative;
    },
     wgs84ToCartesian(longitude, latitude, height) {
      return Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
    },
    getOffsetFromTower(lon, lat, height, tower) {
      const point = this.wgs84ToCartesian(lon, lat, height);
      const towerPoint = this.wgs84ToCartesian(tower.longitude, tower.latitude, tower.height);
      const offset = Cesium.Cartesian3.subtract(point, towerPoint, new Cesium.Cartesian3());
      return {
        x: offset.x,
        y: offset.y,
        z: offset.z
      };
    },
    dealData(){
      const rawData = this.treeData
      let tower  ={
        longitude:globalon,
        latitude:globalat,
        height:0
      }
      relativeData= rawData.forEach(item => {
        item.offset = this.getOffsetFromTower(item.longitude, item.latitude, item.height, tower);
        item.children?.forEach(child => {
          child.offset = this.getOffsetFromTower(child.longitude, child.latitude, child.height, tower);
        });
      })
      console.log(relativeData)
    },
    // conversionPosition(){
    //   const rawData = this.treeData
    //   // const centerCartesian = Cesium.Cartesian3.fromDegrees(0,0, 236);
    //   const centerCartesian = Cesium.Cartesian3.fromDegrees(globalon, globalat, 236);
    //   relativeData= rawData.map(ground => {
    //     const relativeGround = this.toRelativePosition(
    //       ground.longitude,
    //       ground.latitude,
    //       ground.height,
    //       centerCartesian
    //     );
    //     const children = ground.children?.map(child => {
    //       const relativeChild = this.toRelativePosition(
    //         child.longitude,
    //         child.latitude,
    //         child.height,
    //         centerCartesian
    //       );
    //       return {
    //         ...child,
    //         relativePosition: {
    //           x: relativeChild.x,
    //           y: relativeChild.y,
    //           z: relativeChild.z,
    //         }
    //       };
    //     });
    //     return {
    //       ...ground,
    //       relativePosition: {
    //         x: relativeGround.x,
    //         y: relativeGround.y,
    //         z: relativeGround.z,
    //       },
    //       children
    //     };
    //   });
    //   console.log(relativeData)
    // },
    submit(){
      // this.dialogVisible = false
      this.$emit('close')
      console.log(this.chooseModelId)
      console.log(relativeData)
    }
  }
}