ArcGIS Engine 捕捉功能的实现(转)

时间:2013-4-22    作者:悬浮的青春    分类:


一般情况下。大家都是直接调用AE的捕捉接口实现捕捉的。


调用接口也可以实现捕捉 有兴趣的话去看一下帮助文档 

IEngineAgent 


IEngineFeaturesnapagent



IEngineSnapEnvironment



不过不太灵活。于是就有了自己写代码实现捕捉的意向


经过网络搜集。得到下面的代码。待我有时间自己试试吧。有识之士也可以参详一下。


感觉应该还行。


下面贴实现代码

bool bCreateElement = true;
        int internalTime = 5;//时间间隔
        int snapTime = 10;//初始值
        IElement m_element = null;  //界面绘制点元素
        IPoint currentPoint = new PointClass();  //当前鼠标点
        IPoint snapPoint = null;  //捕捉到的点
        IMovePointFeedback pFeedback = new MovePointFeedbackClass();

        public void DoMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            AxMapControl axMapControl1 = sender as AxMapControl;
            currentPoint.PutCoords(e.mapX, e.mapY);
            if (action == ActionType.CreateFeature)
            {
                snapTime++;
                snapTime = snapTime%internalTime ;
                ILayer layer = GetLayerByName(snapLayer, axMapControl1);
                IFeatureLayer m_iFeatureLyr = layer as IFeatureLayer;
                if (bCreateElement)
                {
                    CreateMarkerElement(currentPoint,axMapControl1);
                    bCreateElement = false;
                }               
                if (snapPoint == null)
                    ElementMoveTo(currentPoint, axMapControl1);
                //鼠标自动扑获顶点  
                if (snapTime == 0)
                    snapPoint = Snapping(e.mapX, e.mapY, m_iFeatureLyr, axMapControl1);
                if (snapPoint != null && snapTime == 0)
                    ElementMoveTo(snapPoint, axMapControl1);
            }
        }

/// <summary>
        /// 捕捉
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="iFeatureLyr"></param>
        /// <param name="axMapControl1"></param>
        /// <returns></returns>
        public IPoint Snapping(double x, double y, IFeatureLayer iFeatureLyr, AxMapControl axMapControl1)
        {
            IPoint iHitPoint = null;
            IMap iMap = axMapControl1.Map;
            IActiveView iView = axMapControl1.ActiveView;
            IFeatureClass iFClss = iFeatureLyr.FeatureClass;
            IPoint point = new PointClass();
            point.PutCoords(x,y);
            double length = ConvertPixelsToMapUnits(axMapControl1.ActiveView, 8);
            ITopologicalOperator pTopo = point as ITopologicalOperator;
            IGeometry pGeometry = pTopo.Buffer(length).Envelope as IGeometry;
            ISpatialFilter spatialFilter = new SpatialFilterClass();
            spatialFilter.GeometryField = iFeatureLyr.FeatureClass.ShapeFieldName;
            spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
            spatialFilter.Geometry = pGeometry;
            
            IFeatureCursor cursor = iFClss.Search(spatialFilter, false);
            IFeature iF = cursor.NextFeature();
            if (iF == null) return null;
            
            IPoint iHitPt = new ESRI.ArcGIS.Geometry.Point();
            IHitTest iHitTest = iF.Shape as IHitTest;
            double hitDist = 0;
            int partIndex = 0;
            int vertexIndex = 0;
            bool bVertexHit = false;
            // Tolerance in pixels for line hits
            double tol = ConvertPixelsToMapUnits(iView, 8);

            if (iHitTest.HitTest(point, tol, esriGeometryHitPartType.esriGeometryPartBoundary,
                iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bVertexHit))
            {
                iHitPoint = iHitPt;
            }
            axMapControl1.ActiveView.Refresh();
            return iHitPoint;
        }

/// <summary>
        /// 创建新的element用于显示
        /// </summary>
        /// <param name="point"></param>
        /// <param name="axMapControl1"></param>
        public void CreateMarkerElement(IPoint point, AxMapControl axMapControl1)
        {
            IActiveView iView = axMapControl1.ActiveView;
            IGraphicsContainer iGraphContainer = axMapControl1.Map as IGraphicsContainer;
            //建立一个marker元素
            IMarkerElement iMarkerElement = new MarkerElement() as IMarkerElement;
            ISimpleMarkerSymbol iSym = new SimpleMarkerSymbol();
            //符号化元素
            IRgbColor iColor = new RgbColor();
            iColor.Red = 0;
            iColor.Blue = 100;
            iColor.Green = 255;
            iSym.Color = iColor;
            IRgbColor iColor2 = new RgbColor();
            iColor2.Red = 0;
            iColor2.Blue = 0;
            iColor2.Green = 0;
            iSym.Outline = true;
            iSym.OutlineColor = iColor2 as IColor;
            iSym.OutlineSize = 1;
            iSym.Size = 5;
            iSym.Style. = esriSimpleMarkerStyle.esriSMSCircle;
            ISymbol symbol = iSym as ISymbol;
            symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
            iMarkerElement.Symbol = iSym;
            m_element = iMarkerElement as IElement;
            m_element.Geometry = point as IGeometry;
            iGraphContainer.AddElement(m_element, 0);
            iView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, m_element, null);
            IGeometry iGeo = m_element.Geometry;
            pFeedback.Display = iView.ScreenDisplay;
            pFeedback.Symbol = iSym as ISymbol;
            pFeedback.Start(iGeo as IPoint, point);
        }
        /// <summary>
        /// 移动元素
        /// </summary>
        /// <param name="iPt"></param>
        /// <param name="axMapControl1"></param>
        public void ElementMoveTo(IPoint iPt, AxMapControl axMapControl1)
        {
            //移动元素
            pFeedback.MoveTo(iPt);
            IGeometry iGeo1 = null;
            IGeometry iGeoResult;
            if (m_element != null)
            {
                iGeo1 = m_element.Geometry;
                iGeoResult = pFeedback.Stop();
                //map.ActiveView.Refresh();
                m_element.Geometry = iGeoResult;
                //更新该元素的位置
                axMapControl1.ActiveView.GraphicsContainer.UpdateElement(m_element);
                //重新移动元素
                pFeedback.Start(iGeo1 as IPoint, iPt);
                //map.ActiveView.Refresh();
                axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
            }
        }

        public ILayer GetLayerByName(string layerName, AxMapControl axMapControl1)
        {
            for (int i = 0; i < axMapControl1.LayerCount; i++)
            {
                if (axMapControl1.get_Layer(i).Name.Equals(layerName))
                    return axMapControl1.get_Layer(i);
            }
            return null;
        }

        public double ConvertPixelsToMapUnits(IActiveView pActiveView, double pixelUnits)
        {
            double realWorldDisplayExtent;
            int pixelExtent;
            double sizeOfOnePixel;
            pixelExtent = pActiveView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().right - pActiveView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().left;
            realWorldDisplayExtent = pActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;
            sizeOfOnePixel = realWorldDisplayExtent / pixelExtent;
            return pixelUnits * sizeOfOnePixel;
        }

 

标签: arcgis

WRITTEN BY

avatar


评论:

kof99qqa 2014-06-23 21:53
您的 action 和actiontype 是哪里定义的???
悬浮的青春 2014-06-28 23:45
@kof99qqa:actiontype是一个枚举变量,里面定义了各种编辑操作,添加要素,编辑要素,删除要素等。action就是个工具状态标记,你点击捕捉后还得确定当前的工具状态。
五点五 2022-11-21 21:56
@悬浮的青春:那请问您的actiontype是用哪个接口或者怎么定义的嘞
悬浮的青春 2022-12-05 11:14
@五点五:就是个枚举变量,拿来判断当前是什么操作的。里面存的字符串。例如
enum ActionType
{
CreateFeature='你自己想定义的字符串或者值',
DeleteFeature='删除元素'
} ;