开发者问题收集

VueJS2 与 Cesium:未捕获的 typeError:无法使用 ScreenSpaceEventHandler 读取未定义的属性“viewer”

2021-07-15
944

我正在用 Cesium 和 VueJS 构建一个地球仪。我的一个组件如下所示。此组件已添加到 App.vue。地球仪运行正常,所有图元均显示良好。

现在我想向查看器添加一些 Cesium ScreenSpaceEventHandler,正如您在代码中看到的那样。当我单击与左键单击有关的 screenSpaceEventHandler 时,它给出了以下错误。该错误让我相信查看器尚未定义,但是,这很奇怪,因为查看器已在工作,因为我可以从绘制矩形和矩形轮廓没有问题以及通过多次调用 his.viewer 使用查看器数据来判断(可能在下面的代码中不可见)。

我希望如果有人查看下面的代码,他们可以看到我在这里遗漏了什么。我只需通过说“this.viewer...”来调用查看器数据。但是它“无法读取未定义的属性‘viewer’。错误发生在以下代码的最后一行之一:“let pickedFeature = this.viewer.scene.pick(movement.position);”。显然我不能在这里使用this.viewer,我只是不明白为什么不行,为什么它会是未定义的?我能做什么:slight_smile:

我希望有人能帮我解决这个问题。谢谢。

错误 这向我表明查看器工作正常。但是我遇到了以下堆栈跟踪的错误:

Uncaught TypeError: Cannot read property ‘viewer’ of undefined at onLeftClick (Globe.vue?c172:419) at cancelMouseEvent (ScreenSpaceEventHandler.js?1863:295) at handleMouseUp (ScreenSpaceEventHandler.js?1863:317) at handlePointerUp (ScreenSpaceEventHandler.js?1863:867) at HTMLCanvasElement.listener (ScreenSpaceEventHandler.js?1863:54)

CODE

<template>
  <div id="cesiumContainer"></div>
</template>

import * as Cesium from "cesium";

export default {
  name: "Globe",
  data: function () {
        return {
            viewer : undefined,
            terrainProviderViewModels : [],
            selectedTerrainProviderViewModel : undefined,
            imageryProviderViewModels : [],
            selectedImageryProviderViewModel : undefined,
        }
    },
    mounted: function () {
    window.CESIUM_BASE_URL = "/cesium/"
    this.drawGlobe();
    },
   methods: {
    async drawGlobe() {
      try{
        this.terrainProviderViewModels.push(await this.getTerrainViewModels());
        this.selectedTerrainProviderViewModel = await this.assignTerrainProviderViewModel();
        this.imageryProviderViewModels.push(await this.getImageryModels());
        this.selectedImageryProviderViewModel = await this.assignImageryModels();
        this.viewer = await this.createViewer();
        await this.drawCells();
        
      } catch(e) {
        console.log("Failed to draw globe: " + e);
      }
    },
        async getTerrainViewModels() {
            // some code to get terrain view models
        },
        
        async assignTerrainProviderViewModel() {
            // some code to get terrain provider view models
        },
        async getImageryModels() {
            // some code to get imagery models
        },
        async assignImageryModels() {
            // some code to assign current imagery models
        },
        async createViewer() {
            // creating  a viewer
        },
        async drawCells() {
            await this.createRectangleInstancesAndRectangleOutlineInstances();
            await this.createPrimitives();
            await this.addPrimitivesToViewer();
            await this.addEvents();
        },
        async createRectangleInstancesAndRectangleOutlineInstances() {
            // some code to create rectangleInstances
        }, 
        async createPrimitives() {
            // some code to create primitives
        }, 
        async addPrimitivesToViewer() {
            // some code to add primitives to viewer
        },
        async addEvents() {
            try{
                this.viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
                    let pickedFeature = this.viewer.scene.pick(movement.position);
                    // .... some more code
                },Cesium.ScreenSpaceEventType.LEFT_CLICK);
            }catch(e) {
                console.log(e);
            }
        }
   }
}
2个回答

我已将 addEvents() 方法中的代码添加到创建查看器的 createViewer() 方法中。我预期查看器是某种对象,但它显示为未知组件。所以也许这就是 this.viewer 不起作用的原因?无论如何,它现在起作用了。

AlmostGr
2021-07-16

我必须检查:

viewer?.isDestroyed()

这对我有用:

if (!viewer?.isDestroyed() && viewer?.screenSpaceEventHandler) {
      viewer.screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
    }
Sindre Solheim
2023-02-09