【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

You may also like...