Files
sunvpy-docs/docs/content/13-zhi-xing-guo-lu-cha-xun.md
2026-04-10 13:47:53 +08:00

417 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.
本页面介绍 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) - 理解选择集的生命周期管理