所谓时空数据,顾名思义,包含了两个维度的信息:空间信息与时间信息。空间信息,以地理位置点最为基础,还包括线、多边形以及更为复杂的多维结构。最典型的时空数据,莫过于移动对象的轨迹点数据,如每隔5秒钟记录的车辆实时位置信息。这类数据,在物联网领域司空见惯,在可预见的未来,这类数据将会出现爆炸性的增长。
所谓时空数据,顾名思义,包含了两个维度的信息:空间信息与时间信息。空间信息,以地理位置点最为基础,还包括线、多边形以及更为复杂的多维结构。最典型的时空数据,莫过于移动对象的轨迹点数据,如每隔5秒钟记录的车辆实时位置信息。这类数据,在物联网领域司空见惯,在可预见的未来,这类数据将会出现爆炸性的增长。
本节我们以查询为例,看下GeoSpark如何利用分布式来实现高效查询。首先,对于Spark来说,想要利用Spark,必须要将自己的类型转为RDD,我们就先看下Geospark是如何读取GeoJson,并将Geometry
转为RDD的。
首先来讲下shp文件组成,一个shp文件通常由:shp、dbf、shx、prj四个文件组成,其中prj代表空间参考信息,shx存储了索引信息,有助于程序加快搜索效率,shp保存了元素的几何实体,最后dbf里面存放了每个几何形状的属性数据,所以我们将shp文件编码,实际上是将dbf文件编码,因为只有dbf来说,才有可能存储GBK编码的中文或其他编码的其他语言的。
我是GeoSpark的作者。我的个人网站的Talk section里面有非常详细的教程讲解GeoSpark到底是做什么的。简单来说:
GeoSpark provides distributed index and query.on spatial vector data in Apache Spark. Spatia vector data includes point polygon linestrings trajectories.
GeoMesa是一个基于Apache Accumulo key value store的spatial index, also for spatial vector data. GeoMesa里面的Spark核心部分是GeoSpark算法的再造轮子(GeoMesa的作者当面告诉我的)
GeoTrellies provides distributed query and map algebra on spatial raster data such as satellite imagery data.
①PostGis为PostgreSql提供了空间数据类型,空间函数,空间索引,作为插件使PostGreSql成为了一个空间关系型数据库。
②Ganos同理为Hbase提供空间能力,使得Hbase成为了一个空间分布式数据库,但是不仅仅如此,数据库仅仅是存储,而Ganos还通过Spark进行数据分析。
③PolarDb底层通过存储集群的方式实现了按存储容量收费,避免Mysql按照2T的实例购买。首先抛开原理谈优点,相比Mysql实现了容量大,高性价比,分钟级弹性,读一致性,毫秒级延迟,无锁备份,复杂Sql查询加速。说白了是对标于Mysql的竞争产品。
④GeoHash通过一定的规则把经纬度二维坐标转换成一维编码,从而更加高效,同时在个别场景下有更好的用途。实质是个算法。
⑤GeoMesa被阿里进一步封装,形成了Ganos。GeoMesa同样是基于Hbase或者其他分布式数据库进行存储,基于Spark进行时空数据分析,两者说白了就是使用一定的方法(添加时空数据类型,添加时空函数等等)把时空数据与大数据组件如存储Hbase,计算Spark结合起来,使之成为能处理,存储,分析时空的大数据平台。
⑥在上面的场景下,GeoMesa不能处理时空栅格数据,那么就引入了GeoTrellis来处理时空栅格数据。可以说是对GeoMesa的补充。
⑦GeoMesa中空间处理部分Spark核心部分是GeoSpark算法的优化和改进。
⑧GeoWave作为Apache顶级项目Accumulo键值对数据库的spatial index,为Accumulo键值对数据库提供了空间能力的同时也提供了空间数据处理能力。
⑨lgnite可以看作分布式内存网格的一种实现,提供分布式计算的同时提供分布式内存存储(可以看作redis)
⑩Sphinx使用C++语言编写,作为一种基于Sql的全文检索引擎。与其对标的典型有
Lucene,Solr,ElstaticSearch。
Geospark将从shapefile、csv等格式文件以及DataFrame中的读取的字段保存到了Geometry
的userData
字段中,可以通过调用.getUserData()
方法获取,他会返回一个String对象,各个字段以\t
连接。
PostGreSQL以及Mysql均有空间引擎扩展,且GeoSpark是针对大数据的空间分析,而SHP、GeoJson等只是小数据集的,PostGIS就能胜任其分析任务。所以对于大数据集的,我们还是要用空间关系数据库存储,利用Spark SQL从数据库中加载数据,获得DataFrame,然后利用Geospark转为几何弹性数据集RDD。
GeoSpark SQL默认是无法读取Shp和GeoJson格式的矢量数据的,必须要通过RDD读取,然后利用GeoSpark提供的Adapter
在RDD和DataFrame之间互转。
接下来我们还是利用我们上一节的公园的数据来学习。
GeoSpark本质还是对地理要素进行操作,所以它支持了常用的一些地学几何图形。
几何图形中主要有三个要素:点,线,面。
横纵坐标构成点,多个点构成线,环线构成面,点线面混合构成几何集合。
GeoSpark
是基于Spark之上的分布式群集计算系统。GeoSpark扩展了Spark Core和SparkSQL并提出了空间弹性分布式数据集(Spatial Resilient Distributed Datasets (SRDDs))同时提供了可视化组件。简而言之就是可以利用它在Spark上做空间运算。能够基于经纬度等信息创建点(Point)线(LineString)面(Polygon)。并提供了几种空间查询:空间临近查询(Spatial KNN Query)、空间范围查询( Spatial Range Query)、空间连接查询(Spatial Join Query)和距离连接查询(Distance Join Query)。
由于考虑到日后需要基于GeoMesa进行二次开发,所以本文采用的是编译GeoMesa源代码的方式,如果读者仅仅为了学习应用GeoMesa进行空间数据管理,可以直接从官方下载已经编译好的GeoMesa HBase工具包,最新版本为2.0: GitHub
ETL部分提供了城市(例如昆明、苏州)的管线数据,管线有不同类型(电力、热水、给水、中水、雨水、交通信号、通信等),某个具体类型的管线数据,也有不同类型(点Point、线Line)。本案例选用昆明市的电力线表,即km_npl。(np代表“电力”,l代表线)
GeoNames是一个地理信息数据库,包括一千万的地理名称和超过九百万的特征。针对纽约出租车的数据信息,假设有如下问题:出租车上下客是否集中在某些兴趣点附近?为了找到答案,需要把GeoNames数据和NYCTaxi数据结合,在结果上做聚合统计。需要Join在彼此可容许的距离之内的点,以下将其称为D-within Join。
GDELT提供了一个全面的时间和位置索引存档,包括1979年至今全球广播,印刷和网络新闻媒体报道的事件。假设一个国家的GDELT事件越多,政治相关性就越大。由于GDELT是几何点的数据集,不能直接知道它属于哪个国家,因此我们需要第二个数据集,即FIPS Codes(联邦信息处理标准出版物代码)的shapefile,可以表示一个国家的边界,两个数据集之间可以JION。(本例进行的前提是两个数据集已经存储好了)
本例中国家只有3000条记录,我们可以广播(Spark Broadcast)这些国家让查询更有效率。
GeoMesa为在GeoMesa数据之上执行Spark任务提供了支持,可以使用标准CQL查询来初始化RDD,通过使用CQL函数来转换数据。
FSDS(FileSystem data store)可以让用户在没有数据库实例的情况下使用flat files存储和查询数据,这些flat files存储在HDFS,AWS或者本地磁盘。了解本章内容是基础,有助于掌握Geomesa的其他使用案例。
上一节我们使用GeoSpark SQL简单进行了空间的一些操作,本节我们继续利用GeoSpark SQL以及GeoSparkViz将我们的结果进行渲染展示。下面是我们今天要用到的新的6个SQL函数
Spark提供DataFrame数据集,并且可以通过SQL语句来操作。GeoSpark在这个基础上实现了一些空间上的函数,可以用于SQL语句中,以下是本节要用到的5个,其余的函数参考GeoSpark SQL
tag:
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true