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

10 KiB
Raw Blame History

SGS Map SDK 快速接入指南

本项目同步版本: V2.5.0 | 支持终端: H5 浏览器、大屏终端、微信小程序

发布源保留了 V2.3.0 文档标题和历史 API 注释;实际发行版本以 package.jsondist 产物自报的 2.5.0 为准。本文只同步其公开接入资料,不声明未经本项目验证的 iframe renderer 能力。

1. 引入方式

SDK 提供多种模块规范的产出文件,适配不同的应用场景:

1.1 Script 标签引入 (浏览器直连)

dist/index.global.jsIIFE 格式)通过 <script> 标签引入SDK 会挂载全局变量 window.SGSMapSDK

<script src="./dist/index.global.js"></script>
<script>
  const sdk = new SGSMapSDK({ ... });
</script>

如果 SDK 已由 sgs-frontend-map 发布到前端静态目录,也可以直接使用浏览器发布文件:

<script src="/sdk/sgs-map-sdk.min.js?v=2.5.0"></script>

1.2 ESM Import (Webpack / Vite / Next.js)

在现代前端工程中,直接使用 ESM 格式:

import SGSMapSDK from 'path/to/sdk/index.mjs';

const sdk = new SGSMapSDK({ ... });

1.3 微信小程序 WebView 接入

在微信小程序中,无需引入外壳 SDK直接通过 web-view 组件加载地图基座,并通过 URL 传递参数。

<!-- 小程序 WXML -->
<web-view src="https://map.museum.com/engine/index.html?floorId=1&mode=miniapp"></web-view>

1.4 渲染基座地址

SDK 通过 sdkUrl 连接独立渲染基座。正式接入时请使用地图服务平台管理员提供的基座地址,例如:

https://map.museum.com/engine/index.html

发布包内附带 demo/ 目录,是一个完整的 SDK 能力展示页面。运行方式:

# 在 sgs-map-sdk-release 根目录下
npx -y serve . -l 5555
# 浏览器打开(?server= 指向运行中的地图服务)
# http://localhost:5555/demo/?server=http://localhost:3001

2. 初始化与生命周期

2.1 创建实例

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 事件触发后调用。

map.on('ready', (info) => {
  console.log('地图引擎加载完成', info.engineVersion);
  // 现在可以安全调用 API 了
});

2.3 销毁实例

当页面卸载时,为了避免内存泄漏,必须调用 destroy()

// 清除 DOM、注销所有监听事件并拒绝所有挂起的异步调用
map.destroy();

3. 常用场景 API

3.1 楼层切换

切换楼层是异步SDK 会在后台销毁旧楼层 WebGL 显存,并加载新楼层模型。

map.changeFloor(3).then((res) => {
  console.log("成功切换至楼层: ", res.floorId);
}).catch(err => {
  console.error("切换失败: ", err.message);
});

3.2 搜索与对焦

当用户在搜索栏查找到具体要素后,使镜头平滑飞至要素上方:

// 通过 POI ID 对焦(推荐)
map.focusTo({ type: 'poiId', value: 10102 });

// 通过三维节点名称对焦
map.focusTo({ type: 'nodeName', value: 'Hall_DomeTheater' });

3.3 路线导航

起点与终点均支持绝对坐标或 POI ID。

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 事件。

map.on('poiClick', (poi) => {
  console.log(`用户点击了:${poi.name} (ID: ${poi.poiId})`);
  // 业务侧可在此处弹出底部展品详情栏或抽屉
});

3.5 动态撒图钉 (Marker)

// 添加一个悬浮图标
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

获取地图元数据(楼层列表、地图名称、版本信息等),是初始化后的第一步。

map.getManifest().then((manifest) => {
  console.log('地图名称:', manifest.mapName);
  console.log('楼层列表:', manifest.floors);
  // manifest.floors => [{ id: 1, name: 'F1', ... }, { id: 2, name: 'F2', ... }]
});

加载楼层 Bundle

一次性拉取楼层的模型、POI、空间面和讲解点数据适合需要预加载全部数据的场景。

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 列表、空间面列表、讲解点列表。

// 获取楼层 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”并过滤纯电梯、楼梯、扶梯等交通设施本体。

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)

发布前或接入异常时,可先调用诊断接口确认地图数据是否完整。

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 的模型资源,切换时无需等待。

// 预加载 F2不切换视图
map.preloadFloor(2).then(() => {
  console.log('F2 模型预加载完成,切换时将秒开');
});

模型加载生命周期事件

监控模型加载全过程,实现自定义 Loading UI。

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 返回,还可以通过事件监听获取路径结果。

map.on('routeReady', ({ routeId, distance, duration }) => {
  console.log(`路线 ${routeId} 规划完成`);
  console.log(`路径总长 ${distance}m, 预计 ${duration}s`);
});

性能监控

获取当前渲染性能统计,便于排查性能问题。

map.getPerformanceStats().then((stats) => {
  console.log('FPS:', stats.fps);
  console.log('DrawCalls:', stats.drawCalls);
  console.log('纹理内存:', stats.textureMemoryMB, 'MB');
  console.log('几何体内存:', stats.geometryMemoryMB, 'MB');
});

清空模型缓存

当需要强制刷新模型(如模型更新后),可清空本地缓存。

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 数据不完整(部分资源缺失)