6.1 KiB
6.1 KiB
P5 二维数据集栏渲染 + 底图 Implementation Plan
接续:三栏结构重构(已完成) + 真实 ERT 帘面(已完成)。本计划做「二维数据集」栏的真实渲染 + 天地图底图。 GUI 渲染正确性须用户实测(Claude 不能 GUI 测;见构建铁律)。
Goal: 「二维数据集」栏勾选 → 在 VTK 视图的 2D 俯视面渲染:轨迹线(dd_trajectory_data)、网格面(dd_grid),并叠加天地图底图(可切换 天地图/Google/隐藏)。
Architecture: 复用现有 VtkSceneController(已有 ViewMode::Map2D + addSurveyLine) + GeoLocalFrame(已重锚真实数据) + 天地图 token/WMTS(已存在于 trajectory_map.html)。新增:2D 数据异步加载(轨迹/网格) + 2D actor + 底图瓦片层(VTK)。
已确认事实(真实 API/代码):
- 天地图 token:
TK=aca91d8c9f59a4f779f39061b8a07737,WMTS XYZ:http://t{0-7}.tianditu.gov.cn/{layer}_w/wmts?...&tileMatrixSet=w&TileMatrix={z}&TileRow={y}&TileCol={x}&style=default&format=tiles&tk=TK(图层vec街道/img卫星 +cva/cia注记,EPSG:3857,原生 z18)。见src/app/resources/map/trajectory_map.html。 - 轨迹数据:
GET /business/dd/ert/trajectory/line?dsObjectId={id}&frontCrsCode=EPSG:4326→data.electrodelList[],每项{electrodeNo, electrodeCoordinate}(经纬度)。 - 网格数据:
dd/ert/grid/rows/{id}(GET) 实测 404 → 本计划 Task 0 先确认正确端点(疑似 query 参数或 POST;参考src/app/panels/chart/GridStrategy.hpp+ApiDatasetRepository的gridRowsBatch/makeGridRows)。 dimensionOf:dd_trajectory_data→Dim2D(已);dd_grid→当前 Other(需加 Dim2D)。- col2D(
Column2DDataset) 信号basemapChanged/view2DModeChanged/customZChanged/checkedDatasetsChanged在 main.cpp 当前未接线(T7 留待本期)。
Task 0:确认 dd_grid 端点 ✅(已做,结论纠正本计划)
dd_grid= 「白化数据」分页坐标点表:GET /business/dd/ert/grid/rows?dsObjectId=&pageNo=&pageSize=→data={rowList[{x,y,id}], gridHeaderDisplay[x,y], total}(见ApiDatasetRepository::gridRowsBatch+GridStrategy.hpp)。- 结论:dd_grid 是表格数据、不是 2D 地图面,不作渲染层 → 维持
Other(仅在「数据详情」看表)。 - 2D 地图可渲染类型只剩
dd_trajectory_data(轨迹线)+ 底图。Task 1 取消(不把 dd_grid 归 2D);Task 2/3/4 只做轨迹。
Task 1:(取消)dd_grid 非地图渲染类型,维持 Other。
Task 2:2D 数据异步加载(轨迹 + 网格)
在 Api3dRepository(真实) + LocalSample3dRepository(样本 stub) 加异步方法(照 loadSection 范式):
loadTrajectory(dsId, onOk(vector<LatLon>), onErr):真实走trajectory/line,解析electrodelList[].electrodeCoordinate→ 经纬序列。load2dGrid(dsId, onOk(SectionData/Grid), onErr):按 Task 0 的端点解析网格面。I3dSceneRepository加这两个虚方法(接口扩展,LocalSample stub 返回样本/空)。- 验证:编译绿;FakeSceneRepo 加 override。
Task 3:2D actor(render 层)
- 轨迹线:新增
render/actors/TrajectoryActor(或复用MapLineActor):经GeoLocalFrame.toLocal把经纬序列 → 局部米折线,摆在 Z=0 平面(或 2D视图 Z)。橙色(对齐轨迹详情#ff8c00)。 - 网格面:复用
MapLineActor(俯视红线) 或GridContourActor(着色面,需 frame)。 - 单测:纯几何(经纬→局部米折线点数/坐标)抽出可测。
Task 4:VtkSceneView + Controller 接 2D 渲染
I3dSceneView/VtkSceneView加addTrajectory(...)、add2dGrid(...)。VtkSceneController:Map2D 分支里,对勾选的 2D ds 按维度调loadTrajectory/load2dGrid→ addTrajectory/add2dGrid(异步 + QPointer/gen 守护,照帘面范式)。setViewMode:col2D 的「2D视图位置」(关闭/Z=0/顶部/底部/自定义Z) 控制 2D 面的 Z(自定义Z=世界绝对米,见三栏 spec)。
Task 5:main.cpp 接 col2D 信号
drawer->col2D()的checkedDatasetsChanged→ 渲染 2D ds(同 col3D 模式,按维度过滤后的真实 dsId)。view2DModeChanged/customZChanged→ setViewMode + 2D 面 Z。basemapChanged→ Task 6 底图开关。- 验证:编译绿 + 用户实测(勾选轨迹 ds → 俯视面出橙色测线;网格 ds → 面)。
Task 6:天地图底图瓦片层(最复杂,可独立验证)
新增 render/ground/TileGroundLayer:
- 输入:当前数据地理范围(从已渲染 actor 的 lat/lon 包围盒,或 GeoLocalFrame 原点 + 视域)→ 选合适 zoom(数据跨度→z)。
- 瓦片数学:EPSG:3857 经纬→TileRow/Col(标准 Web Mercator 瓦片公式),取覆盖范围的瓦片集。
- 异步拉取:
QNetworkAccessManagerGET 天地图 WMTS URL(token/子域见上)→ QImage → vtkTexture。 - 摆放:每块瓦片的地理 bbox → 四角经纬
GeoLocalFrame.toLocal→ 局部米 →vtkPlaneSource+ texture,置于 Z=底图平面。 - 切换:
basemapChanged(0天地图/1Google/2隐藏);Google 可后置(国内可用性),先天地图 + 隐藏。 - LOD/随相机更新:本期可固定一档 zoom(覆盖数据范围),相机驱动 LOD 后置。
- 配准是精度敏感点:3857 瓦片范围反算到 GeoLocalFrame 必须与帘面/轨迹同一 frame,否则底图与数据错位。须用户实测对齐(Claude 不能 GUI 测)。
- 单测:瓦片数学(经纬→z/x/y、瓦片 bbox→经纬)纯函数抽出可测。
④ 三维分析栏交互(本期受限,附记)
- 树/右键菜单已是 UI。
detailRequested→detailCtrl.openDataset已接(T7)。显示/隐藏可接 actor 可见性。 - 真切片需 3D 体模型(dd_voxel/dd_Structual3D),后端缺 → 受限,待后端。
- 切片 CRUD/色阶/异常 = P4,接口已留位(②a),待后端 + 1.0 参考。
风险/验证
- 全部渲染须用户
build.bat rebuild实测(Claude 不能 GUI 测)。 - 底图配准、2D 面 Z、轨迹/网格定位都是精度敏感点 → 小步验证。
- Task 0(grid 端点) 不明会卡 Task 2 的网格分支 → 先确认。