在这里注册以来,只字未曾发表,有点不好意思了。刚好最近解决了一个空间索引方面的难题,写几个字以充门面:)
最近在做嵌入式GIS系统,由于PDA的CUP和内存跟不上,做东西的时候自己要斤斤计较不能再像PC机上那么大手大脚的浪费内存。开始的时候,加载矢量数据(暂时只针对shp文件)是先把全部几何对象读入内存,放在一个动态数组CArray上的,这样就造成打开一个shp文件的时间比较长,而且文件大的时候就根本加载不进去了比如一个100多M的shp文件。
原来的方式不能加载大文件,可现实是残酷的,在老板的一再催逼之下只能换种方式——使用空间索引。在系统启动的时候并不把几何对象的数据加载进内存,而是显示的时候临时从文件中读取当前视图范围内的对象。
现有的能查到的空间索引创建方法,大多都是“树”结构的,比如二叉树、四叉树等。采用树结构建立空间索引,必须要保存每个几何对象的矩形位置,也就是上下左右四个坐标(或者也有其他办法但我不知道的……),这样一来就有个问题——索引文件还是比较大的,点图层就非常明显,生成的索引文件比shp文件更大,而且当索引文件很大的时候,同样会遇到加载不了的问题。我就试过用四叉树建立索引,一个广东省的居民地生成的索引有好几十M,同样在PDA上加不了。。。。。
浪费了一周时间搞的四叉树没用,心灰意懒突然又柳暗花明,且听我细细道来:
现在很多webgis都是事先把地图配好,然后再切成一幅幅的图片,显示的时候再根据当前视图范围和显示层数计算出有哪几张图片需要显示再从服务器加载。这就是传说中的“瓦片”了。开源的三维系统WorldWind(上帝之眼)的影像也是采用这种方式加载的。这方式的特点就是根据图层范围和级别可以计算出需要多少个格网,以及每个格的行、列号,根据某个视图范围也可以计算出当前范围内有多少个格,每个格的行、列号。
到这里就清晰了,建立索引需要解决的是什么问题?无非就是如何最快的找到当前视图范围内有哪些几何对象!而worldwind的影像加载方法很适合,因为他可以直接计算出当前视图范围有多少格网、以及每个格网的行、列号,而不是像树结构那样需要从根节点递归搜索。只要我们知道这个图层在每个格网中有多少几何对象,每个几何对象的记录号——shp文件中只要知道了记录号就可以非常方便的定位读取,就可以实现我们创建空间索引的目的了。
创建方法是这样的:使用WorldWind切割影像的方法对整个图层范围进行分割,得到n个格网,然后查询每个格网范围内的几何对象(查询的操作我是通过ArcEngine做的),然后按格式保存到索引文件内即可。下面发索引文件的结构图给大家看看吧,不多说了。
这种方式创建的空间索引有几个好处:索引文件很小,由于不保存几何对象的范围,只是保存了记录号,一个几十M的shp文件,索引才几K;检索比较快,知道行列号后,只需要一次读取两个int类型的结构就可以知道这个格内有多少几何对象,读N个int类型的内容就可得到这个格内所有的几何对象记录号了(格子内有多少几何对象就读多少次)。
空间索引再配合图层的可见比例尺,以及空间索引的级别,可以很好的实现在PDA上面加载大shp文件了!现在存储卡已经有好几G了,虽然跟PC机差太远,但加载几百M的数据再不是做梦了嘿嘿
此外,在PDA上面也可以用worldwind的方法加载影像图,也就是先切图片,再一块块加载显示。速度还不错,就是需要空间大
《远景地理信息系统|RemoteGIS》
RemoteGIS是基于HTML5开发的高性能WEBGIS,支持百万级别矢量数据。
详细介绍和在线演示地址:www.remotegis.net