PyQGIS用户输入验证脚本开发求助:按CSV规则校验图层属性
PyQGIS 图层字段验证脚本完善方案
以下是实现完整验证功能的脚本,涵盖CSV规则读取、图层存在性检查、多条件字段验证的全部需求:
import csv # 1. 读取CSV规则文件,处理表头与字段的空格问题 csv_path = r'layer1_Validation.csv' validation_rules = [] with open(csv_path, mode='r', newline='', encoding='utf-8') as file_obj: # 忽略逗号后的空格,确保表头键名无多余空格 reader_obj = csv.DictReader(file_obj, skipinitialspace=True) for row in reader_obj: # 清理每个字段的首尾空格,避免键名或值的空格干扰 cleaned_row = {k.strip(): v.strip() for k, v in row.items()} validation_rules.append(cleaned_row) # 2. 提取唯一图层名并检查是否存在于当前QGIS项目 project = QgsProject.instance() unique_layer_names = {rule['layer'] for rule in validation_rules} existing_layers = {} for layer_name in unique_layer_names: matched_layers = project.mapLayersByName(layer_name) if matched_layers: existing_layers[layer_name] = matched_layers[0] print(f"图层 '{layer_name}' 已找到") else: print(f"警告:图层 '{layer_name}' 不存在于当前项目,跳过该图层验证") # 3. 按图层分组存储验证规则,提升处理效率 rules_grouped_by_layer = {} for rule in validation_rules: layer_name = rule['layer'] if layer_name not in rules_grouped_by_layer: rules_grouped_by_layer[layer_name] = [] rules_grouped_by_layer[layer_name].append(rule) # 4. 执行字段验证逻辑 for layer_name, rules in rules_grouped_by_layer.items(): if layer_name not in existing_layers: continue target_layer = existing_layers[layer_name] print(f"\n=== 开始验证图层: {layer_name} ===") for rule in rules: field_name = rule['columnname'] condition = rule['condition'] allowed_values = rule['values'].split(',') if rule['values'] else [] # 先检查字段是否存在于图层中 if field_name not in [field.name() for field in target_layer.fields()]: print(f"⚠️ 图层 '{layer_name}' 无字段 '{field_name}',跳过该规则") continue print(f" 验证字段: {field_name} | 条件: {condition}") invalid_records = [] # 处理不同验证条件 for feature in target_layer.getFeatures(): raw_value = feature[field_name] processed_value = str(raw_value).strip() # 处理"not blank"(含可选integer校验) if 'not blank' in condition: # 检查非空 if not processed_value: invalid_records.append((feature.id(), "值为空或仅含空格")) # 额外验证整数类型(如果条件包含integer) if ',integer' in condition: try: int(processed_value) except ValueError: invalid_records.append((feature.id(), "值不是有效整数")) # 处理"matching"条件 elif condition == 'matching': # 空值处理:如果允许值包含NA则跳过空值错误 if not processed_value: if 'NA' not in allowed_values: invalid_records.append((feature.id(), "值为空且不在允许列表")) else: if processed_value not in allowed_values: invalid_records.append((feature.id(), f"值不在允许列表: {', '.join(allowed_values)}")) # 输出该字段的验证结果 if invalid_records: print(f" ❌ 发现 {len(invalid_records)} 个无效要素:") for feat_id, reason in invalid_records: print(f" 要素ID {feat_id}: {reason}") else: print(f" ✅ 所有要素均符合规则")
关键功能说明
- CSV预处理:自动处理表头和字段中的空格,避免因格式问题导致的键名不匹配
- 图层校验:提前检查CSV中指定的图层是否存在,不存在则跳过对应规则
- 字段存在性检查:验证前先确认图层包含目标字段,避免运行时错误
- 多条件支持:
not blank:检查值是否为空/仅空格,附带,integer时额外验证整数类型matching:校验值是否在指定列表中,支持NA作为空值的允许选项
- 结果可视化:清晰输出每个字段的验证状态,无效要素标注ID和错误原因
内容的提问来源于stack exchange,提问作者Ayan
相关产品推荐
相关产品推荐

