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 }
-----------------------------------------------------割割更健康,一入糗百深似海------------------------------------------------------
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 }
这两个例子,直观的演示了,如何进行属性查询和空间查询,细细研究代码实现,收获不小。