Compare commits

...

2 commits

Author SHA1 Message Date
david kiania
a6d5a19273 Merge: document map-overlay layers + recent features 2026-06-08 22:01:54 +03:00
david kiania
4eef23677b docs: document map-overlay layers + recent map features
README: add a "Map overlay layers" section (how the toggleable layer system
works + how to add a layer in ~2 min), document fleet segmentation / department
colours / legend / POIs, refresh the file tree (layers/), and correct the deploy
note (Coolify auto-deploys on push to main).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 22:01:52 +03:00

View file

@ -3,13 +3,17 @@
A single-file map console that **merges live vehicle positions and historical A single-file map console that **merges live vehicle positions and historical
trips** into one view for the Fireside Communications / Tracksolid fleet. trips** into one view for the Fireside Communications / Tracksolid fleet.
> **Status:** v2 — **feature-frozen 2026-06-07** (two-tier bottom dock + clustering > **Status:** v2 — live at <https://fleetnow.rahamafresh.com>. Deployed from this
> + tracker/camera dedup). Live at <https://fleetnow.rahamafresh.com>. Deployed > repo via Coolify (Dockerfile → nginx). Reads the `dashboard_api` read-API at
> from this repo via Coolify (Dockerfile → nginx). Reads the `dashboard_api` > `fleetapi.rahamafresh.com`.
> read-API at `fleetapi.rahamafresh.com`.
> >
> Deploy is **manual** — push, then hit Redeploy in Coolify (no auto-deploy > **2026-06-08 additions:** fleet segmentation (specialist vehicle icons that
> webhook wired yet). > never cluster), per-department colour coordination + collapsible **Key** legend,
> persistent POIs (Fireside HQ, Safaricom HQ), and a **toggleable map-overlay
> layer system** (first layer: 232 Shell fuel stations). See *Map overlay layers*.
>
> **Deploy auto-fires on push to `main`** via Coolify (~23 min build); if it
> lags, hit Redeploy in Coolify.
## What it does ## What it does
@ -30,6 +34,15 @@ trips** into one view for the Fireside Communications / Tracksolid fleet.
Leaflet.MarkerCluster style, via `supercluster`); click a bubble to zoom and Leaflet.MarkerCluster style, via `supercluster`); click a bubble to zoom and
expand it. Clusters disband into individual pins at ~city zoom (z11). Clustering expand it. Clusters disband into individual pins at ~city zoom (z11). Clustering
honours the active filter and applies to the live view only (not trip routes). honours the active filter and applies to the live view only (not trip routes).
- **Fleet segmentation & department colours.** Specialist vehicles (crane /
motorbike / pick-up) get their own marker icons and are **never clustered**
(always individually visible); every cost centre has a fixed, distinct colour,
with a collapsible **Key** legend (bottom-left) listing only the centres on
screen. Non-operational vehicles (personal / management / Uganda-MTN) are
filtered out upstream in the read-API, so the live map shows the operational
fleet only.
- **Persistent POIs** — Fireside HQ and Safaricom HQ (Waiyaki Way) as labelled
reference markers.
- **Filters** (bottom-right card) apply to the live map *instantly*: - **Filters** (bottom-right card) apply to the live map *instantly*:
- **Number plate** — multi-select, sorted A→Z; picking a vehicle auto-fills its - **Number plate** — multi-select, sorted A→Z; picking a vehicle auto-fills its
cost centre + city. cost centre + city.
@ -64,9 +77,10 @@ GL JS loaded from a CDN). It has no build step and no local assets. It reads fro
the existing dashboard read-API — it does **not** talk to the database directly. the existing dashboard read-API — it does **not** talk to the database directly.
``` ```
index.html → the entire SPA index.html → the entire SPA
Dockerfile → bakes index.html into an nginx:alpine image (port 80) layers/*.geojson → static overlay data (gas stations, …), served at /layers/
nginx.conf → static serve + /healthz + no-cache on index.html Dockerfile → bakes index.html + layers/ into an nginx:alpine image (port 80)
nginx.conf → static serve + /healthz + no-cache on index.html
``` ```
### Backend it depends on ### Backend it depends on
@ -86,6 +100,38 @@ exposes:
(`DASHBOARD_CORS_ORIGINS`). It is in the code default; make sure the deployed (`DASHBOARD_CORS_ORIGINS`). It is in the code default; make sure the deployed
`dashboard_api` container's env includes it, then restart that container. `dashboard_api` container's env includes it, then restart that container.
## Map overlay layers
Toggleable reference overlays (gas stations, etc.) sit behind the **Layers**
control (top-right, collapsed, all **off** by default). Each is a static GeoJSON
in `layers/`, rendered as a MapLibre **symbol** layer that **auto-declutters**
(`icon-allow-overlap: false` — sparse when zoomed out, all points reveal as you
zoom in), with a zoom-scaled icon (~8→16 px) and a **hover** label (one reused
popup, so only ever one is visible). Overlays render *under* the vehicle markers.
Shipped layers:
| Layer | Data | Points |
|---|---|---|
| Shell stations | `layers/shell_stations.geojson` (OSM `kenya-260605`) | 232 |
**To add a layer (≈2 min):**
1. Drop its point GeoJSON in `layers/<name>.geojson`.
2. Add one entry to the `OVERLAYS` array near the top of the `<script>` in
`index.html`:
```js
{ id: '<name>', label: '<Label>', url: 'layers/<name>.geojson',
iconSvg: <40×40 SVG string>, nameKey: 'name', defaultOn: false }
```
`iconSvg` is registered as the marker image (reuse `SHELL_ICON_SVG` as a
template). Nothing else to wire — `addOverlay()` builds the source + symbol
layer, and the Layers control lists it automatically.
3. Commit + push. The `Dockerfile` already `COPY`s `layers/` into nginx.
> The Shell layer was extracted from a Kenya OSM `.pbf` — the reproducible
> workflow (filter `amenity=fuel`, `brand=Shell`) lives in the `tracksolid` repo:
> `scripts/export_osm_pois.py` + `docs/OSM_POI_EXPORT.md`.
## Deploy (Coolify, git-based) ## Deploy (Coolify, git-based)
1. In Coolify, create a new **Application** from this git repo 1. In Coolify, create a new **Application** from this git repo