jihongshun
2025-09-11 bcb67f336c2b352177884b8db6decc3fcf382bb0
src/views/system/flightRouteSimulation/index.vue
@@ -1,6 +1,6 @@
<template>
   <div class="app-container">
    <el-button type="primary" @click="showGZ">主要按钮</el-button>
    <el-button type="primary" @click="showGZ">显示视锥体</el-button>
    <input @change="handleKMZUpload" type="file" id="kmzFile" accept=".kmz" class="block w-full text-sm text-gray-500
    file:mr-4 file:py-2 file:px-4
    file:rounded-md file:border-0
@@ -93,36 +93,33 @@
      //   // 更多点...
      // ],
      trajectoryData:[],
      c3Position:Cesium.Cartesian3.fromDegrees(125.14349012556997, 46.55684464616254,33.157873665937274),
      enableChange:true,
      trajectoryData:[],//数据数组
      c3Position:Cesium.Cartesian3.fromDegrees(125.04159166971326, 46.63755601510411,33.13806141449017),//初始化位置
      camera: null,      // Cesium Camera 实例
      frustumOutline: null, // 视锥体
      heading: 0,        // 相机的 heading (朝向)
      pitch: -90, // 相机的 pitch (俯仰)
      heading: -90,        // 相机的 heading (朝向)
      pitch: 0, // 相机的 pitch (俯仰)
      roll: 0,           // 相机的 roll (滚转)
      aspectRatio: 1.0,  // 纵横比
      color: '#FF0000',  // 视锥体颜色
      id: 'frustumOutline',
      positionProperty : new Cesium.SampledPositionProperty(),
      orientation : new Cesium.SampledProperty(Cesium.Quaternion)
      orientation : new Cesium.SampledProperty(Cesium.Quaternion),//无人机朝向
      sztOrientation : new Cesium.SampledProperty(Cesium.Quaternion),//云台朝向
    }
  },
  mounted() {
    console.log(window.viewer)
    console.log(viewer)
    // this.showGZ()
  },
  methods: {
    async handleKMZUpload(event) {
      const file = event.target.files[0];
      if (!file) return;
      try {
        const arrayBuffer = await this.readFileAsArrayBuffer(file);
        this.waypoints = await this.parseKMZ(arrayBuffer);
        //加点逻辑 比如向第2-n-1中插入元素  经纬度为当前的  heading pitch roll 下一个的
        const dealArr = [];
        console.log(">> this.waypoints:", this.waypoints);
        // console.log(">> this.waypoints:", this.waypoints);
        for (let i = 0; i < this.waypoints.length - 1; i++) {
            dealArr.push(this.waypoints[i]); // Push the current element
            const current = this.waypoints[i];
@@ -144,7 +141,7 @@
        dealArr.push(this.waypoints[this.waypoints.length - 1]);
        console.log(dealArr)
        // this.waypoints = dealArr
        this.waypoints = dealArr
        console.log(">> this.waypoints:", this.waypoints);
        this.fileInfo = `
@@ -157,9 +154,12 @@
        const speeds = [10, 10, 20, 30, 80, 100, 60, 50, 40, 30, 20, 10]; // 自定义速度
        // const result = this.waypoints.map((item, index) => {
        console.log(result)
        const result = dealArr.map((item, index) => {
        // const result = this.waypoints.map((item, index) => {
          // 每次加一天
          const time = new Date(startDate.getTime() + index * 60 * 1000).toISOString();
          // const time = Cesium.JulianDate.addSeconds(startDate, 3600, new Cesium.JulianDate());
          return {
            time,
            position: {
@@ -171,11 +171,12 @@
            pitch:item.pitch|| 0,
            roll:item.roll || 0,
            speed: speeds[index] || 0,
            flyHeading:item.flyHeading
            // flyHeading:item.flyHeading
          };
        });
        this.trajectoryData = result
        console.log(result);
        console.log(this.trajectoryData)
        // console.log(result);
        this.loadTimeLine()
      } catch (error) {
        console.error(error);
@@ -199,7 +200,7 @@
      const kmlFile = Object.keys(zip.files).find(name =>
        name.endsWith(".kml")
      );
      console.log(">> kmlFile:", kmlFile);
      // console.log(">> kmlFile:", kmlFile);
      if (!kmlFile) throw new Error("未找到KML文件");
      const kmlContent = await zip.file(kmlFile).async("text");
@@ -238,35 +239,18 @@
                totalPitch += gimbalPitch;
                totalRoll += gimbalRoll;
                totalHeading += gimbalYaw;
                console.log('totalHeading里面循环' + totalHeading)
            }
            // 处理 rotateYaw 函数
            if (action['wpml:actionActuatorFunc'].includes("rotateYaw")) {
                // 获取 aircraftHeading
                const aircraftHeading = parseFloat(action['wpml:actionActuatorFuncParam'][0]["wpml:aircraftHeading"][0]);
                console.log(aircraftHeading)
                flyHeadingData = aircraftHeading
                // 将 aircraftHeading 累加到 totalHeading
                totalHeading += aircraftHeading;
                console.log('totalHeading外层外层外层外层外层循环' + totalHeading)
            }
            // action['wpml:actionActuatorFuncParam'][0].['wpml:gimbalPitchRotateAngle']
            // let params = action["wpml:actionActuatorFuncParam"]?.[0];
            // if (!params) return;
            // // 飞机航向角
            // if (action["wpml:actionActuatorFunc"]?.[0] === "rotateYaw" &&
            //     params["wpml:aircraftHeading"]) {
            //   heading = Number(params["wpml:aircraftHeading"][0]);
            // }
            // // 云台角度
            // if (action["wpml:actionActuatorFunc"]?.[0] === "gimbalRotate") {
            //   if (params["wpml:gimbalPitchRotateAngle"])
            //     gimbalPitch = Number(params["wpml:gimbalPitchRotateAngle"][0]);
            //   if (params["wpml:gimbalRollRotateAngle"])
            //     gimbalRoll = Number(params["wpml:gimbalRollRotateAngle"][0]);
            //   if (params["wpml:gimbalYawRotateAngle"])
            //     gimbalYaw = Number(params["wpml:gimbalYawRotateAngle"][0]);
            // }
          });
        }
        // 输出结果
@@ -276,7 +260,6 @@
        if (coords) {
          coords.trim().split(" ").forEach(coord => {
            const [lng, lat] = coord.split(",").map(Number);
            //,heading:gimbalYaw || 0,pitch:gimbalPitch|| 0,roll:gimbalRoll|| 0
            points.push({ lng, lat, alt: height,heading:totalHeading  || 0,pitch:totalPitch || 0,roll:totalRoll|| 0 ,flyHeading:flyHeadingData});
          });
        }
@@ -318,9 +301,6 @@
    showFlightPath() {
      console.log(">> this.waypoints:", this.waypoints);
      if (this.waypoints.length === 0) return alert('请先上传KMZ文件');
      // viewer.entities.removeAll();
      // 转换坐标
      const positions = this.waypoints.map(wp =>
        Cesium.Cartesian3.fromDegrees(wp.lng, wp.lat, wp.alt)
@@ -367,7 +347,6 @@
      //精度维度高度
      getScopeTower(lon,lat,distance).then(res=>{
        if(res.code == 200) {
          console.log(res.rows)
          res.rows.forEach((data) => {
            this.createModel(data);
          });
@@ -376,7 +355,6 @@
      })
    },
    createModel(data){
      console.log(data)
      viewer.entities.add({
        id: data.id,
        position: Cesium.Cartesian3.fromDegrees(data.longitude, data.latitude, data.altitude),
@@ -404,7 +382,11 @@
    loadTimeLine(){
      // 设置时间范围
      const allTimes = this.trajectoryData.map(item => Cesium.JulianDate.fromIso8601(item.time))
      console.log(allTimes)
      // 获取所有时间,并减去8小时
      // const allTimes = this.trajectoryData.map(item => {
      //     const time = Cesium.JulianDate.fromIso8601(item.time)
      //     return Cesium.JulianDate.addHours(time, +8, new Cesium.JulianDate())
      // })
      const startTime = allTimes[0]
      const stopTime = allTimes[allTimes.length - 1]
      // const startTime = Cesium.JulianDate.minimum(...allTimes)
@@ -433,45 +415,38 @@
        speedProperty.addSample(time, data.speed)
            // 计算朝向四元数
        // const hpr = new Cesium.HeadingPitchRoll(
        //     Cesium.Math.toRadians(data.heading),
        //     Cesium.Math.toRadians(data.flyHeading),
        //     Cesium.Math.toRadians(data.pitch),
        //     Cesium.Math.toRadians(data.roll)
        // );
        const hpr = new Cesium.HeadingPitchRoll(
            Cesium.Math.toRadians(data.flyHeading),
            Cesium.Math.toRadians(0),
            Cesium.Math.toRadians(0),
            Cesium.Math.toRadians(0)
        );
        const quaternion = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
        console.log(Cesium.JulianDate.toDate(time))
        // // 添加飞机朝向采样
        this.orientation.addSample(time, quaternion);
        //云台
        const szthpr = new Cesium.HeadingPitchRoll(
            Cesium.Math.toRadians(data.heading),
            Cesium.Math.toRadians(data.pitch),
            Cesium.Math.toRadians(data.roll)
        );
        const sztquaternion = Cesium.Transforms.headingPitchRollQuaternion(position, szthpr);
        
        // // 添加朝向采样
        this.orientation.addSample(data.time, quaternion);
        this.sztOrientation.addSample(time, sztquaternion);
      })
      console.log(">> positionProperty:",this.positionProperty );
      // console.log(">> positionProperty:",this.positionProperty );
      let entity = viewer.entities.add({
        show: true,
        position: this.positionProperty,
        id:'lineFly',
        // label: {
        //   show: true,
        //   font: '18px 微软雅黑',
        //   style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        //   showBackground: false,
        //   backgroundColor: Cesium.Color.fromCssColorString('#123456').withAlpha(0.5),
        //   outlineColor: Cesium.Color.fromCssColorString('#00ff00'),
        //   outlineWidth: 3,
        //   fillColor: Cesium.Color.fromCssColorString("#000000"),
        //   horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
        //   verticalOrigin: Cesium.VerticalOrigin.TOP,
        //   text: '测试文字',
        //   // pixelOffset: new Cesium.Cartesian2(0, -1 * 100),
        //   pixelOffset: new Cesium.Cartesian2(0, -90)
        // },
        model: {
          uri: "/Model/M300.glb", // 注意entitits.add方式加载gltf文件时,这里是uri,不是url,并且这种方式只能加载.glb格式的文件
          scale:  10, // 缩放比例
          // minimumPixelSize: this.minSize, // 最小像素大小,可以避免太小看不见
          minimumPixelSize: 0, // 最小像素大小,可以避免太小看不见
          maximumScale: 20000, // 模型的最大比例尺大小。minimumPixelSize的上限
          incrementallyLoadTextures: true, // 加载模型后纹理是否可以继续流入
@@ -493,24 +468,12 @@
          leadTime: 60,
          trailTime: 60
        },
        // orientation: Cesium.Quaternion.fromHeadingPitchRoll(
        //     new Cesium.HeadingPitchRoll(
        //         Cesium.Math.toRadians(45), // 航向角(正北为0,顺时针增加)
        //         Cesium.Math.toRadians(45), // 俯仰角
        //         Cesium.Math.toRadians(0)  // 翻滚角
        //     )
        // ),
        orientation:this.orientation
      })
    },
     // 更新视锥体位置和朝向
    updateFrustum() {
      console.log(this.c3Position)
      console.log(this.pitch)
      console.log(this.heading)
      console.log(this.roll)
      // 更新视锥体位置
      // this.c3Position = Cesium.Cartesian3.fromDegrees(114.169, 22.278, 500);  // 动态更新位置
      if (this.frustumOutline) {
        // 更新相机和视锥体位置
        this.camera.setView({
@@ -525,9 +488,6 @@
      } else {
        console.warn('Frustum outline is not initialized');
      }
      // 更新视锥体边框
      console.log(this.frustumOutline)
      // this.frustumOutline.update();
    },
    listenChange() {
      let viewer =  window.viewer;
@@ -535,21 +495,27 @@
        if (viewer.clock.shouldAnimate) {
          this.getCurrentPosition()
        // 执行动作
        console.log("Clock is running, performing action...");
        // 你的代码逻辑
        // console.log("Clock is running, performing action...");
        // 你的代码逻
        } else {
            // 时钟暂停时不执行
            console.log("Clock is paused, no action performed.");
            // console.log("Clock is paused, no action performed.");
        }
      });
    },
    getCurrentPosition() {
      // 获取当前时间
      const currentTime = viewer.clock.currentTime;
      console.log(Cesium.JulianDate.toDate(currentTime))
      console.log('start:', Cesium.JulianDate.toDate(this.positionProperty._property._times[0]));
      console.log('stop:', Cesium.JulianDate.toDate(this.positionProperty._property._times.slice(-1)[0]));
      // const currentTime = Cesium.JulianDate.addHours(currentTime, -8, new Cesium.JulianDate());
      
      console.log(currentTime)
      // 从 positionProperty 中获取当前位置
      const currentPosition = this.positionProperty.getValue(currentTime);
      console.log('currentPosition>>>>>>>>>>>>>>>>>>>>>>>' + currentPosition)
      // console.log('currentPosition>>>>>>>>>>>>>>>>>>>>>>>' + currentPosition)
      // 如果获取到位置
      if (currentPosition) {
        // 将位置从 Cartesian 转换为 Cartographic
@@ -557,18 +523,32 @@
        // 将经纬度从弧度转换为度
        this.currentLongitude = Cesium.Math.toDegrees(cartographicPosition.longitude);
        console.log(Cesium.Math.toDegrees(cartographicPosition.longitude))
        console.log(Cesium.Math.toDegrees(cartographicPosition.latitude))
        this.currentLatitude = Cesium.Math.toDegrees(cartographicPosition.latitude);
        this.currentHeight = cartographicPosition.height;
        this.c3Position = Cesium.Cartesian3.fromDegrees(this.currentLongitude, this.currentLatitude,this.currentHeight)
        // console.log(`当前位置 - 经度: ${this.currentLongitude}, 纬度: ${this.currentLatitude}, 高度: ${this.currentHeight}`);
        //相机变化
        const quaternion = this.orientation.getValue(currentTime)
        if (quaternion) {
          const hpr = Cesium.HeadingPitchRoll.fromQuaternion(quaternion)
        // if(quaternion) {
        //   const hpr111 = Cesium.HeadingPitchRoll.fromQuaternion(quaternion)
        //   console.log('相机的   ' +Cesium.Math.toDegrees(hpr111.heading).toFixed(2))
        // }
        //云台变化
        const sztquaternion = this.sztOrientation.getValue(currentTime)
        console.log(sztquaternion)
        if (sztquaternion) {
          const hpr = Cesium.HeadingPitchRoll.fromQuaternion(sztquaternion)
          console.log(hpr)
          this.heading = Cesium.Math.toDegrees(hpr.heading).toFixed(2)
          // this.heading = 180
          this.pitch = Cesium.Math.toDegrees(hpr.pitch).toFixed(2)
          this.roll = Cesium.Math.toDegrees(hpr.roll).toFixed(2)
          console.log(`当前位置 - heading: ${hpr.heading}, pitch: ${hpr.pitch}, roll: ${hpr.roll}`);
          console.log('当前位置 - heading ' + this.heading)
          console.log(`当前位置 - heading: ${this.heading}, pitch: ${this.pitch}, roll: ${this.roll}`);
        }
        this.updateFrustum();
      } else {
        console.log("无法获取当前位置");
@@ -588,16 +568,12 @@
        up: Cesium.Cartesian3.UNIT_Z,
        destination: this.c3Position,
        orientation: {
          // heading: Cesium.Math.toRadians(this.heading),
          // pitch: Cesium.Math.toRadians(this.pitch),
          // roll: Cesium.Math.toRadians(this.roll),
          heading: Cesium.Math.toRadians(this.heading),
          pitch: Cesium.Math.toRadians(this.pitch),
          roll: Cesium.Math.toRadians(this.roll),
        },
      })
      this.frustumOutline = new Cesium.DebugCameraPrimitive({
        // id: this.id,
        id: 111111,
        camera: this.camera,
        frustumSplits: [0.01, 10000],
@@ -605,7 +581,6 @@
        // updateOnChange: false,
        updateOnChange: true,
      })
      console.log(this.frustumOutline)
      viewer.scene.primitives.add(this.frustumOutline);
      this.listenChange()
    }