fix: 公式报告进度数据驱动 — 按实际 CSV/专题图数量计算总步数
旧: total_steps=7 硬编码, 看不到实际数据处理进度 新: 启动时扫描 10_WaterIndex_CSV 和 11_Thematic_Map, 总步数 = 4(固定章节) + N_csv + N_maps, 每处理 10% CSV 和每张专题图均更新进度, 终端显示 统计 7/63 / 专题图 3/20 等实时信息
This commit is contained in:
@ -951,9 +951,26 @@ class WaterQualityReportGenerator:
|
||||
else:
|
||||
output_path = Path(output_path)
|
||||
|
||||
# 进度: 封面+背景+预处理+公式表+统计+分布图+总结 = 7 步
|
||||
total_steps = 7
|
||||
# 扫描实际数据量
|
||||
csv_files = sorted(csv_dir.glob("*.csv")) if csv_dir.is_dir() else []
|
||||
tif_files = (sorted(thematic_dir.glob("*.tif")) + sorted(thematic_dir.glob("*.png"))
|
||||
) if thematic_dir.is_dir() else []
|
||||
n_csv = len(csv_files)
|
||||
n_maps = min(len(tif_files), 20) # 最多展示 20 张
|
||||
n_fixed = 4 # 封面 + 背景 + 预处理 + 总结
|
||||
total_steps = n_fixed + n_csv + n_maps
|
||||
print(f"[公式报告] 数据: {n_csv} CSV, {len(tif_files)} 专题图 → 总步数 {total_steps}")
|
||||
|
||||
progress = self._create_progress(total=total_steps, desc="生成公式报告", on_step=on_progress)
|
||||
_step = 0
|
||||
def _next(text=""):
|
||||
nonlocal _step
|
||||
_step += 1
|
||||
try: progress.update(1)
|
||||
except Exception: pass
|
||||
if on_progress:
|
||||
try: on_progress(int(_step / total_steps * 100), text or f"步骤 {_step}/{total_steps}")
|
||||
except Exception: pass
|
||||
|
||||
doc = Document()
|
||||
section = doc.sections[0]
|
||||
@ -966,13 +983,10 @@ class WaterQualityReportGenerator:
|
||||
|
||||
# ── 封面 ──
|
||||
self._add_cover_page(doc)
|
||||
try: progress.update(1)
|
||||
except Exception: pass
|
||||
|
||||
# ── 通用章节:单位介绍 / 数据采集 / 工作流程 ──
|
||||
self._add_company_description_page(doc)
|
||||
self._add_data_acquisition_section(doc)
|
||||
self._add_data_processing_section(doc)
|
||||
_next("封面与通用章节")
|
||||
|
||||
# ── 1. 项目背景 ──
|
||||
h1 = doc.add_heading("1 项目背景", level=1)
|
||||
@ -981,36 +995,36 @@ class WaterQualityReportGenerator:
|
||||
"涵盖叶绿素、蓝绿藻、浊度、CDOM 等多种水色指标的定量化空间制图。")
|
||||
doc.add_paragraph("数据来源:机载 / 星载高光谱成像仪,经过辐射定标、大气校正、耀斑去除等预处理。")
|
||||
doc.add_page_break()
|
||||
_next("项目背景")
|
||||
|
||||
# ── 2. 影像预处理 ──
|
||||
h1 = doc.add_heading("2 影像预处理", level=1)
|
||||
self._style_heading(h1, 1)
|
||||
self._add_hyperspectral_images_section(doc)
|
||||
doc.add_page_break()
|
||||
_next("影像预处理")
|
||||
|
||||
# ── 3. 水色指数公式列表 ──
|
||||
h1 = doc.add_heading("3 水色指数计算方法", level=1)
|
||||
self._style_heading(h1, 1)
|
||||
if csv_dir.is_dir():
|
||||
csv_files = sorted(csv_dir.glob("*.csv"))
|
||||
doc.add_paragraph(f"本次反演共应用 {len(csv_files)} 个水色指数公式,"
|
||||
if csv_files:
|
||||
doc.add_paragraph(f"本次反演共应用 {n_csv} 个水色指数公式,"
|
||||
f"各公式基于特征波段比值或差分原理计算:")
|
||||
for i, cf in enumerate(csv_files[:30], 1): # 最多列出30个
|
||||
for i, cf in enumerate(csv_files[:30], 1):
|
||||
doc.add_paragraph(f" {i}. {cf.stem}", style='List Number')
|
||||
if len(csv_files) > 30:
|
||||
doc.add_paragraph(f" ... 共 {len(csv_files)} 个公式,详情见统计章节。")
|
||||
if n_csv > 30:
|
||||
doc.add_paragraph(f" ... 共 {n_csv} 个公式,详情见统计章节。")
|
||||
else:
|
||||
doc.add_paragraph(f"(未找到水色指数目录: {csv_dir})")
|
||||
doc.add_page_break()
|
||||
|
||||
# ── 4. 指数统计结果 ──
|
||||
# ── 4. 指数统计结果(每个 CSV 更新一次进度)──
|
||||
h1 = doc.add_heading("4 水色指数统计结果", level=1)
|
||||
self._style_heading(h1, 1)
|
||||
figure_num = 10
|
||||
if csv_dir.is_dir():
|
||||
csv_files = sorted(csv_dir.glob("*.csv"))
|
||||
if csv_files:
|
||||
stats_rows = []
|
||||
for cp in csv_files:
|
||||
for i_c, cp in enumerate(csv_files):
|
||||
try:
|
||||
df_one = pd.read_csv(cp, sep=',')
|
||||
val_col = df_one.columns[-1]
|
||||
@ -1025,6 +1039,9 @@ class WaterQualityReportGenerator:
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
# 每处理 10 个 CSV 更新进度
|
||||
if (i_c + 1) % max(1, n_csv // 10) == 0 or i_c == n_csv - 1:
|
||||
_next(f"统计 {i_c+1}/{n_csv}")
|
||||
|
||||
if stats_rows:
|
||||
# 统计表
|
||||
@ -1056,17 +1073,14 @@ class WaterQualityReportGenerator:
|
||||
else:
|
||||
doc.add_paragraph(f"(未找到水色指数目录: {csv_dir})")
|
||||
doc.add_page_break()
|
||||
try: progress.update(1)
|
||||
except Exception: pass
|
||||
|
||||
# ── 5. 指数空间分布专题图 ──
|
||||
# ── 5. 指数空间分布专题图(每张更新进度)──
|
||||
h1 = doc.add_heading("5 水色指数空间分布专题图", level=1)
|
||||
self._style_heading(h1, 1)
|
||||
figure_num += 1
|
||||
maps_found = 0
|
||||
if thematic_dir.is_dir():
|
||||
tifs = sorted(thematic_dir.glob("*.tif")) + sorted(thematic_dir.glob("*.png"))
|
||||
for tf in tifs[:20]: # 最多展示 20 张
|
||||
if tif_files:
|
||||
for i_t, tf in enumerate(tif_files[:20]):
|
||||
try:
|
||||
param_name = tf.stem.split('_')[0] if '_' in tf.stem else tf.stem
|
||||
caption = f"图{figure_num} {param_name} 空间分布图"
|
||||
@ -1075,15 +1089,14 @@ class WaterQualityReportGenerator:
|
||||
maps_found += 1
|
||||
except Exception as e:
|
||||
doc.add_paragraph(f"[专题图插入失败: {tf.name} — {e}]")
|
||||
if len(tifs) > 20:
|
||||
doc.add_paragraph(f"... 共 {len(tifs)} 张专题图,此处仅展示前 20 张。")
|
||||
_next(f"专题图 {i_t+1}/{min(len(tif_files), 20)}")
|
||||
if len(tif_files) > 20:
|
||||
doc.add_paragraph(f"... 共 {len(tif_files)} 张专题图,此处仅展示前 20 张。")
|
||||
else:
|
||||
doc.add_paragraph(f"(未找到专题图目录: {thematic_dir})")
|
||||
if maps_found == 0:
|
||||
doc.add_paragraph("(未找到专题图文件,请确认 Step 11 已完成。)")
|
||||
doc.add_page_break()
|
||||
try: progress.update(1)
|
||||
except Exception: pass
|
||||
|
||||
# ── 6. 综合总结 ──
|
||||
h1 = doc.add_heading("6 综合总结", level=1)
|
||||
@ -1092,8 +1105,7 @@ class WaterQualityReportGenerator:
|
||||
"进行了定量化空间制图。各指数的统计结果和空间分布专题图如上所示。")
|
||||
doc.add_paragraph("注意事项:水色指数反演结果为半定量指标,其绝对值可能受大气校正精度、"
|
||||
"水体光学特性复杂性等因素影响。建议结合实测水质数据进行校验。")
|
||||
try: progress.update(1)
|
||||
except Exception: pass
|
||||
_next("综合总结")
|
||||
|
||||
doc.save(str(output_path))
|
||||
print(f"[公式报告] 生成完成: {output_path}")
|
||||
|
||||
Reference in New Issue
Block a user