Skip to content

Commit 3e3f50a

Browse files
committed
add species query
1 parent 3781d3f commit 3e3f50a

2 files changed

Lines changed: 88 additions & 2 deletions

File tree

app/api/tree.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
)
1212
from ..dependencies import get_session
1313
from ..services.tree import (
14-
get_tree_by_id
14+
get_tree_by_id,
15+
get_tree_by_species
1516
)
1617

1718
route_street_tree = APIRouter(prefix='/street_tree/v1')
@@ -54,3 +55,24 @@ async def fetch_tree_by_id(
5455
)
5556

5657
return rows
58+
59+
@route_street_tree.get(
60+
'/species',
61+
response_model=StreetTreeResponse,
62+
tags=['Strassenbaeume'],
63+
description=(
64+
'Retrieves street tree details based on the provided tree id.'
65+
)
66+
)
67+
async def fetch_tree_by_species(
68+
session: AsyncSession = Depends(get_session)
69+
) -> List[StreetTreeResponse]:
70+
rows = await get_tree_by_species(session)
71+
72+
if not rows:
73+
raise HTTPException(
74+
status_code=status.HTTP_404_NOT_FOUND,
75+
detail=f'No matches found'
76+
)
77+
78+
return rows

app/services/tree.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
from sqlalchemy import select, case, literal_column, func
2+
from sqlalchemy.sql import exists, and_, not_
3+
from sqlalchemy.orm import aliased
4+
from geoalchemy2 import functions as geofunc
15
from sqlalchemy.ext.asyncio import AsyncSession
2-
from sqlmodel import select
36
from app.models.tree import StreetTreeRegister
47

58
async def get_tree_by_id(session: AsyncSession, tree_id: int):
@@ -10,3 +13,64 @@ async def get_tree_by_id(session: AsyncSession, tree_id: int):
1013
row = result.scalars().first()
1114

1215
return row
16+
17+
async def get_tree_by_species(session: AsyncSession):
18+
# Alias for subquery
19+
gef = aliased(StreetTreeRegister)
20+
21+
stmt = (
22+
select(
23+
StreetTreeRegister.id,
24+
StreetTreeRegister.tree_number,
25+
StreetTreeRegister.street,
26+
StreetTreeRegister.species,
27+
StreetTreeRegister.type,
28+
func.round(
29+
func.ST_X(func.ST_Transform(StreetTreeRegister.geom, 4326)).cast('numeric'),
30+
6
31+
).label("lon"),
32+
func.round(
33+
func.ST_Y(func.ST_Transform(StreetTreeRegister.geom, 4326)).cast('numeric'),
34+
6
35+
).label("lat"),
36+
case(
37+
(
38+
StreetTreeRegister.species.ilike("%Tilia%"), 1,
39+
),
40+
(
41+
StreetTreeRegister.species.ilike("%Acer%"), 2,
42+
),
43+
(
44+
StreetTreeRegister.species.ilike("%Quercus%"), 3,
45+
),
46+
(
47+
StreetTreeRegister.species.ilike("%Fagus%"), 4,
48+
),
49+
(
50+
StreetTreeRegister.species.ilike("%Betula%"), 5,
51+
),
52+
(
53+
StreetTreeRegister.species.ilike("%Carpinus%"), 6,
54+
),
55+
else_=0,
56+
).label("species_index")
57+
)
58+
.where(
59+
StreetTreeRegister.type == 'bestand',
60+
not_(
61+
exists()
62+
.where(
63+
and_(
64+
gef.type == 'gefaellt',
65+
gef.tree_number == StreetTreeRegister.tree_number,
66+
gef.street == StreetTreeRegister.street,
67+
)
68+
)
69+
)
70+
)
71+
.order_by(StreetTreeRegister.species)
72+
)
73+
74+
result = await session.execute(stmt)
75+
76+
return result.scalars().all()

0 commit comments

Comments
 (0)