diff --git a/app/api/tree.py b/app/api/tree.py index 0d5b84f..54ea4b3 100755 --- a/app/api/tree.py +++ b/app/api/tree.py @@ -3,15 +3,20 @@ from typing import List, Dict, Any from fastapi import Depends, APIRouter, HTTPException, status +from fastapi.encoders import jsonable_encoder +from fastapi.responses import JSONResponse from geojson import Feature, FeatureCollection from sqlalchemy.ext.asyncio import AsyncSession + + from ..schemas.tree import ( StreetTreeResponse ) from ..dependencies import get_session from ..services.tree import ( - get_tree_by_id + get_tree_by_id, + get_tree_by_species ) from geoalchemy2.shape import to_shape @@ -72,4 +77,24 @@ async def fetch_tree_by_id( "registration_date": tree.registration_date.isoformat() if tree.registration_date else None, "type": tree.type, "geom": geojson_dict, - } \ No newline at end of file + } + +@route_street_tree.get( + '/species', + response_model=List, + tags=['Strassenbaeume'], + description='Retrieves street tree details based there species.' +) +async def fetch_tree_by_species( + session: AsyncSession = Depends(get_session) +): + rows = await get_tree_by_species(session) + response = jsonable_encoder(rows) + + try: + return JSONResponse(content=response) + except IndexError: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail='Not found' + ) diff --git a/app/services/tree.py b/app/services/tree.py index 6bba84b..f8d2217 100755 --- a/app/services/tree.py +++ b/app/services/tree.py @@ -1,4 +1,5 @@ from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy.sql import text from sqlmodel import select from app.models.tree import StreetTreeRegister @@ -10,3 +11,39 @@ async def get_tree_by_id(session: AsyncSession, tree_id: int): row = result.scalars().first() return row + +async def get_tree_by_species(session: AsyncSession): + stmt = text(''' + SELECT + tr.id, + tr.tree_number, + tr.street, + tr.species, + tr.type, + ROUND(ST_X(ST_Transform(tr.geom, 4326))::numeric, 6) AS lon, + ROUND(ST_Y(ST_Transform(tr.geom, 4326))::numeric, 6) AS lat, + CASE + WHEN tr.species ILIKE '%Tilia%' THEN 1 + WHEN tr.species ILIKE '%Acer%' THEN 2 + WHEN tr.species ILIKE '%Quercus%' THEN 3 + WHEN tr.species ILIKE '%Fagus%' THEN 4 + WHEN tr.species ILIKE '%Betula%' THEN 5 + WHEN tr.species ILIKE '%Carpinus%' THEN 6 + ELSE 0 + END AS species_index + FROM flensburg.street_tree_register tr + WHERE tr.type = 'bestand' + AND NOT EXISTS ( + SELECT 1 + FROM flensburg.street_tree_register gef + WHERE gef.type = 'gefaellt' + AND gef.tree_number = tr.tree_number + AND gef.street = tr.street + ) + ORDER BY tr.species + ''') + + result = await session.execute(stmt) + rows = result.mappings().all() + + return [dict(row) for row in rows]