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