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

117 lines
4.3 KiB
Markdown

# CLAUDE.md
이 파일은 Claude Code (claude.ai/code)가 이 저장소의 코드를 작업할 때 참고할 수 있는 가이드를 제공합니다.
## 프로젝트 개요
이 프로젝트는 OpenDrift 기반의 **기름 유출 모델링 및 예측 시스템**입니다. OpenDrift는 라그랑지안 입자 기반 해양 표류 모델링 프레임워크입니다. 이 시스템은 기상(GDAPS) 및 해양(MOHID) 예보 데이터를 활용하여 기름 유출 궤적, 풍화 과정(증발, 유화), 환경 영향을 시뮬레이션합니다.
## API 서버 실행
```bash
# 서버 시작 (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 요청 본문
```json
{
"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 시뮬레이션 설정
```python
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 - 일반 예외 |
## 한국 해역 범위
```python
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으로 마스킹됨