ArcGIS Engine捕捉功能

博客围绕ArcGIS Engine捕捉功能展开,虽未给出具体内容,但可知聚焦此功能相关信息技术内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值