ArcGIS Engine開發之屬性查詢


ArcGIS Engine開發之屬性查詢

來自:http://www.cnblogs.com/dongteng/p/5925120.html

 

屬性查詢即基於空間數據的屬性數據的查詢,通過用戶提交SQL語言中的where語句定義的查詢條件,對屬性數據進行搜索,從而得到查詢結果的操作。

相關的類與接口

與屬性查詢功能相關的類主要有QureyFilter、QueryDef、Cursor、FeatureCursor等。涉及的接口有IQueryFilter、IQueryDef、ICursor、IFeatureCursor以及IFeatureSelection等。以上的類和接口都位於ArcGIS.Geodatabase命名空間中。

1.QueryFilter類

該類用於根據屬性值或關系來過濾數據,它實現了IQueryFilter接口,該接口主要有以下的接口和方法。

1)WhereClause屬性

設置用來過濾數據的where條件子句。該子句使用SQL表達式來定義過濾數據的條件,可以使用運算符、通配符、函數等字符來構成where子句。具體的語法根據數據源的不同而有所不同。

2)SubField屬性

定義用於數過濾的屬性字段列表,如果列表有多項,則每項之間用英文逗號隔開,默認為*,意味着返回結果中包含所有字段,否則可以自定義需要返回的字段。

2.QueryDef類

該類是ESRI的查詢定義類,為ArcGIS Engine中的Class類,不能被直接創建,可以由IFeatureWorkspace接口的CreateQueryDef方法創建。它實現了IQueryDef接口,該接口的成員用來操作基於屬性的查詢,主要有一下的屬性和方法:

1)Tables屬性:該屬性定義所查詢表的名稱和列表,如果列表有多項,則每項之間用英文逗號隔開。

2)WhereClause屬性:該屬性的方法與IQueryFilter接口中的WhereClause屬性的用法相同。

3)SubField屬性:該屬性的用法與IQueryFilter接口中的SubField屬性用法相同。

4)Evaluate方法:該方法定義的查詢並返回結果集的游標,該游標為ICursor接口類型。

3.Cursor類

該類是ESRI的游標類,為ArcGIS Engine中的Class類,不能直接被創建,可以由相關接口中的方法創建。

游標的解釋:游標是數據庫中的概念,他是系統為用戶開設的一個數據緩沖區,存放SQL語句的執行結果,用戶可以從游標中逐一獲取上述的執行結果。從本質上講,游標是一種能夠從包括多條數據記錄的結果集中每次提取一條記錄的機制,因此,ArcGIS中使用游標的概念來操作各類查詢的結果。游標的接口主要包括ICursor接口和IFeatureCursor接口,IFeatureCursor接口繼承與ICursor接口,ICursor接口主要用於操作數據行,IFeatureCursor接口主要用來操作要素Feature。

Cursor類主要實現了ICursor接口,該接口的成員用來獲取枚舉的行和列的集合,或用來更新、刪除和插入數據行。使用NextRow方法,將游標的位置向前移動一位,並返回該位置的行對象。

4.FeatureCursor類

該類是ESRI的要素游標類,為ArcGIS Eninge中的Class類,不能被直接創建,同樣可以由相關接口中的方法創建。它實現了IFeatureCursor接口,該接口的成員的用法和ICursor接口的成員用法類似,區別是其操作的對象是要素。重要使用NextFeature方法(IFeature NextFeature),將游標的位置向前移動一位,並返回給位置的要素對象。

5.FeatureLayer類

該類主要操作要素的集合及要素的可視化表達,它實現了IFeatureLayer接口和IFeatureSelection接口。

1)IFeatureLayer接口:該接口的成員主要是要素圖層各類常用屬性和操作。其與查詢相關的屬性和方法有:

(1)Selectable屬性:用於獲取或設置圖層是否可被選擇。

(2)FeatureClass屬性:用於獲取或設置圖層的要素類

(3)Search方法:根據設置的查詢條件創建查詢結果的游標。其參數包括IQueryFilter接口的查詢過濾器,以及布爾類型的參數來確定游標是否需要被回收。該方法的返回值為IFeatureCursor類型

2)IFeatureSelection接口:該接口的成員用來控制圖層的要素選擇集,其中與查詢相關的屬性和方法有:

(1)SelectionFeature方法:用於根據設置的查詢條件和選擇方法等來選擇要素。其參數包括IQueryFilter接口的查詢過濾器,esriSelectionResultEnum枚舉類型的選擇集生成方法,以及布爾型的參數控制是否只選擇一個要素。該方法沒有返回值。

(2)SelectionSet屬性。設置或獲取單個矢量圖層的選擇集,其值為ISelectionSet接口類型。

6.FeatureClass類

該類是Engine中的Class類,不能被直接創建,但可以通過多種方法獲取某個圖層的要素類,如果使用IFeatureLayer接口的FeatureClass屬性。它實現了IFeatureClass接口,該接口的成員用於控制要素類的屬性和行為,主要的方法:

1)search方法:根據查詢條件進行查詢並返回結果游標,該方法的用法與IFeatureLayer接口中的Search方法的用法相同。

2)Select方法:根據查詢條件選擇相應的要素,並將其放置在選擇集中。其參數包括IQueryFilter接口查詢過濾器,定義選擇方式參數,定義查詢的工作區的參數。其返回值為ISelectionSet接口類型。

 


 

最終運行截圖

代碼:

復制代碼
  1  public partial class FormQueryByAttribute : DevExpress.XtraEditors.XtraForm
  2     {
  3         //變量定義
  4         private IMap currentMap;//當前MapControl控件的Map對象
  5         private IFeatureLayer currentFeatureLayer;//設置臨時類變量來使用IFeatureLayer接口的當前圖層對象
  6         private string currentFileName;//設置臨時類變量來存儲字段名稱
  7         /// <summary>
  8         /// 獲得當前MapControl控件中的對象
  9         /// </summary>
 10         public IMap CurrentMap
 11         {
 12             set
 13             {
 14                 currentMap = value;
 15             }
 16         }
 17         public FormQueryByAttribute()
 18         {
 19 
 20             InitializeComponent();
 21         }
 22         #region 窗體加載Load事件
 23         private void FormQueryByAttribute_Load(object sender, EventArgs e)
 24         {
 25             try
 26             {
 27                 //將當前圖層列表清空
 28                 comBoxLayerName.Items.Clear();
 29                 string layerName;//設置臨時變量存儲圖層名稱
 30                 //對Map中的每個圖層進行判斷並加載名稱
 31                 for (int i = 0; i < currentMap.LayerCount; i++)
 32                 {
 33                     //如果該圖層為圖層組類型,則分別對所包含的每個圖層進行操作
 34                     if (currentMap.get_Layer(i) is GroupLayer)
 35                     {
 36                         //使用ICompositeLayer接口進行遍歷操作
 37                         ICompositeLayer compositeLayer = currentMap.get_Layer(i) as ICompositeLayer;
 38                         for (int j = 0; j < compositeLayer.Count; j++)
 39                         {
 40                             //將圖層的名稱添加到comboxLayerName中
 41                             layerName = compositeLayer.get_Layer(j).Name;
 42                             comBoxLayerName.Items.Add(layerName);
 43                         }
 44                     }
 45                     //如果圖層不是圖層組類型,則直接添加名稱
 46                     else
 47                     {
 48                         layerName = currentMap.get_Layer(i).Name;
 49                         comBoxLayerName.Items.Add(layerName);
 50                     }
 51                 }
 52                 //將comboxLayerName控件的默認選項設置為第一個圖層名稱
 53                 comBoxLayerName.SelectedIndex = 0;
 54                 //將comboxselectMethod控件的默認選項設置為第一種選擇方式
 55                 comBoxSelectMethod.SelectedIndex = 0;
 56             }
 57             catch { }
 58         }
 59         #endregion
 60         #region 圖層名稱下拉框中選擇的圖層發生改變時觸發事件
 61         private void comBoxLayerName_SelectedIndexChanged(object sender, EventArgs e)
 62         {
 63             //首先將字段列表和字段值列表清空
 64             ListBoxFields.Items.Clear();
 65             ListBoxValues.Items.Clear();
 66             IField field;//設置臨時變量存儲使用的IField接口對象
 67             for (int i = 0; i < currentMap.LayerCount; i++)
 68             {
 69                 if (currentMap.get_Layer(i) is GroupLayer)
 70                 {
 71                     ICompositeLayer compositeLayer = currentMap.get_Layer(i) as ICompositeLayer;
 72                     for (int j = 0; i < compositeLayer.Count; j++)
 73                     {
 74                         //判斷圖層的名稱是否與comBoxLayerName控件中選擇的圖層名稱相同
 75                         if (compositeLayer.get_Layer(j).Name == comBoxLayerName.SelectedItem.ToString())
 76                         {
 77                             //如果相同則設置為整個窗體使用的IFeatureLayer接口對象
 78                             currentFeatureLayer = compositeLayer.get_Layer(j) as IFeatureLayer;
 79                             break;
 80                         }
 81                     }
 82                 }
 83                 else
 84                 {
 85                     //判斷圖層的名稱是否與comboxLayerName控件中選擇的圖層名稱相同
 86                     if (currentMap.get_Layer(i).Name == comBoxLayerName.SelectedItem.ToString())
 87                     {
 88                         //如果相同則設置為整個窗體所使用的IFeatureLayer接口對象
 89                         currentFeatureLayer = currentMap.get_Layer(i) as IFeatureLayer;
 90                         break;
 91                     }
 92                 }
 93             }
 94             //使用IFeatureClass接口對該圖層的所有屬性字段進行遍歷,並填充listboxField控件
 95             for (int i = 0; i < currentFeatureLayer.FeatureClass.Fields.FieldCount; i++)
 96             {
 97                 //根據索引值獲取圖層的字段
 98                 field = currentFeatureLayer.FeatureClass.Fields.get_Field(i);
 99                 //排除SHAPE字段,並在其他字段名稱前后添加字符“\”
100                 if (field.Name.ToUpper() != "SHAPE")
101                     ListBoxFields.Items.Add("\"" + field.Name + "\"");
102             }
103             //更新labelSelectResult控件中的圖層名稱信息
104             labSelectResult.Text = currentFeatureLayer.Name + "WHERE:";
105             //將顯示where語句的文本內容清除
106             txtSelectResult.Clear();
107         }
108         #endregion
109         #region 選擇方式下拉框中選擇的圖層發生改變時觸發事件
110         private void comBoxSelectMethod_SelectedIndexChanged(object sender, EventArgs e)
111         {
112             //首先將listboxvalue控件中的字段屬性清空
113             ListBoxValues.Items.Clear();
114             //將獲取唯一值按鈕設置為可用狀態
115             if (btnOnlyAttributeValue.Enabled == true)
116             {
117                 btnOnlyAttributeValue.Enabled = true;
118             }
119             //設置窗體可用的字段名稱
120             string str = ListBoxFields.SelectedItem.ToString();
121             str = str.Substring(1);
122             str = str.Substring(0,str.Length-1);
123             currentFileName = str;
124         }
125         #endregion
126         #region 獲取唯一值按鈕的單擊事件
127         private void btnOnlyAttributeValue_Click(object sender, EventArgs e)
128         {
129             //將圖層的某個字段進行唯一值獲取操作,並將所有的唯一值顯示在listBoxValues控件中
130             try
131             {
132                 //使用FeatureClass對象的IDataset接口來獲取dataset和workspace的信息
133                 IDataset dataset = (IDataset)currentFeatureLayer.FeatureClass;
134                 //使用IQueryDef接口的對象來定義和查詢屬性信息。通過IWorkspace接口的CreateQueryDef()方法創建該對象。
135                 IQueryDef queryDef = ((IFeatureWorkspace)dataset.Workspace).CreateQueryDef();
136                 //設置所需查詢的表格名稱為dataset的名稱
137                 queryDef.Tables = dataset.Name;
138                 //設置查詢的字段名稱。可以聯合使用SQL語言的關鍵字,如查詢唯一值可以使用DISTINCT關鍵字。
139                 queryDef.SubFields = "DISTINCT (" +currentFileName  + ")";
140                 //執行查詢並返回ICursor接口的對象來訪問整個結果的集合
141                 ICursor cursor = queryDef.Evaluate();
142                 //使用IField接口獲取當前所需要使用的字段的信息
143                 IFields fields = currentFeatureLayer.FeatureClass.Fields;
144                 IField field = fields.get_Field(fields.FindField(currentFileName));
145 
146                 //對整個結果集合進行遍歷,從而添加所有的唯一值
147                 //使用IRow接口來操作結果集合。首先定位到第一個查詢結果。
148                 IRow row = cursor.NextRow();
149                 //如果查詢結果非空,則一直進行添加操作
150                 while (row != null)
151                 {
152                     //對String類型的字段,唯一值的前后添加'和',以符合SQL語句的要求
153                     if (field.Type == esriFieldType.esriFieldTypeString)
154                     {
155                        ListBoxValues.Items.Add("\'" + row.get_Value(0).ToString() + "\'");
156                     }
157                     else
158                     {
159                         ListBoxValues.Items.Add(row.get_Value(0).ToString());
160                     }
161                     //繼續執行下一個結果的添加
162                     row = cursor.NextRow();
163                 }
164             }
165             catch (Exception ex)
166             {
167 
168             }
169 
170         }
171         #endregion
172         #region 各按鈕的單擊事件
173         //關閉
174         private void btnClose_Click(object sender, EventArgs e)
175         {
176             this.Close();
177         }
178         //清除
179         private void btnClear_Click(object sender, EventArgs e)
180         {
181             txtSelectResult.Clear();
182         }
183         //在字段列表中雙擊屬性字段名稱時發生
184         private void ListBoxFields_MouseDoubleClick(object sender, MouseEventArgs e)
185         {
186             //在結果中添加字段的名稱
187             txtSelectResult.Text += ListBoxFields.SelectedItem.ToString();
188         }
189         //字段值列表中雙擊添加
190         private void ListBoxValues_MouseDoubleClick(object sender, MouseEventArgs e)
191         {
192             txtSelectResult.Text += ListBoxValues.SelectedItem.ToString();
193         }
194         //點擊“+”時
195         private void btnEqual_Click(object sender, EventArgs e)
196         {
197             //添加到結果文本框中
198             txtSelectResult.Text += " " + btnEqual.Text + " ";
199 
200         }
201         //點擊“Like”時
202         private void btnLike_Click(object sender, EventArgs e)
203         {
204             txtSelectResult.Text += " " + btnLike.Text + " ";
205         }
206         //
207         private void btnDayu_Click(object sender, EventArgs e)
208         {
209             txtSelectResult.Text += "" + btnDayu.Text + "";
210 
211         }
212 
213         private void btnDayuEqual_Click(object sender, EventArgs e)
214         {
215             txtSelectResult.Text +=" "+btnDayuEqual.Text+" ";
216         }
217 
218         private void btnAnd_Click(object sender, EventArgs e)
219         {
220             txtSelectResult.Text += "" + btnAnd.Text + "";
221         }
222 
223         private void btnXiYu_Click(object sender, EventArgs e)
224         {
225             txtSelectResult.Text += "" + btnXiYu.Text + "";
226         }
227 
228         private void btnXiaoyuEqual_Click(object sender, EventArgs e)
229         {
230             txtSelectResult.Text += "" + btnXiaoyuEqual.Text + "";
231         }
232 
233         private void btnUnderLine_Click(object sender, EventArgs e)
234         {
235             txtSelectResult.Text += "" + btnUnderLine.Text + "";
236         }
237 
238         private void btnPersent_Click(object sender, EventArgs e)
239         {
240             txtSelectResult.Text += "" + btnPersent.Text + "";
241         }
242 
243         private void btnIs_Click(object sender, EventArgs e)
244         {
245             txtSelectResult.Text += "" +btnIs.Text+"";
246         }
247 
248         private void btnNot_Click(object sender, EventArgs e)
249         {
250             txtSelectResult.Text += "" + btnNot.Text + "";
251         }
252 
253         private void btnNoEqual_Click(object sender, EventArgs e)
254         {
255             txtSelectResult.Text += "" + btnNoEqual.Text + "";
256         }
257         #endregion
258         #region 定義執查詢的方法
259         private void SelectFeatureByAttribute()
260         {
261             //使用FeatureLayer對象的IFeatureSelection接口執行查詢操作。進行接口的轉換。
262             IFeatureSelection featureSelection=currentFeatureLayer as IFeatureSelection;
263             //新建IQueryFilter接口的對象來進行Where語句定義
264             IQueryFilter queryFilter=new QueryFilterClass();
265             //設置Where語句內容
266             queryFilter.WhereClause=txtSelectResult.Text;
267             //通過接口轉換使用Map對象的IActiveView接口來部分刷新地圖窗口,從而高亮顯示查詢結果
268             IActiveView activeView =currentMap as IActiveView ;
269             //根據查詢選擇方式的不同,得到不同的選擇集
270             switch(comBoxSelectMethod.SelectedIndex)
271             {
272                 //在新建選擇集的情況下
273                 case 0:
274                     //首先使用IMap接口的ClearSelection()方法清空地圖選擇集
275                     currentMap.ClearSelection();
276                     //根據定義的where語句使用IFeatureSelection接口的SelectFeature方法選擇要素,並將其添加到選擇集中
277                     featureSelection.SelectFeatures(queryFilter,esriSelectionResultEnum.esriSelectionResultNew,false);
278                     break;
279                 case 1:
280                     featureSelection .SelectFeatures(queryFilter,esriSelectionResultEnum.esriSelectionResultAdd,false);
281                     break;
282                 case 2:
283                      featureSelection .SelectFeatures(queryFilter,esriSelectionResultEnum.esriSelectionResultXOR,false);
284                     break;
285                 case 3:
286                      featureSelection .SelectFeatures(queryFilter,esriSelectionResultEnum.esriSelectionResultAdd,false);
287                     break;
288                     //默認為新建選擇集的情況
289                 default:
290                      featureSelection .SelectFeatures(queryFilter,esriSelectionResultEnum.esriSelectionResultNew,false);
291                     break;
292             }
293             //部分刷新操作,只刷新地理選擇集的內容
294             activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection,null,activeView.Extent);
295         }
296         #endregion
297         //確定按鈕
298         private void btnOk_Click(object sender, EventArgs e)
299         {
300             try
301             {
302                 SelectFeatureByAttribute();
303                 this.Close();
304             }
305             catch { }
306         }
307         //應用按鈕
308         private void btnApply_Click(object sender, EventArgs e)
309         {
310             SelectFeatureByAttribute();
311         }
312 
313     }
復制代碼

 

代碼2:主窗口中按鈕事件

復制代碼
 1   #region 屬性查詢的按鈕事件
 2         private void btnSearchAttribute_ItemClick(object sender, ItemClickEventArgs e)
 3         {
 4             //創建新建屬性查詢窗體
 5             FormQueryByAttribute frmQureyByAttribute = new FormQueryByAttribute();
 6             //將當前主窗體的MapControl控件中的Map對象賦值給FormQueryByAttribute窗體的CurrentMap屬性
 7             frmQureyByAttribute.CurrentMap = mainMapControl.Map;
 8             //顯示屬性查詢窗體
 9             frmQureyByAttribute.Show();
10         }
11         #endregion
復制代碼

 

轉載時請注明出處!


免責聲明!

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



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