1.97k likes | 1.98k Views
GIS 应用开发 Developing GIS Applications with ArcObjects using C#.NET 江西省研究生优质课程 主讲: 兰小机 GIS 博士、教授 Email : landcom8835@163.com QQ : 305333315 课程网站: http://gis.jxust.cn/gis. 兰小机简历. 主要经历 1988 年 7 月 毕业于南方冶金学院工程测量专业,获 学士学位 ,并留校任教 1994 年 6 月 毕业于武汉测绘科技大学工程测量专业,获 硕士学位 ,回校任教
E N D
GIS应用开发 • Developing GIS Applications with ArcObjects using C#.NET • 江西省研究生优质课程 • 主讲:兰小机 GIS博士、教授 • Email : landcom8835@163.com • QQ :305333315 • 课程网站: http://gis.jxust.cn/gis
兰小机简历 • 主要经历 • 1988年7月毕业于南方冶金学院工程测量专业,获学士学位,并留校任教 • 1994年6月毕业于武汉测绘科技大学工程测量专业,获硕士学位,回校任教 • 2005年6月毕业于南京师范大学地图学与地理信息系统专业,获理学博士学位,回校任教 • 主要研究方向 • GIS应用开发 • 分布式并行计算环境下空间数据的存储管理 • 空间数据库理论与GMLGIS • GML空间数据挖掘 • 空间数据集成与共享
科研项目 • 国家自然科学基金项目--面向GML的时空关联规则及序列模式挖掘研究(编号:40971234) ,35万元,主持 • 国家自然科学基金项目--本原GML空间数据库理论及GMLGIS与传统GIS集成研究(编号:40761017) ,16万元,主持 • 国家自然科学基金项目 -- GML空间数据存储索引机制研究(编号:40401045) ,26万元,排名第二 • 地理信息科学江苏省重点实验室开发基金项目 --面向对象的GML空间数据库及其应用研究(编号:JK20050302) ,5万元主持 • 江西省教育厅科技项目—GML空间数据库理论及GMLGIS研究,1万元,主持 • 萍乡市基础地理信息系统研究与开发,22万元,主持 • 城市公众地理信息服务系统研究与开发,10万元,主持
教学目标 • 《GIS应用开发》课程是GIS研究生重要的专业课程,通过课程的学习,了解ArcGIS 软件体系结构及ArcObjects(ArcGISEngine)组件构成,并能熟练使用ArcObjects (ArcGISEngine)进行应用型GIS开发; 掌握应用型GIS开发的基本思路、技术方法.
Chap.10 空间数据编辑 (6学时) • ArcGIS Engine编辑概述 • 版本化空间数据编辑 • DisplayFeedback对象 • 多边形挖空处理 • 分割线要素 • 线、面要素整形(Reshape) • 要素合并 • 多部分要素的处理 • 线要素的延伸与修剪
10.1 Overview of ArcGIS Engine editing • ArcGIS Engine 编辑与ArcMap编辑 • 编辑流程 • 编辑目标图层(Editing target layer) • 编辑任务(Edit tasks) • 编辑绘制(Edit sketch) • 使用操作栈(Working with the operation stack) • 使用捕捉环境 • 编辑事件 • 要素查看器(Feature inspectors) • 使用要素模板
10.1.1ArcGIS Engine 编辑与ArcMap编辑 • ArcGIS桌面的编辑功能通过Editor库发布,ArcGIS Engine 的编辑功能包含在Controls库中. • ArcGIS EngineControls库中提供了内置的编辑命令、工具、菜单等,用于地理要素的复制、剪切、粘贴和删除、启动编辑、停止编辑、保存编辑、编辑工具(Edit Tool)、绘制工具(Sketch Tool)、编辑的目标图层ToolControl、属性编辑、要素编辑过程中右键菜单功能和Snapping设置等功能。 这些命令、工具等在开发过程中可以直接使用。
在ArcGIS 桌面环境中的主要编辑对象是Editor ,而在ArcGIS Engine开发中则是EngineEditor (单实例对象) ;在相应的应用程序中,它们负责管理编辑绘制(edit sketch)、当前任务(current task)、当前目标图层(current target layer)、编辑工作空间(edit workspace)、编辑选择(edit selection)、编辑会话属性(edit session properties)以及捕捉环境(snap environment)。 • EngineEditor主要接口有:IEngineEditor、IEngineEditLayers、IEngineEditProperties、IEngineEditProperties2、IEngineEditSketch、IEngineSnapEnvironment、 IEngineEditEvents 、IExtension (System).
表10-1 ArcGIS Engine与ArcGIS Desktop编辑的主要接口比较
IEngineEditSketch IEngineEditor IEngineEditLayers
IEngineEditProperties IEngineEditProperties2
IEngineEditTask ( new at ArcGIS 9.3 ) • 编辑任务使用编辑绘制几何对象(from IEngineEditSketch.Geometry )完成某项操作; EngineEditor 一次只能有一个活动的编辑任务,使用IEngineEditor.CurrentTask设置当前的编辑任务. • 所有的 Engine 编辑任务都实现了IEngineEditTask接口. Engine 编辑任务必须注册到‘ESRI Engine Edit Tasks’组件类目中,以便显示在ControlsEditingTaskToolControl中 .
10.1.2 编辑流程 • 编辑会话(Edit session ) • 建议所有的编辑操作应该一个编辑会话中完成,当应用程序使用插入游标或更新游标进行批导入或批更新要素除外。 • 一个编辑会话中可以包含多个编辑(Edit operation)和绘制操作(Sketch operation)。 • 编辑操作用于创建、修改或删除要素,而绘制操作用于修改编辑绘制(edit sketch)。 • 编辑与绘制操作可以看作是嵌套在编辑会话对应的长事务中的一系列短事务。
通过把每个操作加入操作栈,实现编辑会话中的 undo /redo 功能。一旦编辑会话完成,所有操作都从操作栈删除。 • 加入到操作栈的绘制操作是暂时的,绘制完成后,一系列的绘制操作将被一个编辑操作取代,编辑会话结束后,操作栈将被清空。 • 使用IEngineEditor(Controls库)和IWorkspaceEdit(Geodatabase库)均可创建编辑会话。 • 在不需要用户交互自动完成空间数据编辑功能的应用程序中,应使用IWorkspaceEdit;反之,在需要用户交互才能完成空间数据编辑的应用程序中,则使用IEngineEditor。
IEngineEditor 启动编辑会话 • 使用IEngineEditor.StartEditing方法启动编辑会话,该方法有一个IMap类型和一个IWorkspace类型的参数。 • 所有来自同一工作空间且处于地图中的可编辑图层均可在编辑会话中进行编辑; IEngineEditLayers.IsEditable属性可以检测某图层是否可以编辑;在SDE工作空间中, IEngineEditor.EditSessionMode可以指定编辑会话的模式(版本化或非版本化编辑),versioned和non-versioned图层不能同时在一个编辑会话中编辑。
启动编辑会话: private IEngineEditor m_engineEditor = new EngineEditorClass(); private void StartEditing (IMap map, IFeatureLayer featureLayer) { if (m_engineEditor.EditState != esriEngineEditState.esriEngineStateNotEditing) return; IDataset dataset = featureLayer.FeatureClass as IDataset; IWorkspace workspace = dataset.Workspace; m_engineEditor.StartEditing(workspace, map); ((IEngineEditLayers) m_engineEditor).SetTargetLayer(featureLayer, -1); } public void SetTargetLayer ( IFeatureLayerLayer,intSubType );
执行编辑操作 • IEngineEditor接口提供了一系列方法用于编辑操作,如StartOperation 、AbortOperation 及StopOperation。 • IEngineEditor.StartOperation --启动编辑操作 • public void StartOperation ( ); • IEngineEditor.AbortOperation --取消编辑操作,不保存编辑 • public void AbortOperation ( ); • IEngineEditor.StopOperation --结束编辑操作 • public void StopOperation ( string operationName ); • operationNameallows the operation to be identified on the operaton stack.
private void cmdEditOperation() { m_engineEditor.StartOperation(); try { //Perform feature edits here. if (someEditValidationChecksMethod == true) m_engineEditor.StopOperation(“Test edit operation”); elsem_engineEditor.AbortOperation(); } catch (Exception ex) { m_engineEditor.AbortOperation(); //Add code to handle exception. } }
保存编辑结束编辑会话 • 通过执行ControlsEditingSaveCommand命令,可以保存编辑会话中的编辑变化;也可以调用IEngineEditor.StopEditing(saveChanges参数设置为true)方法保存编辑变化,该方法的语法如下: public void StopEditing ( bool saveChanges ); • 若saveChanges参数为false,则不保存编辑变化结束编辑会话。
private void btnStopEditing_Click(object sender, EventArgs e) { if (m_engineEditor.HasEdits() == false) m_engineEditor.StopEditing(false); else { if (MessageBox.Show("Save Edits?", "Save Prompt", MessageBoxButtons.YesNo) == DialogResult.Yes) m_engineEditor.StopEditing(true); else m_engineEditor.StopEditing(false); } }
IWorkspaceEdit接口 • IWorkspaceEdit接口是ArcObjects实现空间数据编辑功能的另一接口. • 它可以启动或停止一个编辑流程,适用于不需要用户交互的编辑操作。 • 使用StartEditing方法启动一个编辑流程 • public void StartEditing (bool withUndoRedo ); • withUndoRedo参数用来确定是否支持“undo /redo ”功能。
在启动编辑后,可以使用StartEditOperation方法开启编辑操作。在启动编辑后,可以使用StartEditOperation方法开启编辑操作。 • public void StartEditOperation ( ); • 如果在编辑过程中出现了异常,可以使用AbortEditoperation方法来取消编辑操作。public void AbortEditOperation ( ); • 在完成一个编辑后,用户可以使用StopEditoperation方法来确保编辑操作的完成。 • public void StopEditOperation ( ); • UndoEditoperation方法可以用于编辑状态的回滚操作,如果发现编辑过程有误,通过执行这个方法可以恢复到最近变化前的状态。 • 在整个编辑流程完成后,可以使用StopEditing方法来完成编辑。当执行完这个方法后,就意味着不能再进行“恢复/取消恢复”了。 • public void StopEditing ( bool saveEdits );
private void StartEditing(IFeatureLayer featureLayer) { IFeatureClass featureClass = featureLayer.FeatureClass; IDataset dataset = featureClass as IDataset; IWorkspaceEdit workspaceEdit = dataset.Workspace as IWorkspaceEdit; workspaceEdit.StartEditing(true); workspaceEdit.StartEditOperation(); IFeature pFeature = featureClass.GetFeature(1); pFeature.Delete(); workspaceEdit.StopEditOperation(); bool bHasEdits = true;
DialogResult iResponse = MessageBox.Show("Edit Operation", "Undo operation?", MessageBoxButtons.YesNo); if (iResponse == DialogResult.Yes) workspaceEdit.UndoEditOperation(); workspaceEdit.HasEdits(ref bHasEdits); if (bHasEdits) { iResponse = MessageBox.Show("Edit Operation", "Save edits?", MessageBoxButtons.YesNo); if (iResponse == DialogResult.Yes) { workspaceEdit.StopEditing(true); } else { workspaceEdit.StopEditing(false); } }}
IEngineEditLayers 10.1.3 编辑目标图层 • 使用IEngineEditLayers.SetTargetLayer或ControlsEditingTargetToolControl设置要编辑的目标图层。 • 使用IEngineEditLayers.TargetLayer获得目前编辑的图层。 • 使用IEngineEditEvents.OnTargetLayerChanged事件来监听编辑目标图层的变化。
10.1.4 编辑任务 • 编辑任务使用编辑绘制中的几何对象(IEngineEditSketch.Geometry)完成某一特定的编辑操作;EngineEditor一次只能有一个活动的编辑任务,使用 IEngineEditor.CurrentTask设置当前的编辑任务。所有的 Engine编辑任务都实现了IEngineEditTask接口。Engine编辑任务必须注册到“ESRI Engine Edit Tasks”组件类目中,以便显示在 ControlsEditingTaskToolControl中。 • EngineEditor提供了两个内置的编辑任务:Create New Feature和Modify Feature.
可以通过实现IEngineEditTask接口创建自定义的编辑任务。IEngineEditTask.GroupName属性允许编辑任务在ControlsEditingTaskToolControl 中逻辑分组。使用IEngineEditEvents.OnCurrentTaskChanged事件监听编辑任务的改变。 • 使用ArcGIS添加类向导(ArcGIS Add Class Wizard)来快速创建实现IEngineEditTask接口的类,创建定制的编辑任务.
Samples: • EditingCutPolygonsEditTask • EditingReshapePolylineEditTask
IEngineEditSketch 10.1.5 编辑绘制 - Edit sketch • IEngineEditSketch中的geometry 用于完成当前的编辑任务,如当前编辑任务为“Create New Feature”时,使用该geometry来创建一个要素;geometry 由当前编辑任务设置,其类型可以是: a multipoint, a polyline, or a polygon , 与目标编辑图层的几何类型相同。
AE提供了2个快捷菜单帮助完成edit sketch geometry. • ControlsEditingSketchContextMenu • ControlsEditingVertexContextMenu
Creating a sketch operation • IEngineSketchOperation.Start启动一绘制操作(sketch operation),使用IEngineSketchOperation.SetMenuString方法命名该操作,以便操作栈( operation stack )能够识别该操作,并用作Undo / Redo 的ToolTip . • IEngineSketchOperation.Finish结束一绘制操作,并将该操作放入操作栈中。
public void Start (IEngineEditoreditor ); • public void SetMenuString (stringMenuString ); • public void Finish( IEnvelopeinvalEnv,esriEngineSketchOperationTypeopType,objectData );
private void EngineSketchOperation() { IEngineSketchOperation sketchOp = new EngineSketchOperationClass(); IEngineEditor engineEditor = new EngineEditorClass(); IEngineEditSketch editSketch = (IEngineEditSketch) engineEditor; IEnvelope invalidateEnv = ((IClone)editSketch.Geometry.Envelope).Clone() as IEnvelope; sketchOp.Start(engineEditor); sketchOp.SetMenuString("Delete Vertex"); IPointCollection pointCol = (IPointCollection) editSketch.Geometry; IClone vertexToRemove = (IClone)pointCol.get_Point(pointCol.PointCount - 1); vertexToRemove.Clone(); pointCol.RemovePoints(pointCol.PointCount - 1, 1); editSketch.Geometry = (IGeometry) pointCol; editSketch.RefreshSketch(); sketchOp.Finish( invalidateEnv, esriEngineSketchOperationType.esriEngineSketchOperationVertexDeleted, vertexToRemove as System.Object); }
对于单个绘制操作,使用IEngineSketchOperation.Undo和Redo来实现撤销和重做;对于单个绘制操作,使用IEngineSketchOperation.Undo和Redo来实现撤销和重做; • IEngineSketchOperation.Undo (derived from IOperationStack.Undo) • IEngineSketchOperation.Redo (derived from IOperationStack.Redo) • 对于多个绘制操作,则需要先使用IToolbarControl2.OperationStack访问操作栈,然后再使用IOperationStack.Undo或IOperationStack.Redo来实现撤销和重做。 • 绘制操作的事件: • IEngineEditEvents.OnVertexAdded • IEngineEditEvents.OnVertexDeleted • IEngineEditEvents.OnVertexMoved • IEngineEditEvents.OnSketchModified
10.1.6 使用操作栈 • 由EngineEditor管理的编辑会话,如果需要undo / redo功能,那么应用程序中必须包含ToolbarControl. • IToolbarControl.OperationStack属性提供了对操作栈的访问。IOperationStack.Undo和IOperationStack.Redo方法则分别用于撤销和重复操作。
将编辑和绘制操作添加至操作栈的步骤: • 在应用程序中添加ToolbarControl ,并设置其伙伴控件; • 实例化ControlsOperationStack,并将其与ToolbarControl相关联; • 连接EngineEditor 到ToolbarControl ,使得操作栈包含编辑与绘制操作;可以有2种方式实现该功能: • 将一编辑命令添加到ToolbarControl上; • 在Form_Load 事件中,通过编程连接EngineEditor 与ToolbarControl • 启动编辑会话,并设置IEngineEditor.EnableUndoRedo为true,使编辑会话具有undo/redo功能。
2: IOperationStack operationStack = new ControlsOperationStackClass(); axToolbarControl1.OperationStack = operationStack; axToolbarControl2.OperationStack = operationStack; 3: (a)直接将编辑命令添加到ToolbarControl上 (b)连接EngineEditor 与ToolbarControl object tbr = (object)axToolbarControl1.Object; IExtension engineEditorExt = m_engineEditor as IExtension; engineEditorExt.Startup(ref tbr);
调用IEngineEditor.StopOperation方法后编辑操作便被加入到操作栈中,而调用IEngineSketchOperation.Finish方法后绘制操作便被加入到操作栈中。撤销和重做并不会将操作从操作栈中移除,只是将一指针在栈中上下移动。调用IEngineEditor.StopOperation方法后编辑操作便被加入到操作栈中,而调用IEngineSketchOperation.Finish方法后绘制操作便被加入到操作栈中。撤销和重做并不会将操作从操作栈中移除,只是将一指针在栈中上下移动。