天天看點

空間資料的空間索引

首先說一下spatial index grid

其實它就是索引的一種——格網索引,将空間資料的區域分成一塊塊格網來維護,目的是為了加快空間查詢、檢索的速度(先判斷某個要素落在哪個格網内,再根據格網索引直接去該格網裡去找具體的要素)。

spatial index grid一般是地理資料庫自動維護的,它會根據資料的範圍去計算出合适的格網大小,當用ArcCatalog将資料導入地理資料庫後計算出來的grid是一個定值。

是以這裡grid的大小其實對資料本身并沒影響,不設定都行。隻是設定合适的格網可以增加執行效率,過大或者過小都會影響效率。但在ArcGIS裡面很多時候都會去檢查資料是否有空間索引,沒有的話可能會出錯。

可能導緻的錯誤

地理資料庫有個檢查落在每個grid内的feature數量的機制,如果這個數量過大,超過容限,就被認為會減慢空間查詢的效率,這時候就會出現grid is too small的錯誤。

有時候我們在ArcCatalog建好資料後,再用程式往裡面添加Feature的時候會出現Spatial index grid error,這也是grid size不當導緻的。

解決辦法

當然可以在導入的時候将grid值改大,能滿足後續的添加資料要求即可,沒太大影響,不過具體改多大不好把握;

還可以在添加資料之前将spatial index删掉,修改完後再重新生成,這些都可以通過調用GP工具資料管理工具——indexes下的工具來輕易完成。

那當我們自己去指定grid size的時候到底指定多少呢?這就需要自己設計算法去計算了,總之能加快空間檢索的速度就行。計算最終資料合适的spatial index grid可以參考Engine for VB幫助文檔裡frmSpatialIdxCalc.frm那個例子,它就提供了一種計算合适的grid size的方法。

除了調用ArcToolbox裡的GP工具來管理索引外,其實Engine也提供了方法,下面就是具體的測試代碼,無論空間索引還是屬性索引都可以通過這種方式來管理。

示例代碼

Public Sub ChangeSpatialIndex()
Dim pMxDoc As IMxDocument
Dim pFeatLyr As IFeatureLayer
Dim pFeatCls As IFeatureClass

Set pMxDoc = ThisDocument
Set pFeatLyr = pMxDoc.FocusMap.Layer(0)
Set pFeatCls = pFeatLyr.FeatureClass

Dim pIndexes As IIndexes
Set pIndexes = pFeatCls.Indexes
MsgBox pIndexes.IndexCount

Dim pField As IField
Set pField =
pFeatCls.Fields.Field(pFeatCls.Fields.FindField(pFeatCls.ShapeFieldName))
Dim pEnumIndex As IEnumIndex
Set pEnumIndex =
pFeatCls.Indexes.FindIndexesByFieldName(pFeatCls.ShapeFieldName)

Debug.Print pFeatCls.Indexes.index(0).Name 'FDO_OBJECTID
Debug.Print pFeatCls.Indexes.index(1).Name 'Shape_Index

'Dim pIndex As IIndex
'Set pIndex = pEnumIndex.Next
'If Not pIndex Is Nothing Then
' MsgBox pIndex.Name
'End If
'pFeatCls.DeleteIndex pIndex '**删除已經存在的空間索引**

Dim pgeoDef As IGeometryDef
Dim pGeoDefEdit As IGeometryDefEdit
Set pgeoDef = pField.GeometryDef

'**如果隻是在這裡改了gridsize後,size确實變了,但資料在catalog裡顯示spatialindex還**
'**是原來的**
'**而且在catalog下修改gridsize,再執行recalculate的話spatial Index還是原先預設的**
Set pGeoDefEdit = pgeoDef '**設定每一級grid size**
With pGeoDefEdit
.AvgNumPoints = 5
.GridCount = 2
.GridSize(0) = 0.2
.GridSize(1) = 1.33
.GridSize(2) = 5
End With

'**以下測試通過IIndexEdit來重新添加空間索引,先将原來的空間索引删除,然後更改**
'**geometry字段的grid size,'然後再添加新的index,這樣修改的grid size才會生效**
Dim pIndex As IIndex
Set pIndex = New index '**定義新的空間索引**
Dim pIdxEdit As IIndexEdit
Set pIdxEdit = pIndex

Dim pFields As IFields
Dim pFEdit As IFieldsEdit
Set pFields = New Fields
Set pFEdit = pFields
pFEdit.FieldCount = 1
Set pFEdit.Field(0) = pField

Set pIdxEdit.Fields = pFields '**将索引與geometry字段關聯**
pIdxEdit.Name = “myIndex”
pFeatCls.AddIndex pIndex
End Sub
           

想要了解更多知識,獲得幹貨,關注微信公衆号:GIS點滴

繼續閱讀