Skip to content

VBB: use "canonical" DHID/IFOPT stop IDs in all stop_times entries #312

Description

@derhuerst

Describe the enhancement/addition to the feed you'd like to suggest

Currently, the VBB GTFS Schedule feed contains many trips with stop_times entries that reference non-IFOPT-style (non-DHID-style) stop IDs.

While this is technically correct, and while it usually doesn't prevent matching the trip with external data sources, it causes stops not to be matched, aside from implementing heuristic stop matching and risking false positives.

This leaves conservative (as in: careful, not willing to implement extensive heuristic workarounds) consumers with no other choice than marking the Schedule stop as cancelled/skipped and the other data source's stop as additional, causing bad routing results.

An example from VBB's own GTFS-RT feed:

As of 2026-09-01T11:24:38+02:00, the latest VDV-454 AUS Komplettfahrt=true IstFahrt for the trip. Note that the rudimentary HaltID/stop_id matching works here, so there is a Schedule stop *:*:900340004*.

(using this DuckDB script)

SELECT DISTINCT ON (FahrtBezeichner, HaltID) t.*, stop_name FROM (SELECT * EXCLUDE ("$BestaetigungZst", Betriebstag, FahrtStartEnde, UmlaufID, FahrzeugTypID, RichtungsID, PrognoseMoeglich, Komplettfahrt, ServiceAttributs, AbfahrtssteigText, Einsteigeverbot, AnkunftssteigText, Aussteigeverbot, Durchfahrt, HinweisText), RichtungsID AS RiID, PrognoseMoeglich AS ProgMoegl FROM aus_isthalts WHERE Komplettfahrt = 'true' AND FahrtBezeichner = '3357-800158-8012943-200400#DB#DB' ORDER BY "$BestaetigungZst" DESC, Abfahrtszeit) t LEFT JOIN gtfs.stops ON t.HaltID = split_part(stops.stop_id, ':', 3) ORDER BY coalesce(Ankunftszeit, Abfahrtszeit);
┌──────────────────────────────────┬──────────────────────────┬──────────┬────────────┬───────────────┬───────────┬───────────┬──────────────────────────┬──────────────────────────┬──────────────────────────┬──────────────────────────┬────────────┬────────────────────────┬───────────┬─────────────────────────────────────────┐
│         FahrtBezeichner          │           Zst            │ LinienID │ LinienText │ RichtungsText │ FaelltAus │  HaltID   │       Abfahrtszeit       │    IstAbfahrtPrognose    │       Ankunftszeit       │    IstAnkunftPrognose    │ Zusatzhalt │          RiID          │ ProgMoegl │                stop_name                │
│             varchar              │ timestamp with time zone │ varchar  │  varchar   │    varchar    │  boolean  │  varchar  │ timestamp with time zone │ timestamp with time zone │ timestamp with time zone │ timestamp with time zone │  boolean   │        varchar         │  boolean  │                 varchar                 │
├──────────────────────────────────┼──────────────────────────┼──────────┼────────────┼───────────────┼───────────┼───────────┼──────────────────────────┼──────────────────────────┼──────────────────────────┼──────────────────────────┼────────────┼────────────────────────┼───────────┼─────────────────────────────────────────┤
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900341110 │ 2026-08-31 20:04:00+02   │ NULL                     │ NULL                     │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Schwedt, Bahnhof                        │ 
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900341111 │ 2026-08-31 20:06:00+02   │ NULL                     │ 2026-08-31 20:06:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Schwedt, Mitte Bhf                      │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900340003 │ 2026-08-31 20:18:00+02   │ NULL                     │ 2026-08-31 20:17:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Pinnow (UM), Bahnhof                    │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900340004 │ 2026-08-31 20:32:00+02   │ NULL                     │ 2026-08-31 20:26:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Angermünde, Bahnhof                     │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900350125 │ 2026-08-31 20:43:00+02   │ NULL                     │ 2026-08-31 20:42:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Chorin, Bahnhof                         │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900350124 │ 2026-08-31 20:47:00+02   │ NULL                     │ 2026-08-31 20:46:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Britz, Bahnhof                          │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900350127 │ 2026-08-31 20:53:00+02   │ NULL                     │ 2026-08-31 20:51:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Eberswalde, Hauptbahnhof                │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900350160 │ 2026-08-31 21:08:00+02   │ NULL                     │ 2026-08-31 21:07:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ S Bernau Bhf                            │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900007102 │ 2026-08-31 21:24:00+02   │ NULL                     │ 2026-08-31 21:21:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ S+U Gesundbrunnen Bhf (Berlin)          │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900003200 │ 2026-08-31 21:32:00+02   │ NULL                     │ 2026-08-31 21:29:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ S+U Berlin Hauptbahnhof                 │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900100020 │ 2026-08-31 21:35:00+02   │ NULL                     │ 2026-08-31 21:34:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ S+U Potsdamer Platz Bhf (Berlin)        │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900058101 │ 2026-08-31 21:43:00+02   │ NULL                     │ 2026-08-31 21:39:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ S Südkreuz Bhf (Berlin)                 │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900064301 │ 2026-08-31 21:48:00+02   │ NULL                     │ 2026-08-31 21:47:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ S Lichterfelde Ost Bhf (Berlin)         │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900220001 │ 2026-08-31 21:53:00+02   │ NULL                     │ 2026-08-31 21:52:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Teltow, Bahnhof                         │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900245032 │ 2026-08-31 21:57:00+02   │ NULL                     │ 2026-08-31 21:56:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Großbeeren, Bahnhof                     │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900245030 │ 2026-08-31 22:02:00+02   │ NULL                     │ 2026-08-31 22:01:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Ludwigsfelde, Birkengrund Bhf           │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900245029 │ 2026-08-31 22:06:00+02   │ NULL                     │ 2026-08-31 22:05:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Ludwigsfelde, Bahnhof                   │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900245014 │ 2026-08-31 22:17:00+02   │ NULL                     │ 2026-08-31 22:17:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Woltersdorf (Nuthe-Urstromtal), Bahnhof │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900245016 │ 2026-08-31 22:22:00+02   │ NULL                     │ 2026-08-31 22:21:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Luckenwalde, Bahnhof                    │
│ 3357-800158-8012943-200400#DB#DB │ NULL                     │ 3357     │ RE3        │ NULL          │ NULL      │ 900245002 │ NULL                     │ NULL                     │ 2026-08-31 22:30:00+02   │ NULL                     │ NULL       │ Schwedt(Oder)#Jüterbog │ true      │ Jüterbog, Bahnhof                       │
└──────────────────────────────────┴──────────────────────────┴──────────┴────────────┴───────────────┴───────────┴───────────┴──────────────────────────┴──────────────────────────┴──────────────────────────┴──────────────────────────┴────────────┴────────────────────────┴───────────┴─────────────────────────────────────────┘

However, looking at the Schedule trip 304272689, we can see that it uses a different (non-IFOPT) stop_id for Angermünde Bahnhof.

SELECT stop_sequence_consec AS stop_seq_c, stop_id, stop_name, station_id, station_name, t_arrival, t_departure FROM arrivals_departures WHERE date = '2026-09-01' AND trip_id = '304272689' ORDER BY stop_sequence_consec;
┌────────────┬─────────────────────────┬──────────────────────────────────┬────────────────────┬──────────────────────────────────┬──────────────────────────┬──────────────────────────┐
│ stop_seq_c │         stop_id         │            stop_name             │     station_id     │           station_name           │        t_arrival         │       t_departure        │
│   int32    │         varchar         │             varchar              │      varchar       │             varchar              │ timestamp with time zone │ timestamp with time zone │
├────────────┼─────────────────────────┼──────────────────────────────────┼────────────────────┼──────────────────────────────────┼──────────────────────────┼──────────────────────────┤
│          0 │ de:12073:900341110:1:50 │ Schwedt, Bahnhof                 │ de:12073:900341110 │ Schwedt, Bahnhof                 │ 2026-09-01 20:04:00+02   │ 2026-09-01 20:04:00+02   │
│          1 │ de:12073:900341111:1:50 │ Schwedt, Mitte Bhf               │ de:12073:900341111 │ Schwedt, Mitte Bhf               │ 2026-09-01 20:06:00+02   │ 2026-09-01 20:06:00+02   │
│          2 │ de:12073:900340003:1:50 │ Pinnow (UM), Bahnhof             │ de:12073:900340003 │ Pinnow (UM), Bahnhof             │ 2026-09-01 20:17:00+02   │ 2026-09-01 20:18:00+02   │
│          3 │ 000300570037            │ Angermünde, Bahnhof              │ de:12073:900340004 │ Angermünde, Bahnhof              │ 2026-09-01 20:26:00+02   │ 2026-09-01 20:32:00+02   │
│          4 │ de:12060:900350125:2:51 │ Chorin, Bahnhof                  │ de:12060:900350125 │ Chorin, Bahnhof                  │ 2026-09-01 20:42:00+02   │ 2026-09-01 20:43:00+02   │
│          5 │ de:12060:900350124:2:51 │ Britz, Bahnhof                   │ de:12060:900350124 │ Britz, Bahnhof                   │ 2026-09-01 20:46:00+02   │ 2026-09-01 20:47:00+02   │
│          6 │ de:12060:900350127:3:53 │ Eberswalde, Hauptbahnhof         │ de:12060:900350127 │ Eberswalde, Hauptbahnhof         │ 2026-09-01 20:51:00+02   │ 2026-09-01 20:53:00+02   │
│          7 │ de:12060:900350160:2:52 │ S Bernau Bhf                     │ de:12060:900350160 │ S Bernau Bhf                     │ 2026-09-01 21:07:00+02   │ 2026-09-01 21:08:00+02   │
│          8 │ de:11000:900007102:4:57 │ S+U Gesundbrunnen Bhf (Berlin)   │ de:11000:900007102 │ S+U Gesundbrunnen Bhf (Berlin)   │ 2026-09-01 21:21:00+02   │ 2026-09-01 21:24:00+02   │
│          9 │ de:11000:900003200:1:50 │ S+U Berlin Hauptbahnhof          │ de:11000:900003201 │ S+U Berlin Hauptbahnhof          │ 2026-09-01 21:29:00+02   │ 2026-09-01 21:32:00+02   │
│         10 │ de:11000:900100020:1:50 │ S+U Potsdamer Platz Bhf (Berlin) │ de:11000:900100020 │ S+U Potsdamer Platz Bhf (Berlin) │ 2026-09-01 21:34:00+02   │ 2026-09-01 21:35:00+02   │
│         11 │ de:11000:900058101:2:53 │ S Südkreuz Bhf (Berlin)          │ de:11000:900058101 │ S Südkreuz Bhf (Berlin)          │ 2026-09-01 21:39:00+02   │ 2026-09-01 21:43:00+02   │
│         12 │ de:11000:900064301:1:50 │ S Lichterfelde Ost Bhf (Berlin)  │ de:11000:900064301 │ S Lichterfelde Ost Bhf (Berlin)  │ 2026-09-01 21:47:00+02   │ 2026-09-01 21:48:00+02   │
│         13 │ de:12069:900220001:1:50 │ Teltow, Bahnhof                  │ de:12069:900220001 │ Teltow, Bahnhof                  │ 2026-09-01 21:52:00+02   │ 2026-09-01 21:53:00+02   │
│         14 │ de:12072:900245032:1:50 │ Großbeeren, Bahnhof              │ de:12072:900245032 │ Großbeeren, Bahnhof              │ 2026-09-01 21:56:00+02   │ 2026-09-01 21:57:00+02   │
│         15 │ de:12072:900245030:1:50 │ Ludwigsfelde, Birkengrund Bhf    │ de:12072:900245030 │ Ludwigsfelde, Birkengrund Bhf    │ 2026-09-01 22:01:00+02   │ 2026-09-01 22:02:00+02   │
│         16 │ de:12072:900245029:1:51 │ Ludwigsfelde, Bahnhof            │ de:12072:900245029 │ Ludwigsfelde, Bahnhof            │ 2026-09-01 22:05:00+02   │ 2026-09-01 22:05:00+02   │
└────────────┴─────────────────────────┴──────────────────────────────────┴────────────────────┴──────────────────────────────────┴──────────────────────────┴──────────────────────────┘
SELECT stop_id, stop_name, parent_station AS station_id FROM stops WHERE stop_id = '000300570037';
┌──────────────┬─────────────────────┬────────────────────┐
│   stop_id    │      stop_name      │     station_id     │
│   varchar    │       varchar       │      varchar       │
├──────────────┼─────────────────────┼────────────────────┤
│ 000300570037 │ Angermünde, Bahnhof │ de:12073:900340004 │
└──────────────┴─────────────────────┴────────────────────┘

Last update of GTFS Feed

2026-08-27

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Best PracticeGute GTFS PraxisDE-BBDeutschland - BrandenburgDE-BEDeutschland - BerlinErweiterungErweiterungs- oder ÄnderungswunschVBBVerkehrsverbund Berlin-Brandenburg

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions