CODE:
IQueryFilter pQueryFilter = new QueryFilterClass();
//设置过滤器对象的属性
pQueryFilter.WhereClause = "人口> 10000000";
SpatialFilter过滤器主要用于空间范围查询条件的设置,它主要实现ISpatialFilter(继承 IQueryFilter接口)接口从而实现空间查询功能。
CODE:
ISpatialFilter pSpatialFilter = new SpatialFilterClass();
//设置空间过滤器的范围(多边形)
pSpatialFilter.Geometry = pGeometry;
//设置空间过滤器空间关系类型
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
表1
空间过滤器空间关系类型 |
描述(A是待查询图形,B是过滤条件图形) |
esriSpatialRelUndefined |
未定义 |
esriSpatialRelIntersects |
A与B图形相交 |
esriSpatialRelEnvelopeIntersects |
A的Envelope和B的Envelope相交 |
esriSpatialRelIndexIntersects |
A与B索引相交 |
esriSpatialRelTouches |
A与B边界相接 |
esriSpatialRelOverlaps |
A与B相叠加 |
esriSpatialRelCrosses |
A与B相交(两条线相交于一点,一条线和一个面相交) |
esriSpatialRelWithin |
A在B内 |
esriSpatialRelContains |
A包含B |
esriSpatialRelRelation |
A与B空间关联 |
IFeatureLayer pFeatureLayer = this.axMapControl1.get_Layer(0) as IFeatureLayer;
//QI至IFeatureSelection
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
//创建过滤器
IQueryFilter pQueryFilter = new QueryFilterClass();
//设置过滤器对象的查询条件
pQueryFilter.WhereClause = "人口> 10000000";
//选择要素
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew,false);
//获取选择集对象
ISelectionSet pSelectinSet=pFeatureSelection.SelectionSet;
//设置选择集的符号
pFeatureSelection.SelectionSymbol = pSymbol;
CODE:
private void button1_Click(object sender, EventArgs e)
{
IFeatureLayer pFeatureLayer = this.axMapControl1.get_Layer(0) as IFeatureLayer;
//QI到FeatureSelection
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
//创建过滤器
IQueryFilter pQueryFilter = new QueryFilterClass();
//设置过滤器对象的查询条件
pQueryFilter.WhereClause = "人口> 5000000";
//根据查询条件选择要素
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
//QI到ISelectionSet
ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet;
if (pSelectionSet.Count > 0)
{
IFeatureLayerDefinition pFDefinition = pFeatureLayer as IFeatureLayerDefinition;
//创建新图层
IFeatureLayer pNewFeatureLayer = pFDefinition.CreateSelectionLayer("newlayerName", true, null, null);
pNewFeatureLayer.Name = "查询结果城市";
axMapControl1.AddLayer(pNewFeatureLayer as ILayer);
}
}
code]
5.7空间查询实例
5.7.1目标
实现多边形查询功能
5.7.2功能开发
代码片段如下:
引用的命名空间:
[code]
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.DataSourcesGDB;
//////
在程序运行时的内存中创建矢量要素层,并加到地图控件最顶端
/// ///
地图控件
///IFeatureLayer 新加的要素层
private IFeatureLayer AddFeatureLayerByMemoryWS(AxMapControl pMapCtrl,ISpatialReference pSReference)
{
try
{
if (pMapCtrl == null) return null;
#region
创建新的内存工作空间
IWorkspaceFactory pWSF = new InMemoryWorkspaceFactoryClass();
IWorkspaceName pWSName = pWSF.Create("", "Temp", null, 0);
IName pName = (IName)pWSName;
IWorkspace pMemoryWS = (IWorkspace)pName.Open();
#endregion
IField Field = new FieldClass();
IFields Fields = new FieldsClass();
IFieldsEdit FieldsEdit = null;
IFieldEdit FieldEdit = null;
IFeatureClass FeatureClass = null;
IFeatureLayer FeatureLayer = null;
try
{
FieldsEdit = oFields as IFieldsEdit;
oFieldEdit = oField as IFieldEdit;
oFieldEdit.Name_2 = "OBJECTID";
oFieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
oFieldEdit.IsNullable_2 = false;
oFieldEdit.Required_2 = false;
oFieldsEdit.AddField(oField);
oField = new FieldClass();
oFieldEdit = oField as IFieldEdit;
IGeometryDef pGeoDef = new GeometryDefClass();
IGeometryDefEdit pGeoDefEdit = (IGeometryDefEdit)pGeoDef;
pGeoDefEdit.AvgNumPoints_2 = 5;
pGeoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon;
pGeoDefEdit.GridCount_2 = 1;
pGeoDefEdit.HasM_2 = false;
pGeoDefEdit.HasZ_2 = false;
pGeoDefEdit.SpatialReference_2 = pSReference;
oFieldEdit.Name_2 = "SHAPE";
oFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
oFieldEdit.GeometryDef_2 = pGeoDef;
oFieldEdit.IsNullable_2 = true;
oFieldEdit.Required_2 = true;
oFieldsEdit.AddField(oField);
oField = new FieldClass();
oFieldEdit = oField as IFieldEdit;
oFieldEdit.Name_2 = "Code";
oFieldEdit.Type_2 = esriFieldType.esriFieldTypeSmallInteger;
oFieldEdit.IsNullable_2 = true;
oFieldsEdit.AddField(oField);
//创建要素类
oFeatureClass = (pMemoryWS as IFeatureWorkspace).CreateFeatureClass("Temp", oFields, null, null, esriFeatureType.esriFTSimple, "SHAPE", "");
oFeatureLayer = new FeatureLayerClass();
oFeatureLayer.Name = "TransTemp";
oFeatureLayer.FeatureClass = oFeatureClass;
//创建唯一值符号化对象
IUniqueValueRenderer pURender = new UniqueValueRendererClass();
pURender.FieldCount = 1;
pURender.set_Field(0, "Code");
pURender.UseDefaultSymbol = false;
ISimpleFillSymbol pFillSym = new SimpleFillSymbolClass();
pFillSym.Style. = esriSimpleFillStyle.esriSFSSolid;
//半透明颜色
IRgbColor pColor = new RgbColorClass();
pColor.Red = 255;
pColor.Green = 255;
pFillSym.Color = pColor;
pURender.AddValue("1", "", pFillSym as ISymbol);
pFillSym = new SimpleFillSymbolClass();
pFillSym.Style. = esriSimpleFillStyle.esriSFSSolid;
//唯一值符号化内存图层
(oFeatureLayer as IGeoFeatureLayer).Renderer = pURender as IFeatureRenderer;
ILayerEffects pLyrEffect = oFeatureLayer as ILayerEffects;
//透明度
pLyrEffect.Transparency = 80;
}
catch(Exception Err)
{
MessageBox.Show(Err.Message);
}
finally
{
try{
ystem.Runtime.InteropServices.Marshal.ReleaseComObject(oField);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oFields);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oFieldsEdit);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oFieldEdit);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pName);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pWSF);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pWSName);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pMemoryWS);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oFeatureClass);
}
catch
{
}
GC.Collect();
}
return oFeatureLayer;
}
catch (Exception Err)
{
MessageBox.Show(Err.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return null;}
}
CODE:
/// 在地图控件上添加透明临时图元///
/// 地图控件
/// Envelope或Polygon几何实体
/// 是否清除原有内容
public void AddTransTempEle(AxMapControl pMapCtrl, IGeometry pGeo, bool bAutoClear)
{
try
{
if (pMapCtrl == null) return;
if (pGeo == null) return;
if (pGeo.IsEmpty) return;
IGeometry pPolygon = null;
if (pGeo is IEnvelope)
{
object Miss = Type.Missing;
pPolygon = new PolygonClass();
IGeometryCollection pGeoColl = pPolygon as IGeometryCollection;
pGeoColl.AddGeometry(pGeo, ref Miss, ref Miss);
}
else if (pGeo is IPolygon)
{
(pGeo as ITopologicalOperator).Simplify();
pPolygon = pGeo;
}
else
{
MessageBox.Show( "几何实体类型不匹配","提示" ,MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
//获取透明要素层
IFeatureLayer pFlyr = null;
for (int i = 0; i < pMapCtrl.LayerCount; i++)
{
if (pMapCtrl.get_Layer(i).Name == "TransTemp")
{
pFlyr = pMapCtrl.get_Layer(i) as IFeatureLayer;
break;
}
}
//透明临时层不存在需要创建
if (pFlyr == null)
{
pFlyr = AddFeatureLayerByMemoryWS(pMapCtrl,pMapCtrl.SpatialReference);
if (pFlyr == null)
{
MessageBox.Show("创建透明临时图层发生异常", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
}
IFeatureClass pFC = pFlyr.FeatureClass;
if (bAutoClear)
{
if (pFC.FeatureCount(null) > 0)
{
IFeatureCursor pFCursor = pFC.Search(null, false);
if (pFCursor != null)
{
IFeature pFeature = pFCursor.NextFeature();
if (pFeature != null)
{
while (pFeature != null)
{
pFeature.Delete();
pFeature = pFCursor.NextFeature();
}
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFCursor);
}
}
}
//创建要素
IFeature pNFeature = pFC.CreateFeature();
pNFeature.Shape = pPolygon;
pNFeature.set_Value(pFC.FindField("Code"),"1");
pNFeature.Store();
pMapCtrl.Refresh(esriViewDrawPhase.esriViewGeography, pFlyr, pFlyr.AreaOfInterest);
}
catch (Exception Err)
{
MessageBox.Show(Err.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
CODE:
///
/// 获取查询要素
///
/// 要素图层
/// 图形范围参数
/// 符号条件要素集合
private List GetSeartchFeatures( IFeatureLayer pFeatureLayer,IGeometry pGeometry)
{
try
{
List pList = new List();
//创建SpatialFilter空间过滤器对象
ISpatialFilter pSpatialFilter = new SpatialFilterClass();
IQueryFilter pQueryFilter = pSpatialFilter as ISpatialFilter;
//设置过滤器的Geometry
pSpatialFilter.Geometry = pGeometry;
//设置空间关系类型
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
//获取FeatureCursor游标
IFeatureCursor pFeatureCursor = pFeatureLayer.Search(pQueryFilter, false);
//遍历FeatureCursor
IFeature pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
//获取要素对象
pList.Add(pFeature);
pFeature = pFeatureCursor.NextFeature();
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
return pList;
}
catch (Exception Err)
{
MessageBox.Show(Err.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return null;
}
}
CODE:
bool bSearch = false; //定义bool变量用于启动多边形查询功能
private void button1_Click(object sender, EventArgs e)
{
try
{
//向地图控件添加内存图层
IFeatureLayer pFeatureLayer = this.AddFeatureLayerByMemoryWS(this.axMapControl1,this.axMapControl1.SpatialReference);
this.axMapControl1.AddLayer(pFeatureLayer);
//设置鼠标样式为十字丝
this.axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
//启动范围查询功能
bSearch = true;
}
添加一个新的Form在Form上添加一个DataGridView控件用于显示查询结果信息。如图4所示:CODE:
private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
if (bSearch)
{
//设置鼠标样式为十字丝
this.axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
//获取画定范围的Geometry
IGeometry pGeometry = this.axMapControl1.TrackPolygon();
//添加半透名临时图形
this.AddTransTempEle(this.axMapControl1, pGeometry, false);
IFeatureLayer pFeatureLayer=this.axMapControl1.get_Layer(1) as IFeatureLayer;
//执行查询获取符号条件的要素
List pFList = this.GetSeartchFeatures(pFeatureLayer, pGeometry);
attribute pAttribute = new attribute();
//设置信息显示窗体中DataGridView的属性
//设置行数pFList.Count+1包括字段名哪一行即表头
pAttribute.dataGridView1.RowCount = pFList.Count+1;
//设置边界风格
pAttribute.dataGridView1.ColumnHeadersBorderStyle. = DataGridViewHeaderBorderStyle.Sunken;
//设置列数
pAttribute.dataGridView1.ColumnCount = pFList[0].Fields.FieldCount;
//遍历第一个要素的字段用于给列头赋值(字段的名称)
for(int m=0;m {
pAttribute.dataGridView1.Columns[m].HeaderText = pFList[0].Fields.get_Field(m).AliasName;
}
//遍历要素
for (int i = 0; i < pFList.Count; i++)
{
IFeature pFeature=pFList;
for(int j=0;j {
//填充字段值
pAttribute.dataGridView1[j, i].Value = pFeature.get_Value(j).ToString();
}
}
pAttribute.Show();
}
}
5.7.3功能演示
1.单击按钮向地图控件上添加一内存图层,并启动多边形查询功能如图5示:
1.pFeatureCursor存储的是所有符合条件的Feature对象的引用,
2.Recycling的意思是回收,参数Recycling为True的时当执行这个方法IFeature pFeature=pFeatureCursor.NextFeature()上一条记录的图形值在内存中所占的地址就会被销毁回收,为False的时候当执行这个方法IFeature pFeature=pFeatureCursor.NextFeature()上一条记录的图形值依然存在在内存中。
1.参数Recycling设置为True
IFeatureClass pFeatureClass = (this.axMapControl1.get_Layer(0) as IFeatureLayer).FeatureClass;
IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, true);
//IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, false);
List
IFeature pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
pFeatures.Add(pFeature);
pFeature = pFeatureCursor.NextFeature();
}
for (int i = 0; i < pFeatures.Count; i++)
{
MessageBox.Show(((pFeatures.Shape as IPolygon) as IArea).Area.ToString());
}
分析:pFeatures集合存储了指向FeatureClass上所有Feature的引用,但是由于Recycling参数设置为TRUE也就是说每执行一个NextFeautre方法上一条记录的Feature值在内存中被回收,所以到最后遍历pFeatures集合的时候所有的IFeature引用指向的Feature对象都为Null。所以会引发一下错误(如下图7所示):
分析:pFeatures集合存储了指向FeatureClass上所有Feature的引用,但是由于Recycling参数设置为False也就是说每执行一个NextFeautre方法上一条记录的Feature值在内存中依然存在,所以到最后遍历pFeatures集合的时候所有的IFeature引用指向的Feature对象都依然存在。所以会执行的很Happy(如下图8所示):
image016.jpg
图8
Link: http://www.gisall.com/html/59/4359-899.html