C# Arcgis Engine 捕捉功能实现

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

 源码:http://pan.baidu.com/s/1gdzP8QJ

提取密码:dlpn

visual studio 2008

AE9.3

posted @ 2014-10-16 16:54  Creatisan  阅读(2633)  评论(0编辑  收藏  举报