Skip to content

Commit

Permalink
Merge pull request #1008 from hackforla/mattyweb/issue1007
Browse files Browse the repository at this point in the history
Adding Type hotspots to API
  • Loading branch information
mattyweb authored Mar 10, 2021
2 parents 9e833ff + ecb73c3 commit 95b9bb5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
32 changes: 32 additions & 0 deletions server/api/code/lacity_data_api/models/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,35 @@ async def get_enclosing_council(cls, latitude: float, longitude: float):
).gino.first()
)
return result

@classmethod
async def get_hotspots(cls, type_id: int, start_date: str):

# using ~30m radius (epsilon) and 1+ request/month
query = db.text(f"""
SELECT
h.hotspot_id,
count(*) as hotspot_count,
ST_X(ST_Centroid(ST_Collect(h.request_point))) as hotspot_long,
ST_Y(ST_Centroid(ST_Collect(h.request_point))) as hotspot_lat
FROM (
SELECT
ST_SetSRID(
ST_MakePoint(longitude, latitude), 4326
) as request_point,
ST_ClusterDBSCAN(
ST_SetSRID(ST_MakePoint(longitude, latitude), 4326),
eps := 0.0003, minpoints := 12
) over () AS hotspot_id
FROM
service_requests
WHERE
created_date >= '{start_date}' AND type_id = {type_id}
) as h
WHERE hotspot_id is not null
GROUP BY h.hotspot_id
;
""")

result = await db.all(query)
return result
37 changes: 37 additions & 0 deletions server/api/code/lacity_data_api/routers/geojson.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json

import pendulum
from fastapi import APIRouter, HTTPException

from ..models.geometry import Geometry
Expand All @@ -20,6 +21,24 @@ def createFeature(row):
}


def createHotspotFeature(row):
item = dict(row)
return {
"type": "Feature",
"properties": {
"hotspot_id": item['hotspot_id'],
"count": item['hotspot_count'],
},
"geometry": {
"type": "Point",
"coordinates": [
item['hotspot_long'],
item['hotspot_lat']
]
}
}


@router.get("")
async def get_all_geometries():
result = await Geometry.get_council_geojson()
Expand All @@ -43,3 +62,21 @@ async def get_enclosing_council(
if not result:
raise HTTPException(status_code=404, detail="Item not found")
return result


@router.get("/hotspots")
async def get_hotspots(
type_id: int = 6, # defaults to illegal dumping
start_date: str = pendulum.today().subtract(years=1).to_date_string()
):

features = []
result = await Geometry.get_hotspots(type_id, start_date)

for i in result:
features.append(createHotspotFeature(i))

return {
"type": "FeatureCollection",
"features": features
}

0 comments on commit 95b9bb5

Please sign in to comment.