import type { MapViewport } from '@/domain/poi' import { defineStore } from 'pinia' import { isTrustworthyCoordinate } from '@/domain/poi' /** * 冷启动第一帧的视野,只在数据集读出来之前生效。 * * 取值是当前数据集全部点位的聚类中心与「一眼看全」的缩放(见 computeClusterViewport)。 * 数据集一加载完,地图页会用实时算出来的聚类视野覆盖它,所以这里稍微过期也不影响, * 但对齐能让第一帧就落在光明区,不会出现「先在别处、再跳过来」的位移。 */ export const DEFAULT_GUANGMING_VIEWPORT: MapViewport = { longitude: 113.9275, latitude: 22.761, scale: 12, } interface MapSessionState { categoryCode: string | null selectedPoiId: string | null viewport: MapViewport plannedRouteVisible: boolean } function isUsableViewport(viewport: MapViewport): boolean { return isTrustworthyCoordinate(viewport.longitude, viewport.latitude) && Number.isFinite(viewport.scale) && viewport.scale > 0 } export const useMapStore = defineStore('map-session', { state: (): MapSessionState => ({ categoryCode: null, selectedPoiId: null, viewport: { ...DEFAULT_GUANGMING_VIEWPORT }, plannedRouteVisible: false, }), actions: { setCategory(categoryCode: string | null) { this.categoryCode = categoryCode }, selectPoi(poiId: string | null) { this.selectedPoiId = poiId }, updateViewport(viewport: MapViewport) { if (!isUsableViewport(viewport)) return this.viewport = { ...viewport } }, resetViewport(viewport: MapViewport = DEFAULT_GUANGMING_VIEWPORT) { this.viewport = isUsableViewport(viewport) ? { ...viewport } : { ...DEFAULT_GUANGMING_VIEWPORT } }, showPlannedRoute() { this.plannedRouteVisible = true }, hidePlannedRoute() { this.plannedRouteVisible = false }, resetSession(viewport: MapViewport = DEFAULT_GUANGMING_VIEWPORT) { this.categoryCode = null this.selectedPoiId = null this.viewport = isUsableViewport(viewport) ? { ...viewport } : { ...DEFAULT_GUANGMING_VIEWPORT } this.plannedRouteVisible = false }, }, })