⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surveytools.cs.bak

📁 很好的带有编辑功能、量算功能。可在地图上进行距离、面积、角度测量
💻 BAK
字号:
using System;
using System.IO ;
using System.Windows.Forms ;
using System.Reflection ;  

using ESRI.ArcGIS.Carto ; 
using ESRI.ArcGIS.Display ;
using ESRI.ArcGIS.Geometry ;  


namespace AoTest
{
	/// <summary>
	/// 使用本对象可在地图上进行距离、面积、角度测量
	/// 可取得当前线段长度、线段总长度、多边形面积、当前线段方位角、当前线段与前一线段夹角
	/// 使用时需设置Map变量
	/// </summary>
	public class SurveyTools
	{
		private IMap m_pMap;								//地图对象
		private IPointCollection m_pPnts;					//点集合
		private INewPolygonFeedback m_pPolygonFeedback;		//新建多边形对象
		private INewLineFeedback m_pLineFeedback;			//新建线对象
		private int m_iSurveyType;							//0-空操作;1-测距离; 2-测面积; 3-测角度
		
		private bool m_bBusy ;						//是否正在测量
		private double m_dTotalLength =0 ;			//线总长度
		private double m_dCurrentLength =0 ;		//当前线段长度
		private double m_dArea = 0 ;				//多边形面积
		private double m_dAngle = 0;				//当前线段与前一线段的夹角
		private double m_dDirection = 0;			//与正北方向的夹角,即方位角

		/// <summary>
		/// Map对象,只写
		/// </summary>
		public IMap Map  
		{
			set 
			{
				m_pMap = value;
			}
		}
		
		/// <summary>
		/// 判断是否正在测量,只读
		/// </summary>
		public bool IsSurveying
		{
			get
			{
				return m_bBusy;
			}
		}

		/// <summary>
		/// 折线总长度,只读 
		/// </summary>
		public double totalLength 
		{
			get
			{
				return m_dTotalLength ;
			}
		}

		/// <summary>
		/// 当前线段长度,只读
		/// </summary>
		public double currentLength
		{
			get
			{
				return m_dCurrentLength ;
			}
		}

		/// <summary>
		/// 多边形面积,只读
		/// </summary>
		public double Area 
		{
			get
			{
				return m_dArea ;
			}
		}

		/// <summary>
		/// 当前线段与前一线段的夹角,只读
		/// </summary>
		public double Angle
		{
			get
			{
				return m_dAngle;
			}
		}		
		
		/// <summary>
		/// 当前线段的方向角,只读
		/// </summary>
		public double Direction
		{
			get
			{
				return m_dDirection;
			}
		}
		
		/// <summary>
		/// 构造函数
		/// </summary>
		public SurveyTools()
		{
			m_pMap = null;
			m_pPnts = null;
			m_pPolygonFeedback = null ;
			m_pLineFeedback = null;
			m_iSurveyType = 0;
			m_bBusy = false ;
		}
		
		/// <summary>
		/// 启动距离测量,pPnt为测量起点,测量结果为
		/// totalLength:线总长度
		/// currentLength:当前线段长度
		/// 在Map的MouseDown事件中调用本方法
		/// </summary>
		/// <param name="pPnt">测量起点</param>
		public void LengthStart(IPoint pPnt)
		{
			m_iSurveyType = 1;

			m_pLineFeedback = new NewLineFeedbackClass();
			m_pLineFeedback.Display =((IActiveView) m_pMap).ScreenDisplay; 
			m_pLineFeedback.Start(pPnt); 			
			m_bBusy = true;

			m_pPnts= new PolylineClass() ;
			object ep = System.Reflection.Missing.Value; 
			m_pPnts.AddPoint(pPnt,ref ep, ref ep) ;			
		}
		
		/// <summary>
		/// 启动面积测量,pPnt为多边形起点,测量结果为
		/// Area:多边形面积
		/// 在Map的MouseDown事件中调用本方法
		/// </summary>
		/// <param name="pPnt">测量起点</param>
		public void AreaStart(IPoint pPnt)
		{
			m_iSurveyType = 2;
			m_pPolygonFeedback = new NewPolygonFeedbackClass();
			m_pPolygonFeedback.Display =((IActiveView) m_pMap).ScreenDisplay; 
			m_pPolygonFeedback.Start(pPnt); 
			m_bBusy = true ;

			m_pPnts= new PolygonClass() ;
			object ep = System.Reflection.Missing.Value; 
			m_pPnts.AddPoint(pPnt,ref ep, ref ep) ;			
		}

		/// <summary>
		/// 开始测角度,pPnt为折线起点,测量结果为
		/// Direction:当前线段的方向角,即与正北方向的夹角
		/// Angle:当前线段与前一线段的夹角
		/// 在Map的MouseDown事件中调用本方法
		/// </summary>
		/// <param name="pPnt">折线起点</param>
		public void AngleStart(IPoint pPnt)
		{
			m_iSurveyType = 3;

			m_pLineFeedback = new NewLineFeedbackClass();
			m_pLineFeedback.Display =((IActiveView) m_pMap).ScreenDisplay; 
			m_pLineFeedback.Start(pPnt); 
			m_bBusy = true ;

			m_pPnts= new PolylineClass() ;
			object ep = System.Reflection.Missing.Value; 
			m_pPnts.AddPoint(pPnt,ref ep, ref ep) ;		
		}

		/// <summary>
		/// 向折线或多边形上添加节点
		/// 在Map的MouseDown事件中调用本方法,将当前光标位置作为节点
		/// 添加到折线或多边形上
		/// </summary>
		/// <param name="pPnt">拐点</param>
		public void AddPoint(IPoint pPnt)
		{
			if (m_iSurveyType == 1 || m_iSurveyType == 3)
			{
				m_pLineFeedback.AddPoint(pPnt);				
			}
			else if (m_iSurveyType == 2)
			{
				m_pPolygonFeedback.AddPoint(pPnt);
			}
					
			object ep = System.Reflection.Missing.Value; 
			m_pPnts.AddPoint(pPnt,ref ep, ref ep) ;	
		}

		/// <summary>
		/// 移动鼠标位置,动态改变折线或多边形最后节点的位置,
		/// 重新计算各个测量值,建议在Map的MouseMove事件中调用,
		/// 并提取当前的测量结果进行显示
		/// </summary>
		/// <param name="pPnt">终点</param>
		public void MoveTo(IPoint pPnt)
		{
			if (m_iSurveyType == 1 || m_iSurveyType == 3)
			{
				m_pLineFeedback.MoveTo(pPnt) ;
				CalculateLength(pPnt);
				CalculateDirection(pPnt);
				CalculateAngle(pPnt);
			}
			else if (m_iSurveyType == 2)
			{
				m_pPolygonFeedback.MoveTo(pPnt);
				CalculateArea( pPnt);
			}
		}

		/// <summary>
		/// 结束当前的测量,返回进行量算时在地图上绘的图形对象
		/// 建议在Map的DoubleClick事件或MouseDown(右键)事件中调用本方法
		/// 将返回对象用map.DrawShape方法绘在地图临时层上
		/// </summary>
		/// <param name="pPnt">终点</param>
		/// <returns>地图上绘的图形对象</returns>
		public IGeometry SurveyEnd(IPoint pPnt)
		{
			IGeometry pGeometry =null;

			if (m_iSurveyType == 1 || m_iSurveyType == 3)
			{
				m_pLineFeedback.AddPoint(pPnt) ;
				pGeometry = (IGeometry) m_pLineFeedback.Stop(); 
				m_pLineFeedback = null;				
			}
			else if (m_iSurveyType == 2)
			{
				m_pPolygonFeedback.AddPoint(pPnt);
				pGeometry = (IGeometry) m_pPolygonFeedback.Stop(); 
				m_pPolygonFeedback = null;
			}

			m_pPnts = null;
			m_bBusy = false;
			if (pGeometry != null)
				return pGeometry;			
			else
				return null;
		}

		/// <summary>
		/// 计算测量线段长度,结果分别存贮在:
		/// totalLength:线总长度
		/// currentLength:当前线段长度
		/// </summary>
		/// <param name="pPnt">计算时的终点</param>
		private void CalculateLength(IPoint pPnt)
		{
			try
			{
				IPointCollection pPs = new PolylineClass() ;
				double dL = 0;

				pPs.AddPointCollection(m_pPnts);

				IPolyline pLine ;
				if (pPs.PointCount > 1 )
				{
					pLine = (IPolyline) pPs;
					dL = pLine.Length ;
				}

				object ep = System.Reflection.Missing.Value; 
				pPs.AddPoint(pPnt,ref ep, ref ep) ;

				pLine = (IPolyline) pPs;
				m_dTotalLength = pLine.Length ;
				m_dCurrentLength = m_dTotalLength - dL;
			}
			catch(System.Exception e)
			{
				Console.WriteLine(e.Message.ToString());
			}
		}
		
		/// <summary>
		/// 计算多边形面积,结果存贮在Area中
		/// </summary>
		/// <param name="pPnt">计算时的终点</param>
		private void CalculateArea(IPoint pPnt)
		{
			try
			{
				IPointCollection pPs = new PolygonClass() ;

				pPs.AddPointCollection(m_pPnts);
				object ep = System.Reflection.Missing.Value; 
				pPs.AddPoint(pPnt,ref ep, ref ep) ;

				if (pPs.PointCount > 2 )
				{
					IPolygon pPolygon =(IPolygon) pPs;
					IArea pArea = (IArea) pPolygon;
					m_dArea = pArea.Area; 
					m_dArea = System.Math.Abs(m_dArea);  
				}
			}
			catch(System.Exception e)
			{
				Console.WriteLine(e.Message.ToString());
			}
		}
		
		/// <summary>
		/// 计算当前线段的方向角,结果存贮为Direction中
		/// 正北方向为0度,顺时针为正,值域为0--360度
		/// </summary>
		/// <param name="pPnt">计算时的终点</param>
		private void CalculateDirection(IPoint pPnt)
		{
			double dx, dy, da;
			IPoint p1, p2;

			p1 = m_pPnts.get_Point(m_pPnts.PointCount - 1 );
			p2 = pPnt ;

			dx = p2.X - p1.X ;
			dy = p2.Y - p1.Y ;
			
			if (dx == 0)
			{
				if (dy >0 )
				{
					m_dDirection =0;
				}
				else
				{
					m_dDirection = 180;
				}
			}
			else if (dx > 0)
			{	
				da = System.Math.Abs(dx/dy);  
				m_dDirection = System.Math.Atan(da) * 180 / 3.14159265 ; 
				if (dy < 0 )				
				{
					m_dDirection = 180 -m_dDirection;
				}				
			} 
			else
			{
				da = System.Math.Abs(dx/dy);  
				m_dDirection = System.Math.Atan(da) * 180 / 3.14159265 ; 
				if (dy >= 0 )
				{
					m_dDirection = 360 - m_dDirection;
				}
				else
				{
					m_dDirection = 180 + m_dDirection;
				}		
			}
		}

		/// <summary>
		/// 计算当前线段与前一线段的夹角,结果存贮为Angle中
		/// 算法采用余弦定理,结果值域为0--180度. 
		/// </summary>
		/// <param name="pPnt">计算时的终点</param>
		private void CalculateAngle(IPoint pPnt)
		{
			int iCount = m_pPnts.PointCount ;
			if (iCount < 2) return ;

			double a, aa, b, bb, cc;
			IPoint Pnt1, Pnt2, Pnt3;
			try
			{
				Pnt1 = pPnt; Pnt2 = m_pPnts.get_Point(iCount -1); Pnt3 = m_pPnts.get_Point(iCount -2);
  
				aa = (Pnt1.X -Pnt2.X ) * (Pnt1.X -Pnt2.X ) + (Pnt1.Y  -Pnt2.Y ) * (Pnt1.Y -Pnt2.Y );
				a = Math.Sqrt(aa); 

				bb = (Pnt3.X -Pnt2.X ) * (Pnt3.X -Pnt2.X ) + (Pnt3.Y  -Pnt2.Y ) * (Pnt3.Y -Pnt2.Y );
				b = Math.Sqrt(bb); 

				cc = (Pnt1.X -Pnt3.X ) * (Pnt1.X -Pnt3.X ) + (Pnt1.Y  -Pnt3.Y ) * (Pnt1.Y -Pnt3.Y );

				m_dAngle = Math.Acos((aa+bb-cc)/2/a/b) * 180 /3.14159265;	
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message.ToString());
			}
		}        	
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -