jihongshun
8 天以前 c954cdb51f93585b58b761c2663688c36e6b044f
src/views/system/shootPoint/components/shootPointDialog.vue
@@ -25,21 +25,54 @@
                </div>
                <div class="modelTree">
                  <div class='modelTreeTitle'>巡检点目录</div>
                  <el-tree
                    class="filter-tree"
                    :data="treeData"
                    :props="defaultProps"
                    draggable
                    :allow-drop="allowDrop"
                    @node-drop="handleDrop"
                    default-expand-all
                    ref="tree">
                  </el-tree>
                  <el-tabs v-model="activeName">
                    <el-tab-pane label="航点树" name="first">
                        <el-tree
                          class="filter-tree"
                          :data="treeData"
                          :props="defaultProps"
                          draggable
                          :allow-drop="allowDrop"
                          @node-drop="handleDrop"
                          default-expand-all
                          @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"></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">
@@ -47,18 +80,17 @@
        <el-button type="primary" @click="submit()" >确 定</el-button>
      </span>
    </el-dialog>
    <ChooseModelDialog v-if="showModel" @cancel ='cancel' @getRowData="getRowData" ></ChooseModelDialog>
    <ChooseModelDialog v-if="showModel" @cancel ='cancel' @getRowData="getRowData"></ChooseModelDialog>
  </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 , getPointInfo} from "@/api/system/template"
let globalon  = 0
let globalat = 0
let towerHeight = 47.47
let towerHeight = 45
//塔的朝向算法所用到的 旋转度数
let rotationAngle = Cesium.Math.toRadians(0)
export default{
@@ -92,14 +124,24 @@
        chooseModelId:null,
        modelName:null,
        templateType:null,
        form:{}
        form:{},
        deviceData:null,
        activeName: 'first',
        totalDistance: 3054.9,
        totalTime: '5m 56s',
        totalPoints: 11,
        totalPhotos: 3,
        waypoints:[],
        selectedIndex:null
    }
  },
  mounted(){
    console.log(this.templateId)
    if(this.templateId) {
      //预览逻辑
      getPointInfo(this.templateId).then(res=>{
        if(res.code == 200 ) {
          console.log(res.data)
          this.getRowData(res.data)
          let drawArr = this.convertToTree(res.data.ardListWayPointsLS)
          setTimeout(() => {
@@ -111,6 +153,100 @@
    }
  },  
  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);
      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) {
      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);
      }
      this.$refs.initMap.DealVisualCone(data,node)
    },
    dealTreeData(arrList){
      this.treeData = 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) => {
        const parentId = 'air_' + index;
@@ -264,7 +400,7 @@
        const ground = item
        const air = item.children[0]
        // 地面点到空中点 — 白色虚线
        // 地面点到7空中点 — 白色虚线
        viewer.entities.add({
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
@@ -442,15 +578,19 @@
      console.log(row)
      this.modelName = row.modelName
      this.templateType = row.modelType
      this.deviceData = row
      if(this.templateId){
        this.form.templateName = row.templateName || ''
      }
      this.chooseModelId = row.id
      towerHeight = row.towerHeight || 47.47
      towerHeight = row.modelHeight || 45
      this.showMap =false
      this.$nextTick(()=>{
        // this.towerUrl = row.modelRoute
        this.towerUrl = row.modelRoute
        if(this.templateId){
          this.towerUrl = row.ardTowerModel.modelRoute
        }else {
          this.towerUrl = row.modelRoute
        }
        this.showMap = true
      })
    },
@@ -556,7 +696,7 @@
</script>
<style scoped>
.noScroll{
    height: calc(100vh - 185px);
    height: calc(100vh - 175px);
    overflow: auto;
    position: relative;
}
@@ -669,4 +809,68 @@
  background: transparent;
  box-shadow: none;
}
</style>
</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>