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