【ArcGIS二次开发】多图层查询要素并单独显示

需求举例:

如果我们有三年的空间数据存放在三个不同图层中,现在通过编写程序设定好了所需要素的属性条件和空间条件,查询出三个图层中满足这些条件的要素,并高亮显示在已有的地理底图中,便于观察对比。所要达到效果如下图(点击放大)所示:

demo

功能思路:

实现这个功能可以有多种方式:

1. 创建新图层,将选中要素复制到新图层中;

2. 将要素转换为element,然后放到grahicscontainer中,单独显示;

3. 创建临时图层SelectionLayer。

这三种方式中,第一种需要创建要素类、设置坐标参数、属性结构等等,还涉及图层之间的要素拷贝,较为麻烦,第二种方式创建不含属性结构的element,代码上简单一些了,但是当查询量非常大的时候element的管理效率不如feature的高,会导致界面刷新缓慢,用户体验较差,第三种方式是常用的查询显示要素的办法,只不过针对多图层的查询需要通过循环创建多个SelectionLayer,但是这种方式执行效率最高,代码实现也比较容易。

功能实现:

首先,将底图图层、存放空间数据的三个图层加载到工程中,然后底图的visible属性设置为true,其他图层设置为false;

然后,编写函数实现根据设置条件选中指定图层中的要素,并通过要素创建SelectionLayer,函数代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static IFeatureLayer CreateSelectionLayer(IGeometry outGeometry, IActiveView pAv, string whereclause, string sourcelayername, string selectionlayername)
{
int index = GetIndexByLayerName(sourcelayername, pAv);
//设置查询条件,空间+属性
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = outGeometry;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
spatialFilter.WhereClause = whereclause;
//在原图层中选取要素集
IFeatureLayer pFeatureLayer = pAv.FocusMap.get_Layer(index) as IFeatureLayer;
IFeatureSelection pFtSelection = pFeatureLayer as IFeatureSelection;
pFtSelection.SelectFeatures(spatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
//选取结果返回
IFeatureLayerDefinition pFeaturelyrdef = pFtSelection as IFeatureLayerDefinition;
pFeaturelyrdef.DefinitionExpression = whereclause;
IFeatureLayer pflay = pFeaturelyrdef.CreateSelectionLayer(selectionlayername, true, null, null);
pflay.Visible = true;
pflay.Name = selectionlayername;
pflay.Selectable = true;
return pflay;
}

最后,在主函数中循环调用CreateSelectionLayer创建临时图层,并将图层添加到工作区内,高亮显示,可以建立字符串数组,存储创建的图层名字,便于退出程序时将其删除:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void SpatialQuery(IGeometry outGeometry, IActiveView pAv, MainFrm fm)
{
if (fm.m_year_list.Count <= 0)
{
MessageBox.Show("未找到要加载的图层!");
return;
}
for (int i = 0; i < fm.m_year_list.Count; i++)
{
string sourcelayername = "year" + fm.m_year_list[i];
string selectionlayername = "tmp" + fm.m_year_list[i];
IFeatureLayer tmplay = CreateSelectionLayer(outGeometry, pAv, fm.m_sWhereClause, sourcelayername, selectionlayername);
pAv.FocusMap.AddLayer(tmplay);
}
pAv.Refresh();
}

总结:以上只是一个简单的示例,显示结果的表达可以根据自己需求去写了。