一种高效的基于线性四叉树编码的多级网格索引

来源:互联网 发布:c语言double什么意思 编辑:程序博客网 时间:2024/04/28 15:35

目前主流GIS平台厂商的空间数据库引擎,用的基本是四叉树,R树等索引,主要是供海量的空间数据存储和显示用的,以我的理解(我不负责空间数据引擎,了解有限),它们最重要的功能是:传入一个正交查询区域(矩形),快速计算出所有被这个矩形包含的空间对象。这对于一般的应用也都可以满足。

 

但是,在空间分析中,最通用的,比如空间查询,就不是那么回事了。特别是在大数据量下的,很多时候建空间索引的效果就不明显。最主要的原因是,GIS应有中的真实数据太变态了,什么形状的都有,特别是面数据,动不动就是成千上万个点,成百上千个子对象(也就是面中有小洞),对于这种面,如果只对它们的的最小外包矩形(MBR--Minimum Bounding Rectangle)建立索引,是没有多大作用的。即使空间对象的MBR相交了,也不能表示他们一定相交。而且,天知道这个面里包含了多少个洞,就算是有查询对象的MBR完全落在被查询面的MBR中,也不能说明被包含了,如果不小心落在洞里面的话。

 

对于空间查询来说,该功能要非常精确查找出查询对象与被查询对象之间的包含,被包含,相交等空间关系。注意:是非常精确,比如包含查询,哪怕有一点点边界相交都不行!这就很麻烦了,如果是大范围的面查询面,那只能是将所有与查询面的MBR相交的被查询面,一个一个的和查询面进行是否包含的判断(先判断两面边界是否相交,如果不想交,在判断内点是否被包含)。当被查询面特别多时,这将非常耗时间。特别是如果数据不是存储在本地时,每次都要先将数据读到本地,分析过程中相当部分时间都在读数据,CPU占用率几乎为0,特别是很多离被查询面边界很远的对象,明显包含(或相离),也参与运算,太痛苦了。如果能设计一种索引,能准确的“知道”空间数据的数据分布情况以及邻近关系,这样,每次在分析时,都能过滤掉大部分与明显合法/非法的数据,只对那些挨得很近的、需要精确计算的数据进行分析操作,这样就加快分析速度了。我是出于这种想法,开始做这个多级网格索引的。

 

在介绍多级网格索引之前,先了解下什么是网格索引和四叉树索引。网格索引是最常用的空间索引之一,每次都将所有空间数据集合的MBR划分为M*M个的网格,对于每个网格,如果有空间对象的边界经过,则记录下该空间对象的信息。大概就这样,简单吧~,这种索引是我开发中最常用到的(这两年工作体会最深的是,在处理大数据量时,越简单的数据结构往往越高效,更重要的是易于维护)。四叉树索引是经典的基于MBR的空间索引,我就懒得写了^_^。它们两者的最大区别是,网格索引是为空间数据本身建立索引,而四叉树索引是为空间数据的MBR建立索引!下面是我在网上看到的链接,感觉讲的很好,简明扼要的介绍了两种索引的原理及其在GIS中的应用(熟悉GIS空间索引的同学可以略过):

网格索引介绍:   http://geochenyj.blog.sohu.com/131711611.html

四叉树索引介绍:http://geochenyj.blog.sohu.com/131711865.html

 

        我最初的想法是这样的:扩展网格索引,使之能标示出面对像的内部包含的网格。但是这么做有个问题,如果面对像特别大,它对应的内部网格就会很多,如果面内部全都用小网格填充的话,将导致索引的存储空间过大。于是又想,能不能结合四叉树索引,建立多层网格索引,比如划分十层网格就是:

第一层 将原数据集MBR划分为 1*1个网格,

第二层 将原数据集MBR划分为 2*2个网格,

第三层 将原数据集MBR划分为 4*4个网格,

第三层 将原数据集MBR划分为 8*8个网格,

...

第十层 将原数据集MBR划分为 1024*1024个网格

 

对于不同层级的网格索引,使用线性四叉树编码进行管理,使得相邻网格之间可以跨层级查找,并统一存储在一维数组中。对于大的面,如果是边界经过的网格,用尽可能小的面对像去标示,而对于内部网格,则用尽可能大的网格去填充它,这样,既达到了同样的效果,又极大的节省了存储空间。在做空间查询时,可以利用对象的网格之间的相互关系,过滤掉没必要参与运算的网格索引。例如:

如果被查询对象完全落在查询面的内部网格中,则肯定被包含;

如果被查询对象的网格与查询面的网格没有交集,则肯定相离;

如果被查询对象的内部网格(边界网格)经过查询对象的边界网格(内部网格),则肯定相交;

....

 

这样一来,空间查询的性能就能提高了,毕竟,很多情况下,需要做精确几何运算的数据,还是不多的。以下就是我的多级网格索引实验效果截图。

 

 

图1:简单面对象

 

 

 


 

 

图2:简单面对象建立多级网格索引后的效果

 

如图所示,在建立起多级网格索引后,整个数据集的MBR都被大大小小的网格填充完毕,而且距离面对像边界越近的地方网格越小,距离边界越远网格越大。这样算下来,整个多级网格索引所占的内存空间也很少了。该索引可以很明显的区分出面的外部区域和内部内部:蓝色部分的网格代表是在内部区域,而绿色部分的网格代表外部区域。边界所在的网格由于太小了,Supermap Deskpro不显示,但在视频中是可以看到的。再看看对复杂点的面对像建立网格索引的效果。该面对象由32288个点组成。

 

 

图3:复杂面对象

 

 

图4:复杂面对象建立多级网格索引后的效果

 

       如图所示,对该复杂面对像建立多级网格索引后,网格的数目并没有随着点数的增加而增加,相反,相对于上面的简单面的网格索引,复杂面的网格数目要更少一些。这是多级网格索引的优点之一:网格索引的大小与空间对象的大小无关,与空间对象的外形有关,它真实反映出空间数据的分布状况,点越也密集的地方,网格越密,点稀疏的地方网格稀疏。

      更详细的索引效果 ,我上传到我的资源里了,包含了全局网格,内部网格和边界网格等三种网格索引,以及它们的线性四叉树编码是如何存储的。感兴趣的同学可以下载:)

原创粉丝点击