summit/backend/app/api/routes.py

62 lines
1.9 KiB
Python

from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.database import get_db
from app.schemas import route as route_schema
from app.services.crud_route import route as crud_route
from geoalchemy2.shape import to_shape
from shapely.geometry import mapping
router = APIRouter()
@router.get("/peak/{peak_id}", response_model=List[route_schema.Route])
async def read_routes_by_peak(
peak_id: int,
db: AsyncSession = Depends(get_db),
):
"""
Retrieve routes for a specific peak.
"""
routes = await crud_route.get_by_peak(db, peak_id=peak_id)
results = []
for r in routes:
r_dict = r.__dict__.copy()
# Handle Route Geometry
if r.path_geometry is not None:
sh = to_shape(r.path_geometry)
r_dict['path_geometry'] = mapping(sh)
# Handle Camps Geometry (Nested)
# Since we used selectinload, r.camps should be populated
# But we need to convert their WKB locations to GeoJSON as well
if 'camps' in r_dict:
camps_data = []
for camp in r.camps:
c_dict = camp.__dict__.copy()
if camp.location is not None:
c_sh = to_shape(camp.location)
c_dict['location'] = mapping(c_sh)
camps_data.append(c_dict)
r_dict['camps'] = camps_data
results.append(r_dict)
return results
@router.post("/", response_model=route_schema.Route)
async def create_route(
*,
db: AsyncSession = Depends(get_db),
route_in: route_schema.RouteCreate,
):
"""
Create new route.
"""
route = await crud_route.create(db=db, obj_in=route_in)
r_dict = route.__dict__.copy()
if route.path_geometry is not None:
sh = to_shape(route.path_geometry)
r_dict['path_geometry'] = mapping(sh)
return r_dict