从一月份开始,主要在做cesium的开发,和之前不同的是这次是在react框架的基础上进行开发的😄

先上一张现在开发内容的截图: 外网可访问地址:https://service.eclipsesv.com/cesium/,限于服务器带宽和cesium打包之后的体积,访问速度确实很慢。 下边记录一下开发过程中一些不错的经验和思路:

使用webpack打包cesium

以往的开发过程中,cesium一般直接是用<srcipt>标签引入并使用的。但是如果想在react框架下很方便的开发,用webpack打包我们用到的第三方库会更可取。 cesium官网给出的连接也很明确的告诉用户如何使用webpack打包cesium:链接地址。 我们只需要在新建的react项目的webpack.config.js中按照上边链接中的方法做即可。现在我们就可以通过npm install cesium或者yarn add cesium就可以把cesium引入项目开始使用啦。🍺🍺🍺

在项目中引用cesium

目前主要有两种方法引入cesium中的对象:

  1. import Cesium from 'cesium/Cesium',这种方法引入的Cesium能够涵盖大部分cesium内置的对象
  2. import CesiumMath from 'cesium/Core/Math',这种方法引入部分无法直接通过Cesium就能获取的内容 原理其实很简单:这两种不同的引入方式利用上边webpack.config.js中的配置:
1
2
3
4
5
6
7
const cesiumSource = 'node_modules/cesium/Source'
resolve: {
        alias: {
            // Cesium module name
            cesium: path.resolve(__dirname, cesiumSource)
        }
    }

我们在代码中import的时候,cesium其实代表的是node_modules/cesium/Source,这样的话,上边两种引入方式其实还是通过相对文件路径引入想要的内容。 如何区分该在什么时候用哪种引入方式?我现在的做法是通过查看cesium官方文档来区分: 以最常用的Viewer在文档中是这样的new Cesium.Viewer(container, options),这样看来只需要通过上边的第一种引入方法引入Cesium即可; 涉及数学运算的CesiumMath 源码存在于:Core/Math.js 18在文档中直接是这样的CesiumMath(),所以通过第二种方法引入cesium/Core/Math

cesium在react框架中的状态管理和控制

cesium相关的开发主要集中在cesium图层控制管理和相关鼠标事件而核心的对象则是Cesium.Viewer。在react框架下,如果在某个react组件中实例化Cesium.Viewer对象之后,大部分操作都要围绕这个Viewer对象开展。 现在开发过程中,主要通过两种方式在组件间传递Viewer相关的内容:

  1. 加入redux进行全局状态管理,主要针对cesium的各类图层状态
  2. 组件之间通过props传递鼠标事件或cesium状态

cesium影像图层的添加或移除

以影像图层控制为例,图层增删控制主要通过下边这个流程: 我在viewerContainer.js中完成了Cesium.Viewer的实例化,在componentDidMount()中完成了一系列的初始化,并从配置文件中获取到所有可用的图层列表,将它们的信息存储在imageryProviders数组中。imageryProviders中的每个元素分别描述一个可用以加载的影像图层,包括图层编号、图层名称、图层对应的缩略图、用以解析此项配置的驱动等相关内容。 经过解析,在页面上用以展示图层信息通常只需要图层编号(id),图层名称(name),图层缩略图(thumbnail),如图所示: 所以将imageryProviders转变为imageProviderProfile,然后把imageProviderProfileprops的形式传递给用以展示数据列表的控件即可。 现在虽然能够完成数据列表的展示,可是如何才能控制Viewer上图层的变化呢?我在这里创建了一个selectedImageryProviders数组并使用redux在全局store中维护,这个数组用以保存当前三维球上到底是哪些图层在显示,数组中存储图层的编号(id)即可。 按照上边的思路,我在imageLayerManger.js中,通过connect()监听并控制store.selectedImageryProviders:通过界面按钮选择添加或移除图层的时候通过selectProviderById()触发reducer从而修改selectedImageryProviders。这样同样监听store.selectedImageryProvidersviewerContainer.js可以在生命周期函数componentWillReceiveProps中获取selectedImageryProviders的改变从而影响Viewer上图层的添加或者移除。 上边啰嗦这么多,也只是提供一个思路,按照这样的方法不仅能够完成影像图层的添加和移除,对于其他类型的数据:地形、矢量或者模型数据都可以按照这样的套路。

遇到的问题和困难

在开发过程中遇到的问题和困难中要有以下几点:

  1. 不熟悉webpack配置,开发前期遇到很多缺少webpack plugin的问题
  2. 不能准确拆分组件,组件之间的关系不清晰
  3. 在加入redux之后,全局store设计不够完善
  4. 用以页面展示的组件和处理逻辑的组件拆分不够
  5. 异步reducer使用不够熟练
  6. webpack打包生产环境文件过大导致外网访问速度很慢

通过这次项目的开发,react相关的内容也确实得到了锻炼,里边的很多思路和理念理解也都有进步,可以继续这个开发🍻🍻🍻