Feng.Li's Java See

          抓緊時(shí)間,大步向前。
          隨筆 - 95, 文章 - 4, 評(píng)論 - 58, 引用 - 0
          數(shù)據(jù)加載中……

          2008年3月10日

          空間索引

          在介紹空間索引之前,先談?wù)勈裁唇?#8220;索引“。對(duì)一個(gè)數(shù)據(jù)集做”索引“,是為了提高對(duì)這個(gè)數(shù)據(jù)集檢索的效率。書的”目錄“就是這本書內(nèi)容的”索引“,當(dāng)我們拿到一本新書,想查看感興趣內(nèi)容的時(shí)候,我們會(huì)先查看目錄,確定感興趣的內(nèi)容會(huì)在哪些頁里,直接翻到那些頁,就OK了,而不是從第一章節(jié)開始翻,一個(gè)字一個(gè)字地找我們感興趣的內(nèi)容,直到找到為止,這種檢索內(nèi)容的效率也太低了,如果一本書沒有目錄,可以想象有多么不方便…可見書的目錄有多重要,索引有多重要啊!

          現(xiàn)在大家對(duì)索引有了感性認(rèn)識(shí),那什么是“空間索引“呢?”空間索引“也是”索引“,是對(duì)空間圖形集合做的一個(gè)”目錄“,提高在這個(gè)圖形集合中查找某個(gè)圖形對(duì)象的效率。比如說,我們?cè)谝粋€(gè)地圖圖層上進(jìn)行矩形選擇,確定這個(gè)圖層上哪些圖元被這個(gè)矩形所完全包含呢,在沒有”空間索引“的情況下,我們會(huì)把這個(gè)圖層上的所有圖元,一一拿來與這個(gè)矩形進(jìn)行幾何上的包含判斷,以確定到底哪些圖元被完全包含在這個(gè)矩形內(nèi)。您是不是覺得這樣做很合理呢?其實(shí)不然,我們先看一個(gè)網(wǎng)格索引的例子:

           

          我們對(duì)這個(gè)點(diǎn)圖層作了網(wǎng)格索引,判斷哪些點(diǎn)在這個(gè)矩形選擇框內(nèi),是不需要把這個(gè)圖層里所有的點(diǎn)都要與矩形進(jìn)行幾何包含運(yùn)算的,只對(duì)a,b,c,d,e,f,g這七個(gè)點(diǎn)做了運(yùn)算。可以推想一下,如果一個(gè)點(diǎn)圖層有十萬個(gè)點(diǎn),不建立空間索引,任何地圖操作都將對(duì)整個(gè)圖層的所有圖元遍歷一次,也就是要For循環(huán)10萬次;建立索引將使得For循環(huán)的次數(shù)下降很多很多,效率自然提高很多!

          呵呵…想必大家都知道空間索引的好處了,也不知不覺向大家介紹了點(diǎn)圖層的網(wǎng)格索引,還有哪些常用的空間索引呢?這些空間索引又該如何實(shí)現(xiàn)呢?帶著這樣的問題,下面介紹幾種常用的空間索引。

          網(wǎng)格索引
                  網(wǎng)格索引就是在一個(gè)地圖圖層上,按每個(gè)小網(wǎng)格寬△w,高△h打上均勻的格網(wǎng),計(jì)算每個(gè)圖元所占據(jù)的網(wǎng)格或者所經(jīng)過的網(wǎng)格單元集合,

           

                 

                在這些網(wǎng)格單元中,記錄下圖元對(duì)象的地址或者引用,比如:聲明一個(gè)對(duì)象二維數(shù)組 List grid[m][n]; m代表網(wǎng)格的行數(shù),n代表網(wǎng)格的列數(shù),每個(gè)數(shù)組元素為一個(gè)“集合對(duì)象”,用于存儲(chǔ)這個(gè)網(wǎng)格單元所關(guān)聯(lián)的所有圖元的地址或引用,這樣網(wǎng)格索引就建立好了。下一步,我們?cè)撛趺从眠@個(gè)網(wǎng)格索引呢?所有的圖形顯示和操作都可以借助于“空間索引”來提高效率。舉幾個(gè)例子來說明“空間索引“的使用:

           
                 一、放大開窗顯示,正如上一節(jié)介紹的,當(dāng)我們?cè)诘貓D上畫一個(gè)矩形想放大地圖的時(shí)候,首先得確定放大后的地圖在屏幕上需要顯示哪些圖元?所以,我們需要判斷這個(gè)地圖中有哪些圖元全部或者部分落在這個(gè)矩形中。判斷步驟:

          1,確定所畫矩形左上角和右下角所在的網(wǎng)格數(shù)組元素;即可得到這個(gè)矩形所關(guān)聯(lián)覆蓋的所有網(wǎng)格集合;

          2,遍歷這個(gè)網(wǎng)格集合中的元素,取到每個(gè)網(wǎng)格元素List中所記錄的圖元;

          3,畫出這些圖元即可。(當(dāng)然整個(gè)過程涉及到兩點(diǎn):1,屏幕坐標(biāo)和地圖坐標(biāo)的互相變換;2,窗口裁減,也可以不裁減)

          二、包含判斷,給出一個(gè)點(diǎn)point和一個(gè)多邊形polygon,判斷點(diǎn)是否在面內(nèi),首先判斷這個(gè)點(diǎn)所在的網(wǎng)格,是否同時(shí)關(guān)聯(lián)這個(gè)polygon,如果不是,表明點(diǎn)不在面內(nèi),如果是,可以下一步的精確解析幾何判斷,或者精度允許的情況下,即判斷polygon是包含point的。

          另外,Google Map應(yīng)該也是采用地理網(wǎng)格的方式,對(duì)地圖圖象進(jìn)行索引的,可見一斑,網(wǎng)格索引在圖形顯示,選擇,拓?fù)渑袛嗌系膹V泛應(yīng)用。但同時(shí)也存在很嚴(yán)重的缺陷:當(dāng)被索引的圖元對(duì)象是線,或者多邊形的時(shí)候,存在索引的冗余,即一個(gè)線或者多邊形的引用在多個(gè)網(wǎng)格中都有記錄。隨著冗余量的增大,效率明顯下降。所以,很多學(xué)者提出了各種方法來改進(jìn)網(wǎng)格索引,這個(gè)將在下面的章節(jié)中介紹。而點(diǎn)圖元非常適合網(wǎng)格索引,不存在冗余問題。

          四叉樹索引(Quadtree)

          類似于前面介紹的網(wǎng)格索引,也是對(duì)地理空間進(jìn)行網(wǎng)格劃分,對(duì)地理空間遞歸進(jìn)行四分來構(gòu)建四叉樹,本文將在普通四叉樹的基礎(chǔ)上,介紹一種改進(jìn)的四叉樹索引結(jié)構(gòu)。首先,先介紹一個(gè)GISGeographic Information System)或者計(jì)算機(jī)圖形學(xué)上非常重要的概念——最小外包矩形(MBR-Minimum Bounding Rectangle)

           

                 

                最小外包矩形MBR就是包圍圖元,且平行于XY軸的最小外接矩形。MBR到底有什么用處呢,為什么要引入這個(gè)概念呢?因?yàn)椋瑘D元的形狀是不規(guī)則的,而MBR是平行于XY軸的規(guī)則圖形,設(shè)想一下,如果所有的圖元都是平行于XY軸的矩形,那針對(duì)這樣的矩形進(jìn)行幾何上的任何判斷,是不是要簡單很多呢?不管我們?nèi)俗约簩懝剿惴ɑ蛘呔帉懗绦蜻\(yùn)行,是不是都要比原本復(fù)雜的圖形幾何運(yùn)算要簡潔很多呢?答案很顯然。

                 然后,我們?cè)俳榻B一下GIS空間操作的步驟(這個(gè)步驟,在前面忘記向大家說明了,在這里補(bǔ)充一下)
           

                 

                可見,過濾階段,通過空間索引可以排除掉一些明顯不符合條件的圖元,得到后選集合,然后對(duì)后選圖元集合進(jìn)行精確幾何運(yùn)算,得到最終結(jié)果。大家可能會(huì)有這樣的疑問,這樣有必要嗎?是不是反而把問題復(fù)雜化了?合適的空間索引只會(huì)提高計(jì)算機(jī)的效率,沒有空間索引,我們無疑要對(duì)集合中的每個(gè)圖元進(jìn)行精確幾何運(yùn)算,而這樣的運(yùn)算是復(fù)雜的,是非常占用CPU的,所以需要空間索引,采取少量的內(nèi)存和簡單的CUP運(yùn)算,來盡量減少那種高耗CUP的精確運(yùn)算的次數(shù),這樣做是完全值得的。至于精確的幾何運(yùn)算到底復(fù)雜在哪里,該如何進(jìn)行精確的幾何運(yùn)算,將在下面的章節(jié)中詳細(xì)描述,這里主要介紹過濾階段的空間索引。

                 現(xiàn)在,讓我們來具體了解一下“四叉樹索引”。
           

          四叉樹索引就是遞歸地對(duì)地理空間進(jìn)行四分,直到自行設(shè)定的終止條件(比如每個(gè)節(jié)點(diǎn)關(guān)聯(lián)圖元的個(gè)數(shù)不超過3個(gè),超過3個(gè),就再四分),最終形成一顆有層次的四叉樹。圖中有數(shù)字標(biāo)識(shí)的矩形是每個(gè)圖元的MBR,每個(gè)葉子節(jié)點(diǎn)存儲(chǔ)了本區(qū)域所關(guān)聯(lián)的圖元標(biāo)識(shí)列表和本區(qū)域地理范圍,非葉子節(jié)點(diǎn)僅存儲(chǔ)了區(qū)域的地理范圍。大家可以發(fā)現(xiàn),同樣存在一個(gè)圖元標(biāo)識(shí)被多個(gè)區(qū)域所關(guān)聯(lián),相應(yīng)地存儲(chǔ)在多個(gè)葉子節(jié)點(diǎn)上,比如“6“所代表的圖元,分別存儲(chǔ)在四個(gè)分枝上。這樣,就存在索引的冗余,與網(wǎng)格索引存在同樣的弊端。下面我們介紹一種改進(jìn)的四叉樹索引,或者說是分層的網(wǎng)格索引。

                   改進(jìn)的四叉樹索引,就是為了避免這種空間索引的冗余,基本改進(jìn)思路是:讓每個(gè)圖元的MBR被一個(gè)最小區(qū)域完全包含
           

          可以看出,313分別都跨越了兩個(gè)區(qū)域,要被一個(gè)最小區(qū)域完全包含,就只能是根節(jié)點(diǎn)所代表的區(qū)域,25跨越了兩個(gè)區(qū)域,6跨越了四個(gè)區(qū)域,要被一個(gè)最小區(qū)域完全包含,就只能是NW區(qū)域。怎么判斷一個(gè)圖元被哪個(gè)最小區(qū)域完全包含呢?從直觀上看,遞歸地對(duì)地理空間進(jìn)行四分,如果圖元與一個(gè)區(qū)域四分的劃分線相交,則這個(gè)圖元就歸屬于這個(gè)區(qū)域,或者直到不再劃分了,那就屬于這個(gè)不再劃分的區(qū)域。呵呵。。。可能有點(diǎn)繞口,看圖,結(jié)合“最小”“完全包含這兩個(gè)字眼,您就明白了。這顆四叉樹中,圖元的標(biāo)識(shí)不再僅僅存儲(chǔ)在葉子節(jié)點(diǎn)上,而是每個(gè)節(jié)點(diǎn)都有可能存儲(chǔ),這樣也就避免了索引冗余。同時(shí)每個(gè)節(jié)點(diǎn)存儲(chǔ)本節(jié)點(diǎn)所在的地理范圍。

          有了四叉樹索引,下面又該如何利用這顆樹來幫助檢索查找呢?還是矩形選擇為例吧!(為什么我總是拿這個(gè)例子來說事呢?因?yàn)檫@個(gè)例子簡單,容易理解,有代表性!)我們?cè)诘貓D上畫一個(gè)矩形,判斷地圖上哪些圖元落在這個(gè)矩形里或者和這個(gè)所畫矩形相交。方法很多,這里介紹一種簡單的檢索步驟,如下:

          1,首先,從四叉樹的根節(jié)點(diǎn)開始,把根節(jié)點(diǎn)所關(guān)聯(lián)的圖元標(biāo)識(shí)都加到一個(gè)List里;

          2,比較此矩形范圍與根節(jié)點(diǎn)的四個(gè)子節(jié)點(diǎn)(或者叫子區(qū)域)是否有交集(相交或者包含),如果有,則把相應(yīng)的區(qū)域所關(guān)聯(lián)的圖元標(biāo)識(shí)加到List集合中,如果沒有,則以下這顆子樹都不再考慮。

          3,以上過程的遞歸,直到樹的葉子節(jié)點(diǎn)終止,返回List

          4,從List集合中根據(jù)標(biāo)識(shí)一一取出圖元,先判斷圖元MBR與矩形有無交集,如果有,則進(jìn)行下面的精確幾何判斷,如果沒有,則不再考慮此圖元。(當(dāng)然,這里只說了一個(gè)基本思路,其實(shí)還有其他一些不同的方法,比如,結(jié)合空間數(shù)據(jù)磁盤的物理存儲(chǔ)會(huì)有一些調(diào)整)

          總結(jié):改進(jìn)的四叉樹索引解決了線,面對(duì)象的索引冗余,具有較好的性能,而被大型空間數(shù)據(jù)庫引擎所采用,如ArcSDEOracle Spatial等,同時(shí)這種結(jié)構(gòu)也適用于空間數(shù)據(jù)的磁盤索引,配合空間排序聚類,基于分形的Hilbert算法數(shù)據(jù)組織,將在空間數(shù)據(jù)格式的定義中發(fā)揮重要作用。

          posted @ 2009-05-18 09:34 小鋒 閱讀(1841) | 評(píng)論 (1)編輯 收藏

          線段樹入門

               摘要: 線段樹數(shù)據(jù)結(jié)構(gòu)的入門文章  閱讀全文

          posted @ 2009-04-28 07:14 小鋒 閱讀(734) | 評(píng)論 (0)編輯 收藏

          經(jīng)典的一個(gè)GIS學(xué)習(xí)定位帖(轉(zhuǎn))

               摘要: 一篇經(jīng)典的關(guān)于GIS學(xué)習(xí)定位的帖子。  閱讀全文

          posted @ 2009-02-16 17:54 小鋒 閱讀(760) | 評(píng)論 (0)編輯 收藏

          精解遞歸程序設(shè)計(jì)

               摘要: 對(duì)遞歸程序設(shè)計(jì)的精解  閱讀全文

          posted @ 2008-04-22 01:15 小鋒 閱讀(543) | 評(píng)論 (0)編輯 收藏

          復(fù)雜遞歸程序框架

           

          較為復(fù)雜的遞歸問題的程序一般結(jié)構(gòu)如下
          (1)sub recursien(n)
          (2) if滿足出口條件then
          (3) 出口操作|
          (4) d
          (5) 第n層的準(zhǔn)備性操作P(n);
          (6) 第n層具休性操作G(n)|
          (7) 進(jìn)入探層遞歸前的恢復(fù)性操作H(n);
          (8) 進(jìn)入深層遞歸reeurslon(n一1)
          (9) endif
          (10)end sub

          posted @ 2008-04-18 07:00 小鋒 閱讀(306) | 評(píng)論 (0)編輯 收藏

          N重循環(huán)程序框架

           int[] a  = new int[N+1];
           int i,k;
           for(i=1;i<=n;i++)
              a[i] = left[i];
           k = n;
           while(k>=1) 
            {
               執(zhí)行循環(huán)體內(nèi)該做的事
             
            while (a[k] + step[k]>right[k])
                 {
                    a[k] =  left[k] ;
                    k--;
                  }
            if(k==0)break;//此處也可以為continue;
           a[k] = a[k] + step[k];
           k = n;
           }
          }

           

          posted @ 2008-04-17 04:46 小鋒 閱讀(404) | 評(píng)論 (0)編輯 收藏

          全排列的非遞歸算法



          = malloc(n * sizeof(int));
          for (i = 0; i < n; i++)
             p[i] 
          = i;

          output(p, n);

          for (i = n - 1; i > 0; i--)
             
          if (p[i] > p[i - 1])
             {
                
          for (j = n - 1; p[j] < p[i - 1]; j--);
                swap(
          &(p[i - 1]), &(p[j]));

                
          for (j = i, k = n - 1; j < k; j++, k--)
                   swap(
          &(p[j]), &(p[k]));

                ouput(p, n);
                i 
          = n;
             }

          free(p);

          posted @ 2008-04-16 02:25 小鋒 閱讀(583) | 評(píng)論 (0)編輯 收藏

          DAO模式

               摘要: 轉(zhuǎn)載,關(guān)于DAO模式  閱讀全文

          posted @ 2008-03-10 14:54 小鋒 閱讀(1728) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 镇原县| 平度市| 五家渠市| 九龙坡区| 石狮市| 桑日县| 莱西市| 常德市| 二手房| 麦盖提县| 化隆| 鞍山市| 杨浦区| 砚山县| 钟山县| 宜兴市| 驻马店市| 澄迈县| 宁安市| 福建省| 陵水| 和田市| 沅陵县| 香河县| 西和县| 德惠市| 新和县| 东海县| 武功县| 河间市| 乐陵市| 白河县| 吴桥县| 满洲里市| 遂川县| 古丈县| 上犹县| 张家界市| 宁远县| 吉水县| 磐石市|