This commit is contained in:
@@ -526,6 +526,7 @@ const poiCategoryPriority: Record<string, number> = {
|
|||||||
poi: 86,
|
poi: 86,
|
||||||
accessibility_special_service: 88,
|
accessibility_special_service: 88,
|
||||||
basic_service_facility: 82,
|
basic_service_facility: 82,
|
||||||
|
business_poi: 80,
|
||||||
transport_circulation: 76,
|
transport_circulation: 76,
|
||||||
operation_experience: 46
|
operation_experience: 46
|
||||||
}
|
}
|
||||||
@@ -539,6 +540,7 @@ const isHallPoi = (poi: RenderPoi) => (
|
|||||||
const isServiceFacilityPoi = (poi: RenderPoi) => (
|
const isServiceFacilityPoi = (poi: RenderPoi) => (
|
||||||
poi.primaryCategory === 'basic_service_facility'
|
poi.primaryCategory === 'basic_service_facility'
|
||||||
|| poi.primaryCategory === 'accessibility_special_service'
|
|| poi.primaryCategory === 'accessibility_special_service'
|
||||||
|
|| poi.primaryCategory === 'business_poi'
|
||||||
)
|
)
|
||||||
|
|
||||||
const isTransportPoi = (poi: RenderPoi) => poi.primaryCategory === 'transport_circulation'
|
const isTransportPoi = (poi: RenderPoi) => poi.primaryCategory === 'transport_circulation'
|
||||||
@@ -554,6 +556,12 @@ const poiGlyphMap: Record<string, string> = {
|
|||||||
stair: '梯',
|
stair: '梯',
|
||||||
experience: '展',
|
experience: '展',
|
||||||
theater: '演',
|
theater: '演',
|
||||||
|
restaurant: '餐',
|
||||||
|
cafe: '咖',
|
||||||
|
shop: '购',
|
||||||
|
bookstore: '书',
|
||||||
|
cultural_shop: '文',
|
||||||
|
business: '商',
|
||||||
exhibition_hall: '展',
|
exhibition_hall: '展',
|
||||||
hall_entrance: '门',
|
hall_entrance: '门',
|
||||||
entrance_exit: '门',
|
entrance_exit: '门',
|
||||||
@@ -4102,6 +4110,7 @@ const getPoiColor = (category: string) => {
|
|||||||
exhibition_hall: '#2f6fed',
|
exhibition_hall: '#2f6fed',
|
||||||
exhibition_hall_entrance: '#4659d8',
|
exhibition_hall_entrance: '#4659d8',
|
||||||
basic_service_facility: '#1f8f5f',
|
basic_service_facility: '#1f8f5f',
|
||||||
|
business_poi: '#0f9aa5',
|
||||||
transport_circulation: '#d77b20',
|
transport_circulation: '#d77b20',
|
||||||
accessibility_special_service: '#8a5cf6',
|
accessibility_special_service: '#8a5cf6',
|
||||||
operation_experience: '#cf3f59'
|
operation_experience: '#cf3f59'
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ export interface GuideRenderPoi {
|
|||||||
kind?: MuseumPoiKind
|
kind?: MuseumPoiKind
|
||||||
hallId?: string
|
hallId?: string
|
||||||
hallName?: string
|
hallName?: string
|
||||||
|
spaceId?: string
|
||||||
|
sourcePlaceId?: string
|
||||||
|
sourceSpaceId?: string
|
||||||
entrances?: MuseumPoiEntrance[]
|
entrances?: MuseumPoiEntrance[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -972,7 +972,7 @@ const handleIndoorToolClick = (tool: string) => {
|
|||||||
if (!is3DMode.value) return
|
if (!is3DMode.value) return
|
||||||
|
|
||||||
if (tool === '复位') {
|
if (tool === '复位') {
|
||||||
showIndoorHint('已复位视角,单指旋转、双指可平移', 2800)
|
showIndoorHint('已复位视角,单指平移、双指可缩放', 2800)
|
||||||
} else if (tool === '俯视') {
|
} else if (tool === '俯视') {
|
||||||
showIndoorHint('已切换俯视视角,可点选标记查看位置', 2800)
|
showIndoorHint('已切换俯视视角,可点选标记查看位置', 2800)
|
||||||
} else if (tool === '斜视') {
|
} else if (tool === '斜视') {
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import type {
|
|||||||
GuideModelSource,
|
GuideModelSource,
|
||||||
GuideRenderPoi
|
GuideRenderPoi
|
||||||
} from '@/domain/guideModel'
|
} from '@/domain/guideModel'
|
||||||
|
import type {
|
||||||
|
MuseumPoi
|
||||||
|
} from '@/domain/museum'
|
||||||
import {
|
import {
|
||||||
dataSourceConfig
|
dataSourceConfig
|
||||||
} from '@/config/dataSource'
|
} from '@/config/dataSource'
|
||||||
@@ -35,6 +38,12 @@ import {
|
|||||||
import {
|
import {
|
||||||
mapWithConcurrency
|
mapWithConcurrency
|
||||||
} from '@/utils/concurrency'
|
} from '@/utils/concurrency'
|
||||||
|
import type {
|
||||||
|
GuideRepository
|
||||||
|
} from '@/repositories/GuideRepository'
|
||||||
|
import {
|
||||||
|
guideRepository
|
||||||
|
} from '@/repositories/createGuideRepository'
|
||||||
|
|
||||||
const SDK_FLOOR_BUNDLE_CONCURRENCY = 2
|
const SDK_FLOOR_BUNDLE_CONCURRENCY = 2
|
||||||
|
|
||||||
@@ -57,9 +66,7 @@ const toRenderPoi = (poi: StaticNavPoiPayload): GuideRenderPoi => ({
|
|||||||
hallName: poi.primaryCategory === 'touring_poi' ? poi.name : undefined
|
hallName: poi.primaryCategory === 'touring_poi' ? poi.name : undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
const toSgsRenderPoi = (
|
const toGuideRenderPoi = (poi: MuseumPoi): GuideRenderPoi => ({
|
||||||
poi: ReturnType<typeof toMuseumPoiFromSgs>
|
|
||||||
): GuideRenderPoi => ({
|
|
||||||
id: poi.id,
|
id: poi.id,
|
||||||
name: poi.name,
|
name: poi.name,
|
||||||
floorId: poi.floorId,
|
floorId: poi.floorId,
|
||||||
@@ -71,14 +78,28 @@ const toSgsRenderPoi = (
|
|||||||
kind: poi.kind,
|
kind: poi.kind,
|
||||||
hallId: poi.hallId,
|
hallId: poi.hallId,
|
||||||
hallName: poi.hallName,
|
hallName: poi.hallName,
|
||||||
|
spaceId: poi.spaceId,
|
||||||
|
sourcePlaceId: poi.sourcePlaceId,
|
||||||
|
sourceSpaceId: poi.sourceSpaceId,
|
||||||
entrances: poi.entrances
|
entrances: poi.entrances
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const toSgsRenderPoi = (poi: ReturnType<typeof toMuseumPoiFromSgs>) => toGuideRenderPoi(poi)
|
||||||
|
|
||||||
|
const getRenderPoiDedupeKeys = (poi: GuideRenderPoi) => [
|
||||||
|
poi.id ? `id:${poi.id}` : '',
|
||||||
|
poi.sourceSpaceId ? `space:${poi.floorId}:${poi.sourceSpaceId}` : '',
|
||||||
|
poi.spaceId ? `space:${poi.floorId}:${poi.spaceId}` : '',
|
||||||
|
poi.sourcePlaceId ? `place:${poi.floorId}:${poi.sourcePlaceId}` : '',
|
||||||
|
poi.sourceObjectName ? `object:${poi.floorId}:${poi.sourceObjectName}` : ''
|
||||||
|
].filter(Boolean)
|
||||||
|
|
||||||
const dedupeRenderPoisById = (pois: GuideRenderPoi[]) => {
|
const dedupeRenderPoisById = (pois: GuideRenderPoi[]) => {
|
||||||
const seen = new Set<string>()
|
const seen = new Set<string>()
|
||||||
return pois.filter((poi) => {
|
return pois.filter((poi) => {
|
||||||
if (!poi.id || seen.has(poi.id)) return false
|
const keys = getRenderPoiDedupeKeys(poi)
|
||||||
seen.add(poi.id)
|
if (!keys.length || keys.some((key) => seen.has(key))) return false
|
||||||
|
keys.forEach((key) => seen.add(key))
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -283,7 +304,10 @@ export class StaticGuideModelRepository implements GuideModelRepository {
|
|||||||
export class SgsSdkGuideModelRepository implements GuideModelRepository {
|
export class SgsSdkGuideModelRepository implements GuideModelRepository {
|
||||||
private floorsCache: SgsSdkFloorSummaryPayload[] | null = null
|
private floorsCache: SgsSdkFloorSummaryPayload[] | null = null
|
||||||
|
|
||||||
constructor(private readonly provider: SgsSdkApiProvider = defaultSgsSdkApiProvider) {}
|
constructor(
|
||||||
|
private readonly provider: SgsSdkApiProvider = defaultSgsSdkApiProvider,
|
||||||
|
private readonly guide: GuideRepository = guideRepository
|
||||||
|
) {}
|
||||||
|
|
||||||
async loadPackage(): Promise<GuideModelRenderPackage> {
|
async loadPackage(): Promise<GuideModelRenderPackage> {
|
||||||
const startedAt = getNow()
|
const startedAt = getNow()
|
||||||
@@ -419,7 +443,7 @@ export class SgsSdkGuideModelRepository implements GuideModelRepository {
|
|||||||
|
|
||||||
const resolvedFloorId = String(matchedFloor.floorId)
|
const resolvedFloorId = String(matchedFloor.floorId)
|
||||||
const loadFloorData = async <T>(
|
const loadFloorData = async <T>(
|
||||||
endpoint: 'pois' | 'spaces' | 'navigablePlaces',
|
endpoint: 'pois' | 'spaces' | 'navigablePlaces' | 'guidePois' | 'guideSpacePoints',
|
||||||
loader: () => Promise<T[]>
|
loader: () => Promise<T[]>
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
@@ -434,12 +458,20 @@ export class SgsSdkGuideModelRepository implements GuideModelRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [pois, spaces, navigablePlaces] = await Promise.all([
|
const [pois, spaces, navigablePlaces, guidePois, guideSpacePoints] = await Promise.all([
|
||||||
loadFloorData('pois', () => this.provider.getFloorPois(resolvedFloorId)),
|
loadFloorData('pois', () => this.provider.getFloorPois(resolvedFloorId)),
|
||||||
loadFloorData('spaces', () => this.provider.getFloorSpaces(resolvedFloorId)),
|
loadFloorData('spaces', () => this.provider.getFloorSpaces(resolvedFloorId)),
|
||||||
loadFloorData('navigablePlaces', () => this.provider.getNavigablePlaces(resolvedFloorId))
|
loadFloorData('navigablePlaces', () => this.provider.getNavigablePlaces(resolvedFloorId)),
|
||||||
|
loadFloorData('guidePois', () => this.guide.listPois()),
|
||||||
|
loadFloorData('guideSpacePoints', () => this.guide.listSpacePoints())
|
||||||
])
|
])
|
||||||
const ordinaryPois = pois.map((poi) => toSgsRenderPoi(toMuseumPoiFromSgs(poi, manifest.floors)))
|
const ordinaryPois = pois.map((poi) => toSgsRenderPoi(toMuseumPoiFromSgs(poi, manifest.floors)))
|
||||||
|
const repositoryBusinessPois = guidePois
|
||||||
|
.filter((poi) => poi.floorId === resolvedFloorId && poi.primaryCategory.id === 'business_poi')
|
||||||
|
.map(toGuideRenderPoi)
|
||||||
|
const repositorySpacePois = guideSpacePoints
|
||||||
|
.filter((poi) => poi.floorId === resolvedFloorId)
|
||||||
|
.map(toGuideRenderPoi)
|
||||||
const floorPoiMedianY = getMedianPoiY(ordinaryPois)
|
const floorPoiMedianY = getMedianPoiY(ordinaryPois)
|
||||||
const museumHallPois = toMuseumHallPoisFromSgs(spaces, navigablePlaces, manifest.floors, resolvedFloorId, {
|
const museumHallPois = toMuseumHallPoisFromSgs(spaces, navigablePlaces, manifest.floors, resolvedFloorId, {
|
||||||
fallbackY: floorPoiMedianY
|
fallbackY: floorPoiMedianY
|
||||||
@@ -456,7 +488,9 @@ export class SgsSdkGuideModelRepository implements GuideModelRepository {
|
|||||||
const hallPois = museumHallPois.map(toSgsRenderPoi)
|
const hallPois = museumHallPois.map(toSgsRenderPoi)
|
||||||
const adaptedPois = dedupeRenderPoisById([
|
const adaptedPois = dedupeRenderPoisById([
|
||||||
...hallPois,
|
...hallPois,
|
||||||
...ordinaryPois
|
...ordinaryPois,
|
||||||
|
...repositorySpacePois,
|
||||||
|
...repositoryBusinessPois
|
||||||
])
|
])
|
||||||
const floorMatchedPois = adaptedPois.filter((poi) => poi.floorId === resolvedFloorId)
|
const floorMatchedPois = adaptedPois.filter((poi) => poi.floorId === resolvedFloorId)
|
||||||
const renderPois = floorMatchedPois
|
const renderPois = floorMatchedPois
|
||||||
@@ -467,6 +501,8 @@ export class SgsSdkGuideModelRepository implements GuideModelRepository {
|
|||||||
floorId: resolvedFloorId,
|
floorId: resolvedFloorId,
|
||||||
floorCode: matchedFloor.floorCode,
|
floorCode: matchedFloor.floorCode,
|
||||||
rawPoiCount: pois.length,
|
rawPoiCount: pois.length,
|
||||||
|
rawRepositoryBusinessPoiCount: repositoryBusinessPois.length,
|
||||||
|
rawRepositorySpacePoiCount: repositorySpacePois.length,
|
||||||
rawPoiTypeCounts: countByValue(pois, (poi) => poi.type),
|
rawPoiTypeCounts: countByValue(pois, (poi) => poi.type),
|
||||||
rawPoiGroupCounts: countByValue(pois, (poi) => poi.poiGroup),
|
rawPoiGroupCounts: countByValue(pois, (poi) => poi.poiGroup),
|
||||||
adaptedPoiCount: adaptedPois.length,
|
adaptedPoiCount: adaptedPois.length,
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ const searchableCategories = new Set([
|
|||||||
'basic_service_facility',
|
'basic_service_facility',
|
||||||
'transport_circulation',
|
'transport_circulation',
|
||||||
'accessibility_special_service',
|
'accessibility_special_service',
|
||||||
|
'business_poi',
|
||||||
'operation_experience'
|
'operation_experience'
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -301,15 +302,19 @@ export class SgsSdkGuideRepository implements GuideRepository {
|
|||||||
const floorDataGroups = await Promise.all(
|
const floorDataGroups = await Promise.all(
|
||||||
indoorFloors.map(async (floor) => {
|
indoorFloors.map(async (floor) => {
|
||||||
const floorId = String(floor.floorId)
|
const floorId = String(floor.floorId)
|
||||||
const [pois, spaces, navigablePlaces] = await Promise.all([
|
const [pois, businessPois, spaces, navigablePlaces] = await Promise.all([
|
||||||
this.provider.getFloorPois(floorId).catch(() => []),
|
this.provider.getFloorPois(floorId).catch(() => []),
|
||||||
|
this.provider.getFloorBusinessPois(floorId).catch(() => []),
|
||||||
this.provider.getFloorSpaces(floorId).catch(() => []),
|
this.provider.getFloorSpaces(floorId).catch(() => []),
|
||||||
this.provider.getNavigablePlaces(floorId).catch(() => [])
|
this.provider.getNavigablePlaces(floorId).catch(() => [])
|
||||||
])
|
])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
floorId,
|
floorId,
|
||||||
pois,
|
pois: [
|
||||||
|
...pois,
|
||||||
|
...businessPois
|
||||||
|
],
|
||||||
hallPois: toMuseumHallPoisFromSgs(spaces, navigablePlaces, manifest.floors, floorId)
|
hallPois: toMuseumHallPoisFromSgs(spaces, navigablePlaces, manifest.floors, floorId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user