一种高效的基于线性四叉树编码的多级网格索引
来源:互联网 发布: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:复杂面对象建立多级网格索引后的效果
如图所示,对该复杂面对像建立多级网格索引后,网格的数目并没有随着点数的增加而增加,相反,相对于上面的简单面的网格索引,复杂面的网格数目要更少一些。这是多级网格索引的优点之一:网格索引的大小与空间对象的大小无关,与空间对象的外形有关,它真实反映出空间数据的分布状况,点越也密集的地方,网格越密,点稀疏的地方网格稀疏。
更详细的索引效果 ,我上传到我的资源里了,包含了全局网格,内部网格和边界网格等三种网格索引,以及它们的线性四叉树编码是如何存储的。感兴趣的同学可以下载:)
- 一种高效的基于线性四叉树编码的多级网格索引
- 一种高效的外部索引算法
- LSM-tree 一种高效的索引数据结构
- LSM-tree 一种高效的索引数据结构
- LSM-tree 一种高效的索引数据结构
- LSM-tree 一种高效的索引数据结构
- 一种基于javascript的索引建立
- 基于策略的一种高效内存池的实现
- 基于策略的一种高效内存池的实现
- COPY 一种接近最优的导航网格生成算法以及基于导航网格的寻路算法
- 基于重新划分的三角形网格简化的一种改进算法
- 高效的索引
- CascadingDropDown 多级级联操作的一种解决方案
- 一种基于R-Tree的改进多维索引[待正稿]
- 一种基于网格点来检测网格线的方法(可用于Camera Calibration)
- 一种网格去噪算法(基于平均面法向的均值滤波)
- 索引的一种组织形式
- 一种基于多字节编码的字符集GB2312
- 计算机科学领域会议排名列表
- ubuntu 10.04 VPN 搭建日志
- 运行时异常和非运行时异常的区别?
- 位计数(二进制中1的个数)--读Hacker's Delight
- 虚函数的实现方式
- 一种高效的基于线性四叉树编码的多级网格索引
- 感悟
- 远程客户端 访问 ASM 实例
- 租房协议样本
- 拒绝浮躁(copy来的)
- mount/umount命令详解
- MsgWaitForMultipleObjects用法
- C++ cin与cout
- 真不服气,下载东西还要我积分