如何从文档中获取 Cesium 查看器的实例?

问题描述

我试过使用

var viewer = document.getElementById("cesiumContainer")

但这不会返回实际的查看器对象。获取已经创建的查看器的实例/引用的正确方法是什么。我正在尝试在我创建查看器的部分超出范围的代码中访问它,如果这不明显的话。

正在使用 resium 包为带有 <Viewer> 的 React 应用程序创建查看器。呈现的 HTML 页面仍然将查看器包装在一个 id 为 cesiumContainer 的 div 中,并且从开发工具中检查源代码来看,它看起来与没有反应的情况相同,所以我认为它在以下方面的行为是相同的能够访问它。当然,情况可能并非如此。

解决方法

这个答案侧重于您对 Resium、Cesium 和基于类的 React 组件的使用。

如果您使用的是 React 16+,则可以使用 Context 来实现您的目标。

  1. 首先创建一个上下文,用作您的单例引用。状态和 React Context 被导出。
CesiumContext.js
export const state = {viewer: '',setInstance: (ref)=>{state.viewer = ref;}};
export default CesiumContext;
  1. 在您想要引用 Cesium 实例的每个组件中,将类属性 contextType 设置为 React Contact 引用。 (CesiumContext)。在 ViewerComponent 构造函数中使用 createRef()。它将捕获唯一允许设置 Context 状态的 prop (ref),从而允许所有其他组件访问引用。请注意使用 componentDidMount() 将上下文状态设置为 Resium 提供的引用。
查看器组件.js
export default class ViewerComponent extends React.Component {
  constructor(props) {
    super(props);
    this.ref = createRef();
  }
  componentDidMount() {
    if (this.ref.current && this.ref.current.cesiumElement) {
      this.context.setInstance(this.ref.current.cesiumElement);
    }
  }
  render() {
    return <Viewer ref={this.ref}/>
  }
}
ViewerComponent.contextType = CesiumContext;
  1. 在 App 组件中,使用上下文的状态呈现 ContextProvider。一旦 ViewComponent 渲染/挂载,并且设置了 Context 状态,那么 Context 元素下的每个子组件都可以访问当前的 Cesium View 对象。这种结构造成了一个问题,为了实现这一点,必须重新渲染树。根据您的应用,您可能需要强制重新渲染。
应用程序.js
      <div className="App">
        <CesiumContext.Provider value={state}>
          <ViewerComponent/>
          <AComponent/>
          <BComponent/>
        </CesiumContext.Provider>
      </div>
  1. 最后,在需要访问共享资源(本例中为 Cesium View 实例)的任何组件中,在类上设置 contextType。在 componentDidMount 中,从上下文中获取实例。
任何组件
export default class AComponent extends React.Component {
  constructor() {
    super();
    this.viewer = false;
  }

  componentDidMount() {
    this.viewer = this.context.viewer;
  }
  render() {
    return <p>{/* do something with this.viewer */}</p>;
  }
}
AComponent.contextType = CesiumContext;

一个完整的解决方案在下面演示了这一点。一个组件 AComponent 访问 Cesium.View.shadowed 属性,'BComponent` 访问 Cesium.View. allowDataSourcesToSuspendAnimation 属性。

React Playground Solution

,

文档表明,如果您从 amplify update api 导入 useCesium,那么下面的代码将获取您想要的引用。

resium

Reference

编辑:使用基于类的组件需要以不同的方式访问实例。以下是文档中的两个示例:

使用类方法:

import { Viewer } from "cesium";
import { useCesium } from "resium";
const ExampleComponent = () => {
  const { viewer } = useCesium();
  return <p>Cesium Viewer object is{viewer ? "" : " not"} provided here.</p>;
};
export default ExampleComponent;

使用 createRef:

import React,{ Component } from "react";
import { Viewer as CesiumViewer } from "cesium";
import { Viewer } from "resium";
class ExampleComponent extends Component {
  private viewer: CesiumViewer | undefined;
  componentDidMount() {
    if (this.viewer) {
      // this.viewer is Cesium's Viewer
      // DO SOMETHING
    }
  }
  render() {
    return (
      <Viewer
        ref={e => {
          this.viewer = e ? e.cesiumElement : undefined;
        }}
      />
    );
  }
}