# SGS Map SDK Bridge 契约文档 > 版本: 2.5.0 | 最后更新: 2026-07-15 | 基于独立 `/engine/` 渲染引擎实际实现 ## 概述 本文档记录 SGS Map SDK(客户端 JS 库)与独立发布的 `/engine/` 渲染引擎之间的 `postMessage` 通信契约。运行时引擎源码位于 `sgs-frontend-map/sdk-engine`,发布产物位于 `sgs-map-sdk-release/engine`。 **核心架构**: ``` ┌─────────────┐ postMessage ┌───────────────────┐ REST API ┌──────────┐ │ 宿主页面 │ ◄───────────► │ /engine/ 引擎 │ ◄──────────► │ 后端 │ │ (SDK.js) │ SGS_MAP_* │ (page.tsx iframe) │ /app-api/* │ Spring │ └─────────────┘ └───────────────────┘ └──────────┘ ``` ## 通信协议 ### 请求格式(宿主 → 基座) ```ts { type: 'SGS_MAP_COMMAND', action: string, // 指令名(如 'CHANGE_FLOOR') requestId: string, // 唯一请求 ID,用于匹配响应 payload: object // 指令参数 } ``` ### 响应格式(基座 → 宿主) ```ts { type: 'SGS_MAP_RESPONSE', action: string, // 原样回显请求的 action(A2.6 规约) requestId: string, // 原样回显请求的 requestId payload: object, // 响应数据(含 success: boolean) error?: { // 仅失败时存在 code: string, message: string } } ``` ### 事件格式(基座 → 宿主,主动推送) ```ts { type: 'SGS_MAP_EVENT', action: string, // 事件名(如 'ENGINE_READY', 'ON_POI_CLICK') payload: object } ``` ### Origin 安全校验 基座通过 URL 参数 `?targetOrigin=` 启用 origin 白名单校验。若 `targetOrigin` 非 `*` 且与 `event.origin` 不匹配,消息将被静默丢弃。 --- ## Bridge 支持矩阵 > ✅ = 代码中存在对应 `case` 分支,已实际实现 > ❌ = 代码中无对应 `case` 分支 | # | SDK 方法名 | postMessage action | /engine/ 支持 | 最低版本 | 类别 | |---|-----------|-------------------|:---:|---------|------| | 1 | `自动握手` | `HELLO` | ✅ | 1.0.0 | 生命周期 | | 2 | `changeFloor()` | `CHANGE_FLOOR` | ✅ | 1.0.0 | 地图控制 | | 3 | `focusTo()` | `FOCUS_TO` | ✅ | 1.0.0 | 地图控制 | | 4 | `setViewMode()` | `SET_VIEW_MODE` | ✅ | 2.3.0 | 地图控制 | | 5 | `addMarker()` | `ADD_MARKER` / `ADD_BUSINESS_MARKER` | ✅ | 1.0.0 | 图钉 | | 6 | `removeMarker()` | `REMOVE_MARKER` / `REMOVE_BUSINESS_MARKER` | ✅ | 1.0.0 | 图钉 | | 7 | `clearMarkers()` | `CLEAR_MARKERS` | ✅ | 1.0.0 | 图钉 | | 8 | `planRoute()` / `planRouteV2()` | `PLAN_ROUTE` | ✅ | 1.0.0 | 路径规划 | | 9 | `highlightPolygon()` | `HIGHLIGHT_POLYGON` | ✅ | 1.0.0 | 地图控制 | | 10 | `clearRoute()` | `CLEAR_ROUTE` | ✅ | 1.0.0 | 路径规划 | | 11 | `resetView()` | `RESET_VIEW` | ✅ | 1.0.0 | 地图控制 | | 12 | `getState()` | `GET_STATE` | ✅ | 1.0.0 | 状态查询 | | 13 | `toggleLayer()` | `TOGGLE_LAYER` | ✅ | 1.5.0 | 图层控制 | | 14 | `setVisibleLayers()` | `SET_VISIBLE_TYPES` | ✅ | 1.5.0 | 图层控制 | | 15 | `getManifest()` | `GET_MANIFEST` | ✅ | 2.1.0 | 数据查询 | | 16 | `loadFloorBundle()` | `LOAD_FLOOR_BUNDLE` | ✅ | 2.1.0 | 数据查询 | | 17 | `getFloorPois()` | `GET_FLOOR_POIS` | ✅ | 2.1.0 | 数据查询 | | 18 | `getPois()` | `GET_POIS` | ✅ | 1.0.0 | 数据查询 | | 19 | `getSpaces()` | `GET_SPACES` | ✅ | 2.1.0 | 数据查询 | | 20 | `getGuideStops()` | `GET_GUIDE_STOPS` | ✅ | 2.1.0 | 数据查询 | | 21 | `getGuideStopsByHall()` | `GET_GUIDE_STOPS_BY_HALL` | ✅ | 2.1.0 | 数据查询 | | 22 | `getNavigablePlaces()` | `GET_NAVIGABLE_PLACES` | ✅ | 2.3.0 | 数据查询 | | 23 | `preloadFloor()` | `PRELOAD_FLOOR` | ✅ | 2.1.0 | 性能优化 | | 24 | `clearModelCache()` | `CLEAR_MODEL_CACHE` | ✅ | 2.1.0 | 性能优化 | | 25 | `getPerformanceStats()` | `GET_PERFORMANCE_STATS` | ✅ | 2.1.0 | 诊断 | | 26 | `getDiagnostics()` | `GET_DIAGNOSTICS` | ✅ | 2.3.0 | 诊断 | | 27 | `getFloorDiagnostics()` | `GET_FLOOR_DIAGNOSTICS` | ✅ | 2.3.0 | 诊断 | ### 仅 mock-release 模式专用指令(非公开 SDK 方法) | # | postMessage action | /engine/ 支持 | 说明 | |---|-------------------|:---:|------| | M1 | `GET_RELEASE_MANIFEST` | ✅ | 仅 `env=mock-release` 时可用 | | M2 | `GET_MODEL_RESOURCES` | ✅ | 仅 `env=mock-release` 时可用 | | M3 | `GET_LAYER_TREE` | ✅ | 仅 `env=mock-release` 时可用 | | M4 | `LOAD_MOCK_RELEASE_ROUTE` | ✅ | 仅 `env=mock-release` 时可用 | > 以上 M1–M4 已在 SDK v2.3.0 中标记为废弃 (`deprecated`),新接入方不应使用。 --- ## 各指令详细规格 --- ### 1. HELLO 握手协议。SDK 创建 iframe 后自动发送,基座收到后立即触发 `ENGINE_READY` 事件。 | 项目 | 值 | |------|---| | **postMessage action** | `HELLO` | | **SDK 方法** | 自动握手(SDK 内部调用,不暴露公开方法) | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: ```ts { version?: string } // SDK 版本号(可选) ``` **成功响应**: 无显式 `SGS_MAP_RESPONSE`。基座通过 `SGS_MAP_EVENT` 发送 `ENGINE_READY`: ```ts // type: 'SGS_MAP_EVENT', action: 'ENGINE_READY' { engineVersion: "2.0.0", protocolVersion: 2, sdkVersion: "2.3.0", floorId: string | number, poiCount: number, hasRouteNetwork: boolean } ``` **错误响应**: N/A --- ### 2. CHANGE_FLOOR 切换当前显示楼层。触发 GPU 显存回收、状态重置和新楼层数据加载。 | 项目 | 值 | |------|---| | **postMessage action** | `CHANGE_FLOOR` | | **SDK 方法** | `sdk.changeFloor(floorId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: ```ts { floorId: string | number // 目标楼层 ID 或 floorCode(real-preview 模式支持) } ``` **成功响应**: ```ts { success: true, floorId: string | number // 实际切换到的楼层 ID } ``` **错误响应**: N/A(当前实现始终返回 success) **特殊行为**: - 若目标楼层与当前楼层相同,直接返回 success,不触发重新加载(防抖) - `real-preview` 模式下支持通过 `floorCode`(如 `"L2"`)匹配楼层 --- ### 3. FOCUS_TO 镜头聚焦到指定 POI、坐标或场景节点,支持自适应半径 FlyTo 动画。 | 项目 | 值 | |------|---| | **postMessage action** | `FOCUS_TO` | | **SDK 方法** | `sdk.focusTo(node)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**(三种模式): ```ts // 模式 1: 坐标聚焦 { type: "coord", x: number, // GLB X 坐标(米) z: number, // GLB Z 坐标(米) y?: number, // 高度,默认 0.2 radius?: number // 聚焦半径,默认 3.0 } // 模式 2: POI ID 聚焦 { type: "poiId", value: string | number // POI ID } // 模式 3: 节点名聚焦 { type: "nodeName", value: string // GLB 节点名或 POI 名称 } // 模式 4: 字符串简写 "Hall_Dinosaur" // 直接传 POI 名称字符串 ``` **成功响应**: 无显式响应(fire-and-forget 模式) **错误响应**: 无显式响应,仅 console.warn **备注**: 基座会同时在 POI 列表和讲解点列表中检索匹配项,按 `name` / `nameEn` / `id` / `guideStopId` 匹配。 --- ### 4. SET_VIEW_MODE 切换 2D 俯视 / 3D 透视模式。 | 项目 | 值 | |------|---| | **postMessage action** | `SET_VIEW_MODE` | | **SDK 方法** | `sdk.setViewMode(mode)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.3.0 | **请求 payload**: ```ts { mode: "2d" | "3d" } ``` **成功响应**: ```ts { success: true, mode: "2d" | "3d" } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_INVALID_MODE", message: "Invalid mode: . Expected '2d' or '3d'" } ``` --- ### 5. ADD_MARKER / ADD_BUSINESS_MARKER 添加业务图钉。两个 action 名共享同一处理逻辑,均可使用。 | 项目 | 值 | |------|---| | **postMessage action** | `ADD_MARKER` 或 `ADD_BUSINESS_MARKER` | | **SDK 方法** | `sdk.addMarker(config)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: ```ts { id: string, // 唯一图钉 ID(重复 id 会覆盖已有图钉) name: string, // 显示名称 iconUrl: string, // 图标 URL anchorNodeName?: string, // 可选,绑定到 GLB 场景节点 position?: [number, number, number] // [x, y, z] 世界坐标 } ``` **成功响应**: 无显式响应(fire-and-forget 模式) **错误响应**: N/A --- ### 6. REMOVE_MARKER / REMOVE_BUSINESS_MARKER 移除指定业务图钉。两个 action 名共享同一处理逻辑。 | 项目 | 值 | |------|---| | **postMessage action** | `REMOVE_MARKER` 或 `REMOVE_BUSINESS_MARKER` | | **SDK 方法** | `sdk.removeMarker(markerId)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: ```ts { markerId: string // 要移除的图钉 ID } ``` **成功响应**: 无显式响应(fire-and-forget 模式) **错误响应**: N/A --- ### 7. CLEAR_MARKERS 清空所有业务图钉。 | 项目 | 值 | |------|---| | **postMessage action** | `CLEAR_MARKERS` | | **SDK 方法** | `sdk.clearMarkers()` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: `{}` (空对象) **成功响应**: 无显式响应(fire-and-forget 模式) **错误响应**: N/A --- ### 8. PLAN_ROUTE 路径规划。支持同层和跨层 NavMesh 寻路,起终点支持 POI 名称、POI ID 和坐标三种模式。 | 项目 | 值 | |------|---| | **postMessage action** | `PLAN_ROUTE` | | **SDK 方法** | `sdk.planRoute(from, to, options?, timeout?)` / `sdk.planRouteV2(...)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: ```ts { startNode: string | SgsMapNode, // 起点(POI 名称字符串或结构化节点) endNode: string | SgsMapNode, // 终点 options?: { mode?: "walk" | "accessible", // 路线模式 wheelchair?: boolean // 无障碍路线 } } ``` 其中 `SgsMapNode`: ```ts type SgsMapNode = | { type: "coord"; floorId: string | number; x: number; z: number } | { type: "poiId"; value: string | number } | string // POI 名称 ``` **成功响应**: ```ts { success: true, distance: number, // 总距离(米) duration: number, // 预计耗时(秒) segments: Array<{ // 分段路线 floorId: string | number, transferType: "WALK" | "ELEVATOR" | "STAIRS" | "ESCALATOR", points: Array<{ x: number; y: number; z: number }>, pathGeoJson?: string }> } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_INVALID_PARAMS" | "ERR_ROUTING_FAILED", message: string } ``` --- ### 9. HIGHLIGHT_POLYGON 高亮 POI 关联的多边形边界或空间面。 | 项目 | 值 | |------|---| | **postMessage action** | `HIGHLIGHT_POLYGON` | | **SDK 方法** | `sdk.highlightPolygon(nodeName)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: ```ts { nodeName?: string, // POI/空间面名称 name?: string, // 备选字段 id?: string | number // 备选字段 } ``` **成功响应**: 无显式响应(fire-and-forget 模式) **错误响应**: N/A **备注**: 先在 POI 列表中查找(匹配 `polygonWkt`),若无结果再在空间面列表中查找(匹配 `boundaryWkt`)。 --- ### 10. CLEAR_ROUTE 清除当前导航路线。 | 项目 | 值 | |------|---| | **postMessage action** | `CLEAR_ROUTE` | | **SDK 方法** | `sdk.clearRoute()` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: `{}` (空对象) **成功响应**: ```ts { success: true } ``` **错误响应**: N/A --- ### 11. RESET_VIEW 重置相机视角,清除聚焦和高亮状态,将视角模式恢复为 3D。 | 项目 | 值 | |------|---| | **postMessage action** | `RESET_VIEW` | | **SDK 方法** | `sdk.resetView()` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: `{}` (空对象) **成功响应**: ```ts { success: true } ``` **错误响应**: N/A **备注**: 不会清除导航路线(`routeSegments`),仅重置选中 POI、聚焦目标和高亮节点。视角模式恢复为 `"3d"`。 --- ### 12. GET_STATE 获取基座当前内部状态快照。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_STATE` | | **SDK 方法** | `sdk.getState()` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: `{}` (空对象) **成功响应**: ```ts { success: true, floorId: string | number, poiCount: number, isNavActive: boolean, engineVersion: "2.0.0", routeSegments: any[], activeSegmentIndex: number, hasRouteNetwork: boolean, spatialAreas: Array<{ id: any; name: string; wkt: string }>, // mock-release 模式附加字段 envMode?: "mock-release", floorCode?: string, manifest?: { version: string; releaseId: string; totalFloors: number } | null } ``` **错误响应**: N/A --- ### 13. TOGGLE_LAYER 切换指定 POI 类型图层的显示/隐藏。 | 项目 | 值 | |------|---| | **postMessage action** | `TOGGLE_LAYER` | | **SDK 方法** | `sdk.toggleLayer(types, visible, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.5.0 | **请求 payload**: ```ts { types: string[], // POI 类型列表(如 ["TOILET", "ELEVATOR"]) visible: boolean // true = 显示, false = 隐藏 } ``` **成功响应**: ```ts { success: true, visibleTypes: string[] // 操作后的完整可见类型白名单 } ``` **错误响应**: N/A --- ### 14. SET_VISIBLE_TYPES 设置当前可见的图层类型列表(完全替换模式)。 | 项目 | 值 | |------|---| | **postMessage action** | `SET_VISIBLE_TYPES` | | **SDK 方法** | `sdk.setVisibleLayers(types, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.5.0 | **请求 payload**: ```ts { types: string[] // 可见类型列表 } ``` 特殊值语义: - `[]` → 切换为 `space` 模式(仅显示空间面) - `["space"]` → 空间面模式 - `["guide_stop"]` → 仅讲解点 - `["poi"]` → 仅 POI - 其他 → 自定义类型白名单 **成功响应**: ```ts { success: true, visibleTypes: string[] } ``` **错误响应**: N/A --- ### 15. GET_MANIFEST 获取地图 Manifest(地图名称、楼层摘要、能力声明)。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_MANIFEST` | | **SDK 方法** | `sdk.getManifest(timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: ```ts { mapId?: string | number // 地图 ID,默认 "1" } ``` **成功响应**: ```ts { success: true, mapId: string | number, mapName: string, sdkVersion: string, protocolVersion: number, dataVersion: string, updatedAt: string, coordinateSystem: string, floors: SgsSdkFloorSummary[], capabilities: { ... } } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_NETWORK" | "ERR_FAILED", message: string } ``` --- ### 16. LOAD_FLOOR_BUNDLE 一次性加载指定楼层的完整数据包(模型、POI、空间面、讲解点、路网摘要)。 | 项目 | 值 | |------|---| | **postMessage action** | `LOAD_FLOOR_BUNDLE` | | **SDK 方法** | `sdk.loadFloorBundle(floorId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: ```ts { floorId?: string | number // 目标楼层 ID,默认当前楼层 } ``` **成功响应**: ```ts { success: true, floor: { floorId, floorCode, floorName, sortOrder }, model: { modelUrl, fallbackModelUrl, compressionType, sizeBytes }, pois: SgsPoi[], spaces: SgsSpaceArea[], guideStops: SgsGuideStop[], routeSummary: { hasRouteNetwork, nodeCount, edgeCount }, hiddenSceneNodeNames: string[], dataVersion: string } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_NETWORK" | "ERR_FAILED", message: string } ``` --- ### 17. GET_FLOOR_POIS 获取指定楼层 POI 列表。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_FLOOR_POIS` | | **SDK 方法** | `sdk.getFloorPois(floorId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: ```ts { floorId?: string | number // 目标楼层 ID,默认当前楼层 } ``` **成功响应**: ```ts { success: true, pois: SgsPoi[] } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_FAILED", message: string } ``` --- ### 18. GET_POIS 获取当前楼层 POI 列表(直接返回基座内存中的 POI 数据)。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_POIS` | | **SDK 方法** | `sdk.getPois(floorCode, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 1.0.0 | **请求 payload**: `{}` (空对象) **成功响应**: ```ts { success: true, pois: any[], // 当前基座内存中的 POI 数组 floorCode: string // 当前楼层代码 } ``` **错误响应**: N/A --- ### 19. GET_SPACES 获取指定楼层空间面列表。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_SPACES` | | **SDK 方法** | `sdk.getSpaces(floorId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: ```ts { floorId?: string | number // 目标楼层 ID,默认当前楼层 } ``` **成功响应**: ```ts { success: true, spaces: SgsSpaceArea[] } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_FAILED", message: string } ``` --- ### 20. GET_GUIDE_STOPS 获取指定楼层讲解点列表。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_GUIDE_STOPS` | | **SDK 方法** | `sdk.getGuideStops(floorId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: ```ts { floorId?: string | number // 目标楼层 ID,默认当前楼层 } ``` **成功响应**: ```ts { success: true, guideStops: SgsGuideStop[] } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_FAILED", message: string } ``` --- ### 21. GET_GUIDE_STOPS_BY_HALL 按展厅 ID 获取讲解点列表。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_GUIDE_STOPS_BY_HALL` | | **SDK 方法** | `sdk.getGuideStopsByHall(hallId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: ```ts { hallId: string | number // 必填,展厅 ID } ``` **成功响应**: ```ts { success: true, guideStops: SgsGuideStop[] } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_INVALID_PARAMS", // hallId 为空时 message: "hallId 不能为空" } // 或 { code: "ERR_FAILED", message: string } ``` --- ### 22. GET_NAVIGABLE_PLACES 获取指定楼层可导航目的地列表。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_NAVIGABLE_PLACES` | | **SDK 方法** | `sdk.getNavigablePlaces(floorId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.3.0 | **请求 payload**: ```ts { floorId?: string | number // 目标楼层 ID,默认当前楼层 } ``` **成功响应**: ```ts { success: true, navigablePlaces: SgsNavigablePlace[] } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_INVALID_PARAMS", // floorId 为空时 message: "floorId 不能为空" } // 或 { code: "ERR_NETWORK" | "ERR_FAILED", message: string } ``` --- ### 23. PRELOAD_FLOOR 后台预加载指定楼层的 bundle 数据到缓存(LRU,最多缓存 2 个楼层),不切换当前视图。 | 项目 | 值 | |------|---| | **postMessage action** | `PRELOAD_FLOOR` | | **SDK 方法** | `sdk.preloadFloor(floorId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: ```ts { floorId: string | number // 必填,要预加载的楼层 ID } ``` **成功响应**: ```ts { success: true, cached: boolean, // true = 命中已有缓存, false = 新加载 loadMs?: number // 新加载时的耗时(仅 cached=false 时存在) } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_INVALID_PARAMS", // floorId 为空时 message: "floorId 不能为空" } // 或 { code: "ERR_NETWORK" | "ERR_FAILED", message: string } ``` --- ### 24. CLEAR_MODEL_CACHE 清空客户端 bundle 缓存。 | 项目 | 值 | |------|---| | **postMessage action** | `CLEAR_MODEL_CACHE` | | **SDK 方法** | `sdk.clearModelCache()` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: `{}` (空对象) **成功响应**: ```ts { success: true } ``` **错误响应**: N/A --- ### 25. GET_PERFORMANCE_STATS 获取渲染基座的性能统计数据。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_PERFORMANCE_STATS` | | **SDK 方法** | `sdk.getPerformanceStats(timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.1.0 | **请求 payload**: `{}` (空对象) **成功响应**: ```ts { success: true, currentFloorId: string | number, manifestLoadMs?: number, bundleLoadMs?: number, modelParseMs?: number, firstRenderMs?: number, dracoUsed?: boolean, fallbackUsed?: boolean } ``` **错误响应**: N/A --- ### 26. GET_DIAGNOSTICS 获取地图整体诊断信息。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_DIAGNOSTICS` | | **SDK 方法** | `sdk.getDiagnostics(timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.3.0 | **请求 payload**: ```ts { mapId?: string | number // 地图 ID,默认 "1" } ``` **成功响应**: ```ts { success: true, mapId: string | number, mapName: string, sdkVersion: string, status: "OK" | "WARN" | "ERROR", floors: SgsFloorDiagnosticsSummary[], summary: { floorCount: number, modelReadyFloorCount: number, poiCount: number, spaceCount: number, guideStopCount: number, navigablePlaceCount: number, routeNodeCount: number, routeEdgeCount: number }, warnings: string[] } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_NETWORK" | "ERR_FAILED", message: string } ``` --- ### 27. GET_FLOOR_DIAGNOSTICS 获取单个楼层的详细诊断信息。 | 项目 | 值 | |------|---| | **postMessage action** | `GET_FLOOR_DIAGNOSTICS` | | **SDK 方法** | `sdk.getFloorDiagnostics(floorId, timeout?)` | | **/engine/ 支持** | ✅ | | **最低版本** | 2.3.0 | **请求 payload**: ```ts { floorId?: string | number // 目标楼层 ID,默认当前楼层 } ``` **成功响应**: ```ts { success: true, floorId: string | number, floorCode: string, floorName: string, status: "OK" | "WARN" | "ERROR", modelReady: boolean, poiCount: number, spaceCount: number, guideStopCount: number, navigablePlaceCount: number, routeNodeCount: number, routeEdgeCount: number, routePlanningReady: boolean, warnings: string[] } ``` **错误响应**: ```ts { success: false } // error: { code: "ERR_INVALID_PARAMS", // floorId 为空时 message: "floorId 不能为空" } // 或 { code: "ERR_NETWORK" | "ERR_FAILED", message: string } ``` --- ## 基座主动事件一览 以下事件由基座通过 `SGS_MAP_EVENT` 类型主动推送,无需 SDK 请求: | 事件 action | 触发时机 | payload 关键字段 | |-------------|---------|-----------------| | `ENGINE_READY` | 引擎初始化完成 / HELLO 响应 | `engineVersion`, `protocolVersion`, `sdkVersion`, `floorId`, `poiCount`, `hasRouteNetwork` | | `ON_MODEL_LOADING` | 模型开始加载 | `floorId`, `modelUrl` | | `ON_MODEL_READY` | 模型解析完成 | `floorId`, `parseTimeMs` | | `ON_MODEL_ERROR` | 模型加载失败/超时 | `floorId`, `error`, `fallbackUsed` | | `ON_FLOOR_BUNDLE_READY` | 楼层 bundle 数据加载完成 | `floorId`, `dataVersion` | | `ON_POI_CLICK` | 用户点击 POI | `id`, `name`, `type`, `floorId` | | `ON_ROUTE_TRANSFER` | 跨楼层换乘提示 | `currentFloorId`, `targetFloorId`, `transferType` | --- ## 错误码汇总 | 错误码 | 说明 | 出现指令 | |--------|------|---------| | `ERR_INVALID_MODE` | `SET_VIEW_MODE` 参数非法 | SET_VIEW_MODE | | `ERR_INVALID_PARAMS` | 必填参数缺失或无效 | PLAN_ROUTE, GET_GUIDE_STOPS_BY_HALL, GET_NAVIGABLE_PLACES, PRELOAD_FLOOR, GET_FLOOR_DIAGNOSTICS | | `ERR_ROUTING_FAILED` | NavMesh 路径规划失败 | PLAN_ROUTE | | `ERR_NETWORK` | 后端 API 网络异常 | GET_MANIFEST, LOAD_FLOOR_BUNDLE, GET_NAVIGABLE_PLACES, PRELOAD_FLOOR, GET_DIAGNOSTICS, GET_FLOOR_DIAGNOSTICS | | `ERR_FAILED` | 通用失败 | 多个异步指令的 catch 兜底 | | `ERR_UNSUPPORTED` | 基座不支持该指令 | 未识别的 action(default 分支)、mock-release 专用指令在非 mock 模式下调用 | --- ## 版本演进 | 版本 | 新增 action | |------|------------| | 1.0.0 | HELLO, CHANGE_FLOOR, FOCUS_TO, ADD_MARKER, ADD_BUSINESS_MARKER, REMOVE_MARKER, REMOVE_BUSINESS_MARKER, CLEAR_MARKERS, PLAN_ROUTE, HIGHLIGHT_POLYGON, CLEAR_ROUTE, RESET_VIEW, GET_STATE, GET_POIS | | 1.5.0 | TOGGLE_LAYER, SET_VISIBLE_TYPES | | 2.1.0 | GET_MANIFEST, LOAD_FLOOR_BUNDLE, GET_FLOOR_POIS, GET_SPACES, GET_GUIDE_STOPS, GET_GUIDE_STOPS_BY_HALL, PRELOAD_FLOOR, CLEAR_MODEL_CACHE, GET_PERFORMANCE_STATS | | 2.3.0 | SET_VIEW_MODE, GET_NAVIGABLE_PLACES, GET_DIAGNOSTICS, GET_FLOOR_DIAGNOSTICS |