编辑航线模板、编辑航线时、航线库模拟时,可查询、显示每一个"巡检点"关联的无人机空中点杆塔巡检点的距离值、载荷方位俯仰及焦距值。
已修改2个文件
231 ■■■■■ 文件已修改
src/utils/components/init-map.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/shootPoint/components/shootPointDialog.vue 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/components/init-map.vue
@@ -32,7 +32,7 @@
    <div class="zoom-info">
        <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>
        <el-tag type="success">P: {{ cameraP }}&nbsp;&nbsp;T: {{ cameraT }} </el-tag>
    </div>
    
    
@@ -177,7 +177,9 @@
        },
        betweenDistance:0,
        cameraP:0.0,
        cameraT:0.0
        cameraT:0.0,
        pointGround: { lon: 0, lat: 0, height: 0 },
        pointFly: { lon: 0, lat: 0, height: 0 },
    }
  },
  mounted(){
@@ -388,6 +390,7 @@
                let data = {
                    "altitude":  Cesium.Cartographic.fromCartesian(tagert).height,
                    "id": chooseId,
                    'name':`空中点${counter}`,
                    "latitude": Cesium.Math.toDegrees(Cesium.Cartographic.fromCartesian(tagert).latitude),
                    "longitude":  Cesium.Math.toDegrees(Cesium.Cartographic.fromCartesian(tagert).longitude),
                }
@@ -402,9 +405,20 @@
                //塔的距离和观测点的距离
                console.log(_this.deviceData)
                const point1 = Cesium.Cartesian3.fromDegrees(0, 0, _this.deviceData?.modelHeight || 45);
                _this.pointGround = {
                  lon:longitude,
                  lat:latitude,
                  height:height
                }
                // const point1 = Cesium.Cartesian3.fromDegrees(0, 0, 45);
                const point2 = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(Cesium.Cartographic.fromCartesian(tagert).longitude), Cesium.Math.toDegrees(Cesium.Cartographic.fromCartesian(tagert).latitude), Cesium.Cartographic.fromCartesian(tagert).height);
                _this.pointFly = {
                  lon:Cesium.Math.toDegrees(Cesium.Cartographic.fromCartesian(tagert).longitude),
                  lat:Cesium.Math.toDegrees(Cesium.Cartographic.fromCartesian(tagert).latitude),
                  height:Cesium.Cartographic.fromCartesian(tagert).height
                }
                _this.createDashedLine()
                _this.createBillboard()
                // 计算距离(单位:米)
                const distanceCalculate = Cesium.Cartesian3.distance(point1, point2)
                data.distance = distanceCalculate
@@ -426,6 +440,48 @@
            }
            console.log('右键点击监听已停止');
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);  // 监听右键点击
    },
    createDashedLine() {
      this.lineEntity = viewerM.entities.add({
        polyline: {
          positions: new Cesium.CallbackProperty(() => {
            return Cesium.Cartesian3.fromDegreesArrayHeights([
              this.pointGround.lon, this.pointGround.lat, this.pointGround.height,
              this.pointFly.lon, this.pointFly.lat, this.pointFly.height,
            ]);
          }, false),
          width: 3,
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.RED,
          }),
        },
      });
    },
    createBillboard() {
      // Billboard 中点计算
      viewerM.entities.add({
        position: new Cesium.CallbackProperty(() => {
          const midLon = (this.pointGround.lon + this.pointFly.lon) / 2;
          const midLat = (this.pointGround.lat + this.pointFly.lat) / 2;
          const midHeight = (this.pointGround.height + this.pointFly.height) / 2;
          return Cesium.Cartesian3.fromDegrees(midLon, midLat, midHeight);
        }, false),
        label: {
          text: new Cesium.CallbackProperty(() => {
            return `距离: ${this.betweenDistance.toFixed(1)} m\nP: ${this.cameraP}\nT:${this.cameraT}`;
          }, false),
          font: "16px sans-serif",
          fillColor: Cesium.Color.BLACK,
          outlineColor: Cesium.Color.WHITE,
          outlineWidth: 2,
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          pixelOffset: new Cesium.Cartesian2(0, -20), // 向上偏移
          showBackground: true,
          backgroundColor: new Cesium.Color(1, 1, 1, 0.7),
        },
      });
    },
    azimuthtwopoi(x1, y1, x2, y2) {
      let result;
@@ -561,7 +617,11 @@
            const gure = Cesium.Cartesian3.distance(point1, point2)
            this.betweenDistance  = gure
        }
        this.pointFly = {
          lon: lon,
          lat: lat,
          height: height
        }
        this.dealTree()
      }
      const key = event.key;
@@ -900,6 +960,7 @@
        // viewer.scene.primitives.add(cameraVideo);
        let pmObj = {};
        pmObj.id = data.id;
        pmObj.name = data.name;
        pmObj.primitive = cameraVideo;
        viewerM.scene.primitives.add(cameraVideo);
        preVideoScopePrimitiveArrTie.push(pmObj);
@@ -990,10 +1051,12 @@
        ',' +
        roll.toFixed(1) +
        '\u00B0';
        console.log(heading)
      this.cameraP = heading.toFixed(2)
      this.cameraT = pitch.toFixed(2)
      document.getElementById('cammoveResultCon').innerHTML = camResult;
      // 计算距离(单位:米)
      const distanceBetween = Cesium.Cartesian3.distance(point1, point2)
      console.log(preVideoScopePrimitiveArrTie)
      preVideoScopePrimitiveArrTie.map((item)=>{
        if(item.id == chooseId){
          let obj = this.updateSZScope(Cesium.Math.toDegrees(position.longitude),Cesium.Math.toDegrees(position.latitude),position.height,heading,pitch,roll,this.zoomRatio,distanceBetween)
@@ -1075,6 +1138,25 @@
      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
      return Math.asin(directionLocal.z); // z轴向上
    },
    DealVisualCone(data,node){
      if(data.children && data.children?.length > 0) {
        preVideoScopePrimitiveArrTie.map((item)=>{
          if(item.name != data.children[0].label){
            item.primitive.show = false
          }else{
             item.primitive.show = true
          }
        })
      }else {
        preVideoScopePrimitiveArrTie.map((item)=>{
          if(item.name != data.label){
            item.primitive.show = false
          }else {
            item.primitive.show = true
          }
        })
      }
    }
  }
}
</script>
src/views/system/shootPoint/components/shootPointDialog.vue
@@ -25,6 +25,8 @@
                </div>
                <div class="modelTree">
                  <div class='modelTreeTitle'>巡检点目录</div>
                  <el-tabs v-model="activeName">
                    <el-tab-pane label="航点树" name="first">
                  <el-tree
                    class="filter-tree"
                    :data="treeData"
@@ -36,11 +38,41 @@
                    @node-click="handleNodeClick"
                    ref="tree">
                  </el-tree>
                    </el-tab-pane>
                    <el-tab-pane label="航点列表" name="second">
                      <div class="waypoint-panel">
                        <!-- 航点列表 -->
                        <div class="waypoints">
                          <div
                            v-for="(wp, index) in waypoints"
                            :key="index"
                            class="waypoint-item"
                            :class="{ active: selectedIndex === index }"
                            @click="toggleSelect(wp,index)"
                          >
                            <div class="waypoint-header">
                              <i
                                class="el-icon-success"
                              ></i>
                              <span>
                                <span class="waypoint-index">{{ wp.label }}</span>
                                <i class="el-icon-camera"></i>
                                <i class="el-icon-video-camera"></i>
                                <i class="el-icon-picture-outline"></i>
                              </span>
                            </div>
                          </div>
                        </div>
                      </div>
                    </el-tab-pane>
                  </el-tabs>
                </div>
              </el-card>
          </el-col>
          <el-col :span="20">
              <InitMap v-if="showMap" @mergePoint="mergePoint" :towerUrl="towerUrl"  :deviceData="deviceData"  @dealTreeData="dealTreeData"></InitMap>
              <InitMap v-if="showMap" @mergePoint="mergePoint" :towerUrl="towerUrl"  :deviceData="deviceData"  @dealTreeData="dealTreeData" ref="initMap"></InitMap>
          </el-col>
      </el-row>
      <span slot="footer" class="dialog-footer">
@@ -93,7 +125,14 @@
        modelName:null,
        templateType:null,
        form:{},
        deviceData:null
        deviceData:null,
        activeName: 'first',
        totalDistance: 3054.9,
        totalTime: '5m 56s',
        totalPoints: 11,
        totalPhotos: 3,
        waypoints:[],
        selectedIndex:null
    }
  },
  mounted(){
@@ -114,6 +153,24 @@
    }
  },  
  methods:{
    toggleSelect(wq,index) {
      console.log(this.treeData)
      console.log(wq)
      // 如果点击的是当前行,则取消选中
      if (this.selectedIndex === index) {
        this.selectedIndex = null
      } else {
        this.selectedIndex = index
      }
      const result = this.treeData.filter(item =>
          item.children && item.children.some(child => child.label === wq.label)
      );
      const dataObj = result[0]
      const from = [dataObj.children[0]?.longitude,dataObj.children[0]?.latitude, dataObj.children[0]?.height];
      const to = [dataObj.longitude,dataObj.latitude, dataObj.height];
      this.flyToAndLookAt(from, to);
      this.$refs.initMap.DealVisualCone(dataObj)
    },
   // 计算 heading(偏航角)
    computeHeading(fromCartesian, toCartesian) {
      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
@@ -167,8 +224,6 @@
      });
    },
    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];
@@ -180,11 +235,17 @@
        const to = [node.parent?.data?.longitude,node.parent?.data?.latitude, node.parent?.data?.height]; 
        this.flyToAndLookAt(from, to);
      }
      this.$refs.initMap.DealVisualCone(data,node)
    },
    dealTreeData(arrList){
      this.treeData = arrList
      console.log(arrList)
      const childrenArr = arrList
        .filter(item => Array.isArray(item.children))
        .map(item => item.children)
        .reduce((acc, cur) => acc.concat(cur), []);
      this.waypoints = childrenArr
      console.log(childrenArr)
      console.log(this.treeData)
    },
    convertToTree(data) {
      return data.map((item, index) => {
@@ -635,7 +696,7 @@
</script>
<style scoped>
.noScroll{
    height: calc(100vh - 185px);
    height: calc(100vh - 175px);
    overflow: auto;
    position: relative;
}
@@ -749,3 +810,67 @@
  box-shadow: none;
}
</style>
<style scoped>
.waypoint-panel {
  width: 300px;
  /* background: #1e1e1e;
  color: white; */
  font-size: 14px;
  height: 500px;
  overflow-y: scroll;
  /* overflow: scroll; */
}
.stats {
  display: flex;
  justify-content: space-around;
  padding: 8px;
  border-bottom: 1px solid #333;
}
.stat-item {
  display: flex;
  align-items: center;
}
.stat-item i {
  margin-right: 4px;
}
.waypoint-item {
  border-bottom: 1px solid #333;
  height: 40px;
  line-height: 40px;
}
.waypoint-item.active {
  background-color: rgba(0, 122, 255, 0.3); /* 高亮色 */
}
.waypoint-header {
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 4px 8px;
}
.waypoint-header i {
  margin-right: 6px;
  height: 36px;
  line-height: 36x;
  transition: transform 0.2s;
  font-size: 24px;
}
.waypoint-header .waypoint-index {
  font-size: 24px;
}
.rotated {
  transform: rotate(-90deg);
}
.waypoint-content {
  padding: 4px 8px;
  display: flex;
  gap: 8px;
}
</style>