请问大佬们,后台通过websocket发送的实时经纬度数据?

 // 接收websocket数据
  const onMessage = async (event) => {
    const data = JSON.parse(event.data);
    if (data.data == undefined) {
      console.log('未响应');
    } else {
      processPositionParams(data.data);
    }
  };
  // 封装处理位置参数的函数
  const positionParams = ref([]); // 用于存储所有的位置参数数据
  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.value.push(newPositionParam);
    const labelText = `终端ID:${data.uid},定位类型:${targetingTypes[data.type]}\n经度:${data.longitude},纬度:${data.latitude}\n角度:${data.angle},高度:${data.height}`;
    CarModel(positionParams.value, newPositionParam.Angle); // 车辆模型
    pointPolyline(positionParams.value, labelText) //轨迹点和轨迹线
  }

图片.png
通过这段代码接收的websocket返回的数据,当我通过websocket实时的返回经纬度去显示轨迹点和轨迹线,发送的数据没多久就会导致页面很卡?请问如何解决这个问题呢?求大佬们指教谢谢~

更新的代码

  // 接收websocket数据
  const onMessage = async (event) => {
    const data = JSON.parse(event.data);
    if (data.data == undefined) {
      console.log('未响应');
    } else {
      processPositionParams(data.data);
    }
  };
  // 封装处理位置参数的函数
  const positionParams = ref([]); // 用于存储所有的位置参数数据
  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.value.push(newPositionParam);
    // 超过缓冲区大小限制时移除最旧的位置参数数据
    if (positionParams.value.length > bufferLimit) {
      positionParams.value.shift();
    }
    const labelText = `终端ID:${data.uid},定位类型:${targetingTypes[data.type]}\n经度:${data.longitude},纬度:${data.latitude}\n角度:${data.angle},高度:${data.height}`;
    CarModel(positionParams.value, newPositionParam.Angle); // 车辆模型
    pointPolyline(positionParams.value, labelText) // 轨迹点和轨迹线
  }
// 轨迹点  和  轨迹线   和  标签文字
function pointPolyline(positions, labelText) {
  const cartesian3Array = [];
  // 移除之前的实体
  for (const entity of entityList.value) {
    viewer.value.entities.remove(entity);
  }
  entityList.value = [];
  for (const position of positions) {
    let entityIndex = entityList.value.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.value.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.value.push(pointLabel);
    viewer.value.entities.add(pointLabel);
    cartesian3Array.push(cartesian3);
  }
  // 添加轨迹线
  viewer.value.entities.add({
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray(
        positions.flatMap(pos => [pos.longitude, pos.latitude])
      ),
      width: 15,
      show: checkedLines.value,
      material: Cesium.Color.RED,
    },
  });
}

图片.png

阅读 2.9k
3 个回答

先用浏览器的性能工具(Chrome的Performance tab)来分析具体的性能问题。看一下操作到哪里造成的,
优化一下轨迹线实体,你那样每次都要新建,增加浏览器负荷

// 定义轨迹线实体
let polylineEntity = null;

function pointPolyline(positions, labelText) {
  const cartesian3Array = [];
  // 移除之前的实体
  for (const entity of entityList.value) {
    viewer.value.entities.remove(entity);
  }
  entityList.value = [];

  for (const position of positions) {
    let entityIndex = entityList.value.length;
    const cartesian3 = Cesium.Cartesian3.fromDegrees(
      position.longitude,
      position.latitude,
      0.02
    );
    const pointLabel = new Cesium.Entity({
      // ... 属性
    });
    entityList.value.push(pointLabel);
    viewer.value.entities.add(pointLabel);
    cartesian3Array.push(cartesian3);
  }

  if (!polylineEntity) {
    polylineEntity = viewer.value.entities.add({
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray(
          positions.flatMap(pos => [pos.longitude, pos.latitude])
        ),
        width: 15,
        show: checkedLines.value,
        material: Cesium.Color.RED,
      },
    });
  } else {
    // 否则,只更新轨迹线的位置
    polylineEntity.polyline.positions = Cesium.Cartesian3.fromDegreesArray(
      positions.flatMap(pos => [pos.longitude, pos.latitude])
    );
  }
}

解决闪烁的问题:

let polylineEntity = viewer.value.entities.add({
  polyline: {
    positions: [],
    width: 15,
    material: Cesium.Color.RED,
  },
});

function pointPolyline(positions, labelText) {
  // ... 

  // 更新轨迹线的位置
  polylineEntity.polyline.positions = Cesium.Cartesian3.fromDegreesArray(
    positions.flatMap(pos => [pos.longitude, pos.latitude])
  );

  // 更新轨迹线的显示状态
  polylineEntity.polyline.show = checkedLines.value;
}

如果不行的话用用Web Worker

 positionParams.value.push(newPositionParam);

你一直往数组里面push嘛?那内存早晚得崩啊。

 viewer.value.entities

看到你有.vlaue,我估摸着你是把cesium的viewer丢到vue里面,作为一个响应式变量了。
这样每次cesium的视图更新,都会触发vue的proxy监听,巨卡。
其次cesium中渲染的数据量比较大时,应该用primitive而不是entity。

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