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; }