ArcEngine查詢、添加、刪除要素的方法


 

 

1、查找數據

1)、利用FeaturCursor進行空間查詢

//空間查詢
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = envelope;//指定幾何體
String shpFld = featureClass.ShapeFieldName;
spatialFilter.GeometryField = shpFld;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;//相交
IQueryFilter queryFilter = new QueryFilterClass();
queryFilter = (IQueryFilter)spatialFilter;
IFeatureCursor searchCursor = featureClass.Search(queryFilter, true);
IFeature feature = searchCursor.NextFeature();

int n = 0;
while (feature != null){
    n++;
    feature = baseCursor.NextFeature();
}

 

2)、利用FeatureCursor在選擇集中進行查詢

IFeatureSelection pFeatureSelectio = pFeatureLayer as IFeatureSelection; 
ICursor ppCursor;
pFeatureSelectio.SelectionSet.Search(null, false, out ppCursor);
IFeatureCursor pFeatureCursor = ppCursor as IFeatureCursor; 
IFeature pFeature = pFeatureCursor.NextFeature();

3)、利用FeatureCursor進行屬性查詢

IQueryFilter pQueryFilter = new QueryFilterClass();                           
pQueryFilter.WhereClause = "PROJECTCODE = '" + this.ProjectNumTextBox.Text.Trim() + "'";
IFeatureCursor pFeatureCursor = LineFeaClass.Search(pQueryFilter, false);                           
IFeature pFeatureIfExit = pFeatureCursor.NextFeature();

用Environment.TickCount進行代碼執行時間測試,結果發現4)讀取整個表的時間為4984ms,而 3)讀取同一個屬性給的時間僅為32 ms,3)的執行效率是法一的156倍!!!

完整測試代碼如下:

     IFeatureLayer pLayer = Utilities.GetLayerByName((string)cmbRegLayers.SelectedItem, m_mapControl) as IFeatureLayer;  
     IFeatureCursor FCursor = pLayer.FeatureClass.Search(new QueryFilterClass(), false);  
     IFeature feature = FCursor.NextFeature();  
      
     int t = Environment.TickCount;  
      
     object clsFldValue=null;  
     for (int i = 0; i < pLayer.FeatureClass.FeatureCount(null); i++)  
     {  
         clsFldValue = feature.get_Value(3);  
         feature = FCursor.NextFeature();  
     }  
      
     t = Environment.TickCount - t;  
     MessageBox.Show(t.ToString());  
      
     ITable pTable = pLayer.FeatureClass as ITable;  
      
     t = Environment.TickCount;  
      
     for (int i = 0; i < pTable.RowCount(null); i++)  
         clsFldValue = pTable.GetRow(i).get_Value(3);  
     t = Environment.TickCount - t;  
     MessageBox.Show(t.ToString());  
View Code

 

4)屬性表的方法讀取屬性值

ITable pTable = pLayer.FeatureClass as ITable;  
clsFldValue = pTable.GetRow(i).get_Value(clsFldIndex);  

 

 

2、 插入數據

 

ArcGIS Engine中,主要有兩個方法用於要素的添加:

 

 

批量插入feature,如果用feature.store()方法,在圖層中一個個地插入要素,較之同時使用insert cursor與feature buffer方法,會慢很多。

 

因為后者觸發的事件和復雜行為比較少(比如說沒有引發因拓撲關系產生的行為)。

 

 

1)、利用Insert Cursors和featureBuffer

 

IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();
IFeatureCursor featureCursor = featureClass.Insert(true);
object featureOID;         
featureBuffer.set_Value(featureBuffer.Fields.FindField("InstBy"), "B Pierce");
for (int ic = 0; ic < 99; ic++)
{ 
    featureBuffer.Shape = geometry;    
    featureOID = featureCursor.InsertFeature(featureBuffer);
}
featureBuffer.set_Value(featureBuffer.Fields.FindField("InstBy"), "K Johnston");
for (int ic = 0; ic < 99; ic++)
{
     featureBuffer.Shape = geometry
     featureOID = featureCursor.InsertFeature(featureBuffer);
}
featureCursor.Flush();

 

 

2)、直接進行數據插入(Feature.Store方法)

IFeature newLineFeature = LineFeaClass.CreateFeature();                           

newLineFeature.Shape = pFeature.Shape;
int ii = newLineFeature.Fields.FindField(AreaZonalName); 

if (ii > 0)                           
{                               
    newLineFeature.set_Value(ii, this.AnalysAreaComboBox.Text.Trim());
}

newLineFeature.Store();

 

 

注:最好將編輯操作對象中,如下:

IDataset dataset = (IDataset)featureClass;

  IWorkspace workspace = dataset.Workspace;

  // Cast the workspace to the IWorkspaceEdit interface.

  IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)workspace;

  // Start an edit session and edit operation.

  workspaceEdit.StartEditing(true);

  workspaceEdit.StartEditOperation();

//在這里編寫添加要素的代碼。。。。。。。。。。。

// Stop editing.

  workspaceEdit.StopEditOperation();

  workspaceEdit.StopEditing(true);

 

3、數據刪除 delete

刪除feature,一個個刪除就用IFeature.Delete方法即可,此處不再贅述,只寫一種批量刪除的方法,用於ITable是針對數據庫進行操作的,所以速度很快。

The best approach to take when deleting features depends on two factors, how many features are being deleted and whether the data source is a local geodatabase or an ArcSDE geodatabase.

In the simplest case, a single feature that has already been retrieved can be deleted by callingIFeature.Delete. If bulk features are being deleted and the geodatabase is an ArcSDE geodatabase, the most efficient approach requires the use of a search cursor and the IFeature.Delete method.

On the other hand, if the geodatabase is a local geodatabase (a file or personal geodatabase), the most efficient method for bulk deletion is theITable.DeleteSearchedRows method.

方法1  ITable方法

///<summary>  
///刪除某featurelayer中所有feature  
///</summary>  
///<param name="pLayer">操作的塗層</param>  
///<remarks>該方法可以給一個queryfilter,進行刪除符合條件的features</remarks>  
private void DeleteAllFeatures(IFeatureLayer pLayer, <code></code>IQueryFilter queryFilter)  
{  
  ITable pTable = pLayer.FeatureClass as ITable;  
  pTable.DeleteSearchedRows(queryFilter);  
}  

 

方法2 迭代featureClass方法

IFeatureClass featureClass = featureWorkspace.OpenFeatureClass("Parcels");
IQueryFilter queryFilter = new QueryFilterClass();
queryFilter.WhereClause = "ZONING_S = 'R'";
IFeatureCursor updateCursor = featureClass.Update(queryFilter, false);
IFeature feature = updateCursor.NextFeature();
int m = 0;
while (feature != null)
{
    m++;
    updateCursor.DeleteFeature(feature);
    feature = updateCursor.NextFeature();
}

 

4、 數據更新 update 

4.1 逐條更新記錄

 這種方式中可有三種方法,如下:

(1)

    for (int i = 0; i < pTable.RowCount(null); i++)  
    {  
        pRow = pTable.GetRow(i);  
        pRow.set_Value(2, i + 6);  
        pRow.Store();  
    }  

 

(2)

    IFeatureCursor FCursor = pLayer.FeatureClass.Search(new QueryFilterClass(), false);  
    IFeature feature = FCursor.NextFeature();  
      
    for (int i = 0; i < featureNum; i++)  
    {  
      
        feature.set_Value(2, i);  
        feature.Store();  
        feature = FCursor.NextFeature();  
    }  

 

(3)

    ICursor pCursor =pTable.Update(null, false);  
    pRow = pCursor.NextRow();  
    for (int i = 0; i < pTable.RowCount(null); i++)  
    {  
        pRow.set_Value(2, i + 6);  
        pCursor.UpdateRow(pRow);  
        pRow = pCursor.NextRow();  
    }  

試驗數據為320條記錄,三種方法的運行時間為:法(1)為40297ms;法(2)34922ms為;法(3)為219ms.

可見運用IFeature和IRow的Store方法更新速度都很慢,用ICursor 的UpdateRow方法速度很快,分別是前兩者效率的184倍、159倍!!

 

4.2 批量更新記錄

IFeatureClass featureClass = featureWorkspace.OpenFeatureClass("Parcels");

// 屬性查詢
IQueryFilter queryFilter = new QueryFilterClass();
queryFilter.WhereClause = "ZONING_S = 'U'";

//利用FeatureCursor進行數據更新
IFeatureCursor updateCursor = featureClass.Update(queryFilter, false);
int fieldindex = featureClass.FindField("ZONING_S");
IFeature feature = updateCursor.NextFeature();
int m = 0;

while (feature != null)
{
    m++;
    feature.set_Value(fieldindex, "X");
    updateCursor.UpdateFeature(feature);
    feature = updateCursor.NextFeature();
}

 

 

 當將一批數據更新為某一相同的屬性時,使用ITable.UpdateSearchedRows效率會很高。

    // Find the position of the field that will be updated.  
    int typeFieldIndex = featureClass.FindField("TYPE");  
      
    // Create a query filter defining which fields will be updated  
    // (the subfields) and how to constrain which rows are updated  
    // (the where clause).  
    IQueryFilter queryFilter = new QueryFilterClass  
    {  
        SubFields = "TYPE", WhereClause = "LANE_COUNT = 4"  
    };  
      
    // Create a ComReleaser for buffer management.  
    using(ComReleaser comReleaser = new ComReleaser())  
    {  
        // Create a feature buffer containing the values to be updated.  
        IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();  
        featureBuffer.set_Value(typeFieldIndex, "Highway");  
        comReleaser.ManageLifetime(featureBuffer);  
      
        // Cast the class to ITable and perform the updates.  
        ITable table = (ITable)featureClass;  
        IRowBuffer rowBuffer = (IRowBuffer)featureBuffer;  
        table.UpdateSearchedRows(queryFilter, rowBuffer);  
    }  

 

 

 

 

 參考文章

 ArcEngine查詢、添加、刪除要素的方法

ArcGIS Engine效率探究——要素的添加和刪除、屬性的讀取和更新

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM