使用 Cesium 动态加载 GeoJSON 数据

摘要:
二、解决方案先来看一下整体效果:2.1加载GeoJSON数据在Cesium基础使用介绍一文中已经介绍了如何加载多种格式矢量数据,加载GeoJSON数据已经写出了两种方式,第一种是整体读取的,明显无法满足我们的需求,那么就只能寻求第二种方式了:Cesium.GeoJsonDataSource.load.then;这里需要注意一个细节,地震数据为点状数据,需要先设置entity.billboard=undefined,而后再设置entity.point来显示点状元素,否则会显示一个图标而不是点。
前言

需求是这样的,我需要在地图中显示 08 年到现在的地震情况,地震都是发生在具体的时间点的,那么问题就来了,如何实现地震情况按照时间动态渲染而不是一次全部加载出来。

一、 方案分析

这里面牵扯到两个问题:第一个是如何加载 GeoJSON 格式的数据,其实也就是矢量数据,因为矢量数据之间是可以任意转换的;第二个是如何让加载的数据根据自身的时间显示。

所以就有两种解决问题的思路了:第一种,一次加载 GeoJSON 中所有数据,然后逐个设置显示时间;第二种,逐个加载 GeoJSON 中数据,并设置每个对象的显示时间。

下面我们就一步步来实现解决方案。

二、 解决方案

先来看一下整体效果:

使用 Cesium 动态加载 GeoJSON 数据第1张

2.1 加载 GeoJSON 数据

Cesium基础使用介绍一文中已经介绍了如何加载多种格式矢量数据,加载 GeoJSON 数据已经写出了两种方式,第一种是整体读取的,明显无法满足我们的需求,那么就只能寻求第二种方式了:

Cesium.GeoJsonDataSource.load('data/earthquake.geojson').then(function(dataSource) {
    viewer.dataSources.add(dataSource);

    var entities = dataSource.entities.values;

    for (var i = 0; i < entities.length; i++) {
        var entity = entities[i];
        entity.billboard = undefined;
        entity.point = new Cesium.PointGraphics({
            color: Cesium.Color.RED,
            pixelSize: 10
        });
    }
});

这里需要注意一个细节,地震数据为点状数据,需要先设置 entity.billboard = undefined,而后再设置 entity.point 来显示点状元素,否则会显示一个图标而不是点。

这样看上去是逐一添加了点状元素,但是我们的问题并没有解决,所有地震点还是全部显示出来了,并没有按照时间显示。

2.2 空间对象按照时间显示

查阅了很多资料,发现可以通过设置对象的 availability 属性来控制对象的显示时间,这正是我需要的,于是修改如下:

    Cesium.GeoJsonDataSource.load('data/earthquake.geojson').then(function(dataSource) {
        viewer.dataSources.add(dataSource);

        var entities = dataSource.entities.values; 

        for (var i = 0; i < entities.length; i++) {
            var entity = entities[i];
            entity.billboard = undefined;
            entity.point = new Cesium.PointGraphics({
                color: Cesium.Color.RED,
                pixelSize: 10
            });
            entity.availability = new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
                start: Cesium.JulianDate.fromIso8601(entity.properties.date),
                stop: addDay(Cesium.JulianDate.fromIso8601(entity.properties.date))
            })]);
        }
    });
});

可以看到只是多加了 entity.availability = ... 一项,这样就能够按照时间显示,主要是其中的 start 和 stop 属性,控制显示的时间范围。date 是 GeoJSON 中数据的一个字段,格式为 '2008-01-01',当然你也可以使用其他格式,在此处进行自定义处理即可,addDay 用于控制显示一天,此处不用多考虑。

2.3 GeoJSON 的另外一种读取方式

写到这里问题已经解决了,但是这里再说一个小插曲。刚开始的时候我将 availability 属性直接写到了 point 里,无法得到结果,于是怀疑是此方法走不通,又思考和搜索了片刻,找到了另一种读取 GeoJSON 的方法,如下:

Cesium.loadJson('data/boundary/earthquake.geojson').then(function(jsonData) {
    for (var i =0 ;i<=jsonData.features.length; i++) {
        var ifeature = jsonData.features[i];
        viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(ifeature.geometry.coordinates[0], ifeature.geometry.coordinates[1]),
            availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
                start: Cesium.JulianDate.fromIso8601(ifeature.properties.date),
                stop: addDay(Cesium.JulianDate.fromIso8601(ifeature.properties.date))
            })]),
            point: {
                pixelSize: 10,
                color: Cesium.Color.RED
            }
        });
    }
});

这同样能达到效果,这就是刚开始讨论时描述的逐个读取数据,这与前一种方式不同的是此处读取到的是逐个的 feature 对象(前一种直接读取 entity 对象),根据 feature 生成 entity 对象,再使用 viewer.entities.add 将对象添加到场景中,每个对象单独根据时间设置 availability 属性,这样同样达到了效果。

当此种方式达到效果的时候,再回头来看第一种方式豁然开朗,读取到的 entity 就是一个真实的 entity 对象,于是将 availability 从 point 中移出到外面便达到了效果。

2.4 问题分析

两种方式都能达到效果,而我在刚开始的时候对细节、对 cesium 的各个对象并没有理解的那么透彻,只是看到了表面现象,当研究的稍微深入的时候对整个 cesium 框架也就有了更多的理解,于是条条道路通罗马。

三、 总结

本文简单介绍了如何动态的根据时间加载 GeoJSON 对象,一定要保持深度思考的习惯,凡事不能只看到表面,应该多一些深入的思考。

免责声明:文章转载自《使用 Cesium 动态加载 GeoJSON 数据》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Ubuntu中恢复rm命令误删文件(转)解决python3 pip安装、更新及yaml安装下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

在workbench中导入.sql文件!(导入数据库文件)

第一步,登陆mysql workbench 第二步,打开自己的数据 ,此处默认(root) 打开数据库后页面 : 第三步,新建一个schema ,随便给个名字,这里起名为test : 可以看到test 内的table ,views,routines,等选项都是没有任何内容的。 第四步 ,在file 下打开你需要导入的.sql 文件。...

使用orapki生成证书,配置Oracle数据使用SSL和TLS进行数据库连接的TCP/IP配置==TCPS

内容参考Oracle官方文档:   https://oracle-base.com/articles/misc/configure-tcpip-with-ssl-and-tls-for-database-connections   https://docs.oracle.com/cd/E11882_01/network.112/e40393/asoappf...

怎么充分利用大数据寻找商机?

在大数据时代,数据量日益增加,所以展现在我们面前的就有两个根本性的问题那就是,其一,海量数据如何来存储,其二就是海量数据如何分析,将数据转换为真正的商机呢?下面新霸哥将和你详细的探寻。 海量数据存储一直是一个很重要的问题,由于现在技术在不断的发展,人们对于海量数据的存储有了新的方式,那就是使用分布式系统来存储海量数据。在传统的数据库无法解决现有数据存储的问...

从零搭建企业大数据分析和机器学习平台-技术栈介绍(三)

数据传输和采集 Sqoop数据传输工具实际项目开发中,往往很多业务数据是存放在关系型数据库中,如 MySQL数据库。我们需要将这些数据集中到数据仓库中进行管理,便于使用计算模型进行统计、挖掘这类操作。 Sqoop是Apache软件基金会的⼀一款顶级开源数据传输工具,用于在 Hadoop与关系型数据库(如MySQL、Oracle、PostgreSQL等)之间...

如何在十分钟内插入1亿条记录到Oracle数据库?

这里提供一种方法,使用 APPEND 提示,使得十分钟内插入上亿数据成为可能。 -- Create table create table TMP_TEST_CHAS_LEE ( f01 VARCHAR2(20), f02 NUMBER(10) not null, f03 VARCHAR2(21), f04 VARCHAR2(21), f05 NUMBER,...

jmeter数据驱动csv+批量导出数据到csv文件

基本的软件使用,我们简单一点,附图来讲,详细地方不懂的可以自行百度。 使用Jmeter 批量导入数据,之后批量导出数据到csv文件,可以帮助我们更好的整理数据,在工作中比较常用。 大致过程可以分三步:1. 导入csv文件;2. 变量引用; 3. 批量导出csv文件 1. 导入csv文件: point1:建议使用notpad, sublime等编辑器来编辑保...