修复 SGS SDK 导览数据源与模型加载

升级 SDK API 数据契约,补齐 guideStops、业务 POI、诊断与路线数据接口。

修复 SDK 模式下 POI/模型/楼层混用静态数据的问题,并为 ThreeMap 模型加载增加短退避重试。
This commit is contained in:
lyf
2026-07-02 10:26:52 +08:00
parent 9efcef5190
commit 7cda427de9
13 changed files with 966 additions and 104 deletions

View File

@@ -1,7 +1,7 @@
export type SgsMapNode =
| { type: 'coord'; floorId: string | number; x: number; z: number; y?: number }
| { type: 'poiId'; value: number }
| { type: 'nodeName'; value: string }
| { type: 'poiId'; value: string | number; floorId?: string | number }
| { type: 'nodeName'; value: string; floorId?: string | number }
export interface SgsSnapDetail {
original: { x: number; z: number }
@@ -14,13 +14,14 @@ export interface SgsRouteResult {
distance: number
duration: number
pathPoints: Array<{ x: number; y: number; z: number }>
startSnap: SgsSnapDetail
endSnap: SgsSnapDetail
computeTimeMs: number
polyCount: number
startSnap?: SgsSnapDetail
endSnap?: SgsSnapDetail
computeTimeMs?: number
polyCount?: number
warnings: string[]
errorCode?: string
message?: string
segments?: SgsRouteSegment[]
}
export interface SgsMapSDKOptions {
@@ -28,17 +29,39 @@ export interface SgsMapSDKOptions {
sdkUrl?: string
targetOrigin?: string
floorId?: string | number
mapId?: string | number
timeout?: number
readyTimeout?: number
}
export interface SgsMapEvents {
ready: { engineVersion: string; protocolVersion: number }
poiClick: { id?: number; poiId?: number; name: string; type: string; floorId?: string | number; description?: string }
poiClick: { id: string | number; poiId?: string | number; name: string; type: string; floorId?: string | number; description?: string }
floorChanged: { floorId: string | number }
error: { code: string; message: string }
loadError: { type: string; detail: string }
routeTransfer: {
currentFloorId: string | number
targetFloorId: string | number
fromFloorId: string | number
fromNodeName: string
toNodeName: string
transferType: SgsRouteTransferType
connectorName?: string
segmentIndex: number
totalSegments: number
routeId?: string
}
modelLoading: { floorId: string | number; modelUrl: string }
modelReady: { floorId: string | number; parseTimeMs: number }
modelError: { floorId: string | number; error: string; fallbackUsed: boolean }
floorBundleReady: { floorId: string | number; dataVersion: string }
routeReady: { routeId: string; distance: number; duration: number; segmentCount?: number; hasTransfer?: boolean }
}
export type SgsRouteTransferType = 'ELEVATOR' | 'STAIRS' | 'ESCALATOR'
export type SgsRouteSegmentType = 'WALK' | 'TRANSFER'
export type SgsErrorCode =
| 'ERR_TIMEOUT'
| 'ERR_NO_PATH'
@@ -50,6 +73,9 @@ export type SgsErrorCode =
| 'ERR_UNAUTHORIZED'
| 'ERR_UNSUPPORTED'
| 'ERR_FAILED'
| 'ERR_DESTROYED'
| 'ERR_IFRAME_LOAD'
| 'ERR_READY_TIMEOUT'
export interface SgsMarkerConfig {
id: string
@@ -64,21 +90,316 @@ export interface SgsMapSDKInstance {
off<K extends keyof SgsMapEvents>(event: K, listener: (payload: SgsMapEvents[K]) => void): void
getIsReady(): boolean
getCurrentFloor(): string | number
getMapId(): string | number
getVersion(): string
whenReady(): Promise<unknown>
ready(): Promise<unknown>
focusTo(node: SgsMapNode | string): void
changeFloor(floorId: string | number, timeout?: number): Promise<{ success: boolean; floorId: string | number }>
addMarker(config: SgsMarkerConfig): void
removeMarker(markerId: string): void
clearMarkers(): void
highlightPolygon(nodeName: string): void
highlightPolygon(payload: string | object): void
planRoute(from: SgsMapNode | string, to: SgsMapNode | string, options?: unknown, timeout?: number): Promise<SgsRouteResult>
planRouteV2(from: SgsMapNode, to: SgsMapNode, options?: unknown, timeout?: number): Promise<SgsRouteResult>
clearRoute(): void
getState(): Promise<unknown>
resetView(): void
setViewMode(mode: '2d' | '3d'): void
resetView(timeout?: number): Promise<{ success: boolean }>
setViewMode(mode: '2d' | '3d', timeout?: number): Promise<{ success: boolean; mode: string }>
toggleLayer(types: string[], visible: boolean, timeout?: number): Promise<{ success: boolean; visibleTypes: string[] }>
setVisibleLayers(types: string[], timeout?: number): Promise<{ success: boolean; visibleTypes: string[] }>
setRouteViewActive(active: boolean, timeout?: number): Promise<{ success: boolean; active: boolean }>
getManifest(timeout?: number): Promise<SgsSdkManifest>
loadFloorBundle(floorId: string | number, timeout?: number): Promise<SgsFloorBundle>
getFloorPois(floorId: string | number, timeout?: number): Promise<SgsPoi[]>
getNavigablePlaces(floorId: string | number, timeout?: number): Promise<SgsNavigablePlace[]>
getPois(floorCode: string, timeout?: number): Promise<SgsPoi[]>
getSpaces(floorId: string | number, timeout?: number): Promise<SgsSpaceArea[]>
getGuideStops(floorId: string | number, timeout?: number): Promise<SgsGuideStop[]>
getGuideStopsByHall(hallId: string | number, timeout?: number): Promise<SgsGuideStop[]>
preloadFloor(floorId: string | number, timeout?: number): Promise<{ cached: boolean }>
getPerformanceStats(timeout?: number): Promise<SgsPerformanceStats>
getDiagnostics(timeout?: number): Promise<SgsMapDiagnostics>
getFloorDiagnostics(floorId: string | number, timeout?: number): Promise<SgsFloorDiagnostics>
clearModelCache(): void
getBusinessPois(floorId: string | number, options?: { types?: string[]; keyword?: string; limit?: number }, timeout?: number): Promise<SgsPoi[]>
queryPois(params: SgsPoiQueryParams, timeout?: number): Promise<SgsPoi[]>
getFeaturedRoutes(mapId?: string | number, options?: { limit?: number }, timeout?: number): Promise<SgsFeaturedRouteSummary[]>
getFeaturedRoute(routeId: string | number, timeout?: number): Promise<SgsFeaturedRouteDetail>
showFlowline(routeId: string | number, options?: SgsFlowlineOptions, timeout?: number): Promise<{ success: boolean; routeId: string | number }>
clearFlowline(): void
destroy(): void
}
export type SgsPoiGroup = 'SERVICE' | 'BUSINESS' | 'OTHER'
export type SgsBusinessPoiType =
| 'shop'
| 'restaurant'
| 'cafe'
| 'vending'
| 'bookstore'
| 'cultural_shop'
| 'photo_spot'
| string
export interface SgsPoiQueryParams {
mapId?: string | number
floorId?: string | number
group?: SgsPoiGroup
types?: string[]
keyword?: string
limit?: number
}
export interface SgsPoi {
id: string | number
name: string
type: string
typeName: string
floorCode: string
floorId?: string | number
position: { x: number; y: number; z: number }
status: 'ACTIVE' | 'INACTIVE'
anchorNodeName?: string | null
description?: string
iconUrl?: string
poiGroup?: SgsPoiGroup
businessType?: SgsBusinessPoiType
coverImageUrl?: string | null
phone?: string | null
businessHours?: string | null
sortOrder?: number | null
spatialAreaId?: string | number | null
spatialAreaName?: string | null
}
export interface SgsSdkManifest {
mapId: string | number
mapName: string
sdkVersion: string
protocolVersion: number
dataVersion: string
updatedAt: string
coordinateSystem: string
floors: SgsSdkFloorSummary[]
capabilities: Record<string, boolean | undefined>
}
export interface SgsSdkFloorSummary {
floorId: string | number
floorCode: string
floorName: string
sortOrder: number
modelSizeBytes: number
poiCount: number
spaceCount: number
}
export interface SgsFloorBundle {
floor: SgsSdkFloorSummary
model: {
modelUrl: string
fallbackModelUrl: string
compressionType: 'draco' | 'none'
modelVersion: string
nodeCount: number
sizeBytes: number
originSizeBytes: number
}
pois: SgsPoi[]
spaces: SgsSpaceArea[]
guideStops: SgsGuideStop[]
routeSummary: {
hasRouteNetwork: boolean
nodeCount: number
edgeCount: number
}
hiddenSceneNodeNames: string[]
dataVersion: string
updatedAt: string
}
export 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
}
export interface SgsGuideStop {
id: string | number
name: string
type: string
typeName?: 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'
located?: boolean
hasAudio?: boolean
poiId?: string | number
outlineId?: string | number
outlineName?: string
hallId?: string | number
hallName?: string
sort?: number
routeId?: string | number
routeName?: string
seqOrder?: number
stayMinutes?: number
}
export interface SgsNavigablePlace {
id: string | number
name: string
category: 'door' | 'poi' | 'space' | 'guide_stop'
floorId: string | number
floorCode: string
floorName?: string
x: number
z: number
nodeId?: string | number
ownerName?: string
typeCode?: string
typeName?: string
}
export interface SgsRouteSegment {
segmentIndex: number
floorId?: string | number | null
floorCode: string
floorName: string
segmentType?: SgsRouteSegmentType
type: 'WALK' | SgsRouteTransferType
transferType?: 'WALK' | SgsRouteTransferType
distance: number
duration: number
pathPoints: Array<{ x: number; y: number; z: number }>
points?: Array<{ x: number; y: number; z: number }>
fromNodeName?: string | null
toNodeName?: string | null
startNodeName?: string | null
endNodeName?: string | null
connectorName?: string | null
}
export interface SgsPerformanceStats {
sdkCreatedAt?: number
iframeDomReadyMs?: number
engineReadyMs?: number
manifestLoadMs?: number
bundleLoadMs?: number
modelDownloadMs?: number
modelDownloadAndParseMs?: number
modelParseMs?: number
firstRenderMs?: number
routePlanMs?: number
dracoUsed?: boolean
fallbackUsed?: boolean
currentFloorId?: string | number
}
export 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[]
}
export interface SgsFloorDiagnosticsSummary {
floorId: string | number
floorCode: string
floorName: string
status: 'OK' | 'WARN' | 'ERROR'
modelReady: boolean
routePlanningReady: boolean
navigablePlaceCount: number
}
export interface SgsFloorDiagnostics extends SgsFloorDiagnosticsSummary {
poiCount: number
spaceCount: number
guideStopCount: number
routeNodeCount: number
routeEdgeCount: number
warnings: string[]
}
export interface SgsFeaturedRouteSummary {
id: string | number
mapId: string | number
routeName: string
routeNameEn?: string | null
description?: string | null
descriptionEn?: string | null
coverImageUrl?: string | null
routeColor?: string | null
estimatedMinutes?: number | null
displayOrder?: number | null
waypointCount: number
startEntranceId?: string | number | null
endEntranceId?: string | number | null
updatedAt?: string | null
}
export interface SgsRouteEndpoint {
id: string | number
name: string
floorId: string | number
floorCode?: string | null
position?: { x: number; y: number; z: number } | null
}
export interface SgsFeaturedRouteWaypoint {
order: number
spaceId: string | number
spaceName?: string | null
floorId?: string | number | null
floorCode?: string | null
position: { x: number; y: number; z: number }
title?: string | null
subtitle?: string | null
description?: string | null
imageUrl?: string | null
audioUrl?: string | null
staySeconds?: number | null
tags?: string[]
highlight?: boolean
}
export interface SgsFeaturedRouteDetail extends SgsFeaturedRouteSummary {
startEntrance?: SgsRouteEndpoint | null
endEntrance?: SgsRouteEndpoint | null
waypoints: SgsFeaturedRouteWaypoint[]
}
export interface SgsFlowlineOptions {
autoFit?: boolean
showLabels?: boolean
animate?: boolean
}
export type SgsMapSDKConstructor = new (options: SgsMapSDKOptions) => SgsMapSDKInstance
declare global {