feat: wire guide data source and POI focus UI

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
lyf
2026-06-12 09:25:22 +08:00
parent a6bfda30e1
commit 2055b13b90
58 changed files with 5768 additions and 1898 deletions

View File

@@ -0,0 +1,60 @@
import type {
MuseumCategory,
MuseumPoi
} from '@/domain/museum'
import type {
StaticNavPoiCategoryPayload,
StaticNavPoiPayload
} from '@/data/providers/staticNavAssetsProvider'
const floorIdPattern = /^L(-?\d+(?:\.\d+)?)$/
export const formatNavFloorLabel = (floorId: string) => {
const match = floorId.match(floorIdPattern)
if (!match) return floorId
const value = Number(match[1])
if (Number.isNaN(value)) return floorId
return value < 0 ? `B${Math.abs(value)}` : `${value}F`
}
export const navFloorIdFromLabel = (labelOrId: string) => {
if (floorIdPattern.test(labelOrId)) return labelOrId
const basementMatch = labelOrId.match(/^B(\d+(?:\.\d+)?)$/i)
if (basementMatch) return `L-${basementMatch[1]}`
const floorMatch = labelOrId.match(/^(\d+(?:\.\d+)?)F$/i)
if (floorMatch) return `L${floorMatch[1]}`
return labelOrId
}
const toCategory = (category: StaticNavPoiCategoryPayload): MuseumCategory => ({
id: category.topCategory,
label: category.topCategoryZh,
iconType: category.iconType
})
const isPoiAccessible = (poi: StaticNavPoiPayload) => (
poi.primaryCategory === 'accessibility_special_service'
|| poi.categories?.some((category) => category.topCategory === 'accessibility_special_service') === true
)
export const toMuseumPoi = (poi: StaticNavPoiPayload): MuseumPoi => ({
id: poi.id,
name: poi.name,
floorId: poi.floorId,
floorLabel: formatNavFloorLabel(poi.floorId),
primaryCategory: {
id: poi.primaryCategory,
label: poi.primaryCategoryZh,
iconType: poi.iconType
},
categories: (poi.categories || []).map(toCategory),
positionGltf: poi.positionGltf,
sourceConfidence: poi.sourceConfidence,
navigationReadiness: poi.navigationReadiness,
accessible: isPoiAccessible(poi)
})