我的GIS/CS学习笔记:https://github.com/yunwei37/ZJU-CS-GIS-ClassNotes
<一个浙江大学本科生的计算机、地理信息科学知识库 >
详细代码可在其中查看
空间索引
在谈论空间索引之前,我们必须了解数据索引的概念:索引是为了提高数据集的检索效率。打个比喻,一本书的目录就是这本书的内容的“索引”,我们查看感兴趣的内容前,通过查看书的目录去快速查找对应的内容,而不是一字一句地找我们感兴趣的内容;就像这样,事先构建的索引可以有效地加速查询的速度。
然而,和一般的数据相比,有效地查询地理空间数据是相当大的挑战,因为数据是二维的(有时候甚至更高),不能用如传统的B+树这样标准的索引技术来加速查询位置相关的数据。因此,我们就引入了空间索引技术来解决这个问题。
空间索引的定义:
依据空间实体的位置和形状或空间实体之间的某种空间关系,按一定顺序排列的一种数据结构,其中包含空间实体的概要信息,如对象的标识,最小边界矩形及指向空间实体数据的指针
常见的空间索引技术有网格索引、四叉树索引,空间填充曲线索引,以及最用于地理空间数据库的R树索引以及相关变体等等。
网格索引
网格索引的基本思想是将研究区域用横竖线划分大小相等和不等的网格,每个网格可视为一个桶(bucket),构建时记录落入每一个网格区域内的空间实体编号。
进行空间查询时,先计算出查询对象所在网格,再在该网格中快速查
询所选空间实体
-
网格索引优点:简单,易于实现,具有良好的可扩展性;
-
网格索引缺点:网格大小影响网格索引检索性能
理想的情况下,网格大小是使网格索引记录不至于过多,同时每个网格内的要素个数的均值与最大值尽可能地少。如要获得较好的网格划分,可以根据用户的多次试验来获得经验最佳值, 也可以通过建立地理要素的大小和空间分布等特征值来定量确定网格大小。
网格索引的实现这里暂时没有涉及。
空间填充曲线索引
常用的空间索引曲线有z曲线、希尔伯特曲线,其目的是在空间网格的基础上降低空间维度,以便于在顺序读取的磁盘上存取信息。
空间填充曲线(space-filling curve)是一条连续曲线,自身没有任何交叉;通过访问所有单元格来填充包含均匀网格的四边形。
-
z曲线
-
希尔伯特曲线
Z曲线和Hilbert曲线共同特点:
- 填充曲线值临近的网格,其空间位置通常也相对临近;
- 任何一种空间排列都不能完全保证二维数据空间关系的维护(编号相邻,空间位置可能很远)
不同点:
- Hilbert曲线的数据聚集特性更优,Z曲线的数据聚集特性较差
- Hilbert曲线的映射过程较复杂,Z曲线的映射过程较简单
z曲线实现:
Z-curve曲线的二维坐标与Z值的相互转换:
基于bit-shuffling思想,实现二维坐标(coor)与Z值(value)的相互转换。order为Z-Curve的阶数,order为4时,平面网格大小为(2^4, 2^4),即16x16。
/*
* zorder - Calculate the index number (Z-value) of the point (represented by coordinate) in the Z-curve with given order
*/
void zorder(int order, int& value, int coor[2])
{
// Calculate the z-order by bit shuffling
value = 0;
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < order; ++j) {
// Task 1.1 zorder,修改以下代码
int mask = 1<<j;
// Check whether the value in the position is 1
if (coor[1-i] & mask)
// Do bit shuffling
value |= 1 << (i + j*2);
}
}
}
/*
* izorder - Calculate the coordinate of the point with given Z-value and order
*/
void izorder(int order, int value, int coor[2])
{
// Initialize the coordinate to zeros
for (int i = 0; i < 2; ++i)
coor[i] = 0;
// Task 1.2 izoder
// Write your code here
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < order; ++j) {
// Task 1.1 zorder,修改以下代码
int mask = 1 << j*2+i;
// Check whether the value in the position is 1
if (value & mask)
// Do bit shuffling
coor[1-i] |= 1 << j;
}
}
}
希尔伯特曲线实现
Hilbert Curve的二维坐标与H值的相互转换:
基于linear-quadtrees递归填充思想,实现二维坐标(coor)到H值(value)的相