ArcEngine 9.3 学习笔记(九):地图查询(属性查询实例、空间查询实例)

5.6 属性查询实例
  查询人口大于50000000的城市,并把查询结果创建为一个新的图层。
  程序执行效果如下:

图1:基础MXD文件(注意属性表)

图2:查询功能实现

图3:将选择集创建为新图层

代码如下:

 1         private void button2_Click(object sender, EventArgs e,AxMapControl axMapControl1)
 2         {
 3             IFeatureLayer pFeatureLayer = axMapControl1.get_Layer(0) as IFeatureLayer;
 4             // QI 到FeatureSelection
 5             IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
 6             // 创建过滤器
 7             IQueryFilter pQueryFilter = new QueryFilterClass();
 8             // 设置过滤器对象的查询条件
 9             pQueryFilter.WhereClause = "人口>50000000";
10             // 根据查询条件选中要素
11             pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
12             // QI 到SelectionSet
13             ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet;
14 
15             if (pSelectionSet.Count > 0)
16             {
17                 IFeatureLayerDefinition pFDefinition = pFeatureLayer as IFeatureLayerDefinition;
18                 // 创建新图层
19                 IFeatureLayer pNewFeatureLayer = pFDefinition.CreateSelectionLayer("newLayerName", true, null, null);
20                 pNewFeatureLayer.Name = "查询结果城市";
21                 axMapControl1.AddLayer(pNewFeatureLayer as ILayer);
22             }
23         }
View Code

-----------------------------------------------------割割更健康,一入糗百深似海------------------------------------------------------

5.7 空间查询实例
  目标  :实现多边形查询功能

功能演示:

  1、单击按钮向地图控件上添加一内存图层,并启动多边形查询功能,如图所示:

 

  2、点击鼠标左键,在地图上画一多边形范围,双击结束,将看到在所画的范围,以半透明的形式添加在地图之上,并显示出查询结果的属性信息,

  如图所示:

 

接下来,实现代码如下:

  1         /// <summary>
  2         /// 在程序运行时的内存中创建矢量要素层,并加到地图控件最顶端
  3         /// </summary>
  4         /// <param name="pMapCtrl">地图控件</param>
  5         /// <param name="pSReference">IFeatureLayer 新加的要素图层</param>
  6         /// <returns></returns>
  7         private IFeatureLayer AddFeatureLayerByMemoryWS(AxMapControl pMapCtrl, ISpatialReference pSReference)
  8         {
  9             try
 10             {
 11                 if (pMapCtrl == null) return null;
 12 
 13                 #region 创建新的内存工作空间
 14 
 15                 IWorkspaceFactory pWSF = new InMemoryWorkspaceFactoryClass();
 16                 IWorkspaceName pWSName = pWSF.Create("","TelChina",null,0);
 17                 IName pName = pWSName as IName;
 18                 IWorkspace pMemoryWS = pName.Open() as  IWorkspace;
 19 
 20                 #endregion
 21 
 22                 IField oField = new FieldClass();
 23                 IFields oFields = new FieldsClass();
 24                 IFieldEdit oFieldEdit = null;
 25                 IFieldsEdit oFieldsEdit = null;
 26 
 27                 IFeatureClass oFeatureClass = null;
 28                 IFeatureLayer oFeatureLayer = null;
 29                 try
 30                 {
 31                     // 创建OID字段
 32                     oFieldEdit = oField as IFieldEdit;
 33                     oFieldsEdit = oFields as IFieldsEdit;
 34                     oFieldEdit.Name_2 = "OBJECTID";
 35                     oFieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
 36                     oFieldEdit.IsNullable_2 = false;
 37                     oFieldEdit.Required_2 = false;
 38                     oFieldsEdit.AddField(oField);
 39 
 40                     // 创建图形要素字段
 41                     oField = new FieldClass();
 42                     oFieldEdit = oField as IFieldEdit;
 43                     IGeometryDef pGeoDef = new GeometryDefClass();
 44                     IGeometryDefEdit pGeoDefEdit = pGeoDef as IGeometryDefEdit;
 45                     pGeoDefEdit.AvgNumPoints_2 = 5;
 46                     pGeoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon;
 47                     pGeoDefEdit.GridCount_2 = 1;
 48                     pGeoDefEdit.HasM_2 = false;
 49                     pGeoDefEdit.HasZ_2 = false;
 50                     pGeoDefEdit.SpatialReference_2 = pSReference;
 51 
 52                     oFieldEdit.Name_2 = "SHAPE";
 53                     oFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
 54                     oFieldEdit.GeometryDef_2 = pGeoDef;
 55                     oFieldEdit.IsNullable_2 = true;
 56                     oFieldEdit.Required_2 = true;
 57                     oFieldsEdit.AddField(oField);
 58                     //
 59                     oField = new FieldClass();
 60                     oFieldEdit = oField as IFieldEdit;
 61                     oFieldEdit.Name_2 = "Code";
 62                     oFieldEdit.Type_2 = esriFieldType.esriFieldTypeSmallInteger;
 63                     oFieldEdit.IsNullable_2 = true;
 64                     oFieldsEdit.AddField(oField);
 65 
 66                     //创建要素类
 67                     oFeatureClass = (pMemoryWS as IFeatureWorkspace).CreateFeatureClass("Temp", oFields, null, null, esriFeatureType.esriFTSimple, "SHAPE", "");
 68                     oFeatureLayer = new FeatureLayerClass();
 69                     oFeatureLayer.Name = "TransTemp";
 70                     oFeatureLayer.FeatureClass = oFeatureClass;
 71 
 72                     //创建唯一值符号化对象
 73                     IUniqueValueRenderer pURender = new UniqueValueRendererClass();
 74                     pURender.FieldCount = 1;
 75                     pURender.set_Field(0, "Code");
 76                     ISimpleFillSymbol pFillSym = new SimpleFillSymbolClass();
 77                     pFillSym.Style = esriSimpleFillStyle.esriSFSSolid;
 78                     //半透明颜色
 79                     IRgbColor pColor = new RgbColorClass();
 80                     pColor.Red = 255;
 81                     pColor.Green = 255;
 82                     pFillSym.Color = pColor;
 83                     pURender.AddValue("1", "", pFillSym as ISymbol);
 84                     pFillSym = new SimpleFillSymbolClass();
 85                     pFillSym.Style = esriSimpleFillStyle.esriSFSSolid;
 86                     //唯一值符号化内存图层
 87                     (oFeatureLayer as IGeoFeatureLayer).Renderer = pURender as IFeatureRenderer;
 88                     ILayerEffects pLyrEffect = oFeatureLayer as ILayerEffects;
 89                     //透明度
 90                     pLyrEffect.Transparency = 80;
 91 
 92                 }
 93                 catch (Exception ex)
 94                 {
 95                     MessageBox.Show(ex.Message);
 96                 }
 97                 finally
 98                 {
 99                     try
100                     {
101                         System.Runtime.InteropServices.Marshal.ReleaseComObject(oField);
102                         System.Runtime.InteropServices.Marshal.ReleaseComObject(oFields);
103                         System.Runtime.InteropServices.Marshal.ReleaseComObject(oFieldsEdit);
104                         System.Runtime.InteropServices.Marshal.ReleaseComObject(oFieldEdit);
105                         System.Runtime.InteropServices.Marshal.ReleaseComObject(pName);
106                         System.Runtime.InteropServices.Marshal.ReleaseComObject(pWSF);
107                         System.Runtime.InteropServices.Marshal.ReleaseComObject(pWSName);
108                         System.Runtime.InteropServices.Marshal.ReleaseComObject(pMemoryWS);
109                         System.Runtime.InteropServices.Marshal.ReleaseComObject(oFeatureClass);
110                     }
111                     catch
112                     {
113                     }
114                     GC.Collect();
115                 }
116                 return oFeatureLayer;
117             }
118             catch (Exception)
119             {
120                 return null;
121             }
122         }
123 
124         /// <summary>
125         /// 在地图控件上添加透明临时图元
126         /// </summary>
127         /// <param name="pMapCtrl">地图控件</param>
128         /// <param name="pGeo">Envelope或Polygon几何实体</param>
129         /// <param name="bAutoClear">是否清楚原有内容</param>
130         public void AddTransTempEle(AxMapControl pMapCtrl, IGeometry pGeo, bool bAutoClear)
131         {
132             try
133             {
134                 if (pMapCtrl == null) return;
135                 if (pGeo == null) return;
136                 if (pGeo.IsEmpty) return;
137                 IGeometry pPolygon = null;
138                 if (pGeo is IEnvelope)
139                 {
140                     // 如果是Envelope,则创建Polygon,转为Polygon集合,将Envelope添加进集合,进而,polygon中就包含了Envelope了
141                     object Miss = Type.Missing;
142                     pPolygon = new PolygonClass();
143                     IGeometryCollection pGeoColl = pPolygon as IGeometryCollection;
144                     pGeoColl.AddGeometry(pGeo, ref Miss, ref Miss);
145                 }
146                 else if (pGeo is IPolygon)
147                 {
148                     // 如果是Polygon,就进行拓扑后,直接转换为Polygon
149                     (pGeo as ITopologicalOperator).Simplify();
150                     pPolygon = pGeo;
151                 }
152                 else
153                 {
154                     MessageBox.Show("几何实体类型不匹配","提示",MessageBoxButtons.OK, MessageBoxIcon.Information);
155                     return;
156                 }
157                 // 获取透明要素层
158                 IFeatureLayer pFlyr = null;
159                 for (int i = 0; i < pMapCtrl.LayerCount; i++)
160                 {
161                     if (pMapCtrl.get_Layer(i).Name == "TransTemp")
162                     {
163                         pFlyr = pMapCtrl.get_Layer(i) as IFeatureLayer;
164                         break;
165                     }
166                 }
167                 // 透明临时图层不存在,则创建
168                 if (pFlyr == null)
169                 {
170                     pFlyr = AddFeatureLayerByMemoryWS(pMapCtrl, pMapCtrl.SpatialReference);
171                     if (pFlyr == null)
172                     {
173                         MessageBox.Show("创建透明临时图层发生异常","提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
174                         return;
175                     }
176                 }
177                 // 清理要素图层
178                 IFeatureClass pFC = pFlyr.FeatureClass;
179                 if (bAutoClear)
180                 {
181                     if (pFC.FeatureCount(null) > 0)
182                     {
183                         IFeatureCursor pFCursor = pFC.Search(null, false);
184                         if (pFCursor != null)
185                         {
186                             IFeature pFeature = pFCursor.NextFeature();
187                             if (pFeature != null)
188                             {
189                                 while (pFeature!=null)
190                                 {
191                                     pFeature.Delete();
192                                     pFeature = pFCursor.NextFeature();
193                                 }
194                             }
195                             System.Runtime.InteropServices.Marshal.ReleaseComObject(pFCursor);
196                         }
197                     }
198                 }
199                 //创建要素
200                 IFeature pNFeature = pFC.CreateFeature();//pFC 是pFlyr中的要素类,这里相当于在pFlyr中创建要素
201                 pNFeature.Shape = pPolygon;// 将 参数Envelope 对象设置到pFlyr中
202                 pNFeature.set_Value(pFC.FindField("Code"), "1");// 给创建的要素赋值
203                 pNFeature.Store();// 更新要素
204                 pMapCtrl.Refresh(esriViewDrawPhase.esriViewGeography, pFlyr, pFlyr.AreaOfInterest);// 这样pFlyr中就有了以pPolygon为原型的透明图元
205             }
206             catch (Exception)
207             {
208 
209             }
210         }
211         /// <summary>
212         /// 获取要查询的要素
213         /// </summary>
214         /// <param name="pFeatureLayer">要素图层</param>
215         /// <param name="pGeometry">图形范围参数</param>
216         /// <returns>符合条件的要素集合</returns>
217         private List<IFeature> GetSearchFeatures(IFeatureLayer pFeatureLayer, IGeometry pGeometry)
218         {
219             try
220             {
221                 List<IFeature> pList = new List<IFeature>();
222                 //创建SpatialFilter空间过滤器对象
223                 ISpatialFilter pSpatialFilter = new SpatialFilterClass();
224                 IQueryFilter pQueryFilter = pSpatialFilter as ISpatialFilter;
225                 //设置过滤器的Geometry
226                 pSpatialFilter.Geometry = pGeometry;
227                 //设置空间关系类型
228                 pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
229                 //获取FeatureCursor游标
230                 IFeatureCursor pFeatureCursor = pFeatureLayer.Search(pQueryFilter, false);
231                 //遍历FeatureCursor
232                 IFeature pFeature = pFeatureCursor.NextFeature();
233                 while (pFeature!=null)
234                 {
235                     //获取要素对象
236                     pList.Add(pFeature);
237                     pFeature = pFeatureCursor.NextFeature();
238                 }
239                 System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
240                 return pList;
241             }
242             catch (Exception)
243             {
244                 return null;
245             }
246         }
247         bool bSearch = false; //定义bool变量,用于启动多边形查询功能
248         private void button1_Click(object sender, EventArgs e,AxMapControl axMapCtrl)
249         {
250             try
251             {
252                 // 向地图控件添加内存图层
253                 IFeatureLayer pFeatureLayer = this.AddFeatureLayerByMemoryWS(axMapCtrl, axMapCtrl.SpatialReference);
254                 axMapCtrl.AddLayer(pFeatureLayer);
255                 //设置鼠标样式为十字丝
256                 axMapCtrl.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
257                 // 启动范围查询功能
258                 bSearch = true;
259             }
260             catch (Exception)
261             {
262 
263                 throw;
264             }
265         }
266 
267         // 在新Form中添加一个DataGridView控件,用于显示查询结果信息
268         private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e,AxMapControl axMapCtrl)
269         {
270             if (bSearch)
271             { 
272                 //设置鼠标样式为十字丝
273                 axMapCtrl.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
274                 // 获取划定范围的Geometry
275                 IGeometry pGeometry = axMapCtrl.TrackPolygon();
276                 //添加半透明临时图形
277                 this.AddTransTempEle(axMapCtrl, pGeometry, false);
278                 IFeatureLayer pFeatureLayer = axMapCtrl.get_Layer(1) as IFeatureLayer;
279                 //执行查询获取符号条件的要素
280                 List<IFeature> pFList = GetSearchFeatures(pFeatureLayer, pGeometry);
281 
282                 //实例化包含DataGridView的窗体。取出DataGridView用来设置值,显示被选中要素的属性字段
283                 attribute pAttribute = new attribute();
284                 //设置信息显示窗体中DataGridView属性
285                 // 设置行数pFList。Count+1 包括字段名那一行 即表头
286                 pAttribute.dataGridView1.RowCount = pFList.Count + _1;
287                 //设置边界风格
288                 pAttribute.dataGridView1.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Sunken;
289                 //设置列数
290                 pAttribute.dataGridView1.ColumnCount = pFList[0].Fields.FieldCount;
291                 //遍历第一个要素的字段用于给列头赋值(字段的名称)
292                 for (int m = 0; m < pFList[0].Fields.FieldCount; m++)
293                 {
294                     pAttribute.dataGridView1.Columns[m].HeaderText = pFList[0].Fields.get_Field(m).AliasName;
295                 }
296                 //遍历要素
297                 for (int i = 0; i < pFList.Count; i++)
298                 {
299                     IFeature pFeature = pFList[i];
300                     for (int j = 0; j < pFeature.Fields.FieldCount; j++)
301                     {
302                         //填充字段值
303                         pAttribute.dataGridView1[j, i].Value = pFeature.get_Value(j).ToString();
304                     }
305                 }
306                 pAttribute.Show();
307                 //
308             }
309         }
View Code

这两个例子,直观的演示了,如何进行属性查询和空间查询,细细研究代码实现,收获不小。

posted @ 2013-06-04 00:05  铁手三郎  阅读(2413)  评论(0编辑  收藏  举报