import { create } from 'zustand'; import { subscribeWithSelector } from 'zustand/middleware'; /** * 배경지도 타입 * - normal: 일반지도 * - enc: 전자해도 * - dark: 야간지도 */ export const BASE_MAP_TYPES = { NORMAL: 'normal', ENC: 'enc', DARK: 'dark', }; /** * 테마 타입 (배경지도에 연동) * - light: 일반지도, 전자해도 * - dark: 야간지도 */ export const THEME_TYPES = { LIGHT: 'light', DARK: 'dark', }; /** * 배경지도 -> 테마 매핑 */ const BASE_MAP_TO_THEME = { [BASE_MAP_TYPES.NORMAL]: THEME_TYPES.LIGHT, [BASE_MAP_TYPES.ENC]: THEME_TYPES.LIGHT, [BASE_MAP_TYPES.DARK]: THEME_TYPES.DARK, }; /** * 테마별 색상 정의 * - 선박 레이어에서 사용 */ export const THEME_COLORS = { [THEME_TYPES.LIGHT]: { shipLabel: [30, 30, 30, 255], shipLabelOutline: [255, 255, 255, 255], speedVector: [0, 0, 0, 200], shipDim: [0, 100, 200, 180], }, [THEME_TYPES.DARK]: { shipLabel: [255, 255, 255, 255], shipLabelOutline: [30, 30, 30, 255], speedVector: [255, 255, 255, 200], shipDim: [100, 200, 255, 180], }, }; /** * 지도 상태 관리 스토어 */ export const useMapStore = create(subscribeWithSelector((set, get) => ({ // 지도 인스턴스 map: null, setMap: (map) => set({ map }), // 배경지도 타입 (기본: 야간지도) baseMapType: BASE_MAP_TYPES.DARK, setBaseMapType: (type) => set({ baseMapType: type }), // 현재 테마 (배경지도에 연동) getTheme: () => BASE_MAP_TO_THEME[get().baseMapType] || THEME_TYPES.LIGHT, // 현재 테마 색상 가져오기 getThemeColors: () => THEME_COLORS[get().getTheme()], // 줌 레벨 zoom: 7, setZoom: (zoom) => set({ zoom }), zoomIn: () => { const { map, zoom } = get(); if (map && zoom < 17) { const newZoom = zoom + 1; map.getView().setZoom(newZoom); set({ zoom: newZoom }); } }, zoomOut: () => { const { map, zoom } = get(); if (map && zoom > 0) { const newZoom = zoom - 1; map.getView().setZoom(newZoom); set({ zoom: newZoom }); } }, // 중심 좌표 [lon, lat] center: [127.1388684, 37.4449168], setCenter: (center) => set({ center }), // 측정 도구 activeMeasureTool: null, areaShape: null, setMeasureTool: (tool) => set((state) => ({ activeMeasureTool: state.activeMeasureTool === tool ? null : tool, areaShape: null, })), setAreaShape: (shape) => set({ areaShape: shape }), clearMeasure: () => set({ activeMeasureTool: null, areaShape: null }), // 레이어 가시성 layerVisibility: { baseMap: true, ships: true, weather: false, satellite: false, }, toggleLayer: (layerName) => set((state) => ({ layerVisibility: { ...state.layerVisibility, [layerName]: !state.layerVisibility[layerName], }, })), })));