目录
2.1 纲要
2.2 属性查询
本质上是SQL的Where(条件)查询,通过对话框获取条件语句,然后调用相关接口实现。
2.2.1 对话框布局
其中,选择方式如下:
创建新选择集
添加到当前选择集
从当前选择集中删除
从当前选择集中选择
2.2.2 核心代码
明确对话框的职位:获取参数、展示数据,所以核心功能实现应该单独封装成方法。
/// <summary>
/// 属性查询
/// </summary>
/// <param name="pFeaLyr">查询图层</param>
/// <param name="Method">选择方式</param>
/// <param name="WhereClause">查询语句</param>
/// <param name="pActiveView">活动视图</param>
static public bool SelectFeatures(IFeatureLayer pFeaLyr, esriSelectionResultEnum Method,
string WhereClause, IActiveView pActiveView)
{
IFeatureSelection pFeaSelection = (IFeatureSelection)pFeaLyr;
IQueryFilter pQF = new QueryFilterClass();
pQF.WhereClause = WhereClause;
pFeaSelection.SelectFeatures(pQF, Method, false);
if (pFeaSelection.SelectionSet.Count == 0)
return false;
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
return true;
}
在对话框类内再封装:
private void SelectFeaturesByAttribute()
{
//获取参数
IFeatureLayer pFeaLyr = (IFeatureLayer)pMap.get_Layer(comboBoxLayerName.SelectedIndex);
esriSelectionResultEnum selectMethod;
switch (comboBoxSelectMethod.SelectedItem.ToString())
{
case "创建新选择集":
pMap.ClearSelection();
selectMethod = esriSelectionResultEnum.esriSelectionResultNew;
break;
case "添加到当前选择集":
selectMethod = esriSelectionResultEnum.esriSelectionResultAdd;
break;
case "从当前选择集中删除":
selectMethod = esriSelectionResultEnum.esriSelectionResultXOR;
break;
case "从当前选择集中选择":
selectMethod = esriSelectionResultEnum.esriSelectionResultAnd;
break;
default:
pMap.ClearSelection();
selectMethod = esriSelectionResultEnum.esriSelectionResultNew;
break;
}
string sWhere = textBoxWhere.Text;
//执行查询
bool OK = FunctionTool.SelectFeatures(pFeaLyr, selectMethod, sWhere, pMap as IActiveView);
if (!OK)
{
MessageBox.Show("查找失败!");
return;
}
//定位选择集
ICommand cmd = new ControlsZoomToSelectedCommandClass();
cmd.OnCreate(pMapControl);
cmd.OnClick();
}
2.3 空间查询
要理解“源图层”、“空间关系”、“目标图层”概念。
2.3.1 对话框布局
空间关系如下:
相交(Intersects)
包含(Contains)
被包含(Within)
穿过(Crosses)
相接(Touches)
2.3.2 核心代码
/// <summary>
/// 空间查询
/// </summary>
/// <param name="pFeaTargetLyr">目标图层</param>
/// <param name="Method">选择方式</param>
/// <param name="spatialRel">空间关系</param>
/// <param name="pGeo">源图层几何属性</param>
/// <param name="pActiveView">活动视图</param>
static public bool SelectFeatures(esriSelectionResultEnum Method, esriSpatialRelEnum spatialRel,
IGeometry pGeo, IFeatureLayer pFeaTargetLyr, IActiveView pActiveView)
{
IFeatureSelection pFeaSelection = (IFeatureSelection)pFeaTargetLyr;
ISpatialFilter pSF = new SpatialFilterClass();
pSF.Geometry = pGeo;
pSF.SpatialRel = spatialRel;
pFeaSelection.SelectFeatures(pSF, Method, false);
if (pFeaSelection.SelectionSet.Count == 0)
return false;
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
return true;
}
在对话框内再封装:
private void SelectFeaturesBySpatial()
{
//1. 获取参数
//1.1 选择方式
esriSelectionResultEnum selectMethod;
switch (comboBoxMethod.SelectedItem.ToString())
{
case "创建新选择集":
selectMethod = esriSelectionResultEnum.esriSelectionResultNew;
break;
case "添加到当前选择集":
selectMethod = esriSelectionResultEnum.esriSelectionResultAdd;
break;
case "从当前选择集中删除":
selectMethod = esriSelectionResultEnum.esriSelectionResultXOR;
break;
case "从当前选择集中选择":
selectMethod = esriSelectionResultEnum.esriSelectionResultAnd;
break;
default:
selectMethod = esriSelectionResultEnum.esriSelectionResultNew;
break;
}
//1.2 空间关系
esriSpatialRelEnum spatialRel;
switch (comboBoxSpatialRel.SelectedItem.ToString())
{
case "相交(Intersects)":
spatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
break;
case "包含(Contains)":
spatialRel = esriSpatialRelEnum.esriSpatialRelContains;
break;
case "被包含(Within)":
spatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
break;
case "穿过(Crosses)":
spatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
break;
case "相接(Touches)":
spatialRel = esriSpatialRelEnum.esriSpatialRelTouches;
break;
default:
spatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
break;
}
//1.3 源图层的几何体
IFeatureLayer pFeaSourceLyr = (IFeatureLayer)pMap.get_Layer(comboBoxSourceLayer.SelectedIndex);
int count1 = pMapControl.Map.SelectionCount;
IFeatureSelection pFeaSourceSel = pFeaSourceLyr as IFeatureSelection;
IGeometry pGeo = null;
if (checkBoxUseSelected.Checked)
pGeo = FunctionTool.GetGeoUnion(pFeaSourceSel);
//1.4 目标图层&执行查询
for (int i = 0; i < checkedListBoxTargetLayers.CheckedItems.Count; i++)
{
string sLyrName = checkedListBoxTargetLayers.CheckedItems[i].ToString();
IFeatureLayer pFeaTargetLyr = FunctionTool.GetFeaLyr(pMap, sLyrName);
IFeatureSelection pFeaTargetSel = (IFeatureSelection)pFeaTargetLyr;
bool OK = FunctionTool.SelectFeatures
(selectMethod, spatialRel, pGeo, pFeaTargetLyr, pMap as IActiveView);
if (!OK)
{
MessageBox.Show("图层【{0}】查找失败!", pFeaTargetLyr.Name);
return;
}
}
//定位选择集
ICommand cmd = new ControlsZoomToSelectedCommandClass();
cmd.OnCreate(pMapControl);
cmd.OnClick();
}
其中合并几何体的代码:
static public IGeometry GetGeoUnion(IFeatureSelection pFeaSelection)
{
IGeometry pGeo = null;
ISelectionSet pSelSet = pFeaSelection.SelectionSet;
ICursor pCur;
pSelSet.Search(null, false, out pCur);
IFeatureCursor pFeaCur = (IFeatureCursor)pCur;
IFeature pFea = pFeaCur.NextFeature();
while (pFea != null)
{
if (pGeo != null)
{
ITopologicalOperator pTopoOper = (ITopologicalOperator)pGeo;
pGeo = pTopoOper.Union(pFea.Shape);
}
else
pGeo = pFea.Shape;
pFea = pFeaCur.NextFeature();
}
return pGeo;
}
2.3.3 运行结果
【查询前】“行政区B”(源图层)的邻接“行政区”(目标图层) | 【查询后】 |
---|---|
【查询前】跟选中“铁路”(源图层)相交的“道路”和“河流”(目标图层) | 【查询后】 |
---|---|
2.4 选择集
功能跟【属性表】类似,只是数据不一样,因此依然使用【属性表】的窗体,数据获取封装成方法,然后再窗体的构造函数内订阅不同的方法即可。
2.4.1 核心代码
/// <summary>
/// 获取选择集图层名称
/// </summary>
/// <param name="pMap">地图</param>
/// <returns>选择集图层名称</returns>
static public List<string> GetFeaSelNameList(IMap pMap)
{
List<string> pFeaSelectionNameList = new List<string>();
for (int i = 0; i < pMap.LayerCount; i++)
{
IFeatureLayer pFeaLyr = (IFeatureLayer)pMap.get_Layer(i);
IFeatureSelection pFeaSel = (IFeatureSelection)pFeaLyr;
if (pFeaSel.SelectionSet.Count != 0)
pFeaSelectionNameList.Add(pFeaLyr.Name);
}
return pFeaSelectionNameList;
}
获取选择集表的代码跟获取属性表的代码大同小异
/// <summary>
/// 获取选择集表
/// </summary>
/// <param name="pFeaSel">选择集</param>
/// <returns>选择集表</returns>
static public DataTable GetAttributeTable(IFeatureSelection pFeaSel)
{
DataTable pDataTable = new DataTable();
ISelectionSet pSelSet = pFeaSel.SelectionSet;
ICursor pCur;
pSelSet.Search(null, false, out pCur);
IFeatureCursor pFeaCur = (IFeatureCursor)pCur;
IFeature pFea = pFeaCur.NextFeature();
//1. 填充字段名
for (int i = 0; i < pFea.Fields.FieldCount; i++)
pDataTable.Columns.Add(pFea.Fields.get_Field(i).Name);
//2. 填充要素
while (pFea != null)
{
object[] rowValue = new object[pFea.Fields.FieldCount];
for (int i = 0; i < pFea.Fields.FieldCount; i++)
{
object fieldValue;
if (pFea.Fields.get_Field(i).Name == "Shape")
{
switch (pFea.Shape.GeometryType)
{
case esriGeometryType.esriGeometryLine:
fieldValue = "线";
break;
case esriGeometryType.esriGeometryPoint:
fieldValue = "点";
break;
case esriGeometryType.esriGeometryPolygon:
fieldValue = "面";
break;
case esriGeometryType.esriGeometryPolyline:
fieldValue = "线";
break;
default:
fieldValue = "未知";
break;
}
}
else
fieldValue = pFea.get_Value(i);
rowValue[i] = fieldValue;
}
pDataTable.LoadDataRow(rowValue, true);
pFea = pFeaCur.NextFeature();
}
return pDataTable;
}
订阅不同事件
public FormAttributeTable(IMap pMap, bool isSelectionSet = false)
{
InitializeComponent();
this.pMap = pMap;
if (isSelectionSet)
{
this.Text = "选择集";
//订阅事件
lstbLayersName.SelectedIndexChanged += lsbLayersName_SelectedIndexChanged_SelSet;
//触发事件
lstbLayersName.DataSource = FunctionTool.GetFeaSelNameList(pMap);
}
else
{
//注册事件
lstbLayersName.SelectedIndexChanged += lsbLayersName_SelectedIndexChanged;
//触发事件
lstbLayersName.DataSource = FunctionTool.GetLayerNameList(pMap);
}
}
2.4.2 运行结果
空间查询:”行政区D“内有多少“居民地”?
源码链接:组件GIS