793 lines
30 KiB
Markdown
793 lines
30 KiB
Markdown
# 室内导览楼层切换、点位展示与行业专业规范差异分析
|
||
|
||
> 日期:2026-06-30
|
||
> 范围:深圳自然博物馆 `frontend-miniapp` H5 导览页
|
||
> 证据类型:源码审核 + deep-research 外部资料核验
|
||
> 说明:外部研究依据主要来自 OGC IMDF / IndoorGML、VA/WBDG 综合导视指南、Smithsonian 可访问展览设计指南、CMHR 博物馆 wayfinding 指南和博物馆移动导览案例。IMDF/IndoorGML 是数据模型标准,不直接规定 UI 视觉样式;本文将其作为室内导览数据与交互审计标尺。
|
||
|
||
---
|
||
|
||
## 1. 结论摘要
|
||
|
||
当前项目已经具备“移动 H5 室内 3D 位置预览”的基础能力:
|
||
|
||
- 支持馆外/馆内入口切换。
|
||
- 支持楼层按钮切换。
|
||
- 支持建筑外观、单层、多层视图。
|
||
- 支持 POI 标记、点击、聚焦与底部卡片。
|
||
- 支持导览和讲解业务的部分联动。
|
||
|
||
但和行业内专业室内导览系统相比,当前实现仍有明显差距。核心差距不是单一 UI,而是**楼层上下文、POI 空间语义、坐标体系、数据 readiness 与导航能力边界**尚未完整专业化。
|
||
|
||
最关键的问题包括:
|
||
|
||
1. **楼层切换更像 3D 模型切换,不是完整 floor context 切换。**
|
||
2. **POI 当前主要是单点渲染,缺少 display point / entrance point / route node / space geometry 的专业拆分。**
|
||
3. **SGS 数据源下存在坐标轴语义进入 ThreeMap 后未完全归一化的风险,楼层切换后容易出现模型与点位错位。**
|
||
4. **楼层信息展示主要是 `1F / 2F / B1` label,缺少楼层内容、数据状态、目标楼层、路线途经楼层等专业状态表达。**
|
||
5. **当前能力应定义为“室内 3D 展示 + 位置预览”,不能定义为专业可导航室内导览。**
|
||
|
||
---
|
||
|
||
## 2. 当前项目实现概览
|
||
|
||
### 2.1 导览页入口
|
||
|
||
首页导览页通过 `GuideMapShell` 组织导览地图、楼层控件、模式状态、POI 卡片和路线面板。
|
||
|
||
证据:
|
||
|
||
- `src/pages/index/index.vue:9` 使用 `GuideMapShell`。
|
||
- `src/pages/index/index.vue:23-30` 传入 `indoorModelSource`、`guideFloors`、`indoorView`、`indoorLayerMode`、`activeGuideFloor`。
|
||
- `src/pages/index/index.vue:48-53` 监听 `floor-change`、`indoor-view-change`、`poi-click`、`selection-clear`、`auto-switch`。
|
||
|
||
当前页面结构说明:
|
||
|
||
```text
|
||
index.vue
|
||
└─ GuideMapShell
|
||
├─ ThreeMap / TencentMap
|
||
├─ 搜索入口
|
||
├─ 楼层切换控件
|
||
├─ 缩放/工具按钮
|
||
├─ POI 卡片
|
||
└─ 路线/位置预览相关 UI
|
||
```
|
||
|
||
### 2.2 楼层切换现状
|
||
|
||
楼层控件位于 `GuideMapShell`:
|
||
|
||
- `scroll-view` 展示楼层列表。
|
||
- `floorItems` 来自 `props.floors` 过滤后的室内楼层。
|
||
- 点击楼层后调用 `indoorRendererRef.value?.switchFloor?.(floorId)`。
|
||
- 同时向父组件发送 `indoorViewChange`、`layerModeChange`、`floorChange`。
|
||
|
||
证据:
|
||
|
||
- `src/components/navigation/GuideMapShell.vue:129-158`:楼层列表渲染。
|
||
- `src/components/navigation/GuideMapShell.vue:526-535`:楼层点击处理。
|
||
|
||
`ThreeMap` 的楼层加载逻辑包括:
|
||
|
||
- 根据 `floorId` 查找楼层模型。
|
||
- 加载 GLB。
|
||
- 应用楼层可见性。
|
||
- 加载当前楼层 POI。
|
||
- 适配相机。
|
||
|
||
证据:
|
||
|
||
- `src/components/map/ThreeMap.vue:2612-2725`:`loadFloor()`。
|
||
- `src/components/map/ThreeMap.vue:3768-3789`:`handleFloorChange()`。
|
||
|
||
### 2.3 POI 展示现状
|
||
|
||
当前 POI 展示已经有初步的专业化方向:
|
||
|
||
- 按视图模式区分 POI 显示密度:`overview`、`multi`、`floor`。
|
||
- 按相机距离做可见性分级:`tight`、`balanced`、`full`。
|
||
- 按 POI 类别和选中状态计算优先级。
|
||
- 点击后设置选中态、聚焦相机、弹出底部卡片。
|
||
|
||
证据:
|
||
|
||
- `src/components/map/ThreeMap.vue:617-640`:`getPoiDisplayMode()` 与 `shouldShowPoiInCurrentMode()`。
|
||
- `src/components/map/ThreeMap.vue:667-718`:POI 距离可见性、数量限制、优先级计算。
|
||
- `src/components/map/ThreeMap.vue:3373-3451`:POI marker group 创建与加载。
|
||
- `src/pages/index/index.vue:65-106`:POI 底部卡片。
|
||
|
||
### 2.4 楼层信息展示现状
|
||
|
||
当前楼层信息主要表现为楼层按钮 label:
|
||
|
||
```vue
|
||
<text class="floor-label">{{ floor.label }}</text>
|
||
```
|
||
|
||
证据:
|
||
|
||
- `src/components/navigation/GuideMapShell.vue:149-157`
|
||
|
||
楼层排序和室内楼层判定由 `guideFloor.ts` 处理:
|
||
|
||
- 支持 `L1`、`L-1`、`1F`、`B1`、`L1.5` 等格式。
|
||
- 可过滤 `EXTERIOR`、`OUTDOOR`、外立面、馆外等非室内楼层。
|
||
- 可按语义楼层从高到低排序。
|
||
|
||
证据:
|
||
|
||
- `src/domain/guideFloor.ts:18-22`
|
||
- `src/domain/guideFloor.ts:68-82`
|
||
- `src/domain/guideFloor.ts:98-114`
|
||
|
||
---
|
||
|
||
## 3. 当前项目与行业专业规范的差异
|
||
|
||
## 3.1 楼层切换差异
|
||
|
||
### 当前项目特点
|
||
|
||
当前楼层切换偏向“模型视图切换”:
|
||
|
||
```text
|
||
点击楼层按钮
|
||
-> ThreeMap.switchFloor(floorId)
|
||
-> loadFloor(floorId)
|
||
-> 加载/复用 GLB
|
||
-> 加载该 floorId 的 POI
|
||
-> fit camera
|
||
```
|
||
|
||
问题在于,专业室内地图的楼层切换不只是切换模型,而是切换完整 floor context。
|
||
|
||
### 行业专业规范
|
||
|
||
专业室内导览中的一次楼层切换,应同步更新以下上下文:
|
||
|
||
1. 当前楼层 ID。
|
||
2. 当前楼层 label/name/order/elevation。
|
||
3. 当前楼层底图或 3D 模型。
|
||
4. 当前楼层空间面/展厅区域。
|
||
5. 当前楼层 POI。
|
||
6. 当前楼层路径网络图层。
|
||
7. 当前楼层垂直交通点。
|
||
8. 当前用户定位状态。
|
||
9. 当前目标点是否在本层。
|
||
10. 当前路线是否途经本层。
|
||
11. 当前楼层数据质量与可导航状态。
|
||
|
||
专业表述:
|
||
|
||
```text
|
||
Floor Switch = Floor Context Switch
|
||
不是只换模型,而是同步切换模型、空间、POI、路径、定位、状态和任务上下文。
|
||
```
|
||
|
||
### 当前差距
|
||
|
||
| 维度 | 当前项目 | 专业规范 | 风险 |
|
||
|---|---|---|---|
|
||
| 切换对象 | 主要是模型 + POI | 完整 floor context | 模型、POI、路径、定位上下文可能不同步 |
|
||
| 切换状态 | `activeGuideFloor` 近似单状态 | requested / loading / rendered / failed 分离 | UI 可能显示已切换,但模型或 POI 仍未加载成功 |
|
||
| 模型匹配 | 依赖 `floorId`、`label`、节点名、fallback | floor-model binding 明确 | 节点名不规范时误显示非本层构件 |
|
||
| 多楼层 | 有 multi 视觉展示 | 有跨层路线、垂直交通、换乘提示 | 只能看多层,不能证明可导航 |
|
||
| 失败处理 | 模型 loadError | 模型、POI、空间面、路网分别诊断 | 用户不知道失败发生在哪一层 |
|
||
|
||
### 具体源码风险
|
||
|
||
`GuideMapShell` 点击楼层后立即 emit 父组件状态:
|
||
|
||
- `emit('indoorViewChange', 'floor')`
|
||
- `emit('layerModeChange', 'single')`
|
||
- `emit('floorChange', floor.label)`
|
||
|
||
证据:`src/components/navigation/GuideMapShell.vue:526-535`
|
||
|
||
但 `ThreeMap.switchFloor()` 是异步加载模型。如果模型加载失败,父组件已经切换了楼层状态,可能出现:
|
||
|
||
```text
|
||
UI 显示已切换到 2F
|
||
但 3D 场景仍停留在旧楼层或进入错误状态
|
||
```
|
||
|
||
专业做法应拆分:
|
||
|
||
```ts
|
||
requestedFloorId
|
||
loadingFloorId
|
||
renderedFloorId
|
||
failedFloorId
|
||
```
|
||
|
||
只有 ThreeMap 成功渲染目标楼层后,父级才更新“当前已渲染楼层”。
|
||
|
||
---
|
||
|
||
## 3.2 POI 展示差异
|
||
|
||
### 当前项目特点
|
||
|
||
当前 POI 主要以 `GuideRenderPoi.positionGltf` 作为渲染点,使用 sprite/label 展示。
|
||
|
||
证据:
|
||
|
||
- `src/domain/guideModel.ts:6-18`:`GuideRenderPoi` 只有 `positionGltf`,没有 display/entrance/route node 的拆分。
|
||
- `src/components/map/ThreeMap.vue:3384-3390`:POI marker 直接读取 `[x, y, z]` 并设置 sprite 坐标。
|
||
|
||
### 行业专业规范
|
||
|
||
专业室内导览中,POI 通常不是“一个点”,而是一个空间对象。至少应拆分:
|
||
|
||
| 字段 | 用途 |
|
||
|---|---|
|
||
| `displayPoint` | 图标和标签展示点 |
|
||
| `anchorPoint` | 相机聚焦点 |
|
||
| `entrancePoint` | 用户可到达入口点 |
|
||
| `routeNodeId` | 路网节点,用于路径规划 |
|
||
| `geometry` | 房间、展厅、空间区域边界 |
|
||
| `floorId` | 稳定楼层 ID |
|
||
| `sourceConfidence` | 坐标来源和可信度 |
|
||
|
||
推荐领域模型:
|
||
|
||
```ts
|
||
interface IndoorPoi {
|
||
id: string
|
||
name: string
|
||
categoryId: string
|
||
floorId: string
|
||
|
||
displayPoint: [number, number, number]
|
||
anchorPoint?: [number, number, number]
|
||
entrancePoints?: Array<[number, number, number]>
|
||
routeNodeIds?: string[]
|
||
|
||
geometry?: Polygon | MultiPolygon
|
||
unitId?: string
|
||
spaceId?: string
|
||
|
||
priority: number
|
||
minZoom?: number
|
||
maxZoom?: number
|
||
labelPolicy: 'always' | 'selected' | 'adaptive' | 'hidden'
|
||
sourceConfidence: 'verified' | 'backend' | 'model-derived' | 'fallback'
|
||
dataStatus: 'ready' | 'partial' | 'unverified'
|
||
}
|
||
```
|
||
|
||
### 当前差距
|
||
|
||
| 维度 | 当前项目 | 专业规范 | 风险 |
|
||
|---|---|---|---|
|
||
| POI 坐标 | 单个 `positionGltf` | display / anchor / entrance / route node 分离 | 展厅中心点可能被误作路线终点 |
|
||
| POI 区域 | 以点为主 | 点 + 面 + 入口 + 路网节点 | 展厅语义表达不足 |
|
||
| 坐标高度 | 直接使用 `[x,y,z]` | 楼层绝对高程与本层贴地高度分离 | 切换楼层后 marker 和模型错位 |
|
||
| 可达性 | 有分类但不完整 | 入口、无障碍路线、垂直交通联动 | 不足以支持专业无障碍导览 |
|
||
| 展示策略 | 代码内硬编码优先级 | 可配置图层样式与任务态策略 | 扩展和调参困难 |
|
||
|
||
### SGS 坐标风险
|
||
|
||
当前 SGS adapter 中 `normalizePositionSource()` 直接输出 `[x, y, z]`:
|
||
|
||
证据:`src/data/adapters/sgsSdkGuideAdapter.ts:124-130`
|
||
|
||
`ThreeMap` 又直接把 `y` 用作 sprite 高度:
|
||
|
||
证据:`src/components/map/ThreeMap.vue:3384-3390`
|
||
|
||
但 SGS 坐标常见语义是:
|
||
|
||
```text
|
||
x = GLB 水平 X
|
||
z = GLB 水平 Z
|
||
y = 高度或楼层绝对高程
|
||
```
|
||
|
||
专业渲染中,POI 展示应使用:
|
||
|
||
```text
|
||
renderX = source.x
|
||
renderZ = source.z
|
||
renderY = surfaceOffset 或 floor-local height
|
||
```
|
||
|
||
而不是直接把 SGS `position.y` 当作当前单层模型的局部高度。
|
||
|
||
---
|
||
|
||
## 3.3 楼层信息展示差异
|
||
|
||
### 当前项目特点
|
||
|
||
当前楼层信息主要是楼层按钮:
|
||
|
||
```text
|
||
B2 / B1 / 1F / 2F / 3F ...
|
||
```
|
||
|
||
选中态主要依赖:
|
||
|
||
```vue
|
||
:class="{ active: activeFloorId === floor.id && layerMode !== 'multi' }"
|
||
```
|
||
|
||
证据:`src/components/navigation/GuideMapShell.vue:149-154`
|
||
|
||
### 行业专业规范
|
||
|
||
专业楼层信息不应只是 label,而应包含:
|
||
|
||
```ts
|
||
interface IndoorFloor {
|
||
id: string
|
||
code: string // L1 / L2 / L-1
|
||
label: string // 1F / 2F / B1
|
||
name?: string // 一层大厅 / 二层展厅区
|
||
level: number // -1, 1, 2
|
||
elevation?: number
|
||
order: number
|
||
isIndoor: boolean
|
||
isNavigable: boolean
|
||
isOpen: boolean
|
||
modelStatus: 'ready' | 'missing' | 'loading' | 'error'
|
||
poiStatus: 'ready' | 'empty' | 'partial' | 'error'
|
||
routeStatus: 'ready' | 'not-ready' | 'partial'
|
||
}
|
||
```
|
||
|
||
专业楼层 UI 至少要区分:
|
||
|
||
| 状态 | 展示建议 |
|
||
|---|---|
|
||
| 当前显示楼层 | 高亮 |
|
||
| 用户所在楼层 | “你在这”/定位点 |
|
||
| 目标所在楼层 | 目标标记 |
|
||
| 路线途经楼层 | 路线提示/小圆点 |
|
||
| 有搜索结果楼层 | 数量 badge |
|
||
| 加载中楼层 | spinner |
|
||
| 数据缺失楼层 | 灰化/警告 |
|
||
| 不开放楼层 | 锁定/禁用 |
|
||
|
||
### 当前差距
|
||
|
||
| 维度 | 当前项目 | 专业规范 |
|
||
|---|---|---|
|
||
| 楼层 label | 已实现 | 已实现 |
|
||
| 楼层名称 | 缺少 | 应显示“一层大厅 / 二层展厅区”等 |
|
||
| 楼层内容摘要 | 缺少 | 应显示主要展厅、服务设施数量 |
|
||
| 用户所在楼层 | 缺少 | 应和当前显示楼层区分 |
|
||
| 目标楼层 | 缺少 | 从搜索/讲解进入时应标注 |
|
||
| 路线途经楼层 | 部分 route 数据有,但 UI 未系统表达 | 应在楼层控件中明确标注 |
|
||
| 数据状态 | 缺少 | 应标注模型/POI/路网是否 ready |
|
||
|
||
---
|
||
|
||
## 4. 行业内专业展示规范总结
|
||
|
||
## 4.1 楼层切换规范
|
||
|
||
专业室内导览的楼层切换应满足:
|
||
|
||
1. 楼层 ID 稳定,不使用纯展示 label 作为主键。
|
||
2. 楼层排序基于语义 level,而不是字符串排序。
|
||
3. 切换楼层时,模型、空间面、POI、路线、定位状态同步更新。
|
||
4. 切换过程有 loading/pending 状态。
|
||
5. 切换失败保留旧楼层,并提示失败原因。
|
||
6. 用户所在楼层、目标所在楼层、当前查看楼层应分开表达。
|
||
7. 跨楼层路线时,应标记路线涉及楼层。
|
||
8. 非开放、无数据、无路网楼层应禁用或显示状态。
|
||
|
||
推荐状态模型:
|
||
|
||
```ts
|
||
interface FloorViewState {
|
||
requestedFloorId?: string
|
||
loadingFloorId?: string
|
||
renderedFloorId?: string
|
||
userLocatedFloorId?: string
|
||
targetFloorId?: string
|
||
failedFloorId?: string
|
||
routeFloorIds: string[]
|
||
}
|
||
```
|
||
|
||
## 4.2 POI 展示规范
|
||
|
||
专业 POI 展示应满足:
|
||
|
||
1. 区分展示点、入口点、路线节点、空间几何。
|
||
2. POI 必须绑定稳定 `floorId`。
|
||
3. POI 坐标必须声明坐标系、单位、轴向和变换。
|
||
4. POI label 应按 zoom/camera distance/task state 自适应显示。
|
||
5. POI 高密度区域必须做避让、聚合和优先级裁剪。
|
||
6. 搜索命中、选中、路线起终点、换乘点应强制显示。
|
||
7. 设施、展厅、展品、交通、无障碍、安全设施应有独立图层策略。
|
||
8. 不同任务模式应有不同 POI 图层:浏览、找设施、路线、无障碍、讲解联动。
|
||
|
||
推荐 POI 点位拆分:
|
||
|
||
```text
|
||
展厅中心点:用于标签展示
|
||
展厅入口点:用于路线终点
|
||
路网节点:用于路径计算
|
||
空间面:用于区域高亮
|
||
锚点:用于相机聚焦
|
||
```
|
||
|
||
## 4.3 楼层信息展示规范
|
||
|
||
专业楼层信息应包含:
|
||
|
||
1. 楼层短 label:如 `1F`、`2F`、`B1`。
|
||
2. 楼层名称:如 `一层大厅`、`二层展厅区`。
|
||
3. 主要内容摘要:如 `宇宙厅 / 服务台 / 卫生间`。
|
||
4. 点位数量或搜索结果数量。
|
||
5. 模型加载状态。
|
||
6. POI 数据状态。
|
||
7. 路线数据状态。
|
||
8. 当前用户所在楼层。
|
||
9. 当前目标所在楼层。
|
||
10. 当前路线途经楼层。
|
||
|
||
移动端推荐形式:
|
||
|
||
```text
|
||
楼层按钮:2F
|
||
当前楼层 chip:2F · 地球厅 / 演化厅 · 23 个点位
|
||
楼层详情面板:展示展厅、设施、数据状态、路线状态
|
||
```
|
||
|
||
## 4.4 3D 室内导览规范
|
||
|
||
专业 3D 室内导览应满足:
|
||
|
||
1. 3D 模型只是底图/底座,业务语义来自数据层。
|
||
2. 不应依赖模型节点名推断核心业务楼层语义。
|
||
3. GLB 模型、POI、空间面、路线点必须共享或可转换到同一坐标系。
|
||
4. 模型 translation/rotation/scale 必须被业务图层同步应用。
|
||
5. 单层模型和全馆模型切换不能改变 POI 的真实语义坐标。
|
||
6. 模型加载失败、POI 加载失败、路网加载失败应分别提示。
|
||
7. 移动端应控制 GLB 体积、解码时间和 WebGL 资源释放。
|
||
|
||
## 4.5 导航能力规范
|
||
|
||
如果产品要宣称“室内导航”,至少需要:
|
||
|
||
1. 可步行路网节点。
|
||
2. 路网边和权重。
|
||
3. 垂直交通连接:电梯、楼梯、扶梯。
|
||
4. 跨楼层路线分段。
|
||
5. POI 到可达入口/路网节点的映射。
|
||
6. 无障碍路线约束。
|
||
7. 一方通行/封闭/施工等约束。
|
||
8. 路线可视化。
|
||
9. 起终点和换乘点状态。
|
||
10. 数据 readiness 与 smoke test。
|
||
|
||
当前项目在 route graph / nav data 未验证前,应继续使用:
|
||
|
||
```text
|
||
位置预览 / 查看位置 / 查看三维位置
|
||
```
|
||
|
||
不应使用:
|
||
|
||
```text
|
||
开始馆内导航 / 到达引导 / turn-by-turn / 精准导航
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 当前项目优先改进建议
|
||
|
||
## P1:统一 SGS 坐标归一化
|
||
|
||
当前最优先问题是避免 SGS `position.y` 直接进入 ThreeMap marker 的 Y 坐标。
|
||
|
||
建议:
|
||
|
||
```ts
|
||
// SGS 渲染坐标:只用 x/z 做水平定位,Y 使用本层贴地偏移
|
||
positionGltf = [source.x, 0, source.z]
|
||
```
|
||
|
||
如果需要保留原始高度:
|
||
|
||
```ts
|
||
rawPosition = [source.x, source.y, source.z]
|
||
heightMode = 'absolute-elevation'
|
||
```
|
||
|
||
不要让绝对高程直接控制单层模型里的 marker 高度。
|
||
|
||
## P1:楼层切换状态闭环
|
||
|
||
把当前单一 `activeGuideFloor` 拆成:
|
||
|
||
```ts
|
||
requestedFloorId
|
||
loadingFloorId
|
||
renderedFloorId
|
||
failedFloorId
|
||
```
|
||
|
||
流程:
|
||
|
||
```text
|
||
点击楼层
|
||
-> requested/loading
|
||
-> ThreeMap 加载模型和 POI
|
||
-> 成功后 emit renderedFloorChange
|
||
-> 父组件更新 active/rendered floor
|
||
-> 失败后保留旧楼层并提示
|
||
```
|
||
|
||
## P1:POI 专业语义拆分
|
||
|
||
将 `GuideRenderPoi.positionGltf` 逐步升级为:
|
||
|
||
```ts
|
||
displayPoint
|
||
anchorPoint
|
||
entrancePoints
|
||
routeNodeIds
|
||
geometry
|
||
```
|
||
|
||
展厅类 POI 尤其需要:
|
||
|
||
- `space.geometry` 用于区域高亮。
|
||
- `space.center` 用于标签。
|
||
- `entrancePoints` 用于路线。
|
||
- `routeNodeIds` 用于导航。
|
||
|
||
## P2:楼层信息面板升级
|
||
|
||
建议当前楼层展示从单 label 升级为:
|
||
|
||
```text
|
||
2F · 地球厅 / 演化厅 · 23 个点位
|
||
```
|
||
|
||
楼层按钮可增加:
|
||
|
||
- 当前目标所在楼层标记。
|
||
- 路线途经楼层标记。
|
||
- 搜索结果数量。
|
||
- 数据未就绪/加载失败状态。
|
||
|
||
## P2:POI 图层配置化
|
||
|
||
把 `ThreeMap.vue` 中硬编码的 POI 类别优先级迁到配置或 view model:
|
||
|
||
```ts
|
||
interface PoiLayerStyle {
|
||
categoryId: string
|
||
icon: string
|
||
color: string
|
||
priority: number
|
||
labelPolicy: 'always' | 'adaptive' | 'selected-only'
|
||
routeRelevant: boolean
|
||
accessibilityRelevant: boolean
|
||
}
|
||
```
|
||
|
||
## P2:空间面成为一等图层
|
||
|
||
博物馆展厅不应只显示一个点。建议将 `spaces` 转成专业图层:
|
||
|
||
- 展厅区域 polygon/mesh highlight。
|
||
- 展厅中心标签。
|
||
- 展厅入口点。
|
||
- 点击区域选中展厅。
|
||
- 展厅卡片与讲解内容联动。
|
||
|
||
## P3:路线能力逐步专业化
|
||
|
||
后续如要升级为真正室内导航,需要完成:
|
||
|
||
- route graph / nav data 接入。
|
||
- 跨层连接。
|
||
- POI entrance -> route node 映射。
|
||
- 无障碍路线。
|
||
- 路线分段楼层展示。
|
||
- route readiness smoke test。
|
||
|
||
---
|
||
|
||
## 6. 建议实施顺序
|
||
|
||
| 优先级 | 事项 | 目标 |
|
||
|---|---|---|
|
||
| P1 | SGS 坐标归一化 | 解决楼层切换后 POI 与模型错位 |
|
||
| P1 | 楼层切换状态拆分 | 防止 UI 楼层状态与实际渲染楼层不同步 |
|
||
| P1 | POI display/entrance/routeNode 拆分 | 建立专业导览数据基础 |
|
||
| P1 | 继续限制导航话术 | 防止能力误导 |
|
||
| P2 | 楼层信息展示升级 | 让用户理解每层内容和状态 |
|
||
| P2 | POI 图层配置化 | 支持搜索、设施、路线、无障碍等任务态 |
|
||
| P2 | 空间面展厅图层 | 从“点位地图”升级到“空间地图” |
|
||
| P3 | route graph / nav data 闭环 | 支持真正路线预览/导航 |
|
||
| P3 | 移动端性能优化 | 控制 GLB、POI、标签和 WebGL 资源成本 |
|
||
|
||
---
|
||
|
||
## 8. deep-research 外部资料核验补充
|
||
|
||
> 本节为 2026-06-30 deep-research 工作流补充。研究问题:对比当前深圳自然博物馆 `frontend-miniapp` 导览页的楼层切换、点位展示、楼层信息展示,与室内导览/室内地图行业专业展示规范的差异,并总结行业专业规范。
|
||
|
||
### 8.1 研究限制
|
||
|
||
- 外部结论主要基于博物馆/公共建筑无障碍指南、OGC IMDF/IndoorGML 标准和少量博物馆案例研究。
|
||
- 这些资料适合作为专业规范与审计标尺,不等同于某一司法辖区对移动 H5 导览页的硬性法律要求。
|
||
- IMDF/IndoorGML 是数据模型标准,不直接规定 UI 视觉样式;本文关于“楼层切换 UI 应如何呈现”的部分,是从专业数据模型和地图应用行为要求推导出的应用性结论。
|
||
- 部分可访问性来源讨论实体展览空间、实体地图、导视牌或触觉/印刷材料;映射到 `frontend-miniapp` 时,应理解为同一 wayfinding 原则在移动端的对应实现。
|
||
|
||
### 8.2 外部核验后的高置信结论
|
||
|
||
#### 8.2.1 专业室内导览首先把楼层/层级认知当作核心问题
|
||
|
||
专业室内导览不是简单楼层按钮切换。对于多楼层、多 level、局部区域才能上下转换的建筑,楼层切换必须帮助用户理解:
|
||
|
||
- 我在哪一层。
|
||
- 当前这一层有什么。
|
||
- 目标在哪一层。
|
||
- 如何去另一层。
|
||
- 应通过哪个电梯、楼梯、坡道或换乘点。
|
||
|
||
外部依据:British Museum 移动导览案例显示,复杂博物馆中的多楼层和多 level 会直接造成方向感问题;用户难以理解自己在哪一层、如何换层,以及如何阅读多层表示。VA/WBDG 指南要求每层目录识别该层公共目的地,说明楼层信息应服务于定位和决策,而不是只作为地图图层开关。
|
||
|
||
对当前项目的含义:
|
||
|
||
- 当前 `floor-switcher` 只展示楼层 label,不能充分支撑复杂博物馆场景下的楼层认知。
|
||
- 应补充楼层内容摘要、用户所在楼层、目标楼层、路线途经楼层和可达性提示。
|
||
|
||
#### 8.2.2 专业楼层切换应由结构化 Level 数据驱动
|
||
|
||
OGC IMDF 将楼层建模为 `Level Feature`,核心要求包括:
|
||
|
||
- 稳定 `id`。
|
||
- `feature_type = level`。
|
||
- polygonal geometry。
|
||
- venue-declared `name`。
|
||
- `short_name`。
|
||
- 数字 `ordinal`。
|
||
|
||
其中 `ordinal` 表示真实楼层堆叠位置,应与 UI 显示 label 分离。例如 `B1`、`1F`、`L1` 是展示和命名问题,而 `ordinal` 是排序、跨层关系和空间推理问题。
|
||
|
||
对当前项目的含义:
|
||
|
||
- `guideFloor.ts` 已经有楼层 label/code 解析和排序,这是正确方向。
|
||
- 但当前领域模型仍缺少 IMDF 式 Level geometry、ordinal、display point、楼层范围和数据状态的完整表达。
|
||
- 后续不应只依赖 `floor.label` 或模型节点名推断楼层语义。
|
||
|
||
#### 8.2.3 专业 floor switcher 不应有任意初始状态
|
||
|
||
IMDF Level geometry 规则要求 venue organization 考虑:
|
||
|
||
- 无楼层选择时默认显示哪些楼层。
|
||
- 用户选择单体建筑时默认显示哪层。
|
||
- 复杂结构中 physical parity 与 ordinal parity 不一致时如何处理。
|
||
|
||
对当前项目的含义:
|
||
|
||
- 当前页面传入 `indoor-initial-view="overview"`,同时存在 `activeGuideFloor` 默认值;这应被明确为产品策略,而不是偶然状态。
|
||
- 应定义:初次进入馆内时显示全馆、用户主动选楼层后显示单层、从搜索/讲解定位进入时显示目标楼层。
|
||
- 需要区分 `requestedFloorId`、`renderedFloorId`、`targetFloorId` 和 `userLocatedFloorId`。
|
||
|
||
#### 8.2.4 POI/amenity 必须 floor-aware,且要避免跨楼层重叠混淆
|
||
|
||
IMDF Amenity 规则定义 `correlation_id`,用于不同 Level 上同一服务设施的关联。其目标之一是:当多个楼层垂直重叠存在同类设施,而用户未选楼层时,地图不应混杂或重复展示。
|
||
|
||
对当前项目的含义:
|
||
|
||
- POI 展示必须严格绑定当前渲染楼层。
|
||
- 多层/全馆模式下,不应无差别显示所有楼层 POI。
|
||
- 同一垂直位置的电梯、楼梯、卫生间等跨层设施需要关联关系,而不是多个互不相关的点。
|
||
- 当前代码已有按楼层加载 POI 的方向,但 POI 专业语义仍需从单 `positionGltf` 升级为 floor-aware amenity/space 模型。
|
||
|
||
#### 8.2.5 点位和地图可读性依赖清晰视觉层级与可区分符号系统
|
||
|
||
British Museum 案例中,地图改版通过颜色和样式区分图标、按钮和地图区域,以降低用户对缩放、滚动、选择对象和地图定向的困难。
|
||
|
||
对当前项目的含义:
|
||
|
||
- 当前 `ThreeMap` 已经有 POI 类别颜色、优先级、距离过滤和 label 策略,是正确方向。
|
||
- 但专业系统还应有配置化图层、碰撞避让、聚合、色盲友好、非颜色唯一编码、搜索/路线/无障碍任务态强制显示策略。
|
||
|
||
#### 8.2.6 楼层信息展示应组合地图、文本/语音锚点和附近地标
|
||
|
||
British Museum Museum Navigator 使用 floor、level、room number、方位和附近 landmark 组织位置描述,并结合音频说明、地标图片和高亮路线。COSIT、Met 和 V&A 相关证据也支持在多楼层空间中使用房间号、楼层、地标和可识别转折点辅助定位。
|
||
|
||
对当前项目的含义:
|
||
|
||
- 楼层按钮仅显示 `1F / 2F / B1` 不足。
|
||
- 楼层信息应显示主要展厅、服务设施、附近地标、空间区域名称和换层节点。
|
||
- POI 卡片也应包含“所在楼层 + 附近地标 + 如何到达/查看位置”的组合描述。
|
||
|
||
#### 8.2.7 专业室内导览是 integrated wayfinding system
|
||
|
||
CMHR 指南将 wayfinding 描述为包含 signs、maps、spoken directions、technology、mobile application、website、tactile indicators、lighting 和 amenity communication 的冗余线索系统。VA/WBDG integrated wayfinding 要求所有工具使用一致目的地名称、命名逻辑、视觉语言和同一套 canonical map 信息。
|
||
|
||
对当前项目的含义:
|
||
|
||
- `frontend-miniapp` 不应自成一套命名体系。
|
||
- 展厅名、楼层名、设施名、房间号、讲解内容应与现场实体导视、后台 SGS 数据和讲解内容库一致。
|
||
- 当前项目需要明确 canonical nomenclature,即“哪一套命名为准”。
|
||
|
||
#### 8.2.8 专业导览应在决策点反复确认方向和楼层上下文
|
||
|
||
VA/WBDG 指南要求访客在导航过程中获得 frequent intervals 的 reinforcement and guidance,并强调 decision points、floor directories、you-are-here 和室内导航能力。CMHR 指南也指出 You-Are-Here maps 应布置在电梯、坡道等方向决策点附近。
|
||
|
||
移动端对应规范:
|
||
|
||
- 到达电梯/楼梯/坡道/入口/服务台/转折点时,UI 应强化当前楼层和下一步。
|
||
- 跨楼层路线应明确“当前楼层路径”和“目标楼层路径”。
|
||
- 即使没有实时定位,也应在位置预览中表达“目标在 2F,建议从某电梯/楼梯上楼”。
|
||
|
||
当前项目由于 route graph/nav data readiness 尚未闭环,目前不应承诺此类真实导航,只能在数据可用时逐步增加。
|
||
|
||
#### 8.2.9 可访问楼层图和平面图是专业展览/博物馆导览的重要组成
|
||
|
||
Smithsonian Accessible Exhibition Design 要求提供 accessible floorplan 帮助访客 wayfinding,并建议在展览入口、信息台或中心位置提供;它还要求 circulation route 清楚定义、易跟随,并在 level changes、unexpected turns 或 obstacles 等处清晰表达路线。
|
||
|
||
对移动端的映射:
|
||
|
||
- 楼层图应可被理解,不只是 3D 模型。
|
||
- 路线、无障碍路线、电梯/坡道、台阶规避等应被明确表达。
|
||
- 若 route graph 未就绪,则 UI 应清楚显示“位置预览可用,路线导航未开放”。
|
||
|
||
#### 8.2.10 专业室内导览需要导航网络/连通性模型支撑
|
||
|
||
OGC IndoorGML 1.1 的范围是 indoor navigation network models 的表示与交换,强调为室内导航应用建立通用 schema,并建模室内空间拓扑和语义关系。
|
||
|
||
这不意味着本项目必须采用 IndoorGML,但说明专业室内导航能力应由以下数据支撑:
|
||
|
||
- 可步行路网节点。
|
||
- 边和权重。
|
||
- 垂直连接。
|
||
- 空间拓扑。
|
||
- POI 到可达入口或路网节点的映射。
|
||
- 跨楼层路径分段。
|
||
|
||
当前项目若只有 GLB 和散点 POI,应继续定位为“位置预览”。
|
||
|
||
### 8.3 外部研究映射到当前项目的专项差距
|
||
|
||
| 专业规范 | 当前项目状态 | 差距 |
|
||
|---|---|---|
|
||
| 结构化 Level/ordinal 数据 | 有 `guideFloor.ts` label/code 解析,但缺少完整 Level geometry/ordinal/display point | 楼层模型、POI、路线和 UI 状态还未统一到专业 Level 模型 |
|
||
| floor-aware POI | 有按 floorId 加载 POI | POI 仍以单 `positionGltf` 为主,缺少 amenity correlation、entrance、route node、geometry |
|
||
| 楼层目录/内容摘要 | 楼层按钮只显示 label | 缺少每层目的地、主要展厅、服务设施和状态说明 |
|
||
| 决策点强化 | 暂无完整路线/决策点 UI | 电梯、楼梯、坡道、入口、转折点未形成导览状态机 |
|
||
| integrated wayfinding | miniapp 内部已有导览/讲解联动雏形 | 仍需与现场导视、SGS 后台、讲解内容库统一命名和空间关系 |
|
||
| 可访问 floorplan | 当前是 3D 展示 + POI 预览 | 缺少无障碍路线、可访问入口、坡道/电梯优先等表达 |
|
||
| 导航网络 | route graph/nav data readiness 未验证 | 不能宣称专业室内导航 |
|
||
|
||
### 8.4 deep-research 推荐追问
|
||
|
||
后续专项审计建议回答以下问题:
|
||
|
||
1. 当前 `frontend-miniapp` 的楼层切换是否已经有真实 Level 数据模型支撑,还是仅使用 UI 标签/静态图层状态?
|
||
2. 深圳自然博物馆现场实体导视、房间/展厅编号、楼层命名、服务设施名称与 miniapp 中的 POI 命名是否一致?如果不一致,应以哪一套 canonical nomenclature 为准?
|
||
3. 当前导览页是否支持无障碍路径语义,例如电梯、坡道、无障碍卫生间、台阶规避、跨楼层可达路线?这些信息是否来自可维护的数据源?
|
||
4. SGS Map SDK 或上游 `sgs-frontend-map` 场景设置是否提供 route graph/nav_data、level ordinal、POI level binding、vertical connector 等字段?如果没有,miniapp 应补充适配层还是推动上游数据治理?
|
||
|
||
### 8.5 外部来源
|
||
|
||
- OGC Indoor Mapping Data Format (IMDF): https://www.ogc.org/standards/indoor-mapping-data-format/
|
||
- OGC IMDF Level: https://docs.ogc.org/cs/20-094/Level/index.html
|
||
- OGC IMDF Reference: https://docs.ogc.org/cs/20-094/Reference/index.html
|
||
- OGC IMDF Amenity: https://docs.ogc.org/cs/20-094/Amenity/index.html
|
||
- OGC IndoorGML 1.1: https://docs.ogc.org/is/19-011r4/19-011r4.html
|
||
- VA/WBDG Integrated Wayfinding: https://www.wbdg.org/FFC/VA/VASIGN/wayfinding_new_chapter2.pdf
|
||
- Smithsonian Accessible Exhibition Design: https://affiliations.si.edu/wp-content/uploads/PDFs/Accessible-Exhibition-Design.pdf
|
||
- ADA Museum Access guide: https://archive.ada.gov/business/museum_access.htm
|
||
- CMHR Wayfinding: https://id.humanrights.ca/visitor-supports/wayfinding/
|
||
- British Museum mobile wayfinding case: https://www.museumsandtheweb.com/mw2011/papers/mobile_devices_for_orientation_and_way_finding
|
||
- COSIT museum orientation reference: https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.COSIT.2017.18
|
||
- V&A digital map: https://www.vam.ac.uk/features/digitalmap/where-am-i
|
||
- Metropolitan Museum map design case: https://www.100archive.com/projects/metropolitan-museum-of-art-map-design
|
||
|