배달 라이더를 위한 열 스트레스 안전 경로 API
SafeRoute G의 백엔드 API 서버입니다. Modified A* 알고리즘으로 시간과 열 환경을 동시에 고려한 최적 경로를 계산합니다.
- API Base URL: https://saferoute-g-backend.onrender.com
- API 문서: https://saferoute-g-backend.onrender.com/docs
- Health Check: https://saferoute-g-backend.onrender.com/health
- Python 3.11+
- pip
# 1. 저장소 클론
git clone https://github.com/zerochani/saferoute-g-backend.git
cd saferoute-g-backend
# 2. 가상환경 생성
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 3. 의존성 설치
pip install -r requirements.txt
# 4. 환경변수 설정
cp .env.example .env
# .env 파일 편집 (CLIMATE_API_KEY 설정 - 선택사항)
# 5. 서버 실행
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000서버가 http://localhost:8000 에서 실행됩니다.
backend/
├── app/
│ ├── main.py # FastAPI 앱 진입점
│ ├── core/
│ │ ├── config.py # 환경변수 설정
│ │ └── constants.py # 가중치 프리셋, 상수
│ ├── services/
│ │ ├── routing_engine.py # Modified A* 알고리즘
│ │ ├── osm_network.py # OSM 네트워크 로더
│ │ ├── climate_enrichment.py # 기후 데이터 통합
│ │ └── climate_api.py # 경기도 기후 API 클라이언트
│ ├── routers/
│ │ ├── route.py # 라우팅 엔드포인트
│ │ └── climate.py # 기후 데이터 엔드포인트
│ └── models/
│ └── schemas.py # Pydantic 스키마
├── data/
│ └── processed/
│ └── suwon_network.graphml # 캐시된 도로 네트워크
├── requirements.txt
├── Procfile # Render 배포 설정
└── railway.json # Railway 배포 설정
비용 함수:
TotalCost = α·Time + β·HeatStress + γ·SolarExposure - δ·GreenBonus - ε·ShadeBonus구현 위치: app/services/routing_engine.py
WEIGHT_PRESETS = {
"fast": {
"alpha": 10.0, # Time (HIGHEST)
"beta": 0.1, # Heat (minimal)
"gamma": 0.1, # Solar (minimal)
"delta": 0.0, # Green (ignore)
"epsilon": 0.0, # Shade (ignore)
},
"heat_safe": {
"alpha": 0.1, # Time (minimal)
"beta": 5.0, # Heat (VERY HIGH)
"gamma": 4.0, # Solar (VERY HIGH)
"delta": 3.0, # Green (HIGH)
"epsilon": 3.0, # Shade (HIGH)
},
}| 도로 타입 | UTCI | 그늘 | Green Ratio |
|---|---|---|---|
| motorway | 36°C | 10% | 5% |
| primary/secondary | 34°C | 20% | 10% |
| tertiary | 32°C | 30% | 15% |
| residential | 30°C | 50% | 30% |
| service | 29°C | 60% | 40% |
빠른 경로와 열안전 경로를 비교합니다.
Request Body:
{
"origin": {
"lat": 37.2657,
"lon": 127.0001
},
"destination": {
"lat": 37.2505,
"lon": 127.0736
},
"mode": "balanced"
}Response:
{
"fast_route": {
"mode": "fast",
"geometry": {
"type": "LineString",
"coordinates": [[127.0001, 37.2657], ...]
},
"metrics": {
"distance_m": 8754,
"time_min": 14.16,
"avg_utci": 32.17,
"max_utci": 34.0,
"heat_exposure_index": 1511.9,
"shade_coverage_pct": 32.6,
"green_proximity_m": 50.0,
"rest_stops_count": 0
},
"rest_stops": []
},
"heat_safe_route": {
"mode": "heat_safe",
"geometry": { ... },
"metrics": {
"distance_m": 9839,
"time_min": 16.86,
"avg_utci": 31.50,
"max_utci": 34.0,
"heat_exposure_index": 1511.9,
"shade_coverage_pct": 38.5,
"green_proximity_m": 50.0,
"rest_stops_count": 0
},
"rest_stops": []
},
"improvement": {
"time_change_pct": 19.1,
"distance_change_pct": 12.4,
"heat_exposure_reduction_pct": 0.0,
"utci_reduction": 0.67,
"shade_increase_pct": 6.0
}
}단일 경로를 찾습니다.
사용 가능한 라우팅 모드 목록을 반환합니다.
데모용 프리셋 경로 비교 결과를 반환합니다.
경기도 기후 플랫폼의 사용 가능한 데이터 레이어를 반환합니다.
기후 API 연결 상태를 확인합니다.
서버 헬스 체크
Response:
{
"status": "healthy",
"service": "saferoute-g"
}서비스 정보
.env 파일 설정:
# 경기도 기후 API 키 (선택사항)
CLIMATE_API_KEY=your_api_key_here
# 대상 도시
TARGET_CITY=Suwon, Gyeonggi-do, South Korea
# 대상 지역 경계 (West, South, East, North)
TARGET_BBOX=126.9,37.2,127.2,37.4
# CORS 설정
CORS_ORIGINS=*- FastAPI - 현대적인 Python 웹 프레임워크
- OSMnx - OpenStreetMap 네트워크 분석
- NetworkX - 그래프 알고리즘 (A*)
- GeoPandas - 지리 데이터 처리
- Shapely - 기하학적 연산
- Pydantic - 데이터 검증
- Uvicorn - ASGI 서버
fastapi>=0.104.0
uvicorn[standard]>=0.24.0
osmnx>=1.6.0
networkx>=3.0
geopandas>=0.14.0
shapely>=2.0.0
scikit-learn>=1.3.0
전체 의존성은 requirements.txt 참조.
- Render 웹사이트에서 New Web Service 생성
- GitHub 저장소 연결
- 설정:
- Build Command:
pip install -r requirements.txt - Start Command:
uvicorn app.main:app --host 0.0.0.0 --port $PORT
- Build Command:
- 환경변수 설정:
CLIMATE_API_KEY(선택사항)CORS_ORIGINS=*
railway login
railway init
railway uprailway.json 설정 파일이 자동으로 적용됩니다.
# 서버 실행
uvicorn app.main:app --reload
# 다른 터미널에서
curl -X POST http://localhost:8000/api/route/compare \
-H "Content-Type: application/json" \
-d '{
"origin": {"lat": 37.2657, "lon": 127.0001},
"destination": {"lat": 37.2505, "lon": 127.0736},
"mode": "balanced"
}'서버 실행 후:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
HeatAwareRouter클래스- Modified A* 알고리즘 구현
calculate_edge_cost(): 가중치 기반 비용 계산find_route(): 단일 경로 계산compare_routes(): 빠른 vs 열안전 경로 비교
OSMNetworkBuilder클래스- OpenStreetMap 데이터 로드
- 도로 타입별 열 환경 속성 추가
- GraphML 캐싱
ClimateDataEnricher클래스- 경기도 기후 API에서 녹지/쉼터 데이터 로드
- 도로 간선에 기후 데이터 통합 (선택적)
- 라우팅 모드별 가중치 프리셋
- UTCI 임계값
- 기후 레이어 키워드
-
GraphML 캐싱
- OSM 네트워크를
data/processed/에 캐시 - 재시작 시 빠른 로드
- OSM 네트워크를
-
Startup Event
- 앱 시작 시 그래프 미리 로드
- 첫 요청 지연 방지
-
Render Cold Start
- 무료 플랜: 15분 비활성 후 슬립
- 첫 요청 시 30-60초 소요
- Keep-alive 스크립트 고려 가능
-
지역 제한
- 현재 수원시만 지원
- 다른 지역 추가 시 GraphML 재빌드 필요
-
실시간 기상 데이터 미지원
- 도로 타입 기반 정적 UTCI 사용
- 향후 실시간 API 연동 예정
-
그래프 크기
- 수원시 전체: ~7,500 노드, ~21,000 간선
- 메모리 사용량 고려 필요
- 실시간 기상 API 연동
- 시간대별 열 환경 변화 반영
- 다른 도시 지원 확대
- 경로 캐싱 최적화
- WebSocket 실시간 업데이트
- Fork the repository
- Create feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add AmazingFeature') - Push to branch (
git push origin feature/AmazingFeature) - Open Pull Request
MIT License - 자세한 내용은 LICENSE 참조
GitHub Issues를 통해 버그 리포트 및 기능 제안을 해주세요.
Frontend Repository: https://github.com/zerochani/vibe
Built with ❤️ for delivery riders facing extreme heat