ArcGIS Engine高级功能开发
Button Button GroupBox
btnSave btnStopEditing 保存 结束编辑 地图编辑 保存编辑 结束编辑状态 控件容器 4.2 添加引用和代码
ArcEngine中的地图编辑使用IWorkspaceEdit接口来进行编辑状态的管理,在需要对指定的工作空间进行编辑时,首先使用IWorkspaceEdit获取该工作空间的数据,然后使用StartEditing方法开始编辑状态,StartEditOperation方法打开具体编辑的操作,编辑完成后,使用StopEditOperation方法关闭编辑操作,使用StopEditing方法关闭编辑状态,完成编辑。
在本例中,我们实现了新的点线面要素的创建和移动的功能,涉及到了比较复杂的鼠标与地图间的交互,这个功能的实现中,IDisplayFeedback是一个十分关键的接口,它具有涉及创建要素,移动要素、编辑节点等31个实现类,能够实现鼠标与地图交互中的事件的追踪,返回新的几何对象。
本例的实现,我们首先来添加一个编辑类,将涉及到的编辑的相关方法抽象到这个类中。在项目中添加“Edit”类。添加如下引用。
using System.Windows.Forms; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Display;
定义如下成员变量。
private bool mIsEditing; //编辑状态 private bool mHasEditing; //是否编辑 private IFeatureLayer mCurrentLayer; //当前编辑图层 private IWorkspaceEdit mWorkspaceEdit; //编辑工作空间 private IMap mMap; //地图
private IDisplayFeedback mDisplayFeedback; //用于鼠标与控件进行可视化交互 private IFeature mPanFeature; //移动的要素
带参数的构造函数和默认构造函数如下:
public Edit(IFeatureLayer editLayer, IMap map) {
mCurrentLayer = editLayer; this.mMap = map; }
///
ArcGIS Engine高级功能开发
{ }
添加编辑状态相关属性和方法。
///
return mIsEditing; }
///
return mHasEditing; }
///
public void StartEditing() {
//获取要素工作空间
IFeatureClass pFeatureClass = mCurrentLayer.FeatureClass; IWorkspace pWorkspace = (pFeatureClass as IDataset).Workspace; mWorkspaceEdit = pWorkspace as IWorkspaceEdit; if (mWorkspaceEdit == null) return; //开始编辑
if (!mWorkspaceEdit.IsBeingEdited()) {
mWorkspaceEdit.StartEditing(true); mIsEditing = true; } }
///
/// public void SaveEditing(bool save)
ArcGIS Engine高级功能开发
{
if (!save) {
mWorkspaceEdit.StopEditing(false); }
else if (save && mHasEditing && mIsEditing) {
mWorkspaceEdit.StopEditing(true); }
mHasEditing = false; }
///
///
this.SaveEditing(save); mIsEditing = false; }
下面添加鼠标与地图的交互事件,包括创建要素时鼠标的MouseDown事件、MouseMove事件和DoubleClick事件,移动要素时鼠标的PanMouseDown事件、MouseMove事件和MouseUp事件。
创建要素时首先在MouseDown事件中获取鼠标点击的点位,若图层为点图层,则直接创建要素,若为线图层或面图层,则作为第一个节点,以后每次点击都会添加一个节点,直到双击鼠标完成要素的创建。创建要素时的MouseDown事件在这里定义为CreateMouseDown。代码如下:
public void CreateMouseDown(double mapX, double mapY) {
//鼠标点击位置
IPoint pPoint = new PointClass(); pPoint.PutCoords(mapX, mapY);
INewLineFeedback pNewLineFeedback; INewPolygonFeedback pNewPolygonFeedback; //判断编辑状态 if (mIsEditing) {
//针对线和多边形,判断交互状态,第一次时要初始化,再次点击则直接添加节点 if(mDisplayFeedback==null) {
//根据图层类型创建不同要素
ArcGIS Engine高级功能开发
switch (mCurrentLayer.FeatureClass.ShapeType) {
case esriGeometryType.esriGeometryPoint: //添加点要素 AddFeature(pPoint); break;
case esriGeometryType.esriGeometryPolyline:
mDisplayFeedback = new NewLineFeedbackClass(); //获取当前屏幕显示
mDisplayFeedback.Display = ((IActiveView)this.mMap).ScreenDisplay; pNewLineFeedback = mDisplayFeedback as INewLineFeedback; //开始追踪
pNewLineFeedback.Start(pPoint); break;
case esriGeometryType.esriGeometryPolygon:
mDisplayFeedback = new NewPolygonFeedbackClass();
mDisplayFeedback.Display = ((IActiveView)this.mMap).ScreenDisplay; pNewPolygonFeedback = mDisplayFeedback as INewPolygonFeedback;
//开始追踪
pNewPolygonFeedback.Start(pPoint); break; } }
else //第一次之后的点击则添加节点 {
if (mDisplayFeedback is INewLineFeedback) {
pNewLineFeedback = mDisplayFeedback as INewLineFeedback; pNewLineFeedback.AddPoint(pPoint); }
else if (mDisplayFeedback is INewPolygonFeedback) {
pNewPolygonFeedback = mDisplayFeedback as INewPolygonFeedback; pNewPolygonFeedback.AddPoint(pPoint); } } } }
MouseMove事件在创建要素时和移动要素时可以共用,代码如下:
public void MouseMove(double mapX, double mapY)
ArcGIS Engine高级功能开发
{
if (mDisplayFeedback == null) return;
//获取鼠标移动点位,并移动至当前点位 IPoint pPoint = new PointClass(); pPoint.PutCoords(mapX, mapY); mDisplayFeedback.MoveTo(pPoint); }
创建要素时的DoubleClick事件代码如下:
public void CreateDoubleClick(double mapX, double mapY) {
if (mDisplayFeedback == null) return;
IGeometry pGeometry=null; IPoint pPoint = new PointClass(); pPoint.PutCoords(mapX, mapY);
INewLineFeedback pNewLineFeedback; INewPolygonFeedback pNewPolygonFeedback; IPointCollection pPointCollection; //判断编辑状态 if (mIsEditing) {
if (mDisplayFeedback is INewLineFeedback) {
pNewLineFeedback = mDisplayFeedback as INewLineFeedback; //添加点击点
pNewLineFeedback.AddPoint(pPoint); //结束Feedback
IPolyline pPolyline = pNewLineFeedback.Stop(); pPointCollection = pPolyline as IPointCollection; //至少两点时才创建线要素
if (pPointCollection.PointCount < 2)
MessageBox.Show(\至少需要两点才能建立线要素!\, \提示\); else
pGeometry = pPolyline as IGeometry; }
else if (mDisplayFeedback is INewPolygonFeedback) {
pNewPolygonFeedback = mDisplayFeedback as INewPolygonFeedback; //添加点击点
pNewPolygonFeedback.AddPoint(pPoint);