Files
sunvpy-docs/docs/content/4-shi-yong-ssprocess-guan-li-xuan-ze-ji.md
2026-04-10 13:47:53 +08:00

422 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
本页面将引导初学者了解如何使用 SSProcess 管理和操作地理对象的选择集。选择集是地理信息系统中的核心概念它允许您针对一组特定的对象执行批量操作如属性修改、坐标编辑、数据导出等。SSProcess 提供了完整的选择集管理 API支持基于条件的复杂查询、属性读写和系统同步等功能。
在学习本页内容后,建议按照以下路径继续深入:
- [第一个脚本:查询地物属性](3-di-ge-jiao-ben-cha-xun-di-wu-shu-xing) — 了解属性查询的基础用法
- [清除与初始化选择集](11-qing-chu-yu-chu-shi-hua-xuan-ze-ji) — 深入学习选择集的生命周期管理
- [设置选择条件](12-she-zhi-xuan-ze-tiao-jian) — 掌握复杂条件查询技巧
## SSProcess 架构概览
SSProcess 采用 **Mixin 设计模式** 将不同功能模块化,选择集管理功能位于 `SelectionMixin` 中。这种架构使得代码职责清晰、易于维护和扩展。`SSProcessManager` 类通过多重继承组合了选择集、地理编辑、项目管理、日志和进度等多个功能模块,最终导出全局单例 `SSProcess` 供脚本直接使用。
```mermaid
classDiagram
class SSProcessManager {
+workspace: WorkSpace
+map: ScaleMap
+selGeoList: GeoBaseList
+selNoteList: GeoBaseList
+searchHelper: SSearchHelper
+objBaseAttr: ObjBaseAttr
+clearSelection()
+setSelectCondition(name, mode, value)
+selectFilter()
+getSelGeoValue(index, fieldName)
+setSelGeoValue(index, fieldName, value)
+updateSysSelection(mode)
}
class SelectionMixin {
<<mixin>>
+clearSelection()
+clearSelectCondition()
+setSelectCondition()
+selectFilter()
+getSelGeoCount()
+getSelNoteCount()
+getSelGeoValue()
+setSelGeoValue()
+updateSysSelection()
+resetSelGeoByCode()
+explodeSelectionObj()
}
class GeoEditMixin {
<<mixin>>
+createDefaultGeoBase()
+explodeGeoObject()
}
class LogMixin {
<<mixin>>
+set_logger()
+log_error_msg()
}
class ProgressMixin {
<<mixin>>
+startProgress()
+stepProgress()
+closeProgress()
}
class ProjectMixin {
<<mixin>>
+getCurrentMap()
+getSysSelGeoList()
}
SSProcessManager *-- SelectionMixin
SSProcessManager *-- GeoEditMixin
SSProcessManager *-- LogMixin
SSProcessManager *-- ProgressMixin
SSProcessManager *-- ProjectMixin
class SSProcess {
<<全局单例>>
}
SSProcess ..> SSProcessManager : 创建并导出
```
### 核心组件说明
| 组件 | 类型 | 职责描述 |
|------|------|----------|
| `selGeoList` | GeoBaseList | 存储脚本选择集中的点、线、面对象 |
| `selNoteList` | GeoBaseList | 存储脚本选择集中的注记对象 |
| `searchHelper` | SSearchHelper | 执行条件查询和过滤操作的核心引擎 |
| `objBaseAttr` | ObjBaseAttr | 管理对象基本属性的读写操作 |
| `workspace` | WorkSpace | 当前工作空间实例,提供地图访问 |
| `map` | ScaleMap | 当前比例尺地图,用于对象同步和显示更新 |
Sources: [PySSProcess.py](PySSProcess.py#L21-L44), [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L13-L44)
## 选择集管理基础流程
选择集操作遵循"初始化 → 条件设置 → 过滤查询 → 属性操作 → 系统同步"的标准流程。理解这个流程对于高效使用选择集至关重要。
```mermaid
flowchart TD
A[获取 SSProcess 实例] --> B[清除选择集<br/>clearSelection]
B --> C[清除选择条件<br/>clearSelectCondition]
C --> D[设置查询条件<br/>setSelectCondition]
D --> E{条件设置完成?}
E -->|否| D
E -->|是| F[执行过滤查询<br/>selectFilter]
F --> G[获取选择集数量<br/>getSelGeoCount]
G --> H{数量 > 0?}
H -->|是| I[遍历对象<br/>获取属性/修改属性]
H -->|否| J[结束流程]
I --> K[保存更改]
K --> L[同步到系统选择集<br/>updateSysSelection]
L --> M[更新地图显示]
M --> J
```
### 选择集与系统选择集的关系
SSProcess 维护了两个独立的选择集:**脚本选择集**和**系统选择集**。脚本选择集用于脚本内部操作,系统选择集用于地图显示和用户交互。两者可以通过 `updateSysSelection()` 方法进行双向同步。
| 同步模式 | mode 参数值 | 同步方向 | 说明 |
|----------|-------------|----------|------|
| 脚本 ← 系统 | 0 | 从系统选择集同步到脚本选择集 | 获取用户在地图上选择的对象 |
| 脚本 → 系统(更新显示) | 1 | 从脚本选择集同步到系统选择集 | 将修改后的对象同步并刷新显示 |
| 脚本 → 系统(不更新显示) | 2 | 从脚本选择集同步到系统选择集 | 仅更新数据不刷新显示(性能优化) |
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L102-L126)
## 选择条件详解
`setSelectCondition()` 方法是选择集查询的核心,它支持丰富的属性类型和操作符,能够满足复杂的查询需求。
### 属性类型分类
SSProcess 支持三种属性类型,通过命名规则进行区分:
| 属性类型 | 命名格式 | 示例 | 说明 |
|----------|----------|------|------|
| 基本属性 | `SSObj_` 开头 | `SSObj_Code`, `SSObj_ID`, `SSObj_LayerName` | 系统内置的对象属性 |
| 几何特性 | `< >` 括住 | `<Overlap>`, `<Close>`, `<Intersect>` | 对象的几何状态和空间关系 |
| 扩展属性 | `[ ]` 括住 | `[JG]`, `[CS]`, `[ExAttr]` | 用户自定义的字段属性 |
### 常用基本属性速查
| 属性名称 | 类型 | 说明 | 示例值 |
|----------|------|------|--------|
| `SSObj_ID` | 字符串 | 对象唯一标识 | "12345" |
| `SSObj_Code` | 字符串/整数 | 对象编码 | "3103013" |
| `SSObj_LayerName` | 字符串 | 所在图层名称 | "DLG", "Default_A" |
| `SSObj_Type` | 字符串 | 对象类型 | "POINT", "LINE", "AREA", "NOTE" |
| `SSObj_Color` | 字符串/整数 | 颜色 | "16777215", "RGB(255,0,0)" |
| `SSObj_LineWidth` | 整数 | 线宽 | "1", "2" |
| `SSObj_Name` | 字符串 | 对象名称 | "建筑物1" |
| `SSObj_Area` | 浮点数 | 面积 | "1500.5" |
| `SSObj_Length` | 浮点数 | 长度 | "200.3" |
| `SSObj_X` | 浮点数 | X坐标 | "100.5" |
| `SSObj_Y` | 浮点数 | Y坐标 | "200.8" |
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L45-L107)
### 操作符说明
| 操作符 | 含义 | 适用场景 | 示例 |
|--------|------|----------|------|
| `==` | 等于 | 精确匹配 | `SSObj_Code == "3103013"` |
| `>` | 大于 | 数值比较 | `SSObj_Length > "100"` |
| `<` | 小于 | 数值比较 | `SSObj_Area < "500"` |
| `<>` | 不等于 | 排除特定值 | `SSObj_Type <> "NOTE"` |
| `LIKE` | 模糊匹配 | 字符串部分匹配 | `SSObj_Name LIKE "建筑"` |
| `NOT LIKE` | 不包含 | 排除特定字符串 | `SSObj_Name NOT LIKE "临时"` |
| `CompareNoCase` | 不区分大小写 | 字符串比较 | `SSObj_LayerName CompareNoCase "dlg"` |
| `Dec` | 小数位精度 | 数值精度控制 | `SSObj_Length Dec "2"` |
### 条件值格式
| 值类型 | 格式 | 示例 | 说明 |
|--------|------|------|------|
| 单值 | 直接值 | `"3103013"` | 匹配单个值 |
| 多值 | `值1,值2,值3` | `"3103013,3103014,3103015"` | 匹配任意一个值 |
| 区间 | `值1->值2` | `"100->500"` | 值域范围匹配 |
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L45-L107)
## 选择集操作核心 API
### 初始化与清理
在开始新的选择操作前,通常需要清理之前的选择集和条件,避免结果混入不相关的对象。
```python
# 清除脚本选择集中的所有对象
SSProcess.clearSelection()
# 清除已设置的所有选择条件
SSProcess.clearSelectCondition()
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L34-L43)
### 执行查询
设置好条件后,执行 `selectFilter()` 将符合条件的对象筛选到选择集中。
```python
# 设置选择条件:编码等于 3103013
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")
# 执行过滤查询
SSProcess.selectFilter()
# 查询选择集对象数量
geo_count = SSProcess.getSelGeoCount()
note_count = SSProcess.getSelNoteCount()
print(f"查询到点线面对象: {geo_count}")
print(f"查询到注记对象: {note_count}")
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L108-L126), [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L152-L168)
### 读取对象属性
遍历选择集中的对象并读取其属性值是常见的操作。
```python
# 遍历选择集中的前 10 个对象
for i in range(min(10, SSProcess.getSelGeoCount())):
# 读取基本属性
code = SSProcess.getSelGeoValue(i, "SSObj_Code")
layer_name = SSProcess.getSelGeoValue(i, "SSObj_LayerName")
obj_type = SSProcess.getSelGeoValue(i, "SSObj_Type")
# 读取扩展属性(需要用 [] 括住)
jg_value = SSProcess.getSelGeoValue(i, "[JG]")
# 读取几何特性(需要用 <> 括住)
is_overlap = SSProcess.getSelGeoValue(i, "<Overlap>")
print(f"对象 {i}: 编码={code}, 图层={layer_name}, 类型={obj_type}")
print(f" 扩展属性[JG]={jg_value}, 重叠={is_overlap}")
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L169-L215)
### 修改对象属性
批量修改选择集中对象的属性值,支持基本属性和扩展属性的修改。
```python
# 批量修改选择集对象属性
for i in range(SSProcess.getSelGeoCount()):
# 修改基本属性
SSProcess.setSelGeoValue(i, "SSObj_Name", f"已修改对象{i}")
SSProcess.setSelGeoValue(i, "SSObj_Color", "16777215") # 白色
SSProcess.setSelGeoValue(i, "SSObj_LineWidth", "2")
# 修改扩展属性(多个属性用逗号分隔)
SSProcess.setSelGeoValue(i, "[JG],[CS]", "砖混,6")
# 特殊属性:修改编码
SSProcess.setSelGeoValue(i, "SSObj_Code", "3103014")
```
**重要提示**:修改 `SSObj_Code``SSObj_LayerName` 会触发对象的重新创建操作,这比普通属性修改更耗时,请谨慎使用。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L247-L298)
### 同步到系统选择集
将脚本中对选择集的修改同步到系统选择集,使地图视图更新。
```python
# 模式 1同步并更新显示最常用
SSProcess.updateSysSelection(1)
# 模式 2仅同步数据不更新显示性能优化
SSProcess.updateSysSelection(2)
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L102-L126)
## 完整示例:批量修改对象属性
以下示例展示了完整的选择集操作流程,包括查询、属性修改和系统同步。
```python
from sunvpy import SSProcess
# 步骤 1初始化选择集
SSProcess.clearSelection()
SSProcess.clearSelectCondition()
# 步骤 2设置查询条件
# 条件 1编码为 3103013
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")
# 条件 2且图层为 Default_A隐式 AND 关系)
SSProcess.setSelectCondition("SSObj_LayerName", "==", "Default_A")
# 步骤 3执行过滤查询
SSProcess.selectFilter()
count = SSProcess.getSelGeoCount()
print(f"查询到 {count} 个符合条件的对象")
if count == 0:
print("没有找到符合条件的对象")
else:
# 步骤 4批量修改属性
for i in range(count):
# 读取原始属性
original_name = SSProcess.getSelGeoValue(i, "SSObj_Name")
original_color = SSProcess.getSelGeoValue(i, "SSObj_Color")
print(f"处理对象 {i}: {original_name}")
# 修改属性
SSProcess.setSelGeoValue(i, "SSObj_Name", f"标准_{original_name}")
SSProcess.setSelGeoValue(i, "SSObj_Color", "16711680") # 蓝色
SSProcess.setSelGeoValue(i, "SSObj_LineWidth", "2")
SSProcess.setSelGeoValue(i, "[JG]", "框架")
# 步骤 5同步到系统选择集并更新显示
SSProcess.updateSysSelection(1)
print("批量修改完成,地图显示已更新")
```
Sources: [PySSProcess.py](PySSProcess.py#L115-L140)
## 高级功能:选择集打散操作
SSProcess 还提供了选择集对象的打散功能,可以将复杂对象分解为其组成部分。这在数据处理和拓扑修复等场景中非常有用。
```python
# 打散选择集对象
# 参数说明:
# - explodeWay: 0=图形打散, 1=根据编码表打散
# - delSrcObj: True=删除原始对象, False=保留原始对象
# - callback: 回调函数名,用于处理打散后的对象
def onExplodeComplete(geo, geoVec, noteVec):
"""打散完成后的回调函数"""
print(f"原始对象 {geo.getObjName()} 已打散")
print(f"生成 {geoVec.size()} 个几何对象")
print(f"生成 {noteVec.size()} 个注记对象")
# 执行打散操作
SSProcess.explodeSelectionObj(
explodeWay=1,
delSrcObj=True,
callback="onExplodeComplete"
)
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L500-L654)
## 选择集管理最佳实践
### 性能优化建议
| 场景 | 建议做法 | 原因 |
|------|----------|------|
| 大批量对象处理 | 使用 `updateSysSelection(2)` 不更新显示 | 避免频繁刷新导致的性能下降 |
| 修改编码或图层 | 避免在循环中批量修改 | 这些操作会重新创建对象,耗时较长 |
| 复杂条件查询 | 优先使用索引字段Code、ID、LayerName | 提高查询效率 |
| 扩展属性读写 | 缓存常用字段的索引位置 | 避免重复查找 |
### 错误处理
选择集操作中的常见错误及处理方法:
| 错误类型 | 表现 | 处理建议 |
|----------|------|----------|
| 索引越界 | `getSelGeoValue()` 返回空字符串 | 操作前检查 `getSelGeoCount()` 返回值 |
| 属性名错误 | 属性值读取失败 | 确认属性名拼写及类型(基本属性 vs 扩展属性) |
| 条件格式错误 | `selectFilter()` 无结果 | 检查操作符和条件值格式是否正确 |
| 对象不存在 | 操作失败 | 确保数据源已加载且包含目标图层 |
### 常见问题排查
**问题 1查询结果为空**
可能原因:
- 条件值格式错误(如将数值写成字符串)
- 属性名拼写错误
- 数据源中不包含符合条件的对象
排查方法:
```python
# 先查询总数再筛选
total_before = SSProcess.getSelGeoCount()
SSProcess.selectFilter()
total_after = SSProcess.getSelGeoCount()
print(f"筛选前: {total_before}, 筛选后: {total_after}")
```
**问题 2属性修改不生效**
可能原因:
- 未调用 `updateSysSelection()` 同步
- 属性名使用了错误的类型(扩展属性忘记加 `[]`
- 对象已锁定或只读
排查方法:
```python
# 修改后立即读取验证
SSProcess.setSelGeoValue(0, "SSObj_Name", "新名称")
new_name = SSProcess.getSelGeoValue(0, "SSObj_Name")
print(f"修改后的名称: {new_name}")
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L34-L43), [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L169-L215)
## 下一步学习路径
掌握选择集管理的基础操作后,建议继续学习以下主题以提升开发能力:
- [清除与初始化选择集](11-qing-chu-yu-chu-shi-hua-xuan-ze-ji) — 了解选择集状态管理
- [执行过滤查询](13-zhi-xing-guo-lv-cha-xun) — 深入学习过滤机制
- [遍历选择集对象](14-bian-li-xuan-ze-ji-dui-xiang) — 掌握高效遍历技巧
- [获取地物属性值](15-huo-qu-di-wu-shu-xing-zhi) — 系统学习属性操作
- [修改地物属性值](16-xiu-gai-di-wu-shu-xing-zhi) — 批量修改最佳实践
通过循序渐进地学习这些主题,您将能够熟练使用 SSProcess 管理和操作各种地理对象选择集,为后续的数据处理和分析工作打下坚实基础。