You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:15:34