当前位置: 首页> 财经> 金融 > Vue+Cesium加载GeoJSON并设置entity.billboard,在组件销毁/释放实体entity时报错

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

时间:2025/8/23 21:39:59来源:https://blog.csdn.net/m0_55049655/article/details/141171569 浏览次数:0次

背景: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') 这类错误通常与尝试访问未正确初始化或已被销毁的对象的属性有关。在你提到的场景中,这个错误发生在尝试设置 Billboard 的 image 属性时,而该 Billboard 或其相关的资源(如纹理图集 _textureAtlas)可能已经不再有效或未正确加载。

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

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

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

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

解决步骤

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

if (billboard && !billboard.isDestroyed()) {  billboard.image = 'new-image-url.png';  
}
  1. 注意:isDestroyed() 方法可能在某些 Cesium 版本中不可用。

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

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

viewer.entities.removeAll();

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

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

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

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

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: