""" config.py 중앙집중화된 설정 모듈 모든 경로, 좌표 범위, 시뮬레이션 상수를 한 곳에서 관리합니다. """ import os from pathlib import Path from dataclasses import dataclass from typing import Tuple _BASE_STR = os.getenv("STORAGE_BASE", "C:/upload") @dataclass(frozen=True) class StoragePaths: """파일 저장 경로 설정""" BASE: Path = Path(_BASE_STR) WIND: Path = Path(_BASE_STR) / "wind" POS_WIND: Path = Path(_BASE_STR) / "pos_wind" HYDR: Path = Path(_BASE_STR) / "hydr" POS_HYDR: Path = Path(_BASE_STR) / "pos_hydr" RESULT: Path = Path("result") COASTLINE: Path = Path("coastline/TN_SHORLINE.shp") PARCELS_PATH: str = "/home/gcrnd/apps/parcels" @dataclass(frozen=True) class CoordinateBounds: """한국 해역 좌표 범위""" LON_MIN: float = 124.2083983267507250 LON_MAX: float = 129.9583954964914767 LAT_MIN: float = 32.7916655404227129 LAT_MAX: float = 38.9583268301827559 @property def lon_range(self) -> Tuple[float, float]: return (self.LON_MIN, self.LON_MAX) @property def lat_range(self) -> Tuple[float, float]: return (self.LAT_MIN, self.LAT_MAX) @dataclass(frozen=True) class SimulationConstants: """시뮬레이션 관련 상수""" TEMPERATURE_THRESHOLD: float = 100.0 # 온도 이상값 필터링 임계값 POLLUTION_GRID_BINS: int = 200 # 오염 면적 계산용 격자 해상도 KM_PER_DEG_LAT: float = 111.0 # 위도 1도당 km KM_PER_DEG_LON: float = 91.0 # 경도 1도당 km (위도 35도 기준) EARTH_RADIUS_M: float = 6371000.0 # 지구 반경 (미터) EARTH_RADIUS_KM: float = 6371.0 # 지구 반경 (km) VERTICAL_MIXING_TIMESTEP: int = 5 # 수직 혼합 타임스텝 FILE_FALLBACK_DAYS: int = 3 # 파일 폴백 시도 일수 TIMEZONE_OFFSET_HOURS: int = 9 # KST-UTC 시간차 @dataclass(frozen=True) class WindJsonConfig: """바람 데이터 추출 설정""" RANGE_KM: float = 24.0 # 중심점으로부터의 추출 범위 (km) GRID_SPACING_KM: float = 4.0 # 격자 간격 (km) @dataclass(frozen=True) class CoastlineAnalyzerConfig: """해안선 분석 설정""" BUFFER_DISTANCE: float = 0.001 # 입자 매칭 버퍼 거리 (도) SIMPLIFY_TOLERANCE: float = 0.0 # 해안선 단순화 허용오차 DEFAULT_RADIUS: float = 0.2 # 기본 검색 반경 (도, ~50km) @dataclass(frozen=True) class ThreadPoolConfig: """스레드 풀 설정""" MAX_WORKERS: int = 16 # 최대 워커 수 # 싱글톤 인스턴스 STORAGE = StoragePaths() COORDS = CoordinateBounds() SIM = SimulationConstants() WIND_JSON = WindJsonConfig() COASTLINE = CoastlineAnalyzerConfig() THREAD_POOL = ThreadPoolConfig() # 파일 패턴 템플릿 class FilePatterns: """NC 파일명 패턴""" WIND_FILE = "KO108_GDAPS_ATMO_SURF_{date}00.nc" HYDR_FILE = "KO108_MOHID_HYDR_SURF_{date}00.nc" @staticmethod def get_wind_filename(date_str: str) -> str: return FilePatterns.WIND_FILE.format(date=date_str) @staticmethod def get_hydr_filename(date_str: str) -> str: return FilePatterns.HYDR_FILE.format(date=date_str)