ArcEngine c#开发 距离面积量算 (零碎)

1,整段注释ctrl+k,ctrl+c   消除注释 ctrl+k,ctrl+u;
2,制作菜单
ArcEngine c开发 距离面积量算 (零碎) - nichunquan1990 - nichunquan1990的博客
 3,制作类
算量的相关类命名为surveytools.css
代码如下

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) { if (dy==0) { m_dDirection=90; } else if( dy > 0) { da = System.Math.Abs(dx/dy); m_dDirection = System.Math.Atan(da) * 180 / 3.14159265 ; } else if (dy < 0 ) { da = System.Math.Abs(dx/dy); m_dDirection = System.Math.Atan(da) * 180 / 3.14159265 ; m_dDirection = 180 -m_dDirection; } } else { if (dy==0) { m_dDirection=270; } else if (dy >= 0) { da = System.Math.Abs(dx/dy); m_dDirection = System.Math.Atan(da) * 180 / 3.14159265 ; m_dDirection = 360 - m_dDirection; } else { da = System.Math.Abs(dx/dy); m_dDirection = System.Math.Atan(da) * 180 / 3.14159265 ; 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()); } } } }

在主窗口函数中声明imap类一个公共变量 定义一个surveytools类 的对象     

  public IMap pMap; 

 SurveyTools  pTool;

在主窗口load函数中添加

 pMap = axMapControl1.Map;

pTool = new SurveyTools();

pTool.Map = axMapControl1.Map;

双击菜单上的测长度选项卡,进入响应代码编辑区

private void 测长度ToolStripMenuItem_Click(object sender, EventArgs e) { iMapAction = 1; toolStripStatusLabel1.Text = "测长度"; ITool obj = new ControlsMapPanToolClass(); axMapControl1.CurrentTool = obj; }

 在地图显示区mapcontrol中的onmousedown事件中添加代码

private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e) { object obj ; switch (iMapAction) { case 1: #region //测长度 if (e.button == 1) { if (!pTool.IsSurveying) pTool.LengthStart(axMapControl1.ToMapPoint(e.x, e.y)); else pTool.AddPoint(axMapControl1.ToMapPoint(e.x, e.y)); } else { if (pTool.IsSurveying) { obj = new SimpleLineSymbolClass(); axMapControl1.DrawShape(pTool.SurveyEnd(axMapControl1.ToMapPoint(e.x, e.y)), ref obj); toolStripStatusLabel1.Text = "测距离"; } } break; #endregion case 2: #region //测面积 if (e.button == 1) { if (!pTool.IsSurveying) pTool.AreaStart(axMapControl1.ToMapPoint(e.x, e.y)); else pTool.AddPoint(axMapControl1.ToMapPoint(e.x, e.y)); } else { if (pTool.IsSurveying) { obj = new SimpleFillSymbolClass(); axMapControl1.DrawShape(pTool.SurveyEnd(axMapControl1.ToMapPoint(e.x, e.y)), ref obj); toolStripStatusLabel1.Text = "测面积"; } } break; #endregion

}

}

onmousemove事件中添加代码

private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e) { toolStripStatusLabel2.Text = e.x.ToString(); toolStripStatusLabel3.Text = e.y.ToString(); switch (iMapAction) { case 1: #region //测长度 if (pTool.IsSurveying) { pTool.MoveTo(axMapControl1.ToMapPoint(e.x, e.y)); toolStripStatusLabel1.Text = "总长度:" + pTool.totalLength.ToString() + "; 当前线段长度:" + pTool.currentLength.ToString(); } break; #endregion case 2: #region //测面积 if (pTool.IsSurveying) { pTool.MoveTo(axMapControl1.ToMapPoint(e.x, e.y)); toolStripStatusLabel1.Text = "面积:" + pTool.Area.ToString(); } break; #endregion

}

}


清屏的代码为

axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);


  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值