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

    }
}
时间: 2024-10-19 19:58:34

C# Arcgis Engine 捕捉功能实现的相关文章

ArcGIS Engine 捕捉

原文 ArcGIS Engine 捕捉 bool bCreateElement = true; int internalTime = 5;//时间间隔 int snapTime = 10;//初始值 IElement m_element = null; //界面绘制点元素 IPoint currentPoint = new PointClass(); //当前鼠标点 IPoint snapPoint = null; //捕捉到的点 IMovePointFeedback pFeedback = n

ArcGIS Engine开发的ArcGIS 版本管理的功能

原文:ArcGIS Engine开发的ArcGIS 版本管理的功能 转自:http://blog.csdn.net/linghe301/article/details/7965901 这是以前的ArcGIS Engine开发成果,主要是Geodatabase方面的,模仿ArcGIS版本的流程系统环境: VS2010.ArcGIS Engine10.DevExpress721(第三方控件,比较常用易于下载) ---------------------------------------------

ArcGIS Engine 开发(二)线、圆、矩形、面、文本编辑功能

ArcGIS Engine 开发(二)线.圆.矩形.面.文本编辑功能,这些都是实现课上的源代码,自己调试好了,直接可以放到vs2010下跑,希望能对大家有所帮助 好了,先来看效果 二.下面是调试好的代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using Syste

ArcGIS Engine开发鹰眼图的功能(代码优化篇)

在上一篇,ArcGIS Engine开发鹰眼图的功能(基础篇) 上一篇的实现效果图如下, 如果仔细观察,会发现一个问题,即在“鹰眼”的区域,只要在红色线框内的注记会被覆盖. 如果红色框包括整张图的话,图上的注记都将不会显示. 是什么原因造成的呢? 原因是使用IFillShapeElement向鹰眼视图添加绘图框后,标注与绘图框冲突造成互相压盖. 我们来看一张表, 在基础篇中,我们使用的是IFillShapeElement面要素进行刷新的,现在我们改换为线要素的IScreenDisplay Dra

ArcGIS AddIn 图斑比例分割工具,调用捕捉功能

最近做一个图斑按比例分割的工具,需要绘制一条用以切割的方向线,通过Tool的方式实现 绘制时希望能够使用捕捉功能,查阅相关资料如下: 使用该文章,第Implementing snapping in an edit session部分,实现在编辑时的捕捉功能.

利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用

原文:利用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署应用的方法和步骤. 你可以在下面的目录下找到相应的样例程序: <安装目录>\DeveloperKit\Samples\Developer_Guide_Scenarios\ ArcGIS_Engine\Building_an_ArcGIS_Control_Application\Map_Viewer 注:ArcGIS样

Arcgis Engine 10.2安装过程

安装顺序 : VS2010-->Arcgis 10.2-->Arcgis engine 10.2-->ArcObjects SDK for Microsoft.NET Framework. vs2010安装方式略 一.Arcgis10.2安装 选择ArcGIS10.2 解压后的安装包中ESRI.exe文件 第一步安装ArcGIS License Manager (选择合适路径,基本一路回车) 安装好以后,启动License Manager,选择停止 第二步安装ArcGIS for  De

ArcGIS Engine开发前基础知识(4)

ArcGIS不同开发方式的比较 关于GIS应用软件的开发,通常有三种方式:C/S架构.网络GIS和移动GIS.ArcGIS平台提供了对三种开发方式的支持,对于采用从C/S架构的大多数开发者来讲,首先想到的是ArcGIS Engine进行开发.实际上,并不是所有的系统都必须采用这种方式,上述的三种开发方式(VBA.DLL和Add-in)在很多的时候也可以考虑. 作为VB的子集,VBA方式采用Visual Basic语言规范,简单易学,开发者只需要关注自己需要而ArcGIS没有直接提供的功能.对于广

J2EE(java)后台调用ArcGIS Engine(AE)的部署和代码

arcgis的BS开发解决方案一直是个坑,主推的地图服务查询速度慢,需要异步,功能少.相对来说主要用于CS的AE功能更强大全面,只是部署有点复杂 本文软件环境: win7 sp1 64位 MyEclipse 10,jdk 1.6.45 32位,tomcat 6.0.41 32位,ArcGIS Desktop 10.0(或ArcGIS Engine) 1.1.1.   安装软件 ArcGIS Desktop或ArcGIS Engine Runtime 建议装desktop,因为AE Runtime