本文档详细说明如何在 SunvStation 系统中删除地理对象。删除操作是地理数据维护的重要环节,包括删除当前新建对象、批量删除多个对象以及与选择集结合的删除场景。掌握删除操作的机制和使用方法,能够帮助开发者有效管理地图数据,确保数据的准确性和一致性。 建议在学习本页面之前,先了解 [创建默认地物对象](19-chuang-jian-mo-ren-di-wu-dui-xiang) 和 [添加对象坐标点](21-tian-jia-dui-xiang-zuo-biao-dian)。完成本页面学习后,可以继续学习 [对象缓存机制](23-dui-xiang-huan-cun-ji-zhi) 和 [批量保存到数据库](24-pi-liang-bao-cun-dao-shu-ju-ku)。 Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L395-L404) ## 删除操作概述 SunvStation 提供了两种主要的删除方式:单对象删除和批量删除。单对象删除主要用于删除当前正在创建的对象,而批量删除则适用于处理多个已存在的地理对象。 | 删除方式 | 方法名称 | 适用场景 | 操作时机 | |---------|---------|---------|---------| | 单对象删除 | `deleteNewObj` | 删除当前新建对象 | 对象创建后、保存前 | | 批量删除 | `delBufferGeoList` + `saveBufferObjToDatabase` | 删除多个对象 | 对象已添加到删除缓冲区后 | 删除操作的核心机制基于 `delBufferGeoList` 缓冲区,该缓冲区存储待删除的地理对象。当调用 `saveBufferObjToDatabase()` 方法时,系统会自动处理这些删除操作。 Sources: [PySSProcess.py](PySSProcess.py#L72) [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ## deleteNewObj 方法详解 `deleteNewObj` 方法用于删除当前新建的地理对象。这是一个即时的删除操作,不需要保存到数据库即可生效。 ### 方法签名 ```python def deleteNewObj(self): ``` ### 功能说明 该方法执行以下操作: 1. 检查当前是否有新建对象(`self.curNewObj` 不为空) 2. 如果存在新建对象,调用地图的 `delGeoObject` 方法删除该对象 3. 将 `self.curNewObj` 重置为 `(None, None)`,表示当前没有新建对象 ### 特点 - **无需参数**:该方法不接受任何参数 - **无返回值**:不返回任何结果,仅执行删除操作 - **即时生效**:删除操作立即执行,无需等待数据库保存 - **仅限新建对象**:只能删除通过创建方法生成的当前对象 Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L395-L404) ## 删除新建对象的工作流程 删除当前新建对象是一个简单直接的操作,但需要了解其在整个对象生命周期中的位置。 ```mermaid flowchart TD A[开始] --> B[创建新对象
createNewObjByCode] B --> C{是否需要保留?} C -->|是| D[添加坐标点
addNewObjPoint] D --> E[添加到保存列表
addNewObjToSaveObjList] E --> F[保存到数据库
saveBufferObjToDatabase] F --> G[对象持久化成功] C -->|否| H[删除对象
deleteNewObj] H --> I[curNewObj 重置为 None] I --> J[对象从内存中移除] J --> K[结束] G --> K ``` Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L395-L464) ## 使用场景与示例 ### 场景 1: 取消创建过程中的对象 在创建对象的过程中,如果发现对象不符合要求或需要中止创建,可以使用 `deleteNewObj` 方法取消。 ```python # 尝试创建一个线对象 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](ssprocess_mixins/geo_edit_mixin.py#L395-L404) ### 场景 2: 条件判断后删除 根据业务逻辑判断是否需要保留新建的对象。 ```python # 创建点对象 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](ssprocess_mixins/geo_edit_mixin.py#L395-L464) ### 场景 3: 异常处理中的清理 在创建对象过程中发生异常时,确保清理已创建的对象。 ```python 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](ssprocess_mixins/geo_edit_mixin.py#L395-L404) ## 批量删除机制 批量删除通过 `delBufferGeoList` 删除缓冲区实现。该缓冲区是一个 `GeoBaseList` 类型的对象,存储待删除的地理对象。 ### 批量删除的工作原理 ```mermaid 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](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ### 批量删除的实现 批量删除的核心逻辑在 `saveBufferObjToDatabase` 方法中实现: ```python # 删除缓存列表中的对象 self.map.delGeoBaseComponent(self.delBufferGeoList) self.delBufferGeoList.clear() ``` 该代码段执行以下操作: 1. 调用地图的 `delGeoBaseComponent` 方法,传入 `delBufferGeoList` 2. 系统批量删除列表中的所有对象 3. 清空 `delBufferGeoList`,为下次操作做准备 Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ## 批量删除示例 ### 示例 1: 基于选择集的批量删除 删除选择集中符合特定条件的所有对象。 ```python # 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/selection_mixin.py#L13-L70) [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ### 示例 2: 删除指定图层中的所有对象 ```python # 获取地图中的所有图层 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/project_mixin.py#L133-L145) [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ### 示例 3: 基于属性条件的批量删除 删除属性值不符合要求的对象。 ```python # 查找特定编码的旧版本对象 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/selection_mixin.py#L13-L70) [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ## 删除操作与选择集的结合 删除操作可以与选择集操作配合使用,实现灵活的数据管理。 ### 操作流程 ```mermaid flowchart TD A[开始] --> B[清除选择集
clearSelection] B --> C[设置选择条件
setSelectCondition] C --> D[执行过滤查询
selectFilter] D --> E[遍历选择集
遍历 selGeoList] E --> F{是否需要删除?} F -->|是| G[添加到删除缓冲区
delBufferGeoList.append] F -->|否| H[保留对象] G --> I{还有对象?} H --> I I -->|是| E I -->|否| J[执行批量删除
saveBufferObjToDatabase] J --> K[清除选择集] K --> L[结束] ``` Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L13-L70) [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ### 综合示例:条件判断后批量删除 ```python # 查询特定区域的对象 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/selection_mixin.py#L13-L70) [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ## 方法对比 | 特性 | deleteNewObj | 批量删除 (delBufferGeoList) | |------|-------------|----------------------------| | 操作对象 | 仅当前新建对象 | 多个已存在的地理对象 | | 参数要求 | 无参数 | 需要手动添加对象到缓冲区 | | 调用时机 | 创建后、保存前 | 任何时候 | | 保存要求 | 不需要 | 需要调用 saveBufferObjToDatabase | | 删除范围 | 单个对象 | 多个对象 | | 适用场景 | 取消新建、清理临时对象 | 数据清理、批量维护 | | 即时性 | 立即生效 | 需要保存后才生效 | Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L395-L404) [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ## 注意事项 ### 前置条件检查 在调用 `deleteNewObj` 之前,确保当前确实存在新建对象: ```python # 检查当前新建对象是否存在 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](ssprocess_mixins/geo_edit_mixin.py#L395-L404) ### 对象生命周期 - **新建对象**:通过 `createNewObjByCode` 或 `createNewObjByClass` 创建的对象存储在 `curNewObj` 中 - **已保存对象**:已调用 `addNewObjToSaveObjList` 和 `saveBufferObjToDatabase` 的对象不能使用 `deleteNewObj` 删除 - **选择集对象**:需要通过批量删除机制处理 Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L395-L464) ### 批量删除的保存要求 批量删除必须调用 `saveBufferObjToDatabase` 方法才能真正执行删除操作: ```python # 仅添加到删除缓冲区,不会实际删除 SSProcess.delBufferGeoList.append(geo) # 必须调用此方法才会实际删除 SSProcess.saveBufferObjToDatabase() ``` Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L441-L462) ### 数据完整性 删除操作会影响数据库的完整性,建议在删除前: 1. 备份重要数据 2. 确认删除条件准确无误 3. 考虑使用事务机制(如果系统支持) 4. 记录删除日志以便追溯 ### 性能考虑 对于大量对象的删除操作: - 批量删除比逐个删除效率更高 - 建议分批处理,避免一次性删除过多对象 - 注意内存使用情况,及时清理缓冲区 ### 并发与锁定 - 删除操作可能影响其他正在进行的编辑操作 - 建议在删除前检查是否有其他用户正在编辑相关对象 - 考虑在删除前创建撤销标记:`SSProcess.pushUndoMark("批量删除操作")` Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L65-L75) ## 错误处理与调试 ### 常见问题 | 问题描述 | 可能原因 | 解决方案 | |---------|---------|---------| | `deleteNewObj` 无效效果 | 当前没有新建对象 | 检查 `curNewObj` 是否为 `None` | | 批量删除未生效 | 未调用 `saveBufferObjToDatabase` | 调用保存方法 | | 删除后对象仍显示 | 未更新地图视图 | 调用 `updateSysSelection` 同步选择集 | | 删除操作失败 | 对象被锁定或其他用户使用 | 检查对象状态和锁定情况 | ### 调试技巧 ```python # 检查当前新建对象状态 print(f"当前新建对象: {SSProcess.curNewObj}") # 检查删除缓冲区大小 print(f"删除缓冲区对象数量: {len(SSProcess.delBufferGeoList)}") # 检查选择集状态 print(f"选择集地物数量: {SSProcess.getSelGeoCount()}") print(f"选择集注记数量: {SSProcess.getSelNoteCount()}") ```