Files
frontend-miniapp/static/sgs-map-sdk/sdk-api-reference.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

665 lines
17 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 API Reference
> 本项目同步版本: V2.5.0
> 适用对象: 第三方 H5、大屏、Kiosk、业务前端开发人员
> 发布源保留了 V2.3.0 文档标题和历史 API 注释;实际发行版本以 `package.json` 与 `dist` 产物自报的 2.5.0 为准。本文不表示本项目已经接入或验证 SDK iframe renderer。
本文档按公开 SDK 方法组织,说明初始化参数、事件、常用 API、返回值和错误处理。快速接入请先阅读 `sdk-quickstart.md`,底层通信协议请阅读 `sdk-protocol.md`
## 1. 接入入口
### Script 标签
```html
<script src="./dist/index.global.js"></script>
<script>
const map = new SGSMapSDK({
container: 'map-container',
sdkUrl: 'https://map.example.com/engine/index.html',
targetOrigin: 'https://map.example.com',
floorId: 1
});
</script>
```
如果 SDK 已随 `sgs-frontend-map` 发布到静态目录:
```html
<script src="/sdk/sgs-map-sdk.min.js?v=2.5.0"></script>
```
### ESM
```ts
import SGSMapSDK from './dist/index.mjs';
const map = new SGSMapSDK({
container: document.getElementById('map-container')!,
sdkUrl: 'https://map.example.com/engine/index.html',
targetOrigin: 'https://map.example.com',
floorId: 1
});
```
## 2. 初始化配置
```ts
interface SGSMapSDKOptions {
container: string | HTMLElement;
sdkUrl?: string;
targetOrigin?: string;
floorId?: string | number;
mapId?: string | number;
timeout?: number;
readyTimeout?: number;
}
```
| 字段 | 必填 | 默认值 | 说明 |
|------|------|--------|------|
| `container` | 是 | 无 | 地图 iframe 挂载容器,可传 DOM id 或 HTMLElement |
| `sdkUrl` | 否 | `/engine/index.html` | 独立发布的 SDK 渲染引擎地址 |
| `targetOrigin` | 否 | 从 `sdkUrl` 推导 | `postMessage` 安全通信域,生产环境建议显式填写 |
| `floorId` | 否 | `1` | 初始楼层 ID支持字符串或数字 |
| `mapId` | 否 | `1` | 地图 ID当前由 SDK 实例保存 |
| `timeout` | 否 | `5000` | 普通命令超时时间,单位 ms |
| `readyTimeout` | 否 | `30000` | 等待 `ENGINE_READY` 的最大时间,单位 ms |
生产环境必须保证 `sdkUrl` 可访问,并且 `targetOrigin``sdkUrl` 的 Origin 一致。
## 3. 生命周期
### `whenReady(): Promise<any>`
等待地图引擎 ready。所有需要基座响应的 API 建议在 ready 后调用。
```ts
await map.whenReady();
await map.changeFloor(2);
```
### `ready(): Promise<any>`
`whenReady()` 的别名。
### `getIsReady(): boolean`
返回 SDK 是否已收到基座 `ENGINE_READY`
### `destroy(): void`
销毁 SDK 实例,清理 iframe、事件监听和所有挂起 Promise。销毁后再调用异步命令会返回 `ERR_DESTROYED`
```ts
window.addEventListener('beforeunload', () => {
map.destroy();
});
```
## 4. 状态查询
### `getCurrentFloor(): string | number`
返回 SDK 当前记录的楼层 ID。
### `getMapId(): string | number`
返回初始化时设置的 `mapId`
### `getVersion(): string`
返回 SDK 版本号;本项目同步的 2.5.0 Bridge 返回 `"2.5.0"`
### `getState(): Promise<any>`
向渲染基座查询内部状态。主要用于调试或 Demo 面板。
```ts
const state = await map.getState();
console.log(state);
```
## 5. 地图控制
### `changeFloor(floorId, timeout?): Promise<{ success: boolean; floorId: string | number }>`
切换楼层。成功后 SDK 内部当前楼层会同步更新。
```ts
await map.changeFloor(2);
```
### `focusTo(node): void`
镜头聚焦到 POI、GLB 节点或坐标。
```ts
map.focusTo({ type: 'poiId', value: 10001 });
map.focusTo({ type: 'nodeName', value: 'Hall_Dinosaur' });
map.focusTo({ type: 'coord', floorId: 1, x: 12.5, z: -8.2 });
map.focusTo('Hall_Dinosaur');
```
`SgsMapNode` 类型:
```ts
type SgsMapNode =
| { type: 'coord'; floorId: string | number; x: number; z: number; y?: number }
| { type: 'poiId'; value: string | number }
| { type: 'nodeName'; value: string };
```
坐标统一使用 GLB/Three.js 米制坐标,水平面为 `x/z`,高度为 `y`
### `resetView(): void`
重置相机视角。
### `setViewMode(mode): void`
切换 2D/3D 模式。
```ts
map.setViewMode('2d');
map.setViewMode('3d');
```
### `highlightPolygon(nodeName): void`
高亮指定 3D 场景节点对应的空间轮廓。
```ts
map.highlightPolygon('Hall_Area_01');
```
## 6. 图层控制
### `toggleLayer(types, visible, timeout?): Promise<{ success: boolean; visibleTypes: string[] }>`
批量控制指定类型图层的显示隐藏。
```ts
await map.toggleLayer(['TOILET', 'ELEVATOR'], true);
await map.toggleLayer(['STAIRS'], false);
```
### `setVisibleLayers(types, timeout?): Promise<{ success: boolean; visibleTypes: string[] }>`
设置当前可见的图层类型列表。
```ts
await map.setVisibleLayers(['TOILET', 'ELEVATOR', 'SERVICE_DESK']);
```
## 7. 图钉 Marker
### `addMarker(config): void`
添加业务图钉。
```ts
map.addMarker({
id: 'user-location',
name: '我的位置',
iconUrl: 'https://example.com/avatar.png',
position: { x: 10, y: 1.6, z: -5 }
});
```
`MarkerConfig`
```ts
interface MarkerConfig {
id: string;
name?: string;
iconUrl?: string;
anchorNodeName?: string;
position?: [number, number, number] | { x: number; y: number; z: number };
}
```
### `removeMarker(markerId): void`
移除指定图钉。
```ts
map.removeMarker('user-location');
```
### `clearMarkers(): void`
清空所有业务图钉。
## 8. 路径规划
### `planRoute(from, to, options?, timeout?): Promise<RouteResult>`
规划路线,兼容字符串节点名和结构化节点。
```ts
const route = await map.planRoute(
{ type: 'poiId', value: 8001 },
{ type: 'poiId', value: 9005 },
{ mode: 'walk' }
);
if (route.success) {
console.log(route.distance, route.duration, route.pathPoints);
}
```
也可传节点名:
```ts
await map.planRoute('一楼南卫生间', '生态大展区');
```
### `planRouteV2(from, to, options?, timeout?): Promise<RouteResult>`
结构化参数版本。当前底层同样发送 `PLAN_ROUTE` 指令。
```ts
await map.planRouteV2(
{ type: 'coord', floorId: 1, x: 0, z: 0 },
{ type: 'coord', floorId: 1, x: 12, z: -6 },
{ mode: 'accessible' }
);
```
### `clearRoute(): void`
清除当前路线。
```ts
map.clearRoute();
```
`RouteResult` 主要字段:
```ts
interface RouteResult {
success: boolean;
distance: number;
duration: number;
pathPoints: Array<{ x: number; y: number; z: number }>;
computeTimeMs: number;
warnings: string[];
errorCode?: string;
message?: string;
}
```
## 9. 地图数据 API
### `getManifest(timeout?): Promise<SgsSdkManifest>`
获取地图 Manifest包含地图名称、楼层摘要、能力声明和版本信息。
```ts
const manifest = await map.getManifest();
console.log(manifest.mapName, manifest.sdkVersion, manifest.floors);
```
### `loadFloorBundle(floorId, timeout?): Promise<SgsFloorBundle>`
一次性加载指定楼层的模型、POI、空间面、讲解点和路网摘要。
```ts
const bundle = await map.loadFloorBundle(1);
console.log(bundle.model.modelUrl);
console.log(bundle.pois.length, bundle.spaces.length, bundle.guideStops.length);
```
### `getFloorPois(floorId, timeout?): Promise<SgsPoi[]>`
获取指定楼层 POI 列表。
```ts
const pois = await map.getFloorPois(1);
pois.forEach(poi => console.log(poi.name, poi.type, poi.position));
```
### `getPois(floorCode, timeout?): Promise<SgsPoi[]>`
按楼层代码获取 POI 列表。该方法用于兼容既有基座能力,推荐新接入优先使用 `getFloorPois(floorId)`
```ts
const pois = await map.getPois('L1');
```
### `getSpaces(floorId, timeout?): Promise<SgsSpaceArea[]>`
获取指定楼层空间面列表。
```ts
const spaces = await map.getSpaces(1);
spaces.forEach(space => console.log(space.name, space.boundaryWkt));
```
### `getGuideStops(floorId, timeout?): Promise<SgsGuideStop[]>`
获取指定楼层已标定讲解点列表。
```ts
const stops = await map.getGuideStops(1);
stops.forEach(stop => console.log(stop.name, stop.audioUrl));
```
### `getGuideStopsByHall(hallId, timeout?): Promise<SgsGuideStop[]>`
获取指定展厅下的讲解点列表。
```ts
const stops = await map.getGuideStopsByHall('hall-001');
```
### `preloadFloor(floorId, timeout?): Promise<{ cached: boolean }>`
后台预加载指定楼层模型资源,不切换当前视图。
```ts
await map.preloadFloor(2);
```
### `clearModelCache(): void`
清空客户端模型缓存。
```ts
map.clearModelCache();
```
### `getNavigablePlaces(floorId, timeout?): Promise<SgsNavigablePlace[]>`
获取指定楼层的可导航目的地列表v2.3.0+)。
```ts
const places = await map.getNavigablePlaces(1);
places.forEach(place => console.log(place.name, place.category));
```
## 10. 诊断接口 (v2.3.0+)
### `getDiagnostics(timeout?): Promise<SgsMapDiagnostics>`
获取地图整体诊断信息,包含所有楼层摘要和汇总统计。用于检查数据完整性和就绪状态。
```ts
const diagnostics = await map.getDiagnostics();
console.log('地图状态:', diagnostics.status);
console.log('楼层总数:', diagnostics.summary.floorCount);
console.log('POI总数:', diagnostics.summary.poiCount);
console.log('可导航目的地总数:', diagnostics.summary.navigablePlaceCount);
// 检查警告信息
if (diagnostics.warnings.length > 0) {
console.warn('诊断警告:', diagnostics.warnings);
}
// 遍历楼层摘要
diagnostics.floors.forEach(floor => {
console.log(`${floor.floorName}: ${floor.status}, 可导航点=${floor.navigablePlaceCount}`);
});
```
**返回结构**:
```ts
interface SgsMapDiagnostics {
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[];
}
```
### `getFloorDiagnostics(floorId, timeout?): Promise<SgsFloorDiagnostics>`
获取单个楼层的详细诊断信息。
```ts
const floorDiag = await map.getFloorDiagnostics(1);
console.log('楼层状态:', floorDiag.status);
console.log('模型就绪:', floorDiag.modelReady);
console.log('路径规划就绪:', floorDiag.routePlanningReady);
console.log('POI数量:', floorDiag.poiCount);
console.log('可导航目的地:', floorDiag.navigablePlaceCount);
```
**返回结构**:
```ts
interface SgsFloorDiagnostics {
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[];
}
```
**使用场景**:
- 应用启动时检查地图数据是否完整
- 排查路径规划失败原因(检查 routePlanningReady
- 监控数据发布后的就绪状态
- 生成数据健康报告
## 11. 性能监控
### `getPerformanceStats(timeout?): Promise<SgsPerformanceStats>`
获取 SDK 与渲染基座的性能统计。v2.3.0 保持合并 SDK 自身耗时与基座返回的模型加载耗时。
```ts
const stats = await map.getPerformanceStats();
console.table({
sdkReady: stats.engineReadyMs,
iframeDom: stats.iframeDomReadyMs,
manifest: stats.manifestLoadMs,
bundle: stats.bundleLoadMs ?? 'N/A',
model: stats.modelDownloadAndParseMs,
firstRender: stats.firstRenderMs
});
```
主要字段:
| 字段 | 说明 |
|------|------|
| `sdkCreatedAt` | SDK 实例创建时间戳 |
| `iframeDomReadyMs` | iframe DOM 加载完成耗时 |
| `engineReadyMs` | 地图引擎 ready 耗时 |
| `manifestLoadMs` | Manifest 加载耗时 |
| `bundleLoadMs` | Bundle 加载耗时,未触发时可能为空 |
| `modelDownloadMs` | 模型下载耗时 |
| `modelDownloadAndParseMs` | 模型下载与解析总耗时 |
| `modelParseMs` | 模型解析耗时 |
| `firstRenderMs` | 首帧渲染耗时 |
| `routePlanMs` | 路径规划耗时 |
| `dracoUsed` | 是否使用 Draco 压缩模型 |
| `fallbackUsed` | 是否使用 fallback 原始模型 |
| `currentFloorId` | 当前楼层 ID |
## 11. 事件
SDK 继承事件能力,可通过 `on(eventName, handler)` 监听事件。
```ts
map.on('ready', (info) => {
console.log('ready', info.engineVersion, info.protocolVersion);
});
map.on('poiClick', (poi) => {
console.log('poi clicked', poi.id, poi.name);
});
```
| 事件名 | Payload | 说明 |
|--------|---------|------|
| `ready` | `{ engineVersion, protocolVersion }` | 基座完全挂载,可安全调用 API |
| `poiClick` | `{ id, name, type, floorId?, description? }` | 用户点击 POI |
| `floorChanged` | `{ floorId }` | 楼层切换完成 |
| `error` | `{ code, message }` | 基座或 SDK 异常 |
| `loadError` | `{ type, detail }` | 资源加载异常 |
| `routeTransfer` | `{ currentFloorId, targetFloorId, transferType, ... }` | 跨楼层换乘提示 |
| `modelLoading` | `{ floorId, modelUrl }` | 模型开始加载 |
| `modelReady` | `{ floorId, parseTimeMs }` | 模型解析完成 |
| `modelError` | `{ floorId, error, fallbackUsed }` | 模型加载失败 |
| `floorBundleReady` | `{ floorId, dataVersion }` | 楼层 Bundle 数据加载完成 |
| `routeReady` | `{ routeId, distance, duration }` | 路径规划完成 |
## 12. 常用类型摘要
### `SgsSdkManifest`
```ts
interface SgsSdkManifest {
mapId: string | number;
mapName: string;
sdkVersion: string;
protocolVersion: number;
dataVersion: string;
updatedAt: string;
coordinateSystem: string;
floors: SgsSdkFloorSummary[];
capabilities: {
dracoCompression: boolean;
routePlanning: boolean;
spatialQuery: boolean;
guideStops: boolean;
// v2.3.0 新增标准能力字段
mapLoading?: boolean;
floorSwitching?: boolean;
poiQuery?: boolean;
spaceQuery?: boolean;
navigablePlaces?: boolean;
crossFloorRoute?: boolean;
accessibleRoute?: boolean;
highlight?: boolean;
diagnostics?: boolean;
};
}
```
### `SgsPoi`
```ts
interface SgsPoi {
id: string | number;
name: string;
type: string;
typeName: string;
floorCode: string;
position: { x: number; y: number; z: number };
status: 'ACTIVE' | 'INACTIVE';
anchorNodeName?: string | null;
description?: string;
iconUrl?: string;
}
```
### `SgsSpaceArea`
```ts
interface SgsSpaceArea {
id: string | number;
name: string;
type: string;
floorId: string | number;
boundaryWkt: string;
center: { x: number; y: number; z: number };
sourceNodeName?: string;
status: 'ACTIVE' | 'INACTIVE';
colorHex?: string;
}
```
### `SgsGuideStop`
```ts
interface SgsGuideStop {
id: string | number;
name: string;
type: string;
floorId: string | number;
position: { x: number; y: number; z: number };
targetType: string;
targetId?: string | number;
audioUrl?: string;
coverImageUrl?: string;
description?: string;
status: 'ACTIVE' | 'INACTIVE';
hallId?: string | number;
hallName?: string;
}
```
完整类型以 `dist/index.d.ts` 为准。
## 13. 错误处理
所有 Promise API 失败时会 reject 一个 `{ code, message }` 结构。
```ts
try {
await map.changeFloor(999);
} catch (err) {
console.warn(err.code, err.message);
}
```
| 错误码 | 说明 |
|--------|------|
| `ERR_TIMEOUT` | 命令响应超时 |
| `ERR_READY_TIMEOUT` | ready 超时,基座未发出 `ENGINE_READY` |
| `ERR_NOT_READY` | SDK ready 失败后继续调用命令 |
| `ERR_DESTROYED` | SDK 实例已销毁 |
| `ERR_IFRAME_LOAD` | iframe 加载失败 |
| `ERR_UNAUTHORIZED` | Origin 校验失败 |
| `ERR_UNSUPPORTED` | 当前基座不支持该命令 |
| `ERR_NO_PATH` | 路径规划无可达路线 |
| `ERR_FLOOR_NOT_FOUND` | 楼层不存在或未发布 |
| `ERR_NETWORK` | 网络或接口异常 |
## 14. 废弃方法
以下方法保留签名用于兼容旧接入方,新项目不要使用:
| 方法 | 状态 | 替代方案 |
|------|------|----------|
| `getReleaseManifest()` | 已废弃,返回 `ERR_UNSUPPORTED` | `getManifest()` |
| `getModelResources()` | 已废弃,返回 `ERR_UNSUPPORTED` | `loadFloorBundle()` |
| `getLayerTree()` | 已废弃,返回 `ERR_UNSUPPORTED` | 暂无 |
| `loadMockReleaseRoute()` | 已废弃,返回 `ERR_UNSUPPORTED` | `planRoute()` |
## 15. 第三方接入检查清单
- 页面中存在 SDK 挂载容器,且容器有稳定宽高。
- `sdkUrl` 可在浏览器直接访问,并能加载独立发布的 `/engine/index.html`
- `targetOrigin``sdkUrl` 的 Origin 一致。
- 所有地图控制 API 在 `await map.whenReady()` 后调用。
- 坐标统一使用 GLB/Three.js 米制坐标,水平面为 `x/z`
- 页面卸载时调用 `map.destroy()`
- 生产发布时 SDK、Engine 与后端 Manifest 的 `sdkVersion` 必须保持兼容;本次 Bridge 为 `2.5.0`,上线前需验证 `/engine/index.html` 真实加载 SDK Engine 并完成 `HELLO` -> `ENGINE_READY`