Vue+Cesium加载GeoJSON并设置entity.billboard,在组件销毁/释放实体entity时报错

**背景:**Vue+Cesium加载GeoJSON并设置entity.billboard,在组件销毁/释放实体entity时报错:TypeError: Cannot read properties of undefined (reading '_textureAtlas') at Billboard.setImage (webpack-internal:///./node_modules/cesium/Source/Scene/Billboard.js:1268:98)

  async estimate() {
      try {
        // 使用Promise.all来同时处理多个axios请求
        const [floodLayerResponse, alterLayerResponse] = await Promise.all([
          axios.get('/api' + this.featuresLayer.model.floodLayer),
          axios.get('/api' + this.featuresLayer.model.alterLayer)
        ]);

        // 处理floodLayer数据
        const floodDs = await Cesium.GeoJsonDataSource.load(floodLayerResponse.data, {
          clampToGround: true
        });
        viewer.dataSources.add(floodDs);

        floodDs.entities.values.forEach(entity => {
          entity.polygon.outline = false;
          let properties = entity.properties;
          const score = properties['_degree']['_value'];
          let color;
          if (score === 1 || score === 2) {
            color = Cesium.Color.fromCssColorString("#fdfdfd");
          } else if (score === 3 || score === 4 || score === 5) {
            color = Cesium.Color.fromCssColorString("rgba(160,190,253,0.7)");
          } else {
            color = Cesium.Color.fromCssColorString("rgba(6,76,169,0.87)");
          }
          entity.polygon.material = color;
        });

        // 处理alterLayer数据
        alterDs = await Cesium.GeoJsonDataSource.load(alterLayerResponse.data);
        viewer.dataSources.add(alterDs);

        alterDs.entities.values.forEach(entity => {
          if(!entity.billboard){
            entity.billboard=new Cesium.BillboardGraphics();
          }
          entity.billboard = {
            image: picUrl, // 确保url已经被定义
            scale: 2,
            width: 16,
            height: 16,
            pixelOffset: new Cesium.Cartesian2(0, -20)
          };
        });
        this.descriptionVisi=true;

      } catch (error) {
        console.error('Error loading layers:', error);
      }},

释放资源报错: TypeError: Cannot read properties of undefined (reading '_textureAtlas') at Billboard.setImage)

 viewer.entities.removeAll();
 viewer.scene.primitives.removeAll();

将设置了billborad的entities先释放,在释放所有primitives

      //设置了billbord数据需单独先去除,否则报错:TypeError: Cannot read properties of undefined (reading '_textureAtlas')at Billboard.setImage (webpack-internal:///./node_modules/cesium/Source/Scene/Billboard.js:1268:98)
      alterDs.entities.removeAll();
      viewer.scene.primitives.removeAll();
      this

总结:

Cesium 中遇到 TypeError: Cannot read properties of undefined (reading '_textureAtlas') 这类错误通常与尝试访问未正确初始化或已被销毁的对象的属性有关。在你提到的场景中,这个错误发生在尝试设置 Billboardimage 属性时,而该 Billboard 或其相关的资源(如纹理图集 _textureAtlas)可能已经不再有效或未正确加载。

这个问题可能由几个原因引起:

  1. Billboard 已被销毁 :在 Cesium 中,如果你移除了包含 BillboardEntity 或直接从 PrimitiveCollection 中移除了 Billboard,然后尝试再次访问或修改它,就可能导致此类错误。

  2. 资源加载问题 :如果 Billboard 使用的图像资源在尝试设置时没有正确加载,也可能导致内部状态不一致。

  3. Cesium 内部状态问题:在某些极端情况下,Cesium 的内部状态可能因为错误的使用或与其他库的冲突而变得不一致。

解决步骤

  1. 检查 Billboard 的存在性

    在尝试修改 Billboard 之前,确保它仍然存在且未被销毁。你可以通过检查其 isDestroyed() 方法(如果 Cesium 版本支持)或使用简单的条件语句来验证。

    if (billboard && !billboard.isDestroyed()) {
    billboard.image = 'new-image-url.png';
    }

  2. 注意:isDestroyed() 方法可能在某些 Cesium 版本中不可用。

  3. 确保资源已加载

    如果你正在动态更改 Billboard 的图像,请确保新的图像 URL 是有效的,并且图像已经加载到 Cesium 中。你可以使用 Cesium 的 Resource 类或监听图像加载事件来确保图像已准备好。

  4. 安全地移除 Entities

    当你需要移除所有 entities 时,确保你正确地从 Cesium 的 viewer.entities 中移除了它们。你可以遍历并逐个移除,或者如果可能,直接清空整个集合(注意,直接清空可能会导致事件监听器等问题)。

    viewer.entities.removeAll();

如果你需要更细致地控制移除过程,可以遍历 entities 集合并逐个调用 destroy() 方法(尽管 removeAll() 通常已经足够)。

  1. 检查 Cesium 版本

    确保你使用的 Cesium 版本没有已知的此类问题的 bug。有时,升级到最新版本可以解决这类问题。

  2. 查看控制台和网络请求

    使用浏览器的开发者工具查看控制台输出和网络请求,看是否有与图像加载或 Cesium 内部错误相关的更多信息。

  3. 考虑错误处理和日志记录

    在你的应用中增加错误处理和日志记录,以帮助诊断何时何地发生了此类问题。

相关推荐
无限大.1 小时前
前端知识速记:节流与防抖
前端
十八朵郁金香1 小时前
【VUE案例练习】前端vue2+element-ui,后端nodo+express实现‘‘文件上传/删除‘‘功能
前端·javascript·vue.js
学问小小谢1 小时前
第26节课:内容安全策略(CSP)—构建安全网页的防御盾
运维·服务器·前端·网络·学习·安全
LCG元2 小时前
Vue.js组件开发-实现全屏图片文字缩放切换特效
前端·javascript·vue.js
还是鼠鼠3 小时前
图书管理系统 Axios 源码__新增图书
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
还是鼠鼠6 小时前
图书管理系统 Axios 源码 __删除图书功能
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
轻口味6 小时前
Vue.js `Suspense` 和异步组件加载
前端·javascript·vue.js
m0_zj7 小时前
8.[前端开发-CSS]Day08-图形-字体-字体图标-元素定位
前端·css
还是鼠鼠7 小时前
图书管理系统 Axios 源码__编辑图书
前端·javascript·vscode·ajax·前端框架
北极象7 小时前
vue3中el-input无法获得焦点的问题
前端·javascript·vue.js