# 调研 —— 点位下设备的位置数据来源与三维呈现原语 Type: research Status: resolved Labels: wayfinder:research Blocked by: None ## 进度:100% 已关闭。产物:[`research/device-position-data-and-rendering-primitives.md`](../research/device-position-data-and-rendering-primitives.md)。只做只读调研;后端与前端源码未改任何文件、未跑 build/dev。 ## Question 需求②要求「点击监测点定位后,展示该监测点下所有设备点位的模型及坐标图标」。本票只查**事实**(能做什么、数据在哪),不给建议、不做设计。 1. **数据来源**:现有一张图相关端点里,哪一个能**一次**给出「某监测点下所有设备的经纬度 + 坐标校验 + 状态」?已知(本图 map.md 已复核):`/monitoring-points/{code}` 的 `devices[]`(后端 `CockpitMonitoringPointDeviceCard`)**没有经纬度**;`/monitoring/distribution` 只给「监测点 marker + 未关联设备 marker」;`/equipments/{deviceCode}/archive` 带 `longitude/latitude` 但要逐台取。请读后端源码(`E:\pipe-ner-server`,重点 `cockpit/point/`、`cockpit/monitoring/`、`cockpit/equipment/`、`cockpit/map/` 与 `docs/cockpit/README.md`)给出确切结论:**能 / 不能**;若不能,缺哪个字段、挂在哪个响应类上、要动的类名与端点。 2. **`deviceCodes` 的语义**:`CockpitMonitoringPointSummary.deviceCodes`(BT-1 / Gogs #59)在哪些端点回传、是否含离线设备、是否受分页或状态过滤影响、空值语义。 3. **设备与点位的空间关系**:设备的经纬度与所属监测点的经纬度是否同一个值(点位是设备的空间承载对象)?后端有没有「同井/同杆/相对点位」这类相对位置或安装信息?给出源码证据(类名 + 字段名)。 4. **呈现原语**:Cesium 1.145.0 里呈现「设备点位 + 坐标图标 + 文字标签」,`Entity`(billboard + label)、`BillboardCollection`、`PointPrimitiveCollection` 三者各自的:单点开销、批量更新开销、能否**单独拾取**(不与监测点标记抢)、能否挂 `heightReference` 贴地。给出版本内的结论与出处(随包 d.ts / 官方文档 / 社区实测)。 5. **设备级资产清单**:仓库内(`public/`、`public/plugins/`、`src/plugins/`、`tools/`、`src/modules/cockpit/styles/`)现有可用的设备级图标/模型资产清单;有没有现成的 glTF/GLB 设备模型(区别于票 34 的城市体块 3D Tiles);`domain/icons.js` 与 `domain/pointStatus.js` 的 `SHAPES` 现有哪些形状。 产物写到 `research/device-position-data-and-rendering-primitives.md`,每条结论都要带来源(文件路径 + 行号,或 URL)。 ## Answer **结论:不能一次拿到(缺口在数据模型,不在响应包装);`deviceCodes` 已交付但前端零消费;设备与点位各存一份独立坐标且后端无相对位置信息;三个 Cesium 原语都能单独拾取、只有 `PointPrimitive` 不能贴地;仓库无设备级模型资产。** 产物:[`research/device-position-data-and-rendering-primitives.md`](../research/device-position-data-and-rendering-primitives.md)(每条结论带类名+行号或 URL)。 1. **数据来源:不能。** 20 个 `/api/cockpit/v1/` 端点无一能在「某监测点下所有设备」这一粒度上给全经纬度 + 校验 + 状态。`/monitoring-points/{code}` 的 `devices[]`(`CockpitMonitoringPointDeviceCard`,11 字段)无坐标,且缺在**上游模型** `CockpitMonitoringPointDeviceSnapshot`——两条 `SourceMonitoringPoint.devices`(`CockpitMapSnapshot.java:75`、`CockpitMonitoringDistributionSnapshot.java:107`)都用它;后两者只给**未关联**设备的坐标;`/monitoring/situation` 的 `abnormalEquipment[]` 有设备坐标但只含异常设备、且无 `monitoringPointCode`;带完整坐标的只有 `/equipments/{deviceCode}/archive`,逐台 = N+1。**缺的字段**:设备级 `longitude/latitude/coordinateValidation`;**要动的类**:`CockpitMonitoringPointDeviceSnapshot` → `CockpitMonitoringPointDeviceCard` → `CockpitMonitoringPointStatusResolver.cards()`(若要覆盖 map/distribution 还要补两处 `new CockpitMonitoringPointDeviceSnapshot(...)`);**端点不必新增**。Gogs #59 交付的是 `deviceCodes`(编码清单)而非坐标,票 09 设想的「#59 已带坐标而前端漏读」可以排除。 2. **`deviceCodes`**:只在 `map-snapshot` 的 `monitoringPoints[].deviceCodes` 回传(`distribution` 的 `MonitoringPointMarker` 无此字段);构造链无任何状态过滤 → **含离线设备**;在生成摘要时算完再分页 → **不受分页影响**;`source.getDevices()==null` 时退化为 `Collections.emptyList()` → 空值是 `[]` 而非 `null`;`distinct()` 保持源顺序、**未排序**。受 `industry/region/deviceType` 影响的方式是「点位被筛掉则其 deviceCodes 一并消失」。前端全 `src/` 对它 **0 引用**。 3. **空间关系**:`monitor_point` 与 `equipment_base` 各存**独立**的 `longitude/latitude`,关联表 `equipment_point_rel` 只有 `equipment_id/point_id`(无偏移/高度/朝向/井杆列);全后端 grep 同井/同杆/杆塔/相对位置/安装高度/朝向 → **0 命中** → **没有相对位置信息**。后端只在类注释里声明「已关联设备由它的监测点描述」,**不保证也不校验两点相等**;而走已关联路径时响应里根本取不到设备坐标,所以「是否同一个值」在当前契约下**不可观测**。前端另受 `CONTEXT.md` 的 `Avoid_: 人工坐标偏移` 约束。 4. **呈现原语**:三者 GPU 侧都是批渲染(`BillboardCollection` 整集合一次 instanced draw;`PointPrimitiveCollection` 一顶点一点、一次 draw),draw call 不随点数线性增长;Entity 的额外代价是 JS 对象 + 每帧 Visualizer update + 标签字形生成(`LabelCollection` 自己建在两个 `BillboardCollection` 上)。三者都能逐元素拾取(各带 `id`,pick color 逐实例);`scene.pick` 只回**最上层一个**(默认 3×3 拾取矩形),重叠时必须 `drillPick`。**只有 `PointPrimitive` 不支持 `heightReference`**——Entity 的 `point` 一旦贴地,引擎内部用无图 billboard 顶替它(`PointVisualizer.js:119-128`)。仓库现状:Entity + billboard、`CLAMP_TO_GROUND` + `disableDepthTestDistance: Infinity`、`scene.pick` → `picked.id`(Entity) → `entity.properties.pointCode` 判据;未用任何 Collection 原语、未用 `drillPick`。 5. **资产**:**无设备级 glTF/GLB**(45 个 3D 文件全是建筑/车辆/船只/卫星/人体/道具/倾斜摄影瓦片;唯一设备形状的 glTF 只在 `src/plugins/zoneFreeScene/**` 里以 `oss.icegl.cn` 远程 URL 存在)。`FE/` 下 0 个图片文件,图标是内联 SVG(**不是** canvas 光栅化);`SHAPES` 8 个键全是几何原语(`triangle/diamond/square/circle/ring/hollowSquare/hollowDiamond/cross`),**无任何设备形状**;语义色只在 `tokens.css:34-38`(`--lv1..--lv4/--neutral`)。票 34 的城市体块是另一条线,产物在 repo 外的 `D:/GIS/GIS/cityMassing`。