feat/object-selection-panels #4
|
|
@ -1,376 +0,0 @@
|
||||||
# Geopro 3.0 桌面客户端 — M1 架构设计
|
|
||||||
|
|
||||||
**日期**:2026-06-07
|
|
||||||
**版本**:v2(已按双专家评审 + 数据核验修订;修订点见 §16)
|
|
||||||
**状态**:待用户复核 v2
|
|
||||||
**范围**:M1 里程碑 = 完整工作台外壳 + 登录功能 + 三维视图(基础渲染 / dd_voxel 体绘制与切片 / DEM 地形)
|
|
||||||
**上位文档**:`docs/Geopro3.0_技术选型与架构规约.md`(技术基线,本文遵从其全部约束)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. 目标与范围
|
|
||||||
|
|
||||||
### 1.1 M1 交付目标
|
|
||||||
|
|
||||||
复刻 Geopro 3.0 最核心的「项目分析视图」桌面版,并把登录做实:
|
|
||||||
|
|
||||||
1. **登录功能完全可用**:真实连接生产后端(`pop-api`),走验证码 + RSA 加密密码流程,token 安全存储。登录页样式参考现有 web 系统。
|
|
||||||
2. **完整工作台外壳**:ADS 三区停靠布局,还原原型(左:对象树 + 数据集列表;中:2D/3D 视图 + 数据详情;右:异常列表/对象属性 + 属性)。
|
|
||||||
3. **三维视图**(M1 核心难点):
|
|
||||||
- ① 基础渲染:剖面散点、网格等值面/等值线/标注、异常圈定(直接渲染)
|
|
||||||
- ② dd_voxel 体绘制 + 鼠标交互切片(dd_slice)——C++ 进程内三维插值;**追求可信体**(非演示性),故对输入数据有要求(见 §10、§13 分阶段)
|
|
||||||
- ④ DEM 地形起伏 + 影像贴图
|
|
||||||
- 二维俯视相机预设(验证「单一场景」架构)
|
|
||||||
4. **业务数据来源**:登录联网;工作台业务数据 M1 用本地样本文件,经 Repository 抽象注入,未来无缝切 API。
|
|
||||||
|
|
||||||
### 1.2 不在 M1 范围
|
|
||||||
|
|
||||||
- ③ 雷达单/多通道渲染、⑤ 在线底图瓦片 → M1.5
|
|
||||||
- 反演/数据处理算法本体(M1 只做「展示期插值」,不做反演)
|
|
||||||
- 项目管理、设备连接、在线监测、报告、平台后台、Web 端
|
|
||||||
- 完整算法插件架构(进程隔离 + manifest)→ 规约 D-3 推迟;M1 仅以 `IInterpolator` 接口预留
|
|
||||||
- 在线更新三通道(规约 §8)
|
|
||||||
- macOS 构建(M1 先 Windows / MSVC 2022,架构保持跨平台可移植)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. 关键决策记录
|
|
||||||
|
|
||||||
| 编号 | 决策 | 结论 |
|
|
||||||
|---|---|---|
|
|
||||||
| K-1 | 2D/3D 视图架构 | **单一 VTK 三维场景 + 相机预设切换**;底图做可插拔 GroundLayer(规约 §5.3、D-5)。被现有 web「Cesium 单 3D 引擎」实践印证。 |
|
|
||||||
| K-2 | 启动节奏 | 先出设计文档 → **spike 预研门槛** → 再写完整实现计划 |
|
|
||||||
| K-3 | M1 外壳范围 | 完整工作台(A 方案) |
|
|
||||||
| K-4 | 业务数据来源 | 登录走真实 API;业务数据本地样本 + Repository 抽象(B 方案) |
|
|
||||||
| K-5 | M1 三维内容 | ① 基础 + ② dd_voxel(可信体,图分阶段)+ ④ DEM;③ 雷达、⑤ 底图瓦片留 M1.5 |
|
|
||||||
| K-6 | 三维插值实现 | C++ 进程内(IDW 起步),`IInterpolator` 接口隔离、**返回 core 中立类型**;推迟完整插件架构(D-1/D-3) |
|
|
||||||
| K-7 | 坐标系 | **每数据源各记源 CRS + 各自 LocalFrame** → 统一 rebase 到唯一「项目世界系(局部米,含 Z 基准)」;GIS/经纬/底图用 PROJ 实时换算(见 §5) |
|
|
||||||
| K-8 | 构建/部署 | **方案②-修订**(经双专家评审+实机勘验改定):单一 Qt = **官方 MSVC 预编译 Qt**(`D:\Qt\6.11.1\msvc2022_64`);**VTK/ADS/QtKeychain 对接该官方 Qt**(VTK 源码编到 install 前缀、ADS/QtKeychain 走 FetchContent),**绝不走 vcpkg**(否则 vcpkg 再拉一份 Qt = 双份);仅非 Qt 依赖(GDAL/PROJ/OpenSSL/Eigen/...)走 vcpkg。**关键事实**:用户原装的 `D:\Qt\6.11.1` 是 **MinGW 版**,MSVC 下不可链,须补装 MSVC kit;VTK 无 MSVC 预编译、三方案均须源码编;VS18=MSVC 14.51 链官方 Qt(v143)属"新链旧"ABI 安全。 |
|
|
||||||
| K-9 | 视图 widget | 评估 **`QVTKOpenGLStereoWidget`(QOpenGLWidget 系)** 优先于 native,缓解 ADS reparent 上下文丢失(spike 验证) |
|
|
||||||
| K-10 | dd_voxel 可信度 | 维持可信体目标;可信度取决于输入数据充分性(≥3 非共线剖面或 3D 网格),列为数据依赖(见 §10、§14) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. 分层架构与目录结构
|
|
||||||
|
|
||||||
遵循规约 §10.3 清晰分层(core / data / view / controller / app),细分 net、render。
|
|
||||||
|
|
||||||
```
|
|
||||||
geopro/
|
|
||||||
├─ CMakeLists.txt / CMakePresets.json / vcpkg.json
|
|
||||||
├─ .clang-format / .clangd # AI 编码上下文基础设施(规约 §10.1)
|
|
||||||
├─ cmake/ # Find 模块、打包、dll 部署
|
|
||||||
├─ src/
|
|
||||||
│ ├─ core/ # 纯业务,零 Qt / 零 VTK 依赖(可独立单测)
|
|
||||||
│ │ ├─ model/ # Project, GsObject, TmObject, DsObject, Anomaly, ColorScale, Grid, ScatterField, ScalarVolume
|
|
||||||
│ │ ├─ geo/ # LocalFrame(原点+Z基准+轴向)、CrsTransform(PROJ 封装,多 CRS)
|
|
||||||
│ │ └─ algo/ # IInterpolator 接口 + IdwInterpolator(返回 core 的 ScalarVolume,绝不含 VTK)
|
|
||||||
│ ├─ data/ # 数据访问层(异步契约)
|
|
||||||
│ │ ├─ repo/ # IProjectRepository, IDatasetRepository(QFuture/回调 + 取消 + 分页)
|
|
||||||
│ │ ├─ local/ # LocalSampleRepository(QtConcurrent 线程池跑解析)+ 各格式解析器
|
|
||||||
│ │ ├─ api/ # ApiRepository(M1 骨架,签名对齐)
|
|
||||||
│ │ └─ dto/ # 后端 JSON DTO + → model 映射
|
|
||||||
│ ├─ net/ # ApiClient(QtNetwork)/ AuthService(验证码+RSA+login2)/ Credential(QtKeychain)
|
|
||||||
│ ├─ render/ # VTK 渲染层(独占 vtkRenderWindow,统一管理所有 actor)
|
|
||||||
│ │ ├─ Scene # 场景图、世界坐标空间、可见性;持有 RenderWindow
|
|
||||||
│ │ ├─ actors/ # ScatterActor, GridContourActor, VoxelVolumeActor, AnomalyActor, TerrainActor
|
|
||||||
│ │ ├─ color/ # ColorLutBuilder(colorBar → vtkLookupTable 离散阶梯), ScalarBar
|
|
||||||
│ │ ├─ camera/ # CameraPreset(Top2D / Free3D)
|
|
||||||
│ │ ├─ interact/ # InteractionManager + InteractionTool(MeasureTool/SliceTool/PickSelectTool)
|
|
||||||
│ │ └─ ground/ # IGroundLayer + DemImageGroundLayer(M1);TileGroundLayer(M1.5 预留)
|
|
||||||
│ ├─ view/ # QtWidgets 视图(被动;持有 VTK widget 外壳,不 new actor)
|
|
||||||
│ │ ├─ login/ # LoginWindow(样式参考 web)
|
|
||||||
│ │ ├─ panels/ # ObjectTreePanel, DatasetListPanel, MapViewPanel(QVTKOpenGLStereoWidget),
|
|
||||||
│ │ │ # DataDetailPanel, AnomalyPanel, ObjectPropertyPanel, PropertyPanel
|
|
||||||
│ │ └─ widgets/ # ColorScaleEditor, ToolbarBits
|
|
||||||
│ ├─ controller/ # 联动编排(按交互闭环拆分,避免 God Object)
|
|
||||||
│ │ ├─ SelectionController # 勾选/选中状态
|
|
||||||
│ │ ├─ RenderSyncController # 状态→Scene 渲染同步
|
|
||||||
│ │ └─ DetailSyncController # 列表↔详情↔视图定位三向联动
|
|
||||||
│ └─ app/ # main / MainWindow(ADS 布局、主题)/ AppContext(DI 根)
|
|
||||||
├─ resources/ # QSS 主题、QtAwesome、登录页素材
|
|
||||||
├─ tests/ # gtest(core/data/algo)+ Qt Test(view/controller)
|
|
||||||
└─ docs/
|
|
||||||
```
|
|
||||||
|
|
||||||
**架构铁律(写入 .clangd 供 AI 读取)**:
|
|
||||||
|
|
||||||
- `core` 绝不 `#include` 任何 Qt / VTK 头(含 `IInterpolator`,返回 `core::ScalarVolume`)。
|
|
||||||
- VTK actor / RenderWindow 一律由 `render` 层创建与持有;`view` 只持有 `QVTKOpenGLStereoWidget` 外壳,把其 interactor 注入 render,并将**拾取/交互事件回流**给 controller(见 §4.4),禁止直接 new actor。
|
|
||||||
- 数据流双向已显式化:`view → render`(交互注入)与 `render → controller`(拾取/选择出站信号)。
|
|
||||||
- 信号槽连接集中在各 `*Controller` / `MainWindow` 的 `wireUp()`。
|
|
||||||
- 所有落盘路径经 `QStandardPaths`(规约 §7.1)。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. 渲染核心:单一 VTK 场景(K-1)
|
|
||||||
|
|
||||||
> **⚠️ 实现修正(2026-06-07,经离屏 PNG 核对;权威做法以此为准,详见 `plans/2026-06-07-m1-view-redesign.md` + STATUS)**
|
|
||||||
> 本节 §4.2「2D/3D 仅切相机预设、零数据重建」的理想对**当前 M1 测线数据不成立**:剖面是竖直帘面,俯视只剩一条发丝线 → 俯视图空白。M1 落地做法:
|
|
||||||
> - **二维地图** 与 **三维视图** 是**两种不同渲染内容**(非同一物体换相机):二维地图 = 测线 `lat/lon` 轨迹**线**(`MapLineActor`,俯视);三维视图 = 沿测线的**竖直帘面**(`CurtainActor`,z 取负、纵向夸张、分段色带)。
|
|
||||||
> - **数据详情**(独立 QVTK)才显示单条数据集的 **#18 平面反演剖面**(`GridContourActor`,y 取负、显式 structuredGrid、colorBar 真实分段值、纵向夸张)。
|
|
||||||
> - 坐标统一用 `core::GeoLocalFrame`(经纬→局部米)。**dd_voxel/dd_slice 搁置**(散点 projX/Y 真实 CRS 未确认,无法与 lat/lon 配准)。
|
|
||||||
> - K-1「单场景 + 相机预设」仍是**长期目标**,但需要从俯视/透视都可读的内容(如带底图的地面 + 测线落地线 + 帘面共存)才成立。
|
|
||||||
> - **等值线/体素着色必须用 colorBar 真实非均匀分段值**(均匀分级会一片蓝)。**渲染改动必须用 `tests/spike/render_verify.cpp` 离屏 PNG 核对**。
|
|
||||||
|
|
||||||
### 4.1 Scene 与 RenderWindow 所有权
|
|
||||||
|
|
||||||
- `render::Scene` 持有**唯一** `vtkRenderWindow` + `vtkRenderer` + 项目世界坐标空间里的全部 actor,维护当前色阶与坐标系。
|
|
||||||
- **单一 `QVTKOpenGLStereoWidget`**(K-9,QOpenGLWidget 系,FBO 合成、reparent 友好)承载渲染窗口,**不放进 Tab**;中央面板的「二维/三维」是工具栏上的模式切换,不是两个 widget。
|
|
||||||
- view 仅持有该 widget 外壳;RenderWindow/Interactor 所有权归 render。
|
|
||||||
|
|
||||||
### 4.2 2D / 3D = 三要素组合
|
|
||||||
|
|
||||||
| 模式 | CameraPreset | InteractorStyle | 典型可见性 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| 二维 | Top2D:正交投影、俯视、Z 锁定 | Locked2D:禁旋转,平移/缩放/正南正北 | 地面 + 平面要素 + 俯视散点/网格 |
|
|
||||||
| 三维 | Free3D:透视、自由轨道 | Orbit3D:自由旋转/缩放/平移 | 全部 actor(体素、剖面、地形起伏) |
|
|
||||||
|
|
||||||
切换 = 切相机预设 + 交互器样式 + 工具集 + actor 可见性,**零数据重建**。
|
|
||||||
|
|
||||||
### 4.3 数据 → VTK 管线映射(已按评审修正)
|
|
||||||
|
|
||||||
| 数据类型 | 来源 | VTK 管线(修正后) | 备注 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| 剖面散点 | 剖面原数据(2597 点) | `vtkPolyData`(verts) + `vtkLookupTable` 着色 | 图 #17 |
|
|
||||||
| 网格等值面/线/标注 | 网格数据(规则栅格 x[100]×y[22],v[22][100],z 抬升) | **`vtkImageData`(origin+spacing)→(z 抬升用 `vtkWarpScalar`)→ `vtkDataSetSurfaceFilter`/`vtkGeometryFilter` → `vtkBandedPolyDataContourFilter`(开 `GenerateContourEdgesOn()` 一次产 banded 面+等值线,共用阈值)→ `vtkLabeledDataMapper` 标注** | 图 #18;**不可让 structured/image 直连 banded filter**(B-1) |
|
|
||||||
| dd_voxel 体绘制 | 多剖面散点 → `IInterpolator` → `core::ScalarVolume` | `ScalarVolume` →(render 转)`vtkImageData` → `vtkGPUVolumeRayCastMapper` + 颜色/不透明度传递函数 | 图 #09;插值域受限(§10) |
|
|
||||||
| dd_slice 切片 | voxel + 受控切面 | **`vtkResliceCursorWidget` / `vtkImageReslice`**(受控正交/任意切片),随相机模式启停 | 替代 `vtkImagePlaneWidget`(避免与交互器抢事件,M-2) |
|
|
||||||
| 异常圈定 | 异常数据(markType 1点/2线/3面 + legend + z/elevation) | **按 markType 三条子管线**:点 `vtkGlyph3D`(pointShape)、线 polydata+dashed、面 `vtkPolygon`/`vtkTriangleFilter` 填充+边框;标注屏幕空间 billboard | legend 的 `*NoOpacity` 0–100 → 归一 [0,1];z 取值同剖面 Z 基准(§5) |
|
|
||||||
| DEM 地形 + 影像 | dem.tif + image.tif + tfw(**可能异源 CRS**) | GDAL 读 → **PROJ/GDAL 重投影到项目世界 CRS** → `vtkImageData` → `vtkWarpScalar` 抬升 + 影像纹理 | 图 #05;影像实测为 EPSG:3857,须重投影(§5、M-1) |
|
|
||||||
| 色阶 | colorBar:[值, 颜色] 阶梯 | `vtkLookupTable`(离散阶梯,取下界)+ `vtkScalarBarActor` | 见 §7 |
|
|
||||||
|
|
||||||
### 4.4 模态交互与拾取回流(M-2、B-3)
|
|
||||||
|
|
||||||
- `InteractionManager` 管理**模态工具**激活互斥与 VTK observer 优先级:`MeasureTool`、`SliceTool`、`PickSelectTool`。工具激活/退出负责其临时 actor 生命周期。
|
|
||||||
- 3D Widget(切片)与自定义 InteractorStyle 共享同一 interactor,须显式管理 `SetEnabled()` 与事件优先级,避免抢事件。
|
|
||||||
- **拾取回流通道**:`render` 拾取到对象 → 经 view 中转发出出站信号 → `DetailSyncController` → 列表/详情定位。此箭头在分层图中显式存在(§3)。
|
|
||||||
|
|
||||||
### 4.5 GroundLayer 可插拔
|
|
||||||
|
|
||||||
`IGroundLayer { build(Scene&); setVisible(bool); }`:M1 `DemImageGroundLayer`;M1.5 `TileGroundLayer`。若 VTK 贴瓦片体验差(D-5),可仅替换二维为 MapLibre 而不动 data/render 的 actor 体系。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. 坐标系设计(K-7,评审最大短板,已重写)
|
|
||||||
|
|
||||||
数据现实(已核验真实样本):
|
|
||||||
|
|
||||||
- 剖面/网格/异常:带 GIS 投影 `projectX`≈516868=**Easting**、`projectY`≈2494259=**Northing**;另带局部米 `xlist/ylist`(各数据集自原点起算)。
|
|
||||||
- ⚠️ **CRS 待确认(Phase 1 用 PROJ 实测纠正)**:`projectX/Y` 的真实 CRS **不是 EPSG:32649**。PROJ 实测 `(516868,2494259)` 在 EPSG:32649 下解出 lon≈**111.16°E**,而网格自带 lat/lon 是 **114.16°E**(docx 标明为**香港** Volia 数据,香港≈114°E)——真实 CRS 的中央经线在 ~114°E(疑为港式/自定义 TM)。**做底图/影像配准(M1.5)前必须向客户确认项目 CRS**。
|
|
||||||
- **对 M1 core 无影响**:`LocalFrame` 用相对米(减原点,CRS 无关),网格自带 lat/lon;`CrsTransform` 已实现并单测验证 PROJ 机制本身。
|
|
||||||
- 影像 `image.tfw`:原点 (12708343, 2577685) = **EPSG:3857(Web 墨卡托)**,与剖面**不同投影**。
|
|
||||||
- 网格另带 `elevation[100]` / `lat/lon`(经纬度,EPSG:4326)。
|
|
||||||
- API 几何 `tm/geometry/get` 返回 **EPSG:4326**。
|
|
||||||
|
|
||||||
**设计**:
|
|
||||||
|
|
||||||
1. **唯一权威系 = 项目世界系**:局部米,含明确 Z 基准;选定一个工作平面 CRS(默认项目 UTM,如 EPSG:32649)+ 双精度原点偏移。
|
|
||||||
2. **每数据源各记源 CRS + 源 LocalFrame**:领域模型为每个数据集保存其源 CRS 与(如有)自身局部原点。**不假设全项目单一 CRS**。
|
|
||||||
3. **统一 rebase 管线**(显式步骤,非一句话):任何几何进入 Scene 前,`CrsTransform`(PROJ)把 `源局部米 →(源原点)→ 源 CRS GIS → 项目世界 CRS →(减项目原点)→ 项目世界米`。多数据集因此对齐到同一世界系(解决 B-1 多原点冲突)。
|
|
||||||
4. **轴向约定钉死**:world.x = Easting = `projectX`,world.y = Northing = `projectY`,world.z 向上为正、单位米。**解析器不信 `eastCoord/northCoord` 字段名**(实测与值颠倒),按 projectX/Y 取值,单测对照(B-2)。
|
|
||||||
5. **垂向(Z)基准统一**(M-3):`LocalFrame` 定义高程基准面、向上为正、单位米、可选垂向夸张 z-scale。网格 z(剖面深度/构造面)、DEM `elevation`(地表高程)、体素 Z 在进入 Scene 前统一归算到该基准,避免地形与剖面垂直穿插。
|
|
||||||
6. **影像/DEM 重投影**:装载时经 GDAL/PROJ 重投影到项目世界 CRS 再贴地,**不能简单减原点**(M-1)。
|
|
||||||
7. **float 精度**:世界=局部米(小数值)从根本规避 VTK float 大坐标抖动。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. 数据层:Repository(K-4,异步契约)
|
|
||||||
|
|
||||||
接口即按 **API 现实形态**定义(异步 + 分页 + 取消),本地实现用 QtConcurrent 满足同一签名(M-1):
|
|
||||||
|
|
||||||
```
|
|
||||||
IProjectRepository {
|
|
||||||
QFuture<Project> loadProject(id);
|
|
||||||
QFuture<vector<GsObject>> loadStructure(projectId); // GS/TM 树
|
|
||||||
}
|
|
||||||
IDatasetRepository {
|
|
||||||
QFuture<Page<DsObject>> listDatasets(tmObjectId, PageReq); // 分页
|
|
||||||
QFuture<ScatterField> loadScatter(dsId);
|
|
||||||
QFuture<Grid> loadGrid(dsId);
|
|
||||||
QFuture<ColorScale> loadColorScale(dsId);
|
|
||||||
QFuture<vector<Anomaly>> loadAnomalies(dsId);
|
|
||||||
QFuture<TerrainTile> loadTerrain(...);
|
|
||||||
// 大数据(体素/雷达):返回带取消句柄 + 进度回调;M1.5 走 FlatBuffers/Protobuf 流
|
|
||||||
RequestHandle loadVolumeStream(dsId, sink, onProgress); // 可 cancel
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- 切换 ds 时取消上一个未完成请求;列表类带游标/分页;大数据流式 + 进度 + 取消。
|
|
||||||
- **M1**:`LocalSampleRepository` 读样本目录,解析器映射成领域模型(DTO ↔ model 在 `data/dto` 隔离)。
|
|
||||||
- **未来**:`ApiRepository` 同签名对接 `pop-api`。
|
|
||||||
|
|
||||||
### 6.1 样本文件 → 模型解析约定(已核对真实样本)
|
|
||||||
|
|
||||||
| 文件 | 结构 | 解析要点 |
|
|
||||||
|---|---|---|
|
|
||||||
| 剖面原数据N.txt | `{data:{min,max,projectXList,projectYList,vlist,xlist,ylist,hlist}}` | 2597 点;local(x,y)+gis(projX=East,projY=North)+value |
|
|
||||||
| 剖面网格数据N.txt | `{data:{x[100],y[22],v[22][100],z[22][100],elevation[100],lat[100],lon[100],vmin,vmax,overlayCoordinate,overlayElevation}}` | **规则栅格**(dx≈0.709,dy≈0.704 恒定)→ vtkImageData;**v/z 为 [j=y][i=x],灌点序 i 最快**;无顶层 min/max;对未知字段宽容 |
|
|
||||||
| 剖面网格数据的色阶数据N.txt | `{data:{properties:{colorBar:[[值,rgba]],lineConfig,labelConfig,lvlMinMax}}}` | 17 段阶梯;`lineType` 实测 "solid"(以配置为准,勿硬编码 dashed) |
|
|
||||||
| 剖面网格数据N——对应的异常圈定数据.txt | `{data:[{exceptionName,exceptionMarkType(1点/2线/3面),legend{point*/polyline*/polygon*},location:{coordinate[{x,y}]},zlist?,elevationList?,geographicalCoordinates{projectX,projectY,...}}]}` | 字段比早期列举多;`eastCoord/northCoord` 名值颠倒,按 projectX/Y 取 |
|
|
||||||
| dem.tif / image.tif / image.tfw | GeoTIFF + world file | **影像 tfw 为 EPSG:3857**;GDAL 读 + PROJ 重投影到世界 CRS |
|
|
||||||
| test_001_A*.head/.data/.cor | GPR 原始(462×4100×int16,多通道分文件) | **属 M1.5 雷达,LocalSampleRepository 不解析** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. 色阶(ColorScale)
|
|
||||||
|
|
||||||
`colorBar` 为 `[值, 颜色]` 阶梯数组(颜色支持 `#RRGGBB` 与 `rgba(r,g,b,a)`)。映射:值落相邻两 stop 间取**下界 stop** 颜色(阶梯,非线性插值)。
|
|
||||||
|
|
||||||
- **实现统一为离散 `vtkLookupTable`**(贴合「取下界阶梯」语义,2D/3D 共用同一可信源),显式定义 under(低于首 stop)/ over(高于末 stop)/ NaN 颜色。
|
|
||||||
- **alpha 量纲按色阶来源文件类型判定**(网格色阶 0–255、LVL 色阶 0–1),解析器入口带 source 标记,**不按数值范围猜**(m-2)。
|
|
||||||
- `lineConfig`:等值线显隐/颜色/`lineType`(以配置为准)/zmin/zmax;`labelConfig`:标注显隐/颜色;`equalAreaLayerCount`/`logLinesCount`。
|
|
||||||
- 视图层 `ColorScaleEditor`:M1 读取与基本调整;命名保存对接后续色阶模板 API。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. 登录与网络层(M1 必做,真实流程已抓取)
|
|
||||||
|
|
||||||
### 8.1 已确认的生产实现细节
|
|
||||||
|
|
||||||
- **API 基址** `http://tenant.geomative.cn/pop-api`(openresty 反代;OpenAPI 的 `/admin/*`、`/business/*` 加 `/pop-api` 前缀)。
|
|
||||||
- **认证头** `geomativeauthorization: Geomative <token>`(不透明会话令牌,非 JWT)。
|
|
||||||
- **登录三步**:① `GET /business/system/personalUser/getImageCode`→验证码图+`codeId` → ② `POST /business/system/personalUser/verifyCodeCheck {code,codeId}` → ③ `POST /admin/tenant/auth/login2 {username, password=RSA加密, checkCode}`→token。
|
|
||||||
- **密码加密 = JSEncrypt RSA-2048**(前端 vendor 用 JSEncrypt 库;密文 base64 ~344 字符 = 256 字节)。token 取响应 **`data.accessToken`**(值即 `"Geomative <hash>"`,存 web localStorage `token`)。
|
|
||||||
- 另有 `/email`、`/phone` 登录支线(非 M1)。
|
|
||||||
- 登录后:`getInfo` / `list-menus` / `enterprise/info` / `enterprise/joined/list`。
|
|
||||||
|
|
||||||
### 8.2 实现要点
|
|
||||||
|
|
||||||
- `AuthService`:取验证码→展示→校验→**OpenSSL RSA** 加密密码→login2→持有 token。
|
|
||||||
- `Credential`(**QtKeychain**):token 存平台密钥库,严禁明文(规约 §7.4)。
|
|
||||||
- `ApiClient`:注入 `geomativeauthorization`、基址、超时、错误码、401 处理;QtNetwork 原生。
|
|
||||||
- **登录窗 UI**:样式参考现有 web 登录页(实现阶段截图复刻)。
|
|
||||||
|
|
||||||
### 8.3 ⚠️ 前置确认项(与 RSA 同级,M-5)
|
|
||||||
|
|
||||||
抓取的真实流程里**未见 refresh-token 实际使用,login2 只返不透明会话 token**。因此:
|
|
||||||
|
|
||||||
- **RSA 公钥已取得 ✅**(Phase 3,用 Playwright `page.route` 拦截 JS chunk 给 `setPublicKey` 注入 hook + 缓存绕过强制加载补丁版,触发一次真登录捕获)。RSA-2048 SPKI,存于 `resources/rsa_public_key.pem`。加密用 PKCS#1 v1.5(JSEncrypt 默认),`RsaEncryptor`(OpenSSL)已实现+单测。
|
|
||||||
- **token 生命周期 / 是否有 refresh 机制**待确认。据此二选一设计:
|
|
||||||
- (a) 有 refresh token → 标准静默刷新、401 静默续期。
|
|
||||||
- (b) 仅会话 token → 「免登录」= 持久化会话 token 至其有效期;**到期/401 引导用户重新登录(含验证码),不声称静默重登**。
|
|
||||||
- 本项在 spike/实现前向后端确认;spec 不把「静默刷新」当既定能力。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. UI 外壳:完整工作台(K-3)
|
|
||||||
|
|
||||||
- **停靠框架**:ADS(LGPL,规约 §6.2)。**VTK 面板默认不可浮动**(或浮动时占位、停靠回重建),缓解 reparent 上下文问题(spike 验证,M-4)。
|
|
||||||
- **三区布局**(还原原型):左(对象树 + 数据集列表)/ 中(2D-3D 视图 + 数据详情)/ 右(异常-对象属性 + 属性)。
|
|
||||||
- **主题**:QSS + QDarkStyleSheet 打底 + QtAwesome 图标。
|
|
||||||
- **布局持久化**:ADS 透视图 + 窗口几何存 QSettings(Windows 强制 INI,规约 §7.2)。
|
|
||||||
- **联动**(controller 按闭环拆分,§3):勾选 GS/TM→按 dd 类型筛选 ds→勾选 ds→渲染;列表↔详情↔视图定位三向;色阶调整两视角实时更新。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. 算法:展示期三维插值(K-6、K-10)
|
|
||||||
|
|
||||||
- `core/algo/IInterpolator`:`core::ScalarVolume interpolate(const PointSet& pts, const GridSpec& spec)`——**返回 core 中立类型**(dims/spacing/origin/double 数组),绝不含 VTK(M-2)。render 层 `VoxelVolumeActor` 把 `ScalarVolume`→`vtkImageData`。
|
|
||||||
- M1 实现 `IdwInterpolator`(反距离加权,Eigen 辅助;2597 点规模**不需要 PCL/KD-tree**,m-1)。
|
|
||||||
- **可信度与数据依赖(K-10、B-3)**:可信体素需 **≥3 条非共线剖面或真实 3D 网格(dd_Property3D)/ 反演网格** 输入。仅两条近平行剖面 IDW 会得到「夹层片状」幻影。故:
|
|
||||||
- 插值**限定在输入包络内 + 最大距离 clamp**,包络外置 blank/透明,避免 ray cast 渲染整盒幻影。
|
|
||||||
- M1 体绘制按 §13 分阶段:先在**充分输入**数据上出可信体;输入不足的复杂体后置。
|
|
||||||
- **数据依赖**:需客户提供达到可信度的体素级输入数据(≥3 剖面 / 3D 网格)——列入 §14 待办。
|
|
||||||
- **不做反演**(上游、Python 生态 ResIPy 等),未来按规约 §8.3 进程隔离接入,M1 仅接口预留。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. 构建与依赖(K-8,方案②-修订:官方 MSVC Qt + 源码 VTK + vcpkg 非 Qt 依赖)
|
|
||||||
|
|
||||||
- **构建**:CMake 3.21+。MSVC 工具集 **VS18 / 14.51**(实机),C++17;生成 `compile_commands.json`。
|
|
||||||
- **单一 Qt 纪律(核心)**:全链路只用**一份官方 MSVC 预编译 Qt**(`D:\Qt\6.11.1\msvc2022_64`,经 `CMAKE_PREFIX_PATH`)。**凡依赖 Qt 的组件都不走 vcpkg**(vcpkg 任何 Qt 依赖端口都会再编一份 qtbase = 双份冲突,已核 `ports/vtk/vcpkg.json`:`vtk[qt]`→`qtbase`+`qtdeclarative`)。
|
|
||||||
- **VTK**:无 MSVC 预编译,**必须源码编**。预先用官方 Qt 把 VTK 9.3 配置/编译/`install` 到 `external/vtk-install`(`-DVTK_GROUP_ENABLE_Qt=YES -DQt6_DIR=...`),app 经 `VTK_DIR` `find_package(VTK)`。一次编好、隔离于 app 构建。
|
|
||||||
- **ADS / QtKeychain**:经 **FetchContent** 对接同一份官方 Qt(体量小,源码编可接受),**不走 vcpkg**。
|
|
||||||
- **非 Qt 依赖经 vcpkg**:GDAL/PROJ/OpenSSL/Eigen/spdlog/fmt/nlohmann-json/gtest(这些不拉 Qt)。
|
|
||||||
- **M1 依赖矩阵**:
|
|
||||||
|
|
||||||
| 依赖 | 来源 | 用途 | 许可证 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| Qt 6.11.1(msvc2022_64,预编译) | 官方安装器(MSVC kit) | UI/网络/SQL/并发 | LGPLv3(动态)⚠️ 商务 D-2 |
|
|
||||||
| VTK 9.3([qt,opengl] + gdal/proj 可选) | **源码编→install 前缀** | 三维渲染 + QVTK widget | BSD ✅ |
|
|
||||||
| ADS(Qt-Advanced-Docking-System) | FetchContent(对接官方 Qt) | 停靠布局 | LGPL v2.1 ✅ |
|
|
||||||
| QtKeychain | FetchContent(对接官方 Qt) | 凭证存储 | BSD ✅ |
|
|
||||||
| gdal / proj | vcpkg | DEM/影像/坐标重投影 | MIT 类 ✅ |
|
|
||||||
| openssl | vcpkg | RSA/HTTPS | Apache 2.0 ✅ |
|
|
||||||
| eigen3 | vcpkg(头文件) | 数值/插值 | MPL2 ✅ |
|
|
||||||
| spdlog / fmt | vcpkg | 日志 | MIT ✅ |
|
|
||||||
| nlohmann-json | vcpkg(头文件) | JSON | MIT ✅ |
|
|
||||||
| gtest | vcpkg | 单测 | BSD ✅ |
|
|
||||||
|
|
||||||
- ~~PCL~~:**M1 移除**(点规模不需要)。
|
|
||||||
- **ABI**:官方 Qt 为 MSVC 2022(v143)预编译,本机 VS18(14.51)编 VTK/app/ADS/QtKeychain;"新链旧"在 MSVC v14x 兼容区内**安全**,全程动态 CRT `/MD[d]`、Release 链 Release、Debug 链 Debug,不跨配置混链。
|
|
||||||
- 部署:用**官方 Qt 的 `windeployqt`**(`D:\Qt\6.11.1\msvc2022_64\bin\windeployqt.exe`)部署 Qt + 插件;VTK/vcpkg dll 用 `TARGET_RUNTIME_DLLS` 拷贝。确保 exe 目录只有这一份 Qt。
|
|
||||||
- **二进制缓存**:vcpkg 实测无缓存,落地前先配 `VCPKG_BINARY_SOURCES`(省 GDAL/PROJ 等重编)。
|
|
||||||
- 环境从零搭建:见 `docs/ENV_SETUP_Windows.md`(方案②-修订)。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12. 测试策略(规约 §10.2)
|
|
||||||
|
|
||||||
- `core`/`data`/`algo`:gtest(坐标 rebase/轴向、Z 基准归算、colorBar LUT 映射、v[j][i] 灌点序、样本解析、IDW 正确性)。
|
|
||||||
- `view`/`controller`:Qt Test(联动、模态工具互斥)。
|
|
||||||
- 失败路径必测:登录失败/验证码错/token 失效、样本缺失/损坏、空数据集、异源 CRS 重投影。
|
|
||||||
- 渲染以小基准截图人工核对(对照图 #17/#18/#09)。
|
|
||||||
- clang-tidy + cppcheck 入 CI;Debug 启用 ASan/UBSan。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13. M1 验收标准(图分阶段,K-5/K-10)
|
|
||||||
|
|
||||||
**M1-a(先达成)**
|
|
||||||
1. 启动→登录窗(近 web)→真连 `pop-api` 登录成功。
|
|
||||||
2. 完整工作台 ADS 三区停靠;对象树/数据集来自本地样本。
|
|
||||||
3. ① 渲染剖面散点(图 #17 样)、网格 banded 等值面+等值线+标注(图 #18 样)、异常按 markType 圈定。
|
|
||||||
4. ④ DEM 地形起伏 + 影像(经重投影对齐)。
|
|
||||||
5. 色阶离散 LUT 可调,两视角实时联动;二维俯视相机预设可切。
|
|
||||||
|
|
||||||
**M1-b(在充分输入数据上达成可信体)**
|
|
||||||
6. 由 ≥3 剖面/3D 网格经 IDW 生成**可信** dd_voxel 体绘制,插值域受限;`vtkResliceCursorWidget` 交互切片得 dd_slice。
|
|
||||||
|
|
||||||
**通用**:core 单测通过;clang-tidy 无新增告警;布局/偏好持久化生效;2D/3D 切换零数据重建、坐标对齐正确。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 14. 风险与待决(承接规约 §11)
|
|
||||||
|
|
||||||
| 风险/待决 | 说明 | 处理 |
|
|
||||||
|---|---|---|
|
|
||||||
| D-2 Qt 许可证 | LGPL 动态 vs 商业 | M1 按 LGPL 动态链接;商务并行 |
|
|
||||||
| RSA 公钥来源 + token 生命周期 | 登录加密公钥、是否有 refresh | spike 前向后端确认(§8.3) |
|
|
||||||
| 可信体输入数据 | 2 平行剖面不足以出可信体(K-10) | 需客户提供 ≥3 剖面/3D 网格;M1-b 验收依赖此 |
|
|
||||||
| ADS 端口 + QVTK reparent | vcpkg 端口可用性、浮动黑屏 | spike 门槛验证(§15) |
|
|
||||||
| 全 vcpkg 首编译耗时 | VTK+Qt 编译久 | 二进制缓存 `VCPKG_BINARY_SOURCES` |
|
|
||||||
| 异源 CRS 配准 | 影像 3857 vs 剖面 32649 | GDAL/PROJ 重投影(§5) |
|
|
||||||
| macOS / OpenGL 废弃 | 规约 §3.3 | M1 仅 Windows;保持可移植 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 15. Spike 预研门槛(K-2,进入完整实现计划前必过)
|
|
||||||
|
|
||||||
第一周先跑通三个高风险点,任一不过则调整方案后再展开计划:
|
|
||||||
|
|
||||||
1. **构建/部署 spike**:全 vcpkg(qtbase + vtk[qt] 共用一份 Qt)配置、编译、出 exe、单一链路部署、无双 Qt 冲突。
|
|
||||||
2. **UI 上下文 spike**:ADS(vcpkg 或 FetchContent)+ `QVTKOpenGLStereoWidget`,验证停靠/浮动/重停靠不黑屏、相机预设切换稳定。
|
|
||||||
3. **渲染管线 spike**:用真实样本跑通 `vtkImageData(+warp) → geometry filter → vtkBandedPolyDataContourFilter(GenerateContourEdges) → 标注`,目视对照图 #18;散点 + 离散 LUT 色阶对照图 #17。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 16. v2 修订记录(对应评审)
|
|
||||||
|
|
||||||
- 网格管线改 `vtkImageData(+warp)→geometry filter→banded contour(GenerateContourEdges)`(B-1/B-2 code)。
|
|
||||||
- 坐标系重写:多源 CRS + 各自 LocalFrame + 统一 rebase + 轴向钉死 + Z 基准 + 影像重投影(B-1/B-2 arch、M-1/M-3 code、M-3 arch)。
|
|
||||||
- dd_voxel 维持可信体但列数据依赖、插值域受限、验收分阶段(B-3 code、K-10)。
|
|
||||||
- Repository 改异步契约(分页/取消/流)(M-1 arch)。
|
|
||||||
- `IInterpolator` 返回 core `ScalarVolume`,去 VTK(M-2 arch)。
|
|
||||||
- 交互:模态工具抽象 + 拾取回流 + 切片改 `vtkResliceCursorWidget`(B-3 arch、M-2 code)。
|
|
||||||
- widget 改 `QVTKOpenGLStereoWidget` + VTK 面板不可浮动 + spike(M-4 code)。
|
|
||||||
- 构建改全 vcpkg(已核 vtk[qt]→qtbase 依赖)、删 PCL(M-5 code、m-1)。
|
|
||||||
- 登录 refresh/token 生命周期降为前置确认(M-5 arch)。
|
|
||||||
- 色阶离散 LUT + under/over/NaN + alpha 按来源 + lineType 以配置为准(m-1/m-2/m-4 各)。
|
|
||||||
- controller 拆 Selection/RenderSync/DetailSync(m-5 arch)。
|
|
||||||
- 新增 §15 spike 门槛(K-2)。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*v2 经双专家评审 + 数据核验修订。下一步:spike 预研 → writing-plans。*
|
|
||||||
Loading…
Reference in New Issue