欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

aoeditor.cs

很好的带有编辑功能、量算功能。可在地图上进行距离、面积、角度测量
CS
第 1 页 / 共 2 页
字号:

using System;
using System.IO ;
using System.Windows.Forms ;
using System.Reflection ; 

using ESRI.ArcGIS.Carto ; 
using ESRI.ArcGIS.Display ;
using ESRI.ArcGIS.Geometry ;
using ESRI.ArcGIS.Geodatabase ; 

namespace AoTest
{
	/// <summary>
	/// 使用本类可以新建点、线、面
	/// 移动点、线、面
	/// 编辑线、面的节点
	/// 使用时需设置Map和CurrentLayer
	/// </summary>
	public class AoEditor
	{
		private ILayer m_pCurrentLayer;
		private IMap m_pMap ;
		private IFeature m_pEditFeature ;
		private IPoint m_pPoint;
		private IDisplayFeedback m_pFeedback;
//		private ISelectionTracker m_pSelectionTracker;
		private bool m_bInUse;
		private IPointCollection m_pPointCollection;
		
		/// <summary>
		/// 当前图层,只写
		/// </summary>
		public ILayer CurrentLayer
		{
			set
			{
				m_pCurrentLayer = (ILayer) value;
			}
		}

		/// <summary>
		/// 地图对象,只写
		/// </summary>
		public IMap Map
		{
			set 
			{
				m_pMap = (IMap) value;
			}
		}

		/// <summary>
		/// 构造函数
		/// </summary>
		public AoEditor()
		{
			
		}

		/// <summary>
		/// 开始编辑,使工作空间处于可编辑状态
		/// 在进行图层编辑前必须调用本方法
		/// </summary>
		public void StartEditing()
		{			 
			try
			{				
				if (m_pCurrentLayer ==null ) 	return ;

				if (!(m_pCurrentLayer is IGeoFeatureLayer)) 	return ;
			
				IFeatureLayer pFeatureLayer = (IFeatureLayer) m_pCurrentLayer;
				IDataset pDataset = (IDataset) pFeatureLayer.FeatureClass;
				if (pDataset ==null)	return ;
  
				// 开始编辑,并设置Undo/Redo 为可用
				IWorkspaceEdit pWorkspaceEdit =(IWorkspaceEdit) pDataset.Workspace;
				if (!pWorkspaceEdit.IsBeingEdited()) 
				{
					pWorkspaceEdit.StartEditing(true);
					pWorkspaceEdit.EnableUndoRedo();
				}
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message.ToString());
			}
		}
		
		/// <summary>
		/// 停止编辑,并将以前的编辑结果保存到数据文件中。
		/// </summary>
		public void StopEditing()
		{
			bool bHasEdits = false;
			bool bSave = false;
  
			try
			{				
				if (m_pCurrentLayer ==null)		return ;

				IFeatureLayer pFeatureLayer =(IFeatureLayer) m_pCurrentLayer;
				if (pFeatureLayer.FeatureClass ==null)	return ;

				IDataset pDataset =(IDataset) pFeatureLayer.FeatureClass;
				if (pDataset ==null)	return ;
   
				//如果数据已被修改,则提示用户是否保存
				IWorkspaceEdit pWorkspaceEdit =(IWorkspaceEdit) pDataset.Workspace;
				if (pWorkspaceEdit.IsBeingEdited())
				{
					pWorkspaceEdit.HasEdits(ref bHasEdits);
					if (bHasEdits)
					{
						DialogResult result;
						result = MessageBox.Show("是否保存已做的修改?","提示",MessageBoxButtons.YesNo);
						if (result == DialogResult.Yes)
						{
							bSave = true;
						}
					}
					pWorkspaceEdit.StopEditing(bSave);
				}
 
				m_pMap.ClearSelection();
				IActiveView pActiveView =(IActiveView) m_pMap;
				pActiveView.Refresh();
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message.ToString());
			}

		}

		/// <summary>
		/// 检查工作空间中是否有数据处于编辑状态
		/// </summary>
		/// <returns>是否正在编辑</returns>
		public bool InEdit()
		{			
			try
			{				
				if (m_pCurrentLayer ==null ) return false ; 

				IFeatureLayer pFeatureLayer = (IFeatureLayer) m_pCurrentLayer;
				if (pFeatureLayer.FeatureClass == null) return false ; 

				IDataset pDataset =(IDataset) pFeatureLayer.FeatureClass;
				if ( pDataset == null) return false ;

				IWorkspaceEdit pWorkspaceEdit = (IWorkspaceEdit) pDataset.Workspace;
				if (pWorkspaceEdit.IsBeingEdited()) return true;
                		
				return false;
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message.ToString()); 
				return false;
			}
		}

		/// <summary>
		/// 新建对象方法
		/// 当前图层为点图层时,每调用一次就新点一个点对象
		/// 当前图层为线图层或面图层时,第一次调用开始新建对象,并添加当前点,
		/// 以后每调用一次,即向新对象中添加一个点,调用NewFeatureEnd方法完成对象创建
		/// 在Map.MouseDown事件中调用本方法
		/// </summary>
		/// <param name="x">鼠标X坐标,屏幕坐标</param>
		/// <param name="y">鼠标Y坐标,屏幕坐标</param>
		public void NewFeatureMouseDown( int x, int y)
		{
			INewPolygonFeedback pPolyFeed ;
			INewLineFeedback pLineFeed;
  
			try
			{				
				if (m_pCurrentLayer == null ) return ;

				if (!(m_pCurrentLayer is IGeoFeatureLayer)) return ;

				IFeatureLayer pFeatureLayer =(IFeatureLayer) m_pCurrentLayer;
				if (pFeatureLayer.FeatureClass ==null ) return ;

				IActiveView pActiveView =(IActiveView) m_pMap;
				IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
  
				// 如果是新开始创建的对象,则相应的创建一个新的Feedback对象;
				// 否则,向已存在的Feedback对象中加点
				if (!m_bInUse) 
				{
					m_pMap.ClearSelection();  //清除地图选中对象

					switch ( pFeatureLayer.FeatureClass.ShapeType)
					{
						case esriGeometryType.esriGeometryPoint:
							CreateFeature( pPoint);
							break;
						case esriGeometryType.esriGeometryMultipoint:
							m_bInUse = true;
							m_pFeedback = new NewMultiPointFeedbackClass();
							INewMultiPointFeedback pMPFeed =(INewMultiPointFeedback) m_pFeedback;
							m_pPointCollection = new MultipointClass();
							pMPFeed.Start(m_pPointCollection, pPoint);
							break;
						case esriGeometryType.esriGeometryPolyline:
							m_bInUse = true;
							m_pFeedback = new  NewLineFeedbackClass();
							pLineFeed = (INewLineFeedback) m_pFeedback;
							pLineFeed.Start(pPoint);
							break;
						case esriGeometryType.esriGeometryPolygon:
							m_bInUse = true;
							m_pFeedback = new NewPolygonFeedbackClass();
							pPolyFeed = (INewPolygonFeedback) m_pFeedback;
							pPolyFeed.Start(pPoint);
							break;
					}
			
					if (m_pFeedback != null)
						m_pFeedback.Display = pActiveView.ScreenDisplay;
				}
				else
				{
					if (m_pFeedback is INewMultiPointFeedback)
					{
						object obj = Missing.Value ;
						m_pPointCollection.AddPoint(pPoint,ref obj,ref obj);
					}
					else if (m_pFeedback is INewLineFeedback)
					{
						pLineFeed =(INewLineFeedback) m_pFeedback;
						pLineFeed.AddPoint(pPoint);
					}
					else if (m_pFeedback is INewPolygonFeedback)
					{
						pPolyFeed = (INewPolygonFeedback) m_pFeedback;
						pPolyFeed.AddPoint(pPoint);
					}
				}
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message.ToString());
			}
		}

		/// <summary>
		/// 新建对象过程中鼠标移动方法,产生Track效果
		/// 在Map.MouseMove事件中调用本方法
		/// </summary>
		/// <param name="x">鼠标X坐标,屏幕坐标</param>
		/// <param name="y">鼠标Y坐标,屏幕坐标</param>
		public void NewFeatureMouseMove(int x, int y)
		{
			if ((!m_bInUse)||(m_pFeedback ==null)) return ;  
			
			IActiveView  pActiveView = (IActiveView) m_pMap;
			m_pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
			m_pFeedback.MoveTo(m_pPoint);
		}

		/// <summary>
		/// 完成新建对象,取得绘制的对象,并添加到图层中
		/// 建议在Map.DblClick或Map.MouseDown(Button = 2)事件中调用本方法
		/// </summary>
		public void NewFeatureEnd()
		{
			IGeometry pGeom = null;
			IPointCollection pPointCollection;
  
			try
			{
				if (m_pFeedback is INewMultiPointFeedback)
				{
					INewMultiPointFeedback pMPFeed =(INewMultiPointFeedback) m_pFeedback;
					pMPFeed.Stop();
					pGeom =(IGeometry) m_pPointCollection;
				}
				else if (m_pFeedback is INewLineFeedback)
				{				 
					INewLineFeedback pLineFeed =(INewLineFeedback) m_pFeedback;

					pLineFeed.AddPoint(m_pPoint);
					IPolyline pPolyLine = pLineFeed.Stop();
				
					pPointCollection =(IPointCollection) pPolyLine;
					if (pPointCollection.PointCount < 2)
						MessageBox.Show("至少输入两个节点");				
					else
						pGeom =(IGeometry) pPointCollection;
				}
				else if (m_pFeedback is INewPolygonFeedback)
				{
					INewPolygonFeedback pPolyFeed =(INewPolygonFeedback) m_pFeedback;
					pPolyFeed.AddPoint(m_pPoint);
				
					IPolygon pPolygon ;
					pPolygon = pPolyFeed.Stop();
					if (pPolygon !=null)
					{
						pPointCollection =(IPointCollection) pPolygon;
						if (pPointCollection.PointCount < 3)
							MessageBox.Show("至少输入三个节点");
						else
							pGeom =(IGeometry) pPointCollection;
					}
				}
				
				CreateFeature(pGeom);
				m_pFeedback = null;
				m_bInUse = false;
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message.ToString());
			}
		}			

		/// <summary>
		/// 查询当前图层中鼠标位置处的地图对象
		/// 建议在Map.MouseDown事件中调用本方法
		/// </summary>
		/// <param name="x">鼠标X坐标,屏幕坐标</param>
		/// <param name="y">鼠标Y坐标,屏幕坐标</param>
		public void SelectMouseDown(int x, int y)
		{

			ISpatialFilter pSpatialFilter;
			IQueryFilter pFilter ;
			  
			try
			{
				if (m_pCurrentLayer == null) return ;
				if (!(m_pCurrentLayer is IGeoFeatureLayer)) return ;
  
				IFeatureLayer pFeatureLayer =(IFeatureLayer) m_pCurrentLayer;
				IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
				if (pFeatureClass == null) return;

				IActiveView pActiveView =(IActiveView) m_pMap;
				IPoint pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
				IGeometry pGeometry = pPoint;
  
				// 设置查询缓冲区
				double length = ConvertPixelsToMapUnits(pActiveView, 4.0);
				ITopologicalOperator pTopo =(ITopologicalOperator) pGeometry;
				IGeometry pBuffer = pTopo.Buffer(length);
				pGeometry = pBuffer.Envelope;
  
				//设置过滤器对象
				pSpatialFilter = new SpatialFilterClass();
				pSpatialFilter.Geometry = pGeometry;
			
				switch (pFeatureClass.ShapeType)
				{
					case esriGeometryType.esriGeometryPoint:
						pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
						break;
					case esriGeometryType.esriGeometryPolyline:
						pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
						break;
					case esriGeometryType.esriGeometryPolygon:
						pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
						break;
				}
				pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName;
				pFilter = pSpatialFilter;
 
				// 查询
				IFeatureCursor pCursor = pFeatureLayer.Search(pFilter, false);

				// 在地图上高亮显示查询结果
				IFeature pFeature = pCursor.NextFeature();
				while (pFeature != null)
				{
					m_pMap.SelectFeature(m_pCurrentLayer, pFeature);
					pFeature = pCursor.NextFeature();
				}				
				pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection ,null,null);
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message.ToString());
			}
		}
	
		/// <summary>
		/// 编辑当前图层中鼠标击中的地图对象(开始编辑),
		/// 如果为点对象,可进行位置移动,如果为线对象或面对象,可进行节点编辑
		/// 建议在Map.MouseDown事件中调用本方法
		/// </summary>
		/// <param name="x">鼠标X坐标,屏幕坐标</param>
		/// <param name="y">鼠标Y坐标,屏幕坐标</param>
		/// <returns></returns>
		public bool EditFeatureMouseDown(int x, int y)
		{
			IGeometryCollection pGeomColn ;
			IPointCollection pPointColn;
			IObjectClass pObjectClass ;
			IFeature pFeature;
			IGeometry pGeom ;
			
			IPath pPath ;
			IPoint pHitPoint =null ;
			IPoint pPoint =null;
			Double hitDist =0.0;
			double tol;
			int vertexIndex =0;
			int numVertices;
			int partIndex =0;
			bool vertex = false;

			try
			{
				
				m_pMap.ClearSelection();

				// 取得鼠标击中的第一个对象
				SelectMouseDown(x,y);
				IEnumFeature pSelected =(IEnumFeature) m_pMap.FeatureSelection;
				pFeature = pSelected.Next();
				if (pFeature ==null ) return false;
  
				IActiveView pActiveView =(IActiveView) m_pMap;
				pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
  
				// 节点空间查询容差
				tol = ConvertPixelsToMapUnits(pActiveView, 4.0);
  
				pGeom = pFeature.Shape;
				pObjectClass = pFeature.Class;
				m_pEditFeature = pFeature;
				object objNull = Missing.Value ;
				object objBefore, objAfter;

				switch (pGeom.GeometryType)
				{
					case esriGeometryType.esriGeometryPoint:
						m_pFeedback = new MovePointFeedbackClass();
						m_pFeedback.Display = pActiveView.ScreenDisplay;
						IMovePointFeedback pPointMove =(IMovePointFeedback) m_pFeedback;
						pPointMove.Start((IPoint)pGeom, pPoint);  
						break;
					case esriGeometryType.esriGeometryPolyline:
						if (TestGeometryHit(tol, pPoint, pFeature, pHitPoint, hitDist,out partIndex,out vertexIndex,out vertex))
						{
							if (!vertex)
							{								
								pGeomColn =(IGeometryCollection) pGeom;
								pPath =(IPath) pGeomColn.get_Geometry(partIndex);
								pPointColn =(IPointCollection) pPath;
								numVertices = pPointColn.PointCount;							
								
								if (vertexIndex == 0)
								{
									objBefore = (object) (vertexIndex+1); 
									pPointColn.AddPoint(pPoint,ref objBefore,ref objNull);
								}
								else
								{
									objAfter = (object) vertexIndex; 
									pPointColn.AddPoint( pPoint,ref objNull , ref objAfter);
								}

								TestGeometryHit(tol, pPoint, pFeature, pHitPoint, hitDist,out partIndex,out vertexIndex,out vertex);
							}
							m_pFeedback = new LineMovePointFeedbackClass();
							m_pFeedback.Display = pActiveView.ScreenDisplay;
							ILineMovePointFeedback pLineMove =(ILineMovePointFeedback) m_pFeedback;
							pLineMove.Start((IPolyline)pGeom, vertexIndex, pPoint);
							
//							m_pSelectionTracker = new LineTrackerClass();
//							m_pSelectionTracker.Display = pActiveView.ScreenDisplay ;
//							m_pSelectionTracker.Geometry = pGeom;
//							m_pSelectionTracker.ShowHandles = true;
//							m_pSelectionTracker.QueryResizeFeedback(ref m_pFeedback); 
//							m_pSelectionTracker.OnMouseDown(1,0,x,y); 							
						}
						else
						{
							return false;
						}
						break;
					case esriGeometryType.esriGeometryPolygon:
						if (TestGeometryHit(tol, pPoint, pFeature, pHitPoint, hitDist,out partIndex,out vertexIndex,out vertex))
						{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -