31 KiB
SGS SDK 与当前 H5 三维渲染对照研究报告
版本:2026-07-18
范围:frontend-miniapp当前本地 ThreeMap 渲染器,与smart-navigation-system/sgs-frontend-map/sdk-engine的 SDK Engine。
结论边界:本报告是参数、空间契约与验证方案研究,不是将当前 H5 迁移为 SDK iframe 的建议;不将外观首页和 SDK 单楼层 Demo 误判为应像素级一致的场景。
1. 执行摘要
当前 H5 应继续采用“本地 ThreeMap 渲染 + SGS REST 数据”的架构。src/config/dataSource.ts:91-94 中的 SDK 脚本和 Engine URL 只是配置能力;实际 SDK 数据路径是 sgsSdkApiProvider 的 uni.request,经 GuideModelRepository 转为本地模型资源供 Three.js 加载。既有的本地渲染和 SDK Engine 在背景、相机投影、DPR、渲染器、色调映射、阴影与三灯参数上已基本对齐,因此不建议进行无目标的颜色/灯光再调参。
当前最高优先级不是视觉参数,而是 Bundle 的模型变换契约缺失:SDK Engine 会尝试读取变换但静默回退单位矩阵,H5 类型、领域模型和仓储也只传递 URL。实时 Bundle 已确认不含变换字段;但尚未证明生产数据库中存在非单位变换。因此 P0 仅应完成真实激活模型的只读数据核验,不能先行扩展运行时代码。
SDK 与 H5 的相机、POI 密度与标签实现有刻意的产品策略差异。SDK 单楼层 AutoFit 与 H5 外观/楼层状态机不是相同视图;后续视觉验收必须固定同一楼层、同一模型、同一视口、同一 DPR 和同一 view mode。POI LOD 可做受控实验,但应保留 H5 的 WebGL 命中目标、DOM 标签和碰撞规避。
2. 证据口径
| 标签 | 含义 | 本报告用法 |
|---|---|---|
| 源码事实 | 可定位到当前两仓源码的声明或执行路径 | 可以用于架构、参数和契约判断 |
| 实时接口事实 | 2026-07-18 对已部署接口的实际响应 | 只说明当时、该地图/楼层的数据 |
| 浏览器观察 | 指定服务、URL、视口下的实际运行结果 | 不能外推为所有发布物或设备 |
| 尚未证明 | 当前证据不足以作出肯定结论 | 列为核验或回归项,不写作已修复 |
3. 两项目架构边界与数据链
| 维度 | 当前 H5 (frontend-miniapp) |
SDK Engine / Web Demo | 判断 |
|---|---|---|---|
| 数据取得 | sgsSdkApiProvider 以 uni.request 请求 /app-api/gis/sdk/*(src/data/providers/sgsSdkApiProvider.ts:381,458,489) |
Engine 读取 SDK API / Bundle | 数据可比,渲染运行时不同 |
| 模型资源 | GuideModelRepository 取 modelUrl / fallbackModelUrl,生成本地 GuideModelFloorAsset(src/repositories/GuideModelRepository.ts:364-378) |
Engine 直接消费 Bundle model | 都依赖 Bundle,但不可假设变换已传递 |
| 渲染器 | 本地 Three.js ThreeMap.vue |
SDK iframe 内 Engine | 不建议因本次研究替换 H5 渲染器 |
| SDK URL 配置 | 存在 sgsSdkScriptUrl、sgsMapEngineUrl 和 timeout(src/config/dataSource.ts:91-94) |
发布 Demo 用相对 ../engine/ |
配置存在不等于当前 H5 走 iframe |
| 页面能力 | H5 有自己的楼层基线、状态机、DOM 标签和 WebGL 命中目标 | 单楼层 AutoFit、HTML POI 层、可选服务端 LOD | 应比较契约/行为,不要求视觉像素等价 |
源码事实。 当前 H5 的领域类型 GuideModelFloorAsset 只含楼层、标签、顺序和 URL 类字段(src/domain/guideModel.ts:24-31);这与 REST 提供者 SgsModelInfoPayload 的字段集合一致(src/data/providers/sgsSdkApiProvider.ts:194-202)。本报告不建议跨仓抽取共享运行时包:两端发布、部署和生命周期边界不同,优先使用契约快照防漂移。
4. 三维基础渲染参数对照
| 项 | SDK Engine | 当前 H5 | 结论 |
|---|---|---|---|
| 场景背景 | #ECEFF1 |
0xeceff1,ThreeMap.vue:106-108,1918-1920 |
一致 |
| PerspectiveCamera | FOV 42、near 0.1、far 20000,Viewport3D.tsx:509-558 |
FOV 42、near 0.1、far 20000,ThreeMap.vue:108-112,1923-1928 |
一致 |
| Renderer | DPR cap 1.5、high-performance、antialias、alpha=false | 同值,ThreeMap.vue:114-121,1931-1937 |
一致 |
| 色调/曝光/阴影 | NoToneMapping、1.0、关闭阴影 | 同值,ThreeMap.vue:119-121,1939-1941 |
一致 |
| 半球灯 | #fff/#b0bec5、1.7 |
同值,ThreeMap.vue:123-127,1968-1973 |
一致 |
| 主光 | [80,120,80]、2.2 |
同值,ThreeMap.vue:129-132,1975-1980 |
一致 |
| 补光 | [-60,70,-50]、0.55 |
同值,ThreeMap.vue:134-137,1982-1987 |
一致 |
源码事实。 SDK 参数来源为 sgs-frontend-map/sdk-engine/src/components/Viewport3D.tsx:509-558,H5 参数集中在 src/components/map/ThreeMap.vue:106-137,1918-1987。因此基础色彩、灯光和 renderer 默认值不是当前主要根因;除非有受控的同场景截图证据,否则不应启动另一轮全局视觉调参。
5. 相机与视图策略
SDK AutoFit 以 __model_root__ 的 Box3、模型尺寸和预设计算相机(sdk-engine/src/components/AutoFitCamera.tsx:164-321),常规距离约为 fitDim * 1.2,高度/目标依赖 preset。预设 sdk-kiosk-landscape、sdk-mobile-portrait、default 定义在 sdk-engine/src/config/viewport-presets.ts:67-160;竖屏会旋转约 90 度并设置 minFitDimension=260。
H5 则保存自己的参考外观相机和楼层基线:楼层基线从模型盒、屏幕偏移和相机方向计算(ThreeMap.vue:3505-3554),setCameraView / fitCameraToObject 根据 overview 或 floor 使用不同方向、距离与偏移(ThreeMap.vue:3833-3921),楼层恢复还会回放快照(ThreeMap.vue:4245-4250)。
源码事实与验收结论。 H5 外观首页和 SDK 单楼层 Demo 是不同产品视图,不能要求像素级相同。视觉对照的前置条件是:相同 floorId、模型 URL/版本、视口尺寸、DPR、view mode、相机 preset/基线以及无 POI 焦点状态。此前宽屏初始化后缩窄的空白,固定 430x720 刷新未复现,故为“尚未证明的生产缺陷”;保留“相机快照污染”回归测试即可。
6. 模型变换契约
| 层级 | 现状 | 证据类型 | 风险 |
|---|---|---|---|
| SDK Engine | Bundle model 被 any 读取,尝试 translationX/Y/Z、rotationX/Y/Z、scaleX/Y/Z;缺失回退 [0,0,0] / [0,0,0] / [1,1,1] |
源码事实:H5SdkEngine.tsx:5078-5099,5224-5239 |
非单位数据会被静默忽略 |
| SDK Bundle VO | 只发布 URL、压缩/版本、节点数和大小 | 源码事实:SdkModelInfoVO.java:15-36 |
外部契约未承载矩阵 |
| H5 Provider / Domain / Repo | 同样只承载 URL 等字段 | 源码事实:sgsSdkApiProvider.ts:194-202、guideModel.ts:24-31、GuideModelRepository.ts:364-378 |
H5 也使用单位变换 |
| 另一后端模型接口/DO | 存在变换字段 | 源码事实:AppGisModelController.java:70-83、Map3dModelDO.java:57-87 |
数据能力与 SDK Bundle 契约脱节 |
| L2 实时 Bundle | floorId=2065808921578303490,code=0、30 POI;model keys 仅 URL/压缩/版本/统计字段,所有变换字段缺失 |
实时接口事实(2026-07-18) | 只证明该 Bundle 未发布变换 |
根因判断。 如果数据库中存在非单位模型变换,当前 SDK 与 H5 都会静默按单位矩阵渲染,可能导致模型、POI、路线和点击坐标失配。尚未证明: 当前没有证据证明任一激活模型的数据库变换为非单位值;不可把该风险表述为已发生故障。
P0 核验。 在不改运行代码的前提下,通过只读 SQL 或管理接口枚举所有激活模型的平移、旋转、缩放;记录 modelId、floorId、版本和原始字段。只有发现非单位值,才进入 P2。
7. POI、标签与 LOD 策略
SDK 的 PoiMarkerLayer 是 HTML 标签,结合类型配置、遮挡检测与绝对相机距离阈值;非 kiosk 为 far=400、mid=150(sdk-engine/src/components/layers/PoiMarkerLayer.tsx:771-855,1080-1086)。服务端 LOD API 能力存在(sdk-engine/src/api/sdk-api-loader.ts:524-533),但 Engine real-preview 默认关闭,仅 URL 带 enablePoiLabelLod=1/true 才启用(H5SdkEngine.tsx:1187-1225);当前 Web Demo 未传该参数。
实时接口 /app-api/gis/sdk/maps/1/poi-label-lod 返回 9 层;总体为 far=22、mid=181、near=183、sourcePoiCount=183、clusterCount=24、singleCount=362,L2 为 far=3 / mid=26 / near=26(实时接口事实,2026-07-18)。这证明服务端可供实验,不证明当前 Engine Demo 已消费它。
H5 使用模型尺度归一化:点位阈值 0.32/0.20、标签阈值 0.42/0.26(ThreeMap.vue:1260-1328);点位数量 tight=5、balanced=9、full=无限,屏幕间距 116/78/0(ThreeMap.vue:1300-1309,1425-1551)。标记为 WebGL Sprite,另设命中 Sprite(ThreeMap.vue:4805-4828,4880-4897);DOM 标签带碰撞规避与 ResizeObserver(ThreeMap.vue:4550-4591)。
建议。 仅以 feature flag 引入服务端 LOD 作为候选数据源;保留 DOM 标签、碰撞规避及 WebGL 点击命中目标,失败时回退本地策略。不要直接用 SDK HTML POI 替换移动 H5 实现。
8. Web Demo 与运行证据
| 观察 | 证据类型 | 判断与后续动作 |
|---|---|---|
发布 Demo app.js:482-530 从 scene/floorCode 读取参数、固定相对 ../engine/,等待 sdk.whenReady() |
源码事实 | 宿主和 Engine 发布目录是关键依赖 |
本地 5555 Demo 持续“连接中”,30 秒 whenReady 超时;iframe 指向 5555/engine;直开 5556/engine 成功 |
浏览器观察 | 优先查静态托管目录/发布版本不一致;不能归咎渲染器 |
直开 SDK Engine:1280x720 Canvas 非空;L2 Bundle 约117ms、30 POI、Draco 约0.24MB、160节点;AutoFit 约262x133m、distance 314m、height 220m;发出 ENGINE_READY |
浏览器观察 | Engine 在该直接入口可运行 |
曾出现一次 webglcontextlost,最终画面非空;Viewport3D.tsx:531-539 有恢复监听 |
浏览器观察 + 源码事实 | 仍需 context lost/restored 回归,不得视为已完全排除 |
当前 H5 外观页正常;430x720 刷新后诊断 API 切到 1F:activeView=floor、单位变换误差0、7个 WebGL 点、2个 DOM 标签都在 Canvas 内 |
浏览器观察 | 证明此固定条件可用,非全部设备证明 |
9. 风险分级与分阶段实施方案
| 优先级 | 风险 / 目标 | 实施范围 | 退出条件 |
|---|---|---|---|
| P0 | Bundle 模型变换是否漏传 | 报告 + 所有激活模型的只读 SQL/管理接口核验;不改运行代码 | 有带版本的单位/非单位清单 |
| P1 | 两仓参数与 Bundle schema 漂移 | 增加参数与 schema 契约快照/测试;不抽取跨仓共享 runtime 包 | 两仓变化能在 CI/本地契约检查中定位 |
| P2 | 仅在 P0 发现非单位变换时,补齐变换契约 | SdkModelInfoVO、service mapper、SDK TS 类型、H5 provider/domain/repo/render matrix |
模型、POI、路线、点击坐标共用矩阵 |
| P3 | 验证服务端 POI LOD 是否优于本地密度策略 | feature flag、候选数据源与对照记录;保持现有标签/命中目标 | 通过完整 LOD 验收,否则回退 |
| P4 | Demo 宿主/Engine 版本闭环和 WebGL 韧性 | 统一静态发布目录与版本链;增加 context lost/restored 回归 | whenReady 与 ENGINE_READY 稳定闭环 |
P2 的最小正确实现不是“给模型加 transform”即可,而是定义同一 M:模型使用 M,POI 与路线使用同一正向投影,点击/射线结果用 M^-1 回到业务坐标。同步覆盖单位矩阵和非单位平移/旋转/缩放,禁止局部补偿。
10. 验收矩阵
| 验收主题 | 条件 | 必须记录 / 断言 | 失败处理 |
|---|---|---|---|
| Bundle 变换 | P0 全部激活模型 | 原始字段、floor/model/version、是否单位矩阵 | 未完成前禁止宣称 P2 必要 |
| 变换契约(若 P2) | 单位与非单位矩阵 | 模型位置、POI 投影、路线点、点击反变换、同楼层视觉验证 | 任一失配阻断上线 |
| 视觉对照 | 同楼层、同模型版本、同视口、同 view mode | 相机参数、DPR、截图及差异说明 | 不可用跨场景截图判定 |
| LOD 实验 | L1/L2/EXTERIOR;390x844;DPR 1 与 3 | 可见标签数、重叠数、点击命中、帧时间 | 失败立即回退当前本地策略 |
| Demo 发布 | Demo 与 Engine 同一发布目录/版本 | whenReady resolve、ENGINE_READY、楼层切换、30 POI、模型 Canvas 非空 |
调查宿主/资源/版本链 |
| WebGL 恢复 | 主动或受控触发 context lost/restored | 日志、恢复后 Canvas、楼层、POI、交互状态 | 失败阻断 P4 闭环 |
| H5 相机回归 | 固定刷新与宽屏后缩窄 | 外观/楼层快照、Canvas 非空、标签边界 | 标记相机快照污染并修复后复验 |
11. 实测与测试证据
- 测试事实: 当前 H5 已执行
tests/unit/poiDomLabels.spec.ts、GuideMapShell.spec.ts、GuideModelStateReset.spec.ts,共 9/9 通过。 - 测试事实: SDK 相关测试 19/20 通过;
model-load-lifecycle.test.ts的唯一失败来自只匹配 LF 的正则读取 CRLF 文件。实际 remount key 代码存在,因此这是 Windows 跨平台测试脆弱性,不是生命周期实现缺失。 - 证据边界: 上述结果是既有审核提供的执行证据,本报告只整理记录,未在本次文档任务重跑测试或 build,避免写入
output/dist。
12. 明确不建议事项
- 不因本报告将当前 H5 本地 ThreeMap 替换为 SDK iframe。
- 不在没有同场景证据时继续做全局颜色、灯光或 renderer 参数调参。
- 不把外观首页与 SDK 单楼层 AutoFit 作为像素级等价对象。
- 不在未核验数据库存在非单位变换前,盲目扩展 Bundle、SDK 或 H5 运行时代码。
- 不单独变换模型而遗漏 POI、路线和点击坐标,也不采用页面级坐标补丁。
- 不直接照搬 SDK HTML POI,替换 H5 的 DOM 碰撞标签和 WebGL 命中 Sprite。
- 不把 5555 Demo “连接中”直接归因为渲染器故障;先证明发布目录、Engine 版本和静态资源链一致。
- 不以单次
webglcontextlost后画面恢复为 context-recovery 已验收。
13. 交接清单
后续执行者应先完成 P0 只读核验,再决定是否开启 P2;并在每个阶段把“源码事实、实时接口事实、浏览器观察、尚未证明”分列记录。任何变更前保留当前本地策略作为回退基线,特别是移动端 DOM 标签、WebGL 命中目标、楼层基线和相机快照状态机。
14. SDK Demo 业务功能与当前 H5 对比
14.1 范围、概念与运行边界
本节分析的 SDK Demo 是 E:/MyWork/深圳国际艺术馆/智慧导览/smart-navigation-system/sgs-map-sdk-release/demo/,主要证据为 README.md、index.html、app.js,以及 Engine 的 sgs-frontend-map/sdk-engine/src/H5SdkEngine.tsx。Demo README 明确其定位是“展示 SDK 能开发成什么效果,同时用于调试”,独立静态页不直接调用 /app-api 或 /admin-api,而是由 SDK iframe/Engine 连接远端地图服务(demo/README.md:1-35)。它不是当前博物馆移动 H5 的产品需求清单。
本节严格区分四个概念:
| 概念 | 判定依据 | 不能推导出的结论 |
|---|---|---|
| Demo 展示入口 | index.html Tab/按钮和 app.js 处理函数存在 |
不代表发布链可用,也不代表适合移动端 |
| SDK 已实现能力 | SDK 公开方法可调用,且 Engine 有对应命令/事件处理 | 不代表业务数据已发布或产品流程已设计 |
| 后端接口能力 | Engine 调用的数据接口/Bundle 字段存在 | 不代表 Demo 或 H5 已做端到端错误恢复 |
| 当前 H5 已产品化能力 | H5 页面/组件、Repository/provider 和用户流程共同存在 | 不以按钮文案、类型声明或历史 mock 单独认定 |
浏览器观察(2026-07-18)。 URL 场景为本地 5555 发布 Demo,iframe 指向 5555/engine 时持续“连接中”,约 30 秒 whenReady() 超时;直接打开 5556/engine 则可获得非空 Canvas 和 ENGINE_READY。因此,Demo 的入口和源代码均已验证,但完整宿主链未闭环;本节不把 Demo 所列业务能力标记为“5555 发布版已实测成功”。具体发布链限制见第 8 节。
14.2 SDK Demo 功能清单
| 功能域 | Demo 触发入口 | SDK 方法 / 事件 | Engine / 数据接口证据 | 运行状态 |
|---|---|---|---|---|
| 初始化与状态 | URL server/env/mapId/floorCode/token,创建 SGSMapSDK |
whenReady()、on('ready') |
app.js:479-535;Engine 收到 HELLO 后发 ENGINE_READY,H5SdkEngine.tsx:2521-2525 |
直接 Engine 已观察成功;5555 Demo 链未闭环 |
| 事件/错误日志 | “事件”Tab | ready、poiClick、floorChanged、error、loadError、routeTransfer、模型/Bundle/路线/漫游事件 |
app.js:554-643 |
展示和诊断入口,不是访客业务 UI |
| 地图/楼层/图层/视图 | 楼层浮栏、2D/3D、全局、Tab 切换 | getManifest、changeFloor、setVisibleLayers、setViewMode、resetView、setRouteViewActive |
app.js:172-315,655-704,718-795;CHANGE_FLOOR 在 Engine 实现,H5SdkEngine.tsx:2527-2546 |
方法存在;宿主发布链仍是前置风险 |
| 空间查询与聚焦 | “空间”Tab:搜索、列表、详情 | getSpaces()、highlightPolygon() |
app.js:890-999,999-1068;GET_SPACES 返回 Bundle spaces,H5SdkEngine.tsx:4111-4145;高亮设置空间与 fly-to,3188-3218 |
SDK/接口能力可确认;Demo 是否完整运行受 whenReady 限制 |
| POI 查询、筛选、详情、聚焦 | “POI”Tab:类型 chip、搜索、列表 | getFloorPois()、focusTo()、poiClick |
app.js:1137-1288;GET_FLOOR_POIS,H5SdkEngine.tsx:4070-4104;Canvas 点击上报并 fly-to,4920-4938 |
SDK/Engine 已实现;Demo 全链未闭环 |
| 讲解点查询 | “讲解点”Tab:跨楼层扫描、搜索、详情 | getGuideStops()、getGuideStopsByHall() |
app.js:1289-1464;GET_GUIDE_STOPS 返回 Bundle guideStops,H5SdkEngine.tsx:4159-4176,按展厅查询 4178-4193 |
查询能力,不等于讲解内容产品流程 |
| 同层/跨层路径 | “导航”Tab:起终点楼层/地点、无障碍、overview/handoff、推荐路线 | getNavigablePlaces()、planRouteV2()/planRoute()、clearRoute() |
app.js:803-825,1465-1777,1814-1986;Engine PLAN_ROUTE 支持 displayMode 并激活跨层 viewer,2785-2816 |
SDK 实现存在;真实路网、起终点与发布 Demo 仍应单独验收 |
| 路线分段/换层/漫游 | 路线结果分段按钮、漫游控制 | routeTransfer、routeReady、startRoaming()、暂停/停止 |
app.js:587-602,827-889;Engine 有 START_ROAMING 命令(H5SdkEngine.tsx:3243-3299) |
SDK 技术能力;不是 H5 当前可宣称的馆内导航 |
| 推荐/精品动线 | “导航”推荐按钮及“动线”Tab | getFeaturedRoutes()、getFeaturedRoute()、planFeaturedRoutePreview()、showFlowline() |
app.js:1793-1986,2348-2563;Engine GET_FEATURED_ROUTES,4437-4471 |
可供后续产品评估,未证明当前博物馆数据已可用 |
| 商户 POI | “商户”Tab:餐饮/商店/咖啡厅筛选 | getBusinessPois()、focusTo() |
index.html:177-193;app.js:2145-2245;Engine GET_BUSINESS_POIS,4378-4396 |
后端/SDK 可调用,不代表自然博物馆有商户业务需求 |
| 诊断 | “诊断”Tab | getDiagnostics()、getFloorDiagnostics() |
index.html:161-175;app.js:1987-2144;Engine GET_DIAGNOSTICS,4300-4333 |
仅调试/运维能力,不应作为访客入口 |
| 场景模式 | URL scene=desktop/mobile/kiosk |
Engine 查询参数与 view preset | demo/README.md:25-34,index.html:47-64;SDK 预设见第 5 节 |
展示适配维度,不代表 H5 应复制 kiosk UI |
14.3 当前 H5 的实际业务路径
当前 H5 不使用 Demo iframe;仍是本地 ThreeMap 加 REST 数据(第 3 节)。其已可由源码证明的产品能力如下:
| 用户目标 | 真实 H5 路径与实现 | 证据 | 产品化判断 |
|---|---|---|---|
| 进入馆内/切换楼层/查看模型 | 首页 -> GuideMapShell -> ThreeMap,带外观/楼层/多层状态、楼层请求与失败状态 |
src/pages/index/index.vue:11-51,395-445;src/components/navigation/GuideMapShell.vue:12-26,136-165;src/components/map/ThreeMap.vue:27-43,444-452 |
已产品化 |
| 搜索并定位 POI | 首页或搜索页 -> PoiSearchPanel 分类、关键词、楼层结果 -> 详情/聚焦请求 |
src/components/search/PoiSearchPanel.vue:3-203,263-324;src/pages/index/index.vue:157-179,1637-1709 |
已产品化;不同于 Demo 的单列表/类型 chip |
| 地图 POI 点击、卡片和聚焦 | ThreeMap 发出 poiClick,H5 使用自己的渲染、命中和详情卡片状态 |
src/components/map/ThreeMap.vue:43-45,4805-4828,4880-4897;DOM 标签见第 7 节 |
已产品化,采用 WebGL 命中 Sprite + DOM 标签而非 iframe HTML 图层 |
| 小屏可读标签 | DOM 标签投影、碰撞规避、ResizeObserver,配合模型尺度和屏幕密度策略 |
ThreeMap.vue:1260-1328,1425-1551,4550-4591 |
已产品化,优于直接复制 Demo 标签层 |
| 讲解浏览与详情 | 讲解 -> 展厅列表 -> 讲解对象列表 -> 讲解详情;列表按展厅分页 |
src/utils/explainNavigation.ts:1-3;src/usecases/explainUseCase.ts:481-513;src/components/explain/ExplainGuideStopCatalog.vue:40-75 |
已产品化的内容 IA;不能退化成 Demo 按楼层查“讲解点” |
| 音频讲解 | 讲解详情选择语言、播放/重试/进度;全局播放器具备 H5 audio lifecycle | src/pages/exhibit/detail.vue:76-114,291-316;src/components/audio/AudioPlayer.vue:122-158,231-295 |
有源码能力;具体对象音频仍取决于真实内容数据 |
| 位置预览而非导航承诺 | 路线 use case 先读取 readiness,不就绪返回“暂不提供正式室内导航” | src/usecases/guideRouteUseCase.ts:43-76;src/pages/route/detail.vue:144-148,361-363,736-766 |
产品意图明确:不可将 Demo 路径规划视为当前 H5 缺陷 |
| 来馆导航桥接 | H5 通过微信小程序宿主位置页传入经校验的目标 | src/services/WechatMiniProgramBridgeService.ts:55-121 |
已实现桥接;保证结果是微信内置地图能力,不等同直接拉起任意第三方地图 |
14.4 完整业务功能矩阵
| 功能域 | SDK Demo 能力 | 当前 H5 能力 | 差异状态 | 差异根因 | 产品建议 | 源码证据 |
|---|---|---|---|---|---|---|
| 初始化、ready、错误日志 | whenReady + 12 类事件日志 |
本地模型加载/失败和诊断事件,无 SDK iframe ready | 不适用 | 渲染架构不同;Demo 还承担调试 | 保持 H5 本地生命周期;仅复用可观测性字段 | Demo app.js:479-643;H5 ThreeMap.vue:451-452 |
| Manifest/楼层切换 | Manifest、SDK changeFloor、重置视图 | Repository/Guide shell/ThreeMap 楼层状态、基线与预加载 | 部分覆盖 | H5 有自己的数据/相机契约 | 保持 H5;可对齐错误码和诊断快照 | Demo 655-795;H5 GuideMapShell.vue:136-165、ThreeMap.vue:3505-3554 |
| 图层/2D-3D/场景 | Tab 驱动 setVisibleLayers、2D/3D、desktop/mobile/kiosk |
overview/floor/multi、自动切换,非 Demo 场景模式 | 部分覆盖 | 产品体验不同 | 不接 kiosk;只在同场景评估必要的 view control | Demo 172-315;H5 ThreeMap.vue:90,3833-3921 |
| 空间面查询/详情 | 搜索空间、highlightPolygon |
已有馆内 POI/展厅位置预览;未证明有独立空间面详情产品 | 部分覆盖 | H5 面向访客 POI,不是 GIS 空间管理 | P2,仅当“展厅/区域详情”有真实内容与模型锚点 | Demo 999-1136;Engine 4111-4145;H5 GuideRepository.ts:115-153 |
| POI 搜索/分类/详情/聚焦 | 当前楼层类型筛选、搜索、focus、点击事件 | 分类搜索、跨楼层结果、详情/定位、点击卡片 | 相同(流程不同) | H5 针对移动端任务流程深化 | 保持 H5;不迁移 iframe 列表实现 | Demo 1137-1288;H5 PoiSearchPanel.vue:3-203、index.vue:1637-1709 |
| POI 标签与点击命中 | Engine HTML 标签、poiClick/fly-to | WebGL Sprite + hit target + DOM 碰撞标签 | 相同(实现不同) | H5 需移动端性能与命中稳定性 | 保持 H5;P3 才实验服务端 LOD | Engine 4920-4938;H5 ThreeMap.vue:4550-4591,4805-4897 |
| 讲解点查询 | 按楼层扫描/搜索/详情 | 按展厅分页的讲解对象列表和详情 | 部分覆盖(H5 更产品化) | Demo 以 SDK 数据查询为主,H5 是内容 IA | 保持 H5 IA;可在后台按 hallId 补充关联,不改变用户导航 | Demo 1289-1464;Engine 4159-4193;H5 explainUseCase.ts:481-513 |
| 讲解内容/音频 | Demo 仅展示 guide stop 字段 | 讲解详情、语言、音频/图文状态、播放器 | 当前 H5 更高 | Demo 未形成内容播放流程 | 保持 H5,先补真实内容数据而非接 SDK UI | H5 exhibit/detail.vue:76-114,291-316、AudioPlayer.vue:231-295 |
| 同层/跨层路线 | 可选起终点、轮椅、overview/handoff、路线段、换层和漫游 | 有 readiness 门控的位置关系/预览;不把其称为正式导航 | 缺失(有意门控) | 路网/导航数据与真实运行未验收 | P0 数据核验后再评估,不能直接打开功能 | Demo 1465-1777,827-889;H5 guideRouteUseCase.ts:43-76 |
| 推荐/精品动线 | 内置推荐和 featured-route 预览/展示 | 未证明有当前博物馆的路线产品数据 | 当前业务不需要/数据未证实 | Demo 是 SDK showcase,数据依赖待确认 | P2,先做内容/运营需求与路线数据评审 | Demo 1793-1986,2348-2563;Engine 4437-4471 |
| 商户 POI | 餐饮/商店/咖啡筛选 | H5 有通用服务/设施和搜索,但未证明商户运营域 | 不适用 | 自然博物馆当前产品域与商业体不同 | 不接入,除非业务明确新增餐饮/商店运营数据 | Demo index.html:177-193、app.js:2145-2245 |
| 诊断与事件面板 | 地图/楼层诊断、Event Log | 开发诊断、测试和控制台,不呈现访客面板 | 仅调试能力 | 受众不同,暴露技术细节会损害访客体验 | 不接入访客 H5;可做受权限保护的 QA 工具 | Demo 1987-2144,554-643;Engine 4300-4333 |
| 来馆/室外导航 | 未见宿主导航桥接 | 微信小程序宿主位置页桥接 | H5 独有 | H5 部署容器和用户任务不同 | 保持现状 | WechatMiniProgramBridgeService.ts:86-121 |
14.5 建议接入、保持现状与不接入
| 决策 | 能力 | 优先级 | 前置条件与原因 |
|---|---|---|---|
| 建议接入 | 路网/可达性只读核验与契约快照 | P0 | 先验证每个激活楼层 routePlanningReady、节点/边、可导航地点、无障碍连接器和真实路径;没有数据不得开放导航。可复用 SdkGuideRouteRepository 的诊断逻辑(src/repositories/SdkGuideRouteRepository.ts:92-155),不接 iframe。 |
| 建议接入 | Bundle/参数/路线 readiness 自动化契约检查 | P1 | 继承本报告第 9 节 P1;SDK Engine 的 GET_NAVIGABLE_PLACES / diagnostics 仅说明接口存在(H5SdkEngine.tsx:4205-4238,4300-4333),需要 H5 数据层的稳定契约。 |
| 建议接入 | 受 feature flag 控制的服务端 POI LOD 对照 | P1 | 遵循第 7、10 节,保留 DOM 标签、碰撞与 WebGL 点击。只采集对比数据,不迁移 SDK HTML 标签层。 |
| 建议接入 | 精品路线的产品/数据可行性探索 | P2 | 先取得博物馆运营定义、真实 routeId/waypoints、审核后图和无障碍规则;再在 H5 GuideRouteRepository/use case 后实现,不采用 Demo 硬编码推荐路线。 |
| 建议接入 | 访客需要的展厅/区域空间详情 | P2 | 必须有空间-内容稳定 ID、模型面/锚点和有效详情数据;走 Repository/view model,不能把 highlightPolygon 当作完整产品。 |
| 保持现状 | 本地 ThreeMap + REST、H5 搜索、卡片、相机基线、POI DOM/WebGL 混合策略 | P0 | 当前架构和移动体验已针对本项目;详见第 3、5、7 节。 |
| 保持现状 | 展厅列表 -> 讲解对象列表 -> 讲解详情及音频路径 | P0 | 这是当前内容业务 IA;Demo 的按楼层 guide stop 查询不应改变此流程。 |
| 不接入 | Demo iframe/Engine 的整体替换 | 不适用 | 发布 whenReady 链未闭环,且会破坏本地 ThreeMap 的相机、标签、点击和状态机契约。 |
| 不接入 | 访客端诊断/事件日志、模型性能日志 | 不适用 | 仅调试/运维能力;需要时应做独立、受权限保护的 QA 面板。 |
| 不接入 | kiosk/desktop 控制面与商户 POI 业务 | 不适用 | 设备和业务域不匹配;不能仅因 SDK Demo 展示而迁移。 |
| 不接入 | 在路网未验收时的漫游、跨层 turn-by-turn、无障碍承诺 | 不适用 | 属于真实产品缺口但不应以 UI 模拟填补,必须先满足 P0 数据与现场验收。 |
14.6 后续实施边界、接口契约与验收
若通过 P0 证明路网和目标业务数据可用,实施边界必须保持如下分层,禁止页面直接调 SDK 或后端接口:
| 目标 | 文件边界 | 必要契约 | 测试与移动端验收 |
|---|---|---|---|
| 路线 readiness | src/data/providers/sgsSdkApiProvider.ts -> src/repositories/SdkGuideRouteRepository.ts -> src/usecases/guideRouteUseCase.ts -> src/pages/route/detail.vue / src/pages/index/index.vue |
楼层、route node/edge、navigable place、connector、wheelchair constraint、数据版本;失败必须给出不可用原因 | 单测覆盖无数据/部分楼层/全就绪;390x844 验证禁用、重试、返回位置预览,不显示“开始导航”承诺 |
| 路线渲染(仅获批后) | GuideRouteRepository / guideRouteUseCase -> GuideMapShell.vue -> ThreeMap.vue |
同一模型矩阵 M 下的 route point、floorId、段类型、换层连接器、起终点;与第 6 节变换契约一并演进 | 单位/非单位矩阵、同层/跨层/无障碍路线、路线点/点击反变换;390x844、DPR 1/3 下分段切楼层与取消清理 |
| 精品路线 | 新 Repository/provider/use case 与页面 view model,不在 ThreeMap.vue 硬编码路线 |
routeId、name、waypoints、运营状态、无障碍规则、内容关联、版本 | 空/失效 waypoints、跨层、重复进入、关闭恢复;内容审核和运营验收后才暴露入口 |
| 空间详情 | provider/adapter/repository -> GuideMapShell 或专用详情页 |
spaceId 与 hallId/poiId、几何锚点、展示内容、有效状态 |
空间缺面/缺内容/锚点不匹配降级;不遮挡移动端控件 |
| POI LOD 实验 | provider/adaptor 候选数据 -> ThreeMap.vue feature flag |
server LOD 层、POI 稳定 ID、当前本地优先级和回退标志 | L1/L2/EXTERIOR、390x844、DPR 1/3,记录标签数/重叠/命中/帧时间;失败回退 |
所有实施都应补充:同一发布目录下的 SDK Demo whenReady resolve、ENGINE_READY、楼层切换、模型非空、30 POI 与 context lost/restored 验收,但这些是 SDK 发布物的独立回归项,不能作为把 iframe 引入当前 H5 的理由。