@@ -15,9 +15,12 @@ import type {
|
||||
import {
|
||||
NAV_ROUTE_UNAVAILABLE_MESSAGE
|
||||
} from '@/domain/guideReadiness'
|
||||
import {
|
||||
isIndoorNavigableFloor
|
||||
} from '@/domain/guideFloor'
|
||||
import {
|
||||
isIndoorNavigableFloor
|
||||
} from '@/domain/guideFloor'
|
||||
import {
|
||||
isPoiSearchCategorySupported
|
||||
} from '@/domain/poiCategories'
|
||||
import type {
|
||||
SgsFloorDiagnosticsPayload,
|
||||
SgsGuideStopPayload,
|
||||
@@ -194,20 +197,22 @@ const toNumber = (value: number | null | undefined, fallback = 0) => (
|
||||
Number.isFinite(Number(value)) ? Number(value) : fallback
|
||||
)
|
||||
|
||||
const optionalNumber = (value: number | null | undefined) => (
|
||||
Number.isFinite(Number(value)) ? Number(value) : undefined
|
||||
)
|
||||
const optionalNumber = (value: number | null | undefined) => (
|
||||
value !== null && typeof value !== 'undefined' && Number.isFinite(Number(value))
|
||||
? Number(value)
|
||||
: undefined
|
||||
)
|
||||
|
||||
const normalizedText = (value?: string | null) => (value || '').trim()
|
||||
|
||||
const normalizePositionSource = (source: SgsPositionPayload): [number, number, number] | undefined => {
|
||||
const x = Number(source.x)
|
||||
const y = Number(source.y)
|
||||
const z = Number(source.z)
|
||||
|
||||
if (![x, y, z].every(Number.isFinite)) return undefined
|
||||
return [x, y, z]
|
||||
}
|
||||
const normalizePositionSource = (source: SgsPositionPayload): [number, number, number] | undefined => {
|
||||
const x = optionalNumber(source.x)
|
||||
const y = optionalNumber(source.y)
|
||||
const z = optionalNumber(source.z)
|
||||
|
||||
if (typeof x === 'undefined' || typeof y === 'undefined' || typeof z === 'undefined') return undefined
|
||||
return [x, y, z]
|
||||
}
|
||||
|
||||
const normalizeStatus = (status?: string): GuideDiagnosticsStatus => {
|
||||
if (status === 'OK' || status === 'WARN' || status === 'ERROR') return status
|
||||
@@ -354,7 +359,7 @@ const searchableSpaceText = (space: SgsSpacePayload) => [
|
||||
|
||||
const parseBoundaryWktCenter = (
|
||||
boundaryWkt?: string | null,
|
||||
fallbackY = 0
|
||||
fallbackY?: number
|
||||
): [number, number, number] | undefined => {
|
||||
const matches = [...(boundaryWkt || '').matchAll(/(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)/g)]
|
||||
const points = matches
|
||||
@@ -377,12 +382,11 @@ const normalizePositionSourceWithFallbackY = (
|
||||
): [number, number, number] | undefined => {
|
||||
if (!source) return undefined
|
||||
|
||||
const x = Number(source.x)
|
||||
const rawY = Number(source.y)
|
||||
const y = Number.isFinite(rawY) ? rawY : Number(fallbackY)
|
||||
const z = Number(source.z)
|
||||
const x = optionalNumber(source.x)
|
||||
const y = optionalNumber(source.y) ?? optionalNumber(fallbackY)
|
||||
const z = optionalNumber(source.z)
|
||||
|
||||
if (![x, y, z].every(Number.isFinite)) return undefined
|
||||
if (typeof x === 'undefined' || typeof y === 'undefined' || typeof z === 'undefined') return undefined
|
||||
return [x, y, z]
|
||||
}
|
||||
|
||||
@@ -513,13 +517,16 @@ const kindForSgsPoi = (poi: SgsPoiPayload, category: MuseumCategory) => {
|
||||
return 'facility'
|
||||
}
|
||||
|
||||
export const toMuseumPoiFromSgs = (
|
||||
poi: SgsPoiPayload,
|
||||
floors: SgsSdkFloorSummaryPayload[]
|
||||
): MuseumPoi => {
|
||||
const floorId = stringifyId(poi.floorId)
|
||||
const matchedFloor = floors.find((floor) => stringifyId(floor.floorId) === floorId || floor.floorCode === poi.floorCode)
|
||||
const category = categoryFor(poi)
|
||||
export const toMuseumPoiFromSgs = (
|
||||
poi: SgsPoiPayload,
|
||||
floors: SgsSdkFloorSummaryPayload[]
|
||||
): MuseumPoi => {
|
||||
const sourceFloorId = stringifyId(poi.floorId)
|
||||
const matchedFloor = floors.find((floor) => stringifyId(floor.floorId) === sourceFloorId || floor.floorCode === poi.floorCode)
|
||||
const floorId = stringifyId(matchedFloor?.floorId)
|
||||
|| sourceFloorId
|
||||
|| stringifyId(poi.floorCode)
|
||||
const category = categoryFor(poi)
|
||||
|
||||
return {
|
||||
id: stringifyId(poi.id),
|
||||
@@ -983,14 +990,19 @@ const addIssue = (
|
||||
})
|
||||
}
|
||||
|
||||
const missingFieldsForPoi = (poi: MuseumPoi) => {
|
||||
const fields: string[] = []
|
||||
if (!poi.id) fields.push('id')
|
||||
if (!poi.name) fields.push('name')
|
||||
if (!poi.floorId) fields.push('floorId')
|
||||
if (!poi.positionGltf) fields.push('position')
|
||||
return fields
|
||||
}
|
||||
const missingFieldsForPoi = (poi: MuseumPoi) => {
|
||||
const fields: string[] = []
|
||||
if (!poi.id) fields.push('id')
|
||||
if (!poi.name) fields.push('name')
|
||||
if (!poi.floorId) fields.push('floorId')
|
||||
if (!poi.floorLabel) fields.push('floorLabel')
|
||||
if (
|
||||
!Array.isArray(poi.positionGltf)
|
||||
|| poi.positionGltf.length !== 3
|
||||
|| poi.positionGltf.some((value) => !Number.isFinite(value))
|
||||
) fields.push('position')
|
||||
return fields
|
||||
}
|
||||
|
||||
export const createGuideDataIntegrityReport = (
|
||||
diagnostics: GuideMapDiagnostics,
|
||||
@@ -1065,7 +1077,7 @@ export const createGuideDataIntegrityReport = (
|
||||
}
|
||||
if (poi.id) poiIds.add(poi.id)
|
||||
|
||||
if (poi.floorId && !floorIds.has(poi.floorId)) {
|
||||
if (poi.floorId && !floorIds.has(poi.floorId)) {
|
||||
addIssue(issues, {
|
||||
scope: 'poi',
|
||||
severity: 'error',
|
||||
@@ -1074,9 +1086,21 @@ export const createGuideDataIntegrityReport = (
|
||||
floorLabel: poi.floorLabel,
|
||||
poiId: poi.id,
|
||||
fields: ['floorId']
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (!isPoiSearchCategorySupported(poi)) {
|
||||
addIssue(issues, {
|
||||
scope: 'poi',
|
||||
severity: 'warn',
|
||||
message: `${poi.name || poi.id} 缺少有效搜索分类`,
|
||||
floorId: poi.floorId,
|
||||
floorLabel: poi.floorLabel,
|
||||
poiId: poi.id,
|
||||
fields: ['primaryCategory']
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const errorCount = issues.filter((issue) => issue.severity === 'error').length
|
||||
const warningCount = issues.filter((issue) => issue.severity === 'warn').length
|
||||
|
||||
Reference in New Issue
Block a user