feat(transit): name Hamilton's routes, which ship as internal keys

Not one of HSR's 80 route ids equals the number on the bus. Hamilton was
registered without a routeLabel, so every vehicle in the city read as
"Route 5783" where a rider would say 5 DELAWARE — 228 of them in an
afternoon sample. The mechanism to fix it already existed and simply was
never pointed at this feed.

Two details the table cannot skip:

Hamilton runs two generations of route id at once. `5688` and `5780` are
both the 2 BARTON, and both arrive in the live feed, so both are listed.
That is why 80 ids collapse to 46 distinct routes.

The seasonal and event shuttles publish a name where the local routes
publish a number — TC230, PEACH, ROCKTON. Those are already what a rider
would say, so they survive as published rather than being forced into a
number they do not have. Numbers are unpadded to match the rest of the
registry: routes.txt says `02`, a rider says 2.

Ids and names are from the City's own published GTFS routes.txt, which
sits under the same open-data licence as the realtime feed. Checked
against the live feed: all 30 route ids in service translate, none fall
through.
This commit is contained in:
Cliff Flood committed 2026-10-15 20:18:21 -04:00
1 parent 007562c6c8
commit 65ac2d37fb
2 files changed
+122

No files matched your search

+17
View File
@@ -432,6 +432,23 @@ test('YRT local branches read as the branch letter, not the padded id', () => {
assert.equal(transitRouteLabel(yrt, '9101'), '9101');
});
test('Hamilton route ids are internal keys, read as the number on the bus', () => {
// Not one of HSR's 80 route ids equals its published short name, so every
// vehicle reads as "Route 5783" until the table translates it. Hamilton also
// carries two generations of id for the same route — `5688` and `5780` are
// both the 2 BARTON — so both must land on the same answer.
const hsr = getTransitFeed('hsr-hamilton');
assert.equal(transitRouteLabel(hsr, '5780'), '2');
assert.equal(transitRouteLabel(hsr, '5688'), '2', 'the older id agrees');
assert.equal(transitRouteLabel(hsr, '5687'), '1');
assert.equal(transitRouteLabel(hsr, '5829'), '10', 'the B-Line');
assert.equal(transitRouteLabel(hsr, '5793'), '20', 'the A-Line');
// Published names that are not numbers are already what a rider would say,
// so they survive as published rather than being forced into a number.
assert.equal(transitRouteLabel(hsr, '5820'), 'TC230');
assert.equal(transitRouteLabel(hsr, '9999'), '9999', 'unknown survives');
});
test('Burlington route ids are joined, never prefix-stripped', () => {
// `351` is route 1 and `3510` is route 10, so no amount of trimming a `35`
// prefix works — the table is the only correct answer.