AE跨屏幕测量距离和测量面积的实现

时间:2014-4-16    作者:悬浮的青春    分类: gis二次开发


arcgis自带的测量工具进行重写后可以进行自定义的测距和测量面积。

但客户常常会提出这样的需求。其实提出这样的需求也一般是因为操作不当或者使用不熟练。导致本来能在一个屏幕就完成的结果

需要跨屏幕测量。本来想着很简单。结果刷新有问题。拖动地图后。原本的feedback留下了好多影子。后来尝试了很多办法。终于解决。

color:#333333;font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:26px;white-space:normal;background-color:#FFFFFF;">具体是在OnAfterScreenDraw事件中使用Refresh函数刷新INewLineFeedback,完美解决问题。


下面。。额。不赘述了。。直接贴代码吧。

重写的测量工具代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Controls;
using System.Windows.Forms;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using System.Drawing;
namespace ComDll

    /// <summary>
    /// Summary description for celiangTool.
    /// </summary>
    [Guid("345696e0-3e2e-43b8-9a41-a51eeb3e798a")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("ComprehensiveLandManage.DrawPolygonTool")]
    public sealed class DrawPolygonTool : BaseTool
    {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);
            //
            // TODO: Add any COM registration code here
            //
        }

        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);

            //
            // TODO: Add any COM unregistration code here
            //
        }

        #region ArcGIS Component Category Registrar generated code
        /// <summary>
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            ControlsCommands.Register(regKey);

        }
        /// <summary>
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            ControlsCommands.Unregister(regKey);

        }

        #endregion
        #endregion

        private IHookHelper m_hookHelper;
        private INewLineFeedback lineFeedback;
        private INewPolypolyFeedback polyFeedback;
        private string state = "";

        private int step = 0;//
        private IPoint fPt;//
        private IPoint lastPt;//
        private IPoint activePt;//


        private static DistanceForm disForm;
        private static AreaFormcs areaForm;
        private IMapControl3 mapControl;
        private List<IPoint> lineList = new List<IPoint>();
        private List<IPoint> gonList = new List<IPoint>();

        private bool m_pan=false;

        /// <summary>
        /// 
        /// </summary>
        private Form mainForm;
        public Form MainForm
        {
            get { return mainForm; }
            set { mainForm = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        private string m_prjPath;
        public string m_PrjPath
        {
            get { return m_prjPath; }
            set { m_prjPath = value; }
        }

        public DrawPolygonTool(string temp)
        {
            //
            // TODO: Define values for the public properties
            //
            base.m_category = ""; //localizable text 
            base.m_caption = "";  //localizable text 
            base.m_message = "";  //localizable text
            base.m_toolTip = "";  //localizable text
            base.m_name = "";   //unique id, non-localizable (e.g. "MyCategory_MyTool")
            try
            {
                //
                // TODO: change resource name if necessary
                //
                //base.m_bitmap = new Bitmap(GetType().Assembly.GetManifestResourceStream("ComDll.Resources.celiangTool.bmp"));
                //base.m_cursor = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream("ComDll.Resources.celiangTool.cur"));

                this.state = temp;
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// 

        /// </summary>
        /// <param name="pt"></param>
        private void mouseDown(IPoint pt)
        {
            #region 
            if (step == 0)
            {
                fPt = pt;
                lastPt = pt;
                switch (state)
                {
                    case "距离":
                        (mapControl.Map as IGraphicsContainer).DeleteAllElements();
                        lineFeedback.Display = this.m_hookHelper.ActiveView.ScreenDisplay;
                        lineFeedback.Start(pt);
                        step = 1;
                        if (lineList.Count == 0)
                        {
                            lineList.Add(pt);
                        }
                        break;
                    case "面积":
                        (mapControl.Map as IGraphicsContainer).DeleteAllElements();
                        polyFeedback.Display = this.m_hookHelper.ActiveView.ScreenDisplay;
                        polyFeedback.Start(pt);
                        step = 1;
                        if (gonList.Count == 0)
                        {
                            gonList.Add(pt);
                        }
                        break;
                }
            }
            #endregion

            #region 
            else if (step == 1)
            {
                lastPt = pt;
                switch (state)
                {
                    case "距离":
                        lineFeedback.AddPoint(pt);
                        lineList.Add(pt);
                        break;
                    case "面积":
                        polyFeedback.AddPoint(pt);
                        gonList.Add(pt);
                        break;
                }
            }
            #endregion
        }

        /// <summary>
        /// 
        /// </summary>
        private void endTool()
        {
            try
            {
                if (step == 1)
                {
                    step = 0;
                    IPolyline line = null;
                    IPolygon polygon = null;
                    switch (state)
                    {
                        case "距离":
                            line = lineFeedback.Stop();
                            lineList.Clear();
                            disForm.showDistance(line.Length.ToString("#######0.##"));
                            MyDrawPolyline(line, mapControl);
                            break;
                        case "面积":
                            polygon = polyFeedback.Stop();
                            gonList.Clear();
                            IArea area = polygon as IArea;
                            areaForm.showArea(System.Math.Abs(area.Area * 0.0015).ToString("#######0.##"));
                            MyDrawPolygon(polygon, mapControl);
                            //IGeometry pGeometry = polygon as IGeometry;
                            //frmExportCoordinate frm = new frmExportCoordinate(pGeometry);
                            //frm.m_PrjPath = this.m_prjPath;     // 
                            //frm.Show();
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                return;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="feature"></param>
        /// <param name="m_mapControl1"></param>
        private void MyDrawPolygon(IGeometry pGeometry, IMapControl3 m_mapControl1)
        {
            try
            {
                if (pGeometry == null || (pGeometry.GeometryType != esriGeometryType.esriGeometryPolygon && pGeometry.GeometryType != esriGeometryType.esriGeometryEnvelope))
                {
                    return;
                }
                IMap pMap = m_mapControl1.Map;
                IGraphicsContainer pGCs = pMap as IGraphicsContainer;
                ISimpleFillSymbol pSimpleFillsym = new SimpleFillSymbolClass();
                IRgbColor color = new RgbColor();
                color.RGB = 255;
                ILineSymbol outline = new SimpleLineSymbol();
                outline.Width = 2;
                outline.Color = color;
                pSimpleFillsym.Outline = outline;
                pSimpleFillsym.Style = esriSimpleFillStyle.esriSFSHollow;
                IFillShapeElement pPolygonEle = new PolygonElementClass();
                pPolygonEle.Symbol = pSimpleFillsym;
                IElement pEle = pPolygonEle as IElement;
                pEle.Geometry = pGeometry;
                if (pEle != null) pGCs.AddElement(pEle, 0);
                IActiveView pAV = (IActiveView)pMap;
                pAV.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, pAV.Extent);
            }
            catch (Exception ex)
            {
            }
        }
        private void MyDrawPolyline(IGeometry pGeometry, IMapControl3 m_mapControl1)
        {
            try
            {
                if (pGeometry == null || (pGeometry.GeometryType != esriGeometryType.esriGeometryPolyline && pGeometry.GeometryType != esriGeometryType.esriGeometryLine))
                {
                    return;
                }
                IMap pMap = m_mapControl1.Map;
                IGraphicsContainer pGCs = pMap as IGraphicsContainer;
                IRgbColor color = new RgbColor();
                color.RGB = 255;
                ILineSymbol outline = new SimpleLineSymbol();
                outline.Width = 2;
                outline.Color = color;
                ILineElement pPolylineEle = new LineElementClass();
                pPolylineEle.Symbol = outline;
                IElement pEle = pPolylineEle as IElement;
                pEle.Geometry = pGeometry;
                if (pEle != null) pGCs.AddElement(pEle, 0);
                IActiveView pAV = (IActiveView)pMap;
                pAV.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, pAV.Extent);
            }
            catch (Exception ex)
            {
            }
        }
        #region Overriden Class Methods

        /// <summary>
        /// Occurs when this tool is created
        /// </summary>
        /// <param name="hook">Instance of the application</param>
        public override void OnCreate(object hook)
        {
            if (m_hookHelper == null)
                m_hookHelper = new HookHelperClass();

            m_hookHelper.Hook = hook;
            mapControl = (IMapControl3)hook;
            lineFeedback = new NewLineFeedbackClass();
            polyFeedback = new NewPolypolyFeedbackClass();

            if (state.Equals("距离"))
            {
                if (frmDistanceForm.state == false)
                {
                    if (frmAreaFormcs.state == true)
                    {
                        areaForm.Close();
                    }
                    disForm = new frmDistanceForm(mapControl);
                    disForm.Show(m_mainForm);
                }
            }
            if (state.Equals("面积"))
            {
                if (frmAreaFormcs.state == false)
                {
                    if (frmDistanceForm.state == true)
                    {
                        disForm.Close();
                    }
                    areaForm = new frmAreaFormcs(mapControl);
                    areaForm.Show(m_mainForm);
                }
            }
            // TODO:  Add celiangTool.OnCreate implementation
        }

        /// <summary>
        /// Occurs when this tool is clicked
        /// </summary>
        public override void OnClick()
        {
            // TODO: Add celiangTool.OnClick implementation
        }

        public override void OnMouseDown(int Button, int Shift, int X, int Y)
        {
            // TODO:  Add celiangTool.OnMouseDown implementation
            try
            {
                if (Button == 1)
                {
                    if (state.Equals("距离"))
                    {
                        if (frmDistanceForm.state == false)
                        {
                            if (frmAreaFormcs.state == true)
                            {
                                areaForm.Close();
                            }
                            disForm = new frmDistanceForm(mapControl);
                            disForm.Show(m_mainForm);
                        }
                    }
                    if (state.Equals("面积"))
                    {
                        if (frmAreaFormcs.state == false)
                        {
                            if (frmDistanceForm.state == true)
                            {
                                disForm.Close();
                            }
                            areaForm = new frmAreaFormcs(mapControl);
                            areaForm.Show(m_mainForm);
                        }
                    }
                    IPoint pt = this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
                    if (Button == 1)
                    {
                        mouseDown(pt);
                    }
                }
                else if (Button == 4)
                {
                    IPoint point=mapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
   mapControl.ActiveView.ScreenDisplay.PanStart(point);
   m_pan = true;
                }
                else
                {
                }
            }
            catch (Exception ex)
            {
                return;
            }
        }

        public override void OnMouseMove(int Button, int Shift, int X, int Y)
        {
            // TODO:  Add celiangTool.OnMouseMove implementation
            try
            {
                if (Button == 4)
                {
                    if (m_pan == true)
                    {
                        IPoint point = mapControl.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
                        mapControl.ActiveView.ScreenDisplay.PanMoveTo(point);
                    }
                }
                else
                {
                    IPoint pt = this.m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
                    activePt = pt;
                    if (step == 1)
                    {
                        object before = Type.Missing;
                        object after = Type.Missing;
                        if (state.Equals("距离"))
                        {
                            lineFeedback.MoveTo(pt);
                            IPolyline activeLine = new PolylineClass();
                            for (int i = 0; i < lineList.Count; i++)
                            {
                                (activeLine as IPointCollection).AddPoint(lineList[i], ref before, ref after);
                            }
                            (activeLine as IPointCollection).AddPoint(pt, ref before, ref after);
                            disForm.showDistance(activeLine.Length.ToString("#######0.##"));
                        }
                        if (state.Equals("面积"))
                        {
                            polyFeedback.MoveTo(pt);
                            IPolygon activeGon = new PolygonClass();
                            for (int m = 0; m < gonList.Count; m++)
                            {
                                (activeGon as IPointCollection).AddPoint(gonList[m], ref  before, ref after);
                            }
                            (activeGon as IPointCollection).AddPoint(pt, ref before, ref after);
                            areaForm.showArea(System.Math.Abs((activeGon as IArea).Area * 0.0015).ToString("#######0.##"));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return;
            }
        }

        public override void OnMouseUp(int Button, int Shift, int X, int Y)
        {
            // TODO:  Add celiangTool.OnMouseUp implementation
            if (Button == 1)
            {
            }
            else if (Button == 4)
            {
                if (m_pan==true)
                {
                    IEnvelope extent=mapControl.ActiveView.ScreenDisplay.PanStop();
   if(extent!=null)
   {
   mapControl.ActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds=extent;
   mapControl.ActiveView.ScreenDisplay.Invalidate(null,true,(short)esriScreenCache.esriAllScreenCaches);
   }
                }
                m_pan = false;              
            }
            else
            {
            }
        }

        public override void OnDblClick()
        {
            if (step == 1)
            {
                endTool();
            }
        }
        #endregion

        public void OnMapRefresh()
        {
            lineFeedback.Refresh(mapControl.ActiveView.ScreenDisplay.hDC);
            polyFeedback.Refresh(mapControl.ActiveView.ScreenDisplay.hDC);
        }
    }
}



主窗体刷新时可以用 delegate 代理事件


 public delegate void DelOnMapRefresh();


 public DelOnMapRefresh OnMapRefresh;

距离时


DrawPolygonTool dpt = new DrawPolygonTool("距离");
            dpt.m_MainForm = this;
            dpt.OnCreate(axMapControl1.Object);
            axMapControl1.CurrentTool = dpt;
            this.OnMapRefresh = dpt.OnMapRefresh; 


完成。


标签: arcgis Geodatabase gis

WRITTEN BY

avatar


评论:

zxa 2015-03-12 12:21
后面最重要的地方,你要说详细点,OnAfterScreenDraw事件里如何写?
悬浮的青春 2015-03-13 16:51
@zxa:用的feedback啊。