一、为什么要用空间索引

1、传统暴力求解方法的局限性。

在地理空间搜索这块,我们会常常遇到一个问题,假设我们知道了一个地点经纬度信息,我们如何检索它附近10km以内的所有的点,假设我们是用关系数据库mysql来存放的,数据库里大概有40万条数据。我们能够直觉想到的是利用球面距离公式,直接求解该地点与所有地点的距离,然后根据计算结果再进行筛选,这时候我们发现该方法的复杂度为要执行40万 * 距离函数,随着数据库地点数据的增加,该距离计算复杂度也会线性增长,我们知道,在球面距离计算公式里面有sin()、cos()、sqrt()等计算,这对计算机的处理器会带来很大的计算量,占用宝贵的CPU资源,所以暴力求解的方案实际上是无法适应大数据量的地理空间数据检索。

2、空间索引Geohash编码和B+树方案的出现以及局限性

既然暴力求解不可行,那么有一种比较聪明的方法去解决了以上的这个问题,那就是Geohash编码和B+树索引,一般地理位置信息的数据结构都是以经纬度的组成出现,针对这种固定的数据结构,我们利用0和1通过层层划分区间得到一串二进制字符,然后通过Base32编码得到Geohash字符串,该方法将经纬度点的二维数据转化成了一维线性数据,并且Geohash编码有比较明显的特点是如果距离相近的点的字符编码的前缀是一样的,如果在存放经纬度数据时可以先存放一份Geohash编码,在每次查询附近点的时候,可以借助关系数据库本身的对一维数据比较成熟的处理B+树来检索,将会大大的缩小数据的计算范围,如同上面的例子,40万的数据量在B+树的检索下把数据量缩小至10条数据(假设情况),此时再执行空间距离函数再做一次距离的匹配,我们会发现此时方法的复杂度变为 10 * 距离函数。并且随着数据量的增加并不会给该计算方法的复杂性带来线性的增长。很完美的解决了地理信息点与点之间的距离信息检索的问题。

但是Geohash编码和B+树的只是解决了点与点之间的距离检索,因为在地理信息空间里面,空间数据类型具有多样性,空间数据库会存放点、线和面的数据,此时会产生更多的复杂情况,有点与点之间,点与线之间,点与面之间,线与线之间,线与面之间和面与面之间的距离检索问题,比如我们知道如何用检索附近10km内的餐馆(点与点问题),但是如果要求解附近10km以内的商圈(点与面)的距离,附近此时Geohash就不能解决更复杂的空间数据检索问题。

3、解决高维度空间数据索引问题:R树索引和Gist搜索树

在处理高维空间数据(主要是二维数据和三维数据)方面,Geohash编码的索引存在了局限性,使得无法去解决这个新出现又迫切需要解决的问题,这时候更聪明的方法出现了,那就是R树索引,R树索引引进了最小外接矩形的概念,它可以将地图上离散的点构建最小的外接矩形,也可以将地图上的线构建最小的外接矩形,也可以将地图上的不规则的区域构建最小的外接矩形,这样点线面的数据都转换成了一个相同的图形,那就是矩形,R数主要处理三个问题:第一、根据点线面构建最小外接矩形;第二,如何根据外接矩形对叶子节点进行检索,第三,如果往R树新增或者删除叶子节点的时候,如何重新构建R树来保持R树的平衡。Gist的意思是通用搜索树(Generalized Search Tree),它是一种平衡树结构的访问方法,类似于B-Tree的概念,Gist搜索树适用于多维数据类型和集合数据类型,和B-Tree相比,Gist多字段索引在查询条件中包含索引字段的任何子集都会用索引进行扫描,而B-tree索引只有查询条件包含的第一索引字段才会使用到索引扫描,所以这也导致了它的缺点,Gist创建时间长,占用的空间大,但是这对于处理多维数据的遍历的时候,Gist通用搜索树能发挥它的作用,所以一般情况下Gist索引是和R树来配合使用的。它如果放到三维空间,R树构建完成后的检索就需要用到Gist树索引,原理也是一样的,最小的外接矩形就变成了最小的外接矩形方块,不过本文主要介绍的是二维数据下的R树原理。

二、空间数据的简介

(1)点(point):一般的地理空间的点是用经纬度来表示的,如单点:point(lon, lat),多点:multipoint(point, point)。

(2)线(polyline): 一般地理的空间的线是用多个点来表示的,如直线:polyline((lon, lat), (lon, lat)),多线:mutipolyline(polyline, polyline)

(3)面(polygon): 一般地理的空间的面是多条线围成一个区域来表示的,如面:polygon((lon lat, lon lat,lon lat,lon lat),(lon lat, lon lat,lon lat,lon lat)),多面mutipolygon(polygon, polygon)。

三、R树的数据的获取方法

在二维的地理位置信息中,对于点线面的数据,我们不会去索引几何物体的本身,因为不规则的形状无规律可循,R树往往会采用最小限定箱的策略,即最小外接矩形,将不规则的的几何图形转换为规则的矩形来构建空间索引。最小外接矩形构建对象包括对不规则的面,不规则的多线和离散的多点,对于构建好的最小外接矩形后,剩下的问题就转化为如何利用矩形之间的相交和相离判断两个地理位置之间的距离。

1、R树的构建

下面我们就通过一个通俗的例子讲解下R树的构建,如上图所示,最基础的地理位置信息是R8-R19之间的叶子节点,这些叶子节点都是基于不规则的几何面、几何线和离散的点锁构成的地理位置信息元素,第一步就是对这些地理信息元素进行最小外接矩形的构建,我们在构建完之后会得到第一批要素信息R8-R19的外接矩形,第二步就是在这些最小外接矩形之上再进行外接矩形的构建,形成了R3-R7的直接的外接最小矩形,第三步,基于R3-R7再进行最小外接矩形的构建,我们会构建到R树最顶层的根节点,那么在现实中的R树分割中我们一般会按行政区划作为R树的切割最小外接的切割依据,比如省可以作为顶层的外接矩形的根节点,市会成为第二层的最小外接矩形,县或区会成为最小的切割的叶子节点。如下图所示,对江苏省的最小外接矩形的切割示意图:

2、R树的查找原理

如果我们要查找D1这块区域附近10km以内的商圈,首先在构建的R树索引上,D1的最小外接矩形是R8,R8之上的最小外接矩形是R3,R3的最小外接矩形是R1,这样经过初步筛选过滤,我们在求距离的时候,就可以把R2根节点及以下节点的外接矩形的地理位置排除在外,然后再筛选,可以排除二级节点R4和R5的外接矩形和其下面的叶子节点外接矩形多包含的地理区域,这样就可以把范围缩小至D1这块区域和R9和R10所包含的D2区域和D3区域进行做距离的比较,只需2次面的距离计算就可以求解出我们想要的结果,通过R树索引我们避免了很多不必要的开销。R树的原理其实在现实生活中也很好理解,假如我们在无锡市内要寻找某个地理位置附近的某个商圈,我们不会跑到南京市的商圈去跟无锡的商圈去做距离计算进行比较,因为在R树的索引下,我们可以避免这样不必要的计算。

3、R树的定义

(1) 除非它是根结点之外,所有叶子结点包含有m至M个记录索引(条目)。作为根结点的叶子结点所具有的记录个数可以少于m。通常,m=M/2。

(2)对于所有在叶子中存储的记录(条目),I是最小的可以在空间中完全覆盖这些记录所代表的点的矩形(注意:此处所说的“矩形”是可以扩展到高维空间的)。

(3)每一个非叶子结点拥有m至M个孩子结点,除非它是根结点。

(4)对于在非叶子结点上的每一个条目,i是最小的可以在空间上完全覆盖这些条目所代表的点的矩形(同性质2)。

(5)所有叶子结点都位于同一层,因此R树为平衡树。

4、R树的插入和删除操作

(1)R树的插入操作

如果插入的的区域X刚好在P2的最小限定箱内,但是又和D和E的最小限定箱保持相交或相离状态,则直接在P2的节点下面直接新增X最小外接矩形。

如果插入的区域Y刚好与原来的最小限定箱体相交,那么则直接会扩张P2的最小外接矩形,把Y区域给包含进去,同时将Y区域作为P2的最小外接矩形叶子节点。

根据R树的定义,P1的子节点不得超过4,但P1已经容纳了4个条目,新增的W区域刚好落尽P1区域里面,让P1的区域扩张为5个节点,不符合R树的平衡定义,此时需要通过分裂算法对R树进行平衡调整。

采用分裂算法对P1进行分裂,缩小P1的区域范围,让P1只包含A和B最先限定箱,新增P5区域,让C、W、K最小限定箱体在包含在P5的箱体之中,由于新增了P5的区域,原有的P1-P4超过了4个条目,使得P1-P5不能作为根节点,需要在P1-P5再往上构建2个新的根节点Q1-Q2,如上图所示,此时一棵新的R树就形成了。这里的问题是如何合理的分裂2个组,这里是分裂算法锁需要解决的问题,其思路大致是先选择两个对角线最远的2个区域作为种子进行构建新的箱体,通过计算不同的分裂限定箱,使得分裂出来的2个限定箱体尽量不要重叠。

在分裂的过程中,在挑选对角线最远的2个种子seed1和seed2,然后遵循所有的最小箱体,离哪个种子箱体比较近就跟谁在一组,这样最后分裂的箱体就能使得2个箱体尽量不会重叠。

当然刚才所描述的只是分裂算法的一种,其实还有很多的分裂算法,每个分裂算法都有各自的优缺点,这里展示一下不同的分裂算法对美国的构建的效果图:

(2)R树的删除

R树的删除比较复杂,会需要辅助函数来完成整个操作。抛开复杂的删除算法的描述,我们这里通过一个简单的例子来理解R树的删除过程。(根据R树的定义,假设节点的最大的条目数为4,最小条目数为2)。

如图我们要R1和R2所构建的箱体中删除区域d,由于区域d是在R11的箱体中,如果删除d的话,R11的箱体将会没有位置元素,所以会删除R11箱体,删除R11箱体后,我们发现R4下面原来有R11和R12的,现在只剩下R12了,违反了R树的M/2平衡定义(R4下面至少要有2个以上的箱体),出现向下溢出,下溢的条目R12将会加入一个链表,这个链表的中的箱体R12将会做为插入元素,对R树进行插入操作,采用分裂算法的逻辑对R树进行选种子重新进行R树平衡操作,这里不再赘述。

最后总结一下,R树解决了二维空间复杂的点线面等地理位置信息,将点线面不规则的几何问题转化为最小外接矩形来处理,然后通过分裂算法和矩形的相交相离来完成对R树的平衡操作,R树的查询可以通过R树的剪枝来排除无关联的区域来达到缩小计算区域的目的来提高计算的性能。

地理空间搜索 ->R树索引相关推荐

  1. geotools应用-JTS生产四叉树索引和R树索引

    微信搜索:"二十同学" 公众号,欢迎关注一条不一样的成长之路 geotools介绍 geotools官网https://geotools.org/ Geotools是一个java类 ...

  2. 基于R树索引的点面关系判断以及效率优化统计

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在之前的博客中,我分别介绍了基于网格的空间索引(http:// ...

  3. 如何在vs中创建r树索引代码_线段树详解与实现

    此篇文章用于记录<玩转数据结构>课程的学习笔记 什么是线段树 线段树也被称为区间树,英文名为Segment Tree或者Interval tree,是一种高级的数据结构.这种数据结构更多出 ...

  4. R树:处理空间存储问题

    转自大神的博客:http://blog.csdn.net/v_JULY_v/article/details/6530142/ R树:处理空间存储问题 相信经过上面第一节的介绍,你已经对B树或者B+树有 ...

  5. 从B 树、B+ 树、B* 树谈到R 树

    作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由weedge完成,R 树部分由Frank ...

  6. B树、B+树、B*树谈到R 树

    转自: https://blog.csdn.net/v_JULY_v/article/details/6530142 从B 树.B+ 树.B* 树谈到R 树 作者:July.weedge.Franki ...

  7. 从B树、B+树、B*树谈到R 树

    从B 树.B+ 树.B* 树谈到R 树 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由 ...

  8. [转]从B树、B+树、B*树谈到R 树

    来源:http://blog.csdn.net/v_july_v/article/details/6530142 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈 ...

  9. B树,B+树,B*树以及R树的介绍

    https://blog.csdn.net/peterchan88/article/details/52248714 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开 ...

  10. [置顶] 从B树、B+树、B*树谈到R 树

    从B 树.B+ 树.B* 树谈到R 树 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由 ...

最新文章

  1. hbase shell 查看列名_Hbase的简单命令使用
  2. vue案例 - vue-awesome-swiper实现h5滑动翻页效果
  3. 【Android 内存优化】Java 内存模型 ( Java 虚拟机内存模型 | 线程私有区 | 共享数据区 | 内存回收算法 | 引用计数 | 可达性分析 )
  4. 笔记本敲代码真香,包邮送一个!
  5. SqlConnection就一定要关闭吗?
  6. boost::type_erasure::negatable相关的测试程序
  7. rabbitmq java 应用实例
  8. One order search dynamic SQL build logic
  9. 设置SSH免密码自动登录(使用别名)
  10. 成功入职阿里P7后 一个技术老哥总结了这几句话
  11. python抽取指定url页面的title_Python使用scrapy爬虫,爬取今日头条首页推荐新闻
  12. Web API-随机性案例步骤
  13. 忘记 Apple Watch PIN 码,如何解锁 Apple Watch?
  14. 初学Java必须知道的几件事
  15. 今日分享:几个好用的文字转语音软件,来看看吧
  16. 猪齿鱼开源四周年庆典,邀您共享精彩瞬间
  17. 用Python把PDF文件转换成Word文档
  18. 听完周杰伦的《Mojito》,我不禁想用分子料理做几颗
  19. 贪心算法基础之活动时间安排(一)安排 51nod 贪心教程
  20. AS星尘(stardust)粒子系统 学习 3

热门文章

  1. 如何用PS的量度标尺工具调整图片
  2. 背景图片定位background-position用photoshopcs4标尺工具
  3. redies的复习总结
  4. wamp php不可用_PHPWAMP开启php
  5. 三种近场通信技术的特点及未来趋势
  6. js 生成二维码及打印
  7. 测试 minpy gpu加速 numpy 矩阵相乘 matmul matrix multiplication
  8. 生信技能树linux虚拟机,2019-08-21生信技能树Linux20题
  9. 微信小程序如何使用视频组件
  10. 【白板动画制作软件】万彩手影大师教程 | 分享在线视频