传统的GIS数据库,如ArcGIS这种传统桌面型的软件,主要还是强调测绘模型数据的规范化输入。GIS的本质上在于多维索引,对一个最简单的平面地图来说,主要就是靠最原始的GPS芯片返回的经纬度坐标。问题是,即使静止在同一个位置,由于地球在自转(?),卫星反射返回的信号时间可能不一样,这样得到的经纬度坐标不能保持一模一样。更不用说移动中的目标(汽车)了。中国的GPS坐标还会涉及到一个非线性的加密扰乱,人为地降低精度。
PostgreSQL(pg)数据库有一个插件,可以用于存储POI(Place of Interest,或Point of Interest),即附带了经纬度坐标属性的数据记录。经纬度坐标可以认为是2维的数值型数据,但是坐标系本身却又有额外的问题:经纬度坐标是球面的,并且它有多不同的国际标准。假如我们不考虑这个,即不要求绝对精确的网格系统,只要求保证每个维度上的严格偏序关系成立即可,则GIS数据库引擎本身的目标就是:
给定一个POI查询位置,快速返回一个包含此POI的最小区域范围?
考虑SQL数据库里的key,它是一个1维的value range index。而GIS的key是2维的,如何实现索引呢?一般就是R树(包围盒)、k-d树(相当于扩展的B+树,每个维度轮流索引)或者是某些混合方案,当然还有一个基于GeoHash的快速定位。原则上,不同的最小区域在边界处可能是有重叠的,因此,为保证查询结果不会遗漏,需要查询一个POI所在区域的9宫格邻域,当然也有使用6边形的,不规则多边形、三角形当然也可以(数学的离散几何里的平面镶嵌)。
对R树而言,最简单的是基于实时计算机图形学里的BSP概念的划分,当然,也可以使用4叉树、八叉树,n叉树,其本质就是对于一个2维的(x,y)坐标,划分函数,要求能够高效决定查询落在哪个子范围内,如此就可以快速地以log复杂度定位最终的最小包围区域了。考虑到实际这些最小区域中的POI对象的密度不均匀,这些划分方案最好应该是自适应的,即:原生的就解决掉数据倾斜(分布不均匀)的问题。
当需要将一个平面地图绘制出来时,无非就是一个分层问题,以及每个图元的2D图形学绘制。三角形、矩形这类简单的对应建筑物的,以及河流、道路对应的Bezier曲线。GIS中可能需要