<template>
  <div>
    <div id="path-viewer"></div>
    <div class="path-container" >
      <div class="fly-box">
        <div class="fly-title">
          <label>飞行漫游</label>
          <i class="el-icon-close" @click="close"></i>
        </div>
        <div class="fly-content">
          <div class="fly-tab-path" v-show="!showCoord">
            <div class="fly-operation">
              <button @click="addPath">
                <i class="el-icon-circle-plus-outline"></i>新增路线
              </button>
              <button @click="document.getElementById('importBtn').click()">
                导入
              </button>
              <input
                type="file"
                style="display: none"
                name="导入"
                id="importBtn"
                accept=".json"
                @change="importPath"
              />
              <button @click="clearDraw">清除</button>
            </div>
            <div class="fly-table">
              <table>
                <thead class="fly-table-header">
                  <tr>
                    <th
                      style="width: 150px; text-align: left; padding-left: 10px"
                    >
                      名称
                    </th>
                    <th style="text-align: center">操作</th>
                  </tr>
                </thead>
                <tbody class="fly-table-body">
                  <tr v-for="p in paths" :key="p.id">
                    <td @dblclick.stop="enableInput">
                      <input
                        v-model="p.name"
                        disabled
                        @blur="inptBlur(p.id, $event)"
                      />
                    </td>
                    <td class="fly-table-operation">
                      <i
                        title="漫游"
                        v-show="!p.playing"
                        @click.stop="flyPath(p.id)"
                        class="el-icon-s-promotion"
                      ></i>
                      <i
                        title="暂停"
                        v-show="p.playing"
                        @click.stop="stopFly(p.id)"
                        class="el-icon-video-pause"
                      ></i>
                      <i
                        title="编辑"
                        @click.stop="editPath(p.id)"
                        class="el-icon-edit-outline"
                      ></i>
                      <i
                        title="删除"
                        @click.stop="deletePath(p.id)"
                        class="el-icon-delete"
                      ></i>
                      <i
                        title="导出"
                        @click.stop="exportPath(p.id)"
                        class="el-icon-printer"
                      ></i>
                    </td>
                  </tr>
                </tbody>
              </table>
              <div
                v-show="!paths.length"
                style="height: 80px; text-align: center"
              >
                <i
                  class="el-icon-folder-delete"
                  style="font-size: 2rem; margin: 20px 0 10px"
                ></i>
                <div>暂无数据</div>
              </div>
            </div>
          </div>
          <div class="fly-tab-coord" v-show="showCoord">
            <div class="title-box">
              <label>路线名称：{{ currPath.name }}</label>
            </div>
            <div class="fly-coord-content">
              <div
                class="path-coord"
                v-for="(item, index) in currPath.coords"
                :key="index"
              >
                <label>第&nbsp{{ index + 1 }}&nbsp个点</label>
                <table>
                  <tr>
                    <td style="width: 120px; text-align: center">经度</td>
                    <td><input v-model.number="item[0]" /></td>
                  </tr>
                  <tr>
                    <td style="width: 120px; text-align: center">纬度</td>
                    <td><input v-model.number="item[1]" /></td>
                  </tr>
                  <tr>
                    <td style="width: 120px; text-align: center">高度</td>
                    <td><input v-model.number="item[2]" /></td>
                  </tr>
                </table>
              </div>
            </div>

            <div class="coord-btn">
              <button @click="changPath">确定</button>
              <button @click="showCoord = false">取消</button>
            </div>
          </div>
          <!--<div class="fly-tabs">-->
          <!--<label class="fly-tabs-item">轨迹</label>-->
          <!--<label class="fly-tabs-item">坐标</label>-->
          <!--</div>-->
        </div>
        <div class="handle handle-l"></div>
        <div class="handle handle-r"></div>
        <div class="handle handle-t"></div>
        <div class="handle handle-b"></div>
        <div class="handle handle-lb"></div>
        <div class="handle handle-rb"></div>
      </div>
      <div
        id="tooltip"
        style="
          position: fixed;
          display: none;
          z-index: 999;
          background: rgba(0, 0, 0, 0.3);
          color: rgb(255, 255, 255);
          font-size: 12px;
          padding: 5px;
          border-radius: 5px;
        "
      >
        左键点击选点，右键也可取消
      </div>
    </div>
  </div>
</template>

<script>
// 对Date的扩展，将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
// 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
// 例子：
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
Date.prototype.Format = function (fmt) { //author: meizz
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}
// import { cartesianToLnglat, uuid } from "./js/cUtils";
export default {
  data() {
    return {
      name: "轨迹播放(第一人称视角)",
      showCoord: false,

      tableData: [],
      isAddStatus: false,
      pointPositionList: [], //点位置坐标数组
      pointEntities: [],
      polylineEntities: [],
      playing: false,
      // handler:new Cesium.ScreenSpaceEventHandler(viewer.canvas),//事件实例
      pathVisible: true,

      // tempPoints:[],//存储绘制的点
      // isAddPoint:false,//是否新增加了点，需要更新
      // tempEntities:[],//存储绘制轨迹中产生的实体（点、线）
      paths: [], //路径集合，{id:'',name,'',coords:[]}
      currPath: {
        id: "dsdad",
        name: "未命名-124230",
        coords: [
          [112, 32, 2],
          [112.2, 32.1, 2],
          [112.2, 32.1, 2],
          [112.2, 32.1, 2],
          [112.2, 32.1, 2],
          [112.2, 32.1, 2],
        ],
      },
      currId: "", //记录当前绘制的轨迹Id
    };
  },
  mounted() {
    this.initCesium();
    // let Cesium = this.$cesium;
    window.pointEntities = [];
    this.handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); //事件实例
    // 创建轨迹实体数据源
    window.pathSource = new Cesium.CustomDataSource("pathSource");
    viewer.dataSources.add(window.pathSource);
    // 获取本地存储的轨迹数据
    let localPath = JSON.parse(localStorage.getItem("localPaths"));
    this.palyPath = localPath ? localPath : [];
  },
  methods: {
    cartesianToLnglat:(cartesian)=>{
      //  //笛卡尔空间坐标转WGS84弧度.
      //  const ellipsoid84 = Cesium.Ellipsoid.wgs84;
      //  const cartographicPosition = ellipsoid84.cartesianToCartographic(cartesian);
      const cartographicPosition = Cesium.Cartographic.fromCartesian(cartesian);
  
      return [
        Cesium.Math.toDegrees(cartographicPosition.longitude),
        Cesium.Math.toDegrees(cartographicPosition.latitude),
      ]
    },
    uuid:function(len, radix) {
        var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
        var uuid = [], i;
        radix = radix || chars.length;
        if (len) {
            // Compact form
            for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
        } else {
            // rfc4122, version 4 form
            var r;
            // rfc4122 requires these characters
            uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
            uuid[14] = '4';
            // Fill in random data.  At i==19 set the high bits of clock sequence as
            // per rfc4122, sec. 4.1.5
            for (i = 0; i < 36; i++) {
                if (!uuid[i]) {
                    r = 0 | Math.random() * 16;
                    uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                }
            }
        }
        return uuid.join('');
    },
    initCesium() {
      let box = document.getElementsByClassName("content__default")[0];
      box.style.maxWidth = "100%";
      box.style.paddingTop = 0;
      
      let Cesium = this.$cesium;
      window.CESIUM_BASE_URL = "/cesium";
      Cesium.Ion.defaultAccessToken =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5ZjRjNTZkNC01NDYxLTRhMjQtOGEwZC1kZjA3YzQ5YTJlZDkiLCJpZCI6MjYwODQsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODcxOTMwODN9.prGsSKyAW_9Ow5zHYPhbm3LsQL-ApQw5-5PNJkDaHi8";
      var viewer = new Cesium.Viewer("path-viewer", {
        geocoder: false, //位置查找
        homeButton: false, //视图返回初始位置
        sceneModePicker: false, //视角选择器
        baseLayerPicker: false, //底图选择器
        navigationHelpButton: false, //导航帮助按钮
        animation: false, //动画控制器
        creditContainer: document.createElement("div"), //版权显示
        timeline: false, //时间线
        fullscreenButton: false, //全屏控件
        vrButton: false,
        skyBox: false,
        infoBox: false,
        selectionIndicator: false,
        shouldAnimate: false, // Enable animations
        timeline: true, //时间线
        imageryProvider:new Cesium.UrlTemplateImageryProvider({
            url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
            minimumLevel: 3,
            maximumLevel: 18
        })
      });
      // var imageryLayers = viewer.scene.imageryLayers;
      // let tdtLayer = 
      // imageryLayers.addImageryProvider(tdtLayer);

      viewer.camera.flyTo({
        destination: new Cesium.Cartesian3(
          -2325771.0288233184,
          5392181.511762224,
          2484480.395134067
        ),
        orientation: {
          heading: 6.0399326,
          pitch: -0.30503,
          roll: 6.2825747,
        },
      });

      window.viewer = viewer;
      window.Cesium = Cesium;
    },
    close() {
      this.isAddStatus = false;
      this.playing = false;
      window.pathSource.entities.removeAll();
      viewer.clock.shouldAnimate = false;
      viewer.trackedEntity = null;
    //   this.setFly(false);
    },
    triggerImport() {
      let importBtn = document.getElementById("importBtn").click();
      importBtn.click();
    },

    inptBlur(id, e) {
      this.paths.forEach((p) => {
        if (p.id == id && !p.name) {
          p.name = "未命名";
        }
      });
      e.currentTarget.disabled = true;
      localStorage.setItem("localPaths", JSON.stringify(this.paths));
    },
    enableInput(e) {
      let inputDom = e.currentTarget.getElementsByTagName("input")[0];
      inputDom.disabled = false;
      inputDom.focus();
    },
    importPath(e) {
      const file = e.target.files[0];
      if (file.type !== "application/json") {
        layer.msg("仅允许上传json文件！");
        return;
      }
      // 执行后清空input的值，防止下次选择同一个文件不会触发onchange事件
      e.target.value = "";
      // 执行读取json数据操作
      const reader = new FileReader();
      reader.readAsText(file); // 读取的结果还有其他读取方式，我认为text最为方便
      reader.onerror = (err) => {
        layer.msg("json文件解析失败！", err);
      };

      reader.onload = () => {
        const resultData = reader.result;
        if (resultData) {
          try {
            const importData = JSON.parse(resultData);
            this.$set(this.paths, this.paths.length, importData);
            // 更新本地的 paths
            localStorage.setItem("localPaths", JSON.stringify(this.paths));
            layer.msg("导入成功！", { icon: 1, time: 1000 });
          } catch (error) {
            layer.msg("读取数据解析失败！", error);
          }
        } else {
          layer.msg("读取数据解析失败！", error);
        }
      };
    },
    exportPath(id) {
      let path = this.paths.filter((p) => p.id == id)[0];
      let data = JSON.stringify(path, undefined, 4);
      var blob = new Blob([data], { type: "text/json" }),
        e = document.createEvent("MouseEvents"),
        a = document.createElement("a");
      a.download = path.name + ".json";
      a.href = window.URL.createObjectURL(blob);
      a.dataset.downloadurl = ["text/json", a.download, a.href].join(":");
      e.initMouseEvent(
        "click",
        true,
        false,
        window,
        0,
        0,
        0,
        0,
        0,
        false,
        false,
        false,
        false,
        0,
        null
      );
      a.dispatchEvent(e);
    },
    deletePath(id) {
      this.paths = this.paths.filter((p) => p.id != id);
      // 更新本地的 paths
      localStorage.setItem("localPaths", JSON.stringify(this.paths));
      if (this.currId == id) {
        window.pathSource.entities.removeAll();
      }
    },
    editPath(id) {
      this.showCoord = true;
      let path = this.paths.filter((p) => p.id == id)[0];
      this.currPath = { ...path };
    },
    changPath() {
      this.showCoord = false;
      // 更新
      localStorage.setItem("localPaths", JSON.stringify(this.paths));
      console.log(this.currPath);
    },
    clearDraw() {
      window.pathSource.entities.removeAll();
      if (this.handler) {
        this.handler.destroy();
      }
    },
    addPath() {
      // 清空绘制的路径
      window.pathSource.entities.removeAll();

      let that = this;
      let tempPoints = []; //保存点的集合
      let isAddPoint = false; //是否添加了点
      let tempEntities = []; //用来保存路径上的点实体和线实体

      // viewer.scene.globe.depthTestAgainstTerrain = true;// 开启深度检测
      document.getElementById("path-viewer").style.cursor = "crosshair";
      let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); //事件实例
      this.handler = handler;
      //鼠标移动事件
      handler.setInputAction( (movement)=> {
        let tooltip = document.getElementById("tooltip");
        tooltip.style.display = "block";
        tooltip.style.left = movement.endPosition.x + 80 + "px";
        tooltip.style.top = movement.endPosition.y + "px";
        let car3 = viewer.scene.pickPosition(movement.endPosition);

        //当鼠标在一些Entity上时，car3会是undefined
        if (tempPoints.length > 0 && Cesium.defined(car3)) {
          let carto = this.cartesianToLnglat(car3);
          if (!window.lineEntity || isAddPoint) {
            isAddPoint = false;
            console.log([...tempPoints, [...carto, 8]]);
            window.lineEntity &&
              window.pathSource.entities.remove(window.lineEntity);
            window.lineEntity = that.drawPolyline([
              ...tempPoints,
              [...carto, 8],
            ]);
          }
          let positions = window.lineEntity.polyline.positions.getValue();

          positions[positions.length - 1].x = car3.x;
          positions[positions.length - 1].y = car3.y;
          positions[positions.length - 1].z = car3.z;
          window.lineEntity.polyline.positions = new Cesium.CallbackProperty(
            function () {
              return positions;
            },
            false
          );
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
      //左键点击操作
      handler.setInputAction( (click)=> {
        isAddPoint = true;
        //调用获取位置信息的接口
        let ray = viewer.camera.getPickRay(click.position);
        let position = viewer.scene.globe.pick(ray, viewer.scene);

        //将笛卡尔三维坐标转为地图坐标（弧度）
        var cartographic =
          viewer.scene.globe.ellipsoid.cartesianToCartographic(position);
        var lat_String = Cesium.Math.toDegrees(cartographic.latitude).toFixed(
          6
        );
        var log_String = Cesium.Math.toDegrees(cartographic.longitude).toFixed(
          6
        );
        tempPoints.push([Number(log_String), Number(lat_String), 8]);

        // tempPoints.push(position);
        let tempLength = tempPoints.length;
        //调用绘制点的接口
        let point = that.drawPoint(tempPoints[tempLength - 1]);
        tempEntities.push(point);
        if (tempLength > 1) {
          let pointline = that.drawPolyline([
            tempPoints[tempPoints.length - 2],
            tempPoints[tempPoints.length - 1],
          ]);
          tempEntities.push(pointline);
        } else {
          // tooltip.innerHTML = "请绘制下一个点，右键结束";
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
      //右键点击操作
      handler.setInputAction( (click) =>{
        that.currId = this.uuid(8);
        that.$set(that.paths, that.paths.length, {
          id: that.currId,
          name: "未命名-" + new Date().Format("hhmmss"),
          coords: [...tempPoints],
          playing: false,
        });
        // 将轨迹数据保存到本地的 localStorage 中
        localStorage.setItem("localPaths", JSON.stringify(that.paths));
        tempPoints = [];
        handler.destroy(); //关闭事件句柄
        handler = null;
        window.pathSource.entities.remove(window.lineEntity);
        window.lineEntity = null;
        let tooltip = document.getElementById("tooltip");
        tooltip.style.display = "none";
        document.getElementById("path-viewer").style.cursor = "default";
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    },
    drawPoint(coords, config) {
      let config_ = config ? config : {};
      return window.pathSource.entities.add({
        name: "点几何对象",
        // position: position,
        position: Cesium.Cartesian3.fromDegrees(
          coords[0],
          coords[1],
          coords[2]
        ),
        point: {
          color: Cesium.Color.SKYBLUE,
          pixelSize: 10,
          outlineColor: Cesium.Color.YELLOW,
          outlineWidth: 3,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
          // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        },
      });
    },
    drawPolyline(positions, config_) {
      if (positions.length < 1) return;
      let config = config_ ? config_ : {};
      return window.pathSource.entities.add({
        name: "线几何对象",
        polyline: {
          // positions: positions,
          positions: new Cesium.CallbackProperty(function () {
            return Cesium.Cartesian3.fromDegreesArrayHeights(positions.flat(3));
          }, false),
          width: config.width ? config.width : 5.0,
          material: new Cesium.PolylineGlowMaterialProperty({
            color: config.color
              ? new Cesium.Color.fromCssColorString(config.color)
              : Cesium.Color.GOLD,
          }),
          depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
            color: config.color
              ? new Cesium.Color.fromCssColorString(config.color)
              : Cesium.Color.GOLD,
          }),
          // clampToGround: true,
        },
      });
    },
    // clearPath(){
    //   if(window.entity){
    //     viewer.entities.remove(window.entity);
    //   }
    //   window.pointEntities.forEach(entity=>{
    //     viewer.entities.remove(entity);
    //   });
    //   window.pointEntities = [];
    //   this.pointPositionList=[];
    // },
    stopFly(id) {
      // 获取轨迹对象
      let path = this.paths.filter((p) => p.id == id)[0];
      path.playing = false;
      window.pathSource.show = true;
      viewer.trackedEntity = null;
      viewer.clock.shouldAnimate = false;
    },
    flyPath(id) {
      this.currId = id;
      // 获取轨迹对象
      let path = this.paths.filter((p) => p.id == id)[0];
      let coords = path.coords;
      // 清空绘制的路径
      window.pathSource.entities.removeAll();
      // 设置时间
      this.initTimeline(coords.length - 1);
      // 设置坐标的时间，使用 SampledPositionProperty进行插值
      let positions = this.getPositionProperty(coords);
      let orientation = new Cesium.VelocityOrientationProperty(positions);

      // 创建轨迹实体
      !window.flyEntity && (window.flyEntity = {});
      let flyEntity = window.pathSource.entities.add({
        show: true,
        //Set the entity availability to the same interval as the simulation time.
        availability: new Cesium.TimeIntervalCollection([
          new Cesium.TimeInterval({
            start: this.start,
            stop: this.stop,
          }),
        ]),
        //使用计算的位置
        position: positions,
        //Automatically compute orientation based on position movement.
        orientation: orientation,
        //Load the Cesium plane model to represent the entity
        model: {
          show: true,
          uri: "/assets/region/models/CesiumAir/Cesium_Air.glb",
          minimumPixelSize: 64,
        },
        path: {
          resolution: 1,
          material: new Cesium.PolylineGlowMaterialProperty({
            glowPower: 0.1,
            color: Cesium.Color.YELLOW,
          }),
          width: 10,
        },
      });
      window.flyEntity[id] = flyEntity;

      //监听时间变化,【关键代码】。保存返回值，是一个移除事件的回调函数
      this.tickCallBack && this.tickCallBack();
      this.tickCallBack = viewer.clock.onTick.addEventListener((e) => {
        if (viewer.clock.shouldAnimate === true) {
          let ori = orientation.getValue(viewer.clock.currentTime); //获取偏向角
          let center = positions.getValue(viewer.clock.currentTime); //获取位置
          let transform = Cesium.Matrix4.fromRotationTranslation(
            Cesium.Matrix3.fromQuaternion(ori),
            center
          ); //将偏向角转为3*3矩阵，利用实时点位转为4*4矩阵
          viewer.camera.lookAtTransform(
            transform,
            new Cesium.Cartesian3(-10, 0, 0)
          ); //将相机向后面放一点
        }
      });
      // 修改飞行状态
      path.playing = true;
      // 飞行的时候隐藏轨迹相关的实体
      window.pathSource.show = false;
      viewer.trackedEntity = window.flyEntity[id];
      viewer.clock.shouldAnimate = true;
    },
    hidePath() {
      this.pathVisible = !this.pathVisible;
      if (window.entity) {
        window.entity.show = this.pathVisible;
      }
      window.pointEntities.forEach((entity) => {
        entity.show = this.pathVisible;
      });
    },
    initTimeline(len) {
      var start = Cesium.JulianDate.fromDate(new Date("2022-10-9"));
      var stop = Cesium.JulianDate.addSeconds(
        start,
        len,
        new Cesium.JulianDate()
      );
      this.start = start;
      this.stop = stop;
      //Make sure viewer is at the desired time.
      viewer.clock.startTime = start.clone();
      viewer.clock.stopTime = stop.clone();
      viewer.clock.currentTime = start.clone();
      viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end
      viewer.clock.multiplier = 0.06;
      //Set timeline to simulation bounds
      viewer.timeline.zoomTo(start, stop);
      viewer.clock.shouldAnimate = false;
    },
    getPositionProperty(coords) {
      // 给轨迹点关联时间和插值
      const property = new Cesium.SampledPositionProperty();
      for (var i = 0; i < coords.length; i++) {
        var time = Cesium.JulianDate.addSeconds(
          this.start,
          i,
          new Cesium.JulianDate()
        );
        var position = Cesium.Cartesian3.fromDegrees(
          coords[i][0],
          coords[i][1],
          coords[i][2]
        );
        property.addSample(time, position);
        window.pathSource.entities.add({
          position: position,
          point: {
            color: Cesium.Color.SKYBLUE,
            pixelSize: 10,
            outlineColor: Cesium.Color.YELLOW,
            outlineWidth: 3,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
            // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          },
        });
      }
      return property;
    },
    readyPath() {
      // 给轨迹点关联时间和插值
      const property = new Cesium.SampledPositionProperty();
      property.setInterpolationOptions({
        interpolationDegree: 5,
        interpolationAlgorithm: Cesium.HermitePolynomialApproximation, //设置插值算法
      });
      for (var i = 0; i < this.pointPositionList.length; i++) {
        var time = Cesium.JulianDate.addSeconds(
          this.start,
          i,
          new Cesium.JulianDate()
        );
        var position = Cesium.Cartesian3.fromArray(this.pointPositionList[i]);
        property.addSample(time, position);
      }
      this.position = property;
      this.orientation = new Cesium.VelocityOrientationProperty(property);
    },
    createModel() {
      //Actually create the entity
      if (window.entity) {
        viewer.entities.remove(window.entity);
        window.entity = null;
      }
      window.entity = viewer.entities.add({
        //Set the entity availability to the same interval as the simulation time.
        availability: new Cesium.TimeIntervalCollection([
          new Cesium.TimeInterval({
            start: this.start,
            stop: this.stop,
          }),
        ]),
        //Use our computed positions
        position: this.position,
        //Automatically compute orientation based on position movement.
        orientation: this.orientation,
        model: {
          uri: "./models/CesiumAir/Cesium_Air.glb",
          minimumPixelSize: 64,
          show: false,
        },
        //Show the path as a pink line sampled in 1 second increments.
        path: {
          resolution: 10,
          material: new Cesium.PolylineGlowMaterialProperty({
            width: 30,
            // glowPower: 0.1,
            color: Cesium.Color.fromCssColorString("rgba(230,163,60,1)"),
          }),
          width: 10,
        },
      });
      // window.entity = entity;
      //追踪物体
      // viewer.trackedEntity = entity;
    },
    palyPath() {
      this.playing = !this.playing;
      viewer.trackedEntity = this.playing ? window.entity : null;
      viewer.clock.shouldAnimate = this.playing;
    },
    handlerPath() {
      this.isAddStatus = !this.isAddStatus;
      if (this.isAddStatus) {
        // 清空坐标点
        (this.pointPositionList = []), //点位置坐标数组
          (window.pointEntities = []),
          this.registerEvent();
      } else {
        window.pointEntities.forEach((entity) => {
          viewer.entities.remove(entity);
        });
        window.pointEntities = [];
        this.cancelEvent();
        window.entitiy && viewer.entities.remove(window.entitiy);
        window.entitiy = null;
        viewer.trackedEntity = null;
        document.getElementsByTagName("body").item(0).style.cursor = "default";
      }

      // 关闭双击事件
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
        Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
      );
    },
    registerEvent() {
      this.addMouseListener();
      this.addMouseClick(); // 地图鼠标左键单击事件
      this.addMouseRightClick();
      this.addClockEvent();
    },
    cancelEvent() {
      this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除事件
      this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE); //移入事件
      this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK); //右击事件
    },
    addClockEvent() {
      // let handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
      // handler.setInputAction((movement) => {
      //   let pick = scene.pick(movent.position);
      //   // if(){

      //   // }
      // }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
      //监听时间变化
      viewer.clock.onTick.addEventListener((e) => {
        if (viewer.clock.shouldAnimate === true) {
          let ori = this.orientation.getValue(viewer.clock.currentTime); //获取偏向角
          let center = this.position.getValue(viewer.clock.currentTime); //获取位置
          let transform = Cesium.Matrix4.fromRotationTranslation(
            Cesium.Matrix3.fromQuaternion(ori),
            center
          ); //将偏向角转为3*3矩阵，利用实时点位转为4*4矩阵
          viewer.camera.lookAtTransform(
            transform,
            new Cesium.Cartesian3(-1, 0, 0)
          ); //将相机向后面放一点
          // viewer.camera.lookAtTransform(transform);
        }
      });
    },
    // 鼠标左侧单击事件
    addMouseClick() {
      let that = this;
      that.handler.setInputAction(function (movement) {
        console.log("========单击事件========");
        // 添加区域情况
        if (that.isAddStatus) {
          // 平面坐标(x,y)
          let windowPosition = movement.position;
          // 三维坐标（x,y,z）
          let ellipsoid = viewer.scene.globe.ellipsoid;
          let cartesian = viewer.camera.pickEllipsoid(
            windowPosition,
            viewer.scene.globe.ellipsoid
          );
          // 坐标转换:世界坐标转换为经纬度
          let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
          let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
          let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
          // 经度在前纬度在后
          // that.pointPositionList.push([Number(lng.toFixed(6)),Number(lat.toFixed(6)),30]);
          that.pointPositionList.push([
            cartesian.x,
            cartesian.y,
            cartesian.z + 20,
          ]);
          if (!cartesian) {
            return;
          }
          // 实例化点实体
          let point = viewer.entities.add({
            name: "gon_point",
            position: new Cesium.Cartesian3(
              cartesian.x,
              cartesian.y,
              cartesian.z + 20
            ),
            point: {
              color: Cesium.Color.WHITE,
              pixelSize: 10,
              outlineColor: Cesium.Color.BLACK,
              outlineWidth: 1,
            },
          });
          window.pointEntities.push(point);

          if (window.pointEntities.length > 1) {
            that.initTimeline();
            that.readyPath();
            that.createModel();
          }
          // 存储点的实体，用于下图
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },
    // 鼠标移入事件，添加状态改变鼠标光标
    addMouseListener() {
      let that = this;
      // const handler = new Cesium.ScreenSpaceEventHandler(
      //   viewer.scene.canvas
      // );
      that.handler.setInputAction(function (movement) {
        console.log("========移入事件========");
        if (that.isAddStatus) {
          document.getElementsByTagName("body").item(0).style.cursor =
            "pointer";
        } else {
          document.getElementsByTagName("body").item(0).style.cursor =
            "default";
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    },
    // 鼠标右击事件，添加状态改变鼠标光标
    addMouseRightClick() {
      let that = this;
      that.handler.setInputAction(function (movement) {
        console.log("========右击事件========");
        // 结束区域查询
        that.isAddStatus = false;
        that.cancelEvent();
        document.getElementsByTagName("body").item(0).style.cursor = "default";
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    },
  },
};
</script>

<style lang='stylus' scoped>
#path-viewer {
  height: 80vh;
  width: 100%;
}

.path-container {
  position: absolute;
  top: 70px;
  left: 70px;
}

.path-container .box-card {
  width: 250px;
}

.fly-box {
  padding-top: 44px;
  padding-bottom: 10px;
  width: 300px;
  z-index: 900;
  // right: 10px;
  // left: 59px;
  position: absolute;
  box-sizing: border-box;
  z-index: 999 !important;
  z-index: 100;
  border-bottom: 1px solid #008aff70;
  border-left: 1px solid #008aff70;
  border-right: 1px solid #008aff70;
  box-shadow: 0 4px 15px 1px #02213bb3;
  border-radius: 0;
  background: linear-gradient(to left, #ffffff, #ffffff) left bottom no-repeat, linear-gradient(to bottom, #ffffff, #ffffff) left bottom no-repeat, linear-gradient(to left, #ffffff, #ffffff) right bottom no-repeat, linear-gradient(to left, #ffffff, #ffffff) right bottom no-repeat;
  background-size: 1px 10px, 10px 1px, 1px 10px, 10px 1px;
  background-color: rgba(22, 51, 76, 0.8) !important;
}

.fly-title {
  height: 44px;
  width: 100%;
  line-height: 44px;
  overflow: hidden;
  height: 41px;
  line-height: 41px;
  background: url('http://mars3d.cn/project/vue/assets/msg-title-bg.53c38de6.png'); // mars3d.cn/project/vue/assets/msg-title-bg.53c38de6.png);
  background-size: 10px 44px;
  padding: 0 5px 0 10px;
  color: #fff;
  position: absolute;
  top: 0;
  left: 0;
  box-sizing: border-box;
  font-size: 16px;
}

.fly-title i {
  float: right;
  margin-right: 10px;
  cursor: pointer;
  line-height: 40px;
}

.fly-content {
  height: 100%;
  overflow: auto;
  padding: 5px 15px;
}

.fly-operation {
  text-align: center;
  margin-bottom: 10px;
  padding-top: 10px;
}

.fly-operation button {
  height: 32px;
  background: rgba(0, 138, 255, 0.5);
  border: none;
  padding-left: 10px;
  padding-right: 10px;
  color: #fff;
  cursor: pointer;
}

.fly-operation button i {
  padding: 0 5px;
  cursor: pointer;
}

.fly-table {
  clear: both;
  max-width: 100%;
  box-sizing: border-box;
  position: relative;
  transition: opacity 0.3s;
  color: #cdcdcd;
  font-size: 12px;
  border: solid 1px;
  border-color: #0b67b7;
  border-top-color: #c1c1d5;
  min-height: 180px;
}

.fly-table table {
  width: 100%;
  border-spacing: 0;
  border-collapse: separate;
}

.fly-table table td, fly-table table th {
  padding: 10px;
}

.fly-table-header {
  background: rgba(0, 138, 255, 0.2);
  /* text-align: left; */
  height: 32px;
}

.fly-table-body {
  background: rgba(22, 51, 76, 0.5);
  color: white;
}

.fly-table-body input {
  color: white;
  background: transparent;
  border: none;
}

.fly-table-operation {
  text-align: center;
}

.fly-table-operation i {
  padding: 0 2px;
  cursor: pointer;
}

.fly-tab-coord {
  color: white;
  padding: 5px;
}

.fly-tab-coord .title-box {
  font-size: 15px;
  padding: 5px;
}

.fly-tab-coord .path-coord {
  padding: 5px;
  border: solid 1px #295f8f;
}

.fly-tab-coord .fly-coord-content {
  max-height: 520px;
  overflow: auto;
}

.fly-tab-coord .path-coord input {
  color: white;
  background: transparent;
  width: 100px;
}

.fly-tab-coord .coord-btn {
  text-align: center;
  margin-top: 5px;
}

.fly-tab-coord .coord-btn button {
  padding: 3px 10px;
  font-size: 12px;
  margin: 0 10px;
  color: white;
  background: rgba(120, 255, 53, 0.3);
  border: none;
}

.handle {
  box-sizing: border-box;
  position: absolute;
  z-index: 1;
  width: 10px;
  height: 10px;
  opacity: 0;
}

.handle-l {
  height: auto;
  top: 10px;
  left: 0;
  bottom: 10px;
}

.handle-r {
  height: auto;
  top: 10px;
  right: 0;
  bottom: 10px;
}
/deep/.cesium-viewer-timelineContainer{
    display: none !important;
}
.handle-t {
  width: auto;
  top: 0;
  left: 10px;
  right: 10px;
}

.handle-b {
  width: auto;
  bottom: 0;
  left: 10px;
  right: 10px;
}

.handle-lb {
  bottom: 0;
  left: 0;
}

.handle-rb {
  bottom: 0;
  right: 0;
}
</style>