基于C#的ArcEngine二次开发46:编辑内容回撤与炸开multipart feature

目录

1 支持撤销操作

1.1 方法接口介绍

1.1.1 StartOperation()

1.1.2 StopOperation

1.2 代码实现

2 炸开复合要素(explode multipart feature)


绘制街道时,我们会对LRDL、VEGA、RESA、RESL和RESP中的要素进行操作,编辑完成后,改动的要素涉及多个图层,一旦出错,回撤功能将变得十分重要;同时,截取裁切LRDL面会产生许多复合要素(multipart feature),要求是不能产生复合要素。本文针对这两个问题,进行分析和探讨。

1 支持撤销操作

1.1 方法接口介绍

  • arcengine中使用StartOperation 和StopOperation,将编辑操作记录到ArcGIS引擎中

  • 每一个开始结束对之间的操作会被存储在一个操作栈中,点击undo时,会以整个操作栈的形式,执行撤销操作

  • 不能保存编辑或者停止编辑,否则会出错;

  • 在StopOperation之后,不能再在同一函数或按钮中,对刚才操作栈进行修改,否则调试不会出错;运行会崩

1.1.1 StartOperation()

[C#]public void StartOperation ();

Description

StartOperation marks the beginning of an edit operation. To provide undo/redo capability programmatically all edits must be performed within an edit operation. (标记编辑操作的开始,提供了以编程方式记录编辑操作中执行的所有编辑)

Calling IEngineEditor::StopOperation completes an edit operation which is then added to the top of the operation stack. The operation stack is how ArcGIS Engine implements Undo and Redo. When using StartOperation, proper error handling, including the use of IEgineEditor::AbortOperation, is neccessary.(调用StopOperation完成编辑操作,然后将其添加到操作堆栈的顶部。操作堆栈是ArcGIS引擎如何实现撤消和重做的。使用StartOperation时,必须进行正确的错误处理,包括使用IEEngineEditor:AbortOperation)

Edit operations cannot be nested; calling StartOperation within another operation will raise an error.(不能嵌套编辑操作,在另一个操作中调用StartOperation将引发错误)

Remarks

This method fires the IEngineEditEvents::OnStartOperation event.

(该方法将触发OnStartOperation事件)

1.1.2 StopOperation

[C#]public void StopOperation (
    stringoperationName);

Description

StopOperation marks the end of an edit operation. Calling StopOperation creates an edit operation that is added to the top of the operation stack. The operation stack is how ArcGIS Engine implements Undo and Redo.(StopOperation标记编辑操作的结束,调用该方法将在操作栈的顶部创建一个编辑操作,这也是ArcGIS引擎实现撤销和重做的操作栈)

When using IEngineEditor::StartOperation proper handling of errors, including the use of IEngineEditor::AbortOperation, is neccessary.(使用StartOperation 时,必须进行正确的错误处理,包括使用IEEngineEditor:AbortOperation)

The string argument allows the operation to be identified on the operaton stack.(不能嵌套编辑操作,在另一个操作中调用StartOperation将引发错误)

Remarks

This method fires the IEngineEditEvents::OnBeforeStopOperation and IEngineEditEvents::OnStopOperation events.

该方法将触发OnBeforeStopOperation 和OnStopOperation 事件

1.2 代码实现

public void supportUndo()
{
    UID editorUID= new UIDClass();
    editorUID.Value = "esriEditor.Editor";

    IMxApplication mxApplication = new ArcMap.ThisApplication;
    IApplication application = mxApplication as IApplication;
    IEidtor pEditor = application.FindExtensionByCLSID(editorID) as IEidtor;
    IEditorLayers pEditorLayer = pEditor as IEditorLayers;
    
    if(pEditor.EditState != esriEditState.esriStateEditing)
    {
        MessageBox("先打开编辑器");
        return;
    }
    IActiveView pActiveView = ArcMap.Document.FocusMap as IActiveView;
    pEditor.StartOperation();
    //-------------------------------------------------------
    // 绘制街区,标记删除点房,道路GB修改等操作
    //-------------------------------------------------------
    pEditor.StopOperation("Edit Finshed");
}

2 炸开复合要素(explode multipart feature)

关于这个问题,网上大多是ArcEngine判断要素(feature)是否为multipart feature及分解(炸开)代码文章的复制版本,但是有一个问题,他的代码中有一个变量GeometryHelper未明确说明,无法验证代码可行与否,所幸找到如下一篇文章

explode multiPart 炸开多部件(复杂对象)又称为多部分: https://blog.csdn.net/gishys/article/details/55100655

较好的解决了我的问题:

其思路为先将multipart feature包含的各个Geometry取出来,以创建要素的方式将其添加到图层中;之后再删除原multipart feature

public void ExplodeMultipart(IFeatureClass ExFeature)
        {
            IFeatureCursor mFeatureCursor = ExFeature.Update(null, false);
            IFeature mFeature = mFeatureCursor.NextFeature();
            IWorkspace del_workspace = (ExFeature as IDataset).Workspace;
            IWorkspaceEdit del_workspaceedit = del_workspace as IWorkspaceEdit;
            if (del_workspaceedit.IsBeingEdited() == true)
                del_workspaceedit.StopEditing(true);
            del_workspaceedit.StartEditing(false);
            del_workspaceedit.StartEditOperation();
            while (mFeature != null)
            {
                IGeometryCollection mGeometryCol = mFeature.ShapeCopy as IGeometryCollection;
                int mGeoCount = mGeometryCol.GeometryCount;
                int idRemark = -1;
                if (mGeoCount > 1)
                {
                    idRemark = int.Parse(mFeature.get_Value(0).ToString());
                    for (int index = 0; index < mGeoCount; index++)
                    {
                        IFeature mNewFeature =
                            (mFeature.Class as IFeatureClass).CreateFeature();
                        IFeatureEdit mFeatureEdit = mFeature as IFeatureEdit;
                        mFeatureEdit.SplitAttributes(mNewFeature);
                        IGeometry mGeoNew = mGeometryCol.get_Geometry(index);
                        mGeoNew.SpatialReference = mFeature.Shape.SpatialReference;
                        IGeometryCollection mGCollection = new PolygonClass();
                        mGCollection.AddGeometry(mGeoNew);
                        mNewFeature.Shape = mGCollection as IGeometry;
                        mNewFeature.Store();
                    }
                }
                if (idRemark != -1)
                {
                    mFeatureCursor.DeleteFeature();
                    idRemark = -1;
                }
                mFeature = mFeatureCursor.NextFeature();
            }
            del_workspaceedit.StopEditOperation();
            del_workspaceedit.StopEditing(true);
        }

关注作者欢迎关注公众号:

你可能感兴趣的:(基于C#的ArcEngine二次开发46:编辑内容回撤与炸开multipart feature)