Files
sunvpy-docs/docs/content/13-zhi-xing-guo-lu-cha-xun.md

417 lines
16 KiB
Markdown
Raw Normal View History

2026-04-10 13:47:53 +08:00
本页面介绍 SunvStation Python 脚本中执行过滤查询的方法。`selectFilter()` 方法是选择集查询的核心执行环节,它根据之前设置的选择条件,从数据源中筛选出符合条件的地理对象,并将结果填充到脚本选择集中。掌握此方法的执行机制和结果处理,是构建高效数据查询脚本的关键。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L131-L154)
## 核心方法概述
`selectFilter()` 方法负责执行实际的选择集过滤操作。该方法内部协调搜索助手 `searchHelper`,通过两阶段查询机制完成对象筛选:首先获取候选对象列表,然后根据完整条件进行精确过滤,最后将结果分类存储到脚本选择集中。
```python
SSProcess.selectFilter()
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L131-L154)
**方法返回值**:该方法无返回值,执行结果通过脚本选择集成员变量 `selGeoList`(点线面对象)和 `selNoteList`(注记对象)提供访问。查询成功后,可以使用 `getSelGeoCount()``getSelNoteCount()` 获取结果数量,使用 `getSelGeoValue()` 等方法遍历对象属性。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L131-L154)
## 执行流程
过滤查询的执行过程包含四个关键阶段:缓存清理、候选对象获取、精确过滤、结果分类存储。整个流程由进度条模块提供可视化反馈,确保操作透明可控。
```mermaid
flowchart TD
A[调用 selectFilter] --> B[清理缓存]
B --> C[清空 curSelGeoFields]
C --> D[清空 curSelGeoValues]
D --> E[执行选择过滤]
E --> F[创建临时 GeoBaseList]
F --> G[getFilterObj 获取候选对象]
G --> H{候选对象非空?}
H -->|是| I[filterObj 精确过滤]
H -->|否| J[跳过过滤步骤]
I --> K[遍历结果列表]
J --> K
K --> L{对象类型判断}
L -->|注记对象| M[添加到 selNoteList]
L -->|点线面对象| N[添加到 selGeoList]
M --> O[完成选择集过滤]
N --> O
O --> P[关闭进度条]
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L131-L154)
**进度反馈机制**:方法执行过程中会调用 `stepProgress()` 方法报告当前进度,包括"清理缓存"、"执行选择过滤"、"更新选择集"、"完成选择集过滤"四个阶段。开发者可以通过 `enable_progress` 属性控制是否显示进度条。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L134-L154)
## 详细执行步骤
### 步骤一:清理缓存
执行查询前,方法首先清理属性缓存字段 `curSelGeoFields``curSelGeoValues`。这两个字符串数组用于存储当前选中对象的属性字段和对应值,清理缓存确保新的查询结果不会受到之前属性访问的干扰。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L137-L138)
### 步骤二:获取候选对象
方法创建临时的 `GeoBaseList` 容器,并调用 `searchHelper.getFilterObj()` 方法。该方法根据 `m_selectConditions` 中存储的选择条件,从当前数据源中获取满足条件的候选对象列表。这一步是初步筛选,可能包含部分不完全符合所有条件的对象。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L141-L142)
### 步骤三:精确过滤
如果候选对象列表非空,方法调用 `searchHelper.filterObj()` 进行精确过滤。这一步对候选对象应用完整的条件规则集合,确保最终结果严格满足所有设置的条件。只有通过精确过滤的对象才会被加入最终的选择集。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L145-L146)
### 步骤四:结果分类存储
最后,方法遍历过滤后的对象列表,根据对象类型将其分类存储:注记对象(`e_Note_Obj`)添加到 `selNoteList`,其他类型的点线面对象添加到 `selGeoList`。这种分离存储便于后续对不同类型对象进行差异化处理。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L148-L152)
## 完整使用示例
以下示例展示了一个完整的过滤查询流程,从条件设置到结果处理的各个步骤。
```mermaid
flowchart LR
A[开始查询] --> B[clearSelection<br/>清除旧结果]
B --> C[clearSelectCondition<br/>清除旧条件]
C --> D[setSelectCondition<br/>设置查询条件]
D --> E[selectFilter<br/>执行过滤]
E --> F{检查结果数量}
F -->|大于0| G[遍历处理对象]
F -->|等于0| H[输出无结果提示]
G --> I[获取对象属性]
I --> J[完成处理]
```
Sources: [PySSProcess.py](PySSProcess.py#L94-L98)
### 基础查询示例
```python
# 准备阶段:清除旧的状态
SSProcess.clearSelection() # 清除之前的选择集对象
SSProcess.clearSelectCondition() # 清除之前的选择条件
# 设置查询条件:编码等于 3103013
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")
# 执行过滤查询
SSProcess.selectFilter()
# 获取结果数量
geo_count = SSProcess.getSelGeoCount()
print(f"选择集中的点线面对象数量: {geo_count}")
# 处理查询结果
if geo_count > 0:
for i in range(min(10, geo_count)): # 只处理前10个对象
code = SSProcess.getSelGeoValue(i, "SSObj_Code")
name = SSProcess.getSelGeoValue(i, "SSObj_Name")
print(f"对象 {i}: 编码={code}, 名称={name}")
else:
print("未找到符合条件的对象")
```
Sources: [PySSProcess.py](PySSProcess.py#L94-L115)
### 多条件复合查询
```python
# 清除状态
SSProcess.clearSelection()
SSProcess.clearSelectCondition()
# 设置多个查询条件(逻辑与关系)
SSProcess.setSelectCondition("SSObj_LayerName", "==", "Default_A")
SSProcess.setSelectCondition("SSObj_Type", "==", "AREA")
SSProcess.setSelectCondition("SSObj_Area", ">", "100")
# 执行查询
SSProcess.selectFilter()
# 统计结果
area_count = SSProcess.getSelGeoCount()
print(f"查询到 {area_count} 个面积大于100的面对象")
```
### 使用多值和区间查询
```python
# 清除状态
SSProcess.clearSelection()
SSProcess.clearSelectCondition()
# 使用多值方式(匹配任意一个)
SSProcess.setSelectCondition("SSObj_Code", "==", "A1,A2,A3")
# 使用区间方式值1->值2
SSProcess.setSelectCondition("SSObj_Length", "==", "50->200")
# 执行查询
SSProcess.selectFilter()
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L122-L134)
## 查询前后的选择集状态对比
下表展示了执行 `selectFilter()` 前后脚本选择集的典型状态变化。
| 状态指标 | 查询前 | 查询后 | 说明 |
|---------|-------|-------|------|
| `selGeoList` 对象数量 | 0 或旧值 | 新查询结果数量 | 完全替换,非追加 |
| `selNoteList` 对象数量 | 0 或旧值 | 新查询结果数量 | 完全替换,非追加 |
| `m_selectConditions` 条件数量 | 保持不变 | 保持不变 | 条件不受影响 |
| `curSelGeoFields` | 旧值或空 | 空 | 缓存已清理 |
| `curSelGeoValues` | 旧值或空 | 空 | 缓存已清理 |
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L131-L154)
**重要特性**`selectFilter()` 是"替换模式"而非"追加模式"。每次执行都会完全重写 `selGeoList``selNoteList`,之前的选择集结果会被完全覆盖。如果需要保留之前的结果,应在调用前将结果保存到其他容器中。
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L148-L152)
## 结果处理最佳实践
### 检查查询结果
执行查询后,首先检查结果数量,避免对空列表进行操作。
```python
SSProcess.selectFilter()
geo_count = SSProcess.getSelGeoCount()
note_count = SSProcess.getSelNoteCount()
if geo_count == 0 and note_count == 0:
print("警告:未找到符合条件的对象")
return # 提前退出
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L204-L218)
### 批量处理对象
对于大量查询结果,建议使用循环批量处理,并记录处理进度。
```python
SSProcess.selectFilter()
count = SSProcess.getSelGeoCount()
print(f"开始处理 {count} 个对象...")
for i in range(count):
# 获取对象属性
obj_id = SSProcess.getSelGeoValue(i, "SSObj_ID")
obj_code = SSProcess.getSelGeoValue(i, "SSObj_Code")
# 执行处理逻辑
# SSProcess.setSelGeoValue(i, "SSObj_Name", f"新名称_{i}")
# 每处理100个对象输出一次进度
if (i + 1) % 100 == 0:
print(f"已处理 {i + 1}/{count} 个对象")
print("处理完成")
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L236-L250)
### 同步到系统选择集
如果需要在地图上高亮显示查询结果,使用 `updateSysSelection()` 方法同步。
```python
# 执行查询
SSProcess.selectFilter()
# 同步到系统选择集(更新地图显示)
SSProcess.updateSysSelection(1) # mode=1 表示更新显示
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L156-L176)
## 常见问题与故障排除
### 问题一:查询结果为空
**症状**:调用 `selectFilter()` 后,`getSelGeoCount()` 返回 0。
**可能原因与解决方案**
| 原因 | 检查方法 | 解决方案 |
|------|---------|---------|
| 条件设置过于严格 | 使用宽泛条件重新查询 | 放宽筛选条件,如使用 `LIKE` 代替 `==` |
| 条件名称拼写错误 | 检查 `SSObj_` 前缀是否正确 | 参考 [设置选择条件](12-she-zhi-xuan-ze-tiao-jian) 中的属性列表 |
| 数据源为空 | 检查当前地图是否加载了数据 | 确保地图已打开并加载了相应图层 |
| 多条件逻辑冲突 | 逐一测试每个条件 | 简化条件,逐步增加约束 |
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L131-L154)
### 问题二:查询结果不符合预期
**症状**:查询结果数量不为零,但结果对象不符合预期条件。
**排查步骤**
```python
# 1. 检查条件是否正确设置
# 注意:条件是累积的,不会自动清除
SSProcess.clearSelectCondition()
# 2. 重新设置条件并验证
SSProcess.setSelectCondition("SSObj_Type", "==", "AREA")
print("条件已设置")
# 3. 执行查询并检查结果
SSProcess.selectFilter()
# 4. 打印前几个对象的属性进行验证
for i in range(min(5, SSProcess.getSelGeoCount())):
obj_type = SSProcess.getSelGeoValue(i, "SSObj_Type")
print(f"对象 {i} 类型: {obj_type}")
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L131-L154)
### 问题三:进度条不显示
**症状**:调用 `selectFilter()` 时没有看到进度条提示。
**解决方案**:检查 `enable_progress` 属性是否被禁用。
```python
# 确保启用进度条
SSProcess.enable_progress = True
# 执行查询
SSProcess.selectFilter()
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L44-L45)
### 问题四:性能问题
**症状**:大规模数据查询执行缓慢。
**优化建议**
| 优化方向 | 具体措施 | 预期效果 |
|---------|---------|---------|
| 减少条件复杂度 | 避免使用多个模糊匹配条件 | 减少候选对象范围 |
| 使用精确匹配 | 优先使用 `==` 代替 `LIKE` | 加速索引查找 |
| 分批处理 | 对大数据集分页查询 | 降低单次查询压力 |
| 利用索引 | 确保查询字段建立了索引 | 显著提升查询速度 |
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L131-L154)
## 完整工作流示例
以下示例展示了一个包含错误处理、进度反馈和结果导出的完整工作流。
```python
import time
def query_and_export():
"""执行查询并导出结果"""
# 步骤1重置选择集状态
print("步骤1重置选择集状态")
SSProcess.clearSelection()
SSProcess.clearSelectCondition()
# 步骤2设置查询条件
print("步骤2设置查询条件")
SSProcess.setSelectCondition("SSObj_LayerName", "==", "Default_A")
SSProcess.setSelectCondition("SSObj_Type", "==", "AREA")
SSProcess.setSelectCondition("SSObj_Area", ">", "50")
# 步骤3执行查询
print("步骤3执行过滤查询")
start_time = time.time()
SSProcess.selectFilter()
elapsed_time = time.time() - start_time
print(f"查询完成,耗时 {elapsed_time:.2f} 秒")
# 步骤4检查结果
geo_count = SSProcess.getSelGeoCount()
note_count = SSProcess.getSelNoteCount()
print(f"\n查询结果统计")
print(f" 点线面对象数量: {geo_count}")
print(f" 注记对象数量: {note_count}")
if geo_count == 0:
print("警告:未查询到地物对象")
return
# 步骤5处理查询结果
print("\n步骤5处理查询结果显示前10个")
print("-" * 60)
fields = ["SSObj_ID", "SSObj_Code", "SSObj_LayerName", "SSObj_Area"]
# 打印表头
print(f"{'索引':<6} {fields[0]:<15} {fields[1]:<15} {fields[2]:<15} {fields[3]:<15}")
print("-" * 60)
# 打印数据
display_count = min(10, geo_count)
for i in range(display_count):
row_data = []
for field in fields:
value = SSProcess.getSelGeoValue(i, field)
row_data.append(str(value))
print(f"{i:<6} {row_data[0]:<15} {row_data[1]:<15} {row_data[2]:<15} {row_data[3]:<15}")
if geo_count > display_count:
print(f"... 还有 {geo_count - display_count} 个对象未显示")
# 步骤6可选同步到系统选择集
# SSProcess.updateSysSelection(1)
print("\n处理完成")
# 执行函数
query_and_export()
```
Sources: [PySSProcess.py](PySSProcess.py#L94-L138)
## 与其他方法的协作关系
`selectFilter()` 方法在 SunvStation 脚本体系中处于核心位置,与其他选择集相关方法形成完整的数据查询链路。
```mermaid
flowchart TD
A[clearSelectCondition<br/>清除条件] --> B[setSelectCondition<br/>设置条件]
B --> C[selectFilter<br/>执行查询]
C --> D[getSelGeoCount/getSelNoteCount<br/>获取数量]
C --> E[getSelGeoValue<br/>获取属性]
C --> F[updateSysSelection<br/>同步显示]
C --> G[clearSelection<br/>清除结果]
G --> A
style C fill:#e1f5ff,stroke:#01579b,stroke-width:3px
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L57-L154)
**方法调用顺序**:通常的调用顺序为 `clearSelection()``clearSelectCondition()``setSelectCondition()`(可多次)→ `selectFilter()` → 结果处理 → `updateSysSelection()`(可选)。`clearSelection()` 也可以在处理完结果后调用,为下一次查询做准备。
Sources: [PySSProcess.py](PySSProcess.py#L94-L98)
## 延伸阅读
完成本页面学习后,建议继续阅读以下相关页面以构建完整的选择集操作知识体系:
- [遍历选择集对象](14-bian-li-xuan-ze-ji-dui-xiang) - 学习如何高效遍历和处理查询结果
- [获取地物属性值](15-huo-qu-di-wu-shu-xing-zhi) - 深入了解属性访问的各种方法和技巧
- [修改地物属性值](16-xiu-gai-di-wu-shu-xing-zhi) - 掌握批量修改选中对象属性的方法
- [清除与初始化选择集](11-qing-chu-yu-chu-shi-hua-xuan-ze-ji) - 理解选择集的生命周期管理