本页面介绍 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
清除旧结果] B --> C[clearSelectCondition
清除旧条件] C --> D[setSelectCondition
设置查询条件] D --> E[selectFilter
执行过滤] 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
清除条件] --> B[setSelectCondition
设置条件] B --> C[selectFilter
执行查询] C --> D[getSelGeoCount/getSelNoteCount
获取数量] C --> E[getSelGeoValue
获取属性] C --> F[updateSysSelection
同步显示] C --> G[clearSelection
清除结果] 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) - 理解选择集的生命周期管理