文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/
1.背景
针对判断一个点落在面图层中哪个要素上的需求,在我之前的博客:WebGIS中一种根据网格索引判断点面关系的方法(http://www.cnblogs.com/naaoveGIS/p/5148185.html)中有详细的描述。其原理大致为:
其处理步骤为:
2.当前网格索引的几个缺点
a.网格索引方案分为了一个索引文件和一个数据文件,任何请求进入时均会先读取索引文件,再读取数据文件,那么很容易出现资源争抢情况,不利于并发支持。
b.网格的大小会严重影响到查询效率,但是如果网格建立的足够小,那么索引文件不断增大,同样会导致磁盘寻址花费的时间增多。
c.数据的读取一定要经过两次IO,一次读索引,一次读数据,会影响读取效率。
3.方案的优化,基于网格索引的索引四叉树划分
四叉树、R树等均是空间索引常用的算法,这里我选择使用四叉索引来进行进一步优化。四叉树索引原理非常简单,即将一个范围根据深度,不断平分,如图所示:
这里优化思路是:将要素首先进行四叉树平分,然后对每个叶子节点包含的范围再进行网格索引生成:
4.优化方案的详细描述
4.1索引的生成步骤
a.首先生成数据文件。
b.通过设置的四叉树深度,算出叶子节点的个数。然后通过获取到的要素四角坐标,算出叶子节点的四角范围:leafminx、leafminy、leafmaxx、leafmaxy。
c.根据要素个数和网格因子,算出整个范围内网格的个数,用整个范围的四角坐标与网格因子计算,得出一个网格的BlockXsize和BlokcYsize。
d.针对每个叶子节点,建立该节点的网格索引,索引中包含了网格与要素的对应关系。
生成文件截图:
4.2数据读取
a.读取配置获取到要素的四角范围mapminx、mapminy、mapmaxx、mapmaxy、leafgeoxsize、leafgeoysize。
b.通过mapminx、mapminy、leafgeoxsize、leafgeoysize参数算出该XY坐标所在的网格索引编号。
c.读取该网格索引,获取到该索引的leafminx、leafminy、leafmaxx、leafmaxy、blockxsize、blockysize。
d.通过leafmaxx、leafmaxy以及blockxsize、blockysize算出XY所在网格索引的字节位置pos,将磁盘指针移动至该pos处。
e.获取到索引中包含的要素信息,比如要素所在的数据文件中的datapos。
f.读取数据文件,在该文件的datapos处将详细信息读取返回。
5.方案优点总结
a.将一个大索引文件分成多个索引文件,在大量随机点并发访问时,可以将压力负载至各文件上,减少同一文件读取时的资源争抢IO瓶颈。
b.每一个索引文件大小大大减小,读取会更快,磁盘寻址也会更快。
c.为增加网格命中单个(非多个)要素的概率,可以将每个网格的大小进一步缩小,其导致的网格索引增大会平摊至每个网格索引上,从而使副作用变小。
6.进一步优化
a.在读取索引基本信息后可以将该信息缓存至内存中,减少Config文件的IO次数。
b.生成索引时,如果一个网格只包含了一个要素的信息,可以将该信息也整合至网格索引中。这样,查询时,如果查询到的网格只包含单个要素,则可以直接在索引中将要素信息获取,而不需要再对数据索引做读取操作,减少对数据索引的IO次数。
-----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/
如果您觉得本文确实帮助了您,可以微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^