01-research-device-position-data-and-rendering-primitives.md 7.1 KB

调研 —— 点位下设备的位置数据来源与三维呈现原语

Type: research Status: resolved Labels: wayfinder:research Blocked by: None

进度:100%

已关闭。产物: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(每条结论带类名+行号或 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。