# SGS Map SDK 快速接入指南 > 版本: V2.3.0 | 支持终端: H5 浏览器、大屏终端、微信小程序 ## 1. 引入方式 SDK 提供多种模块规范的产出文件,适配不同的应用场景: ### 1.1 Script 标签引入 (浏览器直连) 将 `dist/index.global.js`(IIFE 格式)通过 ` ``` 如果 SDK 已由 `sgs-frontend-map` 发布到前端静态目录,也可以直接使用浏览器发布文件: ```html ``` ### 1.2 ESM Import (Webpack / Vite / Next.js) 在现代前端工程中,直接使用 ESM 格式: ```javascript import SGSMapSDK from 'path/to/sdk/index.mjs'; const sdk = new SGSMapSDK({ ... }); ``` ### 1.3 微信小程序 WebView 接入 在微信小程序中,无需引入外壳 SDK,直接通过 `web-view` 组件加载地图基座,并通过 URL 传递参数。 ```html ``` ### 1.4 渲染基座地址 SDK 通过 `sdkUrl` 连接独立渲染基座。正式接入时请使用地图服务平台管理员提供的基座地址,例如: ```text https://map.museum.com/h5-sdk ``` 本 SDK 发布包不附带产品化 Demo。Demo 将作为独立交付物在后续版本中重构,不作为当前 SDK 接入前置条件。 --- ## 2. 初始化与生命周期 ### 2.1 创建实例 ```javascript const map = new SGSMapSDK({ container: 'map-container', // 挂载的 DOM 容器 ID sdkUrl: 'https://map.museum.com/h5-sdk', // 渲染基座的 URL targetOrigin: 'https://map.museum.com', // [重要] 安全防范,配置只允许该域名通信 floorId: 1, // 初始楼层 ID timeout: 5000 // API 调用的默认超时时间(毫秒) }); ``` ### 2.2 等待就绪事件 **重要:** SDK 的所有控制指令(如聚焦、寻路等)必须在 `ready` 事件触发后调用。 ```javascript map.on('ready', (info) => { console.log('地图引擎加载完成', info.engineVersion); // 现在可以安全调用 API 了 }); ``` ### 2.3 销毁实例 当页面卸载时,为了避免内存泄漏,必须调用 `destroy()`。 ```javascript // 清除 DOM、注销所有监听事件并拒绝所有挂起的异步调用 map.destroy(); ``` --- ## 3. 常用场景 API ### 3.1 楼层切换 切换楼层是**异步**的,SDK 会在后台销毁旧楼层 WebGL 显存,并加载新楼层模型。 ```javascript map.changeFloor(3).then((res) => { console.log("成功切换至楼层: ", res.floorId); }).catch(err => { console.error("切换失败: ", err.message); }); ``` ### 3.2 搜索与对焦 当用户在搜索栏查找到具体要素后,使镜头平滑飞至要素上方: ```javascript // 通过 POI ID 对焦(推荐) map.focusTo({ type: 'poiId', value: 10102 }); // 通过三维节点名称对焦 map.focusTo({ type: 'nodeName', value: 'Hall_DomeTheater' }); ``` ### 3.3 路线导航 起点与终点均支持绝对坐标或 POI ID。 ```javascript map.planRoute( { type: 'poiId', value: 8001 }, // 起点 { type: 'poiId', value: 9005 }, // 终点 { mode: 'walk' } // 选项:walk 或 accessible(无障碍) ).then((result) => { if (result.success) { console.log(`路径规划成功:总距离 ${result.distance} 米,预计步行 ${result.duration} 秒`); // 基座会自动在 3D 场景中渲染青色流光折线 } }).catch(err => { if (err.code === 'ERR_NO_PATH') { alert("抱歉,无法找到可达的路线。"); } }); // 清除路线 map.clearRoute(); ``` ### 3.4 响应 POI 点击 游客在三维场景中点击任意可交互物体时,SDK 会派发 `poiClick` 事件。 ```javascript map.on('poiClick', (poi) => { console.log(`用户点击了:${poi.name} (ID: ${poi.poiId})`); // 业务侧可在此处弹出底部展品详情栏或抽屉 }); ``` ### 3.5 动态撒图钉 (Marker) ```javascript // 添加一个悬浮图标 map.addMarker({ markerId: 'marker-user-1', anchorNodeName: 'Hall_Dinosaur', imageUrl: 'https://domain.com/user-avatar.png', width: 64, height: 64, yOffset: 2 // 悬浮于物体上方 2 米 }); // 清除图钉 map.removeMarker('marker-user-1'); map.clearMarkers(); ``` --- ## 核心数据 API (v2.2.0+ / v2.3.0 兼容) ### 获取地图 Manifest 获取地图元数据(楼层列表、地图名称、版本信息等),是初始化后的第一步。 ```javascript map.getManifest().then((manifest) => { console.log('地图名称:', manifest.mapName); console.log('楼层列表:', manifest.floors); // manifest.floors => [{ id: 1, name: 'F1', ... }, { id: 2, name: 'F2', ... }] }); ``` ### 加载楼层 Bundle 一次性拉取楼层的模型、POI、空间面和讲解点数据,适合需要预加载全部数据的场景。 ```javascript map.loadFloorBundle(1).then((bundle) => { console.log('模型:', bundle.model); console.log('POI 数量:', bundle.pois.length); console.log('空间面数量:', bundle.spaces.length); console.log('讲解点数量:', bundle.guideStops.length); }); // 监听 Bundle 就绪事件 map.on('floorBundleReady', (data) => { console.log(`楼层 ${data.floorId} Bundle 就绪,数据版本: ${data.dataVersion}`); }); ``` ### 查询楼层数据 分别获取 POI 列表、空间面列表、讲解点列表。 ```javascript // 获取楼层 POI 列表 const pois = await map.getFloorPois(1); pois.forEach(poi => console.log(poi.name, poi.type)); // 获取空间面列表(展厅/分区) const spaces = await map.getSpaces(1); spaces.forEach(s => console.log(s.name, s.area)); // 获取讲解点列表 const guideStops = await map.getGuideStops(1); guideStops.forEach(stop => console.log(stop.title, stop.audioUrl)); ``` ### 获取可导航目的地 (v2.3.0) 获取指定楼层可用于路线规划的候选目的地。该列表会优先返回业务门点(例如“快餐店 出入口 1”),并过滤纯电梯、楼梯、扶梯等交通设施本体。 ```javascript const places = await map.getNavigablePlaces(2065808921012072449); places.forEach(place => { console.log(place.name, place.category, place.x, place.z, place.ownerName); }); ``` ### SDK 诊断接口 (v2.3.0) 发布前或接入异常时,可先调用诊断接口确认地图数据是否完整。 ```javascript const mapDiag = await map.getDiagnostics(); console.log('地图状态:', mapDiag.status); console.log('楼层数量:', mapDiag.summary.floorCount); console.log('POI 数量:', mapDiag.summary.poiCount); console.log('可导航目的地:', mapDiag.summary.navigablePlaceCount); const floorDiag = await map.getFloorDiagnostics(2065808921578303490); console.log('楼层状态:', floorDiag.status); console.log('路网节点:', floorDiag.routeNodeCount); console.log('路网边:', floorDiag.routeEdgeCount); ``` ### 预加载楼层 在用户当前浏览 F1 时,后台静默预加载 F2 的模型资源,切换时无需等待。 ```javascript // 预加载 F2(不切换视图) map.preloadFloor(2).then(() => { console.log('F2 模型预加载完成,切换时将秒开'); }); ``` ### 模型加载生命周期事件 监控模型加载全过程,实现自定义 Loading UI。 ```javascript map.on('modelLoading', ({ floorId, modelUrl }) => { showLoadingSpinner(`正在加载楼层 ${floorId} 模型...`); console.log('模型地址:', modelUrl); }); map.on('modelReady', ({ floorId, parseTimeMs }) => { hideLoadingSpinner(); console.log(`楼层 ${floorId} 模型就绪,解析耗时 ${parseTimeMs}ms`); }); map.on('modelError', ({ floorId, error, fallbackUsed }) => { hideLoadingSpinner(); if (fallbackUsed) { console.warn(`楼层 ${floorId} Draco 解码失败,已回退原始 GLB`); } else { console.error(`楼层 ${floorId} 模型加载失败:`, error); } }); ``` ### 路径规划完成事件 除了 `planRoute` 的 Promise 返回,还可以通过事件监听获取路径结果。 ```javascript map.on('routeReady', ({ routeId, distance, duration }) => { console.log(`路线 ${routeId} 规划完成`); console.log(`路径总长 ${distance}m, 预计 ${duration}s`); }); ``` ### 性能监控 获取当前渲染性能统计,便于排查性能问题。 ```javascript map.getPerformanceStats().then((stats) => { console.log('FPS:', stats.fps); console.log('DrawCalls:', stats.drawCalls); console.log('纹理内存:', stats.textureMemoryMB, 'MB'); console.log('几何体内存:', stats.geometryMemoryMB, 'MB'); }); ``` ### 清空模型缓存 当需要强制刷新模型(如模型更新后),可清空本地缓存。 ```javascript map.clearModelCache().then(() => { console.log('模型缓存已清空,下次加载将从服务端重新拉取'); }); ``` --- ## 4. 错误处理 SDK 采用 Promise 风格的异步响应,所有 `catch` 捕获的错误都遵循 `{ code, message }` 格式。 | 错误码 | 触发场景 | |--------|----------| | `ERR_TIMEOUT` | 网络拥塞或基座无响应,超出了构造时设置的超时时间 | | `ERR_NOT_READY` | 在 `ready` 事件触发前,强行调用了 API | | `ERR_NO_PATH` | 起点与终点之间没有连通的 NavMesh 物理网格 | | `ERR_UNAUTHORIZED` | 通信双方跨域安全策略 (`targetOrigin`) 校验失败 | | `ERR_FLOOR_NOT_FOUND` | 指定的楼层 ID 不存在或未发布 | | `ERR_MODEL_LOAD` | 模型文件加载失败(网络异常或文件损坏) | | `ERR_DRACO_DECODE` | Draco 压缩模型解码失败(已自动回退原始 GLB) | | `ERR_BUNDLE_INCOMPLETE` | 楼层 Bundle 数据不完整(部分资源缺失) |