diff --git a/docs/superpowers/specs/2026-06-30-vtk-merged-dataset-column-refactor-design.md b/docs/superpowers/specs/2026-06-30-vtk-merged-dataset-column-refactor-design.md new file mode 100644 index 0000000..a050a37 --- /dev/null +++ b/docs/superpowers/specs/2026-06-30-vtk-merged-dataset-column-refactor-design.md @@ -0,0 +1,166 @@ +# VTK 视图重构:合并数据集单栏 + 动态段 + 图标工具条 + 2D 平面底图 — Spec(2026-06-30) + +> 分支起点:`main`(PR #9 已合并)。职责范围:VTK 视图左侧数据集栏(面板结构 + 段交互 + 2D/3D 共存渲染 + 底图)。 +> 本 spec 替代 2026-06-26「二维分析:锁定俯视」模型的相机/显隐部分(见 §10 迁移说明)。 + +## 0. 一句话目标 + +把「三维分析 + 二维分析」两个 tab 合并成**一个无标题的单列数据集栏**:2D 与 3D 数据集用**一致的分段组织**同列呈现;段按数据有无**动态显隐**;段操作改**响应式图标工具条**;2D 数据以**按类型一块平面**的方式与 3D 体/帘面在**同一个自由透视场景**里共存。 + +--- + +## 1. 背景与现状(接手必读) + +- **面板**:`ColumnDrawer` = 左侧抽屉,`QTabWidget` 两 tab: + - 三维分析 `CategoryAnalysisTab`:`QScrollArea` 竖堆 `CategorySection`×4(电阻率/视电阻率/瞬变/三维体)。 + - 二维分析 `Column2DDataset`:平铺树 + 底图下拉 + 2D视图模式下拉 + 自定义Z 滑块。 + - 切 tab 发 `analysisModeChanged(bool is2D)`。 +- **段** `CategorySection`:段头(chevron+标题 | 新增三维体[反演类] | 导入雷达[voxel])+ 段体(**固定显示**的筛选行[日期范围+装置类型] + 可勾选数据树)。 +- **分类**:3D 用 `splitByCategory()`(`categoryConfigs()` 4 段);2D 用 `splitByDimension().dim2D`(当前仅 `dd_trajectory_data`)。 +- **渲染**: + - 2D 轨迹 → `MapLineActor`(橙色 `vtkPolyLine`),经 `VtkSceneController::set2DPlacement(mode,z)` 摆到**单一全局 Z**(5 模式:0关/1 Z=0/2顶+50/3底-50/4自定义)。已有逐 ds 的 Z 拖动偏移 `mapLineZOffset_`。 + - `VtkSceneView::setAnalysisMode2D(is2D)`:切 tab 时**按维度翻 actor 可见标志** + 相机锁定近俯视 + `VtkViewToolbar` 禁 6 向视图。 + - 底图 `TileBasemap`(单例):天地图 WMTS(卫星 `img_w`→`buildWarped` 带高程地形 / 矢量 `vec_w`→`buildFlat` 纯平面),透明度**固定 0.55**,瓦片范围 = `dataHorizontalRadius()×10` 钳 `[2000,30000]m`,置 Z=0。`buildFlat` 已能纯平贴矢量瓦片。 +- **顶部工具条** `TopBar`:视图/项目管理/业务工具/**设备** 四菜单。 +- **渲染区竖排工具栏** `VtkViewToolbar`:段1 `Gear`(坐标轴设置) → 分隔线 → 6向视图 → 缩放。 + +--- + +## 2. 已确认的关键决策(与用户逐条确认) + +1. **单一自由场景共存**:合并删 tab 后,**取消**「锁定近俯视相机 + 按维度自动显隐」。场景恒为自由透视,勾选的 2D 平面与 3D 体/帘面**同时可见**。 +2. **底图 = 1 个 3D 底图 + N 个 2D 底图**:所有三维数据**共用一个** 3D 底图(现状 `TileBasemap`);每个 **2D 类型(段)** 一块**独立平面底图**(N = 2D 段数,非每条 ds 一张)。 +3. **默认勾选**:沿用现有「直接挂项目下的 ds 默认进 VTK」逻辑,本次只保证动态显隐段时不破坏它。 +4. **2D z 值按类型一块平面**:每个 2D 类型一块平面 + 一个 z 滑块;平面初始 z = 该类型**第一个被勾选 ds** 的 z;同类型其余 ds 投影到此平面。 +5. **3D 底图控件移到 `VtkViewToolbar`**(Gear 之后),不在 3D 段上。 +6. **「导入雷达」移到 `TopBar` 设备菜单**(临时测试功能,后续整体移除)。 +7. **`view2DMode` 5 模式下拉废弃**,2D 高度完全由「z值」滑块替代。 + +--- + +## 3. 架构方案 + +**采用方案 A:统一单列 `DatasetColumn`(由 `CategoryAnalysisTab` 升级而来)。** + +- 用**一份扩展的段配置**(增 `dimension`)同时驱动 3D 类型段与 2D 类型段;`CategorySection` 扩展「响应式图标工具条 + 维度专属操作」。 +- 删除 `Column2DDataset` 与 `QTabWidget`;`ColumnDrawer` 承载单个 `DatasetColumn`,保留折叠开关。 +- 取舍:复用已验证的勾选保留/折叠/spinner/结构树逻辑;改动集中在段配置、段头工具条、2D 段操作、渲染落点。 + +(备选 B「两 widget 去 tab 竖堆」因 2D/3D 段不一致、重复逻辑被否;C「全重写」工作量过大被否。) + +--- + +## 4. 面板结构(§1 重构) + +- `ColumnDrawer`:去 `QTabWidget` + `Column2DDataset`;改持 `DatasetColumn`;**移除** `analysisModeChanged` 信号链。折叠开关保留。 +- `DatasetColumn`(原 `CategoryAnalysisTab` 改名/改造):`QScrollArea` 竖堆 N 个 `CategorySection`,**无栏目标题**。 +- **动态显隐**:段 bucket 为空 → 段 `hide()`;非空 → `show()`。三维体段同理(默认空→默认不显示)。`relayoutSections()`/stretch 逻辑只对可见段生效。 +- **空面板占位**:所有段均空时,滚动区中央显示提示语占位(文案:「请在左侧对象树勾选测线 / 数据集」);任一段非空则隐藏占位。 + +--- + +## 5. 统一段配置(§2) + +- `CategorySpec` 增字段:`Dimension dim`(枚举 `D3` / `D2`)。 +- `categoryConfigs()` 末尾加 2D 段:`{"trajectory","轨迹数据", dsTypeCode="", ddCode="dd_trajectory_data", dim=D2, ...}`。 +- 段顺序(自上而下):电阻率 / 视电阻率 / 瞬变(D3 反演)→ 三维体(D3)→ 轨迹(D2)。 +- 分流:`splitByCategory()` 扩展为同时按 D3 规则(现状)与 D2 口径(`dd_trajectory_data`,吸收 `splitByDimension` 的 2D 分支)分入对应段。`Column2DDataset`/`splitByDimension` 退役(保留 `dimOf` 给渲染路由按 ddCode 分派用)。 + +--- + +## 6. 响应式图标工具条(新建 `SectionIconBar`) + +- 段头右侧承载图标工具条:**默认最多显示 3 个图标**;图标总数超 3,或段宽被挤压放不下时,**右侧图标依次收进末尾「…」下拉菜单**。`resizeEvent` 动态重算可见数。 +- 每个图标 = `QToolButton`(autoRaise + glyph + tooltip),点击触发对应操作(部分弹 popup)。 +- 各维度图标集: + | 段 | 图标(左→右,右侧优先收进…) | + |---|---| + | 3D 反演(电阻率/视电阻率/瞬变) | `新增三维体`、`筛选` | + | 3D 三维体 | `筛选` | + | 2D 轨迹 | `z值`、`筛选`、`底图` | +- 注:当前各段图标 ≤3,「…」折叠为**前瞻能力**(后续图标会增加),需实现但当前不触发。 + +--- + +## 7. 段内操作行为(§4) + +### 7.1 筛选(通用,D2+D3) +- 现「固定显示的筛选行(日期范围 + 装置类型[仅 ERT])」改为**默认折叠**(段体内不占位)。 +- 点「筛选」图标 → 展开筛选行;再点 → 收起(toggle)。筛选逻辑(`passesFilters`/`rebuildList`)不变。 + +### 7.2 新增三维体(仅 3D 反演段) +- 保持原功能(发 `generateVolumeRequested`),入口从文字按钮改图标。 + +### 7.3 z值(仅 2D 段) +- 点图标弹 popup:一个滑块,整体上下移动**该 2D 类型那块平面**的 z。 +- 初值 = 该类型第一个被勾选 ds 的 z(见 §8.2);范围按场景高程量级合理取(实现期定)。 + +### 7.4 底图(仅 2D 段) +- 点图标弹 popup:【底图类型:矢量平面(默认) / 无】+【透明度滑块(默认 50%)】。 +- 作用于**该 2D 类型自己那块平面底图**(§9.2)。 + +### 7.5 3D 底图(移到 `VtkViewToolbar`,非段操作) +- 在 `Gear`(坐标轴设置) 正下方新增「地图」图标按钮,点击弹 popup:【底图类型:天地图(默认) / 无】+【透明度滑块(默认 50%)】。 +- 控制**全局唯一**的 3D 底图(`TileBasemap`):「无」= 隐藏;透明度去掉固定 `0.55`、改默认 `0.5` 可调。 + +### 7.6 导入雷达(移到 `TopBar` 设备菜单,临时测试) +- `TopBar` 设备菜单加「导入雷达测线」→ 子项「规范化(.head/.data)…」「Impulse(.iprb)…」,发等价于现 `radarImportRequested(impulse)` 的信号到既有导入流程。 +- 从 `CategorySection`(voxel 段头) 移除该入口及 `radarImportRequested` 转发。 + +--- + +## 8. 渲染模型(§5) + +### 8.1 删除维度耦合 +- 移除 `VtkSceneView::setAnalysisMode2D` 的「相机锁定俯视 + 按维度翻可见标志」与 `VtkViewToolbar::setAnalysisMode2D` 的 6 向禁用。场景恒自由透视;2D/3D actor 同时可见(各自由勾选控制显隐)。 +- 移除 `view2DMode` 5 模式(`set2DPlacement` 的 mode 维度退化为「按类型平面 z」)。 + +### 8.2 2D 按类型平面(需求 5) +- 同一 2D 类型(段)勾选的全部 ds 投影到**一块平面**: + - 平面 z = 该类型**第一个被勾选 ds** 的 z(首个勾选时确定;该 ds 取消后平面 z 保持,由 z 滑块掌控)。 + - 平面**纯平、不渲染高程**。 + - 同类型其余 ds 的折线全部落在此平面 z(覆盖现有逐 ds 全局 Z;逐 ds 拖动偏移 `mapLineZOffset_` 的取舍见 §11)。 +- 渲染复用 `MapLineActor`(折线几何不变),仅 Z 落点改为「所属类型平面 z」。 + +--- + +## 9. 底图体系(§6) + +### 9.1 3D 共享底图(1 个) +- 沿用 `TileBasemap` 单例(带高程地形,Z=0)。透明度参数化(默认 0.5,由 §7.5 popup 调);支持隐藏。瓦片范围规则不变。 + +### 9.2 2D 平面底图(N 个,每类型一块) +- 每个 2D 类型一块**纯平矢量底图**:复用天地图矢量图层 `vec_w` + `buildFlat`,贴在该类型平面 z(§8.2)上。 +- 瓦片范围**复用** `dataHorizontalRadius()×10` 钳 `[2000,30000]m` 规则。 +- 实现选型(实现期定):把 `TileBasemap` 参数化(z + 强制 flat + 图层 + opacity + 实例 id)以支持多实例;或抽出轻量 `PlaneBasemap`。优先参数化复用,避免瓦片下载/坐标对齐逻辑重复。 +- 坐标对齐沿用 `GeoLocalFrame`(经纬→局部);frame 重锚逻辑不变。 + +--- + +## 10. 信号 / 默认勾选(§7) + +- 2D 勾选/选中信号从 `Column2DDataset` 迁到 2D `CategorySection`(复用 `checkedDatasetsChanged` / `datasetSelected`)。`basemapChanged` / `view2DModeChanged` / `customZChanged` 退役,由 §7.4/§7.5 的 popup + §8.2 平面 z 替代。 +- 「直接挂项目下 ds 默认进 VTK」既有逻辑保留;动态显隐段时确保默认勾选的 ds 所属段被显示且勾选状态正确。 + +--- + +## 11. 迁移说明 / 取舍 / 待定 + +- **替代 2026-06-26 spec**:该 spec 的「一场景两相机 + 按维度显隐 + 高程拖动分层」中,**相机锁定 + 维度显隐被本 spec 推翻**(改单一自由场景共存)。其「2D 沿 Z 拖动分离」语义改由「按类型平面 + z 滑块」承担——逐 ds 独立拖动 `nudgeSelectedMapLinesZ` / `mapLineZOffset_` 是否保留待定:默认**退役**(统一到类型平面 z),若实测需要单条微调再议。 +- **`dd_raster`** 仍未接(2026-06-26 §6 遗留),本 spec 不含;后续作为新的 2D 类型段加入时复用 §8.2/§9.2 平面+底图机制。 +- **3D 反演段 vs 三维体段**:均为 D3,但 3D 反演段渲染为帘面、三维体段为体素/雷达体——共用 3D 底图与自由场景,无需区分。 +- **责任拆分**:`SectionIconBar` 响应式工具条、`TileBasemap` 多实例参数化、`DatasetColumn` 动态显隐 三块相互独立,可分别实现与测试。 + +--- + +## 12. 验收 + +1. 左侧只有**一个无标题数据集栏**(无 tab);其中同时出现 3D 类型段(电阻率/视电阻率/瞬变/三维体)与 2D 类型段(轨迹)。 +2. 段**动态显隐**:无对应数据的段不显示;面板全空时显示居中占位提示。 +3. 段头操作为**图标工具条**:默认最多 3 个,超出/挤压时右侧收进「…」下拉。3D 反演段含「新增三维体/筛选」,2D 轨迹段含「z值/筛选/底图」。 +4. 「筛选」图标可**展开/收起**段内筛选行(默认折叠)。 +5. 勾选 2D 轨迹:同类型 ds 投影到**一块纯平平面**,平面 z = 首个勾选 ds 的 z;「z值」滑块整体升降该平面;「底图」popup 可换矢量平面底图/无 + 调透明度(默认 50%)。 +6. 3D 与 2D 数据在**同一自由透视场景**同时可见,可自由旋转(无锁定俯视、无 tab 切换)。 +7. 渲染区工具栏 Gear 下方新增「地图」按钮,控制全局 3D 底图(天地图/无 + 透明度默认 50%)。 +8. 「导入雷达」入口出现在顶部「设备」菜单;三维体段头不再有该按钮。 +9. 「直接挂项目下的 ds」加载时默认勾选进 VTK 不被破坏。