Editing with the geodatabase API

本文详细介绍了如何利用地理数据库编辑会话与操作来管理数据库事务,包括分组编辑为原子事务、错误回滚、批量更新等优势。重点阐述了在ArcSDE地理数据库中如何启动和停止编辑会话与操作,以及在不同编辑模式下(如版本化编辑和非版本化编辑)的操作步骤和最佳实践。文章还提供了在编辑过程中遇到特定问题(如版本定义重定义)时的处理策略,并讨论了在不同版本之间编辑的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Applications can use geodatabase edit sessions and operations to manage database transactions. Edit sessions and operations provide the following benefits:
  • Grouping edits into atomic transactions. If an error occurs before all edits are completed, the transaction can be rolled back.
  • Optional edit operation undo and redo stacks maintained by the geodatabase. After an edit operation is stopped, it is placed on the undo stack. Application developers can traverse the undo/redo stack by calling UndoEditOperation and RedoEditOperation.
  • Edit sessions and edit operations allow batched updates to occur, offering significant performance advantages when editing ArcSDE geodatabases.
  • In geodatabases that allow multiple users to edit concurrently, an application in an edit session will not recognize changes made by other applications until the session is complete.
  • The geodatabase guarantees unique instancing of row objects retrieved from the database within an edit session. Any data access call that retrieves a non-recycled object returns an in-memory instance of the object if the object has been previously instantiated in the edit session.

Starting and stopping edit sessions and operations

The  IWorkspaceEdit and IWorkspaceEdit2 interfaces can be used to start and stop edit sessions and edit operations. These interfaces are implemented by file, personal, and ArcSDE geodatabases. The IMultiuserWorkspaceEdit interface is implemented only by ArcSDE geodatabases, and can be used to start an edit session in either versioned or non-versioned editing mode (however, stopping the edit session and controlling operations must still be performed through IWorkspaceEdit).
public void CreateRowInEditSession(IWorkspace workspace, ITable table)
{
    // Cast the workspace to the IWorkspaceEdit interface.
    IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)workspace;

    // Start an edit session. An undo/redo stack isn't necessary in this case.
    workspaceEdit.StartEditing(false);

    // Start an edit operation.
    workspaceEdit.StartEditOperation();

    // Create a row. The row's attribute values should be set here and if
    // a feature is being created, the shape should be set as well.
    IRow row = table.CreateRow();
    row.Store();

    // Save the edit operation. To cancel an edit operation, the AbortEditOperation
    // method can be used.
    workspaceEdit.StopEditOperation();

    // Stop the edit session. The saveEdits parameter indicates the edit session
    // will be committed.
    workspaceEdit.StopEditing(true);
}



Versioned editing in ArcSDE geodatabases

public void EditWithReconcile(IWorkspace workspace, ITable table)
{
    // Cast the workspace to the IMultiuserWorkspaceEdit and IWorkspaceEdit2 interfaces.
    IMultiuserWorkspaceEdit muWorkspaceEdit = (IMultiuserWorkspaceEdit)workspace;
    IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)workspace;

    // Start a versioned edit session and an edit operation.
    muWorkspaceEdit.StartMultiuserEditing
        (esriMultiuserEditSessionMode.esriMESMVersioned);
    workspaceEdit.StartEditOperation();

    // Perform edits here...
    IRow row = table.CreateRow();
    row.Store();

    // Save the edit operation. To cancel an edit operation, the AbortEditOperation
    // method can be used.
    workspaceEdit.StopEditOperation();
    try
    {
        // Stop the edit session. The saveEdits parameter indicates the edit session
        // will be committed.
        workspaceEdit.StopEditing(true);
    }
    catch (COMException comExc)
    {
        if (comExc.ErrorCode == (int)fdoError.FDO_E_VERSION_REDEFINED)
        {
            // Get the version name.
            IVersion version = (IVersion)workspace;
            String versionName = version.VersionName;

            // Reconcile the version. Modify this code to reconcile and handle conflicts
            // appropriately for the specific application.
            IVersionEdit4 versionEdit4 = (IVersionEdit4)workspace;
            versionEdit4.Reconcile4(versionName, true, false, true, true);

            // Stop the edit session.
            workspaceEdit.StopEditing(true);
        }
        else
        {
            // A different error has occurred. Handle appropriately for the application.
            workspaceEdit.StopEditing(false);
        }
    }
}

Non-versioned editing in ArcSDE geodatabases

public void CreateRowInNonVersionedEditSession(IWorkspace workspace, ITable table)
{
    // Cast the workspace to the IWorkspaceEdit2 and IMultiuserWorkspaceEdit interfaces.
    IWorkspaceEdit2 workspaceEdit2 = (IWorkspaceEdit2)workspace;
    IMultiuserWorkspaceEdit muWorkspaceEdit = (IMultiuserWorkspaceEdit)workspace;

    // Make sure that non-versioned editing is supported. If not, throw an exception.
    if (!muWorkspaceEdit.SupportsMultiuserEditSessionMode
        (esriMultiuserEditSessionMode.esriMESMNonVersioned))
    {
        throw new ArgumentException(
            "The workspace does not support non-versioned editing.");
    }

    // Start a non-versioned edit session.
    muWorkspaceEdit.StartMultiuserEditing
        (esriMultiuserEditSessionMode.esriMESMNonVersioned);

    // Create a row. The row's attribute values should be set here, and if
    // a feature is being created, the shape should be set as well.
    IRow row = table.CreateRow();
    row.Store();

    // Stop the edit session. The saveEdits parameter indicates the edit session
    // will be committed.
    workspaceEdit2.StopEditing(true);
}


Best practices

The following are best practices when editing in the geodatabase.
public void SafelyCreateRowInEditSession(IWorkspace workspace, ITable table)
{
    // Cast the workspace to the IWorkspaceEdit2 interface.
    IWorkspaceEdit2 workspaceEdit2 = (IWorkspaceEdit2)workspace;

    try
    {
        // Start an edit session and operation.
        workspaceEdit2.StartEditing(false);
        workspaceEdit2.StartEditOperation();

        // Create a row. The row's attribute values should be set here, and if
        // a feature is being created, the shape should be set as well.
        IRow row = table.CreateRow();
        row.Store();

        // Save the edit operation and session.
        workspaceEdit2.StopEditOperation();
        workspaceEdit2.StopEditing(true);
    }
    catch (COMException comExc)
    {
        // To handle the error depending on its severity, use a switch statement
        // to check its error code.
        switch (comExc.ErrorCode)
        {
            case ((int)fdoError.FDO_E_NOT_EDITABLE_EDITSESSIONMODE): 
            // For example...
            break;
            default:
                // Handle appropriately.
                break;
        }
    }
    catch (Exception exc)
    {
        // Handle exceptions other than Component Object Model (COM) exceptions. 
        //  For example, if there is a possibility of a NotImplementedException being thrown.
    }
    finally
    {
        // If an exception was raised, make sure the edit operation and
        // edit session are discarded.
        try
        {
            if (workspaceEdit2.IsInEditOperation)
            {
                workspaceEdit2.AbortEditOperation();
            }
            if (workspaceEdit2.IsBeingEdited())
            {
                workspaceEdit2.StopEditing(false);
            }
        }
        catch (Exception exc)
        {
            // Log or ignore errors that occur at this point.
        }
    }
}


Connecting to one version and editing another

public void EditDifferentVersion(IWorkspace workspace)
{
    // Cast the workspace to the IVersionedWorkspace interface and get
    // the QA version.
    IVersionedWorkspace versionedWorkspace = (IVersionedWorkspace)workspace;
    IVersion qaVersion = versionedWorkspace.FindVersion("QA");

    // Start an edit session on the QA version.
    IMultiuserWorkspaceEdit muWorkspaceEdit = (IMultiuserWorkspaceEdit)qaVersion;
    IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)qaVersion;
    muWorkspaceEdit.StartMultiuserEditing
        (esriMultiuserEditSessionMode.esriMESMVersioned);

    // Perform any edits in edit operations here...

    // Stop the edit session.
    workspaceEdit.StopEditing(true);
}



<think>我们正在讨论如何在ArcGIS中向属性表添加数据。根据用户的问题,他/她想知道如何向属性表的属性表中添加数据。在ArcGIS中,属性表是存储地理要素属性信息的表格,用户可以通过多种方式向其中添加数据。 根据引用[2]中提到的方法,我们可以通过FeatureTable来操作属性数据。在ArcGIS中,FeatureLayer对应的数据源是FeatureTable,因此我们可以通过操作FeatureTable来修改属性表。 具体步骤如下: 1. **打开属性表**:在ArcMap或ArcGIS Pro中,右键单击图层,选择“打开属性表”。 2. **添加字段**:在属性表窗口中,点击“表选项”按钮(在ArcMap中是一个小图标,在ArcGIS Pro中可能位于功能区),然后选择“添加字段”。输入字段名称、类型(如文本、数字、日期等)和字段属性(如长度)。 3. **编辑数据**:在开始编辑之前,需要启动编辑会话。在ArcMap中,点击“编辑器”工具栏上的“开始编辑”按钮。在ArcGIS Pro中,切换到“编辑”选项卡,点击“开始编辑”。 4. **输入数据**:在属性表中,找到新添加的字段,单击单元格并输入数据。也可以使用字段计算器批量计算字段值。 5. **保存编辑**:编辑完成后,保存编辑并停止编辑会话。 此外,还可以通过编程方式(如使用ArcPy或ArcGIS API for Android)来添加数据。例如,在ArcGIS API for Android中,可以通过FeatureTable的updateFeatureAsync方法来更新要素属性(即向属性表添加数据)。 下面是一个使用ArcPy在ArcGIS Desktop中添加字段并计算字段值的示例代码: ```python import arcpy # 设置工作空间 arcpy.env.workspace = "C:/data" # 要添加字段的要素类 fc = "roads.shp" # 添加一个名为"NEW_FIELD"的文本字段,长度为50 arcpy.AddField_management(fc, "NEW_FIELD", "TEXT", field_length=50) # 开始编辑会话 edit = arcpy.da.Editor(arcpy.env.workspace) edit.startEditing(False, True) edit.startOperation() # 使用更新游标更新新字段的值 with arcpy.da.UpdateCursor(fc, ["NEW_FIELD"]) as cursor: for row in cursor: # 设置字段值,这里设置为一个示例值 row[0] = "Example Value" cursor.updateRow(row) # 停止操作和编辑会话 edit.stopOperation() edit.stopEditing(True) ``` 在移动应用开发中,如使用ArcGIS for Android,可以通过以下步骤向属性表添加数据: 1. 获取FeatureTable的引用。 2. 创建一个新的Feature(要素),设置其几何和属性。 3. 使用FeatureTable的addFeatureAsync方法添加要素。 示例代码(Android): ```java // 假设featureTable是一个ServiceFeatureTable或GeodatabaseFeatureTable实例 Feature feature = featureTable.createFeature(); // 设置几何 Point point = new Point(-100, 40, SpatialReferences.getWgs84()); feature.setGeometry(point); // 设置属性 Map<String, Object> attributes = new HashMap<>(); attributes.put("FIELD_NAME", "New Value"); feature.setAttributes(attributes); // 添加要素并监听结果 ListenableFuture<Void> addFuture = featureTable.addFeatureAsync(feature); addFuture.addDoneListener(() -> { try { addFuture.get(); // 等待完成 // 提交更改到服务(如果使用ServiceFeatureTable) if (featureTable instanceof ServiceFeatureTable) { ServiceFeatureTable serviceTable = (ServiceFeatureTable) featureTable; ListenableFuture<List<FeatureTableEditResult>> applyFuture = serviceTable.applyEditsAsync(); applyFuture.addDoneListener(() -> { // 处理提交结果 }); } } catch (Exception e) { e.printStackTrace(); } }); ``` 以上方法适用于不同的ArcGIS平台和开发环境。 §§相关问题§§ 1. 如何在ArcGIS中批量更新属性表中的数据? 2. 使用ArcPy进行属性表操作有哪些常见方法? 3. 在ArcGIS for Android中如何编辑要素的属性?</think>### 如何在ArcGIS中向属性表添加数据 在ArcGIS中向属性表添加数据主要有两种方式:**添加新字段**和**编辑现有字段值**。以下是详细操作步骤: #### 一、添加新字段 1. **打开属性表** - 在内容列表(Table of Contents)中右键单击目标图层 - 选择"打开属性表"(Open Attribute Table) 2. **添加字段** - 点击属性表左上角的"表选项"按钮(Table Options) - 选择"添加字段"(Add Field) - 在弹出的对话框中: - 输入字段名称(如"人口密度") - 选择字段类型(文本/整型/浮点型/日期等) - 设置字段属性(如文本长度、精度等) - 点击"确定"保存 3. **批量计算字段值** - 右键单击新字段的列标题 - 选择"字段计算器"(Field Calculator) - 在表达式框中输入计算公式(如`[人口]/[面积]`) - 点击"确定"执行批量计算 #### 二、编辑现有字段值 1. **启动编辑会话** - 在编辑器工具栏(Editor Toolbar)点击"开始编辑"(Start Editing) - 选择要编辑的工作空间 2. **手动编辑单元格** - 在属性表中定位到目标单元格 - 双击单元格直接输入新值 - 按Enter键保存更改 3. **使用字段计算器** - 适用于批量更新(如将空值设为0): ```python # 示例:将空值替换为0 def calc_value(!字段名!): return 0 if !字段名! is None else !字段名! ``` #### 三、编程方式添加数据(Python示例) 使用ArcPy库批量添加字段和计算值: ```python import arcpy # 设置工作空间 arcpy.env.workspace = "C:/data/geodatabase.gdb" # 添加新字段 arcpy.AddField_management("roads", "ROAD_TYPE", "TEXT", field_length=20) # 批量计算字段值(根据条件赋值) arcpy.CalculateField_management( "roads", "ROAD_TYPE", "classify(!SPEED_LIMIT!)", # 自定义分类函数 "PYTHON3", """def classify(speed): return '高速' if speed > 80 else '普通'""" ) ``` > **重要提示**: > 1. 编辑前请备份数据 > 2. 编辑完成后点击"保存编辑"(Save Edits) > 3. 停止编辑会话释放锁定的数据 > 4. 字段名不能包含特殊字符(如空格、@、#等) #### 四、移动端开发(Android示例) 通过ArcGIS Runtime API更新属性[^2]: ```java // 获取要素和属性表 Feature feature = featureLayer.getFeature(102); FeatureTable featureTable = feature.getFeatureTable(); // 创建新属性键值对 Map<String, Object> attributes = new HashMap<>(); attributes.put("新增字段", "值"); // 更新要素属性 feature.setAttributes(attributes); ListenableFuture<Void> updateFuture = featureTable.updateFeatureAsync(feature); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值