Files
frontend-miniapp/static/sgs-map-sdk/sdk-quickstart.md
lyf 72885b7f54
Some checks failed
CI / verify (push) Has been cancelled
升级 SGS Map SDK 至 2.5.0
2026-07-16 09:43:52 +08:00

327 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SGS Map SDK 快速接入指南
> 本项目同步版本: V2.5.0 | 支持终端: H5 浏览器、大屏终端、微信小程序
> 发布源保留了 V2.3.0 文档标题和历史 API 注释;实际发行版本以 `package.json` 与 `dist` 产物自报的 2.5.0 为准。本文只同步其公开接入资料,不声明未经本项目验证的 iframe renderer 能力。
## 1. 引入方式
SDK 提供多种模块规范的产出文件,适配不同的应用场景:
### 1.1 Script 标签引入 (浏览器直连)
`dist/index.global.js`IIFE 格式)通过 `<script>` 标签引入SDK 会挂载全局变量 `window.SGSMapSDK`
```html
<script src="./dist/index.global.js"></script>
<script>
const sdk = new SGSMapSDK({ ... });
</script>
```
如果 SDK 已由 `sgs-frontend-map` 发布到前端静态目录,也可以直接使用浏览器发布文件:
```html
<script src="/sdk/sgs-map-sdk.min.js?v=2.5.0"></script>
```
### 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
<!-- 小程序 WXML -->
<web-view src="https://map.museum.com/engine/index.html?floorId=1&mode=miniapp"></web-view>
```
### 1.4 渲染基座地址
SDK 通过 `sdkUrl` 连接独立渲染基座。正式接入时请使用地图服务平台管理员提供的基座地址,例如:
```text
https://map.museum.com/engine/index.html
```
发布包内附带 `demo/` 目录,是一个完整的 SDK 能力展示页面。运行方式:
```bash
# 在 sgs-map-sdk-release 根目录下
npx -y serve . -l 5555
# 浏览器打开(?server= 指向运行中的地图服务)
# http://localhost:5555/demo/?server=http://localhost:3001
```
---
## 2. 初始化与生命周期
### 2.1 创建实例
```javascript
const map = new SGSMapSDK({
container: 'map-container', // 挂载的 DOM 容器 ID
sdkUrl: 'https://map.museum.com/engine/index.html', // 独立渲染引擎 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 数据不完整(部分资源缺失) |