Step4 心跳刷新 + Step10 输出目录更名与智能寻址优化

This commit is contained in:
DXC
2026-06-12 10:27:47 +08:00
parent 4c9ca2aa03
commit be47b70594
3 changed files with 68 additions and 36 deletions

View File

@ -204,7 +204,7 @@ class Step10WatercolorPanel(QWidget):
"输出目录:", "输出目录:",
"Directories" "Directories"
) )
self.output_dir.line_edit.setPlaceholderText("留空 → 工作目录/8_WaterIndex_Images") self.output_dir.line_edit.setPlaceholderText("留空 → 工作目录/10_WaterIndex_Images")
self.output_dir.browse_btn.clicked.disconnect() self.output_dir.browse_btn.clicked.disconnect()
self.output_dir.browse_btn.clicked.connect(self._browse_output_dir) self.output_dir.browse_btn.clicked.connect(self._browse_output_dir)
output_layout.addRow("输出目录:", self.output_dir) output_layout.addRow("输出目录:", self.output_dir)
@ -437,22 +437,42 @@ class Step10WatercolorPanel(QWidget):
self.work_dir = None self.work_dir = None
main_window = self.window() main_window = self.window()
deglint_path = None
# 自动填入去耀斑影像 # 1. 优先从 pipeline 的真实输出中获取
if main_window and hasattr(main_window, 'step3_panel'): if pipeline and hasattr(pipeline, 'step_outputs'):
deglint_path = main_window.step3_panel.output_file.get_path() step3_out = pipeline.step_outputs.get('step3', {})
if deglint_path and not self.bsq_file.get_path(): deglint_path = step3_out.get('deglint_image') or step3_out.get('output_path')
if not os.path.isabs(deglint_path):
deglint_path = os.path.join(self.work_dir or '', deglint_path).replace('\\', '/') # 2. 回退:从 step3 面板实例获取
self.bsq_file.set_path(deglint_path) if not deglint_path and main_window and hasattr(main_window, 'step3_panel'):
hdr = Path(deglint_path).with_suffix('.hdr') if hasattr(main_window.step3_panel, 'output_file'):
if hdr.exists(): deglint_path = main_window.step3_panel.output_file.get_path()
self.hdr_file.set_path(str(hdr))
self._load_metadata(deglint_path, str(hdr)) # 3. 终极回退:智能扫描 3_deglint 目录,取最新的 .bsq 或 .dat 文件
if not deglint_path and self.work_dir:
deglint_dir = os.path.join(self.work_dir, "3_deglint")
if os.path.isdir(deglint_dir):
import glob
candidates = glob.glob(os.path.join(deglint_dir, "*.bsq")) + glob.glob(os.path.join(deglint_dir, "*.dat"))
if candidates:
candidates.sort(key=os.path.getmtime, reverse=True)
deglint_path = candidates[0]
# 填入 UI 并自动寻找对应的 hdr 文件
if deglint_path:
if not os.path.isabs(deglint_path):
deglint_path = os.path.join(self.work_dir or '', deglint_path).replace('\\', '/')
self.bsq_file.set_path(deglint_path)
hdr_path = os.path.splitext(deglint_path)[0] + '.hdr'
if os.path.exists(hdr_path):
self.hdr_file.set_path(hdr_path)
self._load_metadata(deglint_path, hdr_path)
# 自动填入输出目录 # 自动填入输出目录
if self.work_dir: if self.work_dir:
out_dir = os.path.join(self.work_dir, "8_WaterIndex_Images").replace('\\', '/') out_dir = os.path.join(self.work_dir, "10_WaterIndex_Images").replace('\\', '/')
os.makedirs(out_dir, exist_ok=True) os.makedirs(out_dir, exist_ok=True)
if not self.output_dir.get_path(): if not self.output_dir.get_path():
self.output_dir.set_path(out_dir) self.output_dir.set_path(out_dir)
@ -483,7 +503,7 @@ class Step10WatercolorPanel(QWidget):
return return
if not output_dir: if not output_dir:
work_dir = self._get_default_work_dir() work_dir = self._get_default_work_dir()
output_dir = os.path.join(work_dir, "8_WaterIndex_Images").replace('\\', '/') output_dir = os.path.join(work_dir, "10_WaterIndex_Images").replace('\\', '/')
os.makedirs(output_dir, exist_ok=True) os.makedirs(output_dir, exist_ok=True)
self.output_dir.set_path(output_dir) self.output_dir.set_path(output_dir)

View File

@ -6,6 +6,7 @@ Step4 面板 - 采样点布设
import os import os
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QGroupBox, QFormLayout, QWidget, QVBoxLayout, QGroupBox, QFormLayout,
QPushButton, QCheckBox, QSpinBox, QMessageBox, QPushButton, QCheckBox, QSpinBox, QMessageBox,
@ -94,6 +95,11 @@ class Step4SamplingPanel(QWidget):
layout.addStretch() layout.addStretch()
self.setLayout(layout) self.setLayout(layout)
# 添加心跳定时器每2秒自动检查一次输出文件状态刷新预览按钮
self._status_timer = QTimer(self)
self._status_timer.timeout.connect(self._check_csv_exists)
self._status_timer.start(2000)
# 监听输出路径变化,实时更新预览按钮状态 # 监听输出路径变化,实时更新预览按钮状态
self.output_file.line_edit.textChanged.connect(self._on_output_changed) self.output_file.line_edit.textChanged.connect(self._on_output_changed)

View File

@ -1374,7 +1374,7 @@ class WaterQualityGUI(QMainWindow):
'step7_index': "6_water_quality_indices/training_spectra_indices.csv", 'step7_index': "6_water_quality_indices/training_spectra_indices.csv",
'step8_ml_train': "7_Supervised_Model_Training/", 'step8_ml_train': "7_Supervised_Model_Training/",
'step9_ml_predict': "11_12_13_predictions/Machine_Learning_Prediction/", 'step9_ml_predict': "11_12_13_predictions/Machine_Learning_Prediction/",
'step10_watercolor': "8_WaterIndex_Images/", 'step10_watercolor': "10_WaterIndex_Images/",
'step11_map': "14_visualization/" 'step11_map': "14_visualization/"
} }
@ -2286,7 +2286,17 @@ class WaterQualityGUI(QMainWindow):
if step_id not in self.step_default_outputs: if step_id not in self.step_default_outputs:
return None return None
step_outputs = self.step_default_outputs[step_id] raw = self.step_default_outputs[step_id]
# ★ 兼容扁平化后的纯字符串路径格式
rel_path = None
if isinstance(raw, str):
rel_path = raw
elif isinstance(raw, dict):
rel_path = raw.get(output_type) or list(raw.values())[0]
if not rel_path:
return None
# ★ 掩膜类型列表:这些类型只接受科学数据格式 # ★ 掩膜类型列表:这些类型只接受科学数据格式
mask_types = {'water_mask', 'glint_mask', 'boundary_mask'} mask_types = {'water_mask', 'glint_mask', 'boundary_mask'}
@ -2319,12 +2329,11 @@ class WaterQualityGUI(QMainWindow):
# 根据输出类型查找对应的文件 # 根据输出类型查找对应的文件
if output_type == 'water_mask': if output_type == 'water_mask':
# 水域掩膜:优先查找NDWI生成的其次是shp生成的 # 水域掩膜:直接用统一路径
for mask_type in ['water_mask_ndwi', 'water_mask_shp']: if rel_path:
if mask_type in step_outputs: mask_path = work_path / rel_path
mask_path = work_path / step_outputs[mask_type] if mask_path.exists():
if mask_path.exists(): return str(mask_path)
return str(mask_path)
elif output_type == 'reference_img': elif output_type == 'reference_img':
# 参考影像从step1的配置中获取用户输入的影像路径 # 参考影像从step1的配置中获取用户输入的影像路径
if hasattr(self, 'step1_panel'): if hasattr(self, 'step1_panel'):
@ -2332,29 +2341,26 @@ class WaterQualityGUI(QMainWindow):
if img_path and Path(img_path).exists(): if img_path and Path(img_path).exists():
return img_path return img_path
elif output_type == 'deglint_image': elif output_type == 'deglint_image':
# 去耀斑影像:查找step3的各种去耀斑方法输出 # 去耀斑影像:直接用统一路径
deglint_types = ['deglint_kutser', 'deglint_goodman', 'deglint_hedley', 'deglint_sugar'] if rel_path:
for deglint_type in deglint_types: deglint_path = work_path / rel_path
if deglint_type in step_outputs: if deglint_path.exists():
deglint_path = work_path / step_outputs[deglint_type] return str(deglint_path)
if deglint_path.exists():
return str(deglint_path)
# 还要检查插值方法生成的文件 # 还要检查插值方法生成的文件
deglint_dir = work_path / "3_deglint" deglint_dir = work_path / "3_deglint"
if deglint_dir.exists(): if deglint_dir.exists():
for file_path in deglint_dir.glob("interpolated_*.bsq"): for file_path in deglint_dir.glob("interpolated_*.bsq"):
return str(file_path) return str(file_path)
elif output_type in step_outputs: elif rel_path:
# 直接匹配的输出类型 # 直接匹配的输出类型(统一使用 rel_path
relative_path = step_outputs[output_type] if rel_path.endswith('/'):
if relative_path.endswith('/'):
# 是目录 # 是目录
output_path = work_path / relative_path.rstrip('/') output_path = work_path / rel_path.rstrip('/')
if output_path.exists() and output_path.is_dir(): if output_path.exists() and output_path.is_dir():
return str(output_path) return str(output_path)
else: else:
# 是文件 # 是文件
output_path = work_path / relative_path output_path = work_path / rel_path
if output_path.exists(): if output_path.exists():
return str(output_path) return str(output_path)