mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
feat(transit): add Guelph and Kingston, register Barrie off
Guelph's feed publishes the internal database key of a route (`2991`) where the rider sees the number on the bus (`1`), which would have put "Route 2991" on the label a person reads. So a feed may now carry its own `routeLabel`, the same way it may carry its own `modeWords`. Guelph's table is its 33 routes, taken from the City's own published GTFS; an id missing from it renders unchanged, because a raw id you can compare against the bus beats a blank. Every other feed is identity and carries no table. Kingston is catalogued by the City against this exact URL. Its licence PDF link is pinned to the canonical location rather than the legacy path that currently redirects there — Durham's entry records what happens when such a redirect is eventually dropped. Barrie ships REGISTERED AND OFF. The City offers its licence for acceptance behind a click-through gate, and nobody on this project has accepted it. Whether to accept is a person's decision, not an assumption a poller should make, so the feed is visible, documented, and one line from enabled.
This commit is contained in:
1 parent
849cb80375
commit
11dd914c2f
7 files changed
+223
-9
No files matched your search
@@ -4,7 +4,10 @@
|
||||
* scene state, no network: everything here is exercised by node:test.
|
||||
*/
|
||||
|
||||
import { TRANSIT_MODE_ICON } from '../../data/transitFeeds.js';
|
||||
import {
|
||||
TRANSIT_MODE_ICON,
|
||||
transitRouteLabel,
|
||||
} from '../../data/transitFeeds.js';
|
||||
import { displayMotion, playbackPosition } from './movement.js';
|
||||
|
||||
export const TRANSIT_SELECTED_OVERLAY_SOURCE_ID = 'transit-selected';
|
||||
@@ -337,7 +340,7 @@ export function buildTransitSelectionCopy(
|
||||
) {
|
||||
const icon = TRANSIT_MODE_ICON[mode] || TRANSIT_MODE_ICON.unknown;
|
||||
const routeLabel = record.routeId
|
||||
? `Route ${record.routeId}`
|
||||
? `Route ${transitRouteLabel(feed, record.routeId)}`
|
||||
: record.label
|
||||
? `Vehicle ${record.label}`
|
||||
: `Vehicle ${record.id}`;
|
||||
@@ -515,12 +518,14 @@ export function transitModeAbbr(mode, feed = null) {
|
||||
* names one, else the fleet number, else the raw id. What a person standing at
|
||||
* the stop would call it.
|
||||
* @param {object} record Normalized vehicle record.
|
||||
* @param {object|null} [feed] Registry entry, for feeds whose route ids are
|
||||
* internal keys rather than the number on the vehicle.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function transitDetectionId(record) {
|
||||
export function transitDetectionId(record, feed = null) {
|
||||
const route =
|
||||
typeof record?.routeId === 'string' ? record.routeId.trim() : '';
|
||||
if (route) return elideRouteText(route);
|
||||
if (route) return elideRouteText(transitRouteLabel(feed, route));
|
||||
const label = typeof record?.label === 'string' ? record.label.trim() : '';
|
||||
if (label) return elideRouteText(label);
|
||||
return elideRouteText(String(record?.id || 'TRANSIT'));
|
||||
|
||||
@@ -143,7 +143,10 @@ export function createQueries({ state, parts }) {
|
||||
// Route and operator text change with the record and the mode, both of
|
||||
// which arrive on polls — the same events that rebuild this list.
|
||||
if (!entry.labelId || entry.labelRecord !== entry.record) {
|
||||
entry.labelId = transitDetectionId(entry.record);
|
||||
entry.labelId = transitDetectionId(
|
||||
entry.record,
|
||||
feedForEntry(state, entry),
|
||||
);
|
||||
entry.labelRecord = entry.record;
|
||||
}
|
||||
if (!entry.labelClass || entry.labelMode !== entry.mode) {
|
||||
|
||||
@@ -3,6 +3,7 @@ import assert from 'node:assert/strict';
|
||||
import {
|
||||
buildTransitSelectionCopy,
|
||||
transitDetectionClass,
|
||||
transitDetectionId,
|
||||
transitDetectionMetric,
|
||||
transitModeAbbr,
|
||||
transitModeWord,
|
||||
@@ -50,3 +51,26 @@ test('detection labels carry the operator vocabulary within the field width', ()
|
||||
const metric = transitDetectionMetric({ mode: 'tram' }, 'tram', 0, ttc());
|
||||
assert.match(metric, /^STREETCAR/);
|
||||
});
|
||||
|
||||
test('a Guelph vehicle is labelled with the number on the bus, not the database key', () => {
|
||||
const guelph = getTransitFeed('guelph-transit');
|
||||
const record = { id: '196', routeId: '2991', timestamp: 0 };
|
||||
const copy = buildTransitSelectionCopy(guelph, record, 'bus', 0, null, null);
|
||||
assert.match(copy.title, /Route 1\b/);
|
||||
assert.doesNotMatch(copy.title, /2991/);
|
||||
assert.equal(transitDetectionId(record, guelph), '1');
|
||||
});
|
||||
|
||||
test('a feed that already speaks rider route numbers is untouched', () => {
|
||||
const record = { id: '4400', routeId: '501', timestamp: 0 };
|
||||
assert.equal(transitDetectionId(record, ttc()), '501');
|
||||
const copy = buildTransitSelectionCopy(ttc(), record, 'tram', 0, null, null);
|
||||
assert.match(copy.title, /Route 501/);
|
||||
// No feed at all still renders the raw route rather than throwing.
|
||||
assert.equal(transitDetectionId(record), '501');
|
||||
});
|
||||
|
||||
test('a vehicle with no route still falls back to its fleet number', () => {
|
||||
const guelph = getTransitFeed('guelph-transit');
|
||||
assert.equal(transitDetectionId({ id: '196', label: '196' }, guelph), '196');
|
||||
});
|
||||
Reference in new issue
Block a user