wing-ops/prediction/opendrift/CLAUDE.md
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

4.3 KiB

CLAUDE.md

이 파일은 Claude Code (claude.ai/code)가 이 저장소의 코드를 작업할 때 참고할 수 있는 가이드를 제공합니다.

프로젝트 개요

이 프로젝트는 OpenDrift 기반의 기름 유출 모델링 및 예측 시스템입니다. OpenDrift는 라그랑지안 입자 기반 해양 표류 모델링 프레임워크입니다. 이 시스템은 기상(GDAPS) 및 해양(MOHID) 예보 데이터를 활용하여 기름 유출 궤적, 풍화 과정(증발, 유화), 환경 영향을 시뮬레이션합니다.

API 서버 실행

# 서버 시작 (uvicorn 4 workers, 포트 5003)
./startup.sh

# 서버 중지
./shutdown.sh

# 로그 파일: uvicorn.log
# PID 파일: server.pid

API 엔드포인트

  • GET /get-received-date - 최신 예보 수신 가능 날짜 조회
  • GET /get-uv/{datetime}/{category} - 바람/해류 시각화 데이터 (category: "wind" 또는 "hydr")
  • GET /get-base64/{datetime}/{img_type} - Base64 인코딩된 지도 이미지
  • POST /check-nc - 특정 시작 시간에 대한 NetCDF 파일 존재 여부 확인
  • POST /run-model - 기름 유출 시뮬레이션 실행

run-model 요청 본문

{
  "startTime": "2025-01-15 12:00:00",
  "runTime": 72,
  "matTy": "CRUDE OIL",
  "matVol": 100.0,
  "lon": 126.1,
  "lat": 36.6,
  "spillTime": 12,
  "name": "simulation_id"
}

아키텍처

핵심 흐름

  1. api.py - FastAPI 진입점, 요청 처리 및 OpenOil 시뮬레이션 실행
  2. createJsonResult.py - 시뮬레이션 NetCDF 출력 처리, 시계열 데이터 추출(위치, 부피, 풍화 지표), 컨벡스 헐 및 해안 오염 계산
  3. 결과는 시간 단계별 입자 위치, 유류 부피, 환경 조건을 포함한 JSON으로 반환

주요 모듈

파일 용도
calcCostlineLength.py OilSpillCoastlineAnalyzer 클래스 - 한국 해안선 shapefile에 KD-tree 공간 인덱싱을 사용하여 오염 해안선 길이 계산
convex_hull.py 입자 위치로부터 WKT 폴리곤 생성
extractUvFull.py / extractUvWithinBox.py 시각화를 위한 NetCDF에서 UV 바람/해류 벡터 추출
createWindJson.py 특정 지점의 바람 데이터 추출
latestForecastDate.py 예보 데이터 가용성 확인
weatherData.py 조석, 파고, 기상 데이터용 PostgreSQL/PostGIS 쿼리
findFile.py 폴백 로직이 포함된 시간 기반 파일 탐색기

데이터 소스

  • 바람: /storage/pos_wind/ 또는 /storage/wind/ - KMA GDAPS 파일 (KO108_GDAPS_ATMO_SURF_YYYYMMDDhh.nc)
  • 해양: /storage/pos_hydr/ 또는 /storage/hydr/ - MOHID 해양역학 파일 (KO108_MOHID_HYDR_SURF_YYYYMMDDhh.nc)
  • 해안선: coastline/TN_SHORLINE.shp (EPSG:5179, EPSG:4326으로 변환)

파일 폴백 로직

특정 날짜의 데이터 요청 시 파일이 없으면 최대 3일 전까지 순차적으로 확인합니다.

주요 의존성

  • opendrift - 핵심 기름 표류 시뮬레이션 엔진 (opendrift.models.openoil.OpenOil)
  • xarray - NetCDF 파일 처리
  • geopandas, shapely - GIS 연산 및 지오메트리
  • scipy.spatial.cKDTree - 해안선 분석용 공간 인덱싱
  • psycopg2 - PostgreSQL 데이터베이스 연결
  • FastAPI/uvicorn - 웹 API 프레임워크

OpenOil 시뮬레이션 설정

o.set_config('processes:evaporation', True)
o.set_config('processes:emulsification', True)
o.set_config('drift:vertical_mixing', True)
o.set_config('vertical_mixing:timestep', 5)
o.set_config('seed:m3_per_hour', matVol)
# 시간 간격: 900초, 출력 간격: 3600초

오류 코드

코드 의미
5001 FILE_NOT_FOUND - NetCDF 예보 파일 없음
5002 PARSE_ERROR - JSON 추출 실패
5003 MODELING_ERROR - OpenOil 시뮬레이션 실패
5004 SYSTEM_ERROR - 일반 예외

한국 해역 범위

lon_range: (124.21, 129.96)
lat_range: (32.79, 38.96)

동시성

  • API: uvicorn 4 workers
  • 결과 처리: 병렬 시간 단계 계산을 위한 ThreadPoolExecutor 16 workers
  • OilSpillCoastlineAnalyzer는 스레드 세이프

참고 사항

  • 모든 시간은 시뮬레이션 전에 KST(UTC+9)에서 UTC로 변환됨
  • 시뮬레이션 결과는 result/{name}.nc에 저장됨
  • 해양 데이터에서 100도 이상의 온도 값은 NaN으로 마스킹됨