Commit Graph

278 Commits

Author SHA1 Message Date
e8a81008fa feat: 专题图克里金插值支持多线程并发
- ThreadPoolExecutor 替代串行 for 循环,默认 2 线程并发
- 克里金内部 numpy/scipy 运算释放 GIL,线程并行有效
- 通过 kriging_workers 配置项控制并发数(默认 2,设为 1 回退串行)
- 主线程预先设置 matplotlib Agg 后端,避免多线程竞争
- 保留串行路径作为 fallback(单 CSV 或 workers=1 时)
2026-07-28 16:41:41 +08:00
3c7e735342 feat: 预测结果百分位裁剪 — 消除极端异常值拉爆专题图色阶
- 新增 _clip_outliers(P1-P99) 方法,预测完成后自动裁剪
- 水体边界零值区域导致模型外推极端值(-86~7026),
  裁剪后克里金插值色阶不再被拉爆,正常空间细节可见
- 无异常值时不触发裁剪(零开销)
2026-07-28 16:38:07 +08:00
b6fa07925a fix: 新模型路径推理时缺失 WQI 特征导致 Pipeline 维度不匹配
- 新模型路径(有 train_wavelengths)重采样后仅产出 50 列光谱,
  未计算模型训练时包含的 WQI 指数特征(期望 113 列)
- 旧模型路径(else 分支)有此逻辑但被隔离,新路径无法受益
- 将 WQI 特征补全逻辑提至 if/else 之后统一执行,
  通过 n_features_in_ 属性自动检测特征缺口并补齐
2026-07-28 15:31:49 +08:00
b59371f441 fix: 专题图 CRS 探测增强 + 地理坐标系 UTM 临时投影
map.py:
- CRS 探测从 Proj4 字符串兜底解析 EPSG(+init=epsg:XXXX / +zone=)
- rasterio 支持 .dat/.bsq/.bil/.bip/.img 等 ENVI 格式
- 新增 _is_geographic_crs() / _get_utm_epsg() 方法
- 地理坐标系自动临时投影到 UTM 米制空间进行插值,避免经纬度数值
  过小导致 Kriging/IDW 矩阵崩溃、std 退化为 0(纯色图)
- 防御:CRS 标记为地理系但坐标值超出经纬度范围时判定为探测错误,
  跳过投影直接使用米制坐标

water_quality_gui_v2.py: 格式清理
2026-07-28 14:59:16 +08:00
89b67fbd34 fix: ML Pipeline 缺失值填充 + 推理端外部模型 dict 兼容
- modeling_batch: Pipeline 首步新增 SimpleImputer(median) 填充 NaN
- inference_batch: 外部模型支持完整 dict(含 metadata/train_wavelengths),
  兼容旧版裸 Pipeline 对象
- step9_ml_predict_panel: 模型加载保留完整 dict 而非仅 model 对象,
  确保推理端可从 train_wavelengths 做光谱重采样
2026-07-28 14:59:11 +08:00
02592cc181 fix: 光谱提取 NaN/Inf 防护 + 边界掩膜支持
- 逐波段读取路径:防止 GDAL ReadAsArray 返回 NaN/Inf 污染光谱
- 批量读取路径:astype(float64) 后统一过滤非法值
- 两路径均支持 boundary_mask:水体之外光谱置零
2026-07-28 14:59:07 +08:00
46c5e51772 fix: BIP→BSQ 转换数据丢失修复 + 只读文件处理
- 延迟删除原始文件:先验证临时 BSQ 文件存在且非空,再删原始数据
- 异常处理不再删除临时 BSQ:保留完好副本供手动恢复
- 新增 _make_writable() 移除只读属性,避免 Windows PermissionError
- 清理孤儿 .aux.xml 临时文件
- 路径变量提前声明,保证异常处理块可访问
2026-07-28 14:59:03 +08:00
c16cddf384 feat: 推理端自动波长回填+linspace子采样(旧模型兼容) 2026-07-27 18:08:37 +08:00
de9d6f0835 fix: Kriging 整体拟合+变异函数容错+自适应分层抽样+高斯平滑+掩膜修复 2026-07-27 18:08:37 +08:00
c8ab4e029e fix: 采样+水掩膜+专题图十项修复
采样 (sampling.py):
- min_interval 50→10, base_interval 改用 min_interval
- np.all(sample_area)→water_ratio_threshold=0.35, 窄水体采样率大幅提升
- 自适应采样参数改用 P5-最近邻距离, 免疫外扩点污染

水掩膜 (extract_water_area.py):
- 移除 imgdata_in==0 误杀逻辑, 380nm水体反射率为0不再被跳过

专题图 (map.py):
- 坐标列检测修复: 删除 ('longitude','longitude') 短路bug
- 栅格掩膜重采样改用 GDAL ReprojectImage + 掩膜内 NaN 全量填充
- binary_closing iterations 2→1, 窄河道不丢
- visualize_raster 检测 nodata_value 避免矢量掩膜二次擦除
- IDW 自适应参数: 基于最近邻距离的连续映射
- Kriging 重构为整体拟合+变异函数多模型容错+高斯平滑
- 克里金无500K一刀切, 局部克里金失败自动回退IDW
2026-07-27 14:52:40 +08:00
92e8c90370 feat: ML模型波长记忆 + 跨传感器光谱重采样 + 数据加载规范化
训练端 (modeling_batch.py):
- _extract_train_wavelengths() 从列名提取训练波长写入 metadata
- load_data_batch/load_data_single 改为基于列名语义智能提取特征
- 废除 feature_start_column 硬编码位置索引

推理端 (inference_batch.py):
- preprocess_spectra() 分支A: train_wavelengths存在→np.interp精确重采样
- preprocess_spectra() 分支B: 无波长元数据→解析列名→np.interp到400-800nm标准网格
- 废除暴力截断和零值填充
2026-07-27 14:52:30 +08:00
99aeab3076 refactor: 中间层消除硬编码波段号+CRS动态探测
- GlintRemovalStep/handler/service 全部改为传递波长参数而非波段索引
- ContentMapper 移除 EPSG:32651 硬编码, 新增 _ensure_crs() + _probe_crs_from_file()
- _prepare_shared_context 在 read_csv_data 前先探测边界文件 CRS
- GUI QSpinBox→QDoubleSpinBox,默认值改为波长(nm),placeholder 提示自动探测
- 消除 38/36/49/47/25/37/65/91 等所有魔法数字
2026-07-27 14:52:23 +08:00
f6d61693e3 refactor: 耀斑去除算法从波段索引驱动改造为波长驱动
- Kutser/Hedley/Goodman 的 __init__ 参数从硬编码波段号改为目标波长(nm)
- 内部通过 find_band_number() 从 HDR 元数据动态解析波段索引
- Goodman 消除 P0 不一致: 25/37 vs 65/91 统一为 641.93/751.49nm
- 彻底解除传感器耦合,任何传感器均可自动适配
2026-07-27 14:52:15 +08:00
b609a64811 fix: 多项稳定性修复与打包优化
- PyInstaller: runtime hook 预加载 osgeo DLL 避免 Qt5 符号冲突;
  spec 纳入 osgeo .py 文件 + 运行时 DLL 依赖 (ffi/lzma/bz2/expat/sqlite3);
  移除 DLL 双副本防止 segfault
- GDAL 环境: 新增 _MEIPASS/osgeo/data/gdal 路径搜索,改善打包后 GDAL_DATA 检测
- 预览生成器: 掩膜与底图同分辨率时跳过 Warp 加速读取
- 专题图: ConvexHull 坐标中心化修复 UTM 大坐标精度退化;
  边界采样兜底防止外扩点为空;
  TIFF 已含 NaN 掩膜时跳过矢量擦除;
  形态学闭运算填充掩膜小孔洞
- NDWI: int16→float32 防止减法溢出
- 面板注册表: 步骤模块分组重构 (模块一/二/三/四重划分)
2026-07-26 20:35:50 +08:00
0bd54d5fdd feat(step3): auto BIP→BSQ conversion with metadata preservation
- _ensure_bsq(): 检测 BIP 格式并自动调用 gdal.Translate 转换为 BSQ
- 临时文件原地替换原名,所有下游步骤零感知
- 保留原始波长/波段名称等元数据到新 HDR
- 空间不足时跳过转换,回退 BIP-chunked 模式运行
2026-07-24 14:37:00 +08:00
2c637596eb perf(step3): Kutser BIP-chunked mode + auto interleave detection
- 新增 run_fast(): 自动检测 BIP/BSQ 格式,BIP 按行块读立方体(文件只读一遍)
- BSQ 模式逐波段顺序读取,均比原版块外波段内随机 IO 快 10-100 倍
- get_corrected_bands() 默认走 run_fast(),原版 run() 保留为低内存兼容
- 每 10 波段打印进度 + 预计剩余时间
2026-07-24 14:36:56 +08:00
beed27b1f0 perf(step11): IDW auto-switch for large grids + GDAL fast rasterize
- 网格 >500K 点自动跳过 Kriging 切 IDW(千万级点从数小时降至数秒)
- n_closest_points 50→20,Block 每块打印进度
- GDAL ReprojectImage 直接重采样栅格掩膜,避免 58K 多边形 rasterize 卡死
- 自动扫描工作目录 .dat 栅格,不依赖 handler 传参
- 特殊 Unicode 字符替换为 ASCII 兼容
2026-07-24 14:36:51 +08:00
d0344b8fa0 fix: add missing self._pipeline_mode assignment + getattr guard + init stats_data before try 2026-07-14 15:22:24 +08:00
5b04a120e3 chore: replace app icon uitubiao.ico -> app.ico (converted from app.png) 2026-07-14 15:15:03 +08:00
d4de09caa2 fix: total_steps now uses actual map count, not capped at 20 2026-07-10 13:21:31 +08:00
6f4717662a fix: remove 20-map limit in formula report - all distribution maps now included, AI limit still controlled by ai_maps_limit 2026-07-10 12:49:14 +08:00
8f01624171 fix: step7 filter bar split into 2 rows - row1: combo+selectAll+clear, row2: ratio+conc+reload+count 2026-07-10 11:58:58 +08:00
600400a4d9 fix: step13 auto-detect report mode on panel load (in _auto_pull_work_dir), not just on generate click 2026-07-09 15:38:47 +08:00
208e067334 feat: step13 auto-detect mode + user confirmation combo (with fallback to manual override) 2026-07-09 15:33:45 +08:00
66a181cbe2 feat: step13 auto-detect ML vs formula mode like step11, remove manual selector 2026-07-09 15:21:45 +08:00
3f4cb94929 fix: clean up step13 mode selector labels - remove misleading step numbers 2026-07-09 15:18:55 +08:00
a13b4be6d4 feat: formula report AI analysis per distribution map with configurable limit in UI panel 2026-07-09 15:03:39 +08:00
683cf77da5 fix: restore generic sections and AI analysis in formula report 2026-07-09 15:00:25 +08:00
a3e83e846a fix: remove leftover glint_analysis reference causing NameError 2026-07-09 14:52:50 +08:00
a572b52239 fix: formula report reads distribution maps from 12_visualization/distribution_maps/ instead of 11_Thematic_Map 2026-07-09 14:49:36 +08:00
5fe71917a6 fix: hyperspectral images section - skip missing instead of showing placeholder text, fix flight path rglob scope 2026-07-09 14:47:44 +08:00
f99fa63f0e fix: remove duplicate hyperspectral images and conflicting generic sections from formula report 2026-07-09 14:45:53 +08:00
8a7273dd57 fix: 公式报告进度步数用实际脉冲数而非原始数据量 (87→30)
旧: total_steps = 4 + 63 + 20 = 87 (但大部分步骤不发脉冲)
新: total_steps = 4 + 63//10 + 20 = 30 (与 _next 调用次数一致)
2026-07-09 13:27:47 +08:00
dd04ee323c fix: ML 报告进度增加 on_progress 回调 + 两条报告逻辑审查确认
ML 报告: 参数循环中加入 on_progress 回调,
  终端显示 ML报告 参数 3/13: Chlorophyll

审查结论:
  公式报告 (_generate_formula_report):
    数据源: 10_WaterIndex_CSV + 11_Thematic_Map + 1_water_mask
    不含 ML 内容 (无 scatter/boxplot/heatmap/R²/RMSE)
    进度: 数据驱动 (N_csv + N_maps + 4 固定)

  ML 报告 (_generate_ml_report):
    数据源: 12_visualization + 5_Data_Cleaning + 9_Concentration
    完整 ML 流程 (统计表→热力图→浓度→逐参数图表→总结)
    进度: 图片数 + 参数数 + 2
2026-07-09 13:26:09 +08:00
836c322b10 fix: 公式报告进度数据驱动 — 按实际 CSV/专题图数量计算总步数
旧: total_steps=7 硬编码, 看不到实际数据处理进度
新: 启动时扫描 10_WaterIndex_CSV 和 11_Thematic_Map,
  总步数 = 4(固定章节) + N_csv + N_maps,
  每处理 10% CSV 和每张专题图均更新进度,
  终端显示 统计 7/63 / 专题图 3/20 等实时信息
2026-07-09 13:21:32 +08:00
b88bab57ee fix: 公式报告 4 项修复 — 通用章节+AI接口+图片路径+标题数字
修复一: _generate_formula_report 封面后恢复
  _add_company_description_page/doc
  _add_data_acquisition_section/doc
  _add_data_processing_section/doc

修复二: _call_minimax_text / _call_minimax_vision
  URL 自动补齐 /chat/completions 后缀

修复三: _call_minimax_vision
  MIME 类型动态检测 (.png→image/png, 其他→image/jpeg)

修复四: _add_hyperspectral_images_section
  航线图搜索: 多路径 + rglob 递归查找
  去掉所有硬编码编号 (3.1/图3-2/3-3/3-4/3-5/3-6)
2026-07-09 13:12:14 +08:00
fc6036efb7 fix: _add_hyperspectral_images_section 去掉多余的 start_figure_num 参数 2026-07-09 11:53:23 +08:00
43d56e74d9 fix: _add_cover_page 参数对齐 + 确认 _generate_formula_report 无 ML 混入 2026-07-09 11:42:32 +08:00
650e505ac4 feat: 报告生成模块双轨制重构 — 公式模式 + ML 模式独立分流
**UI (step13_report_panel.py):**
  - 新增 QComboBox 报告模式选择:
    机器学习(ml) / 水色指数公式(formula)
  - WorkerThread 传递 report_mode 到 generate_report

**后端 (report_word.py):**
  - generate_report(report_mode='ml'/'formula') 参数路由
  - _generate_formula_report(): 水色指数专属结构
    1.项目背景 → 2.影像预处理 → 3.公式列表 →
    4.指数统计(10_WaterIndex_CSV) → 5.分布专题图(11_Thematic_Map)
    绝不包含模型训练/R²/RMSE 等 ML 内容
  - _generate_ml_report(): 原有 ML 逻辑完整保留
  - _analyze_statistics(): 全部改用 .get() 防御式读取
    兼容 参数/Parameter/name, 点位数/数量/count,
    最小值/min, 最大值/max, 平均值/mean, 标准差/std
2026-07-09 11:33:50 +08:00
692a88c7bb fix: heatmap_path 提前声明避免水色指数模式下 UnboundLocalError 2026-07-09 11:22:50 +08:00
1740425152 fix: 报告水色指数模式 stats_data 补全缺失的统计字段
水色指数模式 stats_data 只复制了 参数/点位数,
  缺少 最小值/最大值/平均值/标准差 →
  _analyze_statistics 访问时 KeyError: '最小值'
2026-07-09 11:17:54 +08:00
303f202547 fix: read_csv_data 含量列动态识别 — 排除所有坐标列名
问题: CSV 格式 [proj_x, proj_y, longitude, latitude, BGA_Am09KBBI],
  旧逻辑 coord_cols={proj_x,proj_y} 只排除识别的坐标列,
  longitude 被错误提取为含量列 → Kriging 用坐标值插值

修复: 扩展排除集合包含全部已知坐标列名:
  proj_x/proj_y, longitude/latitude, x/y, lon/lat,
  x_coord/y_coord, pixel_x/pixel_y, geometry, uncertainty
  兜底取最后一列
2026-07-09 09:56:03 +08:00
9fa60e2995 fix: CRS 比较改用 GDAL osr.IsSame() 语义比对, 消除 WKT 格式差异误报
问题: 两组不同数据的 .hdr 文件由不同软件生成,
  同一 UTM 投影的 WKT 字符串格式不同 (PROJCS 命名/参数精度),
  原 validate_projections 用字符串比较会误报 CRS 不一致。

修复: 改用 gdal.osr.SpatialReference.IsSame() 语义比对:
  - 同一定义 → 通过 (即使 WKT 格式不同)
  - 真正不同 → 报错
  - osr 解析失败 → 回退字符串比较
2026-07-09 09:37:50 +08:00
1d051c9fec feat: 报告生成器自动检测水色指数模式 — 支持非 ML 管线
问题: 报告模板仅适配 ML 管线 (steps 5-9+13),
  用户跑 1,2,3,4,10,11,12 (水色指数公式管线) 时大量显示
  [图片未找到]。

修复: 自动模式检测 + 分支逻辑

  1. _detect_pipeline_mode(): 检测 scatter_with_confidence 文件
     不存在 → 水色指数模式

  2. _get_available_image_types(): 扫描实际存在的图片类型,
     只报告确实生成的内容

  3. 统计表格: ML→5_Data_Cleaning, 水色指数→10_WaterIndex_CSV
     水色指数模式遍历所有公式 CSV 生成统计汇总表

  4. 相关性热力图: 水色指数模式跳过并注明原因

  5. 分布图: 利用已有 fallback 从 11_Thematic_Map 读取
2026-07-09 09:31:58 +08:00
d18da41505 fix: step13 统一使用 12_visualization 目录名
问题: step13_service.py 检查 14_visualization 但 report_word.py
  内部写死使用 12_visualization, 目录名不一致导致新服务报
  '可视化目录不存在'。

修复: step13_service.py 全部 14_visualization → 12_visualization
2026-07-09 09:25:14 +08:00
f496b28c8c fix: 回退 setWidgetResizable(False) 恢复图像显示 + 保留滚动条策略修复
setWidgetResizable(False)+QSizePolicy.Ignored 导致 QLabel
  无有效 sizeHint, 图像不显示。

回退为 setWidgetResizable(True), 保留显式 ScrollBarAsNeeded
  策略 (原默认可能为 AlwaysOff 导致滚动条异常)。
2026-07-08 17:55:34 +08:00
830589c108 fix: 智能坐标列检测 — proj_x/proj_y 优先 + 双列名输出
问题: CSV 中 UTM 米坐标被命名为 longitude/latitude,
  列名与实际内容不符, 容易引发 CRS 配置错误。

修复:

1. map.py read_csv_data: 优先级智能列检测
   proj_x/proj_y → longitude/latitude → lon/lat → x_coord/y_coord
   → 终极回退按位置[0][1]。新旧文件全部兼容。

2. csv_processor.py: 输出双列名
   proj_x + proj_y (新标准, 优先)
   longitude + latitude (旧标准, 兼容)
   值完全相同, 新旧代码都能正确读取
2026-07-08 16:50:20 +08:00
f996353b37 fix: 克里金矩阵鲁棒性 — 去重重叠点 + nugget 防奇异化
问题: 4326 点仍崩溃回退 IDW,原因两个:
  1. 采样点中存在空间完全重叠点 → 协方差矩阵行列式为 0
  2. 坐标范围出现负数 (X=-793275) → 经/纬度传反,空间距离扭曲

修复:
  1. read_csv_data: drop_duplicates(subset=['proj_x','proj_y'])
     坐标 <0.01m 的重叠点只保留首个,防止矩阵奇异化
  2. OrdinaryKriging (2处): nugget=1e-6
     微小固有方差强制打破矩阵奇异性,病态矩阵仍可求逆
2026-07-08 16:29:33 +08:00
7921e21750 fix: step4 采样点过密 — 提高自适应下限 + 默认关闭自适应模式
问题: min_interval=10 导致每个水面产生数千个密集采样点 (8242点)

修复:
  1. sampling.py: min_interval 默认值 10→50 (提高 5×)
     两个入口函数同步修改 (chunked + full)
  2. step4_sampling_panel.py: 自适应采样复选框默认 False
     用户设置的固定间隔 (interval=100px) 真正生效
2026-07-08 16:03:42 +08:00
197f58c187 fix: step12 图像预览横向滚动条被挤出视口底部
根因: QScrollArea.setWidgetResizable(True) 强制 QLabel 填充视口,
  与缩放后 QLabel 的 pixmap 固有尺寸冲突,滚动条布局异常。

修复:
  1. setWidgetResizable(False) — QLabel 保持 pixmap 自然尺寸
  2. QScrollArea SizePolicy → Expanding×Expanding (受父布局约束)
  3. ScrollBarPolicy → AsNeeded (显式设置)
  4. QLabel SizePolicy → Ignored (按内容自适应大小)

缩放行为:
  - 放大超出视口 → 自动出现滚动条
  - 缩小/适应窗口 → QLabel 自动缩至 pixmap 尺寸, 无滚动条
2026-07-08 15:24:44 +08:00