[Introduction to CesiumJS] (5) Loading, updating, monitoring and destruction of GooJSON - GeoJsonDataSource application

foreword

In this article, we will introduce the GeoJSON/TopoJSON related methods in Cesium more completely.

GeoJSON specification address: RFC 7946: The GeoJSON Format (rfc-editor.org)
GeoJSON online drawing: geojson.io

CesiumJS provides a DataSourceclass called , which is mainly used to load and display vector data, including but not limited to data in formats such as GeoJSON, KML, TopoJSON, and CZML. And today, we will introduce DataSourcea subclass of GeoJsonDataSource . Let's get straight to the point and write a class that includes methods for loading, updating, destroying, and monitoring GeoJSON data.

1. Preparation

Prepare the GeoJSON file, you can draw directly on the online drawing website I provided above, or download it from the code warehouse of this project: src/assets/geojson

// 将这些文件引入:
import pointSample from '@/assets/geojson/point.json' // 示例点要素
import lineSample from '@/assets/geojson/line.json' // 示例线要素
import polygonSample from '@/assets/geojson/polygon.json' // 示例面要素
import collectionSample from '@/assets/geojson/collection.json' // 示例要素集合

Two, loading

Write out the framework of the class, and then add the first method to it,load()

class CesiumGeoJSON {
    
    
  constructor(data, options, callback) {
    
    
    this.data = data;
    this.options = options;
    this.dataSource = null;

    // 初始化 GeoJSON 数据源
    this.init(callback);
  }

  // 初始化 GeoJSON 数据源
  init(callback) {
    
    
    Cesium.GeoJsonDataSource.load(this.data, this.options)
      .then((dataSource) => {
    
    
        this.dataSource = dataSource
        viewer.dataSources.add(this.dataSource);

        // this.dataSource.describe = ''
        // this.dataSource.credit = ''
        // dataSource.show = true // boolean - Whether to show
        // dataSource.name = '' // string - The name of the data source

        viewer.zoomTo(this.dataSource)

        callback && callback(this.dataSource) // 触发回调函数
      }).catch((error) => {
    
    
        console.error('矢量数据加载发生了一些错误:', error);
      })
  }
}

As can be seen from the above code, when we create and initialize an instance object of this class, we can provide 3 parameters:

  • data—— The data source of GeoJSON or TopoJSON, which can be string, object or Cesium's Resource format.
  • options—— Optional options when loading data sources: GeoJsonDataSource.LoadOptions
  • callback—— Callback function, which exposes the loaded vector data (dataSource) for calling
// 调用:实例化然后就直接加载
const jsonInstance= new CesiumGeoJSON(collectionSample)

insert image description here

3. Update (reload)

In actual production, we may need to modify the data source to achieve an effect of updating data and reloading. So let's CesiumGeoJSONadd the following method to the class:

  // 更新(重新加载)数据源
  async update(newData, options) {
    
    
    if (this.dataSource == null) {
    
    
      throw new Error('矢量数据未加载或已被销毁');
    }

    if (typeof newData == 'object') {
    
    
      // 使用 Cesium.Resource 对象创建一个新的 GeoJSON 数据源,这么做才能触发changeEvent
      const resource = new Cesium.Resource({
    
    
        url: URL.createObjectURL(new Blob([JSON.stringify(newData)], {
    
     type: 'application/json' }))
      });
      return await this.dataSource.load(resource, options)
    } else {
    
    
      return await this.dataSource.load(newData, options)
    }
  }

transfer:

// 实例化然后就直接加载
constjsonInstance = new CesiumGeoJSON(collectionSample)

// 调用:2秒后更新数据
setTimeout(() => {
    
    
  jsonInstance.update(pointSample)
}, 2000);

insert image description here

4. New addition (do not replace existing data)

What if I need to add additional new vector data to the dataset? Then add this method:

   // 新增(不替换已有的数据)数据源
  async add(newData, options) {
    
    
    if (this.dataSource == null) {
    
    
      throw new Error('矢量数据未加载或已被销毁');
    }

    // 使用 Cesium.Resource 对象创建一个新的 GeoJSON 数据源,这么做才能触发changeEvent
    const resource = new Cesium.Resource({
    
    
      url: URL.createObjectURL(new Blob([JSON.stringify(newData)], {
    
     type: 'application/json' }))
    });

    // 重新加载数据源
    return await this.dataSource.process(resource, options);
  }

Call again on the basis of the previous step, adding line data:

// 实例化后加载
constjsonInstance = new CesiumGeoJSON(collectionSample)

setTimeout(() => {
    
    
  jsonInstance.update(pointSample)
  jsonInstance.add(lineSample) // 调用:添加数据
}, 2000);

insert image description here

5. Monitoring

  // 监听数据源的变化
  watch() {
    
    
    if (this.dataSource == null) {
    
    
      throw new Error('矢量数据未加载或已被销毁');
    }

    // 监听数据源变化事件
    this.dataSource.changedEvent.addEventListener(this._changedEvent);
    // 监听错误事件
    this.dataSource.errorEvent.addEventListener(this._errorEvent);
  }

  // 数据源变化的事件
  _changedEvent(dataSource) {
    
    
    console.log('矢量数据源已被修改:', dataSource);
  }

  // 数据错误的事件
  _errorEvent(err) {
    
    
    console.error('矢量数据加载发生了一些错误:', err);
  }

6. Destruction

  // 销毁数据源和监听器
  destroy() {
    
    
    if (this.dataSource == null) {
    
    
      throw new Error('矢量数据未加载或已被销毁');
    }

    // 取消所有监听器
    this.dataSource.changedEvent.removeEventListener(this.changedEvent);
    this.dataSource.errorEvent.removeEventListener(this.errorEvent)

    // 移除数据源
    viewer.dataSources.remove(this.dataSource);
    this.dataSource = null;
    console.log('CesiumGeoJSON has been destroyed.');
  }

0. Finally

Code submission record:
feat: Add GeoJSON related methods · 0f31b7e · ReBeX/cesium-tyro-blog - Gitee.com
fix: Optimize data source update method · 411ab3f · ReBeX/cesium-tyro-blog - Gitee.com

Guess you like

Origin blog.csdn.net/ReBeX/article/details/131265815