cesium 如何用Primitive来实现根据websocket实时发送的经纬度,利用primitive来实现绘制轨迹线和轨迹点?

function webValue() {
  // 初始Websocket
  const onOpen = () => {
    const data = JSON.stringify({ command: 1, serializeAlgorithm: 1, token: window.localStorage.getItem('token') });
    ws.send(data); // 发送JSON字符串
    // 设置心跳间隔为5秒
    pingInterval.value = window.setInterval(() => {
      const pingMessage = JSON.stringify({
        command: 2,
        serializeAlgorithm: 1
      });
      ws.send(pingMessage);
    }, 5000);
  };
  if (window.localStorage.getItem('CardUID') === null) {
    return ElMessage({
      message: '车辆终端ID未绑定,请点击右上角的“设置”图标进行绑定。',
      type: 'warning',
      showClose: true
    });
  }
  // 接收websocket数据
  const onMessage = async (event) => {
    const data = JSON.parse(event.data);
    if (data.data == undefined) {
      console.log('未响应');
    } else {
      processPositionParams(data.data);
    }
  };
  // 封装处理位置参数的函数
  const positionParams = []; // 用于存储所有的位置参数数据
  const bufferLimit = 50; // 缓冲区大小限制,可以根据需求调整
  function processPositionParams(data) {
    const targetingTypes = {
      0x10: 'RTK',
      0x11: 'UWB',
      0x12: '融合'
    };
    const newPositionParam = {
      TargetingType: targetingTypes[data.type],
      UID: data.uid,
      Angle: data.angle,
      Height: data.height,
      longitude: data.longitude,
      latitude: data.latitude
    };
    positionParams.push(newPositionParam);
    // 超过缓冲区大小限制时移除最旧的位置参数数据
    if (positionParams.length > bufferLimit) {
      positionParams.shift();
    }
    const labelText = `终端ID:${data.uid},定位类型:${targetingTypes[data.type]}\n经度:${data.longitude},纬度:${data.latitude}\n角度:${data.angle},高度:${data.height}`;
    CarModel(positionParams, newPositionParam.Angle, data.uid); // 车辆模型
    pointPolyline(positionParams, labelText, data.uid) // 轨迹点和轨迹线
  }
  const onClose = () => {
    window.clearInterval(pingInterval.value); // 清除心跳间隔定时器
    console.log('Websocket连接关闭');
    webValue();
  };
  const onError = (error) => {
    console.log('Websocket连接错误');
    ws.close();
    window.clearInterval(pingInterval.value); // 清除心跳间隔定时器
    webValue();
  };
  ws.addEventListener('open', onOpen);
  ws.addEventListener('message', onMessage);
  ws.addEventListener('close', onClose);
  ws.addEventListener('error', onError);
}
------------------------------------------------------------------------------------------
let polylineEntity = null;
let entityList = [];
let positionsArray = [];
function pointPolyline(positions, labelText, uid) {
  const cartesian3Array = [];
  positionsArray = positions.flatMap(pos => [pos.longitude, pos.latitude]);
  // 移除之前的实体点
  for (const entity of entityList) {
    viewer.entities.remove(entity);
  }
  entityList = [];
  for (const position of positions) {
    let entityIndex = entityList.length;
    const cartesian3 = Cesium.Cartesian3.fromDegrees(
      position.longitude,
      position.latitude,
      0.02
    );
    const pointLabel = new Cesium.Entity({
      position: cartesian3,
      point: {
        pixelSize: 10,
        color: Cesium.Color.BLUE,
        show: checkedPoint.value,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 1,
      },
      label: {
        text: labelText,
        font: '14pt monospace',
        show: new Cesium.CallbackProperty(() => {
          return entityIndex === entityList.length - 1;
        }, false),
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        outlineWidth: 2,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        pixelOffset: new Cesium.Cartesian2(0, -9),
        fillColor: Cesium.Color.WHITE,//标签的文本填充颜色。
        outlineColor: Cesium.Color.WHITE,//标签的文本轮廓颜色。
      },
    });
    entityList.push(pointLabel);
    viewer.entities.add(pointLabel);
    cartesian3Array.push(cartesian3);
  }

  // 更新轨迹线位置
  if (polylineEntity) {
    polylineEntity.polyline.positions = new Cesium.CallbackProperty(() => {
      return Cesium.Cartesian3.fromDegreesArray(positionsArray);
    }, false);
    polylineEntity.polyline.show = checkedLines.value;
  } else {
    // 创建新的轨迹线
    polylineEntity = viewer.entities.add({
      polyline: {
        positions: new Cesium.CallbackProperty(() => {
          return Cesium.Cartesian3.fromDegreesArray(positionsArray);
        }, false),
        width: 15,
        material: Cesium.Color.RED,
      },
    });
  }
}

大佬们,请问如何根据websocket实时返回的数据,如何通过new Cesium.Primitive()进行绘制点和线,并且如何让websocket里面的pointPolyline()和CarModel()函数使其不是每次都会在websocket里面调用,而只是实时更新数据?

阅读 4.1k
1 个回答
const viewer = new Cesium.Viewer('cesiumContainer');

let primitive = null;
let geometryInstances = [];

function webValue() {
  const ws = new WebSocket('ws://your-websocket-url');

  const onOpen = () => {
    // 
    // ...
  };

  const onMessage = (event) => {

    const data = JSON.parse(event.data);
    // 更新geometryInstances数组
    // ...

    viewer.scene.primitives.remove(primitive);

    primitive = new Cesium.Primitive({
      geometryInstances: geometryInstances,
      appearance: new Cesium.PerInstanceColorAppearance(),
    });
    viewer.scene.primitives.add(primitive);
  };

  const onClose = () => {
   
    // ...
  };

  const onError = (error) => {
    
    // ...
  };

  ws.addEventListener('open', onOpen);
  ws.addEventListener('message', onMessage);
  ws.addEventListener('close', onClose);
  ws.addEventListener('error', onError);
}


function updateGeometryInstances() {
  geometryInstances = [
    new Cesium.GeometryInstance({
      geometry: new Cesium.PointGeometry({
        positions: Cesium.Cartesian3.fromDegreesArray([
          // 经度,纬度
          116.0, 40.0,
          117.0, 41.0,
          // ... 更多点
        ]),
      }),
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED),
      },
    }),
    new Cesium.GeometryInstance({
      geometry: new Cesium.PolylineGeometry({
        positions: Cesium.Cartesian3.fromDegreesArray([
          // 经度,纬度
          116.0, 40.0,
          117.0, 41.0,
          // ... 更多点
        ]),
        width: 5.0,
      }),
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE),
      },
    }),
  ];
}

updateGeometryInstances();
webValue();
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题