diff --git a/src/gui/panels/step10_watercolor_panel.py b/src/gui/panels/step10_watercolor_panel.py index 7d1f4f9..ace8750 100644 --- a/src/gui/panels/step10_watercolor_panel.py +++ b/src/gui/panels/step10_watercolor_panel.py @@ -204,7 +204,7 @@ class Step10WatercolorPanel(QWidget): "输出目录:", "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.connect(self._browse_output_dir) output_layout.addRow("输出目录:", self.output_dir) @@ -437,22 +437,42 @@ class Step10WatercolorPanel(QWidget): self.work_dir = None main_window = self.window() + deglint_path = None - # 自动填入去耀斑影像 - if main_window and hasattr(main_window, 'step3_panel'): - deglint_path = main_window.step3_panel.output_file.get_path() - if deglint_path and not self.bsq_file.get_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(deglint_path).with_suffix('.hdr') - if hdr.exists(): - self.hdr_file.set_path(str(hdr)) - self._load_metadata(deglint_path, str(hdr)) + # 1. 优先从 pipeline 的真实输出中获取 + if pipeline and hasattr(pipeline, 'step_outputs'): + step3_out = pipeline.step_outputs.get('step3', {}) + deglint_path = step3_out.get('deglint_image') or step3_out.get('output_path') + + # 2. 回退:从 step3 面板实例获取 + if not deglint_path and main_window and hasattr(main_window, 'step3_panel'): + if hasattr(main_window.step3_panel, 'output_file'): + deglint_path = main_window.step3_panel.output_file.get_path() + + # 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: - 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) if not self.output_dir.get_path(): self.output_dir.set_path(out_dir) @@ -483,7 +503,7 @@ class Step10WatercolorPanel(QWidget): return if not output_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) self.output_dir.set_path(output_dir) diff --git a/src/gui/panels/step4_sampling_panel.py b/src/gui/panels/step4_sampling_panel.py index 20b6b23..e61c063 100644 --- a/src/gui/panels/step4_sampling_panel.py +++ b/src/gui/panels/step4_sampling_panel.py @@ -6,6 +6,7 @@ Step4 面板 - 采样点布设 import os +from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import ( QWidget, QVBoxLayout, QGroupBox, QFormLayout, QPushButton, QCheckBox, QSpinBox, QMessageBox, @@ -94,6 +95,11 @@ class Step4SamplingPanel(QWidget): layout.addStretch() 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) diff --git a/src/gui/water_quality_gui.py b/src/gui/water_quality_gui.py index e94daf2..3939276 100644 --- a/src/gui/water_quality_gui.py +++ b/src/gui/water_quality_gui.py @@ -1374,7 +1374,7 @@ class WaterQualityGUI(QMainWindow): 'step7_index': "6_water_quality_indices/training_spectra_indices.csv", 'step8_ml_train': "7_Supervised_Model_Training/", 'step9_ml_predict': "11_12_13_predictions/Machine_Learning_Prediction/", - 'step10_watercolor': "8_WaterIndex_Images/", + 'step10_watercolor': "10_WaterIndex_Images/", 'step11_map': "14_visualization/" } @@ -2286,7 +2286,17 @@ class WaterQualityGUI(QMainWindow): if step_id not in self.step_default_outputs: 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'} @@ -2319,12 +2329,11 @@ class WaterQualityGUI(QMainWindow): # 根据输出类型查找对应的文件 if output_type == 'water_mask': - # 水域掩膜:优先查找NDWI生成的,其次是shp生成的 - for mask_type in ['water_mask_ndwi', 'water_mask_shp']: - if mask_type in step_outputs: - mask_path = work_path / step_outputs[mask_type] - if mask_path.exists(): - return str(mask_path) + # 水域掩膜:直接用统一路径 + if rel_path: + mask_path = work_path / rel_path + if mask_path.exists(): + return str(mask_path) elif output_type == 'reference_img': # 参考影像:从step1的配置中获取用户输入的影像路径 if hasattr(self, 'step1_panel'): @@ -2332,32 +2341,29 @@ class WaterQualityGUI(QMainWindow): if img_path and Path(img_path).exists(): return img_path elif output_type == 'deglint_image': - # 去耀斑影像:查找step3的各种去耀斑方法输出 - deglint_types = ['deglint_kutser', 'deglint_goodman', 'deglint_hedley', 'deglint_sugar'] - for deglint_type in deglint_types: - if deglint_type in step_outputs: - deglint_path = work_path / step_outputs[deglint_type] - if deglint_path.exists(): - return str(deglint_path) + # 去耀斑影像:直接用统一路径 + if rel_path: + deglint_path = work_path / rel_path + if deglint_path.exists(): + return str(deglint_path) # 还要检查插值方法生成的文件 deglint_dir = work_path / "3_deglint" if deglint_dir.exists(): for file_path in deglint_dir.glob("interpolated_*.bsq"): return str(file_path) - elif output_type in step_outputs: - # 直接匹配的输出类型 - relative_path = step_outputs[output_type] - if relative_path.endswith('/'): + elif rel_path: + # 直接匹配的输出类型(统一使用 rel_path) + if rel_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(): return str(output_path) else: # 是文件 - output_path = work_path / relative_path + output_path = work_path / rel_path if output_path.exists(): return str(output_path) - + return None def scan_work_directory_for_files(self, work_path):