本页面将引导初学者了解如何使用 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 管理和操作各种地理对象选择集，为后续的数据处理和分析工作打下坚实基础。