wing-ops/prediction/opendrift/config.py
jeonghyo.k b601edd741 feat(prediction): flyTo 완료 후 자동 재생 + OpenDrift Docker 설정 추가
- MapView: flyToIncident/onIncidentFlyEnd props 추가, moveend 이벤트 후 콜백 호출
- OilSpillView: 사고 지점 변경 시 flyTo 완료 후 재생(pendingPlayRef), 동일 지점은 즉시 재생
- opendrift/config.py: STORAGE_BASE 환경변수로 스토리지 경로 설정
- opendrift/dockerfile, .dockerignore 추가
- opendrift/createKmaImage.py 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 18:46:15 +09:00

102 lines
3.1 KiB
Python

"""
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)