# Backend API 문서 ## 시뮬레이션 API ### POST /api/simulation/run 오일 확산 시뮬레이션을 실행합니다. #### 요청 ```json { "model": "OpenDrift", // "KOSPS" | "POSEIDON" | "OpenDrift" | "앙상블" "lat": 34.7312, // 사고 위도 "lon": 127.6845, // 사고 경도 "duration_hours": 48, // 예측 시간 (시간) "oil_type": "벙커C유", // 유종 "spill_amount": 100, // 유출량 (kL) "spill_type": "연속" // 유출 형태 } ``` #### 응답 ```json { "success": true, "model": "OpenDrift", "parameters": { "lat": 34.7312, "lon": 127.6845, "duration_hours": 48, "oil_type": "벙커C유", "spill_amount": 100, "spill_type": "연속" }, "trajectory": [ { "lat": 34.7312, "lon": 127.6845, "time": 0, "particle": 0 }, // ... more points ], "metadata": { "particle_count": 20, "time_steps": 49, "generated_at": "2026-02-16T16:45:00.000Z" } } ``` #### 오류 응답 ```json { "error": "Missing required parameters", "required": ["model", "lat", "lon", "duration_hours"] } ``` --- ### GET /api/simulation/status/:jobId 시뮬레이션 작업 상태를 확인합니다 (향후 비동기 작업용). #### 응답 ```json { "jobId": "abc123", "status": "completed", // "pending" | "running" | "completed" | "failed" "progress": 100, // 0-100 "message": "Simulation completed" } ``` --- ## OpenDrift 통합 계획 ### 1단계: 환경 설정 ```bash # Python 가상 환경 생성 python3 -m venv venv source venv/bin/activate # Linux/Mac # venv\Scripts\activate # Windows # OpenDrift 설치 pip install opendrift # 필요한 기상/해양 데이터 라이브러리 pip install netCDF4 xarray ``` ### 2단계: 데이터 소스 연동 OpenDrift는 다음 데이터 소스가 필요합니다: - **바람 데이터**: WindSpeed, WindDirection - 소스: ERA5, ECMWF, NCEP 등 - 형식: NetCDF (CF-compliant) - **해류 데이터**: CurrentSpeed, CurrentDirection - 소스: CMEMS, HYCOM, RTOFS 등 - 형식: NetCDF - **파고 데이터**: WaveHeight (선택) - 소스: WaveWatch III ### 3단계: TypeScript에서 Python 호출 ```typescript // backend/src/routes/simulation.ts import { spawn } from 'child_process' function runOpenDriftPython(params: SimulationRequest): Promise { return new Promise((resolve, reject) => { const python = spawn('python3', [ './src/utils/opendrift_runner.py', JSON.stringify(params) ]) let stdout = '' let stderr = '' python.stdout.on('data', (data) => { stdout += data.toString() }) python.stderr.on('data', (data) => { stderr += data.toString() console.error('OpenDrift stderr:', data.toString()) }) python.on('close', (code) => { if (code === 0) { const result = JSON.parse(stdout) resolve(result.trajectory) } else { reject(new Error(`OpenDrift failed with code ${code}: ${stderr}`)) } }) }) } ``` ### 4단계: 비동기 작업 큐 (선택) 장시간 시뮬레이션의 경우 작업 큐 사용: ```bash npm install bull redis ``` ```typescript import Queue from 'bull' const simulationQueue = new Queue('simulation', { redis: { host: 'localhost', port: 6379 } }) simulationQueue.process(async (job) => { const result = await runOpenDriftPython(job.data) return result }) ``` --- ## 레이어 API ### GET /api/layers/tree/all 전체 레이어 트리 구조를 반환합니다. #### 응답 ```json [ { "id": "해도", "name": "해도", "type": "group", "children": [ { "id": "기본해도", "name": "기본해도", "type": "layer", "wmsLayer": "khoa:base_chart" } ] } ] ```