You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+16-4Lines changed: 16 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
-
# Where the Plow
1
+
# where the plow
2
2
3
-
Real-time tracking of City of St. John's snowplow vehicles.
3
+
Real-time and historical tracking of City of St. John's snowplow vehicles.
4
4
5
5
Polls the city's public AVL (Automatic Vehicle Location) API every 6 seconds, stores historical position data in DuckDB, serves it as GeoJSON, and visualizes it on a live map.
6
6
@@ -12,6 +12,12 @@ Polls the city's public AVL (Automatic Vehicle Location) API every 6 seconds, st
12
12
13
13
Requires [uv](https://docs.astral.sh/uv/):
14
14
15
+
```
16
+
uv run cli.py dev
17
+
```
18
+
19
+
This starts the app with auto-reload and sets `DB_PATH=./data/plow.db`. You can also run uvicorn directly:
20
+
15
21
```
16
22
uv run uvicorn where_the_plow.main:app --host 0.0.0.0 --port 8000
17
23
```
@@ -39,12 +45,16 @@ All geo endpoints return GeoJSON. Full OpenAPI docs at [`/docs`](https://plow.ja
39
45
40
46
| Endpoint | Description |
41
47
|---|---|
42
-
|`GET /vehicles`| Latest position for every vehicle |
48
+
|`GET /vehicles`| Latest position for every vehicle (with mini-trails) |
43
49
|`GET /vehicles/nearby?lat=&lng=&radius=`| Vehicles within radius (meters) |
44
50
|`GET /vehicles/{id}/history?since=&until=`| Position history for one vehicle |
45
51
|`GET /coverage?since=&until=`| Per-vehicle LineString trails with timestamps |
46
52
|`GET /stats`| Collection statistics |
47
53
|`GET /health`| Health check |
54
+
|`POST /track`| Record anonymous viewport focus event |
55
+
|`POST /signup`| Email signup for notifications |
56
+
57
+
All GET list endpoints support cursor-based pagination via `limit` and `after` query parameters. Write endpoints (`/track`, `/signup`) are rate-limited per IP.
48
58
49
59
## Database schema
50
60
@@ -76,6 +86,8 @@ CREATE TABLE positions (
76
86
77
87
Deduplication is by `(vehicle_id, timestamp)` composite key -- if the API returns the same `LocationDateTime` for a vehicle, the row is skipped.
78
88
89
+
There are also `viewports` (analytics) and `signups` (email signups) tables -- see `db.py` for their full schemas.
0 commit comments