wing-ops/prediction/opendrift/config.py
jeonghyo.k 88eb6b121a feat(prediction): OpenDrift 유류 확산 시뮬레이션 통합 + CCTV/관리자 고도화
[예측]
- OpenDrift Python API 서버 및 스크립트 추가 (prediction/opendrift/)
- 시뮬레이션 상태 폴링 훅(useSimulationStatus), 로딩 오버레이 추가
- HydrParticleOverlay: deck.gl 기반 입자 궤적 시각화 레이어
- OilSpillView/LeftPanel/RightPanel: 시뮬레이션 실행·결과 표시 UI 개편
- predictionService/predictionRouter: 시뮬레이션 CRUD 및 상태 관리 API
- simulation.ts: OpenDrift 연동 엔드포인트 확장
- docs/PREDICTION-GUIDE.md: 예측 기능 개발 가이드 추가

[CCTV/항공방제]
- CCTV 오일 감지 GPU 추론 연동 (OilDetectionOverlay, useOilDetection)
- CCTV 안전관리 감지 기능 추가 (선박 출입, 침입 감지)
- oil_inference_server.py: Python GPU 추론 서버

[관리자]
- 관리자 화면 고도화 (사용자/권한/게시판/선박신호 패널)
- AdminSidebar, BoardMgmtPanel, VesselSignalPanel 신규 컴포넌트

[기타]
- DB: 시뮬레이션 결과, 선박보험 시드(1391건), 역할 정리 마이그레이션
- 팀 워크플로우 v1.6.1 동기화

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

101 lines
3.1 KiB
Python

"""
config.py
중앙집중화된 설정 모듈
모든 경로, 좌표 범위, 시뮬레이션 상수를 한 곳에서 관리합니다.
"""
from pathlib import Path
from dataclasses import dataclass
from typing import Tuple
_BASE_STR = "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)