Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-04-23 17:30:48 +08:00
parent 4857cb6e45
commit 6313905356
8 changed files with 313 additions and 108 deletions

View File

@@ -43,15 +43,15 @@ def get_prop_level(prop_level):
if pd.isna(prop_level) or str(prop_level) == "0":
return "-"
# 请根据您的实际分级标准调整这里的阈值
if str(prop_level) == "8" or prop_level == '砂土及壤质砂土':
if str(prop_level) == "1" or prop_level == '砂土及壤质砂土':
return "砂质"
elif str(prop_level) == "11" or prop_level == '砂质壤土':
elif str(prop_level) == "2" or prop_level == '砂质壤土':
return "砂壤质"
elif str(prop_level) in ["6","3"] or prop_level in ['粉砂质壤土', '壤土']:
elif str(prop_level) in ["3","4"] or prop_level in ['粉砂质壤土', '壤土']:
return "壤质"
elif str(prop_level) in ["1","4","9"] or prop_level in ['粉砂质年壤土', '黏壤土', '砂质黏壤土']:
elif str(prop_level) in ["5","6","7"] or prop_level in ['粉砂质年壤土', '黏壤土', '砂质黏壤土']:
return "黏壤质"
elif str(prop_level) in ["2","5","7","10","12"] or prop_level in ['粉砂质黏土', '黏土', '壤质黏土', '砂质黏土', '重黏土']:
elif str(prop_level) in ["8","9","10","11","12"] or prop_level in ['粉砂质黏土', '黏土', '壤质黏土', '砂质黏土', '重黏土']:
return "黏质"
else:
return "-"

View File

@@ -259,7 +259,7 @@ def process_data_for_table1(gdb_path, soil_prop_feature_name, df_origin_area, ta
return df_final, stat_sample
# --- 3. Excel 制表 总表---
def write_to_excel_table1(df:pd.DataFrame, output_path, prop_config, soil_prop_tif, stat_sample):
def write_to_excel_table1(df:pd.DataFrame, output_path, prop_config, stats_map, stat_sample):
"""
【最终修正版】: 将处理好的数据写入格式化的 Excel 文件。
"""
@@ -271,30 +271,35 @@ def write_to_excel_table1(df:pd.DataFrame, output_path, prop_config, soil_prop_t
wb.save(output_path)
return
# 全区制图统计
"""
try:
raster = arcpy.Raster(soil_prop_tif)
# # 全区制图统计
# try:
# raster = arcpy.Raster(soil_prop_tif)
# 转换为numpy数组进行计算
array = arcpy.RasterToNumPyArray(raster,nodata_to_value=9999)
# # 按行政区蒙膜区域统计
# out_raster = arcpy.sa.ExtractByMask(
# in_raster=raster,
# in_mask_data=tif_mask,
# extraction_area="INSIDE"
# )
# # 转换为numpy数组进行计算
# array = arcpy.RasterToNumPyArray(out_raster,nodata_to_value=9999)
# 过滤掉NoData值
# 过滤NoData值和9999值
array = array[~np.isnan(array)] # 过滤NoData
array = array[array != 9999] # 过滤9999
array = array.astype(np.float64)
# # 过滤掉NoData值
# # 过滤NoData值和9999值
# array = array[~np.isnan(array)] # 过滤NoData
# array = array[array != 9999] # 过滤9999
# array = array.astype(np.float64)
stats = {
'min': round(np.min(array),2),
'max': round(np.max(array),2),
'mean': round(np.mean(array),2),
'median': round(np.median(array),2),
'std': round(np.std(array),2)
}
except Exception as e:
print(f"错误: {e}")
"""
# stats_map = {
# 'min': round(np.min(array),2),
# 'max': round(np.max(array),2),
# 'mean': round(np.mean(array),2),
# 'median': round(np.median(array),2),
# 'std': round(np.std(array),2)
# }
# except Exception as e:
# print(f"错误: {e}")
# 全区样点统计
stats = stat_sample
@@ -419,17 +424,26 @@ def write_to_excel_table1(df:pd.DataFrame, output_path, prop_config, soil_prop_t
ws.cell(row=current_row, column=6).value = '100'
# 3. 合计单元格填充
ws.merge_cells(f'B{current_row + 1}:F{current_row + 1}')
ws.merge_cells(f'A{current_row + 1}:B{current_row + 1}')
ws.cell(row=current_row + 1, column=1).value = '全区均值'
ws.cell(row=current_row + 1, column=2).value = f'{stats["mean"]:.{prop_name}}'
ws.merge_cells(f'C{current_row + 1}:D{current_row + 1}')
ws.cell(row=current_row + 1, column=3).value = f'{stats["mean"]:.{prop_name}}'
ws.merge_cells(f'E{current_row + 1}:F{current_row + 1}')
ws.cell(row=current_row + 1, column=5).value = f'{stats_map["mean"]:.{prop_name}}'
ws.merge_cells(f'B{current_row + 2}:F{current_row + 2}')
ws.merge_cells(f'A{current_row + 2}:B{current_row + 2}')
ws.cell(row=current_row + 2, column=1).value = '全区中位值'
ws.cell(row=current_row + 2, column=2).value = f'{stats["median"]:.{prop_name}}'
ws.merge_cells(f'C{current_row + 2}:D{current_row + 2}')
ws.cell(row=current_row + 2, column=3).value = f'{stats["median"]:.{prop_name}}'
ws.merge_cells(f'E{current_row + 2}:F{current_row + 2}')
ws.cell(row=current_row + 2, column=5).value = f'{stats_map["median"]:.{prop_name}}'
ws.merge_cells(f'B{current_row + 3}:F{current_row + 3}')
ws.merge_cells(f'A{current_row + 3}:B{current_row + 3}')
ws.cell(row=current_row + 3, column=1).value = '全区范围'
ws.cell(row=current_row + 3, column=2).value = f'{stats["min"]:.{prop_name}} {stats["max"]:.{prop_name}}'
ws.merge_cells(f'C{current_row + 3}:D{current_row + 3}')
ws.cell(row=current_row + 3, column=3).value = f'{stats["min"]:.{prop_name}} {stats["max"]:.{prop_name}}'
ws.merge_cells(f'E{current_row + 3}:F{current_row + 3}')
ws.cell(row=current_row + 3, column=5).value = f'{stats_map["min"]:.{prop_name}} {stats_map["max"]:.{prop_name}}'
# --- a. 定义样式 ---
header_font = Font(name='宋体', size=11, bold=True)
@@ -447,7 +461,7 @@ def write_to_excel_table1(df:pd.DataFrame, output_path, prop_config, soil_prop_t
print("Excel 报告生成成功!")
def main(gdb_path, soil_prop_name, reclassed_features_path, dltb_features, soil_prop_tif, output_path, target_area_dict,xzqmc, prop_config):
def main(gdb_path, soil_prop_name, reclassed_features_path, dltb_features, stats_map, output_path, target_area_dict,xzqmc, prop_config):
try:
# --- 1. 用户配置 ---
# 输出配置
@@ -493,10 +507,24 @@ def main(gdb_path, soil_prop_name, reclassed_features_path, dltb_features, soil_
)
clipped_table_df = arcgis_utils.read_arcgis_table(temp_out_tables_area)
# 定义需要过滤地类的属性列表
filtered_props = ['ECA', 'EMG', 'ACU', 'AZN', 'AFE', 'AMN', 'AMO', 'AB', 'AS1', 'TSE']
dltb_features = os.path.join(gdb_path, "地类图斑")
# 生成表1 土壤属性分级分布 的统计Excel报告
final_dataframe,stat = process_data_for_table1(gdb_path, soil_prop_name, clipped_table_df, target_area_dict,xzqmc,is_by_xzq, prop_config)
write_to_excel_table1(final_dataframe, output_excel_path, prop_config, soil_prop_tif, stat)
# 过滤地类图斑
temp_mask = r"in_memory/temp_dltb_features_filtered"
temp_files.append(temp_mask)
if soil_prop_name == "GZCHD":
arcpy.conversion.ExportFeatures(dltb_features, temp_mask, "DLBM LIKE '01%'")
if soil_prop_name in filtered_props:
arcpy.conversion.ExportFeatures(dltb_features, temp_mask, "DLBM LIKE '01%' OR DLBM LIKE '02%'")
else:
temp_mask = dltb_features
write_to_excel_table1(final_dataframe, output_excel_path, prop_config, stats_map, stat)
# return df_with_factors
except Exception as e:

View File

@@ -72,7 +72,7 @@ def process_data_for_table2(gdb_path, soil_prop_feature_name, df_dltb, target_ar
return df_final
# 写入EXCEL 表2
def write_to_excel_table2(df, output_path, prop_config:dict, soil_prop_name: str = ''):
def write_to_excel_table2(df, output_path,stats_map, prop_config:dict, soil_prop_name: str = ''):
"""
将处理好的数据写入格式化的 Excel 文件。
"""
@@ -260,7 +260,7 @@ def write_to_excel_table2(df, output_path, prop_config:dict, soil_prop_name: str
ws.cell(row=current_row, column=4).value = total_range
ws.cell(row=current_row, column=5).value = f"{total_counts:.0f}" if total_counts > 0 else "-"
if pd.notna(total_zhitu_mean):
ws.cell(row=current_row, column=6).value = f"{total_zhitu_mean:.{prop_name}}"
ws.cell(row=current_row, column=6).value = f"{stats_map['mean']:.{prop_name}}"
else:
ws.cell(row=current_row, column=6).value = "-"
ws.cell(row=current_row, column=7).value = f"{total_areas:.0f}" if total_areas > 0 else "-"
@@ -285,7 +285,7 @@ def write_to_excel_table2(df, output_path, prop_config:dict, soil_prop_name: str
print("Excel 报告生成成功!")
def main(gdb_path, soil_prop_name, dltb_features, soil_prop_tif, output_path,target_areas_df, prop_config):
def main(gdb_path, soil_prop_name, dltb_features, soil_prop_tif, output_path,target_areas_df, prop_config,stats_map):
try:
# --- 1. 用户配置 ---
# 输出配置
@@ -311,7 +311,7 @@ def main(gdb_path, soil_prop_name, dltb_features, soil_prop_tif, output_path,tar
final_dataframe = process_data_for_table2(gdb_path, soil_prop_name, dltb_df, target_areas_df)
# final_dataframe = process_data_for_table5_2(gdb_path, out_table_area, sample_table_name, df_with_factors)
write_to_excel_table2(final_dataframe, output_excel_path, prop_config, soil_prop_name)
write_to_excel_table2(final_dataframe, output_excel_path,stats_map, prop_config, soil_prop_name)
# return df_with_factors
except Exception as e:

View File

@@ -55,7 +55,6 @@ def process_data_for_table3(soil_prop_name, df_trlx_sample, df_trlx_zhitu, df_tr
filtered_props = ['ECA', 'EMG', 'ACU', 'AZN', 'AFE', 'AMN', 'AMO', 'AB', 'AS1', 'TSE']
# 拿到目标df总面积计算比例进行平差
print(target_areas_df)
if soil_prop_name == "GZCHD":
target_areas = target_areas_df[target_areas_df['EJDL'] == '耕地']['面积'].values[0]
elif soil_prop_name in filtered_props:
@@ -91,7 +90,7 @@ def process_data_for_table3(soil_prop_name, df_trlx_sample, df_trlx_zhitu, df_tr
return df_final, df_sample_mymz
# 写入EXCEL 表2
def write_to_excel_table3(df, output_path, prop_config:dict, stats):
def write_to_excel_table3(df, output_path, prop_config:dict, stats,stats_map):
"""
将处理好的数据写入格式化的 Excel 文件。
"""
@@ -246,9 +245,9 @@ def write_to_excel_table3(df, output_path, prop_config:dict, stats):
# total_mean = total_weighted_sum.sum() / total_counts
# total_median = df_to_write['median'].mean()
total_range = f"{df_to_write['min'].min():.{prop_name}}{df_to_write['max'].max():.{prop_name}}"
total_zhitu_weighted_sum = df_to_write['制图均值'] * df_to_write['面积_亩']
# total_zhitu_weighted_sum = df_to_write['制图均值'] * df_to_write['面积_亩']
total_areas = df_to_write['面积_亩'].sum()
total_zhitu_mean = total_zhitu_weighted_sum.sum() / total_areas
# total_zhitu_mean = total_zhitu_weighted_sum.sum() / total_areas
ws.merge_cells(start_row=current_row, start_column=1, end_row=current_row, end_column=2)
ws.cell(row=current_row, column=1).value = '全区'
@@ -256,7 +255,7 @@ def write_to_excel_table3(df, output_path, prop_config:dict, stats):
ws.cell(row=current_row, column=4).value = f"{stats['median']:.{prop_name}}"
ws.cell(row=current_row, column=5).value = total_range
ws.cell(row=current_row, column=6).value = f"{stats['count']:.0f}"
ws.cell(row=current_row, column=7).value = f"{total_zhitu_mean:.{prop_name}}"
ws.cell(row=current_row, column=7).value = f"{stats_map['mean']:.{prop_name}}"
ws.cell(row=current_row, column=8).value = f"{total_areas:.0f}"
# --- a. 定义样式 ---
@@ -397,7 +396,7 @@ def write_to_excel_table4(df:pd.DataFrame, output_path, prop_config, stats):
print(f"数据已成功写入到 {output_path}")
def main(gdb_path, soil_prop_name, trlx_features, soil_prop_tif, output_path,target_areas_df, prop_config, dltb_features):
def main(gdb_path, soil_prop_name, trlx_features, soil_prop_tif, output_path,target_areas_df, prop_config, dltb_features,stats_map):
try:
# --- 1. 用户配置 ---
# 输出配置
@@ -411,16 +410,6 @@ def main(gdb_path, soil_prop_name, trlx_features, soil_prop_tif, output_path,tar
arcpy.env.overwriteOutput = True
print("开始处理数据...")
if soil_prop_name == "GZCHD":
temp_gdtb_trlx_out = r"in_memory/temp_gdtb_trlx_out"
temp_gdtb_trlx = r"in_memory/temp_gdtb_trlx"
temp_files.append(temp_gdtb_trlx)
temp_out_features = r"in_memory/temp_out_type_features"
out_table_mean = r"in_memory/out_table_type_mean"
temp_files.append(temp_out_features)
temp_files.append(out_table_mean)
# 2. 用样点进行空间连接到土壤类型图斑
fields_to_keep = {
soil_prop_features: [soil_prop_name],
@@ -442,25 +431,37 @@ def main(gdb_path, soil_prop_name, trlx_features, soil_prop_tif, output_path,tar
# 定义需要过滤地类的属性列表
filtered_props = ['ECA', 'EMG', 'ACU', 'AZN', 'AFE', 'AMN', 'AMO', 'AB', 'AS1', 'TSE']
if soil_prop_name == "GZCHD":
temp_gdtb_trlx_out = r"in_memory/temp_gdtb_trlx_out"
temp_files.append(temp_gdtb_trlx_out)
# 2. 创建临时图斑用于过滤、土壤类型与地类图斑相交
# 用于样点
temp_out_features = r"in_memory/temp_out_type_features"
out_table_mean = r"in_memory/out_table_type_mean"
temp_files.append(temp_out_features)
temp_files.append(out_table_mean)
# 用于制图
temp_gdtb_trlx_filtered = r"in_memory/temp_gdtb_trlx_filtered"
temp_gdtb_trlx_out_filtered = r"in_memory/temp_gdtb_trlx_out_filtered"
temp_files.append(temp_gdtb_trlx_filtered)
temp_files.append(temp_gdtb_trlx_out_filtered)
# 空间连接
arcpy.analysis.SpatialJoin(soil_prop_features, trlx_features, temp_out_features, "JOIN_ONE_TO_ONE", "KEEP_ALL",field_mappings, "INTERSECT")
# 交集土壤类型与土地利用图斑
arcpy.analysis.Intersect([trlx_features, dltb_features], temp_gdtb_trlx_filtered, 'NO_FID')
# 3. 交集土壤类型与土地利用图斑
if soil_prop_name == "GZCHD":
arcpy.analysis.Intersect([trlx_features, dltb_features], temp_gdtb_trlx, 'NO_FID')
arcpy.conversion.ExportFeatures(temp_gdtb_trlx,temp_gdtb_trlx_out,"DLBM LIKE '01%'")
arcpy.conversion.ExportFeatures(temp_gdtb_trlx_filtered,temp_gdtb_trlx_out,"DLBM LIKE '01%'")
# 3. 以表格显示分区统计 计算均值
# 以表格显示分区统计 计算均值
arcpy.sa.ZonalStatisticsAsTable(temp_gdtb_trlx_out, "YL_TS", soil_prop_tif, out_table_mean, "DATA", "MEAN")
trlx_area_df = pd.DataFrame(arcpy.da.FeatureClassToNumPyArray(temp_gdtb_trlx_out, ["YL", "TS", "Shape@Area"]))
# 如果当前属性在列表中,则只统计耕地和园地
elif soil_prop_name in filtered_props:
temp_gdtb_trlx_filtered = r"in_memory/temp_gdtb_trlx_filtered"
temp_gdtb_trlx_out_filtered = r"in_memory/temp_gdtb_trlx_out_filtered"
temp_files.append(temp_gdtb_trlx_filtered)
temp_files.append(temp_gdtb_trlx_out_filtered)
# 交集土壤类型与土地利用图斑
arcpy.analysis.Intersect([trlx_features, dltb_features], temp_gdtb_trlx_filtered, 'NO_FID')
# 导出耕地和园地DLBM LIKE '01%' OR DLBM LIKE '02%'
arcpy.conversion.ExportFeatures(temp_gdtb_trlx_filtered, temp_gdtb_trlx_out_filtered, "DLBM LIKE '01%' OR DLBM LIKE '02%'")
@@ -472,7 +473,7 @@ def main(gdb_path, soil_prop_name, trlx_features, soil_prop_tif, output_path,tar
print(f"过滤制图数据仅统计耕地和园地DLBM LIKE '01%' OR '02%'")
else:
# 3. 以表格显示分区统计 计算均值
arcpy.sa.ZonalStatisticsAsTable(trlx_features, "YL_TS", soil_prop_tif, out_table_mean, "DATA", "MEAN")
arcpy.sa.ZonalStatisticsAsTable(temp_gdtb_trlx_filtered, "YL_TS", soil_prop_tif, out_table_mean, "DATA", "MEAN")
# 获取土壤类型图斑面积
trlx_area_df = pd.DataFrame(arcpy.da.FeatureClassToNumPyArray(trlx_features, ["YL", "TS", "Shape@Area"]))
@@ -493,7 +494,7 @@ def main(gdb_path, soil_prop_name, trlx_features, soil_prop_tif, output_path,tar
# print(final_dataframe)
# 生成表3
write_to_excel_table3(final_dataframe, output_excel_path, prop_config, stat_sample)
write_to_excel_table3(final_dataframe, output_excel_path, prop_config, stat_sample,stats_map)
# 母岩母质表
write_to_excel_table4(df_mymz, output_excel4_path, prop_config,stat_sample)