C#AE面积测量

传入AxmapControl参数即可实现实时面积测量

代码如下:


using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AxESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;

namespace PartOfJRSpace
{
    public class MeasureArea
    {
        //地图面板
        AxMapControl myMapControl;
        //地图面板容器
        IGraphicsContainer g;
        //点集
        IPointCollection pAreaPointCol = new MultipointClass();
        //画线
        NewLineFeedbackClass m_NewLineFeedback;
        //线段起始点
        IPoint starPoint;
        //第一个点
        IPoint firstPoint;
        //面积显示标签
        IElement measureAreaText;
        //动态连接线
        IElement firstPointToLast,lastLine;
        //连接线标签
        IElement firstPointToLastText;
        //连接线标签
        IElement moveText;
        public MeasureArea(AxMapControl pMapControl)
        {
            myMapControl = pMapControl;
            myMapControl.OnMouseDown += new IMapControlEvents2_OnMouseDownEventHandler(myMapControl_OnMouseDown);
            myMapControl.OnDoubleClick += new IMapControlEvents2_OnDoubleClickEventHandler(myMapControl_OnDoubleClick);
            myMapControl.OnMouseMove += new IMapControlEvents2_OnMouseMoveEventHandler(myMapControl_OnMouseMove);
            g = myMapControl.Map as IGraphicsContainer;
        }

        private void myMapControl_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            if (m_NewLineFeedback == null)
            {
                return;
            }
            IPoint pt = new PointClass();
            pt.X = e.mapX;
            pt.Y = e.mapY;
            
            if (pAreaPointCol.PointCount==1)
            {
                m_NewLineFeedback.MoveTo(pt);
                return;
            }

            ILine laLine = new LineClass();
            laLine.PutCoords(starPoint, pt);
            #region//动态连接线starTolast
            try
            {
                object missing = Type.Missing;

                ISegmentCollection segColl = new PolylineClass();

                segColl.AddSegment(laLine as ISegment, ref missing, ref missing);
                if (lastLine != null)
                {
                    g.DeleteElement(lastLine);
                    myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, lastLine, null);
                }

                lastLine = CreateElement(segColl as IPolyline);

                g.AddElement(lastLine, 0);

                myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, lastLine, null);

            }
            catch
            {
                throw;
            }
            #endregion

            //连接起点和终点
            ILine firstToLastLine = new LineClass();
            firstToLastLine.PutCoords(firstPoint, pt);

            #region 动态连接线
            try
            {
                object missing = Type.Missing;

                ISegmentCollection segColl = new PolylineClass();

                segColl.AddSegment(firstToLastLine as ISegment, ref missing, ref missing);

                //删除上一个连接线
                if (firstPointToLast != null)
                {
                    g.DeleteElement(firstPointToLast);
                    //myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, firstPointToLast, null);
                }

                firstPointToLast = CreateElement(segColl as IPolyline);

                g.AddElement(firstPointToLast, 0);

                myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, firstPointToLast, null);

            }
            catch
            {
                throw;
            }
            #endregion

            #region 动态连接线长度
            try
            {
                double angle = firstToLastLine.Angle;
                if ((angle > (Math.PI / 2) && angle < (Math.PI)) || (angle > -Math.PI && angle < -(Math.PI / 2))) // 大于90度小于等于180
                    angle += Math.PI;

                //标注点Y值偏移量
                double d_OffsetY = myMapControl.ActiveView.ScreenDisplay.DisplayTransformation.FromPoints(9);

                //标注点
                double d_CenterX = (firstPoint.X + pt.X) / 2;
                double d_CenterY = (firstPoint.Y + pt.Y) / 2 + d_OffsetY; //向上偏移

                IPoint labelPt = new PointClass();
                labelPt.PutCoords(d_CenterX, d_CenterY);
                //删除上一个长度标签
                if (firstPointToLastText != null)
                {
                    g.DeleteElement(firstPointToLastText);
                    //刷新
                    myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, firstPointToLastText, null);
                }
                ITextElement txtElement = CreateTextElement(firstToLastLine.Length.ToString("0.00") + GetMapLenUnit(myMapControl.Map.MapUnits));
                firstPointToLastText = txtElement as IElement;
                firstPointToLastText.Geometry = labelPt;
                object oElement = (object)firstPointToLastText;
                //根据角度旋转
                TransformByRotate(ref oElement, labelPt, angle);
                ////添加到GraphicsContainer
                g.AddElement(firstPointToLastText, 0);
                //刷新
                myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, firstPointToLastText, null);

            }
            catch
            {
                throw;
            }
            #endregion

            #region 计算单线的长度,并将结果显示在单线中点偏上上面
            try
            {
                ILine line = new LineClass();
                line.PutCoords(starPoint, pt);
                //删除上一个连接线
                if (moveText != null)
                {
                    g.DeleteElement(moveText);
                    //刷新
                    myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, moveText, null);
                }
                double angle = line.Angle;
                if ((angle > (Math.PI / 2) && angle < (Math.PI)) || (angle > -Math.PI && angle < -(Math.PI / 2))) // 大于90度小于等于180
                    angle += Math.PI;

                //标注点Y值偏移量
                double d_OffsetY = myMapControl.ActiveView.ScreenDisplay.DisplayTransformation.FromPoints(9);

                //标注点
                double d_CenterX = (starPoint.X + pt.X) / 2;
                double d_CenterY = (starPoint.Y + pt.Y) / 2 + d_OffsetY; //向上偏移

                IPoint labelPt = new PointClass();
                labelPt.PutCoords(d_CenterX, d_CenterY);

                ITextElement txtElement = CreateTextElement(line.Length.ToString("0.00") + GetMapLenUnit(myMapControl.Map.MapUnits));

                moveText = txtElement as IElement;
                moveText.Geometry = labelPt;
                object oElement = (object)moveText;

                //根据角度旋转
                TransformByRotate(ref oElement, labelPt, angle);
                ////添加到GraphicsContainer
                g.AddElement(moveText, 0);
                //刷新
                myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, moveText, null);

            }
            catch
            {
                throw;
            }
            #endregion

        }
        private void myMapControl_OnDoubleClick(object sender, IMapControlEvents2_OnDoubleClickEvent e)
        {
            m_NewLineFeedback.Stop();
            m_NewLineFeedback = null;
            pAreaPointCol.RemovePoints(0, pAreaPointCol.PointCount);
            //删除g中的所有要素
            g.DeleteAllElements();
            starPoint=null;
            firstPoint=null;
            lastLine = null;
            measureAreaText = null;
            firstPointToLast = null;
            firstPointToLastText = null;
            //刷新
            myMapControl.ActiveView.Refresh();
        }
        private void myMapControl_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            if (e.button == 1)
            {
                
                IPoint pt = new PointClass();
                pt.X = e.mapX;
                pt.Y = e.mapY;
                pAreaPointCol.AddPoint(pt);

                #region 绘制结点
                try
                {
                    pt.X = e.mapX;
                    pt.Y = e.mapY;
                    IElement pointElement = CreateElement(pt);
                    //
                    g.AddElement(pointElement, 0);

                    myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pointElement, null);
                }
                catch
                {
                    throw;
                }
                #endregion

                //画线
                if (m_NewLineFeedback == null)
                {
                    m_NewLineFeedback = new NewLineFeedbackClass();
                    ISimpleLineSymbol pLine = m_NewLineFeedback.Symbol as ISimpleLineSymbol;
                    RgbColorClass pColor = new RgbColorClass();
                    pColor.Red = 255;
                    pColor.Green = 0;
                    pColor.Blue = 0;
                    pLine.Color = pColor;
                    m_NewLineFeedback.Display = myMapControl.ActiveView.ScreenDisplay;
                    m_NewLineFeedback.Start(pt);
                    firstPoint = pt;
                }
                else
                {
                    m_NewLineFeedback.AddPoint(pt);
                }
                if (starPoint == null)
                {

                }
                else
                {
                    ILine line = new LineClass();
                    line.PutCoords(starPoint, pt);
                    if (lastLine != null)
                    {
                        g.DeleteElement(lastLine);
                        myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, lastLine, null);
                        lastLine = null;
                    }
                    #region 绘制轨迹线
                    try
                    {
                        object missing = Type.Missing;

                        ISegmentCollection segColl = new PolylineClass();

                        segColl.AddSegment(line as ISegment, ref missing, ref missing);

                        IElement traceElement = CreateElement(segColl as IPolyline);

                        g.AddElement(traceElement, 0);

                        myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, traceElement, null);

                    }
                    catch
                    {
                        throw;
                    }
                    #endregion

                    #region 计算单线的长度,并将结果显示在单线中点偏上上面
                    try
                    {
                        double angle = line.Angle;
                        if ((angle > (Math.PI / 2) && angle < (Math.PI)) || (angle > -Math.PI && angle < -(Math.PI / 2))) // 大于90度小于等于180
                            angle += Math.PI;

                        //标注点Y值偏移量
                        double d_OffsetY = myMapControl.ActiveView.ScreenDisplay.DisplayTransformation.FromPoints(9);

                        //标注点
                        double d_CenterX = (starPoint.X + pt.X) / 2;
                        double d_CenterY = (starPoint.Y + pt.Y) / 2 + d_OffsetY; //向上偏移

                        IPoint labelPt = new PointClass();
                        labelPt.PutCoords(d_CenterX, d_CenterY);

                        ITextElement txtElement = CreateTextElement(line.Length.ToString("0.00") + GetMapLenUnit(myMapControl.Map.MapUnits));

                        IElement labelelement = txtElement as IElement;
                        labelelement.Geometry = labelPt;
                        object oElement = (object)labelelement;

                        //根据角度旋转
                        TransformByRotate(ref oElement, labelPt, angle);
                        ////添加到GraphicsContainer
                        g.AddElement(labelelement, 0);
                        //刷新
                        myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, labelelement, null);

                    }
                    catch
                    {
                        throw;
                    }
                    #endregion

                    if (pAreaPointCol.PointCount >= 3)
                    {
                        //连接起点和终点
                        ILine firstToLastLine = new LineClass();
                        firstToLastLine.PutCoords(firstPoint,pt);

                        #region 动态连接线
                        try
                        {
                            object missing = Type.Missing;

                            ISegmentCollection segColl = new PolylineClass();

                            segColl.AddSegment(firstToLastLine as ISegment, ref missing, ref missing);
                            //删除上一个连接线
                            if (firstPointToLast != null)
                            {
                                g.DeleteElement(firstPointToLast);
                                myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, firstPointToLast, null);
                            }

                            firstPointToLast = CreateElement(segColl as IPolyline);

                            g.AddElement(firstPointToLast, 0);

                            myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, firstPointToLast, null);

                        }
                        catch
                        {
                            throw;
                        }
                        #endregion

                        #region 动态连接线长度
                        try
                        {
                            double angle = firstToLastLine.Angle;
                            if ((angle > (Math.PI / 2) && angle < (Math.PI)) || (angle > -Math.PI && angle < -(Math.PI / 2))) // 大于90度小于等于180
                                angle += Math.PI;

                            //标注点Y值偏移量
                            double d_OffsetY = myMapControl.ActiveView.ScreenDisplay.DisplayTransformation.FromPoints(9);

                            //标注点
                            double d_CenterX = (firstPoint.X + pt.X) / 2;
                            double d_CenterY = (firstPoint.Y + pt.Y) / 2 + d_OffsetY; //向上偏移

                            IPoint labelPt = new PointClass();
                            labelPt.PutCoords(d_CenterX, d_CenterY);
                            if (firstPointToLastText!=null)
                            {
                                g.DeleteElement(firstPointToLastText);
                                //刷新
                                myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, firstPointToLastText, null);
                            }
                            ITextElement txtElement = CreateTextElement(firstToLastLine.Length.ToString("0.00") + GetMapLenUnit(myMapControl.Map.MapUnits));
                            firstPointToLastText = txtElement as IElement;
                            firstPointToLastText.Geometry = labelPt;
                            object oElement = (object)firstPointToLastText;
                            //根据角度旋转
                            TransformByRotate(ref oElement, labelPt, angle);
                            ////添加到GraphicsContainer
                            g.AddElement(firstPointToLastText, 0);
                            //刷新
                            myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, firstPointToLastText, null);

                        }
                        catch
                        {
                            throw;
                        }
                        #endregion


                        IPointCollection pPointCol = new Polygon();
                        IPolygon pPolygon = new PolygonClass();
                        for (int i = 0; i < pAreaPointCol.PointCount; i++)
                        {
                            pPointCol.AddPoint(pAreaPointCol.Point[i]);
                        }
                        pPolygon = pPointCol as IPolygon;
                        if (pPolygon != null)
                        {
                            //使封闭
                            pPolygon.Close();
                            IArea pArea = pPolygon as IArea;
                            //几何中心点
                            IPoint iPnt = pArea.Centroid;
                            ITextElement txtElement = CreateTextElement(Math.Abs(pArea.Area).ToString("0.00") + GetMapAreaUnit(myMapControl.Map.MapUnits));

                            if (measureAreaText != null)
                            {
                                g.DeleteElement(measureAreaText);
                                myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, measureAreaText, null);
                            }

                            //文字注记
                            measureAreaText = txtElement as IElement;
                            measureAreaText.Geometry = iPnt;
                            g.AddElement(measureAreaText, 0);
                            myMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, measureAreaText, null);
                        }
                    }

                }
                starPoint = pt;
            }
        }

        /// <summary>
        /// 按指定的角度旋转
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="originPt"></param>
        /// <param name="rotate"></param>
        private void TransformByRotate(ref object obj, IPoint originPt, double rotate)
        {
            if (obj == null && originPt == null)
                return;
            try
            {
                ITransform2D transform2D = obj as ITransform2D;
                if (transform2D == null)
                    return;
                transform2D.Rotate(originPt, rotate);

            }
            catch
            {
                throw;
            }
        }


        /// <summary>
        /// 绘制几何图形
        /// </summary>
        /// <param name="geoType"></param>
        /// <param name="geometry"></param>
        /// <returns></returns>
        private ESRI.ArcGIS.Carto.IElement CreateElement(ESRI.ArcGIS.Geometry.IGeometry geometry)
        {
            IElement element = null;
            try
            {
                switch (geometry.GeometryType)
                {
                    case esriGeometryType.esriGeometryPolygon://设置Polygon面
                        IRgbColor polygonRGB = new RgbColorClass();
                        polygonRGB.Blue = 255;
                        polygonRGB.Red = 179;
                        polygonRGB.Green = 196;
                        polygonRGB.Transparency = (byte)0;

                        IFillSymbol polygonFill = new SimpleFillSymbolClass();
                        polygonFill.Color = polygonRGB;

                        IFillShapeElement fillShapeElement = new PolygonElementClass();
                        fillShapeElement.Symbol = polygonFill;
                        element = fillShapeElement as IElement;


                        element.Geometry = geometry;


                        break;
                    case esriGeometryType.esriGeometryPolyline://Polyline线
                        ISimpleLineSymbol simpleLineSymbol = m_NewLineFeedback.Symbol as ISimpleLineSymbol;

                        ILineElement lineElement = new LineElementClass();
                        lineElement.Symbol = simpleLineSymbol as ILineSymbol;
                        element = lineElement as IElement;
                        element.Geometry = geometry;
                        break;
                    case esriGeometryType.esriGeometryPoint://设置结点符号
                        IRgbColor pRGB = new RgbColorClass();
                        pRGB.Red = 255;
                        pRGB.Green = 0;
                        pRGB.Blue = 0;
                        ISimpleMarkerSymbol pSimpleMarkSymbol = new SimpleMarkerSymbolClass();
                        pSimpleMarkSymbol.Color = pRGB as IColor;
                        pSimpleMarkSymbol.Size = 2;
                        pSimpleMarkSymbol.Style = esriSimpleMarkerStyle.esriSMSSquare;

                        IMarkerElement pMarkerElement = new MarkerElementClass();
                        pMarkerElement.Symbol = pSimpleMarkSymbol as IMarkerSymbol;
                        element = pMarkerElement as IElement;
                        element.Geometry = geometry as IGeometry;
                        break;
                }
            }
            catch
            {
                throw;
            }
            return element;
        }

        /// <summary>
        /// 创建一个TextElement
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private ITextElement CreateTextElement(string text)
        {
            //创建一个TextSymbol
            ITextSymbol txtSymbol = new TextSymbolClass();

            //设置字体
            Font dispFont = new Font("Arial", 10, FontStyle.Regular);
            txtSymbol.Font = (stdole.IFontDisp)ESRI.ArcGIS.ADF.COMSupport.OLE.GetIFontDispFromFont(dispFont);

            //设置属性
            txtSymbol.Color = TransColorToAEColor(Color.Red); //颜色

            //创建一个TextElement
            ITextElement txtElement = new TextElementClass();
            txtElement.Symbol = txtSymbol;
            txtElement.Text = text;

            return txtElement;
        }


        /// <summary>
        /// 获取当前地图的面积单位
        /// </summary>
        /// <param name="pEsriUnits"></param>
        /// <returns></returns>
        private string GetMapAreaUnit(esriUnits pEsriUnits)
        {
            string sMapUnits = string.Empty;
            switch (pEsriUnits)
            {
                case esriUnits.esriCentimeters:
                    sMapUnits = "平方厘米";
                    break;
                case esriUnits.esriDecimalDegrees:
                    sMapUnits = "十进制度";
                    break;
                case esriUnits.esriDecimeters:
                    sMapUnits = "分米";
                    break;
                case esriUnits.esriFeet:
                    sMapUnits = "尺";
                    break;
                case esriUnits.esriInches:
                    sMapUnits = "英寸";
                    break;
                case esriUnits.esriKilometers:
                    sMapUnits = "平方千米";
                    break;
                case esriUnits.esriMeters:
                    sMapUnits = "平方米";
                    break;
                case esriUnits.esriMiles:
                    sMapUnits = "英里";
                    break;
                case esriUnits.esriMillimeters:
                    sMapUnits = "毫米";
                    break;
                case esriUnits.esriNauticalMiles:
                    sMapUnits = "海里";
                    break;
                case esriUnits.esriPoints:
                    sMapUnits = "点";
                    break;
                case esriUnits.esriUnitsLast:
                    sMapUnits = "UnitsLast";
                    break;
                case esriUnits.esriUnknownUnits:
                    sMapUnits = "";
                    break;
                case esriUnits.esriYards:
                    sMapUnits = "码";
                    break;
                default:
                    break;
            }

            return sMapUnits;
        }

        /// <summary>
        /// 获取当前地图的长度单位
        /// </summary>
        /// <param name="pEsriUnits"></param>
        /// <returns></returns>
        private string GetMapLenUnit(esriUnits pEsriUnits)
        {
            string sMapUnits = string.Empty;
            switch (pEsriUnits)
            {
                case esriUnits.esriCentimeters:
                    sMapUnits = "厘米";
                    break;
                case esriUnits.esriDecimalDegrees:
                    sMapUnits = "十进制度";
                    break;
                case esriUnits.esriDecimeters:
                    sMapUnits = "分米";
                    break;
                case esriUnits.esriFeet:
                    sMapUnits = "尺";
                    break;
                case esriUnits.esriInches:
                    sMapUnits = "英寸";
                    break;
                case esriUnits.esriKilometers:
                    sMapUnits = "千米";
                    break;
                case esriUnits.esriMeters:
                    sMapUnits = "米";
                    break;
                case esriUnits.esriMiles:
                    sMapUnits = "英里";
                    break;
                case esriUnits.esriMillimeters:
                    sMapUnits = "毫米";
                    break;
                case esriUnits.esriNauticalMiles:
                    sMapUnits = "海里";
                    break;
                case esriUnits.esriPoints:
                    sMapUnits = "点";
                    break;
                case esriUnits.esriUnitsLast:
                    sMapUnits = "UnitsLast";
                    break;
                case esriUnits.esriUnknownUnits:
                    sMapUnits = "";
                    break;
                case esriUnits.esriYards:
                    sMapUnits = "码";
                    break;
                default:
                    break;
            }

            return sMapUnits;
        }


        /// <summary>
        /// 将系统颜色转换为IColor
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        ESRI.ArcGIS.Display.IColor TransColorToAEColor(Color color)
        {
            IRgbColor rgb = new RgbColorClass();
            rgb.RGB = color.R + color.G * 256 + color.B * 65536;
            return rgb as IColor;
        }


        /// <summary>
        /// 关闭测量工具,并清除所绘制的内容
        /// </summary>
        public void Close()
        {
            m_NewLineFeedback = null;
            pAreaPointCol.RemovePoints(0, pAreaPointCol.PointCount);
            //删除g中的所有要素
            g.DeleteAllElements();
            starPoint = null;
            firstPoint = null;
            lastLine = null;
            measureAreaText = null;
            firstPointToLast = null;
            firstPointToLastText = null;
            //刷新
            myMapControl.ActiveView.Refresh();
            //去除地图绑定的事件
            myMapControl.OnMouseDown -= new IMapControlEvents2_OnMouseDownEventHandler(myMapControl_OnMouseDown);
            //去除鼠标双击事件
            myMapControl.OnDoubleClick -= new IMapControlEvents2_OnDoubleClickEventHandler(myMapControl_OnDoubleClick);
            //去除鼠标移动事件
            myMapControl.OnMouseMove -= new IMapControlEvents2_OnMouseMoveEventHandler(myMapControl_OnMouseMove);
        }


    }
}
 

猜你喜欢

转载自blog.csdn.net/qq_38370387/article/details/89144320