【ArcEngine入门与提高】要素选择工具
选择工具继承自BaseTool,主要使用IHookHelper接口、ITracker接口、IGeometry接口等。
/// <summary>
/// 选择要素工具
/// </summary>
public sealed class BTSelectFeature : BaseTool
{
#region 成员变量
private IHookHelper m_hookHelper;
/// <summary>
/// 设置图层。
/// </summary>
public IFeatureLayer FeatureLayer { get; set; }
/// <summary>
/// 选择工具类型:1为矩形,2为多边形,3为圆形,4为点,5为线。
/// </summary>
public SpatialTypeEnum SpatialType { get; set; }
/// <summary>
/// 父窗体
/// </summary>
public Form ParentForm { get; set; }
#endregion
#region 构造函数
public BTSelectFeature()
{
base.m_category = "";
base.m_caption = "";
base.m_message = "";
base.m_toolTip = "";
base.m_name = "";
base.m_cursor = Cursors.Cross;
}
public BTSelectFeature(AeEnums.SpatialTypeEnum spatialType)
: this()
{
SpatialType = spatialType;
}
public BTSelectFeature(IFeatureLayer pFeatureLayer, AeEnums.SpatialTypeEnum spatialType)
: this(spatialType)
{
FeatureLayer = pFeatureLayer;
}
public BTSelectFeature(IFeatureLayer pFeatureLayer, AeEnums.SpatialTypeEnum spatialType, Form parentForm)
: this(pFeatureLayer, spatialType)
{
ParentForm = parentForm;
}
#endregion
#region 方法覆写
public override void OnCreate(object hook)
{
try
{
m_hookHelper = new HookHelperClass();
m_hookHelper.Hook = hook;
if (m_hookHelper.ActiveView == null)
{
m_hookHelper = null;
}
}
catch
{
m_hookHelper = null;
}
if (m_hookHelper == null)
base.m_enabled = false;
else
base.m_enabled = true;
// TODO: Add other initialization code
}
public override void OnClick()
{
// TODO: Add StationTool.OnClick implementation
if (ParentForm != null)
ParentForm.WindowState = FormWindowState.Minimized;
}
public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
// TODO: Add StationTool.OnMouseDown implementation
if (Button == 1)
{
// 获取鼠标点击的Geometry(默认点选择)
IGeometry pGeometry = GetGeometryByTrack(SpatialType, m_hookHelper);
// 根据空间关系选择与pGeometry相交的要素
if (m_hookHelper.FocusMap.LayerCount == 0 || pGeometry == null)
return;
// 正常选择
if (FeatureLayer == null)
{
// 常规选择方法
ISelectionEnvironment pSelectionEnvironment = new SelectionEnvironmentClass();
if (Shift == 0)
{
pSelectionEnvironment.CombinationMethod = esriSelectionResultEnum.esriSelectionResultNew;
}
else
{
pSelectionEnvironment.CombinationMethod = esriSelectionResultEnum.esriSelectionResultXOR;
}
// 排除空选出错情况
if (!pGeometry.IsEmpty && pGeometry.Envelope.Width > 0 && pGeometry.Envelope.Height > 0)
m_hookHelper.FocusMap.SelectByShape(pGeometry, pSelectionEnvironment, false);
else
m_hookHelper.FocusMap.ClearSelection();
/* 自定义方法(按图层选择)
IEnumLayer layers= AeHelperLib.Utility.GetLayers(m_hookHelper);
ILayer pLayer;
while ((pLayer = layers.Next())!= null )
{
IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
if (pFeatureLayer.Selectable)
SelectFeaturesByLayer(pGeometry, pFeatureLayer, Shift);
}
*/
}
// 按图层选择
else if (FeatureLayer != null)
{
SelectFeaturesByLayer(pGeometry, FeatureLayer, Shift);
}
// 刷新地图
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, m_hookHelper.ActiveView.Extent);
if (ParentForm != null)
ParentForm.WindowState = FormWindowState.Normal;
}
}
public override void OnMouseMove(int Button, int Shift, int X, int Y)
{
}
public override void OnMouseUp(int Button, int Shift, int X, int Y)
{
// TODO: Add StationTool.OnMouseUp implementation
if (ParentForm != null)
ParentForm.WindowState = FormWindowState.Normal;
}
#endregion
#region 内部方法
/// <summary>
/// 按图层选择要素
/// </summary>
/// <param name="pGeometry">筛选几何图形</param>
/// <param name="pFeatureLayer">筛选图层</param>
/// <param name="shift">Shift键</param>
private static void SelectFeaturesByLayer(IGeometry pGeometry, IFeatureLayer pFeatureLayer, int shift)
{
// 空间分析
ISpatialFilter pSpatialFilter = new SpatialFilterClass();
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
pSpatialFilter.Geometry = pGeometry;
pSpatialFilter.GeometryField = pFeatureLayer.FeatureClass.ShapeFieldName;
// 添加选择要素
esriSelectionResultEnum pResultEnum;
if (shift == 0)
{
pResultEnum = esriSelectionResultEnum.esriSelectionResultNew;
}
else
{
pResultEnum = esriSelectionResultEnum.esriSelectionResultXOR;
}
((IFeatureSelection)pFeatureLayer).SelectFeatures(pSpatialFilter, pResultEnum, false);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pSpatialFilter);
}
#endregion
}
类中涉及到的方法如下:
/// <summary>
/// 绘制并获取地图几何图形。
/// </summary>
/// <param name="spatialType">空间类型</param>
/// <param name="pHookHelper">地图钩子</param>
/// <returns></returns>
public static IGeometry GetGeometryByTrack(AeHelperLib.AeEnums.SpatialTypeEnum spatialType, IHookHelper pHookHelper)
{
IGeometry pGeometry = null;
// 默认的空间图形为点(采用获取屏幕绘制方法,一般情况下不会报错)
IGeometry ordinaryGeometry = AeHelperLib.Utility.GetGeometryByScreenDrawing(AeHelperLib.AeEnums.SpatialTypeEnum.Point, pHookHelper);
ITopologicalOperator pTopoOperator = ordinaryGeometry as ITopologicalOperator;
// 设置容差为1(防止点不中图形)
IGeometry finalGeometry = pTopoOperator.Buffer(1);
// 获取地图控制
IMapControl4 pMapControl4 = pHookHelper.Hook as IMapControl4;
if (pMapControl4 != null)
{
if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Point)
pGeometry = finalGeometry;
else if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Line)
pGeometry = pMapControl4.TrackLine();
else if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Rect)
pGeometry = pMapControl4.TrackRectangle();
else if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Polygon)
pGeometry = pMapControl4.TrackPolygon();
else if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Circle)
pGeometry = pMapControl4.TrackCircle();
else
pGeometry = finalGeometry;
}
else // 获取不到地图控制的时候尝试直接获取地图控件
{
System.Windows.Forms.Control control = AeHelperLib.Utility.GetMapControl(pHookHelper);
if (control is AxMapControl)
{
AxMapControl mapControl = control as AxMapControl;
if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Point)
pGeometry = finalGeometry;
else if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Line)
pGeometry = mapControl.TrackLine();
else if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Rect)
pGeometry = mapControl.TrackRectangle();
else if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Polygon)
pGeometry = mapControl.TrackPolygon();
else if (spatialType == AeHelperLib.AeEnums.SpatialTypeEnum.Circle)
pGeometry = mapControl.TrackCircle();
else
pGeometry = finalGeometry;
}
}
if (pGeometry == null || pGeometry.IsEmpty || pGeometry.Envelope.Width <= 0 || pGeometry.Envelope.Height <= 0)
pGeometry = finalGeometry;
return pGeometry;
}
类中还定义了一个枚举如下
/// <summary>
/// 空间类型
/// </summary>
public enum SpatialTypeEnum
{
/// <summary>
/// 点
/// </summary>
Point,
/// <summary>
/// 线
/// </summary>
Line,
/// <summary>
/// 矩形
/// </summary>
Rect,
/// <summary>
/// 多边形
/// </summary>
Polygon,
/// <summary>
/// 圆形
/// </summary>
Circle,
}
上面的工具类中,我增加了一个ParentForm属性,这个属性主要是用来给其他界面做选择工具的,实现选择的时候自动最小化窗体,选择完之后恢复窗体,如果不需要此功能可以选择忽略。
转载自:https://blog.csdn.net/fywindmoon/article/details/25726027