# 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으로 마스킹됨