GIS空间索引

微信搜索:“二十同学” 公众号,欢迎关注一条不一样的成长之路

在GIS系统中,空间索引技术就是通过更加有效的组织方式,抽取与空间定位相关的信息组成对原空间数据的索引,以较小的数据量管理大量数据的查询,从而提高空间查询的效率和空间定位的准确性。

常见的GIS空间索引

  1. KD树空间索引(二叉树索引)、KDB树索引
  2. R树、R+树空间索引
  3. G树索引
  4. 四叉树索引及其分类(点四叉树索引、MX四叉树索引、PR四叉树索引、CIF四叉树索引、基于固定网格划分的四叉树索引)
  5. CELL树索引
  6. BSP树空间索引

1.关于KD树

在计算机科学里,k-d树(k-维树的缩写)是在k维欧几里德空间组织点的数据结构。k-d树是每个节点都为k维点的二叉树。所有非叶子节点可以视作用一个超平面把空间分区成两部分。在超平面左边的点代表节点的左子树,在超平面右边的点代表节点的右子树。超平面的方向可以用下述方法来选择:每个节点都与k维中垂直于超平面的那一维有关。因此,如果选择按照x轴划分,所有x值小于指定值的节点都会出现在左子树,所有x值大于指定值的节点都会出现在右子树。这样,超平面可以用该x值来确定,其法矢为x轴的单位矢量。(来自维基百科

GIS中的KD树

KD树的基本形式存储了K维空间点。KD树的每个内部节点都包含一个点,并且和一个矩形区域相对应。树的根节点和整个研究区域相对应。树中奇数层次上的点的X坐标和偶数层次上的点的Y坐标把矩形区域分成两部分。在KD树结构中,通过沿着树下降到达一个树叶节点的方式来添加一个新点。KD树的查找是从根节点开始,查看所存储的节点(分裂的点)是否被包括在查找范围内以及和左子树或者右子树是否有交叠。对于每个和查询范围交叠的子树,查询过程将重复执行直到到达树叶那一级为止

示意图如下:

 

KD树的每个内部结点都包含一个点,每个结点表示k维空间中的一个点,并且和一个矩形区域相对应,树的根结点和整个研究区域相对应。KD树要求用平行于坐标轴的纵横分界线将平面分为若干区域,使每个区域中的点数不超过给定值。树中奇数层次上的点的x坐标和偶数层次上的点的y坐标把矩形区域分成两部分。分界线仅起分界的作用,它的选取没有硬性的限制。一般选用通过某点的横向线或者纵向线。分界线上的点,对左右分界线来说属于右部,对上下分界线来说属于上部。 如图:

KD树查找

伪代码

Algorithm KD_Search(R,P)
/*在根结点为R的KD树(子树)中查找点P。找到则返回结点,否则返回NULL*/
Begin
  If R=NULL Then Return NULL;//Not Found
  If R. Point=P Then Return R;//Found;
Else
  Begin
    d:=Discriminator of R;
    If P[d] <R Point[d] Then /*比较P点与R结点的第D维的值*/
      KD_Search(R.Lchild,P)//在左子树继续查找
    Else
      KD_Search(R.Rchild,P)//在右子树继续查找
  End
End.

KD树插入

伪代码

Algorithm KD_Insert(R,P,F)
/*在根结点为R的KD树(子树)中插入点P,F为R的父结点*/
Begin
  If R=NULL Then
    Begin
      Create a Node P;
      If F=NULL Then //KD树为空
        Root:=P//P成为根结点
      Else
        If R Is the Left child of F Then
          F.Lchild:=P//P作为F的左孩子
        Else F.Rchild:=P//P作为F的右孩子
    End
    Else
      Begin
        d:=Discriminator of R;
        If P[d]R.Point[d] Then/*比较P点与R点的第D维的值*/
          KD_Insert(R.Lchild,P,R)//插入到左子树中
        Else
         KD_Insert(R.Rchild,P,R)// 插入到右子树中
     End;
End;

KD树删除

Algorithm KD_Delete(R,P)
/*在根结点为R的KD树(子树)中点P,删除成功返回True,否则返回False */
Begin
      Q:= KD_Search(R,P);//Q为要删除的对象
      LABEL;
      If Q=NULL Then Return False;//Not found
      If (Q.Lchild=NULL) And (Q.Rchild=NULL) Then
        Begin//第一种情况
          F:=Q is Father Node;
          If Q is the left Child of F then
            F.Lchild:=NULL
          Else F.Rchild:NULL;
            Delete Node Q;
          Return True;
       End
    Else
      Begin
         If (Q.Rchild=NULL) Then第三种情况转化为第二种情况处理
            Q.Rchild:=Q.Lchild;
         M:=FindMin(Q.Rchild);
      (Q)←(M);//将M结点的值赋给Q结点
        Q:=M;//让Q指向M结点
        GOTO LABEL;//继续删M结点
    End
end

KDB树是KD树与B树的结合,它由两种基本的结构——区域页(region pages,非叶结点)和点页(point pages,叶结点)组成。如图所示

 

点页存储点目标,区域页存储索引子空间的描述及指向下层页的指针。在KDB树中,区域页则显式地存储了这些子空间信息。区域页的子空间(如s11,S12和s13)两两不相交,且一起构成该区域页的矩形索引空间(如S1)即父区域页的子空间。

KDB-tree包括两种类型的页:

  • 区域页面: (region, child)对的集合包含边界区域的描述,加上该区域指向子页面的指针。
  • 点页面:(point, location)对的集合。数据库方面,location可能指向数据库记录的索引,对于K维空间中的点,可以被看成该空间中的点坐标。

当向KDB树插入元素时,导致节点的规模超过它的最优规模,页面溢出。因为KDB-tree的目的是优化外部内存访问,例如硬盘访问,当节点的规模超过外部内存页大小,一个叶被认为是溢出。通过插入和删除操作,KDB树保持一些属性:

  • 该图是一个多叉树,区域页面指向子页面,并且不能为空。点页面是叶子节点。
  • 对于所有查询,到达叶节点的路径长度是相同的。
  • 如果根节点是区域页面,区域的联合是整个搜索空间。
  • 当一个区域页面的(region, child)对的儿子也是一个区域页面,所有儿子区域的联合是该页面。
  • 如果儿子是一个点页面,儿子中所有点必须被该区域包含。

 

2.关于R树,R+树

R树是一种多级平衡树,它是B树在多维空间上的扩展。在R树中存放的数据并不是原始数据,而是这些数据的最小边界矩形(MBR),空间对象的MBR被包含于R树的叶结点中。在R树空间索引中,设计一些虚拟的矩形目标,将一些空间位置相近的目标,包含在这个矩形内,这些虚拟的矩形作为空间索引,它含有所包含的空间对象的指针。虚拟矩形还可以进一步细分,即可以再套虚拟矩形形成多级空间索引。

R树索引是一种高效的空间索引,它是B树在多维空间的扩展,也是平衡树。R树的结构类似于B+树的平衡树。

 

R树及其特点

对于一棵M阶的R树,R树中每个非叶子结点都由若干个(p,MBR)数据对组成。MBR(Minimal Boundary Rect)为包含其对应孩子的最小边界矩形。这个最小外接矩形是个广义上的概念,二维上是矩形,三维空间上就是长方体MBV(Minimum Bounding Volume),以此类推到高维空间。p是指向其对应该子结点的指针。

叶子结点则是由若干个(OI,MBR)组成,其中MBR为包含对应的空间对象的最小外接矩形。OI是空间对象的标号,通过该标号可以得到对应空间对象的详细的信息。

R树查找

伪代码如下:

Algorithm R_Search(N,W) {
    /*在根结点为N的R树中查找所有与W相交的数据矩形*/

    if (N.LEVEL==0) //N是叶子结点
        //  Return all data rectangles that intersect with W;
    else //N不是叶子结点
        for (i=1;i<N.COUNT;i++)
            if (N.MBRi;Intersect with W)
              R_Search (N.pi,W);
}

 

R树插入

伪代码如下:

Algorithm R_Insert(N,P){
/*向根结点为N的R树中插入数据矩形P*/
  if (N.LEVEL==0) {
        Insert P into N;
        if (N overfill) Split N;
    }
  else {//N是中间结点
      // Choose the entry in N whose rectangle needs 
      // least area enlargement to include the new data rectangle.
      // Resolve ties by choosing the entry with the rectangle of
      // smallest area (Let's suppose it's entry is the answer)
      R_Insert(N.pi,P);
      // Adjust N.MBRi to enclose all rectangle in its child node;
    }
}

R树删除

伪代码如下:

Algorithm R_Delete(N,P){
/*从根结点为N的R树中删除数据矩形P*/
  if (N:LEVEL==0) 
  {//N是叶结点
      if (N包含P)
      {
          // 从N中删除P
          N.COUNT=N.COUNT-1;
          return true;
      }
      else
          return false;
  }
  else
  {
      for (i =1;i<N.COUNT;i++)
          if (N.MBRi intersects with P)
            if (R_Delete(N.pi,P))
                if (N.pi,COUNT=m)
                    // Adjust N.MBRi to enclose all child's rectangles;
                else
                {
                    // Reinsert all remain entries of N.pi and delete N.pi;
                    // if N underfilled, Reinsert alI         
                    // remain entries of it and
                    // delete it too...;〗
                }
  }
}

 

地图对应的R树结构

 

关于R+树

在R树的构造中,要求虚拟矩形一般尽可能少地重叠,并且一个空间对通常仅被一个虚拟矩形所包含。但空间对象千姿百态,它们的最小矩形范围经常重叠。 R+ 改进R树的空间索引,为了平衡,它允许虚拟矩形相互重叠,并允许一个空间目标被多个虚拟矩形所包含。

R+树索引的主要特征是在R+树中兄弟节点对应的空间区域没有重叠,这样划分空间可以使空间搜索的效率提高。R+树也是R树的一个变种,在R+树中,兄弟节点对应的空间区域没有重叠,这样划分空间可以使空间搜索的效率提高。R+树对空间的划分及其索引对象的MBR组织如下:

 

R+树查找

算法Search(R,W)/R:R+树的根结点,W:查找矩形窗口/

S1.[查找中间结点]
If R是非叶结点 then
  For R的每一索引项(p,MBR) DO
      If MBRW then Search(p,WMBR)
S2.[查找叶子结点]
If R是叶子结点 then
  检查R的每一数据项(OI,MBR)
  RETURN所有与W相交的数据矩形

由查找算法可知,与R树相比,对于区域查找,查找路径应该可以减少,但依旧可能有多条;对于点查找,则可以通过一条路径得到查找结果。

R+树插入

Algorithm Insert(R,IR){ 
/*R为R+树的根结点,IR为要插入的数据矩形*/
    I1.[查找中间结点]
    if (R是非叶结点) then
        for (p,MBR) do
          if (MBRIR0) Insert(CHILD,IR);
    I2.[查找叶子结点]
    if (R是叶结点) then
      if (R已有M个数据项)then SplitNode(R);
      else 插入IR于R;
}

 

R+树删除

Algorithm Delete (R,IR){ 
/*R为R+树的根结点,IR为要删除的数据矩形*/
Dl.[查找中间结点]
if (R是非叶结点)then
  for R的每一索引项(p,MBR)do
    if (MBRIR0) then Delete(CHILD,IR);
D2.[查找叶子结点]
if (R是叶结点) then
  从R中删除IR且调整R的父结点中对应的目录矩形;
}

结点分裂

Algorithm SplitNode(R){
SN1[寻找一个划分]
调用Partition;
// 设(p,MBR)为与R相关联的索引项,S1与S2表示划分得到的两个子区域,
// 创建两个新结点n1=(p1,MBR1)与n2=(p2,MBR2),MBRi=MBRSi,i=1,2;〗
SN2[填充新结点]
For (R的每一项(pk,MBRk) do
  if (MBRkMBR==MBRk) then // MBR k完全包含于MBRi
      put(pk,MBRk) in ni;
  else // MBR k与MBR1及MBR2都重叠。
      if (R是叶结点) then
        put (pk,MBRk) in n1 与n2;
      else
        〖用划分线继续分裂(pk,MBRk)所指结点,设得到的新结点为:nk1= 
      (pk1,MBRk1),nk2=(pk2,MBRk2),MBRki完全包含于MBRi,将  
          nki加入到ni,i=I,2;〗
SN3[向上传播结点分裂操作]
if (R是根结点)
    创建一新根结点,n1与n2为其两孩子结点;
else
  // 在R的父结点PR中,用n1与n2替换R。
  // 如果PR的索引项个数超过M,那么调用SplitNode(PR)。
}

3.G树

G树是一种多层次的动态生长的格网结构。与KD树类似,G树也按照循环交替的方式分割空间,但是它是采取平均分割空间的方法。假设各维的值,即有关的属性值,都能规范到0到1之间的值,并且每个区域中不能超过2点。如果超过2点,继续循环交替分割空间,直至每个区域不超过2点为止

 

这种空间分割策略有3个特点:

  1. 区域的二进制编码是全序的;
  2. 分割所得的区域集合构成平面的一个划分;
  3. 区域的二进制编码的位数越多,则该区域越小,它是其编码前缀所代表的区域的子空间

4.四叉树索引及其分类

在GIS中,四叉树索引又分为很多种类,包括点四叉树、PR四叉树、MX四叉树、CIF四叉树等

<1>点四叉树(Point Quadtree)

点四叉树与KD树相似,两者的差别是在点四叉树中,空间被分割成四个矩形。四个不同的多边形分别是:SW、NW、SE、NE。其搜索过程和KD树相似,当一个点包含在搜索范围内时被记录下来,当一个子树和搜索范围有交叠时它将被穿过。下图:点四叉树示意图

点四叉树是QuadTree的一个变种,主要是针对空间点的存储表过与索引(Finkel and Bentley,1974),与KD树相似,两者的差别是在点四叉树中,空间被分割成四个矩形,四个不同的多边形对应于SW、NW、SE、NE四个象限。

对于k维数据空间而言,以新插入的点为中心将其对应索引空间分为两两不相交的2k个子空间,依次与它的2k个孩子结点相对应,对于位于某一子空间的点,则分配给对应的子树。

点四叉树的每个结点存储了一个空间点的信息及2k个孩子结点的指针,且隐式地与一个索引空间相对应。其搜索过程和KD树相似,当一个点包含在搜索范围内时被记录下来,当一个子树和搜索范围有交叠时它将被穿过。如果想从Point QuadTree中删除一个点的话,则会引起相应的子树的重建,一个简单的方法是将所有子树上的数据重新插入。如图是二维空间的一棵点四叉树的例子。

优势&劣势

点四叉树的优点是结构简单,对于精确匹配的点查找性能较高。

其缺点有:

  1. 树的动态性差,删除结点处理复杂;
  2. 树的结构由点的插入顺序决定,难以保证树深度的平衡;
  3. 区域查找性能较差;
  4. 对于非点状空间目标,必须采用目标近似与空间映射技术,效率较差;
  5. 不利于树的外存存储与页面调度;
  6. 每个结点须存储2k个指针域且其中叶子结点中包含许多空指针,尤其是当k较大时,空间存储开销大,空间利用率低。

<2>PR四叉树(Point Region Quadtree)

PR四叉树是点四叉树的一个变种,它不使用数据集中的点来分割空间。在PR四叉树中,每次分割空间时,都是将一个正方形分成四个相等的子正方形,依次进行,直到每个正方形的内容不超过所给定的桶量(比如一个对象)为止。下图:PR四叉树

PR四叉树是点四叉树的一个变种,它不使用数据集中的点来分割空间。在PR四叉树中,每次分割空间时,都是将一个正方形分成四个相等的子正方形,依次进行,直到每个正方形的内容不超过所给定的桶量(比如一个对象)为止。

PR四叉树与MX四叉树的主要区别是:

  1. 叶子结点可能不在树的同一层次;
  2. PR四叉树的叶结点数及树的深度都小于MX四叉树,因此PR四叉树的检索效率要高于MX四叉树。

 

<3>MX四叉树

空间被分割成四个矩形。四个不同的多边形分别是:SW、NW、SE、NE。每次分割空间时,都是将一个正方形分成四个相等的子正方形,依次进行,直到每个正方形的内容不超过所给定的桶量(比如一个对象)为止。

所有的数据都处在四叉树的同一个深度,多个点可以由一个指针联接。

MX四叉树索引即Matrix四叉树索引。在k维空间中,整个数据空间被分割成四个矩形。四个不同的多边形对应于SW、NW、SE、NE四个象限。每次分割空间时,都是将一个正方形分成四个相等的子正方形,依次重复地进行2k次等分,直到每个正方形的内容不超过所给定的桶量(比如一个对象)为止,空间中的每一点都属于某一象限且位于该象限内,每一象限均只与一个空间相关联。

在MX四叉树中,叶子结点的黑结点或空结点分别表示数据空间某一位置空间点的存在与否。如图所示为二维空间的一棵MX四叉树的例子。

<4>CIF四叉树

CIF(Caltech Intermediate From)四叉树是针对表示VLSI(Very Large Scale Integration)应用中的小矩形而提出的,它可以用于索引矩形及其他形体。

它的组织方式与区域四叉树相似,数据空间被递归地细分直至产生的子象限不再包含任何矩形。在分解的过程中,与任一划分线相交的矩形与该划分线对应的象限相关联,属于一个象限的矩形不能属于祖先象限,换句话说,矩形只属于完全包围它的最小象限。

下图是二维空间一颗CIF树的例子(这里假设数据桶的容量为3个矩形)。

 

<5>基于固定网格划分的四叉树索引

先看下图:

非叶结点数:MAX_NONLEAFNODE_NUM=∑N−1i=04i∑i=0N−14i

叶结点数:MAX_LEAFNODE_NUM=2^N×2^N=4N

非叶结点从四叉树的根结点开始编号:

从0到MAX_NONLEAFNODE_NUM-1

叶子结点则从MAX_NONLEAFNODE_NUM开始编号,

直到MAX_NONLEAFNODE_NUM+MAX_LEAFNODE_NUM-1

在四叉树中,空间要素标识记录在其外包络矩形所覆盖的每一个叶结点中,但是,当同一父亲的四个兄弟结点都要记录该空间要素标识时,则只将该空间要素标识记录在该父亲结点上,并按这一规则向上层推进。

在基于固定网格空间划分的四叉树空间索引机制中,二维空间范围被划分为一系列大小相等的棋盘状矩形,即将地理空间的长和宽在X和Y方向上进行2^N等分,形成2^N×2^N的网格,并以此建立N级四叉树。

在四叉树中,空间要素标识记录在其外包络矩形所覆盖的每一个叶结点中。但当同一父亲的四个兄弟结点都要记录该空间要素标识时,则只将该空间要素标识记录在该父亲结点上,并按这一规则向上层推进。

把一幅2^n×2^n的图像压缩成线性四叉树的过程

  1. 按Morton码把图象读入一维数组。
  2. 相邻的四个象元比较,一致的合并,只记录第一个象元的Morton码。循环比较所形成的大块,相同的再合并,直到不能合并为止。 
  3. 进一步用游程长度编码压缩。压缩时只记录第一个象元的Morton码。

解码时,根据Morton码就可知道象元在图像中的位置(左上角),本Morton码和下一个Morton码之差即为象元个数。知道了象元的个数和象元的位置就可恢复出图像了。

  1. 按Morton码读入一维数组。
    Morton码:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    象 元 值: A A A B A B B B A A A A B B B B
  2. 四相邻象元合并,只记录第一个象元的Morton码。
    0 1 2 3 4 5 6 7 8 12
    A A A B A A B B A B
  3. 由于不能进一步合并,则用游程长度编码压缩。
    0 3 4 6 8 12
    A B A B A B

<6>线性可排序四叉树索引

•首先将四叉树分解为二叉树,即在父结点层与子结点层之间插入一层虚结点,虚结点不用来记录空间要素,然后按照中序遍历树的顺序对结点进行编码,包括加入的虚结点。

假设某个结点位于四叉树的第N层,可排序四叉树编码为Index。它的四个子结点位于树的第N-1层,编码从左到右分别为:

Index_C1=Index-3×4×(N-1) 

Index_C2=Index-4×(N-1)

Index_C3=Index+4×(N-1)

Index_C4=Index+3×4×(N-1)

通过编码值很容易确定结点在树中的层数。在进行查询时,给定一个查询范围,假定为矩形,这个矩形范围唯一的对应一个四叉树结点。通过结点的编码,可以快速计算出在这棵子树下的所有子结点。

找子结点的范围的程序伪代码如下:

GetIndexRange(long Index,long Min,long Max)
{
  long  n = GetLayerNum(Index);
  Min = Max = Index;    
  While(n>0)
  {
    Min = Min- 3×4×(n-1);
    Max = Max-3×4×(n-1);
    n = n –1; 
  }
}

5.CELL树索引

针对R树和R+树在插入、删除与空间搜索效率两个方面难于兼顾的问题,产生了CELL树索引。它在空间划分时不再采用矩形作为划分的基本单位,而是采用凸多边形来作为划分的基本单位,具体划分方法与BSP树有类似之处,子空间不再相互覆盖,如图:

 

CELL树的磁盘访问次数比R树和R+树少,由于磁盘访问次数是影响空间索引性能的关键指标,因此大大提高了搜索性能,故CELL树是比较优秀的空间索引方法。

6.BSP树空间索引

BSP树(Binary Space Partitioning Tree,二值空间划分树)是一种二叉树,它将空间逐级进行一分为二的划分,如下图。BSP树能很好地与空间数据库中空间对象的分布情况相适应,但对一般情况而言,BSP树深度较大,对各种操作均有不利影响,所以在GIS系统中采用BSP空间索引的并不多见。如图:

BSP的想法最早在Fuchs(1980)中被提出,起初的目的是为了解决实时地消除隐藏面。BSP可以说是八叉树的一般化。前人在这方面已经做了很多有效的工作,Fuchs首次将BSP技术中剖分平面的定侧性质应用于多边形场景的剖分,建立起空间二叉树结构.该二叉树的每一结点表示一个子空间及空间内所包含的多边形。在每一结点空间中,选取其中一平面作为剖分平面,将该空间继续剖分成正负两子空间,分别作为该结点的两个子结点,其中与剖分平面有交的多边形被分割成两个多边形,分别归入相应的子空间中。上述过程是一个递归过程,直至每一子空间仅包含一个多边形为止。与八叉树剖分相比,BSP树具有内存耗费小,剖分方式灵活,产生的无效区域较小的优点;且对大部分场景来说,BSP树较八叉树更为平衡。

 

生成过程:

最初,整个区域被定义为 BSP树的根。之后,你继续划分区域。一旦把凹形区域划分为两个凸形区域(在最好情况下)或凹多边形,命名这些区域,它们成为其父结点的孩子,父结点实际上代表了整个区域。

优缺点

BSP树能很好地与空间对象的分布情况相适应,但一般而言,BSP树深度较大,对各种操作均有不利影响。 使用BSP树来进行从后向前排序的最大优点就是算法运行的复杂性较低 。这种方法也解决了多边形的多重交叠和多边形穿越问题。但是,通过使用一个预计算结构,我们已经失去了一定的灵活性。如果多边形的排列在运行时发生了改变, BSP树就必须发生相应的改变。

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页