捕捉功能的实现完整版

     bool bCreateElement = true;
        //时间间隔
        int internalTime = 5;
        //初始值
        int snapTime = 10;
        //界面绘制点元素
        IElement m_element = null;
        //当前鼠标点
        IPoint currentPoint = new PointClass();
        //捕捉到得点
        IPoint snapPoint = null;
        //移动点反馈对象
        IMovePointFeedback movePointFeedback = new MovePointFeedbackClass();
        //捕捉图层
        string snapLayer = "";
        public Form1()
        {
            InitializeComponent();
        }

         //鼠标移动事件
        private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            currentPoint.PutCoords(e.mapX, e.mapY);

            snapTime++;
            snapTime = snapTime % internalTime;
            //通过名称获取图层
            ILayer pLayer = GetLayerByName(snapLayer, axMapControl1);
            IFeatureLayer featureLayer = pLayer as IFeatureLayer;
            if (bCreateElement)
            {
                CreateMarkerElement(currentPoint);
                bCreateElement = false;
            }
            if (snapPoint == null)
            {
                ElementMoveTo(currentPoint);
            }
            //鼠标光标自动捕获顶点
            if (snapTime == 0)
            {
                snapPoint = Snapping(e.mapX, e.mapY, featureLayer);
            }
            if (snapPoint != null & snapTime == 0)
            {
                ElementMoveTo(snapPoint);
            }
        }
        //捕捉
        public IPoint Snapping(double x, double y, IFeatureLayer featureLayer)
        {
            IMap pMap = axMapControl1.Map;
            IActiveView activeView = axMapControl1.ActiveView;
            IFeatureClass featureClass = featureLayer.FeatureClass;
            IPoint point = new PointClass();
            point.PutCoords(x, y);
            IPoint hitPoint1 = new PointClass();
            IPoint hitPoint2 = new PointClass();
           // IGeometryCollection pGeometryCol = null;
            IGeometryCollection pGeometryCol = new GeometryBagClass();
            IFeature feature;
            int flag = 0;
           switch (featureClass.ShapeType)
            {
                case esriGeometryType.esriGeometryPoint:
                    pGeometryCol = new MultipointClass() as IGeometryCollection;
                    flag = 0;
                    break;
                case esriGeometryType.esriGeometryPolygon:
                    pGeometryCol = new PolygonClass() as IGeometryCollection;
                    flag = 1;
                    break;
                case esriGeometryType.esriGeometryPolyline:
                    pGeometryCol = new PolylineClass() as IGeometryCollection;
                    flag = 1;
                    break;
            }
            //IGeometryCollection geocollect = new MultipointClass();

            object missing = Type.Missing;
            if (flag==0)
            {
                for (int i = 0; i < featureClass.FeatureCount(null); i++)
                {
                    feature = featureClass.GetFeature(i);
                    pGeometryCol.AddGeometry(feature.Shape, ref missing, ref missing);
                }

            }
            if (flag==1)
            {
                for (int i = 0; i < featureClass.FeatureCount(null); i++)
                {
                    feature = featureClass.GetFeature(i);
                    pGeometryCol.AddGeometryCollection((IGeometryCollection)feature.Shape);
                }
            }

            IHitTest hitTest = pGeometryCol as IHitTest;
            double hitDist = 0;
            int partIndex = 0;
            int vertexIndex = 0;
            bool bVertexHit = false;
            double tol = convertPixelsToMapUnits(activeView, 8);
            if (hitTest.HitTest(point, tol, esriGeometryHitPartType.esriGeometryPartBoundary, hitPoint2, ref hitDist, ref partIndex, ref vertexIndex, ref bVertexHit))
            {
                hitPoint1 = hitPoint2;
            }
            axMapControl1.ActiveView.Refresh();
            return hitPoint1;
        }
        public void CreateMarkerElement(IPoint point)
        {
            IActiveView activeView = axMapControl1.ActiveView;
            IGraphicsContainer graphicsContainer = axMapControl1.Map as IGraphicsContainer;
            //建立一个marker元素
            IMarkerElement markerElement = new MarkerElement() as IMarkerElement;
            ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol();
            //符号化元素
            simpleMarkerSymbol.Color = getRGB(255, 0, 0);
            simpleMarkerSymbol.Outline = true;
            simpleMarkerSymbol.OutlineColor = getRGB(0, 255, 0) as IColor;
            simpleMarkerSymbol.OutlineSize = 5;
            simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
            ISymbol symbol = simpleMarkerSymbol as ISymbol;
            symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
            markerElement.Symbol = simpleMarkerSymbol;
            m_element = markerElement as IElement;
            m_element.Geometry = point as IGeometry;
            graphicsContainer.AddElement(m_element, 0);
            activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, m_element, null);
            IGeometry geometry = m_element.Geometry;
            movePointFeedback.Display = activeView.ScreenDisplay;
            movePointFeedback.Symbol = simpleMarkerSymbol as ISymbol;
            movePointFeedback.Start(geometry as IPoint, point);
        }
        private IRgbColor getRGB(int r, int g, int b)
        {
            IRgbColor pColor = new RgbColorClass();
            pColor.Red = r;
            pColor.Green = g;
            pColor.Blue = b;
            return pColor;
        }
        //移动元素到新的位置
        public void ElementMoveTo(IPoint point)
        {
            //移动元素
            movePointFeedback.MoveTo(point);
            IGeometry geometry1 = null;
            IGeometry geometry2 = null;
            if (m_element != null)
            {
                geometry1 = m_element.Geometry;
                geometry2 = movePointFeedback.Stop();
                m_element.Geometry = geometry2;
                //更新该元素的位置
                axMapControl1.ActiveView.GraphicsContainer.UpdateElement(m_element);
                //重新移动元素
                movePointFeedback.Stop();
                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 activeView, double pixelUnits)
        {
            double realDisplayExtent;
            int pixelExtent;
            double sizeOfOnePixel;
            pixelExtent = activeView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().right - activeView.ScreenDisplay.DisplayTransformation.get_DeviceFrame().left;
            realDisplayExtent = activeView.ScreenDisplay.DisplayTransformation.VisibleBounds.Width;
            sizeOfOnePixel = realDisplayExtent / pixelExtent;
            return pixelUnits * sizeOfOnePixel;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (axMapControl1.LayerCount != 0)
            {
                cbLayerName.Items.Clear();
                for (int i = 0; i < axMapControl1.LayerCount; i++)
                {
                    cbLayerName.Items.Add(axMapControl1.get_Layer(i).Name);
                }
                cbLayerName.Text = cbLayerName.Items[0].ToString();
                snapLayer = cbLayerName.Text;
            }
            else
            {
                MessageBox.Show("请先加载图层!");
            }

        }
        //更改当前捕捉图层名时
        private void cbLayerName_TextChanged(object sender, EventArgs e)
        {            
            snapLayer = cbLayerName.Text;
        }

posted on 2012-03-19 10:17  种瓜得瓜  阅读(578)  评论(0编辑  收藏  举报