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

16 KiB
Raw Permalink Blame History

本页面介绍 SunvStation Python 脚本中执行过滤查询的方法。selectFilter() 方法是选择集查询的核心执行环节,它根据之前设置的选择条件,从数据源中筛选出符合条件的地理对象,并将结果填充到脚本选择集中。掌握此方法的执行机制和结果处理,是构建高效数据查询脚本的关键。

Sources: ssprocess_mixins/selection_mixin.py

核心方法概述

selectFilter() 方法负责执行实际的选择集过滤操作。该方法内部协调搜索助手 searchHelper,通过两阶段查询机制完成对象筛选:首先获取候选对象列表,然后根据完整条件进行精确过滤,最后将结果分类存储到脚本选择集中。

SSProcess.selectFilter()

Sources: ssprocess_mixins/selection_mixin.py

方法返回值:该方法无返回值,执行结果通过脚本选择集成员变量 selGeoList(点线面对象)和 selNoteList(注记对象)提供访问。查询成功后,可以使用 getSelGeoCount()getSelNoteCount() 获取结果数量,使用 getSelGeoValue() 等方法遍历对象属性。

Sources: ssprocess_mixins/selection_mixin.py

执行流程

过滤查询的执行过程包含四个关键阶段:缓存清理、候选对象获取、精确过滤、结果分类存储。整个流程由进度条模块提供可视化反馈,确保操作透明可控。

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

进度反馈机制:方法执行过程中会调用 stepProgress() 方法报告当前进度,包括"清理缓存"、"执行选择过滤"、"更新选择集"、"完成选择集过滤"四个阶段。开发者可以通过 enable_progress 属性控制是否显示进度条。

Sources: ssprocess_mixins/selection_mixin.py

详细执行步骤

步骤一:清理缓存

执行查询前,方法首先清理属性缓存字段 curSelGeoFieldscurSelGeoValues。这两个字符串数组用于存储当前选中对象的属性字段和对应值,清理缓存确保新的查询结果不会受到之前属性访问的干扰。

Sources: ssprocess_mixins/selection_mixin.py

步骤二:获取候选对象

方法创建临时的 GeoBaseList 容器,并调用 searchHelper.getFilterObj() 方法。该方法根据 m_selectConditions 中存储的选择条件,从当前数据源中获取满足条件的候选对象列表。这一步是初步筛选,可能包含部分不完全符合所有条件的对象。

Sources: ssprocess_mixins/selection_mixin.py

步骤三:精确过滤

如果候选对象列表非空,方法调用 searchHelper.filterObj() 进行精确过滤。这一步对候选对象应用完整的条件规则集合,确保最终结果严格满足所有设置的条件。只有通过精确过滤的对象才会被加入最终的选择集。

Sources: ssprocess_mixins/selection_mixin.py

步骤四:结果分类存储

最后,方法遍历过滤后的对象列表,根据对象类型将其分类存储:注记对象(e_Note_Obj)添加到 selNoteList,其他类型的点线面对象添加到 selGeoList。这种分离存储便于后续对不同类型对象进行差异化处理。

Sources: ssprocess_mixins/selection_mixin.py

完整使用示例

以下示例展示了一个完整的过滤查询流程,从条件设置到结果处理的各个步骤。

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

基础查询示例

# 准备阶段:清除旧的状态
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

多条件复合查询

# 清除状态
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的面对象")

使用多值和区间查询

# 清除状态
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

查询前后的选择集状态对比

下表展示了执行 selectFilter() 前后脚本选择集的典型状态变化。

状态指标 查询前 查询后 说明
selGeoList 对象数量 0 或旧值 新查询结果数量 完全替换,非追加
selNoteList 对象数量 0 或旧值 新查询结果数量 完全替换,非追加
m_selectConditions 条件数量 保持不变 保持不变 条件不受影响
curSelGeoFields 旧值或空 缓存已清理
curSelGeoValues 旧值或空 缓存已清理

Sources: ssprocess_mixins/selection_mixin.py

重要特性selectFilter() 是"替换模式"而非"追加模式"。每次执行都会完全重写 selGeoListselNoteList,之前的选择集结果会被完全覆盖。如果需要保留之前的结果,应在调用前将结果保存到其他容器中。

Sources: ssprocess_mixins/selection_mixin.py

结果处理最佳实践

检查查询结果

执行查询后,首先检查结果数量,避免对空列表进行操作。

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.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

同步到系统选择集

如果需要在地图上高亮显示查询结果,使用 updateSysSelection() 方法同步。

# 执行查询
SSProcess.selectFilter()

# 同步到系统选择集(更新地图显示)
SSProcess.updateSysSelection(1)  # mode=1 表示更新显示

Sources: ssprocess_mixins/selection_mixin.py

常见问题与故障排除

问题一:查询结果为空

症状:调用 selectFilter() 后,getSelGeoCount() 返回 0。

可能原因与解决方案

原因 检查方法 解决方案
条件设置过于严格 使用宽泛条件重新查询 放宽筛选条件,如使用 LIKE 代替 ==
条件名称拼写错误 检查 SSObj_ 前缀是否正确 参考 设置选择条件 中的属性列表
数据源为空 检查当前地图是否加载了数据 确保地图已打开并加载了相应图层
多条件逻辑冲突 逐一测试每个条件 简化条件,逐步增加约束

Sources: ssprocess_mixins/selection_mixin.py

问题二:查询结果不符合预期

症状:查询结果数量不为零,但结果对象不符合预期条件。

排查步骤

# 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

问题三:进度条不显示

症状:调用 selectFilter() 时没有看到进度条提示。

解决方案:检查 enable_progress 属性是否被禁用。

# 确保启用进度条
SSProcess.enable_progress = True

# 执行查询
SSProcess.selectFilter()

Sources: ssprocess_mixins/selection_mixin.py

问题四:性能问题

症状:大规模数据查询执行缓慢。

优化建议

优化方向 具体措施 预期效果
减少条件复杂度 避免使用多个模糊匹配条件 减少候选对象范围
使用精确匹配 优先使用 == 代替 LIKE 加速索引查找
分批处理 对大数据集分页查询 降低单次查询压力
利用索引 确保查询字段建立了索引 显著提升查询速度

Sources: ssprocess_mixins/selection_mixin.py

完整工作流示例

以下示例展示了一个包含错误处理、进度反馈和结果导出的完整工作流。

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

与其他方法的协作关系

selectFilter() 方法在 SunvStation 脚本体系中处于核心位置,与其他选择集相关方法形成完整的数据查询链路。

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

方法调用顺序:通常的调用顺序为 clearSelection()clearSelectCondition()setSelectCondition()(可多次)→ selectFilter() → 结果处理 → updateSysSelection()(可选)。clearSelection() 也可以在处理完结果后调用,为下一次查询做准备。

Sources: PySSProcess.py

延伸阅读

完成本页面学习后,建议继续阅读以下相关页面以构建完整的选择集操作知识体系: