ArcGIS Engine开发之属性查询

属性查询即基于空间数据的属性数据的查询,通过用户提交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

 

  • 2
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值