- frontend: React 19 + Vite 7 + Leaflet + Tailwind + Zustand - backend: Express + better-sqlite3 + TypeScript - database: PostgreSQL 초기화 스크립트 - .gitignore: 대용량 참고자료(scat, 참고용) 및 바이너리 파일 제외 - .env.example: API 키 템플릿 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.8 KiB
Executable File
3.8 KiB
Executable File
Backend API 문서
시뮬레이션 API
POST /api/simulation/run
오일 확산 시뮬레이션을 실행합니다.
요청
{
"model": "OpenDrift", // "KOSPS" | "POSEIDON" | "OpenDrift" | "앙상블"
"lat": 34.7312, // 사고 위도
"lon": 127.6845, // 사고 경도
"duration_hours": 48, // 예측 시간 (시간)
"oil_type": "벙커C유", // 유종
"spill_amount": 100, // 유출량 (kL)
"spill_type": "연속" // 유출 형태
}
응답
{
"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"
}
}
오류 응답
{
"error": "Missing required parameters",
"required": ["model", "lat", "lon", "duration_hours"]
}
GET /api/simulation/status/:jobId
시뮬레이션 작업 상태를 확인합니다 (향후 비동기 작업용).
응답
{
"jobId": "abc123",
"status": "completed", // "pending" | "running" | "completed" | "failed"
"progress": 100, // 0-100
"message": "Simulation completed"
}
OpenDrift 통합 계획
1단계: 환경 설정
# 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 호출
// backend/src/routes/simulation.ts
import { spawn } from 'child_process'
function runOpenDriftPython(params: SimulationRequest): Promise<ParticlePoint[]> {
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단계: 비동기 작업 큐 (선택)
장시간 시뮬레이션의 경우 작업 큐 사용:
npm install bull redis
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
전체 레이어 트리 구조를 반환합니다.
응답
[
{
"id": "해도",
"name": "해도",
"type": "group",
"children": [
{
"id": "기본해도",
"name": "기본해도",
"type": "layer",
"wmsLayer": "khoa:base_chart"
}
]
}
]