feat: add geography column + GiST index for routing (migration 05)
geom is geometry(Point,4326) (planar degrees); add geog = geom::geography (STORED generated) + GiST index so ST_Distance/ST_DWithin/KNN work in real metres for nearest-vehicle and radius queries. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
b323e8a1ac
commit
565cd592a0
2 changed files with 19 additions and 0 deletions
|
|
@ -15,6 +15,7 @@ Field-ops **INC ticket** ingestion, geocoding, and read-schema that powers the
|
||||||
| `migrations/02_import_meta.sql` | `tickets.import_meta` (per-dataset snapshot envelope metadata) + `fn_tickets_for_map` re-defined to expose it as `summary.freshness` (same signature — dashboard_api unchanged) |
|
| `migrations/02_import_meta.sql` | `tickets.import_meta` (per-dataset snapshot envelope metadata) + `fn_tickets_for_map` re-defined to expose it as `summary.freshness` (same signature — dashboard_api unchanged) |
|
||||||
| `migrations/03_inc_columns.sql` | Unpacks `tickets.inc.raw` into **typed STORED generated columns** (status, cluster, region, team, owner, sla_status, mttr, lat/lng, is_* booleans, and EAT→`timestamptz` timestamps via `tickets.eat_ts()`). Computed for all rows + auto-populated on every ingest; `raw` stays the source of truth |
|
| `migrations/03_inc_columns.sql` | Unpacks `tickets.inc.raw` into **typed STORED generated columns** (status, cluster, region, team, owner, sla_status, mttr, lat/lng, is_* booleans, and EAT→`timestamptz` timestamps via `tickets.eat_ts()`). Computed for all rows + auto-populated on every ingest; `raw` stays the source of truth |
|
||||||
| `migrations/04_inc_latlng.sql` | Redefines `latitude`/`longitude` to `COALESCE(feed, ST_Y/ST_X(geom))` so they're **populated from the geocoded position** (feed is always empty); precision per `geo_source` (`location` vs `cluster` centroid) |
|
| `migrations/04_inc_latlng.sql` | Redefines `latitude`/`longitude` to `COALESCE(feed, ST_Y/ST_X(geom))` so they're **populated from the geocoded position** (feed is always empty); precision per `geo_source` (`location` vs `cluster` centroid) |
|
||||||
|
| `migrations/05_inc_geography.sql` | Adds `geog geography(Point,4326)` (= `geom::geography`) + GiST index for **routing** — `ST_Distance`/`ST_DWithin`/KNN in real metres (nearest-vehicle, radius search) |
|
||||||
| `import_tickets.py` | Ingests the **newest INC CSV** from the rustfs `tickets` bucket (`automations/inc/<EAT-timestamp>.csv`) and upserts on `ticket_id`; geocodes clusters + INC locations |
|
| `import_tickets.py` | Ingests the **newest INC CSV** from the rustfs `tickets` bucket (`automations/inc/<EAT-timestamp>.csv`) and upserts on `ticket_id`; geocodes clusters + INC locations |
|
||||||
| `run_migrations.py` | Applies `migrations/*.sql` in order (ledger: `tickets.schema_migrations`) |
|
| `run_migrations.py` | Applies `migrations/*.sql` in order (ledger: `tickets.schema_migrations`) |
|
||||||
| `shared.py` | Minimal DB/logging helpers (self-contained — no tracksolid dependency) |
|
| `shared.py` | Minimal DB/logging helpers (self-contained — no tracksolid dependency) |
|
||||||
|
|
|
||||||
18
migrations/05_inc_geography.sql
Normal file
18
migrations/05_inc_geography.sql
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
-- 05_inc_geography.sql — fleettickets · add a geography column for routing/distance
|
||||||
|
-- ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
-- `geom` is geometry(Point,4326) — great for display, but distance on it is in
|
||||||
|
-- planar degrees. For real-world routing ("nearest vehicle", radius search) we want
|
||||||
|
-- geography, whose ST_Distance / ST_DWithin work in metres on the spheroid.
|
||||||
|
--
|
||||||
|
-- `geog` is a STORED generated column = geom::geography (the cast is IMMUTABLE), so
|
||||||
|
-- it tracks geom automatically (incl. after geocode passes). GiST index supports
|
||||||
|
-- ST_DWithin(geog, vehicle::geography, metres) and KNN nearest-neighbour ordering.
|
||||||
|
-- Idempotent.
|
||||||
|
-- ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
SET search_path = tickets, public;
|
||||||
|
|
||||||
|
ALTER TABLE tickets.inc
|
||||||
|
ADD COLUMN IF NOT EXISTS geog geography(Point, 4326) GENERATED ALWAYS AS (geom::geography) STORED;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_inc_geog ON tickets.inc USING gist (geog);
|
||||||
Loading…
Reference in a new issue