GeoMesa-空间数据存储引擎入门学习手册

GeoMesa-空间数据存储引擎

geomesa简介、架构体系、数据存储、spark等

在这里插入图片描述

第一部分:GeoMesa简介

  • GeoMesa是一款开源的基于分布式计算系统的⾯面向海海量量时空数据查询与分析的⼯工具包

  • GeoMesa基于GeoToolsAPI进⾏行行设计,与GeoServer等进⾏行行集成提供OGC标准的服务。

在这里插入图片描述

  • ⽀支持多种可扩展的、基于云端的数据存储架构,包括ApacheAccumulo,HBase,Cassandra,Google Bigtable,以及⽤用于流计算的Apache Kafka 。

在这里插入图片描述

  • 提供了了Spark,并增加了了正对空间数据的UDT、UDF和UDAF,⽅方便便⽤用户直接使⽤用SparkSQL进⾏行行空间数据查询与分析。

  • Git 地址:https://github.com/locationtech/geomesa。

  • Build地址:https://github.com/locationtech/geomesa/releases

在这里插入图片描述

第二部分:GeoMesa架构体系

1:模块划分

在这里插入图片描述

2:时空索引-R树

  • 据R树的这种数据结构,当我们需要进行一个高维空间查询时,我们只需要遍历少数几个叶子结点所包含的指针,查看这些指针指向的数据是否满足要求即可。

在这里插入图片描述

  • Oracle Spatial、MySQL Spatial、PostgreSQL(PostGIS) 都是基于R树进行空 间搜索操作,即对空间字段(Geometry Column)创建R树索引。

  • R树存在的问题:

    1. 单独创建索引⽂文件
    2. 数据更更新问题:为了了达到平衡状态,新插⼊入数据需要更更新整个R树 。
    3. 不不适合NoSQL的结构
      HBase本身只提供基于⾏行行键和全表扫描的查询,⽽而⾏行行键索引单⼀一,对于多维度的查询困难。

3:GeoHash

1简介

GeoHash是一种地址编码方法。他能够把二维的空间经纬度数据编码成一个字符串。GeoHash具有以下特点:
1、GeoHash用一个字符串表示经度和纬度两个坐标。在数据库中可以实现在一列上应用索引
2、GeoHash表示的并不是一个点,而是一个区域;
3、GeoHash编码的前缀可以表示更大的区域。例如wx4g0ec1,它的前缀wx4g0e表示包含编码wx4g0ec1在内的更大范围。 这个特性可以用于附近地点搜索 。

2:GeoHash的计算过程:
1.将经纬度转换成二进制:

比如这样一个点(39.923201, 116.390705) 纬度的范围是(-90,90),其中间值为0。对于纬度39.923201,在区间(0,90)中,因此得到一个1;(0,90)区间的中间值为45度,纬度39.923201小于45,因此得到一个0,依次计算下去,即可得到纬度的二进制表示。

在这里插入图片描述

最后得到纬度的二进制表示为: 10111000110001111001
同理可以得到经度116.390705的二进制表示为: 11010010110001000100

2.合并纬度、经度的二进制:

合并方法是将经度、纬度二进制按照奇偶位合并: 1110011101001000111100000011010101100001

如下图:

在这里插入图片描述

3:按照Base32进行编码:

Base32编码表(其中一种):

在这里插入图片描述

将上述合并后二进制编码后结果为: wx4g0ec1

3:特点:
  • 字符串越长,表示的范围越小越精确;字符串长度越小,表示的范围越大越宽泛。
  • 字符串越相似表示距离越相近。

在这里插入图片描述

4:GeoMesa时空索引

1:各种空间填充曲线

fill-line.png

2:空间查询
  1. 用户定义查询窗口
  2. 层次划分
  3. 计算查询范围(Range)

在这里插入图片描述

3:GeoMesa时空索引

GeoMesa使用了基于Z-order填充曲线的GeoHash空间索引技术,
并针对时间维度进行了扩展,具体分为:
• Z2:空间,点索引
• Z3:时间+空间,点索引
• XZ2:空间,线\面索引
• XZ3:时间+空间,线\面索引。

在这里插入图片描述

git实现:https://github.com/locationtech/sfcurve

​ https://github.com/locationtech/geomesa/tree/master/geomesa-z3

5:GeoMesa HBase 索引

  1. RowKey设计

在这里插入图片描述

  • 属性索引
    在这里插入图片描述

  • Z-Index Shards: 预拆分,范围为1-127,默认为4。
    在这里插入图片描述

  • Z-Index Time Interval
    在这里插入图片描述

  1. 查询:

    • 可以按照属性查询
    • 可以按照空间范围查询
    • 可以按照时间查询
    • Geomesa会综合选择一种最快的查询方式执行

在这里插入图片描述

第三部分:GeoMesa 数据存储

1:数据结构

SimpleFeatureType:空间数据结构描述,包含空间WKT、时间信息、属性信息等。

import org.locationtech.geomesa.utils.interop.SimpleFeatureTypes;
SimpleFeatureTypes.createType("example", "name:String,dtg:Date,*geom:Point:srid=4326");

属性类型

Attribute TypeBindingIndexable
Stringjava.lang.StringYes
Integerjava.lang.IntegerYes
Doublejava.lang.DoubleYes
Longjava.lang.LongYes
Floatjava.lang.FloatYes
Booleanjava.lang.BooleanYes
UUIDjava.util.UUIDYes
Datejava.util.DateYes
Timestampjava.sql.TimestampYes
Pointorg.locationtech.jts.geom.PointYes
LineStringorg.locationtech.jts.geom.LineStringYes
Polygonorg.locationtech.jts.geom.PolygonYes
MultiPointorg.locationtech.jts.geom.MultiPointYes
MultiLineStringorg.locationtech.jts.geom.MultiLineStringYes
MultiPolygonorg.locationtech.jts.geom.MultiPolygonYes
GeometryCollectionorg.locationtech.jts.geom.GeometryCollectionYes
Geometryorg.locationtech.jts.geom.GeometryYes
List[A]java.util.ListYes
Map[A,B]java.util.Map<A, B>No
Bytesbyte[]No

第四部分:GeoMesa Hbase应用

1:Geomesa Hbase操作

2:GeoServer集合 Geomesa

Geomesa实现了GeoTools接口,提供了基于HTTP,方法和标准OGC服务的访问形式。

在这里插入图片描述

数据查询流程

在这里插入图片描述

第五部分:Geomesa Spark

在这里插入图片描述

1:geomesa-spark-jts :基于Spark 的JTS控件库。

依赖包

<dependency>
  <groupId>org.locationtech.geomesa</groupId>
  <artifactId>geomesa-spark-jts_2.11</artifactId>
</dependency>

从文件系统读取

import org.locationtech.jts.geom._
import org.apache.spark.sql.types._
import org.locationtech.geomesa.spark.jts._

import spark.implicits._

val schema = StructType(Array(
  StructField("name",StringType, nullable=false),
  StructField("pointText", StringType, nullable=false),
  StructField("polygonText", StringType, nullable=false),
  StructField("latitude", DoubleType, nullable=false),
  StructField("longitude", DoubleType, nullable=false)))

val dataFile = this.getClass.getClassLoader.getResource("jts-example.csv").getPath
val df = spark.read
  .schema(schema)
  .option("sep", "-")
  .option("timestampFormat", "yyyy/MM/dd HH:mm:ss ZZ")
  .csv(dataFile)

val alteredDF = df
  .withColumn("polygon", st_polygonFromText($"polygonText"))
  .withColumn("point", st_makePoint($"latitude", $"longitude"))

构造df

import spark.implicits._
val point = new GeometryFactory().createPoint(new Coordinate(3.4, 5.6))
val df = Seq(point).toDF("point")

2:geomesa-spark-core:基于Geotools实现的Spark核心库,将空间数据转换为RDD。

// DataStore params to a hypothetical GeoMesa Accumulo table
val dsParams = Map(
  "accumulo.instance.id"   -> "instance",
  "accumulo.zookeepers"    -> "zoo1,zoo2,zoo3",
  "accumulo.user"          -> "user",
  "accumulo.password"      -> "*****",
  "accumulo.catalog"       -> "geomesa_catalog",
  "geomesa.security.auths" -> "USER,ADMIN")

// set SparkContext
val conf = new SparkConf().setMaster("local[*]").setAppName("testSpark")
val sc = SparkContext.getOrCreate(conf)

// create RDD with a geospatial query using GeoMesa functions
val spatialRDDProvider = GeoMesaSpark(dsParams)
val filter = ECQL.toFilter("CONTAINS(POLYGON((0 0, 0 90, 90 90, 90 0, 0 0)), geom)")
val query = new Query("chicago", filter)
val resultRDD = spatialRDDProvider.rdd(new Configuration, sc, dsParams, query)

resultRDD.collect
// Array[org.opengis.feature.simple.SimpleFeature] = Array(
//    ScalaSimpleFeature:4, ScalaSimpleFeature:5, ScalaSimpleFeature:6,
//    ScalaSimpleFeature:7, ScalaSimpleFeature:9)

包括SimpleFeatures、 Multiple backends (Accumulo, HBase, FileSystem, Kudu, GeoMesa Convert library转换后文件系统, 其他 GeoTools 数据源)

3:geomesa-spark-sql:基于SparkSQl 的空间查询库

// DataStore params to a hypothetical GeoMesa Accumulo table
val dsParams = Map(
  "accumulo.instance.id"   -> "instance",
  "accumulo.zookeepers"    -> "zoo1,zoo2,zoo3",
  "accumulo.user"          -> "user",
  "accumulo.password"      -> "*****",
  "accumulo.catalog"       -> "geomesa_catalog",
  "geomesa.security.auths" -> "USER,ADMIN")

// Create SparkSession
val sparkSession = SparkSession.builder()
  .appName("testSpark")
  .config("spark.sql.crossJoin.enabled", "true")
  .master("local[*]")
  .getOrCreate()

// Create DataFrame using the "geomesa" format
val dataFrame = sparkSession.read
  .format("geomesa")
  .options(dsParams)
  .option("geomesa.feature", "chicago")
  .load()
dataFrame.createOrReplaceTempView("chicago")

// Query against the "chicago" schema
val sqlQuery = "select * from chicago where st_contains(st_makeBBOX(0.0, 0.0, 90.0, 90.0), geom)"
val resultDataFrame = sparkSession.sql(sqlQuery)

resultDataFrame.show
/*
+-------+------+-----------+--------------------+-----------------+
|__fid__|arrest|case_number|                 dtg|             geom|
+-------+------+-----------+--------------------+-----------------+
|      4|  true|          4|2016-01-04 00:00:...|POINT (76.5 38.5)|
|      5|  true|          5|2016-01-05 00:00:...|    POINT (77 38)|
|      6|  true|          6|2016-01-06 00:00:...|    POINT (78 39)|
|      7|  true|          7|2016-01-07 00:00:...|    POINT (20 20)|
|      9|  true|          9|2016-01-09 00:00:...|    POINT (50 50)|
+-------+------+-----------+--------------------+-----------------+
*/

第六部分:Cassandra应用

1:Cassandra config

spring.data.cassandra.cluster-name=Test Cluster
spring.data.cassandra.keyspace-name= user_space
spring.data.cassandra.contact-points=127.0.0.1
spring.data.cassandra.port=9042

2:run test

java -cp geomesa-tutorials-cassandra/geomesa-tutorials-cassandra-quickstart/target/geomesa-tutorials-cassandra-quickstart-2.4.0-SNAPSHOT.jar org.geomesa.example.cassandra.CassandraQuickStart --cassandra.contact.point 127.0.0.1:9042 --cassandra.keyspace geomesa --cassandra.catalog sample_table

3:output

bin/geomesa-cassandra export --output-format leaflet --contact-point 127.0.0.1:9042 --key-space geomesa --catalog sample_table

第七部分:其他应用

1:GeoMesa Kafka DataStore

•使⽤用Kafka作为数据存储DataStore
•通过GeoTools DataStore标准接⼝口进⾏行行访问

•Consumer与Producer可以分布在不不同server

•⽀支持要素缓存,定时写⼊入kafka

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ENViAIoI-1619677430713)(resource/kafka.png)]

2:GeoMesa Lambda DataStore

  • 数据存储在两个层:transienttier(Kafka)和 a persistent tier(HBase)

  • 数据定时写⼊持久层

  • 使⽤用ZK同步数据缓存状态,保证数据一次写⼊

  • 进⾏行行数据查询会从两个存储层分别进⾏, 然后合并查询结果返回给⽤用户。

在这里插入图片描述

Geomesa 空间分析是一种基于地理空间数据的分析方法,它将地理空间数据与大数据技术相结合,旨在从海量的地理空间数据中提取有用的信息和知识。 首先,Geomesa 空间分析利用空间索引技术对地理空间数据进行高效存储和查询。地理空间数据通常具有海量的规模和复杂的结构,因此通过空间索引可以大大提高数据查询的效率,并且可以支持各种空间查询操作,如范围查询、邻近查询、交叉查询等。 其次,Geomesa 空间分析可以实现多种空间分析算法。通过使用Geomesa提供的空间分析函数和工具,可以对地理空间数据进行聚合分析、点线面数据关联分析、热力图生成、路径分析等操作。这些空间分析算法可以帮助我们挖掘数据之间的空间关联性,发现地理空间模式和异常,以及进行预测和决策。 此外,Geomesa 空间分析还支持空间数据可视化。通过将地理空间数据与地图相结合,可以直观地展示数据的分布和变化趋势。地理信息系统(GIS)可以通过Geomesa提供的API和工具进行地图制作、交互式分析和可视化展示,帮助我们更好地理解和解释地理空间数据。 综上所述,Geomesa 空间分析是一种利用地理空间数据进行高效存储、查询、分析和可视化的方法。它能够帮助我们从大数据中提取有价值的地理空间信息,并为地理空间决策提供支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学亮编程手记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值