namespace 捕捉 { public partial class Form1 : Form { private bool bCreateElement=true; private int internalTime = 5; private int snapTime = 10; private IElement m_element = null; IPoint currentPoint=new PointClass(); private IPoint snapPoint = null; IMovePointFeedback movePointFeedback=new MovePointFeedbackClass(); private string snapLayer = ""; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void axMapControl1_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e) { currentPoint.PutCoords(e.mapX,e.mapY); snapTime++; snapTime = snapTime%internalTime; ILayer layer=GetLayerByName(snapLayer,axMapControl1); if (layer==null) { return; } IFeatureLayer featureLayer = layer as IFeatureLayer; if (bCreateElement) { CreateMarkerElement(currentPoint); bCreateElement = false; } if (snapPoint==null) { ElementMoveTo(currentPoint); } if (snapTime==0) { #region 第一种捕捉方式 IPoint temPoint = new PointClass(); temPoint.X = e.mapX; temPoint.Y = e.mapY; snapPoint = GetNearestVertex(axMapControl1.ActiveView, temPoint, 8); #endregion #region 第二种方式 //snapPoint = Snapping(e.mapX, e.mapY, featureLayer); #endregion } if (snapPoint!=null&&snapTime==0) { ElementMoveTo(snapPoint); } } 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; } public IPoint Snapping(double x,double y,IFeatureLayer featureLayer) { #region 这种捕捉有问题,无法捕捉点和面图层 IPoint iHitPoint = null; IMap iMap = axMapControl1.Map; IActiveView iView = axMapControl1.ActiveView; IFeatureClass iFClass = featureLayer.FeatureClass; IPoint point=new PointClass(); point.PutCoords(x,y); double length = ConvertPixelsToMapUnits(iView, 8); ITopologicalOperator pTopo = point as ITopologicalOperator; IGeometry pGeometry = pTopo.Buffer(length).Envelope as IGeometry; ISpatialFilter spatialFilter=new SpatialFilterClass(); spatialFilter.GeometryField = featureLayer.FeatureClass.ShapeFieldName; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses; spatialFilter.Geometry = pGeometry; IFeatureCursor cursor = iFClass.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; 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; #endregion } 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; this.axMapControl1.ActiveView.GraphicsContainer.UpdateElement(m_element); movePointFeedback.Start(geometry1 as IPoint,point); axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics,null,null); } } public IPoint GetNearestVertex(IActiveView actview, IPoint pnt, double mapSize) { IPoint vetex = null; IPoint hitPnt = new PointClass(); IHitTest hitTest = null; IPointCollection pntColl = new MultipointClass(); IProximityOperator prox = null; double hitdis = 0; int hitpartindex = 0; int hitsegindex = 0; Boolean rside = false; IFeatureCache2 featCache = new FeatureCacheClass(); double pixelSize = ConvertPixelsToMapUnits(actview, mapSize); //将地理范围转化为像素 featCache.Initialize(pnt, pixelSize); //初始化缓存 for (int i = 0; i < actview.FocusMap.LayerCount; i++) { //只有点、线、面并且可视的图层才加入缓存 IFeatureLayer featLayer = (IFeatureLayer)actview.FocusMap.get_Layer(i); if (featLayer != null && featLayer.Visible == true && (featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline || featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon || featLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint)) { featCache.AddFeatures(featLayer.FeatureClass, null); for (int j = 0; j < featCache.Count; j++) { IFeature feat = featCache.get_Feature(j); hitTest = (IHitTest)feat.Shape; //捕捉节点,另外可以设置esriGeometryHitPartType,捕捉边线点,中间点等。 if (hitTest.HitTest(pnt, mapSize, esriGeometryHitPartType.esriGeometryPartVertex, hitPnt, ref hitdis, ref hitpartindex, ref hitsegindex, ref rside)) { object obj = Type.Missing; pntColl.AddPoint(hitPnt, ref obj, ref obj); break; } } } } prox = (IProximityOperator)pnt; double minDis = 0, dis = 0; for (int i = 0; i < pntColl.PointCount; i++) { IPoint tmpPnt = pntColl.get_Point(i); dis = prox.ReturnDistance(tmpPnt); if (i == 0) { minDis = dis; vetex = tmpPnt; } else { if (dis < minDis) { minDis = dis; vetex = tmpPnt; } } } return vetex; } public ILayer GetLayerByName(string layerName, AxMapControl axMap) { for (int i = 0; i < axMap.LayerCount; i++) { if (axMap.get_Layer(i).Name.EndsWith(layerName)) { return axMap.get_Layer(i); } } return null; } public void CreateMarkerElement(IPoint point) { IActiveView activeView = this.axMapControl1.ActiveView; IGraphicsContainer graphicsContainer = axMapControl1.Map as IGraphicsContainer; IMarkerElement markerElement = new MarkerElement() as IMarkerElement; ISimpleMarkerSymbol simpleMarkerSymbol=new SimpleMarkerSymbol(); IRgbColor rgbColor1=new RgbColor(); rgbColor1.Red = 0; rgbColor1.Blue = 100; rgbColor1.Green = 255; simpleMarkerSymbol.Color = rgbColor1; IRgbColor iRgbColor2=new RgbColor(); iRgbColor2.Red = 0; iRgbColor2.Blue = 0; iRgbColor2.Green = 0; simpleMarkerSymbol.Outline = true; simpleMarkerSymbol.OutlineColor = iRgbColor2 as IColor; simpleMarkerSymbol.OutlineSize = 1; simpleMarkerSymbol.Size = 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 void cbLayerName_SelectedIndexChanged(object sender, EventArgs e) { snapLayer = cbLayerName.Text; } private void Form1_DoubleClick(object sender, EventArgs e) { } private void splitContainer1_Panel2_DoubleClick(object sender, EventArgs e) { for (int i = 0; i < axMapControl1.Map.LayerCount; i++) { cbLayerName.Items.Add(axMapControl1.get_Layer(i).Name); } cbLayerName.Text = cbLayerName.Items[0].ToString(); snapLayer = cbLayerName.Text; } } }
时间: 2024-10-19 19:58:34