167 lines
7.3 KiB
Python
167 lines
7.3 KiB
Python
|
|
# -*- 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("清理完成。") |