轉自:http://www.cnblogs.com/Kane_zzt/archive/2009/04/13/1434708.html
在介紹空間索引之前,先談談什麼叫“索引“。對一個資料集做”索引“,是為了提高對這個資料集檢索的效率。書的”目錄“就是這本書内容的”索引“,當我們拿到一本新書,想檢視感興趣内容的時候,我們會先檢視目錄,确定感興趣的内容會在哪些頁裡,直接翻到那些頁,就OK了,而不是從第一章節開始翻,一個字一個字地找我們感興趣的内容,直到找到為止,這種檢索内容的效率也太低了,如果一本書沒有目錄,可以想象有多麼不友善…可見書的目錄有多重要,索引有多重要啊!
現在大家對索引有了感性認識,那什麼是“空間索引“呢?”空間索引“也是”索引“,是對空間圖形集合做的一個”目錄“,提高在這個圖形集合中查找某個圖形對象的效率。比如說,我們在一個地圖圖層上進行矩形選擇,确定這個圖層上哪些圖元被這個矩形所完全包含呢,在沒有”空間索引“的情況下,我們會把這個圖層上的所有圖元,一一拿來與這個矩形進行幾何上的包含判斷,以确定到底哪些圖元被完全包含在這個矩形内。您是不是覺得這樣做很合理呢?其實不然,我們先看一個網格索引的例子:
我們對這個點圖層作了網格索引,判斷哪些點在這個矩形選擇框内,是不需要把這個圖層裡所有的點都要與矩形進行幾何包含運算的,隻對a,b,c,d,e,f,g這七個點做了運算。可以推想一下,如果一個點圖層有十萬個點,不建立空間索引,任何地圖操作都将對整個圖層的所有圖元周遊一次,也就是要For循環10萬次;建立索引将使得For循環的次數下降很多很多,效率自然提高很多!
呵呵…想必大家都知道空間索引的好處了,也不知不覺向大家介紹了點圖層的網格索引,還有哪些常用的空間索引呢?這些空間索引又該如何實作呢?帶着這樣的問題,下面介紹幾種常用的空間索引。
網格索引
網格索引就是在一個地圖圖層上,按每個小網格寬△w,高△h打上均勻的格網,計算每個圖元所占據的網格或者所經過的網格單元集合,
在這些網格單元中,記錄下圖元對象的位址或者引用,比如:聲明一個對象二維數組 List grid[m][n]; m代表網格的行數,n代表網格的列數,每個數組元素為一個“集合對象”,用于存儲這個網格單元所關聯的所有圖元的位址或引用,這樣網格索引就建立好了。下一步,我們該怎麼用這個網格索引呢?所有的圖形顯示和操作都可以借助于“空間索引”來提高效率。舉幾個例子來說明“空間索引“的使用:
一、 放大開窗顯示,正如上一節介紹的,當我們在地圖上畫一個矩形想放大地圖的時候,首先得确定放大後的地圖在螢幕上需要顯示哪些圖元?是以,我們需要判斷這個地圖中有哪些圖元全部或者部分落在這個矩形中。判斷步驟:
1,确定所畫矩形左上角和右下角所在的網格數組元素;即可得到這個矩形所關聯覆寫的所有網格集合;
2,周遊這個網格集合中的元素,取到每個網格元素List中所記錄的圖元;
3,畫出這些圖元即可。(當然整個過程涉及到兩點:1,螢幕坐标和地圖坐标的互相變換;2,視窗裁減,也可以不裁減)
二、 包含判斷,給出一個點point和一個多邊形polygon,判斷點是否在面内,首先判斷這個點所在的網格,是否同時關聯這個polygon,如果不是,表明點不在面内,如果是,可以下一步的精确解析幾何判斷,或者精度允許的情況下,即判斷polygon是包含point的。
另外,Google Map應該也是采用地理網格的方式,對地圖圖象進行索引的,可見一斑,網格索引在圖形顯示,選擇,拓撲判斷上的廣泛應用。但同時也存在很嚴重的缺陷:當被索引的圖元對象是線,或者多邊形的時候,存在索引的備援,即一個線或者多邊形的引用在多個網格中都有記錄。随着備援量的增大,效率明顯下降。是以,很多學者提出了各種方法來改進網格索引,這個将在下面的章節中介紹。而點圖元非常适合網格索引,不存在備援問題。
四叉樹索引(Quadtree)
類似于前面介紹的網格索引,也是對地理空間進行網格劃分,對地理空間遞歸進行四分來建構四叉樹,本文将在普通四叉樹的基礎上,介紹一種改進的四叉樹索引結構。首先,先介紹一個GIS(Geographic Information System)或者計算機圖形學上非常重要的概念——最小外包矩形(MBR-Minimum Bounding Rectangle):
最小外包矩形MBR就是包圍圖元,且平行于X,Y軸的最小外接矩形。MBR到底有什麼用處呢,為什麼要引入這個概念呢?因為,圖元的形狀是不規則的,而MBR是平行于X,Y軸的規則圖形,設想一下,如果所有的圖元都是平行于X,Y軸的矩形,那針對這樣的矩形進行幾何上的任何判斷,是不是要簡單很多呢?不管我們人自己寫公式算法或者編寫程式運作,是不是都要比原本複雜的圖形幾何運算要簡潔很多呢?答案很顯然。
然後,我們再介紹一下GIS空間操作的步驟(這個步驟,在前面忘記向大家說明了,在這裡補充一下)
可見,過濾階段,通過空間索引可以排除掉一些明顯不符合條件的圖元,得到後選集合,然後對後選圖元集合進行精确幾何運算,得到最終結果。大家可能會有這樣的疑問,這樣有必要嗎?是不是反而把問題複雜化了?合适的空間索引隻會提高計算機的效率,沒有空間索引,我們無疑要對集合中的每個圖元進行精确幾何運算,而這樣的運算是複雜的,是非常占用CPU的,是以需要空間索引,采取少量的記憶體和簡單的CUP運算,來盡量減少那種高耗CUP的精确運算的次數,這樣做是完全值得的。至于精确的幾何運算到底複雜在哪裡,該如何進行精确的幾何運算,将在下面的章節中較長的描述,這裡主要介紹過濾階段的空間索引。
現在,讓我們來具體了解一下“四叉樹索引”。
四叉樹索引就是遞歸地對地理空間進行四分,直到自行設定的終止條件(比如每個節點關聯圖元的個數不超過3個,超過3個,就再四分),最終形成一顆有層次的四叉樹。圖中有數字辨別的矩形是每個圖元的MBR,每個葉子節點存儲了本區域所關聯的圖元辨別清單和本區域地理範圍,非葉子節點僅存儲了區域的地理範圍。大家可以發現,同樣存在一個圖元辨別被多個區域所關聯,相應地存儲在多個葉子節點上,比如“6“所代表的圖元,分别存儲在四個分枝上。這樣,就存在索引的備援,與網格索引存在同樣的弊端。下面我們介紹一種改進的四叉樹索引,或者說是分層的網格索引。
改進的四叉樹索引,就是為了避免這種空間索引的備援,基本改進思路是:讓每個圖元的MBR被一個 最小區域 完全包含。
可以看出,3和13分别都跨越了兩個區域,要被一個最小區域完全包含,就隻能是根節點所代表的區域,2,5跨越了兩個區域,6跨越了四個區域,要被一個最小區域完全包含,就隻能是NW區域。怎麼判斷一個圖元被哪個最小區域完全包含呢?從直覺上看,遞歸地對地理空間進行四分,如果圖元與一個區域四分的劃分線相交,則這個圖元就歸屬于這個區域,或者直到不再劃分了,那就屬于這個不再劃分的區域。呵呵。。。可能有點繞口,看圖,結合“最小”“完全包含”這兩個字眼,您就明白了。這顆四叉樹中,圖元的辨別不再僅僅存儲在葉子節點上,而是每個節點都有可能存儲,這樣也就避免了索引備援。同時每個節點存儲本節點所在的地理範圍。
有了四叉樹索引,下面又該如何利用這顆樹來幫助檢索查找呢?還是矩形選擇為例吧!(為什麼我總是拿這個例子來說事呢?因為這個例子簡單,容易了解,有代表性!)我們在地圖上畫一個矩形,判斷地圖上哪些圖元落在這個矩形裡或者和這個所畫矩形相交。方法很多,這裡介紹一種簡單的檢索步驟,如下:
1,首先,從四叉樹的根節點開始,把根節點所關聯的圖元辨別都加到一個List裡;
2,比較此矩形範圍與根節點的四個子節點(或者叫子區域)是否有交集(相交或者包含),如果有,則把相應的區域所關聯的圖元辨別加到List集合中,如果沒有,則以下這顆子樹都不再考慮。
3,以上過程的遞歸,直到樹的葉子節點終止,傳回List。
4,從List集合中根據辨別一一取出圖元,先判斷圖元MBR與矩形有無交集,如果有,則進行下面的精确幾何判斷,如果沒有,則不再考慮此圖元。(當然,這裡隻說了一個基本思路,其實還有其他一些不同的方法,比如,結合空間資料磁盤的實體存儲會有一些調整)
總結:改進的四叉樹索引解決了線,面對象的索引備援,具有較好的性能,而被大型空間資料庫引擎所采用,如ArcSDE,Oracle Spatial等,同時這種結構也适用于空間資料的磁盤索引,配合空間排序聚類,基于分形的Hilbert算法資料組織,将在空間資料格式的定義中發揮重要作用。