@@ -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 "-"
|
||||
|
||||
@@ -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_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 = {
|
||||
'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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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']
|
||||
|
||||
# 空间连接
|
||||
arcpy.analysis.SpatialJoin(soil_prop_features, trlx_features, temp_out_features, "JOIN_ONE_TO_ONE", "KEEP_ALL",field_mappings, "INTERSECT")
|
||||
|
||||
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%'")
|
||||
temp_gdtb_trlx_out = r"in_memory/temp_gdtb_trlx_out"
|
||||
temp_files.append(temp_gdtb_trlx_out)
|
||||
|
||||
# 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:
|
||||
# 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.conversion.ExportFeatures(temp_gdtb_trlx_filtered,temp_gdtb_trlx_out,"DLBM LIKE '01%'")
|
||||
|
||||
# 以表格显示分区统计 计算均值
|
||||
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:
|
||||
# 导出耕地和园地(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)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
import uuid
|
||||
@@ -92,6 +93,27 @@ def log_arcpy_message(message):
|
||||
sys.stderr.write(f"ArcPyError:{message.message}\n")
|
||||
sys.stderr.flush()
|
||||
|
||||
# 判断单元格类型
|
||||
def get_merge_type(merged_range):
|
||||
"""
|
||||
判断合并类型
|
||||
返回: 'row'(行合并), 'column'(列合并), 'both'(行列合并)或 None(不是合并单元格)
|
||||
"""
|
||||
if not merged_range:
|
||||
return None
|
||||
|
||||
min_row, max_row = merged_range.min_row, merged_range.max_row
|
||||
min_col, max_col = merged_range.min_col, merged_range.max_col
|
||||
|
||||
if max_row > min_row and max_col > min_col:
|
||||
return 'both' # 同时跨行和跨列
|
||||
elif max_row > min_row:
|
||||
return 'row' # 行合并(垂直合并)
|
||||
elif max_col > min_col:
|
||||
return 'column' # 列合并(水平合并)
|
||||
else:
|
||||
return None # 实际上不是合并单元格
|
||||
|
||||
def get_specail_map(original_dict):
|
||||
grade_map = {}
|
||||
dict_len = len(original_dict)
|
||||
@@ -200,7 +222,8 @@ class SoilQualityReporter:
|
||||
# 复制数据并添加分组列
|
||||
df_stats = stats.copy()
|
||||
# df_stats["GRID_GROUP"] = df_stats["GRIDCODE"].apply(self._map_grade)
|
||||
if "YJDLBM" not in df_stats.columns:
|
||||
if "YJDLBM" not in df_stats.columns and "YNDLBM" in df_stats.columns:
|
||||
# 云南地区使用YNDLBM(二级地类)
|
||||
df = df_stats.pivot_table(
|
||||
index="YNDLBM",
|
||||
columns="GRIDCODE",
|
||||
@@ -210,6 +233,7 @@ class SoilQualityReporter:
|
||||
observed=False
|
||||
)
|
||||
else:
|
||||
# 其他地区使用YJDLBM(一级地类)
|
||||
df = df_stats.pivot_table(
|
||||
index="YJDLBM",
|
||||
columns="GRIDCODE",
|
||||
@@ -227,11 +251,46 @@ class SoilQualityReporter:
|
||||
# 按等级排序并添加总计
|
||||
df = df[self.all_grades]
|
||||
df["总计"] = df.sum(axis=1)
|
||||
df.loc["总计"] = df.sum(axis=0)
|
||||
|
||||
# 重命名索引和列
|
||||
df = df.rename(index=self.landuse_map)
|
||||
df.columns = [self.grade_map.get(str(col), str(col)) for col in df.columns]
|
||||
# 添加总计行
|
||||
df.loc["总计"] = df.sum(axis=0)
|
||||
|
||||
# 对于云南地区,添加耕地、园地合计
|
||||
if self.is_yunnan:
|
||||
# 定义排序顺序
|
||||
desired_order = ['水田', '水浇地', '旱地', '耕地合计', '果园', '茶园', '橡胶园', '其他园地', '园地合计', '林地', '草地', '其他', '总计']
|
||||
|
||||
# 检查是否存在水田、水浇地、旱地中的任意一个
|
||||
cultivated_types = ['水田', '水浇地', '旱地']
|
||||
existing_cultivated_types = [ctype for ctype in cultivated_types if ctype in df.index]
|
||||
if existing_cultivated_types:
|
||||
# 计算耕地合计
|
||||
cultivated_total = df.loc[existing_cultivated_types].sum()
|
||||
# 添加耕地合计行
|
||||
df.loc["耕地合计"] = cultivated_total
|
||||
|
||||
# 检查是否存在果园、茶园、橡胶园、其他园地中的任意一个
|
||||
other_garden_types = ['果园', '茶园', '橡胶园', '其他园地']
|
||||
existing_garden_types = [ctype for ctype in other_garden_types if ctype in df.index]
|
||||
if existing_garden_types:
|
||||
# 计算园地合计
|
||||
other_garden_total = df.loc[existing_garden_types].sum()
|
||||
# 添加园地合计行
|
||||
df.loc["园地合计"] = other_garden_total
|
||||
|
||||
# 过滤出实际存在的地类
|
||||
actual_order = [item for item in desired_order if item in df.index]
|
||||
|
||||
# 添加未在排序列表中的其他地类
|
||||
for item in df.index:
|
||||
if item not in actual_order and item != "总计":
|
||||
actual_order.append(item)
|
||||
|
||||
# 重新排序
|
||||
df = df.reindex(actual_order)
|
||||
|
||||
return df
|
||||
|
||||
@@ -351,20 +410,68 @@ class SoilQualityReporter:
|
||||
|
||||
# 写入数据
|
||||
for r_idx, (index, row) in enumerate(df.iterrows(), start=start_row+4):
|
||||
if self.is_yunnan and index in ['水田','水浇地','旱地', '果园', '茶园', '橡胶园', '其他园地', '耕地合计', '园地合计']:
|
||||
if index in ['耕地合计', '园地合计']:
|
||||
sheet.cell(row=r_idx, column=2, value="合计")
|
||||
else:
|
||||
sheet.cell(row=r_idx, column=2, value=index)
|
||||
else:
|
||||
sheet.merge_cells(f"A{r_idx}:B{r_idx}")
|
||||
sheet.cell(row=r_idx, column=1, value=index)
|
||||
|
||||
for c_idx, value in enumerate(row, start=2):
|
||||
sheet.cell(row=r_idx, column=c_idx+1, value=value)
|
||||
|
||||
# 对于云南地区,合并耕地行的A列
|
||||
if self.is_yunnan:
|
||||
# 查找水田、水浇地、旱地的行索引
|
||||
cultivated_rows = []
|
||||
other_garden_rows = []
|
||||
for r_idx, (index, _) in enumerate(df.iterrows(), start=start_row+4):
|
||||
if index in ['水田','水浇地','旱地']:
|
||||
cultivated_rows.append(r_idx)
|
||||
if index in ['果园', '茶园', '橡胶园', '其他园地']:
|
||||
other_garden_rows.append(r_idx)
|
||||
|
||||
# 合并耕地行的A列
|
||||
if cultivated_rows:
|
||||
start = cultivated_rows[0]
|
||||
end = cultivated_rows[-1]
|
||||
sheet.merge_cells(f"A{start}:A{end+1}")
|
||||
sheet[f"A{start}"] = "耕地"
|
||||
# 合并其他园地行的A列
|
||||
if other_garden_rows:
|
||||
start = other_garden_rows[0]
|
||||
end = other_garden_rows[-1]
|
||||
sheet.merge_cells(f"A{start}:A{end+1}")
|
||||
sheet[f"A{start}"] = "园地"
|
||||
|
||||
|
||||
def _apply_common_format(self, sheet, landuse_start_row):
|
||||
"""应用通用格式"""
|
||||
print("正在自动调整列宽...")
|
||||
dims = {}
|
||||
for row in sheet.rows:
|
||||
for cell in row:
|
||||
if cell.value:
|
||||
merged_range = next((range for range in sheet.merged_cells.ranges if cell.coordinate in range), None)
|
||||
if get_merge_type(merged_range) == 'column' or get_merge_type(merged_range) == 'both':
|
||||
continue
|
||||
if r'\n' in str(cell.value):
|
||||
continue
|
||||
# 获取字体大小
|
||||
font_size = cell.font.size
|
||||
cell_len = 0.7 * len(re.findall('([\u4e00-\u9fa5])', str(cell.value))) + len(str(cell.value)) * font_size
|
||||
# 计算列宽
|
||||
cell_len = cell_len / 8
|
||||
dims[cell.column] = max(dims.get(cell.column, 0), cell_len)
|
||||
# 设置列宽
|
||||
for col in range(1, sheet.max_column + 1):
|
||||
col_letter = chr(64 + col)
|
||||
sheet.column_dimensions[col_letter].width = 14
|
||||
for col, value in dims.items():
|
||||
len_val = max(value+4,14)
|
||||
sheet.column_dimensions[get_column_letter(int(col))].width = len_val
|
||||
|
||||
for row in range(5, sheet.max_row+1):
|
||||
if row not in [landuse_start_row,landuse_start_row+1, landuse_start_row+2,landuse_start_row+3]:
|
||||
for row in range(4, sheet.max_row+1):
|
||||
if row not in [landuse_start_row,landuse_start_row+1, landuse_start_row+2]:
|
||||
sheet.row_dimensions[row].height = 23
|
||||
|
||||
# 定义边框样式
|
||||
@@ -385,6 +492,10 @@ class SoilQualityReporter:
|
||||
if cell.column == 1 and cell.row > 3 and cell.row not in (landuse_start_row, landuse_start_row+2): # 列A
|
||||
cell.font = Font(bold=False, size=14)
|
||||
|
||||
# B列bold = False
|
||||
if cell.column == 2 and cell.row > 3 and cell.row not in (landuse_start_row, landuse_start_row+2):
|
||||
cell.font = Font(bold=False, size=14)
|
||||
|
||||
if cell.column == sheet.max_column and cell.row == landuse_start_row+1:
|
||||
cell.font = Font(bold=False, size=14)
|
||||
|
||||
@@ -407,7 +518,6 @@ class SoilQualityReporter:
|
||||
if cell.row >1 and cell.row not in (landuse_start_row, landuse_start_row+1):
|
||||
cell.border = thin_border
|
||||
|
||||
|
||||
def read_arcgis_table(table_path):
|
||||
"""将ArcGIS表格转换为Pandas DataFrame"""
|
||||
array = arcpy.da.TableToNumPyArray(table_path, "*")
|
||||
@@ -431,7 +541,7 @@ def get_area_by_group(dltb_class_feature, excel_target_path, xzqmc, is_by_xzq=Fa
|
||||
# 读取目标面积Excel文件
|
||||
if xzqmc in yunnan_region:
|
||||
target_df = pd.read_excel(excel_target_path, sheet_name="Sheet2")
|
||||
landuse_types = {'0101':'水田', '0102':'水浇地', '0103':'旱地', '02':'园地', '03':'林地', '04':'草地', '12':'其他'}
|
||||
landuse_types = {'0101':'水田', '0102':'水浇地', '0103':'旱地', '0201':'果园', '0202':'茶园', '0203':'橡胶园', '0204':'其他园地', '03':'林地', '04':'草地', '12':'其他'}
|
||||
elif xzqmc in guangxi_region:
|
||||
target_df = pd.read_excel(excel_target_path, sheet_name="Sheet1")
|
||||
landuse_types = {'01':'耕地', '02':'园地', '03':'林地', '04':'草地', '12':'其他'}
|
||||
@@ -607,8 +717,10 @@ def main():
|
||||
.reset_index()
|
||||
)
|
||||
stats["adjusted_area"] = stats["temp_area"]
|
||||
|
||||
# stats.to_csv("area_stats.csv", index=True)
|
||||
|
||||
|
||||
# 重命名列(按实际土壤分级字段调整)
|
||||
if soil_property == "PH" or soil_property == "TRRZ":
|
||||
grade_map = get_specail_map(output_settings["标准等级"])
|
||||
@@ -624,7 +736,7 @@ def main():
|
||||
if xzqmc in guangxi_region:
|
||||
landuse_map = {"01": "耕地", "02": "园地", "03": "林地", "04": "草地", "12": "其他"}
|
||||
else:
|
||||
landuse_map = {"0101": "水田", "0102": "水浇地", "0103": "旱地", "02": "园地", "03": "林地", "04": "草地", "12": "其他"}
|
||||
landuse_map = {'0101':'水田', '0102':'水浇地', '0103':'旱地', '0201':'果园', '0202':'茶园', '0203':'橡胶园', '0204':'其他园地', '03':'林地', '04':'草地', '12':'其他'}
|
||||
|
||||
# 平差处理
|
||||
excel_target_path = Path("tools/config_json/公布的变更调查平差面积.xlsx") # 您的目标面积Excel文件路径
|
||||
|
||||
@@ -16,6 +16,8 @@ import time
|
||||
import arcpy
|
||||
import argparse
|
||||
|
||||
import numpy as np
|
||||
|
||||
from tools.core.utils import 平差工具, common_utils
|
||||
|
||||
sys.path.append(str(Path(__file__).parent))
|
||||
@@ -91,32 +93,77 @@ def process_soil_property(args):
|
||||
print(f"缺少{soil_prop_name}的栅格或重分类要素,请检查输入文件路径是否正确!")
|
||||
return False
|
||||
|
||||
# 输出配置
|
||||
temp_files = []
|
||||
|
||||
filtered_props = ['ECA', 'EMG', 'ACU', 'AZN', 'AFE', 'AMN', 'AMO', 'AB', 'AS1', 'TSE']
|
||||
dltb_features = os.path.join(data_source_path, "地类图斑")
|
||||
|
||||
# 过滤地类图斑
|
||||
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
|
||||
# 全区制图统计
|
||||
try:
|
||||
raster = arcpy.Raster(soil_prop_tif)
|
||||
|
||||
# 按腌膜区域统计
|
||||
out_raster = arcpy.sa.ExtractByMask(
|
||||
in_raster=raster,
|
||||
in_mask_data=temp_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)
|
||||
|
||||
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}")
|
||||
|
||||
# =================================================================
|
||||
print(f"生成{soil_prop_name}的表1...")
|
||||
if soil_prop_name == "TRZD12":
|
||||
B1_TRZD12土壤属性分级分布.main(data_source_path, soil_prop_name, reclassed_features, dltb_features, output_path, target_area_all,xzqmc, prop_config)
|
||||
elif soil_prop_name == "TRZD":
|
||||
B1_TRZD土壤属性分级分布.main(data_source_path, soil_prop_name, reclassed_features, dltb_features, output_path, target_area_all,xzqmc, prop_config)
|
||||
else:
|
||||
B1土壤属性分级分布.main(data_source_path, soil_prop_name, reclassed_features, dltb_features, soil_prop_tif, output_path, target_area_all,xzqmc, prop_config)
|
||||
B1土壤属性分级分布.main(data_source_path, soil_prop_name, reclassed_features, dltb_features, stats_map, output_path, target_area_all,xzqmc, prop_config)
|
||||
time.sleep(2)
|
||||
|
||||
# print(f"生成{soil_prop_name}的表2...")
|
||||
# if soil_prop_name == "TRZD12":
|
||||
# B2_TRZD12土地利用类型土壤属性.main(data_source_path, soil_prop_name, dltb_features, reclassed_features, output_path, target_area_df2, prop_config)
|
||||
# elif soil_prop_name == "TRZD":
|
||||
# B2_TRZD土地利用类型土壤属性.main(data_source_path, soil_prop_name, dltb_features, reclassed_features, output_path, target_area_df2, prop_config)
|
||||
# else:
|
||||
# B2土地利用类型土壤属性.main(data_source_path, soil_prop_name, dltb_features, soil_prop_tif, output_path, target_area_df2, prop_config)
|
||||
# time.sleep(2)
|
||||
print(f"生成{soil_prop_name}的表2...")
|
||||
if soil_prop_name == "TRZD12":
|
||||
B2_TRZD12土地利用类型土壤属性.main(data_source_path, soil_prop_name, dltb_features, reclassed_features, output_path, target_area_df2, prop_config)
|
||||
elif soil_prop_name == "TRZD":
|
||||
B2_TRZD土地利用类型土壤属性.main(data_source_path, soil_prop_name, dltb_features, reclassed_features, output_path, target_area_df2, prop_config)
|
||||
else:
|
||||
B2土地利用类型土壤属性.main(data_source_path, soil_prop_name, dltb_features, soil_prop_tif, output_path, target_area_df2, prop_config,stats_map)
|
||||
time.sleep(2)
|
||||
|
||||
# print(f"生成{soil_prop_name}的表3...")
|
||||
# if soil_prop_name == "TRZD12":
|
||||
# B3_TRZD12不同土壤类型土壤属性.main(data_source_path,soil_prop_name,trlx_features,reclassed_features,output_path,target_area_df1,prop_config)
|
||||
# elif soil_prop_name == "TRZD":
|
||||
# B3_TRZD不同土壤类型土壤属性.main(data_source_path, soil_prop_name, trlx_features, reclassed_features, output_path, target_area_df1, prop_config)
|
||||
# else:
|
||||
# B3不同土壤类型土壤属性.main(data_source_path, soil_prop_name, trlx_features, soil_prop_tif, output_path, target_area_df1, prop_config, dltb_features)
|
||||
# time.sleep(2)
|
||||
print(f"生成{soil_prop_name}的表3...")
|
||||
if soil_prop_name == "TRZD12":
|
||||
B3_TRZD12不同土壤类型土壤属性.main(data_source_path,soil_prop_name,trlx_features,reclassed_features,output_path,target_area_df1,prop_config)
|
||||
elif soil_prop_name == "TRZD":
|
||||
B3_TRZD不同土壤类型土壤属性.main(data_source_path, soil_prop_name, trlx_features, reclassed_features, output_path, target_area_df1, prop_config)
|
||||
else:
|
||||
B3不同土壤类型土壤属性.main(data_source_path, soil_prop_name, trlx_features, soil_prop_tif, output_path, target_area_df1, prop_config, dltb_features,stats_map)
|
||||
time.sleep(2)
|
||||
|
||||
print(f"生成{soil_prop_name}的历史对比...")
|
||||
# if arcpy.Exists(history_reclassed_features) and arcpy.Exists(history_raster) and arcpy.Exists(history_samples_path):
|
||||
@@ -129,6 +176,11 @@ def process_soil_property(args):
|
||||
except Exception as e:
|
||||
print(f"处理{soil_prop_name}时出错: {str(e)}")
|
||||
return False
|
||||
finally:
|
||||
# 清理临时文件
|
||||
temp_files_processor.clean_up_temp_files(temp_files)
|
||||
import gc
|
||||
gc.collect()
|
||||
|
||||
def main():
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"config_file_path": "D:/ProgramData/ArcGis_Py/tools/config_json/广西_华南_地块_config.json",
|
||||
"xzq_features": "E:\\@三普属性图出图\\广西银海区\\银海区土壤属性制表\\土壤属性制表数据.gdb\\行政区划",
|
||||
"dltb_features": "E:\\@三普属性图出图\\广西银海区\\银海区土壤属性制表\\土壤属性制表数据.gdb\\地类图斑",
|
||||
"xzqmc": "西畴县",
|
||||
"xzqmc": "",
|
||||
"is_by_xzq": false
|
||||
},
|
||||
"acid_stat_settings": {
|
||||
@@ -49,12 +49,16 @@
|
||||
"xzqmc": ""
|
||||
},
|
||||
"soil_prop_stat_settings": {
|
||||
"xzqmc": "",
|
||||
"xzqmc": "银海区",
|
||||
"config_file": "D:/ProgramData/ArcGis_Py/tools/config_json/广西_华南_地块_config.json",
|
||||
"data_source_path": "E:/@三普属性图出图/广西武鸣区/武鸣区报告图表/制表数据.gdb",
|
||||
"sanpu_prop_tif_folder": "E:/@三普属性图出图/广西武鸣区/@基础数据/三普栅格/投影后",
|
||||
"reclassed_feature_folder": "E:/@三普属性图出图/广西武鸣区/过程数据/三普重分类/面积统计用栅格面",
|
||||
"output_folder": "E:/@三普属性图出图/广西武鸣区/武鸣区报告图表",
|
||||
"sample_list": []
|
||||
"data_source_path": "E:/@三普属性图出图/广西银海区/银海区土壤属性制表/土壤属性制表数据.gdb",
|
||||
"sanpu_prop_tif_folder": "E:/@三普属性图出图/广西北海市/@基础数据/三普栅格/投影后",
|
||||
"reclassed_feature_folder": "E:/@三普属性图出图/广西北海市/过程数据/面积统计用栅格面",
|
||||
"output_folder": "E:/@三普属性图出图/测试",
|
||||
"sample_list": [
|
||||
"CEC",
|
||||
"AS1",
|
||||
"AP"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,14 @@ def yunnan_dlbm(dlbm):
|
||||
return "0102"
|
||||
elif dlbm.startswith("0103"):
|
||||
return "0103"
|
||||
elif dlbm.startswith("0201"):
|
||||
return "0201"
|
||||
elif dlbm.startswith("0202"):
|
||||
return "0202"
|
||||
elif dlbm.startswith("0203"):
|
||||
return "0203"
|
||||
elif dlbm.startswith("0204"):
|
||||
return "0204"
|
||||
else:
|
||||
return dlbm[:2]
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user