Using GPS Data — Practices

Cross-cutting conventions for fetching, comparing, querying, and visualising GPS/location data. This spans several projects (OwnTracks, location-db, gazetteer, hibernate-on-approach) and the rules were previously scattered across each. Read this when about to answer a location question, run a PostGIS query, compare a fix against known places, or build a location visualisation.

There are two gazetteers — don't conflate them

gazetteer (notes store) — a JSONHTL table of personal named locations (home, gym, stations, motorway landmarks). Authoritative for "what place is this" questions. Not yet synced to the DB table below.

location-db/gazetteer (PostgreSQL table) — reference datasets (gwml-neutral-sections, uk-railway-stations) used by hibernate-on-approach for phase-break detection. Personal points are planned to sync here tagged source='jPhone' once the MCP connector has write permission, but that hasn't happened yet — treat the notes-store gazetteer as the current source of truth for personal places.

Fetch the fix that matches what's being asked

For "where am I / what's nearest" questions, never reuse a position fetched earlier in the same conversation — the phone reports in the background and a fix goes stale within minutes, faster in a moving vehicle. Re-query ORDER BY tst DESC LIMIT 1 (or re-read the loc note) every time. Caught in practice 2026-07-15: answered "nearest station" from a ~30-minute-old fix and got Radyr instead of Pencoed after the car had moved ~15 miles further west. Full detail: location-db/usage.

But when the task is to label a place John already told you he was at — e.g. "save this location as X" — the right fix is neither a blindly reused one from earlier in context nor a freshly re-queried current one. Query the loc table for the fix nearest the timestamp of the message where he said he was there (tst closest to that message time), since he may have moved on by the time the save actually happens. Caught in practice 2026-07-23: a Burger King gazetteer entry was first saved from a fix taken minutes after the request (wrong), then corrected by reusing an earlier fix already seen in the conversation (right answer, but by luck rather than method) — the durable rule is to query by message timestamp, not to special-case "reuse the old one".

Judge fix quality before trusting it

Filter by accuracy (acc) and prefer a stable cluster of close fixes over an isolated low-quality one. Use the movement vector/bearing from the last known place to disambiguate direction rather than guessing the nearest street. For unknown clusters, prefer named points of interest (cafés, gyms, stations) over street names as a first guess. See OwnTracks (Location inference guidance) for the full list, and hibernate-on-approach/data-sources for how much less reliable indirect proxies (e.g. router wifi power-loss) are compared with a direct GPS fix — don't treat every location signal as equally trustworthy.

Query the notes-store gazetteer FIRST, before reaching for a PostGIS ST_Distance query — not the other way round. Caught in practice 2026-07-29: asked "where am I", queried only the PostGIS location-db/gazetteer table (which offers convenient built-in distance functions) and reported “near Greenwich”, missing that the fix was essentially on top of “The Ship Inn” already recorded in the notes-store gazetteer — an entry not yet synced to PostGIS. The failure mode was reaching for the more convenient tool (built-in KNN/distance functions) over the more authoritative source (the smaller, curated, personal list). Check the notes gazetteer first every time; use PostGIS as a supplementary cross-check for anything not yet synced there.

Comparing a fix against known points: check the actual distances

Compute the distance to every plausibly-nearby gazetteer/survey point before describing where a fix sits, and lead with the closest match. Don't default to impressionistic "between A and B" framing — if the numbers only support one point, say so plainly rather than hedging towards a second point that's actually much further away. Full incident and wording: README/lessons ("GPS/gazetteer comparisons: check distances before describing").

Inferring boarding/alighting points: look for dwell, not just proximity

A single fix's nearest-station match is ambiguous on its own — it can't distinguish “walked past,” “vehicle passed through,” and “boarded/alighted here.” What disambiguates it is a dwell signature: two or more consecutive fixes sitting near-zero distance apart, close to a station, for longer than a walking pause would last. A lone close fix, by contrast, is equally consistent with a train or bus rolling straight through that stop without you getting on or off.

Note on ssid: c13 is John's own portable 4G router that travels with him, not a fixed venue network — seeing ssid='c13' on a fix doesn't mean he was on a specific business's WiFi; fall back to GPS coordinates for place-matching. But c13's connect/disconnect transitions ARE independently meaningful for a different purpose: they're the core signal for hibernate-on-approach's GWML neutral-section detection, where a drop from ssid='c13' to conn='m'/null is used as a proxy for "the train router lost power". See hibernate-on-approach/data-sources (section 3) for the full caveats on that use — these are two separate readings of the same column and shouldn't be conflated.

Caught in practice 2026-07-22: matched a DLR boarding point to South Quay from a single close fix, when the real boarding station (Heron Quays, one stop earlier) showed a clear multi-fix dwell nearby that the single-match approach had skipped past. Re-checking for dwell signatures around every candidate station — not just picking the single closest fix — gave the correct answer immediately.

Nearest bus/transport stop: query the gazetteer (naptan), not an external places search

For "what's the nearest bus stop / transport stop" questions, query location-db/gazetteer (source='naptan', the DfT National Public Transport Access Node dataset — ~398k GB stops, category holds the NaPTAN StopType code, e.g. BCT for on-street bus/coach stops) via pg_query BEFORE reaching for an external places-search tool. Example query is on that page.

Caught in practice 2026-08-02: asked for the nearest stop to Home, went straight to an external places-search tool and missed a real stop (Parkside Avenue, ~110 m from Home) that isn't served by scheduled timetabled routes and so doesn't surface well in general-purpose places data. NaPTAN carries it because it's an official DfT-registered stop regardless of service frequency. The general rule from the section above extends here: check the curated/official gazetteer source before the more convenient general-purpose external tool.

PostGIS query conventions (pg_query MCP tool)

• Always cast geom to ::geography before distance calculations, for metre-accurate results rather than degree-based ones.

• Use ST_DWithin for radius filters, ST_Distance for exact distance, and the <-> KNN operator with ORDER BY for nearest-neighbour queries. Worked examples: location-db/usage.

• If a query errors with "Please try again", the connection pool went stale — simply retry; no reconnect logic needed on your side.

• CTEs (WITH ...) have been observed to fail against this tool in practice. Restructure as nested subqueries instead. This is noted from working experience; the underlying cause hasn't been root-caused or written up yet, so treat it as a working assumption rather than a confirmed limitation.

Visualisation convention

For speed/bearing plots, encode speed as bar height and compass bearing as hue at constant lightness/saturation (hsl(bearing,72%,55%), Chart.js in an HTML artifact). Worked example: the Home → David Lloyd ride (2026-07-17) artifact, linked from OwnTracks (Visualisations). The extended “commute” variant (2026-07-22 GWR run) adds a station overlay and refreshes incrementally — recipe below.

Related notes

OwnTracks — receiver, /location API, client scripts, location inference guidance

location-db — PostGIS database index (architecture, schema, usage, gazetteer table)

gazetteer (notes store) — personal named-location table, with the tennis bubble corner survey at gazetteer/david-lloyd-tennis-bubble

hibernate-on-approach/data-sources — reliability ranking for GPS vs indirect proxies

README/lessons — operational lessons, including the GPS/gazetteer distance-checking entry

created 2026-07-21  ·  tags location, owntracks, gps, conventions  ·  updated 2026-08-02  ·  version 7