geopro/docs/superpowers/specs/2026-06-07-geopro-desktop-m...

29 KiB
Raw Permalink Blame History

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.1MinGW 版,MSVC 下不可链,须补装 MSVC kit;VTK 无 MSVC 预编译、三方案均须源码编;VS18=MSVC 14.51 链官方 Qt(v143)属"新链旧"ABI 安全。
K-9 视图 widget 评估 QVTKOpenGLStereoWidgetQOpenGLWidget 系) 优先于 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基准+轴向、CrsTransformPROJ 封装,多 CRS
│  │  └─ algo/         # IInterpolator 接口 + IdwInterpolator返回 core 的 ScalarVolume绝不含 VTK
│  ├─ data/        # 数据访问层(异步契约)
│  │  ├─ repo/         # IProjectRepository, IDatasetRepositoryQFuture/回调 + 取消 + 分页)
│  │  ├─ local/        # LocalSampleRepositoryQtConcurrent 线程池跑解析)+ 各格式解析器
│  │  ├─ api/          # ApiRepositoryM1 骨架,签名对齐)
│  │  └─ dto/          # 后端 JSON DTO + → model 映射
│  ├─ net/         # ApiClientQtNetwork/ AuthService验证码+RSA+login2/ CredentialQtKeychain
│  ├─ render/      # VTK 渲染层(独占 vtkRenderWindow统一管理所有 actor
│  │  ├─ Scene         # 场景图、世界坐标空间、可见性;持有 RenderWindow
│  │  ├─ actors/       # ScatterActor, GridContourActor, VoxelVolumeActor, AnomalyActor, TerrainActor
│  │  ├─ color/        # ColorLutBuildercolorBar → vtkLookupTable 离散阶梯), ScalarBar
│  │  ├─ camera/       # CameraPresetTop2D / Free3D
│  │  ├─ interact/     # InteractionManager + InteractionToolMeasureTool/SliceTool/PickSelectTool
│  │  └─ ground/       # IGroundLayer + DemImageGroundLayerM1TileGroundLayerM1.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 / MainWindowADS 布局、主题)/ AppContextDI 根)
├─ resources/      # QSS 主题、QtAwesome、登录页素材
├─ tests/          # gtestcore/data/algo+ Qt Testview/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 / MainWindowwireUp()
  • 所有落盘路径经 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维护当前色阶与坐标系。
  • 单一 QVTKOpenGLStereoWidgetK-9QOpenGLWidget 系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 抬升) vtkImageDataorigin+spacingz 抬升用 vtkWarpScalar)→ vtkDataSetSurfaceFilter/vtkGeometryFiltervtkBandedPolyDataContourFilter(开 GenerateContourEdgesOn() 一次产 banded 面+等值线,共用阈值)→ vtkLabeledDataMapper 标注 图 #18不可让 structured/image 直连 banded filterB-1
dd_voxel 体绘制 多剖面散点 → IInterpolatorcore::ScalarVolume ScalarVolumerender 转)vtkImageDatavtkGPUVolumeRayCastMapper + 颜色/不透明度传递函数 图 #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 0100 → 归一 [0,1]z 取值同剖面 Z 基准§5
DEM 地形 + 影像 dem.tif + image.tif + tfw可能异源 CRS GDAL 读 → PROJ/GDAL 重投影到项目世界 CRSvtkImageDatavtkWarpScalar 抬升 + 影像纹理 图 #05影像实测为 EPSG:3857须重投影§5、M-1
色阶 colorBar[值, 颜色] 阶梯 vtkLookupTable(离散阶梯,取下界)+ vtkScalarBarActor 见 §7

4.4 模态交互与拾取回流M-2、B-3

  • InteractionManager 管理模态工具激活互斥与 VTK observer 优先级:MeasureToolSliceToolPickSelectTool。工具激活/退出负责其临时 actor 生命周期。
  • 3D Widget切片与自定义 InteractorStyle 共享同一 interactor须显式管理 SetEnabled() 与事件优先级,避免抢事件。
  • 拾取回流通道render 拾取到对象 → 经 view 中转发出出站信号 → DetailSyncController → 列表/详情定位。此箭头在分层图中显式存在§3

4.5 GroundLayer 可插拔

IGroundLayer { build(Scene&); setVisible(bool); }M1 DemImageGroundLayerM1.5 TileGroundLayer。若 VTK 贴瓦片体验差D-5可仅替换二维为 MapLibre 而不动 data/render 的 actor 体系。


5. 坐标系设计K-7评审最大短板已重写

数据现实(已核验真实样本):

  • 剖面/网格/异常:带 GIS 投影 projectX≈516868=EastingprojectY≈2494259=Northing;另带局部米 xlist/ylist(各数据集自原点起算)。
    • CRS 已实证确定(2026-06-08)= EPSG:4547「CGCS2000 / 3-degree Gauss-Kruger CM 114E」(+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80)。方法:同测线既有 lat/lon(4326)又有 projectX/Y,pyproj 转换互校 dX=0.20m/dY=0.30m、反向 ~0.3m;北京54(Krassovsky)差 44m 排除。旧"32649 解出 111°E"系因 32649 中央经线=111°E,改 CM=114°E 即吻合。DEM/影像与 dd_voxel 配准不再被 CRS 阻塞(散点 projX/Y 可经 4547→4326→GeoLocalFrame)。datum WGS84 vs CGCS2000 现差<1m,M1 无影响。
    • 对 M1 core 无影响:LocalFrame 用相对米(减原点,CRS 无关),网格自带 lat/lon;CrsTransform 已实现并单测验证 PROJ 机制本身。
  • 影像 image.tfw:原点 (12708343, 2577685) = EPSG:3857Web 墨卡托),与剖面不同投影
  • 网格另带 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 前,CrsTransformPROJ源局部米 →(源原点)→ 源 CRS GIS → 项目世界 CRS →(减项目原点)→ 项目世界米。多数据集因此对齐到同一世界系(解决 B-1 多原点冲突)。
  4. 轴向约定钉死world.x = Easting = projectXworld.y = Northing = projectYworld.z 向上为正、单位米。解析器不信 eastCoord/northCoord 字段名(实测与值颠倒),按 projectX/Y 取值单测对照B-2
  5. 垂向Z基准统一M-3LocalFrame 定义高程基准面、向上为正、单位米、可选垂向夸张 z-scale。网格 z剖面深度/构造面、DEM elevation(地表高程)、体素 Z 在进入 Scene 前统一归算到该基准,避免地形与剖面垂直穿插。
  6. 影像/DEM 重投影:装载时经 GDAL/PROJ 重投影到项目世界 CRS 再贴地,不能简单减原点M-1
  7. float 精度:世界=局部米(小数值)从根本规避 VTK float 大坐标抖动。

6. 数据层RepositoryK-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 时取消上一个未完成请求;列表类带游标/分页;大数据流式 + 进度 + 取消。
  • M1LocalSampleRepository 读样本目录解析器映射成领域模型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 恒定)→ vtkImageDatav/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:3857GDAL 读 + PROJ 重投影到世界 CRS
test_001_A*.head/.data/.cor GPR 原始462×4100×int16多通道分文件 属 M1.5 雷达LocalSampleRepository 不解析

7. 色阶ColorScale

colorBar[值, 颜色] 阶梯数组(颜色支持 #RRGGBBrgba(r,g,b,a))。映射:值落相邻两 stop 间取下界 stop 颜色(阶梯,非线性插值)。

  • 实现统一为离散 vtkLookupTable贴合「取下界阶梯」语义2D/3D 共用同一可信源),显式定义 under低于首 stop/ over高于末 stop/ NaN 颜色。
  • alpha 量纲按色阶来源文件类型判定(网格色阶 0255、LVL 色阶 01解析器入口带 source 标记,不按数值范围猜m-2
  • lineConfig:等值线显隐/颜色/lineType(以配置为准)/zmin/zmaxlabelConfig:标注显隐/颜色;equalAreaLayerCount/logLinesCount
  • 视图层 ColorScaleEditorM1 读取与基本调整;命名保存对接后续色阶模板 API。

8. 登录与网络层M1 必做,真实流程已抓取)

8.1 已确认的生产实现细节

  • API 基址 http://tenant.geomative.cn/pop-apiopenresty 反代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。
  • CredentialQtKeychaintoken 存平台密钥库,严禁明文(规约 §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

  • 停靠框架ADSLGPL规约 §6.2)。VTK 面板默认不可浮动(或浮动时占位、停靠回重建),缓解 reparent 上下文问题spike 验证M-4
  • 三区布局(还原原型):左(对象树 + 数据集列表)/ 中2D-3D 视图 + 数据详情)/ 右(异常-对象属性 + 属性)。
  • 主题QSS + QDarkStyleSheet 打底 + QtAwesome 图标。
  • 布局持久化ADS 透视图 + 窗口几何存 QSettingsWindows 强制 INI规约 §7.2)。
  • 联动controller 按闭环拆分§3勾选 GS/TM→按 dd 类型筛选 ds→勾选 ds→渲染列表↔详情↔视图定位三向色阶调整两视角实时更新。

10. 算法展示期三维插值K-6、K-10

  • core/algo/IInterpolatorcore::ScalarVolume interpolate(const PointSet& pts, const GridSpec& spec)——返回 core 中立类型dims/spacing/origin/double 数组),绝不含 VTKM-2。render 层 VoxelVolumeActorScalarVolumevtkImageData
  • M1 实现 IdwInterpolator反距离加权Eigen 辅助2597 点规模不需要 PCL/KD-treem-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 预编译 QtD:\Qt\6.11.1\msvc2022_64,经 CMAKE_PREFIX_PATH)。凡依赖 Qt 的组件都不走 vcpkgvcpkg 任何 Qt 依赖端口都会再编一份 qtbase = 双份冲突,已核 ports/vtk/vcpkg.jsonvtk[qt]qtbase+qtdeclarative)。
  • VTK:无 MSVC 预编译,必须源码编。预先用官方 Qt 把 VTK 9.3 配置/编译/installexternal/vtk-install-DVTK_GROUP_ENABLE_Qt=YES -DQt6_DIR=...app 经 VTK_DIR find_package(VTK)。一次编好、隔离于 app 构建。
  • ADS / QtKeychain:经 FetchContent 对接同一份官方 Qt体量小源码编可接受不走 vcpkg
  • 非 Qt 依赖经 vcpkgGDAL/PROJ/OpenSSL/Eigen/spdlog/fmt/nlohmann-json/gtest这些不拉 Qt
  • M1 依赖矩阵
依赖 来源 用途 许可证
Qt 6.11.1msvc2022_64预编译 官方安装器(MSVC kit) UI/网络/SQL/并发 LGPLv3动态⚠️ 商务 D-2
VTK 9.3[qt,opengl] + gdal/proj 可选) 源码编→install 前缀 三维渲染 + QVTK widget BSD
ADSQt-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
  • PCLM1 移除(点规模不需要)。
  • 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/algogtest坐标 rebase/轴向、Z 基准归算、colorBar LUT 映射、v[j][i] 灌点序、样本解析、IDW 正确性)。
  • view/controllerQt Test联动、模态工具互斥
  • 失败路径必测:登录失败/验证码错/token 失效、样本缺失/损坏、空数据集、异源 CRS 重投影。
  • 渲染以小基准截图人工核对(对照图 #17/#18/#09
  • clang-tidy + cppcheck 入 CIDebug 启用 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:全 vcpkgqtbase + vtk[qt] 共用一份 Qt配置、编译、出 exe、单一链路部署、无双 Qt 冲突。
  2. UI 上下文 spikeADSvcpkg 或 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,去 VTKM-2 arch
  • 交互:模态工具抽象 + 拾取回流 + 切片改 vtkResliceCursorWidgetB-3 arch、M-2 code
  • widget 改 QVTKOpenGLStereoWidget + VTK 面板不可浮动 + spikeM-4 code
  • 构建改全 vcpkg已核 vtk[qt]→qtbase 依赖)、删 PCLM-5 code、m-1
  • 登录 refresh/token 生命周期降为前置确认M-5 arch
  • 色阶离散 LUT + under/over/NaN + alpha 按来源 + lineType 以配置为准m-1/m-2/m-4 各)。
  • controller 拆 Selection/RenderSync/DetailSyncm-5 arch
  • 新增 §15 spike 门槛K-2

v2 经双专家评审 + 数据核验修订。下一步spike 预研 → writing-plans。