Files
sunvpy-docs/docs/content/22-shan-chu-dui-xiang-cao-zuo.md
2026-04-10 13:47:53 +08:00

16 KiB

本文档详细说明如何在 SunvStation 系统中删除地理对象。删除操作是地理数据维护的重要环节,包括删除当前新建对象、批量删除多个对象以及与选择集结合的删除场景。掌握删除操作的机制和使用方法,能够帮助开发者有效管理地图数据,确保数据的准确性和一致性。

建议在学习本页面之前,先了解 创建默认地物对象添加对象坐标点。完成本页面学习后,可以继续学习 对象缓存机制批量保存到数据库

Sources: ssprocess_mixins/geo_edit_mixin.py

删除操作概述

SunvStation 提供了两种主要的删除方式:单对象删除和批量删除。单对象删除主要用于删除当前正在创建的对象,而批量删除则适用于处理多个已存在的地理对象。

删除方式 方法名称 适用场景 操作时机
单对象删除 deleteNewObj 删除当前新建对象 对象创建后、保存前
批量删除 delBufferGeoList + saveBufferObjToDatabase 删除多个对象 对象已添加到删除缓冲区后

删除操作的核心机制基于 delBufferGeoList 缓冲区,该缓冲区存储待删除的地理对象。当调用 saveBufferObjToDatabase() 方法时,系统会自动处理这些删除操作。

Sources: PySSProcess.py ssprocess_mixins/geo_edit_mixin.py

deleteNewObj 方法详解

deleteNewObj 方法用于删除当前新建的地理对象。这是一个即时的删除操作,不需要保存到数据库即可生效。

方法签名

def deleteNewObj(self):

功能说明

该方法执行以下操作:

  1. 检查当前是否有新建对象(self.curNewObj 不为空)
  2. 如果存在新建对象,调用地图的 delGeoObject 方法删除该对象
  3. self.curNewObj 重置为 (None, None),表示当前没有新建对象

特点

  • 无需参数:该方法不接受任何参数
  • 无返回值:不返回任何结果,仅执行删除操作
  • 即时生效:删除操作立即执行,无需等待数据库保存
  • 仅限新建对象:只能删除通过创建方法生成的当前对象

Sources: ssprocess_mixins/geo_edit_mixin.py

删除新建对象的工作流程

删除当前新建对象是一个简单直接的操作,但需要了解其在整个对象生命周期中的位置。

flowchart TD
    A[开始] --> B[创建新对象<br/>createNewObjByCode]
    B --> C{是否需要保留?}
    C -->|是| D[添加坐标点<br/>addNewObjPoint]
    D --> E[添加到保存列表<br/>addNewObjToSaveObjList]
    E --> F[保存到数据库<br/>saveBufferObjToDatabase]
    F --> G[对象持久化成功]
    C -->|否| H[删除对象<br/>deleteNewObj]
    H --> I[curNewObj 重置为 None]
    I --> J[对象从内存中移除]
    J --> K[结束]
    G --> K

Sources: ssprocess_mixins/geo_edit_mixin.py

使用场景与示例

场景 1: 取消创建过程中的对象

在创建对象的过程中,如果发现对象不符合要求或需要中止创建,可以使用 deleteNewObj 方法取消。

# 尝试创建一个线对象
obj, geo = SSProcess.createNewObjByCode(2001)
if obj and geo:
    # 添加第一个坐标点
    SSProcess.addNewObjPoint(100.0, 200.0, 0.0, 0, "起点")
    
    # 发现该线对象不符合要求,决定删除
    SSProcess.deleteNewObj()
    print("新创建的线对象已被删除")
    
    # 重新创建符合要求的对象
    obj, geo = SSProcess.createNewObjByCode(2002)
    if obj and geo:
        SSProcess.addNewObjPoint(150.0, 250.0, 0.0, 0, "新起点")

Sources: ssprocess_mixins/geo_edit_mixin.py

场景 2: 条件判断后删除

根据业务逻辑判断是否需要保留新建的对象。

# 创建点对象
obj, geo = SSProcess.createNewObjByCode(1001)
if obj and geo:
    SSProcess.addNewObjPoint(123456.789, 3456789.012, 45.5, 0, "控制点")
    
    # 检查点是否在允许范围内
    x = geo.getPoint(0).x()
    if x < 100000 or x > 200000:
        print(f"坐标 X={x} 超出允许范围,删除对象")
        SSProcess.deleteNewObj()
    else:
        # 保存有效的对象
        SSProcess.addNewObjToSaveObjList()
        SSProcess.saveBufferObjToDatabase()
        print("对象已成功保存")

Sources: ssprocess_mixins/geo_edit_mixin.py

场景 3: 异常处理中的清理

在创建对象过程中发生异常时,确保清理已创建的对象。

try:
    # 创建面对象
    obj, geo = SSProcess.createNewObjByCode(3001)
    if obj and geo:
        # 尝试添加坐标点
        corners = [
            (100.0, 200.0, 0.0),
            (150.0, 200.0, 0.0),
            (150.0, 250.0, 0.0),
            (100.0, 250.0, 0.0)
        ]
        
        for x, y, z in corners:
            if x <= 0 or y <= 0:
                raise ValueError(f"无效的坐标: ({x}, {y})")
            SSProcess.addNewObjPoint(x, y, z, 0, f"点{len(corners)}")
        
        # 如果一切正常,保存对象
        SSProcess.addNewObjToSaveObjList()
        SSProcess.saveBufferObjToDatabase()
        
except ValueError as e:
    print(f"发生错误: {e}")
    # 清理已创建但未保存的对象
    SSProcess.deleteNewObj()
    print("已清理无效对象")

Sources: ssprocess_mixins/geo_edit_mixin.py

批量删除机制

批量删除通过 delBufferGeoList 删除缓冲区实现。该缓冲区是一个 GeoBaseList 类型的对象,存储待删除的地理对象。

批量删除的工作原理

flowchart LR
    A[待删除对象] --> B[添加到 delBufferGeoList]
    C[待删除对象2] --> B
    D[待删除对象3] --> B
    B --> E[调用 saveBufferObjToDatabase]
    E --> F[执行 map.delGeoBaseComponent]
    F --> G[从地图中移除对象]
    G --> H[清空 delBufferGeoList]

Sources: ssprocess_mixins/geo_edit_mixin.py

批量删除的实现

批量删除的核心逻辑在 saveBufferObjToDatabase 方法中实现:

# 删除缓存列表中的对象
self.map.delGeoBaseComponent(self.delBufferGeoList)
self.delBufferGeoList.clear()

该代码段执行以下操作:

  1. 调用地图的 delGeoBaseComponent 方法,传入 delBufferGeoList
  2. 系统批量删除列表中的所有对象
  3. 清空 delBufferGeoList,为下次操作做准备

Sources: ssprocess_mixins/geo_edit_mixin.py

批量删除示例

示例 1: 基于选择集的批量删除

删除选择集中符合特定条件的所有对象。

# 1. 设置选择条件
SSProcess.clearSelection()
SSProcess.clearSelectCondition()
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")

# 2. 执行查询
SSProcess.selectFilter()
count = SSProcess.getSelGeoCount()
print(f"找到 {count} 个待删除对象")

# 3. 将对象添加到删除缓冲区
for i in range(count):
    geo = SSProcess.selGeoList[i]
    SSProcess.delBufferGeoList.append(geo)

# 4. 执行批量删除
SSProcess.saveBufferObjToDatabase()
print(f"已删除 {count} 个对象")

# 5. 清除选择集
SSProcess.clearSelection()

Sources: ssprocess_mixins/selection_mixin.py ssprocess_mixins/geo_edit_mixin.py

示例 2: 删除指定图层中的所有对象

# 获取地图中的所有图层
layer_count = SSProcess.getLayerCount()
target_layer = "Delete_Temp"

# 查询目标图层中的所有对象
SSProcess.clearSelection()
SSProcess.clearSelectCondition()
SSProcess.setSelectCondition("SSObj_LayerName", "==", target_layer)
SSProcess.selectFilter()

# 添加到删除缓冲区并删除
count = SSProcess.getSelGeoCount()
if count > 0:
    for i in range(count):
        SSProcess.delBufferGeoList.append(SSProcess.selGeoList[i])
    
    SSProcess.saveBufferObjToDatabase()
    print(f"已从图层 {target_layer} 删除 {count} 个对象")
else:
    print(f"图层 {target_layer} 中没有对象")

Sources: ssprocess_mixins/project_mixin.py ssprocess_mixins/geo_edit_mixin.py

示例 3: 基于属性条件的批量删除

删除属性值不符合要求的对象。

# 查找特定编码的旧版本对象
SSProcess.clearSelection()
SSProcess.clearSelectCondition()

# 设置多个删除条件
SSProcess.setSelectCondition("SSObj_Code", "==", "OLD_CODE")
SSProcess.setSelectCondition("SSObj_ModifyTime", "<", "2020-01-01")

SSProcess.selectFilter()

geo_count = SSProcess.getSelGeoCount()
note_count = SSProcess.getSelNoteCount()

# 添加地物对象到删除列表
for i in range(geo_count):
    geo = SSProcess.selGeoList[i]
    SSProcess.delBufferGeoList.append(geo)

# 添加注记对象到删除列表
for i in range(note_count):
    note = SSProcess.selNoteList[i]
    SSProcess.delBufferGeoList.append(note)

# 执行批量删除
if geo_count + note_count > 0:
    SSProcess.saveBufferObjToDatabase()
    print(f"已删除 {geo_count} 个地物对象和 {note_count} 个注记对象")

Sources: ssprocess_mixins/selection_mixin.py ssprocess_mixins/geo_edit_mixin.py

删除操作与选择集的结合

删除操作可以与选择集操作配合使用,实现灵活的数据管理。

操作流程

flowchart TD
    A[开始] --> B[清除选择集<br/>clearSelection]
    B --> C[设置选择条件<br/>setSelectCondition]
    C --> D[执行过滤查询<br/>selectFilter]
    D --> E[遍历选择集<br/>遍历 selGeoList]
    E --> F{是否需要删除?}
    F -->|是| G[添加到删除缓冲区<br/>delBufferGeoList.append]
    F -->|否| H[保留对象]
    G --> I{还有对象?}
    H --> I
    I -->|是| E
    I -->|否| J[执行批量删除<br/>saveBufferObjToDatabase]
    J --> K[清除选择集]
    K --> L[结束]

Sources: ssprocess_mixins/selection_mixin.py ssprocess_mixins/geo_edit_mixin.py

综合示例:条件判断后批量删除

# 查询特定区域的对象
SSProcess.clearSelection()
SSProcess.clearSelectCondition()

# 设置查询条件
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")
SSProcess.setSelectCondition("[Area]", ">", "10000")

SSProcess.selectFilter()
count = SSProcess.getSelGeoCount()
print(f"查询到 {count} 个对象")

# 根据条件判断是否删除
delete_count = 0
for i in range(count):
    # 获取对象属性进行进一步判断
    area = float(SSProcess.getSelGeoValue(i, "SSObj_Area"))
    create_time = SSProcess.getSelGeoValue(i, "SSObj_CreateTime")
    
    # 只有面积超过 20000 且创建时间早于 2020 年的对象才删除
    if area > 20000 and create_time < "2020-01-01":
        geo = SSProcess.selGeoList[i]
        SSProcess.delBufferGeoList.append(geo)
        delete_count += 1
        print(f"标记删除对象 ID: {geo.getObjectId()}, 面积: {area}")

if delete_count > 0:
    SSProcess.saveBufferObjToDatabase()
    print(f"已删除 {delete_count} 个对象")
else:
    print("没有符合条件的删除对象")

SSProcess.clearSelection()

Sources: ssprocess_mixins/selection_mixin.py ssprocess_mixins/geo_edit_mixin.py

方法对比

特性 deleteNewObj 批量删除 (delBufferGeoList)
操作对象 仅当前新建对象 多个已存在的地理对象
参数要求 无参数 需要手动添加对象到缓冲区
调用时机 创建后、保存前 任何时候
保存要求 不需要 需要调用 saveBufferObjToDatabase
删除范围 单个对象 多个对象
适用场景 取消新建、清理临时对象 数据清理、批量维护
即时性 立即生效 需要保存后才生效

Sources: ssprocess_mixins/geo_edit_mixin.py ssprocess_mixins/geo_edit_mixin.py

注意事项

前置条件检查

在调用 deleteNewObj 之前,确保当前确实存在新建对象:

# 检查当前新建对象是否存在
if SSProcess.curNewObj[0] is not None and SSProcess.curNewObj[1] is not None:
    # 可以安全删除
    SSProcess.deleteNewObj()
    print("对象已删除")
else:
    print("当前没有新建对象,无需删除")

Sources: ssprocess_mixins/geo_edit_mixin.py

对象生命周期

  • 新建对象:通过 createNewObjByCodecreateNewObjByClass 创建的对象存储在 curNewObj
  • 已保存对象:已调用 addNewObjToSaveObjListsaveBufferObjToDatabase 的对象不能使用 deleteNewObj 删除
  • 选择集对象:需要通过批量删除机制处理

Sources: ssprocess_mixins/geo_edit_mixin.py

批量删除的保存要求

批量删除必须调用 saveBufferObjToDatabase 方法才能真正执行删除操作:

# 仅添加到删除缓冲区,不会实际删除
SSProcess.delBufferGeoList.append(geo)

# 必须调用此方法才会实际删除
SSProcess.saveBufferObjToDatabase()

Sources: ssprocess_mixins/geo_edit_mixin.py

数据完整性

删除操作会影响数据库的完整性,建议在删除前:

  1. 备份重要数据
  2. 确认删除条件准确无误
  3. 考虑使用事务机制(如果系统支持)
  4. 记录删除日志以便追溯

性能考虑

对于大量对象的删除操作:

  • 批量删除比逐个删除效率更高
  • 建议分批处理,避免一次性删除过多对象
  • 注意内存使用情况,及时清理缓冲区

并发与锁定

  • 删除操作可能影响其他正在进行的编辑操作
  • 建议在删除前检查是否有其他用户正在编辑相关对象
  • 考虑在删除前创建撤销标记:SSProcess.pushUndoMark("批量删除操作")

Sources: ssprocess_mixins/project_mixin.py

错误处理与调试

常见问题

问题描述 可能原因 解决方案
deleteNewObj 无效效果 当前没有新建对象 检查 curNewObj 是否为 None
批量删除未生效 未调用 saveBufferObjToDatabase 调用保存方法
删除后对象仍显示 未更新地图视图 调用 updateSysSelection 同步选择集
删除操作失败 对象被锁定或其他用户使用 检查对象状态和锁定情况

调试技巧

# 检查当前新建对象状态
print(f"当前新建对象: {SSProcess.curNewObj}")

# 检查删除缓冲区大小
print(f"删除缓冲区对象数量: {len(SSProcess.delBufferGeoList)}")

# 检查选择集状态
print(f"选择集地物数量: {SSProcess.getSelGeoCount()}")
print(f"选择集注记数量: {SSProcess.getSelNoteCount()}")