# -*- coding: utf-8 -*- import sys import arcpy from pathlib import Path sys.path.append(str(Path(__file__).parent)) from tools.config.arcgis_field_cal_code import codeblock_dltb_ejdl, codeblock_dltb_yjdl def export_to_points(ph_points, dltb_features, trlx_features, xzq_features, assign_raster, workspace): # --- 1. 设置工作空间和变量 --- # 请根据您的实际情况修改以下路径 arcpy.env.workspace = workspace arcpy.env.overwriteOutput = True # 输入的要素类 input_features = ph_points # 历史样点PH数据 join_features_list = [trlx_features,xzq_features,dltb_features] # 连接图层 (规划分区) # 输出的要素类 final_output_fc = "历史样点PH信息_Table" # --- 3. 主处理逻辑 --- try: print("开始处理赋值样点PH信息...") target_features = f"in_memory/temp_sample_raster" # 将栅格数据提取至历史PH样点 arcpy.sa.ExtractValuesToPoints( in_point_features=input_features, in_raster=assign_raster, out_point_features=target_features, interpolate_values="NONE", add_attributes="VALUE_ONLY" ) print("开始计算地类一二级类别...") # 计算地类图斑一级、二级类别 try: arcpy.management.CalculateField(dltb_features, "EJDL", "calculate_ejdl(!DLBM!,!DLMC!)", "PYTHON3", codeblock_dltb_ejdl) arcpy.management.CalculateField(dltb_features, "YJDL", "calculate_yjdl(!DLBM!)", "PYTHON3", codeblock_dltb_yjdl) arcpy.management.CalculateField(dltb_features, "YJDLBM", "!DLBM![:2]", "PYTHON3") raster_path = Path(assign_raster) # if "二普" in raster_path.stem or "测土" in raster_path.stem: arcpy.management.CalculateField(target_features, "dPH", "!RASTERVALU!-!PH!", "PYTHON3", field_type="DOUBLE") # else: # arcpy.management.CalculateField(target_features, "dPH", "!PH!-!RASTERVALU!", "PYTHON3", field_type="DOUBLE") except Exception as e: print(e) # --- 2. 定义要保留的字段 --- # 这是一个非常清晰的配置方式:指定每个图层要保留的字段列表 fields_to_keep = { target_features: ["PH", "RASTERVALU", "dPH"], trlx_features: ["YL", "TS"], xzq_features: ["XZQMC"], dltb_features: ["YJDL", "EJDL"] } print("开始配置字段映射...") # 初始化当前的目标图层,最开始是原始的目标图层 current_target = target_features # 存储所有中间生成的临时文件,以便最后清理 temp_outputs = [] temp_outputs.append(target_features) # 获取目标图层的所有字段,以便在后续迭代中保留 retained_fields = fields_to_keep.get(target_features, []) # 迭代处理每一个连接图层 for i, join_features in enumerate(join_features_list): print(f"\n--- 开始处理第 {i+1} 个连接图层: {join_features} ---") # 检查连接图层是否存在 if not arcpy.Exists(join_features): print(f"警告: 连接图层 '{join_features}' 不存在,将跳过此连接。") continue # --- 配置 FieldMappings --- field_mappings = arcpy.FieldMappings() # a. 保留已经存在于 current_target 中的字段 # 这些字段是在之前的迭代中保留下来的 for field_name in retained_fields: try: field_map = arcpy.FieldMap() field_map.addInputField(current_target, field_name) field_mappings.addFieldMap(field_map) except Exception: # 如果字段在之前的某个步骤中未能成功添加,这里会捕获异常 print(f"注意: 在图层 '{current_target}' 中未找到字段 '{field_name}',可能在之前的步骤中已被跳过。") # b. 从当前的 join_features 中添加新字段 fields_from_current_join = fields_to_keep.get(join_features, []) for field_name in fields_from_current_join: try: field_map = arcpy.FieldMap() field_map.addInputField(join_features, field_name) field_map.mergeRule = "First" # 对所有连接字段使用 "First" 规则 field_mappings.addFieldMap(field_map) except Exception as e: print(f"警告: 添加字段 '{field_name}' (来自 '{join_features}') 时出错,将跳过。错误信息: {e}") # 如果本次迭代没有有效的字段映射,则跳过 if field_mappings.fieldCount == 0: print(f"警告: 对于连接图层 '{join_features}' 没有有效的字段可以添加,跳过此连接。") continue # 定义本次连接的临时输出名 # 使用 in_memory 工作空间可以提高性能 temp_output = f"in_memory/temp_join_{i}" temp_outputs.append(temp_output) print(f"执行空间连接: '{current_target}' + '{join_features}' -> '{temp_output}'") # 执行空间连接 arcpy.analysis.SpatialJoin( target_features=current_target, join_features=join_features, out_feature_class=temp_output, join_operation="JOIN_ONE_TO_ONE", join_type="KEEP_ALL", field_mapping=field_mappings, match_option="INTERSECT" ) # 更新 current_target 为本次操作的输出,以便下一次迭代使用 current_target = temp_output # 更新已保留字段列表,为下一次迭代做准备 retained_fields.extend(fields_from_current_join) print(f"连接成功。目前已保留的字段: {retained_fields}") # --- 4. 保存最终结果并清理 --- # 将最后一个临时输出复制或重命名为最终结果 if arcpy.Exists(current_target): print(f"\n所有连接完成。将最终结果 '{current_target}' 保存为 '{final_output_fc}'...") # arcpy.management.CopyFeatures(current_target, final_output_fc) arcpy.conversion.ExportTable(current_target, final_output_fc) print("最终结果已保存。") # 验证输出字段 output_fields = [f.name for f in arcpy.ListFields(final_output_fc)] print(f"最终输出的字段为: {output_fields}") else: print("警告: 没有任何连接操作成功执行,未生成最终输出。") except arcpy.ExecuteError: print("\n--- ArcPy 执行错误 ---") print(arcpy.GetMessages(2)) except Exception as e: print(f"\n--- 发生未预料的错误 ---") print(e) finally: # 清理所有中间生成的临时文件 print("\n开始清理临时文件...") for temp_file in temp_outputs: if arcpy.Exists(temp_file): arcpy.management.Delete(temp_file) print(f"已删除临时文件: {temp_file}") print("清理完成。")