文章版權由做者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/html
在以前的博客中,我分別介紹了基於網格的空間索引(http://www.cnblogs.com/naaoveGIS/p/5148185.html)以及四叉樹和網格結合的聯合索引(http://www.cnblogs.com/naaoveGIS/p/6641449.html),要解決的問題均是判斷一個點落在了面圖層中的哪一個面要素中。單從算法層面上分析,以上兩種索引均有一些弊端:算法
a.網格索引因爲對整個空間進行網格劃分,若是劃分粒度太細容易出現索引冗餘,若是劃分粒度太大則索引效率又大幅度降低。微信
b.四叉樹索引一樣存在一個圖元標識被多個區域所關聯,相應地存儲在多個葉子節點上,這樣就存在索引的冗餘,與網格索引存在一樣的弊端。工具
爲進一步優化索引,咱們決定採用R樹來進行優化。性能
R樹主要運用空間分割的理念,即採用MBR(Minimal Bounding Rectangle,最小邊界矩形)的方法,從葉子結點開始用矩形(rectangle)將空間框起來,結點越往上,框住的空間就越大,以此對空間進行分割:測試
全部的原始空間要素均是葉節點,這樣便不會出現如四叉樹索引和網格索引中出現的空間要素被多個索引段指引,進而出現大量冗餘索引的問題。優化
JTS中提供了構建索引的方法,其能夠構建四叉樹索引、R樹索引、KD索引等。這裏,咱們直接使用JTS來構建R樹索引。ui
JTS的介紹:https://en.wikipedia.org/wiki/JTS_Topology_Suitespa
JTS的源碼下載:https://sourceforge.net/projects/jts-topo-suite/?source=navbar.net
利用GT讀取到本地的SHP,獲取到全部的要素集,而後遍歷要素將envelope和要素信息一一插入至StrTree中,構建R樹:
將查詢的空間條件構形成一個Envelope在R樹中查詢,對查詢出來的結果再次進行點面關係判斷:
在咱們以前的兩種索引方法中,咱們均將索引文件保存到了本地,每次調用時去加載索引,如此IO是一個很大的瓶頸。如今咱們建立一個容器,將StrTree保存至該容器中。查詢時,直接從內存中獲取到該樹。
在測試數據中選中一個特殊點(多個多邊形的交接處):
分別對使用的三種索引進行了性能對比:
a.本地網格索引:
b.本地混合索引(四叉樹與網格索引整合):
c.內存R樹索引:
可見查詢效率快了一倍左右。
樣本數據有2000多個面要素,以前的兩種索引均使用本地工具構建,時間大約是1S上下(沒有具體統計)。如今使用JTS構建R樹索引,效率爲:
此索引的優化中,咱們將數據所有存入了內存。這裏必須觀察內存的佔用量有多大。
通常監控內存有兩種方式,經過工具查看或者代碼段編寫。代碼段編寫能夠經過應用SizeOf.jar實現,工具查看能夠經過jvisualvm實現:
原始的本地SHP數據大小爲:3.8M。
網格索引大小爲:4.4M。
混合索引文件的大小爲:8.4M。
而讀入內存中的R樹索引的大小爲:4.3M。
因爲咱們存儲了要素所包含的全部信息,理論上,若是咱們將存儲信息進一步減小,內存佔用會更小。目前來看,SHP數據自己的大小,會跟存入內存的信息大小有直接關係。
目前索引方式任然有幾點不足:
a.索引構建中的要素獲取方式爲本地SHP讀取,須要擴展成對第三方服務數據的支持。
b.當R數查詢命中只有一個要素時,由於最小矩形的範圍是大於等於實際要素範圍的,因此還要進行一次點面判斷。如此,當圖層要素個數自己很少時,創建索引不必定能夠加速。
-----歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/
若是您以爲本文確實幫助了您,能夠微信掃一掃,進行小額的打賞和鼓勵,謝謝 ^_^