jihongshun
4 天以前 417c46988366e8c11f54230345f2e6840a0025f7
项目相关
已修改9个文件
908 ■■■■■ 文件已修改
src/api/system/template.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/components/init-map.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/device/components/deviceDialog.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/model/components/modelDialog.vue 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/project/components/addPorjectDialog.vue 646 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/project/components/chooseModelDialog.vue 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/project/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/shootPoint/components/shootPointDialog.vue 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/shootPoint/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/template.js
@@ -8,3 +8,27 @@
    data: data
  });
}
// 查询参数详细
export function getPointInfo(id) {
  return request({
    url: '/tower/point/' + id,
    method: 'get'
  });
}
// 根据设备di获取设备的飞行航线模版
export function obtainRealData(flightTemplateId, deviceId) {
  return request({
    url: `/tower/route/getTrueBearing/${flightTemplateId}/${deviceId}`,
    method: 'get'
  });
}
// 根据设备di获取设备的飞行航线模版
export function flyDataInfo(deviceId) {
  return request({
    url: '/tower/point/device/' + deviceId,
    method: 'get'
  });
}
src/utils/components/init-map.vue
@@ -36,8 +36,8 @@
let  viewerM;
let  viewerC;
let  counter = 0;
 let globalon  = 0
let globalat = 0
let  globalon  = 0
let  globalat = 0
let  pois = [globalon, globalat,0] 
// let  pois = [0, 0,0] 
@@ -78,10 +78,10 @@
    }
  },
  mounted(){
    console.log('111111111111111111')
     this.initCesium();
  },
  beforeDestroy() {
    counter = 0
    this.removeKeyboardEvents();
    if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId);
    if (viewerC) viewerC.destroy();
@@ -90,6 +90,8 @@
    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(()=>{
@@ -147,7 +149,7 @@
      
      // // 关闭光照效果
      // viewer.scene.globe.enableLighting = false; // 关闭光照效果
      window.viewer = viewer;
    //    viewer.imageryLayers.add(bdtvectoranoimagery);
      viewer._cesiumWidget._creditContainer.style.display="none";  
      return viewer;
src/views/system/device/components/deviceDialog.vue
@@ -74,19 +74,25 @@
      this.resetForm("form");
      if (ids) {
        this.getModel()
        // 编辑
        this.$api.detail('/tower/device', ids).then(res => {
          console.log(res)
          this.form = res.data
          this.open = true
          this.$nextTick(() => {
            console.log(this.form)
            this.$refs.cesiumMapSelctPoint.showPickPoint({
              longitude: +this.form.longitude,
              latitude: +this.form.latitude,
              altitude: +this.form.altitude,
              height: +this.form.height,
            })
            console.log(this.modelListData)
            let url = this.modelListData.filter(item=>item.id == this.form.modelId)[0].modelRoute
            console.log(url)
            this.modelUrl = url
            const position = Cesium.Cartesian3.fromDegrees(this.form.longitude, this.form.latitude, this.form.altitude);
            const position = Cesium.Cartesian3.fromDegrees(this.form.longitude, this.form.latitude, this.form.height);
            console.log(position)
            // 设置模型方向(可选)
            let model = viewer.entities.getById("MyModel");
            const heading = Cesium.Math.toRadians(this.form.face); // 朝东南方向
@@ -122,19 +128,20 @@
      }
    },
    handleSelectAddress(data) {
      console.log(data)
      this.$set(this.form, 'longitude', data.longitude)
      this.$set(this.form, 'latitude', data.latitude)
      this.$set(this.form, 'altitude', data.altitude)
      this.$set(this.form, 'height', data.altitude)
      this.$refs.form.validateField('longitude')
      this.$refs.form.validateField('latitude')
      this.$refs.form.validateField('altitude')
      this.$refs.form.validateField('height')
    },
    submitForm() {
      this.$refs["form"].validate(valid => {
        console.log(this.form)
        this.form.longitude = Number(this.form.longitude)
        this.form.latitude = Number(this.form.latitude)
        this.form.altitude = Number(this.form.altitude)
        this.form.height = Number(this.form.height)
        this.form.face = Number(this.form.face)
        if (valid) {
          this.$api.save('tower/device/', 'id', Object.assign({}, this.form)).then(res => {
@@ -178,13 +185,13 @@
        this.$message.error("请输入纬度");
        return;
      }
      if (!this.form.altitude) {
      if (!this.form.height) {
        this.$message.error("请输入高度");
        return;
      }
      //动态经纬度朝向 加载模型位置预览
      // const position = Cesium.Cartesian3.fromDegrees(0, 0, 0);
      const position = Cesium.Cartesian3.fromDegrees(this.form.longitude, this.form.latitude, this.form.altitude);
      const position = Cesium.Cartesian3.fromDegrees(this.form.longitude, this.form.latitude, this.form.height);
      // 设置模型方向(可选)
      // const heading = Cesium.Math.toRadians(135); // 朝东南方向
      let model = viewer.entities.getById("MyModel");
src/views/system/model/components/modelDialog.vue
@@ -13,6 +13,9 @@
                :value="dict.value"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="模型高度" prop="modelHeight">
            <el-input v-model="form.modelHeight" placeholder="请输入模型高度" />
          </el-form-item>
          <el-form-item label="文件上传" prop="modelRoute">
            <el-upload class="upload-demo" action="" :auto-upload="false" accept=".glb"
                :on-change="getFile" :limit="1">
@@ -67,9 +70,9 @@
        modelName: [
          { required: true, message: '请输入模型名称', trigger: 'blur' }
        ],
        deptId: [
          { required: true, message: '归属部门' } // trigger监听不到 使用@input单独校验vue-treeSelect表单项
        ]
        modelHeight: [
          { required: true, message: '请输入模型名称', trigger: 'blur' }
        ],
      },
      // 部门数据
      deptOptions: null,
@@ -88,7 +91,7 @@
          this.open = true
          this.$nextTick(() => {
            this.$refs.cesiumMapNoSelect.clearMap()
            this.addModel()
            this.addModel(this.form)
          })
        })
      } else {
@@ -134,42 +137,33 @@
        }
      });
    },
    addModel(){
    addModel(row){
      console.log(window)
      console.log(window.viewer)
      // viewer.entities.add({
      //   position: Cesium.Cartesian3.fromDegrees(0, 0, 0),
      //   model: {
      //     uri: "/Model/tower.glb",
      //     scale: 10000,
      //     minimumPixelSize: 50,
      //   },
      // });
      // const position = Cesium.Cartesian3.fromDegrees(139.745433, 35.658581, 0);
      const position = Cesium.Cartesian3.fromDegrees(0, 0, 0);
      // 设置模型方向(可选)
      const heading = Cesium.Math.toRadians(135); // 朝东南方向
      const heading = Cesium.Math.toRadians(0); // 朝东南方向
      const pitch = 0;
      const roll = 0;
      const orientation = Cesium.Transforms.headingPitchRollQuaternion(
        position,
        new Cesium.HeadingPitchRoll(heading, pitch, roll)
      );
      if(row){
        const entity = viewer.entities.add({
          name: "MyModel",
          position: position,
          orientation: orientation,
          model: {
            uri: row.modelRoute, // 替换成你的模型路径
          },
        });
        console.log(entity)
      // 加载 glTF 模型
      const entity = viewer.entities.add({
        name: "MyModel",
        position: position,
        orientation: orientation,
        model: {
          uri: "/Model/tower.glb", // 替换成你的模型路径
        },
      });
      console.log(entity)
      // 飞行到模型位置
      viewer.flyTo(entity)
        // 飞行到模型位置
        viewer.flyTo(entity)
      }
    },
    cancel() {
      this.$refs.cesiumMapNoSelect.clearMap()
src/views/system/project/components/addPorjectDialog.vue
@@ -10,12 +10,8 @@
          <el-col :span=6>
              <el-card class="noScroll">
                <div class="chooseModel">
                  <!-- <el-button type="primary" @click='chooseModel'>添加设备</el-button> -->
                  <div class="fontJust">设备列表</div>
                   <el-button @click="addDevice"> 新增</el-button>
                   <el-button @click="draw"> 渲染</el-button>
                   <el-button @click="test"> 转换</el-button>
                   <el-button @click="huixian"> 0.0</el-button>
                  <el-table
                    :data="tableData"
                    max-height = '180'
@@ -75,6 +71,8 @@
import CesiumMap from "../../../../utils/components/cesium-map.vue";
import chooseDeviceDialog from './chooseDeviceDialog.vue';
import chooseModelDialog from './chooseModelDialog.vue';
import { obtainRealData} from "@/api/system/template"
export  default{
  components: {
    CesiumMap,
@@ -85,257 +83,7 @@
    return{
       dialogVisible :true,
        tableData: [],
        treeData:[
    {
        "createBy": null,
        "createTime": null,
        "updateBy": null,
        "updateTime": null,
        "remark": null,
        "id": "3c5fc76c46c54c1187ff0bbcc092194b",
        "modelId": "6257cf734cf94c7caae0dee2ac2231d1",
        "deviceName": "设备3",
        "deviceType": null,
        "longitude": 125.01255362568844,
        "latitude": 46.40803605631184,
        "altitude": -0.029793403136164368,
        "belongingRoute": "线路3",
        "face": 30,
        "label": "设备3",
        "children":[
            {
                "id": "197f211797aa9f32",
                "label": "地面点0",
                "longitude": 125.01254690233337,
                "latitude": 46.408037041988585,
                "height": 5.517266389025914,
                "children": [
                    {
                        "id": "197f211797afb196",
                        "label": "空中点0",
                        "longitude": 125.01240358310912,
                        "latitude": 46.40814584281285,
                        "height": 6.971525719304772
                    }
                ]
            },
            {
                "id": "197f211797af91d9",
                "label": "地面点1",
                "longitude": 125.01254808759698,
                "latitude": 46.4080365594918,
                "height": 7.385339183474696,
                "children": [
                    {
                        "id": "197f211797afdb9a",
                        "label": "空中点1",
                        "longitude": 125.0125163640242,
                        "latitude": 46.407960727919516,
                        "height": 10.451384666363694
                    }
                ]
            },
            {
                "id": "197f211797afab31",
                "label": "地面点2",
                "longitude": 125.01255947706582,
                "latitude": 46.408036885119245,
                "height": 7.42469267651616,
                "children": [
                    {
                        "id": "197f211797a61300",
                        "label": "空中点2",
                        "longitude": 125.0128655208287,
                        "latitude": 46.4080332165472,
                        "height": 14.51791089195843
                    }
                ]
            },
            {
                "id": "197f211797af21e7",
                "label": "地面点3",
                "longitude": 125.01256023273389,
                "latitude": 46.408036999460684,
                "height": 5.5171023712317435,
                "children": [
                    {
                        "id": "197f211797a19b34",
                        "label": "空中点3",
                        "longitude": 125.01277085845463,
                        "latitude": 46.40822397536244,
                        "height": 16.06139535507995
                    }
                ]
            }
        ]
    },
    {
        "createBy": null,
        "createTime": null,
        "updateBy": null,
        "updateTime": null,
        "remark": null,
        "id": "5d7c595466094e369c6ed9fdcab6ba50",
        "modelId": "416a0c3361a9409495623eff5c19fb41",
        "deviceName": "设备2",
        "deviceType": null,
        "longitude": 124.98495711631958,
        "latitude": 46.60913669289758,
        "altitude": -0.010649270561847658,
        "belongingRoute": "线路2",
        "face": 30,
        "label": "设备2",
        "children": [
            {
                "id": "197f2157b83d1d1e",
                "label": "地面点0",
                "longitude": 124.98495046473204,
                "latitude": 46.60913764437918,
                "height": 5.517192953851729,
                "children": [
                    {
                        "id": "197f2157b833e7e6",
                        "label": "空中点0",
                        "longitude": 124.98487290823232,
                        "latitude": 46.609159110536,
                        "height": 8.492315413669576
                    }
                ]
            },
            {
                "id": "197f2157b83cb37c",
                "label": "地面点1",
                "longitude": 124.98495132002881,
                "latitude": 46.609137518901555,
                "height": 7.424720940488529,
                "children": [
                    {
                        "id": "197f2157b83dbf31",
                        "label": "空中点1",
                        "longitude": 124.984847808066,
                        "latitude": 46.60911367086078,
                        "height": 8.37839897370324
                    }
                ]
            },
            {
                "id": "197f2157b831259d",
                "label": "地面点2",
                "longitude": 124.98496295996078,
                "latitude": 46.60913752946039,
                "height": 7.424330357264399,
                "children": [
                    {
                        "id": "197f2157b837245b",
                        "label": "空中点2",
                        "longitude": 124.98502199892675,
                        "latitude": 46.60913926099941,
                        "height": 12.416325107963392
                    }
                ]
            },
            {
                "id": "197f2157b83112ee",
                "label": "地面点3",
                "longitude": 124.9849638899571,
                "latitude": 46.60913769557282,
                "height": 5.51721178277007,
                "children": [
                    {
                        "id": "197f2157b8349c7d",
                        "label": "空中点3",
                        "longitude": 124.98502033157477,
                        "latitude": 46.609152323278046,
                        "height": 4.804689162058357
                    }
                ]
            }
        ]
    },
    {
        "createBy": null,
        "createTime": null,
        "updateBy": null,
        "updateTime": null,
        "remark": null,
        "id": "f796896ac1c445c183456c500502bef0",
        "modelId": "1bd29eedeaaf4a3da83212fbb1793fd5",
        "deviceName": "设备1",
        "deviceType": null,
        "longitude": 125.14336018333184,
        "latitude": 46.558980802047344,
        "altitude": -0.0019061848373990704,
        "belongingRoute": "线路1",
        "face": 60,
        "label": "设备1",
        "children": [
    {
        "id": "197f21d1d1a28cf6",
        "label": "地面点0",
        "longitude": 125.14335344922452,
        "latitude": 46.558982037049276,
        "height": 5.556334669315725,
        "children": [
            {
                "id": "197f21d1d1adcbe6",
                "label": "空中点0",
                "longitude": 125.14330233595797,
                "latitude": 46.55904743869546,
                "height": 6.468726016875199
            }
        ]
    },
    {
        "id": "197f21d1d1a4aa12",
        "label": "地面点1",
        "longitude": 125.14335458905991,
        "latitude": 46.558981268478746,
        "height": 7.384477227891685,
        "children": [
            {
                "id": "197f21d1d1a846ae",
                "label": "空中点1",
                "longitude": 125.14298096389273,
                "latitude": 46.558969173376134,
                "height": 22.10867400719622
            }
        ]
    },
    {
        "id": "197f21d1d1a52190",
        "label": "地面点2",
        "longitude": 125.14336589537841,
        "latitude": 46.558981709304724,
        "height": 7.424676991507425,
        "children": [
            {
                "id": "197f21d1d1a6a4fe",
                "label": "空中点2",
                "longitude": 125.14339720378332,
                "latitude": 46.5590446327473,
                "height": 16.720685909327106
            }
        ]
    },
    {
        "id": "197f21d1d1a272b1",
        "label": "地面点3",
        "longitude": 125.14336689453488,
        "latitude": 46.558981604123645,
        "height": 5.516875737104807,
        "children": [
            {
                "id": "197f21d1d1af7638",
                "label": "空中点3",
                "longitude": 125.14397230855407,
                "latitude": 46.55882377669704,
                "height": 45.87173852318548
            }
        ]
    }
]
    }
],
        treeData:[],
        defaultProps: {
          children: 'children',
          label: 'label'
@@ -348,15 +96,11 @@
  },
  methods:{
    handleClose(){
      console.log("close")
      this.dialogVisible = false
      this.$emit('close')
    },
    flyToLocal(row){
      console.log(row)
      console.log(viewer)
      //  const position = Cesium.Cartesian3.fromDegrees(row.longitude,row.latitude, row.altitude);
       const position = Cesium.Cartesian3.fromDegrees(0,0,0);
       const position = Cesium.Cartesian3.fromDegrees(row.longitude,row.latitude, row.altitude);
      // 设置模型方向(可选)
      const heading = Cesium.Math.toRadians(row.face); // 朝东南方向
@@ -373,7 +117,7 @@
        position: position,
        orientation: orientation,
        model: {
          uri: "http://192.168.1.5:9000/tower/2025/07/11/铁塔_20250711093701A001.glb", // 替换成你的模型路径
          uri: row?.ardTowerModel.modelRoute, // 替换成你的模型路径
          scale: 1,
        },
        label: {
@@ -421,29 +165,27 @@
            type: 'warning'
          })
        }
        this.tableData = this.tableData.concat(arr)
        this.tableData = this.treeData.concat(arr)
      }
      const dealTreeData =this.dealTee()
      // this.treeData = dealTreeData
      console.log(this.treeData)
      this.treeData = dealTreeData
    },
    dealTee(){
      console.log(this.tableData)
     return  this.tableData.map(item => ({
        ...item,
        label: item.deviceName,
        children: []
      }));
    },
    deleteData(row){
      // 找到 id 为 "1" 的元素索引
      const index = this.tableData.findIndex(item => item.id === row.id);
      // 如果找到了,删除该元素
      if (index !== -1) {
        this.tableData.splice(index, 1);
      }
      const dealTreeData = this.dealTee()
      // this.treeData = dealTreeData
      this.treeData = dealTreeData
    },
    chooseModel(row){
      this.deviceId = row.id
@@ -455,117 +197,67 @@
    receiveModel(obj){
      //deal逻辑
      console.log(obj)
      let flightTemplateId =obj.modelObj.id
      let deviceId = obj.deviceId
      this.dealTableTemplate(obj)
      // let
      obtainRealData(flightTemplateId,deviceId).then(res=>{
        console.log(res)
        let treeDealData = this.transformFlightData(res.data?.coordinateSystemVoS || [])
        console.log(treeDealData)
        this.dealTreeMerge(obj,treeDealData)
        // const aaa = this.rotateAllPoints(this.treeData || [],res.data.longitude,res.data.latitude,res.data.height)
         this.drawConnectionsWithLabels(this.treeData)
      })
      // this.dealTreeMerge(obj)
    },
    //返回数据转换树结构
    transformFlightData(data) {
      const result = [];
      data.forEach(item => {
        // 找到第一个 groundPoint,作为代表
        const groundPoint = item.groundPointVo?.[0];
        // 生成 children 节点
        const children = groundPoint ? [{
          id: groundPoint.id,
          label: groundPoint.targetName,
          longitude: groundPoint.longitude,
          latitude: groundPoint.latitude,
          height: groundPoint.height
        }] : [];
        // 生成空中点
        result.push({
          id: item.id,
          label: item.targetName,
          longitude: item.longitude,
          latitude: item.latitude,
          height: item.altitude,
          children
        });
      });
      return result;
    },
    dealTableTemplate(obj){
      const target = this.tableData.find(item => item.id === obj.deviceId)
      if (target) {
        this.$set(target, 'mode', obj.modelObj.name) // ✅ Vue2 需要使用 $set 以确保响应式
      const targetTableData = this.tableData.find(item => item.id === obj.deviceId)
      const targetTreeData = this.treeData.find(item => item.id === obj.deviceId)
      if (targetTableData) {
        this.$set(targetTableData, 'mode', obj.modelObj.templateName) // ✅ Vue2 需要使用 $set 以确保响应式
      }
      if (targetTreeData) {
        this.$set(targetTreeData, 'mode', obj.modelObj.templateName) // ✅ Vue2 需要使用 $set 以确保响应式
      }
    },
    dealTreeMerge(obj){
      let newChildrenData= [
        { id: 100, label: '新子节点A',children:[{id: 1001,label: '新子节点A-1'}]},
        { id: 101, label: '新子节点B' }
      ]
    dealTreeMerge(obj,data){
      this.treeData.forEach(item => {
        if(item.id == obj.deviceId) {
          // 替换第一层每个节点的 children
          this.$set(item, 'children', JSON.parse(JSON.stringify(newChildrenData)));
          this.$set(item, 'children', JSON.parse(JSON.stringify(data)));
        }
      });
    },
    drawConnectionsWithLabels1111(devices) {
      const airPoints = [];
      devices.forEach(device => {
        if (!Array.isArray(device.children)) return;
        device.children.forEach(groundPoint => {
          console.log(groundPoint)
          const groundPos = Cesium.Cartesian3.fromDegrees(
            groundPoint.longitude,
            groundPoint.latitude,
            groundPoint.height
          );
          // ✅ 地面点:添加实体 + label
          viewer.entities.add({
            position: groundPos,
            point: {
              pixelSize: 6,
              color: Cesium.Color.BLUE
            },
            label: {
              text: groundPoint.label || '',
              font: '14px sans-serif',
              fillColor: Cesium.Color.WHITE,
              style: Cesium.LabelStyle.FILL_AND_OUTLINE,
              outlineWidth: 2,
              outlineColor: Cesium.Color.BLACK,
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
              pixelOffset: new Cesium.Cartesian2(0, -12)
            }
          });
          // 遍历空中点
          if (Array.isArray(groundPoint.children)) {
            groundPoint.children.forEach(airPoint => {
              console.log(airPos)
              const airPos = Cesium.Cartesian3.fromDegrees(
                airPoint.longitude,
                airPoint.latitude,
                airPoint.height
              );
              // ✅ 空中点:添加实体 + label
              viewer.entities.add({
                position: airPos,
                point: {
                  pixelSize: 6,
                  color: Cesium.Color.YELLOW
                },
                label: {
                  text: airPoint.label || '',
                  font: '14px sans-serif',
                  fillColor: Cesium.Color.YELLOW,
                  style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                  outlineWidth: 2,
                  outlineColor: Cesium.Color.BLACK,
                  verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                  pixelOffset: new Cesium.Cartesian2(0, -12)
                }
              });
              // ✅ 地面点 ➜ 空中点 蓝色虚线
              viewer.entities.add({
                polyline: {
                  positions: [groundPos, airPos],
                  width: 2,
                  material: new Cesium.PolylineDashMaterialProperty({
                    color: Cesium.Color.BLUE,
                    dashLength: 8
                  })
                }
              });
              airPoints.push(airPos);
            });
          }
        });
      });
      // ✅ 所有空中点 ➜ 黄色实线连接
      if (airPoints.length > 1) {
        viewer.entities.add({
          polyline: {
            positions: airPoints,
            width: 3,
            material: Cesium.Color.YELLOW
          }
        });
      }
    },
    drawConnectionsWithLabels(devices) {
      const airPoints = [];
@@ -657,183 +349,57 @@
        });
      }
    },
    draw(){
      this.drawConnectionsWithLabels(this.treeData)
    },
    test(){
        this.treeData = this.swapGroundAir(this.treeData);
    },
    swapGroundAir(data) {
      return data.map(device => {
        const newChildren = [];
        device.children.forEach(ground => {
          const air = ground.children && ground.children[0];
          if (air) {
            newChildren.push({
              ...air,
              children: [
                {
                  ...ground,
                  children: undefined
                }
              ]
            });
          }
        });
        return {
          ...device,
          children: newChildren
    rotateAllPoints(dataList,towerLongitude,towerLatitude,towerhHight) {
      return dataList.map(item => {
        console.log(item)
        console.log(towerLongitude)
        console.log(towerLatitude)
        console.log(towerhHight)
        const groundPoint = Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, item.height);
        const towerPoint = Cesium.Cartesian3.fromDegrees(towerLongitude, towerLatitude, towerhHight);
        let rotationAngle = Cesium.Math.toRadians(135)
        // 旋转地面点本身(会变,但绕自身旋转不会移动)
        const newGroundPoint = this.rotateAroundPoint( groundPoint,towerPoint, rotationAngle);
        const newGroundCarto = Cesium.Cartographic.fromCartesian(newGroundPoint);
        const newGround = {
          ...item,
          longitude: Cesium.Math.toDegrees(newGroundCarto.longitude),
          latitude: Cesium.Math.toDegrees(newGroundCarto.latitude),
          height: newGroundCarto.height
        };
      });
    },
    huixian(){
      let data=[
    {
        "altitude": 35.09683139439875,
        "ardGroundPoint": [
            {
                "height": 35.0960134603141,
                "latitude": 0.000032899894086000126,
                "longitude": 3.2789183307897707e-7,
                "pointNumber": 1,
                "targetName": "地面点0"
            }
        ],
        "latitude": 0.0009372188427979371,
        "longitude": 0.000009340650264268872,
        "pointNumber": 1,
        "targetName": "空中点0"
    },
    {
        "altitude": 40.057437157900914,
        "ardGroundPoint": [
            {
                "height": 40.05662385374772,
                "latitude": 0.00002759265968150938,
                "longitude": 7.877836487599675e-7,
                "pointNumber": 1,
                "targetName": "地面点1"
            }
        ],
        "latitude": 0.0009315830781716235,
        "longitude": 0.000026597143043885405,
        "pointNumber": 2,
        "targetName": "空中点1"
    },
    {
        "altitude": 90.05743715790092,
        "ardGroundPoint": [
            {
                "height": 40.05662385374772,
                "latitude": 0.00002759265968150938,
                "longitude": 7.877836487599675e-7,
                "pointNumber": 1,
                "targetName": "地面点1-加高"
            }
        ],
        "latitude": 0.0009315830781716235,
        "longitude": 0.000026597143043885405,
        "pointNumber": 3,
        "targetName": "空中点1-加高"
    },
    {
        "altitude": 85.4017386642163,
        "ardGroundPoint": [
            {
                "height": 35.09000336658791,
                "latitude": -0.0000329911085806409,
                "longitude": 4.656954257439534e-7,
                "pointNumber": 1,
                "targetName": "地面点2"
            }
        ],
        "latitude": -0.0009372610742669285,
        "longitude": 0.000013144727598247196,
        "pointNumber": 4,
        "targetName": "空中点2-加高"
    },
    {
        "altitude": 35.401738664216296,
        "ardGroundPoint": [
            {
                "height": 35.09000336658791,
                "latitude": -0.0000329911085806409,
                "longitude": 4.656954257439534e-7,
                "pointNumber": 1,
                "targetName": "地面点2"
            }
        ],
        "latitude": -0.0009372610742669285,
        "longitude": 0.000013144727598247196,
        "pointNumber": 5,
        "targetName": "空中点2"
    }
]
      let aaa = this.convertToTree(data)
      console.log(aaa)
      this.drawLines(aaa)
    },
    convertToTree(data) {
      return data.map((item, index) => {
        const parentId = 'air_' + index;
        return {
          id: parentId,
          label: item.targetName,
          longitude: item.longitude,
          latitude: item.latitude,
          height: item.altitude,
          children: (item.ardGroundPoint || []).map((g, i) => {
            return {
              id: parentId + '_ground_' + i,
              label: g.targetName,
              longitude: g.longitude,
              latitude: g.latitude,
              height: g.height
            }
          })
        }
      });
    },
    drawLines(treeData) {
      console.log(treeData)
      // 收集空中点位置
      const airPositions = treeData.map(point => {
        return Cesium.Cartesian3.fromDegrees(
          point.longitude,
          point.latitude,
          point.height
        );
      });
        console.log(newGround)
        // 处理子空中点
        newGround.children = item.children.map(child => {
          const airPoint = Cesium.Cartesian3.fromDegrees(child.longitude, child.latitude, child.height);
          const rotatedAirPoint = this.rotateAroundPoint( airPoint,towerPoint, rotationAngle);
          const rotatedAirCarto = Cesium.Cartographic.fromCartesian(rotatedAirPoint);
      // 1. 空中点之间用黄色实线连接
      viewer.entities.add({
        polyline: {
          positions: airPositions,
          width: 2,
          material: Cesium.Color.YELLOW
        }
      });
      // 2. 每个空中点与地面点用蓝色虚线连接
      treeData.forEach(point => {
        const airPos = Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, point.height);
        point.children.forEach(child => {
          const groundPos = Cesium.Cartesian3.fromDegrees(child.longitude, child.latitude, child.height);
          viewer.entities.add({
            polyline: {
              positions: [airPos, groundPos],
              width: 1,
              material: new Cesium.PolylineDashMaterialProperty({
                color: Cesium.Color.BLUE,
                dashLength: 8
              })
            }
          });
          return {
            ...child,
            longitude: Cesium.Math.toDegrees(rotatedAirCarto.longitude),
            latitude: Cesium.Math.toDegrees(rotatedAirCarto.latitude),
            height: rotatedAirCarto.height
          };
        });
        return newGround;
      });
    },
    // 计算点A绕点B逆时针旋转指定角度后的新位置
    //  空中点或者地面点笛卡尔坐标 塔的笛卡尔坐标    塔的朝向值
    rotateAroundPoint(startPoint,pivotPoint,rotationAngle) {
      // 创建一个从B点到本地坐标系的转换矩阵(东方向为X轴,北方向为Y轴,垂直方向为Z轴)
     const transformationMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(pivotPoint);
      // 获取世界坐标系到本地坐标系的转换矩阵
     const inverseTransformationMatrix = Cesium.Matrix4.inverse(transformationMatrix,new Cesium.Matrix4());
      // 将A点转换到局部坐标系中
     const localStartPoint = Cesium.Matrix4.multiplyByPoint(inverseTransformationMatrix, startPoint,new Cesium.Cartesian3());
      // 计算A点在局部坐标系中逆时针旋转指定角度后的新位置
     const rotatedX = localStartPoint.x * Math.cos(rotationAngle) + localStartPoint.y * Math.sin(rotationAngle);
     const rotatedY = localStartPoint.y * Math.cos(rotationAngle) - localStartPoint.x * Math.sin(rotationAngle);
     const rotatedZ = localStartPoint.z; // Z轴坐标保持不变
      // 将旋转后的局部坐标转换回世界坐标系
     return Cesium.Matrix4.multiplyByPoint(transformationMatrix, new Cesium.Cartesian3(rotatedX, rotatedY, rotatedZ), new Cesium.Cartesian3());
    }
  }
}
src/views/system/project/components/chooseModelDialog.vue
@@ -1,17 +1,17 @@
<template>
  <el-dialog
    title="选择模板"
    title="选择飞行模板"
    :visible.sync="dialogVisible"
    @close="cancel"
    width="20%">
    <el-form ref="form" :model="form" label-width="80px" :rules="rules">
      <el-form-item label="模板">
        <el-select v-model="form.modelObj" placeholder="请选择模板">
      <el-form-item label="飞行模板">
        <el-select v-model="form.modelObj" placeholder="请选择飞行模板" @change="handleChange">
          <el-option
              v-for="item in templateArr"
              :key="item.id"
              :label="item.name"
              :value="item">
              :label="item.templateName"
              :value="item.id">
            </el-option>
        </el-select>
      </el-form-item>
@@ -22,7 +22,9 @@
    </el-form>
  </el-dialog>
</template>
<script>
import { flyDataInfo} from "@/api/system/template"
  export default {
    name:'chooseModelDialog',
    components: {
@@ -47,21 +49,9 @@
            },
        ],
        selectArr:[],
        form:{},
        templateArr:[
          {
            id:111,
            name:'模板1'
          },
          {
            id:222,
            name:'模板2'
          },
          {
            id:333,
            name:'模板3'
          }
        ],
        form:{
        },
        templateArr:[],
        rules:{
          modelObj: [
            { required: true, message: '请选择模板', trigger: 'change' }
@@ -72,6 +62,12 @@
    mounted() {
      console.log(this.deviceId)
      if(this.deviceId){
        flyDataInfo(this.deviceId).then(res=>{
          console.log(res)
          if(res.code == 200 ) {
            this.templateArr = res.rows
          }
        })
        //点击模板查询设备下的关联模型的所有模板 
      }
    },  
@@ -79,11 +75,15 @@
      cancel(){
        this.$emit('cancelModel')
      }, 
      handleChange(value){
         this.form.deviceId = this.deviceId
        this.form.modelObj =this.templateArr.find(item => item.id === value)
      },
      submit(){
        // this.selectArr 
        //反显参数传递option对象
        this.form.deviceId = this.deviceId
        console.log(this.form)
        // //反显参数传递option对象
        // this.form.deviceId = this.deviceId
        // console.log(this.form)
        this.$emit('receiveModel',this.form)
        this.$emit('cancelModel')
      },
src/views/system/project/index.vue
@@ -2,7 +2,7 @@
  <div class="app-container">
     <el-row :gutter="20">
       <el-col :span=24 :xs="24">
        <AppTable ref="AppTable" selection :showDeptSearch="false" :url="'tower/point/list'" :tableColumns="tableColumns"
        <AppTable ref="AppTable" selection :showDeptSearch="false" :url="'tower/project/list'" :tableColumns="tableColumns"
          :tableFilter="tableFilter">
          <template #operatorBox="{ row }">
            <el-button type="primary" plain icon="el-icon-plus" size="mini"
src/views/system/shootPoint/components/shootPointDialog.vue
@@ -51,22 +51,28 @@
  </div>
</template>
<script>
import { compileToFunctions } from "vue-template-compiler";
import CesiumMap from "../../../../utils/components/cesium-map.vue";
import InitMap from "../../../../utils/components/init-map.vue";
import ChooseModelDialog from './chooseModelDialog.vue';
import { addPoint} from "@/api/system/template"
 let globalon  = 0
import { addPoint , getPointInfo} from "@/api/system/template"
let globalon  = 0
let globalat = 0
let towerHeight = 47.47
const centerCartesian = Cesium.Cartesian3.fromDegrees(globalon,globalat , 0)
//塔的朝向算法所用到的 旋转度数
let rotationAngle = Cesium.Math.toRadians(0)
let relativeData
export default{
  name:'shootPointDialog',
   components: {
    CesiumMap,
    ChooseModelDialog,
    InitMap
  },
  props: {
    templateId: {
      type: String,
      defaule: null
    }
  },
  data(){
    return{
@@ -90,8 +96,84 @@
    }
  },
  mounted(){
    if(this.templateId) {
      //预览逻辑
      getPointInfo(this.templateId).then(res=>{
        if(res.code == 200 ) {
          this.getRowData(res.data)
          let drawArr = this.convertToTree(res.data.ardListWayPointsLS)
          setTimeout(() => {
            //渲染时间问题 加个延时器
            this.drawLines(drawArr)
          }, 500);
        }
      })
    }
  },  
  methods:{
    convertToTree(data) {
      return data.map((item, index) => {
        const parentId = 'air_' + index;
        return {
          id: parentId,
          label: item.targetName,
          longitude: item.longitude,
          latitude: item.latitude,
          height: item.altitude,
          children: (item.ardGroundPoint || []).map((g, i) => {
            return {
              id: parentId + '_ground_' + i,
              label: g.targetName,
              longitude: g.longitude,
              latitude: g.latitude,
              height: g.height
            }
          })
        }
      });
    },
    drawLines(treeData) {
      console.log(treeData)
      console.log(window)
      console.log(window.viewerM)
      let viewer = window.viewerM
      // 收集空中点位置
      const airPositions = treeData.map(point => {
        return Cesium.Cartesian3.fromDegrees(
          point.longitude,
          point.latitude,
          point.height
        );
      });
      // 1. 空中点之间用黄色实线连接
      viewer.entities.add({
        polyline: {
          positions: airPositions,
          width: 2,
          material: Cesium.Color.YELLOW
        }
      });
      // 2. 每个空中点与地面点用蓝色虚线连接
      treeData.forEach(point => {
        const airPos = Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, point.height);
        point.children.forEach(child => {
          const groundPos = Cesium.Cartesian3.fromDegrees(child.longitude, child.latitude, child.height);
          viewer.entities.add({
            polyline: {
              positions: [airPos, groundPos],
              width: 1,
              material: new Cesium.PolylineDashMaterialProperty({
                color: Cesium.Color.BLUE,
                dashLength: 8
              })
            }
          });
        });
      });
    },
    addPoint(viewer, position, color, label) {
      viewer.entities.add({
        name: label,
@@ -170,6 +252,7 @@
        return newGround;
      });
    },
    //合并逻辑  将附近n米范围内的点合并 并且处理成数据
    mergePoint(arr,mergeNumber,viewer){
      this.treeData = arr
      const result = this.replaceCloseChildrenWithHighestPoint(this.treeData,mergeNumber);
@@ -359,10 +442,14 @@
      console.log(row)
      this.modelName = row.modelName
      this.templateType = row.modelType
      if(this.templateId){
        this.form.templateName = row.templateName || ''
      }
      this.chooseModelId = row.id
      towerHeight = row.towerHeight || 47.47
      this.showMap =false
      this.$nextTick(()=>{
        // this.towerUrl = row.modelRoute
        this.towerUrl = row.modelRoute
        this.showMap = true
      })
src/views/system/shootPoint/index.vue
@@ -9,6 +9,8 @@
              @click="handleAdd">新增模板</el-button>
          </template>
          <template #operator="{ row }">
            <el-button size="mini" type="text" icon="el-icon-view"
              @click="preview(row)">预览</el-button>
            <el-button size="mini" type="text" icon="el-icon-delete"
              @click="handleDelete(row)">删除</el-button>
          </template>
@@ -19,7 +21,7 @@
       </el-col>
     </el-row>
    
    <shootPointDialog  @on-submit="$refs.AppTable.getData()"  v-if="showDialog" @close="close"></shootPointDialog>
    <shootPointDialog  @on-submit="$refs.AppTable.getData()"  v-if="showDialog" @close="close" :templateId="templateId"></shootPointDialog>
  </div>
</template>
@@ -67,7 +69,8 @@
        }
      ],
      showMap:false,
      showDialog:false
      showDialog:false,
      templateId:null
    };
  },
  watch: {
@@ -79,6 +82,7 @@
  methods: {
    // 添加数据
    handleAdd() {
      this.templateId = null
      this.showMap  = false
      this.showDialog = true
      // this.$refs.shootPointDialog.show()
@@ -107,7 +111,11 @@
    // },
    close(){
      this.showDialog =false
      this
    },
    preview(row){
      console.log(row)
      this.templateId = row.id
      this.showDialog = true
    }
  },
};