DELFI: Fälschlicherweise zusammengefasste Trips
Beschreibe den Fehler
Im DELFI GTFS Feed entsprechen trip_ids scheinbar einem Substring der ServiceJourney-IDs des DELFI NeTEx-Feeds (z.B. ist 2792044148 die trip_id von DE::ServiceJourney:*2792044148*_0::)
Darüber hinaus enthält der DELFI NeTEx feed für manche Linien neben mit _0:: endenden ServiceJourneys auch solche mit Endung _1::.
Diese scheinen im GTFS-Feed, trotz unterschiedlicher Eigenschaften (in nachfolgendem Beispiel der Möglichkeit der Fahrradmitnahme) zusammengefasst zu werden:
Im GTFS-Feed ist Trip 2792044148 (ohne Suffix) ist Fahrradmitnahme an allen 7 Werktagen möglich:
D select * from trips where trip_id like '2792044148%';
┌──────────────────────────────────────────────┬────────────┬────────────┬───────────────────────┬─────────────────┬──────────────┬──────────┬──────────┬───────────────────────┬───────────────┐
│ route_id │ service_id │ trip_id │ trip_headsign │ trip_short_name │ direction_id │ block_id │ shape_id │ wheelchair_accessible │ bikes_allowed │
│ varchar │ int64 │ varchar │ varchar │ varchar │ int64 │ int64 │ int64 │ int64 │ int64 │
├──────────────────────────────────────────────┼────────────┼────────────┼───────────────────────┼─────────────────┼──────────────┼──────────┼──────────┼───────────────────────┼───────────────┤
│ de:naldo:fe27faafac9f405abb58c5d3fc57a219:_3 │ 38 │ 2792044148 │ Nusplingen Marktplatz │ │ 0 │ │ 45917 │ 0 │ 1 │
└──────────────────────────────────────────────┴────────────┴────────────┴───────────────────────┴─────────────────┴──────────────┴──────────┴──────────┴───────────────────────┴───────────────┘
D select * from calendar where service_id=38;
┌────────────┬────────┬─────────┬───────────┬──────────┬────────┬──────────┬────────┬────────────┬──────────┐
│ service_id │ monday │ tuesday │ wednesday │ thursday │ friday │ saturday │ sunday │ start_date │ end_date │
│ int64 │ int64 │ int64 │ int64 │ int64 │ int64 │ int64 │ int64 │ int64 │ int64 │
├────────────┼────────┼─────────┼───────────┼──────────┼────────┼──────────┼────────┼────────────┼──────────┤
│ 38 │ 1 │ 1 │ 1 │ 1 │ 1 │ 1 │ 1 │ 20250329 │ 20251213 │
└────────────┴────────┴─────────┴───────────┴──────────┴────────┴──────────┴────────┴────────────┴──────────┘
Im NeTEx Feed laut NoticeAssignement scheinbar nur am 30.3. (extrapoliert mutmaßlich sonn- und feiertags).
<UicOperatingPeriod id="DE::UicOperatingPeriod:148197::" version="1744458049">
<FromDate>2025-03-29T00:00:00</FromDate>
<ToDate>2025-04-02T00:00:00</ToDate>
<ValidDayBits>10111</ValidDayBits>
</UicOperatingPeriod>
<UicOperatingPeriod id="DE::UicOperatingPeriod:148199::" version="1744458049">
<FromDate>2025-03-30T00:00:00</FromDate>
<ToDate>2025-03-30T00:00:00</ToDate>
<ValidDayBits>1</ValidDayBits>
</UicOperatingPeriod>
...
<vehicleTypes>
<VehicleType id="DE::VehicleType:4456::" version="1744458049">
<Name>Standard Linienbus</Name>
<ShortName>tgoSL Nor</ShortName>
</VehicleType>
</vehicleTypes>
...
<ServiceJourney id="DE::ServiceJourney:2792044148_1::" version="1744458049">
<TransportMode>bus</TransportMode>
<DepartureTime>10:59:00</DepartureTime>
<JourneyDuration>PT37M</JourneyDuration>
<dayTypes>
<DayTypeRef ref="DE::DayType:148199::" version="1744458049"/>
</dayTypes>
<ServiceJourneyPatternRef ref="DE::ServiceJourneyPattern:273360326_1::" version="1744458049"/>
<VehicleTypeRef ref="DE::VehicleType:4456::" version="1744458049"/>
...
</ServiceJourney>
...
</ServiceJourney>
<ServiceJourney id="DE::ServiceJourney:2792044148_0::" version="1744458049">
<TransportMode>bus</TransportMode>
<DepartureTime>10:59:00</DepartureTime>
<JourneyDuration>PT37M</JourneyDuration>
<dayTypes>
<DayTypeRef ref="DE::DayType:148197::" version="1744458049"/>
</dayTypes>
<ServiceJourneyPatternRef ref="DE::ServiceJourneyPattern:273360326_0::" version="1744458049"/>
<VehicleTypeRef ref="DE::VehicleType:4456::" version="1744458049"/>
...
</ServiceJourney>
...
<ServiceJourneyPattern id="DE::ServiceJourneyPattern:273360326_1::" version="1744458049">
<RouteView id="DE::RouteView:273360326_2::">
<LineRef ref="DE::Line:7095226::" version="1744458049"/>
</RouteView>
<DirectionRef ref="DE::Direction:1::" version="1744458049"/>
<pointsInSequence>
<StopPointInJourneyPattern id="DE::StopPointInJourneyPattern:273360326_2_14::" order="1" version="1744458049">
<ScheduledStopPointRef ref="DE::ScheduledStopPoint:13210908_tub_d_::" version="1744458049"/>
<ForAlighting>true</ForAlighting>
<ForBoarding>true</ForBoarding>
<ChangeOfDestinationDisplay>false</ChangeOfDestinationDisplay>
<noticeAssignments>
<NoticeAssignment id="DE::NoticeAssignment:47631275::" order="1" version="1744458049">
<Notice id="DE::Notice:17_104630::" version="1744458049">
<Text lang="de-DE">Fahrradmitnahme möglich</Text>
<PublicCode>RAD</PublicCode>
</Notice>
</NoticeAssignment>
...
</noticeAssignments>
</StopPointInJourneyPattern>
...
</pointsInSequence>
</ServiceJourneyPattern>
<ServiceJourneyPattern id="DE::ServiceJourneyPattern:273360326_0::" version="1744458049">
<RouteView id="DE::RouteView:273360326_1::">
<LineRef ref="DE::Line:7095226::" version="1744458049"/>
</RouteView>
<DirectionRef ref="DE::Direction:1::" version="1744458049"/>
<pointsInSequence>
<StopPointInJourneyPattern id="DE::StopPointInJourneyPattern:273360326_1_0::" order="1" version="1744458049">
<ScheduledStopPointRef ref="DE::ScheduledStopPoint:13210908_tub_d_::" version="1744458049"/>
<ForAlighting>true</ForAlighting>
<ForBoarding>true</ForBoarding>
<ChangeOfDestinationDisplay>false</ChangeOfDestinationDisplay>
<noticeAssignments>
<NoticeAssignment id="DE::NoticeAssignment:47631219::" order="1" version="1744458049">
<Notice id="DE::Notice:14700_104626::" version="1744458049">
<Text lang="de-DE">Zahl der Stehplätze : 1</Text>
<PublicCode>NSTAND</PublicCode>
</Notice>
</NoticeAssignment>
<NoticeAssignment id="DE::NoticeAssignment:47631220::" order="1" version="1744458049">
<Notice id="DE::Notice:14701_104627::" version="1744458049">
<Text lang="de-DE">Zahl der Sitzplätze : 2</Text>
<PublicCode>NSEAT</PublicCode>
</Notice>
</NoticeAssignment>
<NoticeAssignment id="DE::NoticeAssignment:47631221::" order="1" version="1744458049">
<Notice id="DE::Notice:14702_104628::" version="1744458049">
<Text lang="de-DE">Zahl der behindertengerechten Plätze : 1</Text>
<PublicCode>NBEHIN</PublicCode>
</Notice>
</NoticeAssignment>
<NoticeAssignment id="DE::NoticeAssignment:47631222::" order="1" version="1744458049">
<Notice id="DE::Notice:12676_104629::" version="1744458049">
<Text lang="de-DE">DELFI-Anreicherungs-URL : https://www.efa-bw.de/trias</Text>
<PublicCode>DIPURL</PublicCode>
</Notice>
</NoticeAssignment>
</noticeAssignments>
</StopPointInJourneyPattern>
...
</pointsInSequence>
</ServiceJourneyPattern>
Weitere ServiceJouneys mit gleichem Pattern mit Laufzeit bis zum 20251213 scheinen im GTFS-Feed allesamt auf Trip 2792044148 zusammengefasst zu sein.
Welchen Prinzipien folgt der Zusammenfassungs-Mechanismus? Seine Funktionsweise ist auch relevant, um GTFS-RT trip_ids auf einen aus dem NeTEx-Feed abgeleiteten GTFS-Feed abzubilden.
Aktualisierungszeitpunkt der GTFS-Daten 2025-04-14
Downloadlink der GTFS-Daten DELFI-GTFS-Feed DELFI-NeTEx-Feed
An sich werden Fahrten bereits beim Import zusammengefasst. Die im Beispiel benannte Fahrt von Balingen Bahnhof/Busbhf ab 10:59 nach Nusplingen Marktplatz an 11:36 verkehrt prinzipiell "täglich".
Wir importieren mehrmals pro Woche, wobei jedes Mal eine neue "Linienversion" (Begriff wird in unterschiedlichen Kontexten verwendet, daher hier in Anführungszeichen) erzeugt wird. Grafisch sieht das so aus:
Und wir exportieren jeweils samstags für 14 Tage rückwirkend.
Es kann sein (muss aber nicht), dass die Fahrten in den einzelnen Linienversionen identisch sind.
GTFS als das kompaktere Format versucht beim Export über alle Linien einen optimalen Kalender zu finden und Fahrten zusammenzufassen. NeTEx generiert den Betriebskalender pro Linie bzw. Linienversion. D.h. insbesondere bei der 14-tägigen Rückschau wird der zeitversetzte Beginn der Fahrtgültigkeiten berücksichtigt.
Wenn man also NeTEx in GTFS wandelt, müsste man m.E. auch einen Tool zur Ermittlung des optimalen Kalenders mit einbeziehen.
Ausblick unsererseits: wir versuchen nur noch Linien zu importieren, bei denen es wirklich Änderungen im Fahrplan gibt (sog. "inkrementelle Importe"), sodass die Auswirkungen auf die zeitliche Stückelung der Gültigkeiten in der Vergangenheit sich nicht mehr so stark auf die exportierten Daten auswirkt.
Danke für die Erläuterungen. Bei einer Zusammenfassung dürften mE nur solche Fahrten zusammengefasst werden, die auch gleiche Eigenschaften haben. Insbesondere nicht Mo-Sa Fahrten ohne Fahrradmitnahme zusammen mit So/Feiertags-Fahrten mit Fahrradmitnahme, da es sonst zu einer Verfälschung der Daten kommt.
Mich wundert mehr, das im NeTEx die Fahrradmitnahme aufgesplittet wird. Wie oben beschrieben, hat die betroffene Fahrt bei uns bereits eine Gültigkeit "täglich". Warum sollte dann die Fahrradmitnahme einmal erlaubt sein und einmal nicht?
Bei Abfrage der Online-Auskunft des naldo.de erhält man für Werktage und Sonntag unterschiedliche Hinweise angezeigt.
Sonntag:
Werktag:
Ich kann mir gut vorstellen, dass manche VU/VV die Fahrradmitnahme auf nachfrageschwache Zeiten beschränken und daher nur sonntags zulassen.
(Der Hinweis zu Niederflurfahrzeug mit Klapprampe fehlt in NeTEx bei allen Fahrten der Linie.)
Du hast recht. Um die Beschränkung der Fahrradmitnahme auf Sonn- und Feiertage bei uns zu finden, hat es ein paar Klicks mehr gebraucht. Dann ist es also doch ein GTFS-Thema, das ich auf die Schnelle nicht beantwortet bekomme.
(Die korrekte Übernahme der Fahrzeuge aus den Datenquellen haben wir leider immer noch nicht in Griff, ist aber in Arbeit und ein anderes Thema)
@BeckertAnke Gibt es bereits eine Zeitplanung für a) die Vermeidung der Zerstückelung beim Import b) die Korrektur der falschen Zusammenführung (aufgrund der mutmaßlich fehlenden Berücksichtigung der Notices) von Fahrten?
Weiteres Beispiel für eine in meinen Augen unzulässige Zusammenführung von Trips im DELFI GTFS:
Aus dem NeTEx Feed leite ich folgende Informationen ab (2846214073 entspricht ServiceJourney 2846214073_0):
SELECT trip_id, c.*
FROM trips t
JOIN calendar c ON t.service_id=c.service_id
WHERE trip_id LIKE '2846214073%';
| trip_id | service_id | start_date | end_date | monday | tuesday | wednesday | thursday | friday | saturday | sunday |
|--------------|-----------:|------------|------------|-------:|--------:|----------:|---------:|-------:|---------:|-------:|
| 2846214073 | 238357 | 2025-06-15 | 2025-10-29 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 2846214073_1 | 238363 | 2025-05-17 | 2025-06-14 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Diese sollten m.E. aufgrund unterschiedlicher Stops nicht zusammengeführt werden:
SELECT trip_id, stop_id, stop_sequence, arrival_time, departure_time
FROM stop_times st
WHERE trip_id LIKE '2846214073%' ORDER BY stop_sequence, trip_id;
| trip_id | stop_id | stop_sequence | arrival_time | departure_time |
|--------------|-------------------|--------------:|--------------|----------------|
| 2846214073 | de:13003:1500:3:3 | 0 | 18:31:00 | 18:31:00 |
| 2846214073_1 | de:13003:1500:2:2 | 0 | 18:31:00 | 18:31:00 |
# ... (identische stop_times ausgeblendet ...)
| 2846214073 | de:13003:1489 | 9 | 18:54:00 | 18:54:00 |
| 2846214073_1 | de:13003:1489:3:3 | 9 | 18:54:00 | 18:54:00 |
Ab dem 30.10. ist zudem die Abfahrtzeit laut NeTEx Daten nicht mehr 18:31 sondern 18:29. (Nachfolgende GTFS-Abfrage basiere auf den aus NeTEx konvertierten GTFS-Daten):
SELECT t.*, stop_id, stop_sequence, arrival_time, departure_time
FROM trips t
JOIN calendar c ON t.service_id=c.service_id
JOIN stop_times st ON st.trip_id = t.trip_id
WHERE route_id = '162770_109'
AND stop_sequence=0
AND start_date='2025-10-30'
AND departure_time like '18:%'
AND trip_headsign='Rostock Hauptbahnhof'
ORDER BY departure_time;
| route_id | trip_id | service_id | shape_id | trip_headsign | bikes_allowed | trip_short_name | direction_id | block_id | stop_id | stop_sequence | arrival_time | departure_time |
|------------|--------------|-----------:|----------|----------------------|--------------:|-----------------|-------------:|----------|-------------------|--------------:|--------------|----------------|
| 162770_109 | 2846214104_1 | 238364 | | Rostock Hauptbahnhof | 1 | 33533 | 0 | | de:13003:1500:2:2 | 0 | 18:09:00 | 18:09:00 |
| 162770_109 | 2846214114 | 238361 | | Rostock Hauptbahnhof | 1 | 33387 | 0 | | de:13003:1500:3:3 | 0 | 18:19:00 | 18:19:00 |
| 162770_109 | 2846214103 | 238351 | | Rostock Hauptbahnhof | 1 | 33535 | 0 | | de:13003:1500:2:2 | 0 | 18:29:00 | 18:29:00 |
Ins DELFI-GTFS hingegen ausgeleitet ist nur ein trip, der die Unterschiede bzgl. Steigen und Abfahrtszeiten ignoriert:
# trips.txt
"162770_109",9237,2846214073,"Rostock Hauptbahnhof","75829",0,,13221,0,0
# stop_times.txt
2846214073,18:31:00,18:31:00,"de:13003:1500:2:2",0,0,0,""
2846214073,18:33:00,18:33:00,"de:13003:926:2:1",1,0,0,""
2846214073,18:36:00,18:36:00,"de:13003:840:1:2",2,0,0,""
2846214073,18:38:00,18:39:00,"de:13003:796:4:2",3,0,0,""
2846214073,18:40:00,18:41:00,"de:13003:794:2:2",4,0,0,""
2846214073,18:43:00,18:43:00,"de:13003:827:2:2",5,0,0,""
2846214073,18:46:00,18:46:00,"de:13003:1504:2:2",6,0,0,""
2846214073,18:48:00,18:48:00,"de:13003:791:3:2",7,0,0,""
2846214073,18:50:00,18:50:00,"de:13003:853:3:2",8,0,0,""
2846214073,18:54:00,18:54:00,"de:13003:1489:3:3",9,0,0,""
# calendar.txt
9237,1,1,1,1,1,1,1,20250517,20251213
Welche Kriterien werden für die Zusammenführung von Trips beim DELFI-GTFS-Export genutzt? Sind diese so intendiert oder unbeabsichtigt?