Cesium使用glb模型、图片标记来实现实时轨迹

目录

1、使用glb模型进行实时轨迹 

2、使用图片进行实时轨迹 


基于上一篇加载基础地图的代码上继续开发

vue中加载Cesium地图(天地图、高德地图)-CSDN博客文章浏览阅读164次。vue中加载Cesium三维地球https://blog.csdn.net/ssy001128/article/details/148474799继续在cesium.js中加入需要实现的功能函数方法

 经纬度数据

let interval = null
let coordinateData = [
  {
    lon: 110,
    lat: 30,
    id: "0",
    name: "traject0",
  },
  {
    lon: 110.2,
    lat: 30,
    id: "1",
    name: "traject1",
  },
  {
    lon: 110.4,
    lat: 30.2,
    id: "2",
    name: "traject2",
  },
  {
    lon: 110.8,
    lat: 30.4,
    id: "3",
    name: "traject3",
  },
  {
    lon: 111,
    lat: 31,
    id: "4",
    name: "traject4",
  },
  {
    lon: 111.3,
    lat: 31,
    id: "5",
    name: "traject5",
  },
  {
    lon: 111.6,
    lat: 31,
    id: "6",
    name: "traject6",
  },
  {
    lon: 111.9,
    lat: 31,
    id: "7",
    name: "traject7",
  },
  {
    lon: 112,
    lat: 31,
    id: "8",
    name: "traject8",
  },
  {
    lon: 112.3,
    lat: 31,
    id: "9",
    name: "traject9",
  },
  {
    lon: 112.5,
    lat: 31,
    id: "10",
    name: "traject10",
  },
  {
    lon: 112.8,
    lat: 31,
    id: "11",
    name: "traject11",
  },
  {
    lon: 113,
    lat: 31,
    id: "12",
    name: "traject12",
  },
  {
    lon: 114,
    lat: 31,
    id: "13",
    name: "traject13",
  },
  {
    lon: 115.3,
    lat: 32,
    id: "14",
    name: "traject14",
  },
  {
    lon: 115.5,
    lat: 32,
    id: "15",
    name: "traject15",
  },
  {
    lon: 115.8,
    lat: 31.8,
    id: "16",
    name: "traject16",
  },
  {
    lon: 116,
    lat: 31.4,
    id: "17",
    name: "traject17",
  },
  {
    lon: 116.2,
    lat: 31.1,
    id: "18",
    name: "traject18",
  },
  {
    lon: 116.5,
    lat: 30.5,
    id: "19",
    name: "traject19",
  },
  {
    lon: 115,
    lat: 30.2,
    id: "20",
    name: "traject20",
  },
  {
    lon: 114,
    lat: 29.8,
    id: "21",
    name: "traject21",
  },
  {
    lon: 113,
    lat: 29.6,
    id: "22",
    name: "traject22",
  },
  {
    lon: 112,
    lat: 29.4,
    id: "23",
    name: "traject23",
  },
  {
    lon: 111,
    lat: 30.5,
    id: "24",
    name: "traject24",
  },
  {
    lon: 110,
    lat: 30.4,
    id: "25",
    name: "traject25",
  },
  {
    lon: 109,
    lat: 30.6,
    id: "26",
    name: "traject26",
  },
  {
    lon: 108,
    lat: 36,
    id: "27",
    name: "traject27",
  },
];

1、使用glb模型进行实时轨迹 

模型每次位置改变的朝向可能没有那么标准角度

// 添加使用glb模型进行实时轨迹
export function addGlbTrajectory() {
  // 先添加初始线条
  let arr = [coordinateData[0].lon, coordinateData[0].lat];
  let glbEntity = viewer.entities.add({
    name: "GLB模型示例",
    position: Cesium.Cartesian3.fromDegrees(
      coordinateData[0].lon,
      coordinateData[0].lat
    ),
    // 设置模型初始朝向(这里设置为朝北,即heading=0)
    orientation: Cesium.Transforms.headingPitchRollQuaternion(
      Cesium.Cartesian3.fromDegrees(
        coordinateData[0].lon,
        coordinateData[0].lat
      ),
      new Cesium.HeadingPitchRoll(
        Cesium.Math.toRadians(270), // 朝向(heading):0表示朝北,正数为顺时针旋转(东:90,南:180,西:270)
        0, // 俯仰角(pitch):0表示水平
        0 // 横滚角(roll):0表示不倾斜
      )
    ),
    model: {
      uri: "car.glb",
      scale: 2.0,
      minimumPixelSize: 1228,
      maximumScale: 20000,
      incrementallyLoadTextures: true,
      clampAnimations: true,
      shadows: Cesium.ShadowMode.ENABLED,
    },
  });
  // viewer.trackedEntity = glbEntity;
  let i = 0;
  interval = setInterval(() => {
    // 当数组下标还有数据时
    if (coordinateData[i + 1]) {
      arr.push(coordinateData[i + 1].lon, coordinateData[i + 1].lat);

      // 获取当前点和下一点的坐标
      const currentPos = Cesium.Cartesian3.fromDegrees(
        coordinateData[i].lon,
        coordinateData[i].lat
      );
      const nextPos = Cesium.Cartesian3.fromDegrees(
        coordinateData[i + 1].lon,
        coordinateData[i + 1].lat
      );
      // 更新位置
      glbEntity.position = nextPos;
      // 计算朝向(从当前点指向下一点的方向)
      const heading = -(computeHeading(currentPos, nextPos));

      // 更新朝向
      glbEntity.orientation = Cesium.Transforms.headingPitchRollQuaternion(
        nextPos,
        new Cesium.HeadingPitchRoll(heading, 0, 0)
      );
      // 更新现有模型的位置,而不是创建新模型
      // glbEntity.position = Cesium.Cartesian3.fromDegrees(
      //   coordinateData[i + 1].lon,
      //   coordinateData[i + 1].lat
      // );
      // 轨迹
      viewer.entities.add({
        id: coordinateData[i + 1].id,
        name: coordinateData[i + 1].name,
        polyline: new Cesium.PolylineGraphics({
          positions: Cesium.Cartesian3.fromDegreesArray(arr),
          width: 5, // 线条宽度
          clampToGround: true, // 贴地显示
          material: Cesium.Color.fromCssColorString("#0f0"), // 线条材质颜色
        }),
      });
      i++;
    } else {
      // 已全部获取
      clearInterval(interval);
      interval = null;
    }
  }, 3000);
}

// 计算两点之间的朝向角(弧度)
function computeHeading(start, end) {
  const direction = Cesium.Cartesian3.subtract(
    end,
    start,
    new Cesium.Cartesian3()
  );
  const up = Cesium.Cartesian3.normalize(start, new Cesium.Cartesian3());

  // 计算东方向(垂直于向上方向和北方向)
  const east = Cesium.Cartesian3.cross(
    new Cesium.Cartesian3(0, 0, 1),
    up,
    new Cesium.Cartesian3()
  );
  Cesium.Cartesian3.normalize(east, east);

  // 计算北方向(垂直于东方向和向上方向)
  const north = Cesium.Cartesian3.cross(up, east, new Cesium.Cartesian3());

  // 计算方向向量在水平面(东-北平面)上的投影
  const horizontalDirection = new Cesium.Cartesian3();
  Cesium.Cartesian3.subtract(
    direction,
    Cesium.Cartesian3.multiplyByScalar(
      up,
      Cesium.Cartesian3.dot(direction, up),
      new Cesium.Cartesian3()
    ),
    horizontalDirection
  );
  Cesium.Cartesian3.normalize(horizontalDirection, horizontalDirection);

  // 计算朝向角(从北方向顺时针旋转的角度)
  const dot = Cesium.Cartesian3.dot(north, horizontalDirection);
  const cross = Cesium.Cartesian3.dot(east, horizontalDirection);
  return Math.atan2(cross, dot);
}

 

glb模型实时轨迹

2、使用图片进行实时轨迹 

111.png

Cesium使用glb模型、图片标记来实现实时轨迹_第1张图片

// 使用图片进行实时轨迹
export function addImgTrajectory() {
  // 先添加初始线条
  let arr = [coordinateData[0].lon, coordinateData[0].lat];

  // 添加一个Billboard作为标记
  let billboards  = new Cesium.BillboardGraphics({
      image: "111.png", // 图片路径
      width: 50, // 图片宽度
      height: 50, // 图片高度
      rotation: 0
    })
  let glbEntity = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(110, 30.0), // 经纬度坐标
    billboard: billboards
  });

  let i = 0;
  interval = setInterval(() => {
    // 当数组下标还有数据时
    if (coordinateData[i + 1]) {
      arr.push(coordinateData[i + 1].lon, coordinateData[i + 1].lat);

      // 更改图片位置
      // 更新现有模型的位置,而不是创建新模型
      glbEntity.position = Cesium.Cartesian3.fromDegrees(
        coordinateData[i + 1].lon,
        coordinateData[i + 1].lat
      );

      let arc = 0;
      if (
        (coordinateData[i + 1].lon - coordinateData[i].lon >= 0 &&
          coordinateData[i + 1].lat - coordinateData[i].lat >= 0) ||
        (coordinateData[i + 1].lon - coordinateData[i].lon < 0 &&
          coordinateData[i + 1].lat - coordinateData[i].lat > 0)
      ) {
        arc = Math.atan(
          (coordinateData[i + 1].lon - coordinateData[i].lon) /
            (coordinateData[i + 1].lat - coordinateData[i].lat)
        );
      } else if (
        (coordinateData[i + 1].lon - coordinateData[i].lon > 0 &&
          coordinateData[i + 1].lat - coordinateData[i].lat < 0) ||
        (coordinateData[i + 1].lon - coordinateData[i].lon < 0 &&
          coordinateData[i + 1].lat - coordinateData[i].lat < 0)
      ) {
        arc =
          Math.PI +
          Math.atan(
            (coordinateData[i + 1].lon - coordinateData[i].lon) /
              (coordinateData[i + 1].lat - coordinateData[i].lat)
          );
      }
      // 更新图片朝向
      glbEntity.billboard.rotation._value = -(arc)

      // 轨迹
      viewer.entities.add({
        id: coordinateData[i + 1].id,
        name: coordinateData[i + 1].name,
        polyline: new Cesium.PolylineGraphics({
          positions: Cesium.Cartesian3.fromDegreesArray(arr),
          width: 5, // 线条宽度
          clampToGround: true, // 贴地显示
          material: Cesium.Color.fromCssColorString("#0f0"), // 线条材质颜色
        }),
      });
      i++;
    } else {
      // 已全部获取
      clearInterval(interval);
      interval = null;
    }
  }, 1000);
}

 

图片实时轨迹

你可能感兴趣的:(Cesium相关,vue.js,前端,javascript)